With this breakdown of the available modes and parameters you will find out that
fry has got several spices under the hood for you to better season your runtime.
The CLI front-end offers some modes of operation:
fry [OPTIONS]read-eval-print-loop (REPL)
fry [OPTIONS] FILE [ARGS]execute a FatScript file
fry [OPTIONS] -b/-o OUT INcreate a bundle
fry [OPTIONS] -f FILE...format FatScript source files
Here are the available option parameters:
-a, --astprint abstract syntax tree only
-b, --bundlesave bundle to outfile (implies -p)
-c, --clockenable time and stats log (benchmark)
-d, --debugenable debug logs (implies -c)
-e, --errorcontinue on error (toggle)
-f, --formatindent FatScript source files
-h, --helpshow this help and exit
-i, --interactivestart REPL after file execution
-k, --stack #set stack depth (frame count)
-m, --metashow info about this build
-n, --nodes #set memory limit (node count)
-o, --obfuscateencode bundle (implies -b)
-p, --probeperform static analysis (dry run)
-s, --savestore REPL session to repl.fat
-v, --versionshow version number and exit
-w, --warrantyshow disclaimer and exit
Note that when in the REPL mode or when using
-e option (continue on error) is toggled on by default.
fry manages memory automatically without pre-reservation. You can limit memory usage by specifying the number of nodes with CLI options:
-n <count>for an exact node count
-n <count>kfor kilonodes, count * 1000
-n <count>mfor meganodes, count * 1000000
fry -n 5k mySweetProgram.fat restricts the app to 5000 nodes.
The garbage collector (GC) runs automatically when there are 256 nodes left before the final memory limit is reached (GC premonition). You can also invoke the GC at any time by calling the
runGC method of system lib from the main thread.
Using a negative node count deactivates the garbage collector but still sets the memory limit to the absolute value, which can be useful for debugging purposes.
Bytes estimate (x64)
Each node on a 64-bit platform uses approximately ~200 bytes. The actual node size depends on the data it holds. For example, the default limit is 10 million nodes, your program can use up to 2 GB of RAM when reaching the default limit.
--clock option to print the execution stats to have a better understanding of how your program is behaving in practice.
There are two embedded commands for checking memory usage at runtime:
$nodesUsagecurrently allocated nodes (O(1))
$bytesUsagecurrently allocated bytes (O(n))
checking the currently allocated bytes is an expensive operations as it needs to traverse all nodes to check the actual size of each one
The maximum stack depth is defined in
parameters.h, however you may be able to customize the stack size up to a certain point using CLI options:
-k <count>for an exact frame count
-k <count>kfor kibiframes, count * 1024
Run commands file
fry looks for a
.fryrc file on the same path of the program file and, if not present, also on the current working directory. If found, it is executed as a "precook" phase to set up the environment for the program execution.
Memory management with .fryrc
You can use the
.fryrc file to define the memory limit for your project without needing to specify it as a CLI argument. To do this, you can use the
setMem method provided by the system lib, like this:
_ <- fat.system setMem(64000) # sets 64k nodes as memory limit
CLI options are applied first, except for the memory limit. During the precook phase,
fry uses the default limit of 10 million nodes, regardless of the CLI option. If you define a memory limit in the
.fryrc file, that limit takes effect from that point on and overrides the CLI option for the whole execution. If the
.fryrc file does not set a memory limit, the CLI option takes effect after the precook phase.
The precook scope is invisible by default. After the
.fryrc file is executed, a fresh scope is provided for your program, which allows you to test your code with a very low limit of nodes when using a
.fryrc file without affecting the node count. This also prevents the
.fryrc namespace from clashing with your program's global scope. However, if you want to keep the entries declared in
.fryrc in the global scope for configuration purposes, you can call the embedded command
$keepDotFry somewhere in the
Another possible use, other than setting up memory limit, is to pre-load common imports, for example the standard types:
$keepDotFry _ <- fat.type._