$ ./course04 : is-true? if "yes, it is true" else "no, it is not" then type cr ; ok> 0 is-true? no, it is not ok> 1 is-true? yes, it is true ok>Display the square of the numbers 10 to 1. Counter always is on top of Stack. Don't put in the comments, since the compiler doesn't know how to handle them.
$ ./course04 : square ( n--n*n) dup * ; ok> 4 square 16 ok> drop ok> : .square ( n--n) dup . dup square . cr ; ok> 4 .square 4 16 4 ok> drop ok> : squares ( n--) begin .square -1 + dup while drop ; ok> 10 squares 10 100 9 81 8 64 7 49 6 36 5 25 4 16 3 9 2 4 1 1 ok>again is an uncoditional jump to begin
$ ./course04 : endless-loop ( --) begin again ; ok> endless-loop ... never comes back
f_0branch, f_1_branch are conditional jumps on zero or not zero which disacrds
the top of stack.
f_branch is an uncoditional jump.
static void register_primitives(void) {
...
xt_0branch=add_word("0branch", f_0branch); // jump if zero
xt_1branch=add_word("1branch", f_1branch); // jump if not zero
xt_branch =add_word("branch", f_branch); // unconditional jump
definitions=¯os;
add_word("if", f_if); // compiles an if condition
add_word("then", f_then); // this is the endif
add_word("else", f_else);
add_word("begin", f_begin); // begin of while loop
add_word("while", f_while); // while loop (condition at end of loop)
add_word("again", f_again); // unconditional loop to begin
...
}
static void f_if(void) { // macro, execute at compiletime
*code++=xt_0branch;
sp_push((cell_t)code++); // push forward reference on stack
}
static void f_else(void) { // macro, execute at compiletime
xt_t ***dest=(void*)sp_pop(); // pop address (from f_if)
*code++=xt_branch; // compile a jump
sp_push((cell_t)code++); push forward reference on stack
*dest=code; resolve forward reference given by f_if
}
static void f_then(void) { // macro, execute at compiletime
xt_t ***dest=(void*)sp_pop();
*dest=code; resolve forward reference given by f_if or f_else
}
static void f_begin(void) { // macro, execute at compiletime
sp_push((cell_t)code); // push current compilation address for loop
}
static void f_while(void) { // macro, execute at compiletime
*code++=xt_1branch; // compile a jump if not zero
*code++=(void*)sp_pop(); // jump back to f_begin address
}
static void f_again(void) { // macro, execute at compiletime, unconditional loop
*code++=xt_branch; // compile a jump
*code++=(void*)sp_pop();// jump back to f_begin address
}