REBOL [ Title: "Test Rebasm" ] do %rebasm.r ; generate unique word, to use during macro expansion for labels use [i] [i: 0 sym: does [i: i + 1 to word! form i]] use [w t ok finish] [ rebcode-define [ 'fact set w word! #==> gt (w) 1 brat (ok: sym) seti (w) 1 bra (finish: sym) label (ok) set t (w) until [ sub t 1 mul (w) t gt t 1 ] label (finish) . ] ] context [ slash: to lit-word! first [ / ] res: val: rest: mark1: mark2: op: rv: none value: [set val [decimal! | word! | paren!]] oper: ['+ (op: 'addd) | '- (op: 'subd) | '* (op: 'muld) | slash (op: 'divd)] rebcode-define [ set res set-word! mark1: value some [oper mark2: value] (rest: copy/part mark1 back mark2) #==> (res) (rest) (either paren? val [compose [rv: (to block! val)]] [ ]) (op) (bind to word! res res) (either paren? val ['rv] [val]) . set res set-word! value #==> set (bind to word! res res) (val) . ] ] print "test..." f: rebcode [x y /local res] [ res: x * x + (y * y) return res ] halt comment [ ; old expression compilers (handles precedence rules) slash: to lit-word! first [ / ] expr-val: expr-op: none expression: [ term (expr-val: term-val) any [ ['+ (expr-op: 'add) | '- (expr-op: 'subtract)] term (expr-val: compose [(expr-op) (expr-val) (term-val)]) ] ] term-val: term-op: none term: [ pow (term-val: power-val) any [ ['* (term-op: 'multiply) | slash (term-op: 'divide)] pow (term-val: compose [(term-op) (term-val) (power-val)]) ] ] power-val: none pow: [ unary (power-val: unary-val) opt ['^ unary (power-val: compose [power (power-val) (unary-val)])] ] unary-val: pre-uop: post-uop: none unary: [ (post-uop: pre-uop: []) opt ['- (pre-uop: 'negate)] primary opt ['! (post-uop: 'factorial)] (unary-val: compose [(post-uop) (pre-uop) (prim-val)]) ] prim-val: none ; WARNING: uses recursion for parens. primary: [ set prim-val [number! | word!] | set prim-val paren! (prim-val: translate to-block :prim-val) ] translate: func [expr [block!] /local res recursion] [ ; to allow recursive calling, we need to preserve our state recursion: reduce [ :expr-val :expr-op :term-val :term-op :power-val :unary-val :pre-uop :post-uop :prim-val ] res: if parse expr expression [expr-val] set [ expr-val expr-op term-val term-op power-val unary-val pre-uop post-uop prim-val ] recursion res ] set 'eval func [expr [block!] /translate] [ expr: self/translate expr either translate [expr] [do expr] ] ]