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.

Command-line arguments

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 IN create a bundle
  • fry [OPTIONS] -f FILE... format FatScript source files

Here are the available option parameters:

  • -a, --ast print abstract syntax tree only
  • -b, --bundle save bundle to outfile (implies -p)
  • -c, --clock enable time and stats log (benchmark)
  • -d, --debug enable debug logs (implies -c)
  • -e, --error continue on error (toggle)
  • -f, --format indent FatScript source files
  • -h, --help show this help and exit
  • -i, --interactive start REPL after file execution
  • -k, --stack # set stack depth (frame count)
  • -m, --meta show info about this build
  • -n, --nodes # set memory limit (node count)
  • -o, --obfuscate encode bundle (implies -b)
  • -p, --probe perform static analysis (dry run)
  • -s, --save store REPL session to repl.fat
  • -v, --version show version number and exit
  • -w, --warranty show disclaimer and exit

Note that when in the REPL mode or when using --probe, the -e option (continue on error) is toggled on by default.

Memory management

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>k for kilonodes, count * 1000
  • -n <count>m for meganodes, count * 1000000

For example, 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.

Use the -c or --clock option to print the execution stats to have a better understanding of how your program is behaving in practice.

Runtime verification

There are two embedded commands for checking memory usage at runtime:

  • $nodesUsage currently allocated nodes (O(1))
  • $bytesUsage currently 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

Stack size

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>k for kibiframes, count * 1024

Run commands file

On bootstrap, 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

Bootstrap details

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 .fryrc file.

Another possible use, other than setting up memory limit, is to pre-load common imports, for example the standard types:

_ <- fat.type._

See also

results matching ""

    No results matching ""