-
-
Save crcx/4610280 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## OBERON SYNTAX TO COMPILE: | |
FOR x := start TO goal BY step DO | |
block | |
END; | |
## StringTemplate ( generating retro code ): | |
for_stmt(id, beg, end, step, block) ::= << | |
( FOR ) <id> | |
( := ) <beg> | |
( TO ) <end> | |
( BY ) <step> | |
( DO | |
[ | |
<block> | |
] | |
( END ) FOR | |
>> | |
## Retro helper macro | |
{{ | |
( Helper functions ) | |
: relop dup 2 + @ 0 > [ &<= ] [ &>= ] if ; | |
: start dup 4 + 1 , , ; | |
: goal dup 3 + 1 , , ; | |
: by dup 2 + 1 , , ; | |
: quote dup 1 + 1 , , ; | |
---reveal--- | |
: for ( start goal step quote - ) | |
ahead [ 5 allot ] dip here over ! | |
quote ` ! by ` ! goal ` ! start ` ! | |
` repeat [ | |
start ` @ goal ` @ relop , 0; ` drop | |
start ` @ by ` @ ` + start ` ! | |
quote ` @ ` do | |
] dip ` again | |
drop ; immediate | |
}} | |
( Test ) | |
: foo 10 0 -2 [ 1 ] for ; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This creates a private structure in the code using the for macro. We have helper functions for accessing each of these fields: start, goal, by, and quote. The helper functions add the appropriate offsets and compile VM_LIT instructions into the target definition. Helper functions leave the struct pointer on the stack.
Using the helpers, store values (from the stack) into the new structure.
Starts an unconditional loop. Since repeat leaves a pointer on the stack, we use a quote and dip combinator to move the loop pointer away until we finish filling in the body of the loop.
Compile code to fetch the start and goal values from the struct. relop is a helper which compiles the appropriate conditional into the loop. If it maches, we exit the loop via the 0; drop sequence. Otherwise we go on to modify start for the next cycle through the loop:
Pretty cut and dry. This would probably be better done using +!, but that's an optimization for later consideration.
Invoke the quote. This has some overhead and could be handled much more efficiently. (E.g., by changing quote to compile an implied call rather than a literal pointer to the stored quote address)
Finish off the repeat / again loop.
Discard the struct pointer and finish the macro.