Annotation of gforth/kernel/recognizer.fs, revision 1.5
1.1 pazsan 1: \ recognizer-based interpreter 05oct2011py
2:
3: \ Recognizer are words that take a string and try to figure out
4: \ what to do with it. I want to separate the parse action from
5: \ the interpret/compile/postpone action, so that recognizers
6: \ are more general than just be used for the interpreter.
7:
8: \ The "design pattern" used here is the *factory*, even though
9: \ the recognizer does not return a full-blown object.
10: \ A recognizer has the stack effect
11: \ ( addr u -- token table true | addr u false )
12: \ where the token is the result of the parsing action (can be more than
13: \ one stack or live on other stacks, e.g. on the FP stack)
14: \ and the table contains for actions (as array of four xts:
15: \ interpret it, compile interpretation semantics
16: \ compile it, compile it as literal.
17:
18: : recognizer: ( xt1 xt2 xt3 xt4 -- ) Create 2swap swap 2, swap 2, ;
19:
1.2 pazsan 20: (field) r>int ( r-addr -- addr ) 0 cells ,
21: (field) r>compint ( r-addr -- ) 1 cells ,
22: (field) r>comp ( r-addr -- ) 2 cells ,
23: (field) r>lit ( r-addr -- ) 3 cells ,
1.1 pazsan 24:
25: :noname ( ... nt -- ) name>int execute ;
26: :noname ( ... nt -- ) name>int compile, ;
27: :noname ( ... nt -- ) name>comp execute ;
28: :noname ( ... nt -- ) postpone Literal ;
1.5 ! pazsan 29: recognizer: r:interpreter
1.1 pazsan 30:
31: :noname ( addr u -- nt int-table true | addr u false )
32: 2dup find-name [ [IFDEF] prelude-mask ] run-prelude [ [THEN] ] dup
33: IF
1.5 ! pazsan 34: nip nip r:interpreter true EXIT
1.1 pazsan 35: THEN ; Constant int-recognizer
36:
37: ' noop
38: :noname postpone Literal ;
39: dup
40: dup
41: recognizer: r:number
42:
43: ' noop
44: :noname postpone 2Literal ;
45: dup
46: dup
47: recognizer: r:2number
48:
49: :noname ( addr u -- nt int-table true | addr u false )
50: 2dup 2>r snumber? dup
51: IF
52: 2rdrop 0> IF r:2number ELSE r:number THEN true EXIT
53: THEN
54: drop 2r> false ; Constant num-recognizer
55:
1.3 pazsan 56: ' no.extensions dup 2dup recognizer: r:fail
57:
1.1 pazsan 58: \ recognizer stack
59:
60: $10 Constant max-rec#
61: Variable forth-recognizer max-rec# cells allot
62:
63: : get-recognizers ( rec-addr -- xt1 .. xtn n )
64: dup cell+ swap @ dup >r cells bounds ?DO
65: I @
66: cell +LOOP r> ;
67:
68: : set-recognizers ( xt1 .. xtn n rec-addr -- )
69: over max-rec# u>= abort" Too many recognizers"
70: 2dup ! swap cells bounds swap ?DO
71: I !
72: cell -LOOP ;
73:
74: num-recognizer int-recognizer 2 forth-recognizer set-recognizers
75:
76: \ recognizer loop
77:
78: : do-recognizer ( addr u rec-addr -- token table )
79: dup cell+ swap @ cells bounds ?DO
80: I perform IF UNLOOP EXIT THEN
81: cell +LOOP
1.3 pazsan 82: r:fail ;
1.1 pazsan 83:
84: : interpreter-r ( addr u -- ... xt )
1.2 pazsan 85: forth-recognizer do-recognizer r>int @ ;
1.1 pazsan 86:
87: : compiler-r ( addr u -- ... xt )
1.2 pazsan 88: forth-recognizer do-recognizer r>comp @ ;
1.1 pazsan 89:
90: : [ ( -- ) \ core left-bracket
91: \G Enter interpretation state. Immediate word.
92: ['] interpreter-r IS parser1 state off ; immediate
93:
94: : ] ( -- ) \ core right-bracket
95: \G Enter compilation state.
96: ['] compiler-r IS parser1 state on ;
97:
1.4 pazsan 98: : postpone ( "name" -- ) \ core
99: \g Compiles the compilation semantics of @i{name}.
100: parse-name forth-recognizer do-recognizer >r
101: r@ r>lit perform r> r>comp @ compile, ; immediate
102:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>