Skip to content

Instantly share code, notes, and snippets.

@tangentstorm
Last active December 14, 2015 07:29
Show Gist options
  • Save tangentstorm/5050753 to your computer and use it in GitHub Desktop.
Save tangentstorm/5050753 to your computer and use it in GitHub Desktop.
Work in progress : macros for b4a.js ... These are actually more like mini-compilers. Basically the idea is that when you see a word like `.if` , it's going to define `.then` and `.else` on the fly... This way if you encounter an `.else` that is not inside an `.if`, it will be a syntax error. The assembly code should wind up looking a lot more l…
// when asm( ) encounters a word that starts with punctuation,
// it will not try to compile a call to that word, but will instead
// look up the word's definition in the "macro" vocabulary, and
// execute the macro immediately.
//
// The macros are written in javascript.
// semicolon. in forth this would issue a 'return' instruction,
// but in b4, it's used as punctuation. In the default context,
// it doesn't do anything, but it can be used to break long
// strings of words down into easier to understand chunks.
def( ';', function( ) {
});
// REPEAT ... UNTIL ... ; loop, as in pascal or oberon.
def( '.repeat', function {
// repeat-loop ::= REPEAT <code> UNTIL <condition> ";"
// so define what UNTIL means in this context.
pushdef( '.until', function( ) {
// ... and inside UNTIL, redefine ";"
pushdef( ';', function( ) {
// when we encounter the ';' emit code to conditionally jump back to the REPEAT.
// That is, "UNTIL x;" compiles down to "IF x NOT THEN JUMP: <top-of-loop> END"
// so by the time we're here, we will have already compiled
// 'IF x', and we can continue with:
asm( "not .then" );
// REPEAT will have put the <top-of-loop> label on the stack.
// ".emit" will take it off the stack and compile it:
asm( "JUMP: .emit" );
// close the IF statement, so it can clean up after itself:
asm( ".end" );
// and then step out of the REPEAT context:
popdefs( ";", ".until" );
});
// with the plan for ";" in place, UNTIL now compiles the IF
asm( ".if" );
});
// and with the plan for "UNTIL" in place, REPEAT now records <top-of-loop>.
asm( ".here" );
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment