|
||
---|---|---|
arl | ||
ca1 | ||
libmpdec | ||
subprojects | ||
targets | ||
.gitmodules | ||
README.md | ||
WORDS.md | ||
blblast.py | ||
build.sh | ||
lextest.arl | ||
meson.build | ||
meson_options.txt |
README.md
ARL and CAOS
ARL (Alexis' Reverse LISP) is a stack-based language similar to RPL. CAOS is a CAlculator Operating System consisting of the ARL interpreter and a user interface written in ARL.
Building and loading the interpreter
Building requires meson, ninja, and a compiler for the target platform.
./build.sh unix
to build for unix-like systems./build.sh ca1
to build the CA-1 firmware.
The unix build has some useful command-line options for local testing.
The CA-1 build requires m68k-elf-gcc on the path. The CA-1 also requires a
bootloader. It uses a6boot which
is a UART flash bootloader for m68k. Prebuilt images of the bootloader are
provided in ./targets/ca1
. Use bootloader.hex
to flash onto a chip directly
using an external flash programmer; use bootloader_inplace.srec
to flash the
bootloader with itself (note this is dangerous - there is no protection against
corrupting itself if it crashes!).
The CA-1 build will emit three .srec files for use with this bootloader:
arl.srec
containing the interpreter, ca1.srec
containing the calculator ARL
code, and full.srec
containing both. Once the full image has been flashed
once, the CA-1 ARL code may be updated by itself by reflashing only ca1.srec
;
this is much faster. Note that the offset of this in flash depends on the
build so this can only be used if the interpreter code did not change.
ARL basic intro
ARL is stack-based. Your program is run simply by parsing tokens in sequence and executing them. If they define data, it is pushed to the stack; if they specify code, it is executed.
"Hello, world!\n" puts
This simple sequence first pushes the string "Hello, world!\n"
to the stack,
then looks up the word puts
and executes the attached function.
Data types
ARL is dynamically typed and garbage-collected. The following data types are defined:
-
int
is a 64-bit signed integer. Integers start with#
, an optional radix specifier (x
,b
, oro
), then the number. C-style character literals are also integers. Examples include:#-4321
,#xFFFE
,#b10101
,'f'
. -
real
is a decimal floating point type implemented by a forked libmpdec. Syntax looks like the typical numeric/floating point syntax:1234
,-69.420
,1.337e3
. When areal
and anint
collide, the result is areal
. ARL's default precision can fully represent all possibleint
values asreal
. -
complex
is a pair ofreal
s forming a complex number, with aj
between:0.707j-0.707
. (This is not implemented yet.) -
string
is a string of ASCII characters or bytes. A string is not considered a scalar so it may not be contained in a vector. Strings know their length, so zero is valid content. Syntax is like C strings. -
list
is a list of values. In memory, they are stored as a linked list. Syntax is a series of values in braces:{ 1 2 3 4 }
. List contents may be any type and they need not be homogeneous:{ 1 #2 j3,4 { 5 6 } }
. List are created by executing the code between braces in a new stack, so you can calculate list contents in-place:{ 1 dup dup + dup dup + }
is{1 2 4}
. -
array
is a fixed-size 1D or 2D array. Created with thearray
word. -
program
is an ARL program, which may itself be held on the stack. It is contained between double angle brackets:<< sq swap sq + sqrt >>
(This is not implemented yet.)
Non-scalars (string, list, vector, program) are held by reference, not by
value. If you duplicate one you have two pointers to the same object. A copy
word is provided to make a clone. (This is not implemented yet.)
Words
Words are defined with Forth-like syntax: a colon, then the name, then the
definition, then a semicolon: :hypot sq swap sq + sqrt;
Because ARL has very sparse syntax and most operators are implemented as words, most characters are valid in an identifier. Reserved byte values are:
- ASCII control characters: bytes 0 through 31.
0
through9
and.
but only at the beginning of a word.:
or;
which delimit definitions.@
,#
,$
,'
which are reserved type sigils.(
and)
which create comments.{
,[
,]
, and}
which create lists and vectors.- Whitespace characters:
\f
,\n
,\r
,\t
,\v
The following additional contraint applies: <<
or >>
at the beginning of
a token is always parsed as the syntactic feature, not a word. <<<
for
example is parsed the same as << <
.
For a list of words built into ARL, see WORDS.md.
Program and variable definition
-
:
: Define a word. Forth-style syntax::name statements...;
. Added to the global namespace. -
->
: Evaluate a series of variable names after this word, then pop a value from the stack for each one and define it in a new local with this name (2 3 -> two three
). Parsing of variable names stops at the first non-word or a newline.Control statement "mini-scopes" (if, for, while) can read and write locals already defined in the parent scope, but any locals they newly define are lost when they go out of scope (like C).