# www.jquigley.com # Sat Feb 24 02:06:20 CST 2007 Sexpr := Object clone do ( constants := Map clone constants atPut( "t", true ) constants atPut( "nil", true ) #--------------------------------------------------------------------------- pt := Object clone do ( asString := method( if (xtype == "CONS") then( str := "(#{car} . #{cdr})" interpolate ) else ( str := "atom[type=#{xtype}, lexeme=\"#{lexeme}\"]" interpolate ) str ) ) #--------------------------------------------------------------------------- newBool := method( cond, if( cond ) then( atom := newAtom("t") ) else ( atom := newAtom("nil") ) atom ) #--------------------------------------------------------------------------- newString := method( content, atom := pt clone atom xtype := "STR" atom lexeme := Sequence clone copy(content) atom ) #--------------------------------------------------------------------------- newOperator := method( op, atom := pt clone if( op == "(" ) then( atom xtype := "LEFTPAREN" ) elseif ( op == ")" ) then( atom xtype := "RIGHTPAREN" ) else ( atom xtype := "OP" ) atom lexeme := Sequence clone copy(op) atom ) #--------------------------------------------------------------------------- newAtom := method( _atom, sexpr := pt clone # TODO: how do we force _atom to be a Sequence atom := "#{_atom}" interpolate if( Sexpr constants hasKey(atom) ) then( # constant sexpr xtype := "LITERAL" ) elseif ( atom asNumber isNan ) then( # symbol sexpr xtype := "SYM" ) else ( # numeric sexpr xtype := "NUM" ) sexpr lexeme := Sequence clone copy( atom ) sexpr ) #--------------------------------------------------------------------------- newFun := method( name, fun, special, if( special isNil, special = "" ) func := Object clone func xtype := "FUN" func lexeme := Sequence clone copy(name) func fun := getSlot("fun") func special := Sequence clone copy(special) func ) #--------------------------------------------------------------------------- cons := method( a, b, sexpr := pt clone sexpr xtype := "CONS" sexpr car := a sexpr cdr := b sexpr ) #--------------------------------------------------------------------------- prettyPrint := method( sexpr, inList, pretty := Sequence clone if( sexpr xtype == "CONS" ) then ( str := Sequence clone if( inList ) then ( str appendSeq(" ") ) else ( str appendSeq("(") ) str appendSeq( prettyPrint(sexpr car) ) str appendSeq( prettyPrint(sexpr cdr, true) ) if( inList isNil ) then ( str appendSeq(")") ) pretty copy(str) ) else ( str := Sequence clone if( inList and (sexpr xtype != "LITERAL" or sexpr lexeme != "nil") ) \ then ( str appendSeq(" . ") ) if( sexpr xtype == "FUN" ) then ( if( sexpr special == "macro" ) then ( str appendSeq( "#macro'" ) ) else ( str appendSeq( "#'" ) ) ) if( inList isNil or sexpr xtype != "LITERAL" or sexpr lexeme != "nil" ) then ( if( sexpr xtype == "STR" ) then ( str appendSeq( "\"" ) ) str appendSeq( sexpr lexeme ) if( sexpr xtype == "STR" ) then ( str appendSeq( "\"" ) ) ) pretty copy( str ) ) pretty ) ) # EOF