File:  [gforth] / gforth / kernel / recognizer.fs
Revision 1.21: download - view: text, annotated - select for diffs
Mon Jul 2 21:59:48 2012 UTC (11 years, 9 months ago) by pazsan
Branches: MAIN
CVS tags: HEAD
Recognizer doc update

    1: \ recognizer-based interpreter                       05oct2011py
    2: 
    3: \ Copyright (C) 2012 Free Software Foundation, Inc.
    4: 
    5: \ This file is part of Gforth.
    6: 
    7: \ Gforth is free software; you can redistribute it and/or
    8: \ modify it under the terms of the GNU General Public License
    9: \ as published by the Free Software Foundation, either version 3
   10: \ of the License, or (at your option) any later version.
   11: 
   12: \ This program is distributed in the hope that it will be useful,
   13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: \ GNU General Public License for more details.
   16: 
   17: \ You should have received a copy of the GNU General Public License
   18: \ along with this program. If not, see http://www.gnu.org/licenses/.
   19: 
   20: \ Recognizer are words that take a string and try to figure out
   21: \ what to do with it.  I want to separate the parse action from
   22: \ the interpret/compile/postpone action, so that recognizers
   23: \ are more general than just be used for the interpreter.
   24: 
   25: \ The "design pattern" used here is the *factory*, even though
   26: \ the recognizer does not return a full-blown object.
   27: \ A recognizer has the stack effect
   28: \ ( addr u -- token table | addr u r:fail )
   29: \ where the token is the result of the parsing action (can be more than
   30: \ one stack or live on other stacks, e.g. on the FP stack)
   31: \ and the table contains three actions (as array of three xts):
   32: \ interpret it, compile it, compile it as literal.
   33: 
   34: : recognizer: ( xt1 xt2 xt3 -- ) Create rot , swap , , ;
   35: 
   36: (field) r>int      ( r-addr -- addr )  0 cells ,
   37: (field) r>comp     ( r-addr -- addr )  1 cells ,
   38: (field) r>lit      ( r-addr -- addr )  2 cells ,
   39: 
   40: ' no.extensions dup dup Create r:fail A, A, A,
   41: 
   42: : lit, ( n -- ) postpone Literal ;
   43: : nt, ( nt -- ) name>comp execute ;
   44: : nt-ex ( nt -- )
   45:     [ cell 1 floats - dup [IF] ] lp+!# [ dup , [THEN] drop ]
   46:     r> >l name>int execute @local0 >r lp+ ;
   47: 
   48: ' nt-ex
   49: ' nt,
   50: ' lit,
   51: Create r:word rot A, swap A, A,
   52: 
   53: : word-recognizer ( addr u -- nt r:word | addr u r:fail )
   54:     2dup find-name [ [IFDEF] prelude-mask ] run-prelude [ [THEN] ] dup
   55:     IF  nip nip r:word  ELSE  drop r:fail  THEN ;
   56: 
   57: ' noop
   58: ' lit,
   59: dup
   60: Create r:num rot A, swap A, A,
   61: 
   62: ' noop
   63: :noname ( n -- ) postpone 2Literal ;
   64: dup
   65: Create r:2num rot A, swap A, A,
   66: 
   67: \ snumber? should be implemented as recognizer stack
   68: 
   69: : num-recognizer ( addr u -- n/d table | addr u r:fail )
   70:     2dup 2>r snumber?  dup
   71:     IF
   72: 	2rdrop 0> IF  r:2num   ELSE  r:num  THEN  EXIT
   73:     THEN
   74:     drop 2r> r:fail ;
   75: 
   76: \ recognizer stack
   77: 
   78: $10 Constant max-rec#
   79: 
   80: : get-recognizers ( rec-addr -- xt1 .. xtn n )
   81:     dup swap @ dup >r cells bounds swap ?DO
   82: 	I @
   83:     cell -LOOP  r> ;
   84: 
   85: : set-recognizers ( xt1 .. xtn n rec-addr -- )
   86:     over max-rec# u>= abort" Too many recognizers"
   87:     2dup ! cell+ swap cells bounds ?DO
   88: 	I !
   89:     cell +LOOP ;
   90: 
   91: Variable forth-recognizer
   92: 
   93: ' word-recognizer A, ' num-recognizer A, max-rec# 2 - cells allot
   94: 2 forth-recognizer !
   95: \ ' num-recognizer ' word-recognizer 2 forth-recognizer set-recognizers
   96: 
   97: \ recognizer loop
   98: 
   99: : do-recognizer ( addr u rec-addr -- token table )
  100:     dup cell+ swap @ cells bounds ?DO
  101: 	I perform dup r:fail <>  IF  UNLOOP  EXIT  THEN  drop
  102:     cell +LOOP
  103:     r:fail ;
  104: 
  105: \ nested recognizer helper
  106: 
  107: \ : nest-recognizer ( addr u -- token table | addr u r:fail )
  108: \   xxx-recognizer do-recognizer ;
  109: 
  110: : interpreter-r ( addr u -- ... xt )
  111:     forth-recognizer do-recognizer r>int @ ;
  112: 
  113: ' interpreter-r IS parser1
  114: 
  115: : compiler-r ( addr u -- ... xt )
  116:     forth-recognizer do-recognizer r>comp @ ;
  117: 
  118: : [ ( -- ) \  core	left-bracket
  119:     \G Enter interpretation state. Immediate word.
  120:     ['] interpreter-r  IS parser1 state off ; immediate
  121: 
  122: : ] ( -- ) \ core	right-bracket
  123:     \G Enter compilation state.
  124:     ['] compiler-r     IS parser1 state on  ;
  125: 
  126: : >int      ( token table -- )  r>int perform ;
  127: : >comp     ( token table -- )  r>comp perform ;
  128: : >postpone ( token table -- )
  129:     >r r@ r>lit perform r> r>comp @ compile, ;
  130: 
  131: : postpone ( "name" -- ) \ core
  132:     \g Compiles the compilation semantics of @i{name}.
  133:     parse-name forth-recognizer do-recognizer >postpone
  134: ; immediate restrict
  135: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>