diff --git a/thun/compiler.markII.pl b/thun/compiler.markII.pl index c0fe249..57a7a11 100644 --- a/thun/compiler.markII.pl +++ b/thun/compiler.markII.pl @@ -132,10 +132,12 @@ CPUs.) % has a copy of the address of the record. split_pair(TERM, TEMP1, EXPR, TEMP0), % Now Term has the term's record data and temp1 has the address of the term. + % temp0 still has the address of the expression record. if_literal(TERM, PUSH), % if it is a symbol the rest of it is the pointer to the machine code. lookup(TERM), % Jump to command. - label(PUSH), push(TOS, TERM, SP), % stack = TERM, stack + % going in to push we have the term + label(PUSH), push2(TOS, TEMP1, SP), % stack = TERM, stack label(DONE), write_ram(SP, TOS), % RAM[SP] := TOS jump(MAIN) |Ts]) --> @@ -286,6 +288,12 @@ language. ior(TOS, TOS, SP), % TOS := TOS | SP add_imm(SP, SP, 4)]. % SP += 1 (word, not byte) +⟐(push2(TOS, TERMADDR, SP)) --> + [sub_imm(SP, SP, 4), % SP -= 1 (word, not byte) + sub(TOS, TERMADDR, SP), % TOS := &temp - sp + lsl_imm(TOS, TOS, 15), % TOS := TOS << 15 + ior(TOS, TOS, 4)]. % TOS := TOS | 4 + ⟐( write_ram(To, From)) --> [store_word(From, To, 0)]. ⟐(write_cell(From, SP)) --> [add_imm(SP, SP, 4), store_word(From, SP, 0)]. diff --git a/thun/markII.rst b/thun/markII.rst index 9b02ac2..8bc8cbe 100644 --- a/thun/markII.rst +++ b/thun/markII.rst @@ -112,3 +112,45 @@ lookup(DICT_PTR, DICT_TOP, TERM, HALT) It turns out that you don;t need anything but the record since it's already been looked up. The symbol contains the jump address. + + +Next, push + +push(TOS, TERM, SP) + +There's a note saying + + set(sp, 2), % Reg 2 points to just under top of stack. + +But I've forgotten if that's exactly true. I want to just point to TOS +pair record in SP. If that's the case, then the PUSH operation is: + +Since the record we are constructing is going to have the rest of the +stack as its tail and it's going to be written to the next word in RAM +after (before) the SP (the address of the stack/tail) the offset is +4. + +The address of the term is in a register, the address of the pair record +that we are contrsucting will be SP - 4, to get the offset we have to +subtract that from the term's address. Since we need it anyway, and +we're going to do it sooner or later, let's subtract 4 from the SP right +off: + + sp = sp - 4 + +Then we can use it to calculate the offset and put it in tos: + + tos = &temp - sp + tos = tos << 15 + +If I was as slick as I like to pretend I would insert a check here that +the two high bits are indeed 00. ... + +With the offset of the term in the tos register already we just have to +OR 4: + + tos = tos | 4 + +And write it to the (already decremented) sp. + + ram[sp] = tos +