Home

     _______        _______ __   _  ______
     |______ |      |______ | \  | |  ____
     |       |_____ |______ |  \_| |_____|

This software is an implementation of "FLENG", a low level concurrent

logic programming language descended from Prolog. A compiler is

provided to translate programs written in FLENG into assembly

language which can subsequently be compiled and linked into a binary

executable. As FLENG is quite minimal in features, translators

from "Flat Guarded Horn Clauses", "Strand" and "PCN" (other concurrent

logic languages) into FLENG are also available.

Example code:

The "FizzBuzz" program in FGHC/Strand:

% fizzbuzz

-initialization(main).

main :- loop(1).

loop(I) :- loop2([], I).

loop2(_, 101).

loop2([], I) :-

I =< 101 |

fizzbuzz(I, Ok),

I2 is I + 1,

loop2(Ok, I2).

fizzbuzz(X, Ok) :- X \\ 15 =:= 0 | writeln('FizzBuzz', Ok).

fizzbuzz(X, Ok) :- X \\ 3 =:= 0 | writeln('Fizz', Ok).

fizzbuzz(X, Ok) :- X \\ 5 =:= 0 | writeln('Buzz', Ok).

fizzbuzz(X, Ok) :- otherwise | writeln(X, Ok).

and in PCN:

/* fizzbuzz */

main()

{;

i over 1..100 ::

{?

i % 15 == 0 -> writeln("FizzBuzz"),

i % 3 == 0 -> writeln("Fizz"),

i % 5 == 0 -> writeln("Buzz"),

default -> writeln(i)

}

}

FLENG programs allow for massive parallelism at a very fine grained

level - goals are executed concurrently and communicate solely via

single-assignment logic variables. The use of logic variables for

inter-process communication offers an easy to use and convenient

abstraction to implement many common patterns of synchronization

and message passing in a natural manner. This implementation

additionally can distribute pools of parallel processes over native

OS level threads, thus taking advantage of multicore architectures.

Locking overhead should be small, as data is normally not shared

among processes executing on different threads. Automatic management

of memory is provided using a reference-counting scheme of fixed

size cells, which avoid fragmentation, eliminates garbage collection

pauses and keeps the overall memory required to hold live data at

any point of time minimal, while providing relatively good locality.

Interfacing to native code is straightforward and compiled FLENG

code and the run time library support can be linked with other

modules written in C or C++ without problems. The compilation tools

allow cross compilation, provided the architecture is supported.

The compiler generates native code, but does currently not perform

a lot of optimizations, so performance-sensitive code should probably

be written in C or another language. FLENG should be particularly

well suited as a coordination language for providing intercommunication

and synchronization with reasonable overhead while calling out to

C or C++ code for low-level or speed-critical operations.

Suggestions for improvement or patches providing enhancements and

corrections are very welcome, see the User's manual for information

on how to contact the author. Also check out the "#fleng" IRC channel

on https://libera.chat if you have questions or need assistance.

This software was written by Felix L. Winkelmann and has been released

into the public domain. Do with it whatever you like.

Installation instructions

User's Manual

List of primitive operations

Get the code

SHA1: e49550cef28f48f4dbe88591f5bac30d40c7c788

Release History:

Version 21:

* IMPORTANT - changes incompatible to earlier versions:

* "app" module: "drop/3" returns list starting from first element

where goal fails.

* "array" module: "array:read/4" assigns the number of elements

read to the "DONE" parameter, not the number of bytes.

* "statistics/1" returns a tuple of 6 elements now, including

the peak and average number of heap cells.

* Added the new "flengbundle" tool to link raw data to applications

or libraries.

* Removed a memory leak caused when a variable is repeatedly

suspended in the head of a clause while another clause for the

same goal still commits; this resulted in suspension-records to be

allocated but never freed as long as the suspended variable is not

bound.

* "app" module: added "index/3".

* "array" module: added "list_to_array/3"; "read" and "write" now

accept standard file stream strings ("stdin", ...).

* "base64" module: added "encode/2" and "decode/2"; decoding

incorrectly generated signed byte list.

* "fmt" module: "~q" format only assumes list is character list

when elements are within ASCII range.

* "bb" module: added "dialog/5".

* "list" module: added "index/3".

* "eval" module: fixed implementation of "when/2"; added support

for ":=/2"; "t/{1,2}" reports invalid guard expressions.

* "json" module: eliminated deadlock in "to_string/{2,3}".

* flengmake:

- indirect module dependencies where not linked to programs.

- ixed bug in graph-creation with targets that have no direct

source file.

- handle broken symlinks when traversing directories.

- foreign objects are now deleted in the "clean" operation.

* Fixed several problems in the FGHC FFI (reported by Darren Bane).

* "+LOAD" accepts "-" to read from stdin.

* Dropped an obsolete requirement for "list_to_tuple/2" that forced

the first element of the argument list.

* Use "cc -x assembler" when assembling on OpenBSD 7.4 or later as

binutils don't seem to understand IBT/BTI instructions.

* Assignment to non-var reported incorrect value in error message

if non-immediate.

* Fixed utterly broken internal string-conversion for arrays.

* [PCN] Improved tracking of mutable assignments to avoid nonsensical

warnings when assignments take place in choice-compositions.

* [PCN] "apply/2" is now allowed to be used in expressions.

* [PCN] Fixed compilation of "cpu_time/0" when used as a function.

* [PCN] A separator is now allowed after the last rule in a choice

composition.

* [PCN] Indexing the empty list is now an error.

* [PCN] When an expression is used as a guard it is equivalent to

comparing it to a non-false value; complementary, "!" followed by

a term is equivalent to comparing the term to false.

* [PCN] The dollar sign ("$") is allowed in identifiers.

* [PCN] Functional struct-field update allows giving more than one item.

* [PCN] Guards may now contain function calls and struct field references.

* [PCN] Fixed race-condition for boxing arguments in calls to foreign

C functions with struct-field-references as argument expressions.

* [PCN] Added support for L"..." notation for character list literals.

* [PCN] Definition of a mutable destination produces a more meaningful

error message.

* [PCN] uses of "apply/2" with constant goal and literal argument list

are converted into a direct call, which can be useful in macros that

construct or augment procedure calls.

* [PCN] Fixed bug in FLENG backend causing mutable variables of

type long to terminate the compiler.

* [PCN] module-use in qualified function calls was not recorded.

* [PCN] The source file is properly retained in error messages that have

no associated line-number.

* [PCN] The use of "write_file/3" was incorrectly compiled in sequential

mode, causing deadlock.

* [PCN] Fixed bug in compiler that caused certain warnings to abort.

* [PCN] Changed "let" syntax by removing the "->" and treating it

like any other statement as the scope of the guards encloses the

full program definition anyway. The old syntax "->", including using

"let" as the body of a program definition is deprecated and will be

removed in the future.

Version 20:

* IMPORTANT: the following primitives and library operations

have changed argument order, which is a backwards-incompatible

change, make sure to review all uses of these operations in

existing code!

- "utf_decode/3": changed to "utf_decode(CHAR^, IN?, OUT^)".

- "list" module: changed order of arguments in "trim/3", "trim_left/3"

and "trim_right/3" where the set of trimmed chars is given as first

argument.

- "app" module: the goal called in "foldl/4" takes its first two

arguments in reversed order, to make the applicative easier to

use with argument pairs.

* Added support for interactive debugging of compiled code.

- New "eval" module which allows evaluating a restricted

subset of FGHC.

- Compiler option "-i" to enable use of interactive mode.

- Run-time options "+INTERACTIVE" and "+LOAD <filename>" to

enter interactive mode or evaluate a file instead of running

initialization code.

* Bugfixes in AArch64 backend, bootstrap compiler and code-generation

with profiling information (reported by Darren Bane).

* Bugfix in fl2XXX FFI wrapper code generation that emitted a call

to an obsolete runtime function (reported by Darren Bane).

* Another bugfix in the wrapper code generation that caused the

compiler to abort, also reported by Darren Bane.

* Fixed bug in use of "call/1" with a module-qualified variable term

which was incorrectly compiled.

* Fixed problem in FFI stub generation when a stub for a foreign

function with no output arguments was generated with arity > 3.

* Bugfix in boot/configure, reported by "ctarbide".

* Bugfixes in arm runtimes for struct and array-test primitives.

* Fixed ordering relation for arrays, which was not implemented.

* Primitives that accept a file-descriptor now also allow the use

of the strings "stdin", "stdout" and "stderr", representing the

standard I/O streams.

* Dropped the "spec" library module - its functionality can be more

clearly expressed with code.

* "list" module: added "replace/4".

* "match" module: added "fields/{3,4}".

* "app" module: added "mapappend/4".

* "json" module: "to_string" supports numeric arrays and handles

invalid parse results; parsing and querying allow strings in

some places where char-lists were required before.

* "fmt" module: the "~s" format supports char/int arrays, printing

them as UTF-8 text; "~w"/"~q" print modules.

* "9p" module:

- added "open/{5,6}", "create/6", "remove/4", "stat/5",

"close/3", "fread/{4,6,7}", "fwrite/{5,7,8}", "fstat/4", "fwstat/5"

"readdir/5" and "freaddir/4".

- "write" requests are not sequenced and have the "iounit" argument

dropped.

- "open" and "create" requests may give their mode arguments in

symbolic form.

* Foreign stub files auto-include "fleng-util.h" (again), unless

when compiling PCN code.

* The "fleng" driver script didn't pass the default include path

when preprocessing PCN code.

* Flengmake:

- Fixed numerous bugs.

- Takes implicit command line arguments from environment variable

"FLENGMAKE_FLAGS".

- Drop pre-computed program and module targets when source file

is removed.

- Fixed handling of symlinks; symlinks pointing outside of the

source tree are ignored.

- state files store a version now and are ignored if the version

doesn't match the current one.

- option files may contain references to environment variables.

* Added new primitive "lseek/{3,4}".

* The "error" primitive forces its argument now.

* "scan" module: added "format/4" and "decode/3".

* "array" module:

- dropped "array:size/2" - use "lwngth/2" instead.

- resizing an array to its existing size returns the array unchanged.

- bugfix in "array:search".

- added "array:hex_to_binary/3" and "array:binary_to_hex/3".

* "binfmt" module: "scan" accepts "~<N><F>" format specifiers where

the count is included in the format-string.

* "proc" module: "capture", "submit" and "pipe" read and write byte

streams now, use "utf_encode"/"utf_decode" if you want to convert

from/to character streams.

* [FGHC] Fixed failing compilation of "data/1" guards following

non-"data" guards in compound guard sequences.

* [FGHC] Inlined applicatives did not register the "app" module as

used in fallback mode (when a non-local goal is called).

* [PCN] Added support for ordering guards ("@>", "@<", "@>=" and "@<=").

* [PCN] All formatting library procedures precompiled by the FGHC

front-end are now also by the PCN front-end.

* [PCN] Choice compositions are compiled more eficiently by

removing redundant parameters in the generated FLENG code.

* [PCN] Function-level calls of "global/1" and "getcwd/0" were

not correctly handled.

* [PCN] Composition bodies are more relaxed about stray separators.

* [PCN] Numbers may contain "'" as separators for readability.

* [PCN] "deref/1", "open_file/2" and "list_to_integer/1" can be used

as functions.

* [PCN] Arguments to certain builtin primitives in function call

position did not force their arguments, when required.

* [PCN] Overhauled semantics of the "struct" declaration and added

"." field notation and "<--" statement.

Version 19:

* "9p" module: simplified "read" requests by dropping IO-unit argument

and returning the number of bytes read; reading over multiple requests

must be handled by user code now.

* "find" module: handle symbolic links properly; "leaves/2" takes

a root directory as first argument now, which is deemed more useful.

* [PCN] Term-elements may be arbitrary expressions and are converted

to FGHC-compatible structured terms.

* [PCN] Array dimension specifications may be simple expressions.

* "ezd" module: added "drawings" and "drawing_info" inquiry commands.

* [PCN] Added "tail" primitive function.

* [PCN] "length" is not a reserved keyword anymore.

* Added library module "base64" for basic Base64 encoding and

decoding.

* Added the "comment" declaration.

* flengdoc: Fixed some missing aliases in module descriptions-

* flengmake: doesn't create state file if no targets exist; add

foreign wrappers for modules to linked libraries and executables;

handle relative symbolic links properly when walking directories;

caches scanning results and applies compiler options also during

scanning.

* "path" module: "normalize" preserves absolute paths properly;

added "with_extension/3".

* The "fleng" compiler driver accepts C/C++ source files and

compiles and links them automatically to a generated executable.

* [PCN] Fixed a bug in the compilation of guard expressions that

contained index-references to non-arrays.

* The primitives "file_modification_time/2", "file_type/2" and

"file_size/2" accept file descriptors as first argument.

* Added a detailed PCN tutorial to the documentation

(doc/PCN-tutorial.txt)

Version 18:

* "map" module: swapped 2nd and 3rd arguments of "delete/4" and

3rd and 4th arguments of "replace" for the same reason to

make them easier to use with argument pairs. This is a

backwards-incompatible change, make sure to review all

uses of these operations in existing code!

* Added library module "json" for parsing and printing JSON data.

* "fmt" module: the "~q" format shows character lists in quoted

string representation, if the list only contains valid UNICODE

code points and newline/tab characters.

* Added "with/2" FGHC form and "with" PCN keyword for establishing

dynamic task bindings, together with "binding/{2,3}" and

"call_handler/1" to access bindings and call goals retrieved

from the environment.

* Added "-c++" option to "fleng" driver script to force compilation

of foreign wrappers with C++ compiler.

* Added "-foreign" option to override name of generated C/C++

wrapper and stub file.

* [PCN] Added directives for embedding C/C++ code.

* Dropped support for out-of-tree builds.

* Added "flengmake", a build tool for projects written with FLENG

(the examples are now built using this tool).

* "flengdoc" uses a pager now to display longer sections of

documentation when running inside a terminal.

* Fixed bug in FLENG backend compiler that caused trivial clauses

to be incorrectly executed in predicates that use optimized table

lookups.

* Added new primitives "counter/1", "setenv/{2,3}", "cpu_time/1",

"isatty/2", "string_to_list/2" and "tuple_to_list/2".

* [PCN] Many primitives can now be used as functions inside

expressions.

* Added library module "binfmt" for binary encoding and decoding

of byte strings.

* Added library module "9p" for writing clients for the Plan 9

"9p" protocol.

* Added several bug fixes for the MacOS X runtime system

(contributed by Kon Lovett).

* Renamed "ezbb" module to "bb".

* "lib" module: "write_file/{3,4}" treats the empty list as a list,

not a string.

* "path" module: fixed bug in "join/2", added "normalize/2" and

"with_root/3".

* "fmt" module: all non-printable characters < 32 are now written

as hexadecimal escape codes in quoted (readable) output; exposed

and documented "parse_format", "format_chunked" and

"format_chars_chunked".

* "proc" module: added "shell/1".

* "scan" module: "delimited_with_escape" handles now "\xXX"

sequences.

* The code generation pass of the FLENG-to-assembler compiler stage

has been optimized, which reduces overall compile times

significantly.

* Output of (heap-)statistics is forced once before normal termination.

* [FGHC] Added "rewrite/2" declaration which allows simple

term-rewriting to be performed with user-defined rules.

* [FGHC] Normal (non-pair) access to pair-variable uses current

value, not the one initially set on clause entry.

* [FGHC] "array/1" guard was not recognized.

* Added "short" array type, renamed "byte" array type to "char",

renamed "int" to "long" and added explicit "int" (32 bit) type.

* [PCN] Fixed bug in compilation of "fmt:format/3".

* [PCN] Generalized definition targets to allow multiple indices.

* [PCN] Added "short" mutable variable type, renamed "byte" to "char",

renamed "int" to "long" and added explicit "int" (32 bit) type.

* [PCN] Added "+=", "-=", "*=", "/=", "%=", ">>=", "<<=", "&=", "|="

and "^=" assignment statements for argument pairs.

* [PCN] Reduced redundant forcing of variables used in complex

arithmetic expressions and optimized code for box-references.

* [PCN] Fixed the order of the index incrementation for mutable

quantification variables.

* [PCN] Added "variable pair" notation and "++" operator for more

convenient passing and transforming state and streams.

* [PCN] The PCN translator signals an error now if a definition

expression refers to the defined variable.

* Quoted strings and character lists allow hexadecimally encoded

characters using the \x and \u escape sequences.

* "array:put" didn't handle the empty list as an empty element

sequence.

* "array" module: added "resize/{3,4}", "search/{3,4,5}", "map/{5,6}",

"unmap/{1,2}", "synchronize/{3,4}" and "write_utf/{4,5}"; "copy"

unifies its confirmation argument with the index following the

copied section.

* "list" module: replaced "getprop" with "assoc/{3,4}"; fixed bug in

"join" that caused extra separator at end; added "join/3".

* The system can now be built without OS-thread support, if desired,

by passing "--disable-threads" to the configuration script.

* Added support for BTI/IBT instruction generation on x86_64 and

AArch64 architectures for platforms that enforce this (currently

only enabled for OpenBSD 7.4 or higher).

* Fixed bug in runtime library that would cause a segfault on

platfoms that don't allow read access from the ".text" section.

* Fixed usage of assembler on platforms that require use of internal

clang assembler.

* Examples are installed along with the rest of the documentation,

including makefiles and required assets.

Version 17:

* Fixed bug in building SDL interface from distribution tarball

(thanks to Adrián Arroyo for helping to track this down).

* The "pcn2fl" binary was not properly installed.

* Various bugfixes in RISCV runtime and compiler backend.

Version 16:

* Added an interface to SDL2 for basic graphics programming, a structured

graphics package ("ezd"), including a library for simple UI construction

and many examples demonstrating these new libraries.

* Fixed some problems with the FLENG inline assembler, added inline

assembler support to the PCN compiler.

* Removed primitive "list_to_number/3" and added "list_to_integer/{2,3}".

* List->number conversions assign the string "error" as result

instead of aborting with an error if the list does not contain

valid characters.

* Added new primitive "dbgwrite/{1,2}".

* Added new library module "sec", which provides "unveil" and "pledge"

system calls (if on OpenBSD) and dropping of process privileges.

* "list" module: added "nth/3" and "suffix/3".

* "map" module: "list_to_map/2" now also accepts 2-element tuples in

the input list.

* Added "-a" flag to show intermediate representation of compiled code.

* Logging output now always prints floats with a decimal point.

* "program_name/1" has been changed to assign a string, not a character

list.

* Average cell usage statistic was incorrectly computed.

* Fixed computation typo in definition of TUPLE_LENGTH.

* Fixed ref-counting bug for array slices when forwarded to the

thread that owned the original array.

* Switch to data section for lookup tables has been disabled for x64

on Mac due to problems with generated relocation entries.

* [PCN] Fixed off-by-one error in index check for indexed tuple

references.

* [PCN] Index expressions ("[...]") support lists now.

* [PCN] Added experimental attribute expressions ("<id>.<id>").

* [PCN] Added support for definition statement of indexed tuples or lists.

* [PCN] Assignment to array element did not compile index expression

properly.

* [PCN] Added "``...``" syntax for procedure references.

* [PCN] Added "let" syntactic suger for checked destructuring.

* [PCN] "abs/1" in expressions was not correctly parsed.

* [PCN] Lambda-expressions now are specific to the current module.

* [PCN] Array sizes must now be literal integers or references to

mutable variables, as a size given via an unbound defintional

variable would result in a run-time error.

* [PCN] Quantification end range expressions where not correctly

parsed.

* [PCN] Fixed duplicate variables in task-creation wrappers for sequential

compositions.

* [PCN] Fixed bug in PCN parser that caused module-qualified function

calls to be rejected.

* [PCN] Variable usage tracking for choice compositions wasn't

working properly, resulting in missing or bogus warnings for

singleton variables.

* [PCN] Variable liveness analysis for complex argument expressions

to foreign C function calls was broken and resulted in deadlocks

at execution time, due to unknown and thus unbound variable references.

* [PCN] Fixed further liveness analysis bugs in complex array index

expressions and non-trivial quantification ranges.

* [PCN] Fixed compiler bug that could cause uninitialized environment

slots for singleton arguments.

* [PCN] Added support for the type tests "remote", "module", "known"

and "unknown" in choice clauses.

* [PCN] Added some compiler primitives for generating more efficient

code for PCN programs.

* "array" module: added "pack/4" and "unpack/4". "array:put/4" stores

next untouched index in confirmation argument.

* "io:read_lines_bounded" didn't close the chunk-reading input

stream on EOF, resulting in deadlock.

* Pass linker options to disable BIT/IBT on OpenBSD, if supported.

* Replaced some uses of certain libc functions to avoid patronizing

OpenBSD linker warnings.

* Special thanks to Kon Lovett for detecting several build problems

and bugs in the Mac-specific runtime library.

Version 15:

* [PCN] Fixed a bug in the PCN translator that handled pre-translation

of "fmt:format/3" incorrectly.

* Fixed a bug in the FGHC translator that caused variables to be

clobbered that where introdcued by previous guards in the same

clause.

* "return" in lambda-expressions is handled properly.

* "list" module: added "zip/3" and "search/3".

* Exposed "unify/3" as FGHC and PCN primitives.

* Added "array" type test for FGHC and PCN guards.

* [PCN] fixed missing or broken translation of certain expression

operators.

* [PCN] fixed translation of zero-argument expression operators

("rnd/0").

* [PCN] removed limitation of maximally 5 arguments to C calls.

* [PCN] fixed implicit boxing foreign argument passing for certain

cases.

* [PCN] The "exports" directive is now explicitly disallowed in PCN

code, as it is not suited to the way generated FLENG code is

indirectly called.

* [PCN] Exposed "port", "number" and "real" tests for guards.

* [PCN] Trying to call a foreign function remotely (via "@") is

detected by the compiler now.

* [PCN] Added "nodes()" builtin function.

Version 14:

* Added a translator from "PCN" to FLENG, a language in the

tradition of Strand, but with a more conventional syntax.

PCN (Program Composition Notation) is fully interoperable with

FGHC/Strand code and is equally expressive, but may be easier

to approach for those unfamiliar with Prolog syntax.

* "fmt:format/3" has been changed to take file-descriptor, a

format string and an argument list. This is deemed more useful

but is incompatible to older versions of this library.

* Replaced the "mem" library module with the "array" library,

which provides the support numerical arrays for various

number types and automatic release of unsed memory.

* Increased the maximum number of listeners to 64.

* Added primitive "thread_resource_usage/3", thanks to Kon Lovett

for contributing a MacOS-specific version.

* Added library primitive "file_modification_time/2".

* Added primitive "call_detached/2".

* All heap-traversals only include the currently allocated

chunks, not the full, unused heap.

* Allocation of floats on arm32 could incorrectly signal heap

exhaustion even in the case of still available heap space.

* Fixed various typos and broken examples in the manual

(thanks to "kenaryn" for reporting these).

* Ensure proper flags are passed to C compiler and assembler

on Linux to disable executable stack, which avoids linker

warnings (thanks to "kenaryn").

* Lookup- and jump tables have been moved into the ".data" section

to allow execution in "xonly" environments like newer versions

of OpenBSD.

* Many documentation improvements and additions.

* Fixed bug in "flengdoc" that didn't close files properly for

updated index-entries in the reference docujmentation database.

* Module objects can be sent between threads.

* Specifying an invalid argument mode in "mode" declarations

produces a meaningful error message.

* Dropped the "-n" compiler option.

* Added "-l" option to driver script to force compiling for a

specific source language.

Version 13:

* Added the "flengdoc" tool to create and query a reference

documentation database for all built-in and library predicates.

* New library modules: "match", "path", "find", "ucs" and "spec".

* Inconsistencies with non-latin letters in terms have been removed,

so source code can now contain arbitrary unicode characters.

* Clause indexing is now performed for any of the argument

positions 1 to 4 (or 1 to 3 in predicates with arity > 5),

depending on which position provides the best opportunity for

eliminating matches on argument type.

* Added secondary clause indexing for integers, generating

either a lookup table or a computed branch, increasing dispatch

performance and reducing needless matching.

* Clause selection has been optimized to dispatch first on atomic

arguments before performing normal sequential argument matching.

* Added "trace/{1,2}" to enable logging for specific tasks.

* Sometimes stale entries on the suspension stack could cause

bogus deadlock errors, the stack is now cleared on entry in

a resumed clause.

* On deadlock, the debug info for suspended clauses are shown

in the error message.

* Renamed FFI stub file name generated by driver script to

"<basename>-foreign.o".

* fghc2fl warns if mode declarations refer to non-existent

definitions.

* Fix crash when "arguments/1" declaration is used and additional

runtime-arguments are incomplete.

* Module uses are inferred now from all detectable call goals.

* The compiler produces a warning when multiple "intialization/1"

declarations are present.

* The compiler provides more meaningful error messages when

encountering invalid terms while expanding FGHC code into FLENG.

* "set" module: added "subset/3".

* "list" module: added "characters/{2,3}", "split/3", "trim/3" and

"get_prop/4", fixed broken "trim_right".

* "io" module: exposed "parse_lines/2", fixed invalid 1-character

lookahead after line-terminator in "read_lines/2".

* "app" module: "foreach/{2,3}" executes each goal in a task and

in sequential order.

* Position-independent code is now generated on all platforms.

* I/O error results are represented by a 2-element tuple,

the error number and a string holding the textual representation

of the error.

* The list of free cells is now initialized in chunks, which

reduces startup time and does not touch memory pages until

they are actually used.

* Increased default heap size to 10 MB.

* Statistics output includes peak and average memory usage.

* If the argument to "+LOGFILE" starts with "+", then output

will be appended, otherwise the file will be truncated.

* "@>=/2" and "@=</2" returned wrong result when arguments where

equally ordered, fixed bug in "@=</2" on 32-bit Arm.

* Certain primitives, when given an explicit variable as confirmation

argument expand into simpler code when used with the "&/2"

operator.

* Added the "-check" option to the "fleng" driver script.

* "get_module/2" returns the empty list if a module can not be

found instead of aborting with an error.

* Added new primitives "ticks/1", "fdup/{2,3}", "mkdir/{1,2}",

"nl/{0,1}", "program_name/1" and "directory/{2,3}".

* "app" module: added "filter/4", "maplist/4" and "compose/3".

* Parsing octal and binary number syntax in code used the wrong

numeric base.

* Handling of "otherwise" clauses now delays suspensions in the

clause head to ensure correct semantics.

* Fixed the order in which suspensions were handled, the previous

method could omit matching clauses in certain "deep" matches

of incomplete structured data.

* Fixed the interaction between "global" and "put_global" when

"global" refers to a not yet assigned global variable.

* Fixed bug in "utf_decode/3" when encountering a not completely

bound sequence.

* Fixed deadlock in "fghc2fl" on certain malformed module calls.

* Fixed reaping of child processes on BSD systems.

* Fixed a bug in the compiler that caused registers that hold

temporarily created structures during foreign calls to be

restored in the wrong order.

* Fixed handling of "otherwise" in clause indexing.

* Fixed library order to avoid linker errors when building

the compiler executables (reported to Martin Littlejohn).

* Fixed forcing of arguments in "io:transfer/{3,4}".

* Fixed bug in runtime system where string-length counts

were incorrectly fetched as signed values.

* "fmt" module: fixed bug in printing empty string in quoted

mode.

* Logging and profiling output now includes the module prefix.

Version 12:

* The FGHC front-end and FLENG compiler have been rewritten in

FGHC and the system is now fully self hosted. This means a

Prolog implementation is not required to build and use FLENG,

even though the system can still be bootstrapped from Prolog.

* "get_global/3" takes a default value as 3rd argument for handling

the case that the global is not yet defined. The old meaning

of the 3rd argument has been removed. This is an incompatible

change.

* Argument-pair expansion for conditional expressions was incorrect

when a pair was passed in only one of the branches.

* "sort" module: fixed totally broken "merge", which resulted in

an unusable "sort" operation.

* "parse" module: several bugfixes.

* "lex" module: handle EOF when scanning operator.

* "map" module: removed "replace/6", "replace" uses unification

for old value instead of assignment.

* "fmt" module: several fixes in formatting of expressions

that resulted in un-parsable text, added whitespace for unary

operators to avoid parsing ambiguities.

* Number to string conversion always adds a decimal point for

floating-point numbers, even if the fractional part is zero.

* Increased the suspension stack to 1024 elements.

* "INTERNALS" was missing in the distribution, but referenced

in the makefile (reported by Benedikt Rosenau).

* Ordering for strings didn't take the strings length properly

into account.

* Create test files in current directory instead of /tmp to

make tests work on termux (reported by Alexander Shendi).

* Removed "provide/2" declaration.

* Support for cross-compilation has been removed to simplify

the build system.

* Argument matching for predicates with arity > 4 has been

optimized and produces significantly more efficient code.

* The FGHC frontend and FLENG compiler accept "-" as in- and

output sources.

* Diagnostic compiler output is prefixed with the proper comment

syntax for the target system.

* Thanks to Kon Lovett for pointing out several bugs in the build

system.

Version 11:

* Usage information did not print the program name correctly.

* Added link to publicly available version of the Strand book

to manual (thanks to Alexander Shendi).

* Overhauled Linux signal handling to be more reliable.

* Dropped "--without-threads" configuration option, the system

now always uses the "pthreads" library.

* "map:replace" inserts entry when no previous one existed.

* "map" module: added "map_to_list/{2,3}".

* "app" module: added "take/5".

* "list" module: added "join/4".

* "proc" module: added "submit/3", "capture/3" and "pipe/4".

* "io" module: added "rate_limited_stream/3".

Version 10:

* The system has been ported to MacOS on M1 CPUs.

* Ordering guards ("@>", "@<", "@>=" and "@=<") now suspend on

unbound variables, as in Strand.

* Removed computation types "@<", and "@>" for "compute/4".

* The conditional operator handles conjunctions of guards in the

condition position.

* Calls to the internal matching primitive didn't preserve the

argument registers which could result in a memory leak.

* Fixed a bug in the scheduler related to idle-suspensions, which

could result in an assertion being thrown.

* Argument pair expansion is handled in conditional expressions

properly.

* Added "global/2".

* The "include/1" declaration accepts lists and doesn't require a file

extension.

* Added "arguments/1" declaration which allows defining run-time

command line arguments at compile-time.

* Removed the "threads" declaration, use "-arguments('+THREADS <N>')"

instead.

* Uses saved program states for the FGHC and FLENG compilers when

SWI Prolog is used, which needs fewer files to install and speed

up startup of the compilers.

* Inlining of simple predicates is now done.

* Calls to standard libraries provided by the base system are

now faster by using predefined "entry-point" information.

* Added compiler options "-e" and "-link" to create and use entry-point

information in user code.

* "app" module: added "any/3", "every/3" and "sequence/{4,5}".

* Most higher-order predicates from the "app" module are now

expanded in-line to avoid dynamic goal lookup and invocation.

* Obviously circular variable references in assignments and unifications

generate a compile-time error now.

* "list" module: added "last/2", "delete/3", "prefix/3" and

"reverse/{2,3}".

* "io" module: added "write_lines/3".

* "mem" module: added "copy/{4,5,6}" and "get_blockwise/4".

* "append/{2,3}" and "member/3" have been moved into the "list"

module and must now be invoked with the "list:" module qualifier.

* "kill/3" unifies its last argument with "error(ERRNO)" on failure.

* "&/2" expands into in-line task creation for local calls thus

avoiding dynamic lookup.

* The GHC->FLENG-translation catches redefinitions of certain internal

operators.

* Releasing long variable-chains tries harder to reduce stack-pressure.

* Increased default heap size and goal-buffer to 5MB and 100k,

respectively.

* Fixed bug in "io:transfer/4".

Version 9:

* Added support for Mac OS X (Darwin) on Intel hardware.

* Added the "foreign/1" declaration which automatically generates

C wrapper code for foreign function invocations and foreign struct

accessors.

* Added primitives "halt/0", "statistics/1", "heap_statistics/1",

"write/{1,2}" and "unify_with_occurs_check/3".

* Added guard "remote/1".

* "unify/3" now performs a "safe" unification: bound variables during

recursive unification are undone if the full unification fails.

* Moved result argument in "unify/3" to the end position for consistency

with other primitives.

* Added "->"/2 conditional expression operator.

* Added memory consumption of floats and port objects to heap

statistics log.

* Expansion of extended pair arguments using "+" notation was not

performed correctly in all situations.

* "=:=/2" and "\=:=/2" guards did not force their arguments.

* Fixed two memory leaks in the remote-variable protocol - remotely

accessed variables where not reclaimed after they were resolved

(Thanks to "a88" for test code that triggered these leaks.)

* Fixed bug in ordering-comparison of floating-point numbers.

* Fixed bug in low-level implementation of struct-field accessors

that resulted in a memory leak.

* Fixed stack-handling in the RISCV runtime system.

* Invalid numbers in string-to-number conversion are properly shown

in error messages.

* Fixed bug in float-detection code used in string-to-number conversion.

* Fixed an invalid float-value allocation that could cause misaligned

float values on 32 bit platforms.

* Decoding of UTF input streams performed overly long lookahead.

* Fixed possible stack-misalignment in thread setup.

* Added a workaround for implementations of "kqueue(2)" that do not

detect EOF in input files (NOTE_EOF), which would result in

hangs when repeatedly reading from files.

* Added "module/1" declaration.

* The execution statistics of synthesized predicates generated by

the FGHC/Strand->FLENG translation are now merged with their

parent predicates in profiling reports.

* The documentation for "kill/{2,3}" had PID and signal argument

swapped.

* "proc" module: the exit status of a process terminated by a

signal is reported as a negative exit code.

* "proc" module: renamed "read/2" and "write/2" to "capture/2" and

"submit/2", respectively.

* "list" module: added guards to "cut/5", "take/4" and "drop/3"

that are needed to make them deterministic, added "scan/5",

"search/5", "trim_left/3" and "trim_right/3".

* "map" module: added "lookup/4".

* "io" module: added "transfer/{3,4}".

* "scan" module: added "word/3".

Version 8:

* A git(1) repository of the sources are available now at

https://gitlab.com/b2495/fleng

* Fixed creation of "version.pl" when building with the sources

retrieved from the git repository (reported by "matekai").

* The FGHC front-end now accepts Strand source code, which can be

considered a subset of FGHC.

* Added ":=/2" operator.

* Block comments ("/* ... */") are now officially supported.

* Strand's "machine" and "exports" declarations are accepted.

* Renamed "float/1" guard and expression operator to "real/1",

for concistency with Strand, renamed "float_integer_part/1"

and "float_fractional_part/1" accordingly. The old names are

still valid but deprecated.

* Added "struct" declaration for convenient generation of tuple-field

accessors.

* The "occurs check" to detect circular references when

unifying variables is no by default disabled due to the

signifcant performance impact. It can be enabled at run-time

using the "+OCCURS_CHECK' runtime option.

* Renamed "string_to_float/2" to "string_to_real/2". The old

name is still supported but deprecated.

* Added primitives "real_to_list/2" and "list_to_real/2".

* Added support for module data type: added "module/1" guard.

* Added module-related primitives "get_module/2", "module_name/2",

"module_exports/2" and "all_modules/1".

* Added Strand's "run/2" primitive.

* Added support for KL1 "extended pair" notation.

* Added "chdir/1", "chmod/2", "close_file/2", 'delete_file/2",

"randomize/1", "rmdir/1", "deref/1", "cancel_timer/1",

"restart_timer/2", "signal/2", "kill/2" and "kill/3".

* "signal/2" also accepts an integer instead of a signal name.

* "randomize/2" did not fully derefence the seed argument.

* "list_to_tuple" was not handling tuples of length one correctly.

* Sequencing using the "&/2" operator where the first form is

a primitive with an optional confirmation argument is

compiled in a more efficient manner.

* Sequencing a compound term like "(X, Y) & Z" now does the

correct thing by executing X and Y in parallel (it was previously

treated like "X & Y & Z").

* Invalid expression operators and constant computations now

trigger a more meaningful error.

* Removed requirement for static linkage on Linux systems that

are based on musl libc (e.g. Alpine).

* Fixed handling of addresses in AArch64 assembly (runtime and

geenrated), which could confuse the runtime-linker on Linux.

* Handle "otherwise" guard before any other guards in the same

clause to ensure textually preceding clauses are fully matched.

* Repaired broken handling of profiling information and combined

yield/listen counters into one.

* Fixed nonexistent handling of SIGPROF on Linux.

* Documented "-cflags" and "-libs" options to "fleng" driver

script, also added missing description of "-p" to man page.

* "parse" module: renamed "parse_expression[s]" to "parse_term[s]",

added "parse_term_list/{3,4}", made "vtag" argument optional

(defaults to thread ticks). "parse_terms" also accepts a file

descriptor as input argument, now.

* "app" module: added "foreach/2'.

* "list" module: added "slice/5".

* "set": added "equal/3".

* Added "scan" parser library module.

* Fixed bug in unification of remote-port instances.

* Fixed a bug in the compilation of head-matches that could cause

faulty ref-counts in certain situations.

* Conversion of strings and character-lists in primitives didn't

check argument types thoroughly enough.

Version 7:

* Added a statistical profiler for FGHC/FLENG code, with new

compiler option "-p" and runtime option "+PROFILE".

* Fixed a bug in nested matching of structured terms where inner

data calls could incorrectly succeed in the presence of

suspensions.

* Fixed a bug where signal-handling could cause hanging on Linux.

* Fixed a ref-counting bug in local assignment of remotely

exposed variables.

* Added "rnd/1" computation and expression function.

* The "--" after initial runtime options on the command line of

compiled programs was not correctly skipped.

* Functions for accessing thread-global variables have been

exposed to be usable from foreign code.

* Added "mode" and "provide" declarations.

* Added manual page for runtime options fleng(7).

* "fmt" module: dispatching for "~s" format-spec was ambiguous

at could result in wrong matches.

* "mem" module: most operations got an optional index argument.

Version 6:

* The translation of FGHC guards to FLENG has been fixed to

correctly implement the semantics of clause-resumption in the

presence of multiple complex guards. This both simplifies the

compiler and produces more efficient code.

* RISC-V (RV64IMAFD) is now supported as a target architecture

(experimental).

* Support for "tasks" was added, which allows (possibly nested)

groups of processes to be run with a way of getting information

when all processes in the group have completed execution.

* Process cleanup is now done properly when the last thread

terminates normally.

* When cross compiling by using the "--target" configuration option,

the operating system is inferred from the target triple.

* When cross compiling, no compiler checks are done during

configuration.

* "apply/2" and "call/1" now allow direct invocations of primitive

goals by synthesizing intermediate goals as necessary in most cases.

* Added new primitives "merger/2", "call{2,3}", "environment/1" and

"file_size/2".

* Arithmetic expressions and "compute/{3,4}" have been extended to

support "tan", "log", "exp", "**", "atan", "sign", "abs",

"float_integer_part" and "float_fractional_part" math operators

convering all functions required by ISO Prolog now.

* Added the "&/2" operator to conveniently run goal sequentially

using tasks.

* "file_type/2" unifies the result with an error indicator on

failure.

* Bugfix in ordering relation for tuples with different head.

* Fixed an unhandled corner case when a variable owned by another

thread was locally bound while the read-request is still pending.

* Fixed a bug where event-listeners on Linux could get lost when

another event was triggered.

* The implementation of "idle" guards has been overhauled

to work properly when used with other guards and in combination

with other possibly suspending clauses in the same group.

* Ordering comparison for floats was broken.

* Fixed some bugs in the assembler runtime for ARM.

* The FGHC compiler issues warnings for some cases where goal

head arguments are overlapping and no "otherwise" clause is

used.

* "uses" declarations are not needed anymore when a process is

invoked directly for an external module. "uses" is still

required when dynamic calls are used and the target is a

computed goal.

* "fmt" module: writing the empty list using the "~s" format

specifier writes an empty string.

* "io" module: "io:read_lines/2" handles lines terminated by

CR+LF transparently. Added "io:read_lines_bounded/3".

* "map" module: "map:keys/{2,3}" and "map:values/{2,3}" return

their results in order, sorted by keys.

* "app" module: added "app:take/4" and "app:drop/3".

* "list" module: added "list:iota/{3, 4, 5}".

* "mem" module: added some more predicates.

* "proc" module: added "proc:execute/2" and "proc:shell/2".

* Division by zero on x64 caused segmentation fault instead of

aborting with error.

* Added "-cflags" and "-libs" options to the "fleng" driver script.

* Several performance improvements.

* The use of native threads can be disabled at configuration time.

* Added a new chapter to the manual with some useful programming

tips.

Version 5:

* Changed licensing to public domain.

* Added "-I" option to "fleng" to add include paths.

* Added "thread/1" declaration to hardcode number of threads.

* General tuple syntax ("{...}") is now supported.

* Moved "write_char_stream/2", "write_byte_stream/2",

"read_char_stream/2" and "read_byte_stream/2" into a separate

library ("io"), added "read_lines/2", and "read_byte_stream_chunked/3".

* "signal/3" keeps the signal handler active and delivers a stream

of counts.

* Dropped "get_module/2", it has no real use.

* New primitives "idle_thread/1", "get_global/3", "log/2",

and "restart_timer/3".

* Extended "fleng-utils.h" with some functions to construct

character lists and convert string-like objects to C-strings.

* "app" module: added "mapreduce/4".

* Debug info used for logging is now restricted to modules compiled

with the "-d" option.

* Inline-caches for holding module-resolutions of explicit inter-module

calls are now shared, so the first call will resolve all additional

calls to the same predicate appearing in the current module.

* C runtime is now compiled with "-fwrapv -fno-strict-aliasing" for

correctness.

* Unification using "=/2" is now checked in FLENG as well as in

FGHC.

* Format strings in calls to one of the "fmt:format" predicates

are now precompiled to give better error detection and reduce

the parsing overhead at run time.

* "file_exists/2" did not force the filename argument correctly.

* Fixed totally broken event-processing on Linux.

* "fmt" module: removed variant of "format/3" with the first arg being

a file to make it less ambiguous (required for format-string

precompilation).

* "list" module: added "split/4" and "scan/4".

* "parse" module: renamed "parse_module/4" to "parse_expressions/4",

fixed a bug in "parse_expressions/4" that caused an error on end

of input.

* "sys" module: added an additional parameter to "attach/3", added

"detach/3".

* "proc" module: added "write/2" and "pipe/3", renamed "capture/3" to

"read/2".

* Conversion of numbers using "number_to_list/4" was broken for bases

greater than 10.

* Matching of complex ground literals in clause heads is now more

time and memory efficient.

* "cancel_timer/2" detects now when the timer already expired.

* The default stack size for threads uses a fixed value (500kb) instead

of using the system default.

* The "plot" script did not handle multiple runs correctly, now only

the last run in a log file holding data for separate runs is used

for plotting data.

* Stack usage is somewhat reduced when releasing large data structures

that can be gbarbage collected.

* If forwarded data exceeds the available space for inter-thread

messages a placeholder variable is used to retrieve the rest on

demand.

* "Detached" message port files are cleaned up on termination.

* Fixed processing of signals on Linux when a process sleeps,

waiting for events.

* The error for a missing process definition shows name and arity in

the error message.

* "halt/1" does proper termination clean up.

Version 4:

* Added "+LOGX" runtime option to only log explicit calls to "log/1".

* The values for the runtime options "+HEAP" and "+GOALS" accept

multiplier suffixes.

* In FGHC "=/2" signals an error when unification fails.

* Added the "list" and "app" library modules.

* Added "max/2" and "min/2" expression operators for "is/2" and

"compute/4".

* Added support for periodic timers ("clock/3").

* Added "include/1" declaration (for both FLENG and FGHC).

* The FGHC->FLENG and FLENG->ASM compilers can now be run under

the "YAP" Prolog system.

* The assembler code generated for x86-64 now produces AT&T syntax

and can be assembled with the GNU assembler, so "nasm" is not any

longer needed.

* The "fleng" script allows specifying the linker to be used to

produce the final executable.

* Added the "apply/2" primitive as a more flexible method for

producing calls at run time.

* Allow a variable in goal position as a shortcut for "call/1".

* Added new primitives "compare/3", "append/2", "write_byte_stream/2",

"write_char_stream/2", "delete_file/2", "rmdir/2" and "chmod/2".

* "fleng.h" and "fleng-utils.h" can now be used in C++ code.

* Renamed "write_block" and "read_block" to "write_file" and

"read_file", respectively.

* Fixed several bugs in the "map" library module, added

"list_to_map/{2,3}".

* The "plot" utility scales the X axis to make the output more

readable and also accepts the "-max" option to control the scaling.

* Logging and debugging output cuts off output once it reaches a

certain length.

* Unification performs an occurs-check to avoid creating circular

references.

* Fixed padding bug when interning strings.

* Each thread has its own internal string buffer for temporary

strings, as it should be.

* "open_file/3" now properly opens existing or creates new files.

* Added "keysort/2" to the "sort" library module.

* Added support for exposing a thread's message port to allow

(reasonably) simple inter-process communication (see the "sys"

library module for details).

* Fixed a bug in the scheduler that caused excessive delays when

continuously waiting for input events.

Version 3:

* Added support of AArch64.

* Several bugfixes in Linux event-handling code.

* Corrected detection of "-no-pie" to only apply to x86-64 in

configuration script.

* Fixed installation when used in combination with SWI Prolog.

* Fixed incorrect translation of "otherwise" FGHC guards when combined

with other guards.

* Added primitives "string_to_byte_list/3", "cancel_timer/2", "chdir/2",

"file_exists/2", "getcwd/1", "getenv/2", "file_type/2", "readlink/2",

"get_global/2" and "put_global/3".

* Changed "timer/2" to "timer/3', which produces an additional identfier

result.

* Increased message-port size to 4kb.

* Added support for detached message ports (see "sys.ghc" for more

information).

* Fixed "length/2", which was totally broken for lists (doh).

* Threads could sometimes terminate too early, even with inter-thread

messages still being in flight, a more robust algorithm tries to ensure

that threads never shut down while messages are still pending processing.

* The empty lists is now treated as a empty (null) string, when used

as argument to a primitive that requires a string or character list.

* Character lists were not correctly dereferenced when containing variable

references in primitives that require strings or character lists.

Version 2:

* Typo fix in "configure" script (reported by Mario Goulart).

* Added missing "VERSION" and "fleng.mdoc" files to distribution

archive (reported by "sytse").

* "-no-pie" is added when generating executables on all platforms

if the C compiler supports it (reported by "sytse").

Version 1:

* Initial release