Re: Self Modifying Code
Posted: Wed Oct 31, 2018 6:51 pm
MichaelM wrote:
[...]SMC in the same sense as possible in FORTH where the instruction stream can be physically changed?
Code: Select all
// SCAN
HEX
CODE SCAN ( A1 L1 C -- A2 L2 )
0= # LDA,
AHEAD, ( AH1 )
-3 ALLOT // JUST NEED CONTROL FLOW DATA
BAD STA,
3 # LDA, SETUP JSR,
AHEAD, ( AH1 AH2 )
BEGIN, ( AH1 AH2 BEG )
N 4 + INC,
0= IF, N 5 + INC, THEN,
N 2+ LDA,
0= IF, N 3 + DEC, THEN,
N 2+ DEC,
CS-SWAP THEN, // SECOND AHEAD JUMPS TO HERE
N 2+ LDA, N 3 + ORA, ( AH1 BEG )
0= NOT WHILE, ( AH1 IFW BEG )
N 4 + )Y LDA, N EOR, .A ASL,
// THE ADDRESS OF THE FIRST AHEAD ( THE ADDRESS OF STA,) GETS FIXED UP BY THE FOLLOWING LINE
CS-ROT THEN, ( IFW BEG )
0= UNTIL, // STORE DESIRED BRANCH HERE
THEN, ( )
DEX, DEX,
N 4 + LDA, 0 ,X STA,
N 5 + LDA, 1 ,X STA,
N 2+ LDA, PHA,
N 3 + LDA,
PUSH JMP, END-CODE
// SKIP
CODE SKIP ( A1 L1 C -- A2 L2 )
0= NOT # LDA,
' SCAN @ 3 + @ STA,
' SCAN @ 5 + JMP, END-CODE
Code: Select all
HEX
: NOT 20 + ;
Code: Select all
HEX
: NOT 20 XOR ;
Code: Select all
DOIT:
LDA FLAG
BEQ $1
JSR DOTHIS
JMP $2
$1: JSR DOTHAT
$2: RTS
Code: Select all
_DOIT:
JSR _DOTHIS
RTS
DOTHAT:
LDA #<_DOTHAT
STA _DOIT+1
LDA #>_DOTHAT
STA _DOIT+2
JMP _DOIT
DOTHIS:
LDA #<_DOTHIS
STA _DOIT+1
LDA #>_DOTHIS
STA _DOIT+2
JMP _DOIT
Code: Select all
public class X {
public void thingI() {
System.out.println("Hi there!");
}
public static void main(String args[]) {
X x = new X();
x.thing();
}
}
Code: Select all
// SKIP
CODE SKIP ( A1 L1 C -- A2 L2 )
0= NOT # LDA, // LOAD OPCODE F0 ( BEQ )
' SCAN @ 3 + @ STA,
' SCAN @ 5 + JMP, END-CODE
Code: Select all
CODE SKIP ( A1 L1 C -- A2 L2 )
0= NOT # LDA, // LOAD OPCODE F0 ( BEQ )
' SCAN @ 2+ JMP, END-CODE
Code: Select all
// SCAN
HEX
CODE SCAN ( AD1 N1 C -- AD2 N2 )
DEY,
N 6 + STY, 0 # LDY, // SETUP NEEDS Y TO BE ZERO
3 # LDA, SETUP JSR,
AHEAD,
BEGIN,
N 4 + INC,
0= IF, N 5 + INC, THEN,
N 2+ LDA,
0= IF, N 3 + DEC, THEN,
N 2+ DEC,
CS-SWAP THEN,
N 2+ LDA, N 3 + ORA,
0= NOT WHILE,
N 4 + )Y LDA, N EOR, .A ASL,
0= NOT IF, 0FF # LDA, THEN, // BE SURE RESULT IN ACCUMULATOR IS 0 OR FF
N 6 + EOR, // SCAN INVERTS THE RESULT, SKIP DOES NOT
0= NOT UNTIL, // SO THE TEST IS REVERSED
THEN,
DEX, DEX,
N 4 + LDA, 0 ,X STA,
N 5 + LDA, 1 ,X STA,
N 2+ LDA, PHA,
N 3 + LDA,
PUSH JMP, END-CODE
CODE SKIP ( A1 L1 C -- A2 L2 )
// SKIP HAS NO PARAMETER FIELD. IT'S CFA POINTS ONE BYTE INTO SCAN
// AVOIDING THE DEY, INSTRUCTION
-2 ALLOT
' SCAN @ 1+ , END-CODE
Code: Select all
DEFER (WHERE)
: SHOW.WHERE
['] NOOP IS (WHERE)
// SHOW THE LOCATION OF THE ERROR
//
//
;
: WHERE
(WHERE)
['] SHOW.WHERE IS (WHERE) ;
Code: Select all
VARIABLE WHERE? TRUE WHERE? !
: WHERE
WHERE? @
IF
WHERE? OFF
// SHOW THE LOCATION OF THE ERROR
//
//
THEN
WHERE? ON ;
Code: Select all
SCR# 38
// SCAN
HEX
CODE SCAN ( AD1 N1 C -- AD2 N2 )
0= # LDA, // LOAD D0 ( BNE )
HERE 1+ >A
BAD STA,
3 # LDA, SETUP JSR,
AHEAD,
BEGIN,
N 4 + INC,
0= IF, N 5 + INC, THEN,
N 2+ LDA,
0= IF, N 3 + DEC, THEN,
N 2+ DEC,
CS-SWAP THEN,
N 2+ LDA, N 3 + ORA,
SCR# 39
// SCAN SKIP
0= NOT WHILE,
N 4 + )Y LDA, N EOR, .A ASL,
HERE A> !
0= UNTIL,
THEN,
DEX, DEX,
N 4 + LDA, 0 ,X STA,
N 5 + LDA, 1 ,X STA,
N 2+ LDA, PHA,
N 3 + LDA,
PUSH JMP, END-CODE
CODE SKIP ( A1 L1 C -- A2 L2 )
0= NOT # LDA, // LOAD F0 (BEQ)
' SCAN @ 2+ JMP, END-CODE
Code: Select all
: ENTER >R ; \ ( tcf-addr -- ) call the threaded code fragment at tcf-addr
: SUCC COMPILE R@ COMPILE ENTER ; IMMEDIATE
: FAIL COMPILE R> COMPILE DROP COMPILE EXIT ; IMMEDIATE
: 1-10 ( --> i --- i --> ) \ generate numbers from 1 to 10
0 BEGIN 1+ DUP 11 <
WHILE SUCC \ call the continuation, of type ( i -- i )
REPEAT
DROP
FAIL ; \ exit the code fragment that contains the continuation
: //2 ( i --> i --- i --> i ) \ filter even numbers
DUP 2 MOD 0=
IF SUCC \ call the continuation, of type ( i -- i );
\ (in the case of //2 we could just exit)
THEN
FAIL ; \ exit the code fragment that contains the continuation
: .even1-10 ( -- ) 1-10 //2 DUP . ;
Code: Select all
.even1-10 2 4 6 8 10 ok