git @ Cat's Eye Technologies UampirNexol / master doc / Syntax-of-UampirNexol.md
master

Tree @master (Download .tar.gz)

Syntax-of-UampirNexol.md @masterview markup · raw · history · blame

Syntax of UampirNexol

This document defines the syntax of UampirNexol, a typed functional language for machine-language-level program construction.

The definition is illustrated with examples used as test cases.

These tests are written in Falderal format. Each indented code block (generally preceded by a description) represents a test. All the lines of the code block up until the ===> line give the input to be tested; the text after ===> gives the expected output. ???> gives an expected error message, which is permitted to be a partial (substring) match.

Because the expected results are dumps of internal AST structures, these tests (or at least their expected outputs) are non-normative.

Parsing

-> Tests for functionality "Parse UampirNexol Expression"

-> Functionality "Parse UampirNexol Expression" is implemented by
-> shell command "bin/uampirnexol parse %(test-body-file)"

Demonstrating basic syntax, including line comments and hexadecimal literals.

LDA# 12;
INX;  // this is a comment
LDA# 0x12 ;
INY
===> Seq (Apply LDA_i (IntLit 12)) (Seq INX (Seq (Apply LDA_i (IntLit 18)) INY))

Syntax of a conditional.

if C (LDA# 0; TAX) else TAY
===> If (IsSet C) (Seq (Apply LDA_i (IntLit 0)) TAX) TAY

Syntax of literal locations.

STA @0x0400
===> Apply STA_a (Loc (Address 1024))

Syntax of a repeat..until loop.

repeat (LDA# 0; TAX) until ~C
===> Repeat (Seq (Apply LDA_i (IntLit 0)) TAX) (IsUnset C)

Syntax of a while..do loop, which is just syntactic sugar.

while C do (LDA# 0; TAX)
===> If (IsSet C) (Repeat (Seq (Apply LDA_i (IntLit 0)) TAX) (IsUnset C)) Skip

Syntax of a let..in block.

let foo = 0 in LDA# foo
===> Bind "foo" (IntLit 0) (Apply LDA_i (VarRef "foo"))

A let..in block may have more than one binding.

let foo = 0, bar = 1 in LDA# foo
===> Bind "foo" (IntLit 0) (Bind "bar" (IntLit 1) (Apply LDA_i (VarRef "foo")))

Syntax of routine and call, including typical usage in let, and precedence.

call routine (LDA# 0; TAX)
===> Call (Routine (Seq (Apply LDA_i (IntLit 0)) TAX))

call (routine LDA# 0); TAX
===> Call (Seq (Routine (Apply LDA_i (IntLit 0))) TAX)

let foo = routine (LDA# 0; TAX) in call foo
===> Bind "foo" (Routine (Seq (Apply LDA_i (IntLit 0)) TAX)) (Call (VarRef "foo"))

Syntax of extern, including typical usage in let.

let foo = extern @0xc018 : State[A/] -> State[A,X,Y/] in call foo
===> Bind "foo" (Extern (Loc (Address 49176)) Routine(State[A/] -> State[A,X,Y/])) (Call (VarRef "foo"))

Note the precedence of ; is higher than that of while.

while C do LDA# 0; TAX
===> If (IsSet C) (Repeat (Seq (Apply LDA_i (IntLit 0)) TAX) (IsUnset C)) Skip

while C do (LDA# 0); TAX
===> If (IsSet C) (Repeat (Seq (Apply LDA_i (IntLit 0)) TAX) (IsUnset C)) Skip

(while C do LDA# 0); TAX
===> Seq (If (IsSet C) (Repeat (Apply LDA_i (IntLit 0)) (IsUnset C)) Skip) TAX

These are syntactically valid, but will trip a type error in a later phase.

LDA#; TAX
===> Seq LDA_i TAX

STA; TAX
===> Seq STA_a TAX

STA C
===> Apply STA_a (Loc C)

repeat CLC until @0x0400
===> Repeat CLC (IsSet (Address 1024))