functor import Open export getExpsFromFile:GetExpsFromFile define fun {GetLinesFromFile FileName} local F A in F = {New Open.file init(name:FileName flags:[read])} {F read(list:A size:all)} {F close} {String.tokens A &\n} end end proc {ParseLambda X Atom Exp} % "\Atom.Exp" local AtomDotExp AtomStr ExpStr in &\\|AtomDotExp = X {String.token AtomDotExp &. AtomStr ExpStr} Atom = {String.toAtom AtomStr} Exp = {ParseExp ExpStr} end end proc {FindExps Right Left Exp1 Exp2} if {And {IsExp Right} {IsExp Left}} then Exp2 = {ParseExp Right} Exp1 = {ParseExp Left} elseif Right == nil then % {Browse "Error!"} Exp1 = error Exp2 = error else local Right1 Left1 Head in {String.token Right & Head Right1} if Left == nil then Left1 = Head else Left1 = {Flatten [Left " " Head]} end {FindExps Right1 Left1 Exp1 Exp2} end end end proc {FindExp1AndExp2 Exp1SpaceExp2 Exp1 Exp2} {FindExps Exp1SpaceExp2 nil Exp1 Exp2} end proc {ParseApp X Exp1 Exp2} % "(Exp1 Exp2)" local Exp1SpaceExp2Right Exp2SpaceExp1 Exp1SpaceExp2 in &(|Exp1SpaceExp2Right = X &)|Exp2SpaceExp1 = {Reverse Exp1SpaceExp2Right} Exp1SpaceExp2 = {Reverse Exp2SpaceExp1} {FindExp1AndExp2 Exp1SpaceExp2 Exp1 Exp2} end end fun {IsAtom X} if X == nil then false elseif {Member &( X} then false elseif {Member &) X} then false elseif {Member & X} then false elseif {Member &. X} then false elseif {Member &\\ X} then false else true end end fun {IsLambda X} if X == nil then false elseif X.1 \= &\\ then false else local Y Atom Exp in Y = X.2 {String.token Y &. Atom Exp} {And {IsAtom Atom} {IsExp Exp}} end end end fun {CheckExp1Exp2 Right Left} if Right == nil then false elseif {And {IsExp Right} {IsExp Left}} then true else local Head Right1 Left1 in {String.token Right & Head Right1} if Left == nil then Left1 = Head else Left1 = {Flatten [Left " " Head]} end {CheckExp1Exp2 Right1 Left1} end end end fun {IsApp X} if X == nil then false elseif X.1 \= &( then false elseif {Reverse X.2}.1 \= &) then false else local Exp1SpaceExp2 in Exp1SpaceExp2 = {Reverse {Reverse X.2}.2} {CheckExp1Exp2 Exp1SpaceExp2 nil} end end end fun {IsExp X} if {IsAtom X} then true elseif {IsLambda X} then true elseif {IsApp X} then true else false end end fun {ParseExp X} local Atom Exp Exp1 Exp2 in case X of &(|_ then {ParseApp X Exp1 Exp2} [Exp1 Exp2] [] &\\|_ then {ParseLambda X Atom Exp} lambda(Atom Exp) else {String.toAtom X} end end end fun {ParseExps X} case X of nil then nil else {ParseExp X.1}|{ParseExps X.2} end end fun {GetExpsFromFile FileName} {ParseExps {GetLinesFromFile FileName}} end % {Browse {GetExpsFromFile "input.lambda"}} end