So, ok, here is a draft based on what I think I am supposed
to be accomplishing.
tokenize=: (0;(0 4#:0 12#:69 82 80);a.e.":i.10)&;:@-.&' '
classify=: '*()+-'&(((>:@#...@[ # 2:) #: 2 ^ i.)&tokenize)
rules=: ''
patterns=: i.0 0 1
addrule=:4 :0
rules=:rules,;:x
patterns=: patterns,+./@classify"1 y
)
'Factor' addrule '*()', '0', '0' ,:'*(+-'
'Term' addrule '*(', '0', '+-' ,:'0'
'Parens' addrule '*0+-', '(', '0' ,:')'
rules=:rules,;:'Move'
eval=: monad define
words=: tokenize '*',y
queue=: classify '*',y
tree=: ''
stack=: classify '****'
tokens=: ]&.>i.#words
while.(#queue)+.6<#stack do.
rule=: rules {~ i.&1 patterns (*./"1)@:(+./"1) .(*."1)4{.stack
rule`:6''
end.
'syntax' assert 1 0 1 1 1 1 -: {:"1 stack
gerund=: literal&.> words
ger...@.(1{tree)
)
literal=:monad define ::]
".'t=.',y
5!:1<'t'
)
Factor=: monad define
tree=: ({.tree),(<1 0 2{tree),3}.tree
stack=: ({.stack),(classify '0'),3}.stack
)
Term=: monad define
tree=: ({.tree),(<1 2 3{tree),4}.tree
stack=: ({.stack),(classify '0'),4}.stack
)
Parens=: monad define
tree=: (0 2{tree),4}.tree
stack=: (0 2{stack),4}.stack
)
Move=: monad define
'syntax' assert 0<#queue
tree=: ({:tokens),tree
stack=: ({:queue),stack
queue=: }:queue
tokens=: }:tokens
)
Hypothetically, the global side effects should be wrapped up
in an object, rather than using base.
Hypothetically, this should be tested extensively, and systematically
rather than the half dozen informal tests I used.
But I am leaving those as exercises for you. I will try fixing any
bugs you find.
Good luck,
--
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm