Decompilation
It is sometimes useful to inspect the internals of a word. There are two ways to do this:
SEE
decompiles a named word,DECOMPILE
decompiles a given XT to screen.
: simple 1 2 + . ; SEE simpleRunning this program:
[0] Literal(1) [1] Literal(2) [2] + [3] . okThe listing shows the contents of the code section for the word
SIMPLE. The numbers on the right correspond to each action compiled by Smojo into the word
SIMPLE. The
+word is a primitive word, which adds two numbers.
SEEing it shows that you can't break it down further:
see + + ok
The word
.is a compound word meaning that it is constructed out of primitives and literals. You can
SEEit too:
see . [0] (.) [1] BL [2] (.) ok
Using DECOMPILE
You can similarly decompile any XT (since the XT contains the word's code section), with the wordDECOMPILE:
' otherwise DECOMPILE [0] Literal XT: _ [1] COMPILE, [2] -> ok
Understanding Decompilations
Some further notes on decompilations:Decompilation | What it means |
---|---|
Literal |
This puts the literal, whose value is shown between the parentheses, onto the stack. Literal XTs are also indicated by Literal XT: ... |
Primitive & Compound Words |
The actual name of the primitive/compound word is shown. Compound words can be SEEn to show their component words. |
Jump |
An Unconditional Jump that moves the program to the given line in that word. For example, Jump<21>is an instruction that moves instruction to Line #21. Note: any jump past the end of the compound word will exit that word. |
CJump |
A Conditional Jump that moves the program to the given line in that word, if the top of the stack evaluates to false. For example, CJump<5>is an instruction that moves instruction to Line #5, only if the top of the stack evaluates to false. If it's true, then the program proceeds to the next instruction immediately after the CJump. Note: any jump past the end of the compound word will exit that word. |
BLOCKSand
DOES>that will be explained in later sections.
Quiz
Question 1
The wordSEEis a compound word, which uses the primitive
DECOMPILE. How could you prove this?
see see [0] BL [1] PARSE [2] DOES> [3] DUP [4] NULL? [5] CJump<11> [6] DROP [7] Literal(No such word.) [8] . [9] CR [10] Jump<2147483647> [11] DECOMPILE
DECOMPILEappears in [11] of the listing.
Question 2
Decompile the wordEXIT. Is it primitive or compound?
see exit EXIT ok
exitis a primitive word.
Question 3
Decompile this word:
: xyz EXIT ;Explain the decompilation listing:
- What happened to the primitive word for
EXIT
? Why isn't it inXYZ
's code section? Hint: isEXIT
immediate? - Were the words
:
and ; compiled into the code section ofXYZ
? Why not? Hint: Is:
fired before or afterXYZ
is defined? Is;
immediate? - What kind of jumps are there in the decompilation? Can you explain what it does?
see xyz [0] Jump<2147483647>
exitis immediate so the word
exitis not in the code section. When
exitexecutes immediately and put
Jump<2147483647>into the code section, which will unconditionally jump to the end of the word when executed.
:is not an immediate word, but comes before xyz is defined so it is not in the code section.
;is an immediate word, it is executed immediately, which causes Smojo to switch from compilation mode to interpretation mode.
Question 4
Try this word:
: three ( n -- ) 3 = if "Three!" . else exit then ;What does
THREEdo? Explain every line the decompilation listing. Can
THREEbe simplified? Test out your simplified version if so.
see three [0] Literal(3) [1] = [2] CJump<6> [3] Literal(Three!) [4] . [5] Jump<7> [6] Jump<2147483647>If the number on the top of the stack is not 3, jump to line 6, then in line 6 jumps past the word. Therefore, essentially if the number is not 3, exit the word. If the number is 3, print Three!, then jump past and exit the word. A simplified version would be:
: threeSimplified ( n -- ) 3 = if "Three!" . then ; see threeSimplified [0] Literal(3) [1] = [2] CJump<5> [3] Literal(Three!) [4] .For this version, if the number is not 3, jump past and exit the word. If the number is 3, print Three!, then the word ends.