Skip to content

Latest commit

 

History

History
318 lines (267 loc) · 7.51 KB

File metadata and controls

318 lines (267 loc) · 7.51 KB

b4i macro and interactive commands test suite

#+tanco-format: 0.2

About this file

This file demonstrates the macro and interactive commands. Currently these interactive features are present only in the lil implementation (`mb4.deck`). The macros are also available in the pascal version’s assembler.

TEST b4i.bug.mlatu : bug: b4i treated first two chars as opcode

> :mlatu rt
> 2 3 mlatu ?d /q
ds: [2 3]

TEST b4i.addr : Interactive assembler: assemble to any address

> :100 ^A ^B
> ?100
^A ^B .. .. .. .. .. .. .. .. .. .. .. .. .. ..
> :104 ^C ^D
> ?100
^A ^B .. .. ^C ^D .. .. .. .. .. .. .. .. .. ..
> :100 ^X ^Y
> ?100
^X ^Y .. .. ^C ^D .. .. .. .. .. .. .. .. .. ..
> ?104
^C ^D .. .. .. .. .. .. .. .. .. .. .. .. .. ..

TEST b4i.continue : Continue assembling from previous position

> :100 ^A ^B ^C ^D
> ?100
^A ^B ^C ^D .. .. .. .. .. .. .. .. .. .. .. ..
> : ^E ^F
> ?100
^A ^B ^C ^D ^E ^F .. .. .. .. .. .. .. .. .. ..
> : ^G ^H
> ?100 /q
^A ^B ^C ^D ^E ^F ^G ^H .. .. .. .. .. .. .. ..

Using :address sets the assembly position to a specific address. Using just : (with no address) continues assembling from where the previous line left off. This allows multi-line assembly without having to manually track addresses.

TEST b4i.invoke : invoke register

> :A lb 'a lb 'e io rt
> :B lb 'b lb 'e io rt
> ?A
00000100
> ?B
00000106
> ^A ^B /q
ab

using ^ with a register name should trigger the register

comments

this doesn’t work because the old test parser can’t andle the “#”

Macros

TEST macro.if-else-then : if/else/then macro

> :E lb 'e io rt
> :T c1 .i lb 'T ^E .e lb 'F ^E .t rt
> ^T /q
T

if the top of the stack is non-zero, execute the first block otherwise, execute the second block

TEST macro.while-do : while/do macro

> :E lb 'e io rt
> :T lb 'a !A lb 03 .w du .d c1 +A ^E c1 sb .o rt
> ^T /q
abc

while the top of the stack is non-zero, execute the block decrement the top of the stack each iteration

TEST macro.for-next : for/next macro

> :E lb 'e io rt
> :T lb 03 .f cd du dc lb 'a ad ^E .n rt
> ^T /q
dcb

execute the block a fixed number of times the counter is stored on the control stack

TEST macro.linked-list : .^ : linked list

> :100 .^ .^ .^ .^
> ?100 /q
.. .. .. .. .. ^A .. .. ^D ^A .. .. ^H ^A .. ..

creates a linked list in little endian format each node points to the previous node’s address. The first four bytes are the null value `0x00`, then `0x100` (`00 01 00 00` in little endian format). then `0x104` (`04 01 00 00` in little endian format). then `0x108` (`08 01 00 00` in little endian format).

interactive get/set for labels

TEST b4i.getset : get/set (b4i)

> :int 04 03 02 01
> @int ?d
ds: [1020304]
> zp 5 !int ?d
ds: []
> @int ?d /q
ds: [5]

TEST b4i.semicolon : ; exits assembler mode

> :twice c2 ml rt ; 5 twice ?d /q
ds: [A]

; always exits the assembler (back to calculator mode) and invokes ^] (which by default simply returns). This allows defining a word and calling it on the same line.

TEST b4i.assemble-at : :!name assembles at label address, ; restores HERE

> :buf :+10
> :main rt
> :!buf 'h 'e 'l 'l 'o ;
> ?buf
00000100 +H +E +L +L +O .. .. .. .. .. .. .. .. .. .. ..
> `main ?d /q
ds: [110]

:!name saves the old HERE pointer, sets HERE to the address stored in label name, and enters the assembler. When ; is reached, it exits the assembler and invokes ^], which during a :! assembly restores the old HERE pointer.

TEST b4i.assemble-at-multi : :!name and ; work multiple times on one line

> :100 @[ :buf :+A @] ; ?100 :!buf "hello" ; : "etc" ; ?100
@[ .. .. .. .. .. .. .. .. .. .. @] .. .. .. ..
@[ +H +E +L +L +O .. .. .. .. .. @] +E +T +C ..

Multiple :!name ... ; and : ... ; segments can appear on a single line. Each ; restores HERE (if :! was used) or simply exits the assembler (if bare : was used), and the line continues in immediate mode.

Interactive Commands

TEST interactive.reset : /R : reset the virtual machine

> 01 02 03 ?d /R ?d /q
ds: [1 2 3]
ds: []

resets the stacks and sets ip to 100. does not clear memory.

TEST interactive.clear : /C : clear the virtual machine

> 01 02 03 ?d /R ?d /q
ds: [1 2 3]
ds: []

clears the stacks and resets memory

TEST b4i.label : `label : use label

> :lbl 'a 'b 'c 'd
> : li `lbl rt
> ?lbl
00000100 +A +B +C +D li .. ^A .. .. rt .. .. .. .. .. ..
> `lbl ?d /q
ds: [100]

pushes the address of the label onto the stack

TEST b4i.alloc.hex : :+HEX allocates that many bytes

> :aaa :+123
> :bbb
> `bbb `aaa sb ?d /q
ds: [123]

TEST b4i.hexname : edge case: names that are also lowercase hex numbers

> :def 'a 'b 'c 'd
> : li `def rt
> ?def
00000100 +A +B +C +D li .. ^A .. .. rt .. .. .. .. .. ..
> `def ?d
ds: [100]

TEST interactive.show-memory : ?m : show memory

> :100 01 02 03 04 'h 'e 'l 'l 'o
> ?100 /q
^A ^B ^C ^D +H +E +L +L +O .. .. .. .. .. .. ..

displays the contents of memory starting at the specified address

TEST bug.c.clears.dictionary : bug: /C should clear the dictionary

> :foo rt
> /p
0100:foo
> /C
> /p
> /q

TODO: Additional tests for other macros and interactive commands

/e (run to end)

##+name: interactive.run-to-end ##+begin_src b4a = /e : run to end

executes instructions until a return is encountered

##+end_src

// (goto)

##+name: interactive.goto ##+begin_src b4a = // : goto

jumps to the address stored in the "@\" register

##+end_src

string literals

TEST b4a.string.raw : "abc" : raw string

> :100 "abc def"
> ?100 /q
+A +B +C @@ +D +E +F .. .. .. .. .. .. .. .. ..

TEST b4a.string.len-prefixed : ."abc" : length-prefixed string

> :100 ."abc def"
> ?100 /q
^G +A +B +C @@ +D +E +F .. .. .. .. .. .. .. ..

TEST b4a.fwd : Using > for forward references

> :A cl >foo rt
> /f
0101>foo
> :foo c2 n1 rt
> /f
> ^A ?d /q
ds: [2 -1]

Inside the assembler, you can use the > prefix to indicate a word that is to be defined later. Note that unlike a bare word, this does not assemble an implicit cl so you must write it manually.

Meanwhile, the /f command can be used to inspect forward references that have not yet been filled in.

TEST b4a.u32 : $ for u32 hex values

> :100 lb C0 li $AA .. lb C1 li AA .. .. .. ..
> ?100
lb c0 li AA .. .. .. .. lb c1 li AA .. .. .. ..
> : lb C2 li $01020304 rt
> ?110
lb C2 li ^D ^C ^B ^A rt .. .. .. .. .. .. .. ..

Using $ in front of a number makrs