Anti-nuisance lawsuit warning: The purpose of these notes is to remind me, Zoegond, of stuff or to help me work stuff out. They may contain mistakes.

Quick

  • ($a, $b....) = unpack("A2A7...", $packed)
  • push( array, list )

Saturday, December 29, 2012

Compile-time actions for FORTH-style structures

Assumptions:
NFA is the address that the next instruction will be compiled at
JC is a conditional jump
JP is an unconditional jump
All jump operands are absolute and take up 1 address cell
poke n, x = place x in address n
CASE..OF..ENDOF..ENDCASE can have unconditionally executed code anywhere inside the CASE but outside any OF clauses

IF
compile "JC 0" ; jump past the if clause
push NFA-1 ; address of the JC operand

ELSE ; may not be present
compile "JP 0" ; jump past the else clause
pop JC_ADDR
poke JC_ADDR, NFA ; fill in the JC operand of the IF code
push NFA-1 ; address of the JC operand

ENDIF
pop J_ADDR
poke J_ADDR, NFA ; fill in the JP operand of the ELSE code (or the JC of the IF if there was no ELSE clause)

--

BEGIN
push NFA ; to be used by REPEAT

WHILE
compile "JC 0" ; jump past the end of the loop
push NFA-1 ; address of the JC operand

REPEAT
pop JC_OUT_ADDR
pop JC_TOP_ADDR
compile "JP JC_TOP_ADDR" ; jump back to the BEGIN
poke JC_OUT_ADDR, NFA ; fill in the JC operand of the jump in WHILE

--

CASE
push 0 ; count of OF clauses

OF ; there can be any number of these
compile "JC 0" ; jump past this OF clause
pop COUNT ; temp store of count
push NFA-1 ; address of the JC operand
push COUNT ; restore count to top of stack

ENDOF ; one of these for each OF
compile "JP 0"
pop COUNT ; pop current OF clause count
++COUNT ; increase by exactly 1
pop JC_ADDR
poke JC_ADDR, NFA ; fill in the JC operand of the jump in the OF
push NFA-1 ; address of the JP operand we compiled just now
push COUNT ; put the (incremented) count back on the stack

ENDCASE
pop COUNT
for (I = 1; I <= COUNT; ++I) {
pop JP_ADDR
poke JP_ADDR, NFA ; fill in the JP operand of the jump in each ENDOF
}

Followers

Blog Archive