Skip to content

Instantly share code, notes, and snippets.

@eli-oat
Forked from RickCarlino/see.md
Created June 26, 2021 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eli-oat/72efb4bdad3f1f967645e30e8d2a345a to your computer and use it in GitHub Desktop.
Save eli-oat/72efb4bdad3f1f967645e30e8d2a345a to your computer and use it in GitHub Desktop.
Retroforth SEE implementation (sort of)

dump - A simple way to peek memory addresses.

Provides a word called dump.

Output looks like this:

> [ 'Hello,_world! s:put nl ] dump
3B9F: 0x801
3BA0: 0xE5D
3BA1: H
3BA2: e
3BA3: l
3BA4: l
3BA5: o
3BA6: ,
3BA7:
3BA8: w
3BA9: o
3BAA: r
3BAB: l
3BAC: d
3BAD: !

dump expects a single address on the top of stack.

dump prints all the cells the follow it until it hits 0x0.

dump stops printing cells when a 0x0 value is encountered.

Implementation

Accumulator

I create a private accumulator variable and helpers. The accumulator holds the address of the cell I want to dump:

{{
  'current-cell var

  :fetch-cell     (-a) @current-cell fetch ;
  :increment-cell (-)  @current-cell n:inc !current-cell ;
  :cell-is-null?  (-f) fetch-cell #0 eq? ;

Cell Presentation

Then a helper to determine if a char is printable.

  :is-char? (n-nf) dup #31 #127 n:between? ;

When a char is printable, I will call c:get and make a newline:

  :printable (c-) c:put nl ;

If the char is not printable, print it as hex with a 0x in front.

  :non-printing (n-) '0x s:put hex n:put nl decimal ;

Then we create a word that contextually decides which way to print a value based on if it is printable or not:

  :print-cell-content (-)  is-char? &printable &non-printing choose ;

Lastly, we need a way to pretty-print the cell's address on the left side of the screen.

  :print-cell-address (a-a) @current-cell hex n:put ':_ s:put ;

dump A Single Cell

To dump the next memory address, I fetch the accumulator's value and then increment it. I print the memory address and contents to the screen in a way that makes sense.

  :raw-dump (-)
    fetch-cell
    print-cell-address
    print-cell-content
    increment-cell
  ;

  :dump-next (-f)
    raw-dump
    cell-is-null?
  ;

Finally, the Implementation

---reveal---

:dump-s  (a-)
  !current-cell &dump-next until
;

:dump (na-)
  !current-cell
  &raw-dump times
;

}}

Tests

Now that we have a working dump inplementation, let's try inspecting different types of data:

[ 'Hello,_world! s:put nl ] dump
'Works_on_anything          dump
here #100 -                 dump
&c:put                      dump
'No_errors. s:put nl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment