Annotation of gforth/kernel/recognizer.fs, revision 1.15
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:
1.7 pazsan 18: : recognizer: ( xt1 xt2 xt3 -- ) Create rot , swap , , ;
1.1 pazsan 19:
1.7 pazsan 20: (field) r>int ( r-addr -- addr ) 0 cells ,
1.13 pazsan 21: (field) r>comp ( r-addr -- addr ) 1 cells ,
22: (field) r>lit ( r-addr -- addr ) 2 cells ,
1.1 pazsan 23:
1.14 pazsan 24: ' no.extensions dup dup Create r:fail A, A, A,
25:
1.15 ! pazsan 26: : lit, ( n -- ) postpone Literal ;
! 27: : 2lit, ( n -- ) postpone 2Literal ;
! 28: : nt, ( nt -- ) name>comp execute ;
! 29:
! 30: ' name>int
! 31: :noname ( ... nt -- ... xt ) ['] nt, ;
! 32: :noname ( ... nt -- xt ) ['] lit, ;
1.10 pazsan 33: Create r:word rot A, swap A, A,
1.1 pazsan 34:
1.14 pazsan 35: : word-recognizer ( addr u -- nt r:word | addr u r:fail )
1.1 pazsan 36: 2dup find-name [ [IFDEF] prelude-mask ] run-prelude [ [THEN] ] dup
1.14 pazsan 37: IF nip nip r:word ELSE drop r:fail THEN ;
1.1 pazsan 38:
1.15 ! pazsan 39: :noname ['] noop ;
! 40: :noname ['] lit, ;
1.1 pazsan 41: dup
1.10 pazsan 42: Create r:num rot A, swap A, A,
1.1 pazsan 43:
1.15 ! pazsan 44: :noname ['] noop ;
! 45: :noname ['] 2lit, ;
1.1 pazsan 46: dup
1.10 pazsan 47: Create r:2num rot A, swap A, A,
1.7 pazsan 48:
49: \ snumber? should be implemented as recognizer stack
1.1 pazsan 50:
1.14 pazsan 51: : num-recognizer ( addr u -- n/d table | addr u r:fail )
1.1 pazsan 52: 2dup 2>r snumber? dup
53: IF
1.14 pazsan 54: 2rdrop 0> IF r:2num ELSE r:num THEN EXIT
1.1 pazsan 55: THEN
1.14 pazsan 56: drop 2r> r:fail ;
1.3 pazsan 57:
1.1 pazsan 58: \ recognizer stack
59:
60: $10 Constant max-rec#
61:
62: : get-recognizers ( rec-addr -- xt1 .. xtn n )
1.8 pazsan 63: dup swap @ dup >r cells bounds swap ?DO
1.1 pazsan 64: I @
1.8 pazsan 65: cell -LOOP r> ;
1.1 pazsan 66:
67: : set-recognizers ( xt1 .. xtn n rec-addr -- )
68: over max-rec# u>= abort" Too many recognizers"
1.8 pazsan 69: 2dup ! cell+ swap cells bounds ?DO
1.1 pazsan 70: I !
1.8 pazsan 71: cell +LOOP ;
1.1 pazsan 72:
1.7 pazsan 73: Variable forth-recognizer
74:
1.10 pazsan 75: ' word-recognizer A, ' num-recognizer A, max-rec# 2 - cells allot
1.7 pazsan 76: 2 forth-recognizer !
1.10 pazsan 77: \ ' num-recognizer ' word-recognizer 2 forth-recognizer set-recognizers
1.1 pazsan 78:
79: \ recognizer loop
80:
81: : do-recognizer ( addr u rec-addr -- token table )
82: dup cell+ swap @ cells bounds ?DO
1.14 pazsan 83: I perform dup r:fail <> IF UNLOOP EXIT THEN drop
1.1 pazsan 84: cell +LOOP
1.3 pazsan 85: r:fail ;
1.1 pazsan 86:
1.6 pazsan 87: \ nested recognizer helper
88:
1.14 pazsan 89: \ : nest-recognizer ( addr u -- token table | addr u r:fail )
90: \ xxx-recognizer do-recognizer ;
1.6 pazsan 91:
1.1 pazsan 92: : interpreter-r ( addr u -- ... xt )
1.15 ! pazsan 93: forth-recognizer do-recognizer r>int perform ;
1.1 pazsan 94:
1.7 pazsan 95: ' interpreter-r IS parser1
96:
1.1 pazsan 97: : compiler-r ( addr u -- ... xt )
1.15 ! pazsan 98: forth-recognizer do-recognizer r>comp perform ;
1.1 pazsan 99:
100: : [ ( -- ) \ core left-bracket
101: \G Enter interpretation state. Immediate word.
102: ['] interpreter-r IS parser1 state off ; immediate
103:
104: : ] ( -- ) \ core right-bracket
105: \G Enter compilation state.
106: ['] compiler-r IS parser1 state on ;
107:
1.15 ! pazsan 108: : >int ( token table -- ) r>int perform execute ;
! 109: : >comp ( token table -- ) r>comp perform execute ;
1.7 pazsan 110: : >postpone ( token table -- )
1.15 ! pazsan 111: >r r@ r>lit perform execute r> r>comp perform compile, ;
1.7 pazsan 112:
1.4 pazsan 113: : postpone ( "name" -- ) \ core
114: \g Compiles the compilation semantics of @i{name}.
1.7 pazsan 115: parse-name forth-recognizer do-recognizer >postpone ; immediate
1.4 pazsan 116:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>