package Ġcom . nin jac ont rol . kr isp Ċ Ċ fun Ġread ( input : ĠString ) Ġ= Ġread Str ( input ) Ċ Ċ fun Ġeval ( ast : ĠMal Type , Ġenv : ĠEnvironment ): ĠMal Type Ġ{ ĊĠĠĠ Ġvar Ġcurrent Ast Ġ= Ġast ĊĠĠĠ Ġvar Ġnext Ast Ġ= Ġast ĊĠĠĠ Ġvar Ġcurrent Env Ġ= Ġenv ĊĠĠĠ Ġvar Ġnext Env Ġ= Ġcurrent Env ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġnull Ġwhen Ġa Ġnew Ġenvironment Ġand Ġast Ġhas Ġbeen Ġset , ĠMal Type Ġotherwise ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġapply : Ġ() Ġ-> ĠMal Type ? Ġ= Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġevaluated List Ġ= Ġeval Ast ( current Ast , Ġcurrent Env )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal List Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġf Ġ= Ġevaluated List . head ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Function Container Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġwhen Ġ( f . params ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal List Ġ-> Ġf . params ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Vector Ġ-> Ġf . params . asList () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( params Ġ== Ġnull ) Ġthrow ĠInvalidArgumentException (" Invalid Ġparameter Ġtype ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Env Ġ= ĠEnvironment . with Bindings ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġouter Ġ= Ġf . environment , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbindings Ġ= Ġparams . items , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexpressions Ġ= Ġevaluated List . tail . items ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Env Ġ= Ġnew Env ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Ast Ġ= Ġf . ast ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Function Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġf . apply ( evalu ated List . tail ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠEvaluation Exception (" Not Ġa Ġfunction ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠEvaluation Exception (" Cannot Ġapply ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( current Ast Ġ! is ĠMal List ) Ġreturn Ġeval Ast ( current Ast , Ġcurrent Env ) ĊĠĠĠĠĠĠĠ Ġcurrent Ast Ġ= Ġmacro Expand ( current Ast , Ġcurrent Env ) ĊĠĠĠĠĠĠĠ Ġ// Ġcheck Ġresulting ĠAST Ġagain Ġafter Ġmacro Ġexpansion ĊĠĠĠĠĠĠĠ Ġif Ġ( current Ast Ġ! is ĠMal List ) Ġreturn Ġeval Ast ( current Ast , Ġcurrent Env ) ĊĠĠĠĠĠĠĠ Ġif Ġ( current Ast . isEmpty ()) Ġreturn Ġcurrent Ast ĊĠĠĠĠĠĠĠ Ġval Ġhead Ġ= Ġcurrent Ast . head ĊĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . def Ġ-> Ġreturn Ġdefine ( current Ast . tail , Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . let Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( result Ast , Ġnew Env ) Ġ= Ġlet ( current Ast . tail , Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ast Ġis ĠMal Error ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult Ast ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Ast Ġ= Ġresult Ast ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Env ?. let Ġ{ Ġnext Env Ġ= Ġnew Env Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols .` do ` Ġ-> Ġnext Ast Ġ= Ġ` do `( current Ast . tail , Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols .` if ` Ġ-> Ġnext Ast Ġ= Ġ` if `( current Ast . tail , Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . fn Ġ-> Ġnext Ast Ġ= Ġfn ( current Ast . tail , Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . quote Ġ-> Ġreturn Ġquote ( current Ast . tail ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . qu asi quote expand Ġ-> Ġreturn Ġqu asi quote ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġunwrap Single ( current Ast . tail ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Env ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . qu asi quote Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Ast Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqu asi quote ( unwrap Single ( current Ast . tail ), Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . def Macro Ġ-> Ġreturn Ġdef Macro ( current Ast . tail , Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols . macro Expand Ġ-> Ġreturn Ġmacro Expand ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġunwrap Single ( current Ast . tail ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Env ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhead Ġeq ĠS ymbols .` try ` Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Ast Env Ġ= Ġtry Catch ( current Ast . tail , Ġcurrent Env ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Ast Ġ= Ġnext Ast Env . first ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Env Ġ= Ġnext Ast Env . second ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġapply ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcurrent Ast Ġ= Ġnext Ast ĊĠĠĠĠĠĠĠ Ġcurrent Env Ġ= Ġnext Env ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġtry Catch ( ast : ĠMal List , Ġenv : ĠEnvironment ): ĠPair < Mal Type , ĠEnvironment > Ġ{ ĊĠĠĠ Ġif Ġ( ast . size Ġ< Ġ 1 ) Ġthrow ĠInvalidArgumentException (" Invalid Ġnumber Ġof Ġarguments ") ĊĠĠĠ Ġval Ġtry Form Ġ= Ġast . get ( 0 ) ĊĠĠĠ Ġif Ġ( ast . size Ġ== Ġ 1 ) Ġ{ Ġ// Ġaccept Ġa Ġtry Ġexpression Ġwithout Ġa Ġcatch ĊĠĠĠĠĠĠĠ Ġreturn Ġeval ( try Form , Ġenv ) Ġto Ġenv ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġwhen Ġ( val Ġcatch Form Ġ= Ġast . get ( 1 )) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠMal List Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcatch Form . size Ġ!= Ġ 3 Ġ-> Ġthrow ĠInvalidArgumentException (" Expected Ġa Ġcatch Ġexpression Ġwith Ġtwo Ġarguments ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcatch Form . head Ġne q ĠS ymbols . catch Ġ-> Ġthrow ĠInvalidArgumentException (" Expected Ġa Ġ' catch ' Ġexpression Ġfollowing Ġ' try '. ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcatch Form . get ( 1 ) Ġ! is ĠMal Symbol Ġ-> Ġthrow ĠInvalidArgumentException (" Expected Ġsymbol ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtry Result Ġ= Ġeval ( try Form , Ġenv ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Result Ġto Ġenv ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexception Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e Ġis ĠUser Exception ) Ġe . toMap () Ġelse Ġe . toMap () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbind Symbol Ġ= Ġcatch Form . get ( 1 ) Ġas ĠMal Symbol ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Env Ġ= ĠEnvironment ( outer Ġ= Ġenv ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcatch Expression Ġ= Ġcatch Form . get ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Env . set ( bind Symbol , Ġexception ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcatch Expression Ġto Ġnew Env ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠInvalidArgumentException (" Expected Ġa Ġlist ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġunwrap Single ( ast : ĠMal List ) Ġ= Ġwhen Ġ( ast . size ) Ġ{ ĊĠĠĠĠ 1 Ġ-> Ġast . head ĊĠĠĠ Ġelse Ġ-> Ġast Ċ } Ċ Ċ fun Ġfn ( expressions : ĠMal List , Ġenv : ĠEnvironment ): ĠMal Type Ġ{ ĊĊĠĠĠ Ġif Ġ( expressions . size Ġ!= Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠInvalidArgumentException (" Invalid Ġnumber Ġof Ġarguments , Ġexpected Ġ 2 ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġfunction Bindings : ĠList < Mal Type > Ġ= Ġwhen Ġ( val Ġbindings Ġ= Ġexpressions . get ( 0 )) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠMal List Ġ-> Ġbindings . items ĊĠĠĠĠĠĠĠ Ġis ĠMal Vector Ġ-> Ġbindings . items ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠInvalidArgumentException (" Error Ġcreating Ġbindings , Ġinvalid Ġtype , Ġexpected Ġlist Ġor Ġvector ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġfn Ġ= ĠMal Function Ġ{ Ġfunction Arguments Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġnew Env Ġ= ĠEnvironment . with Bindings ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġenv , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbindings Ġ= Ġfunction Bindings , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpressions Ġ= Ġfunction Arguments . toList () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġreturn @ Mal Function Ġeval ( expressions . get ( 1 ), Ġnew Env ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠMal Function Container ( ĊĠĠĠĠĠĠĠ Ġast Ġ= Ġexpressions . get ( 1 ), ĊĠĠĠĠĠĠĠ Ġparams Ġ= Ġexpressions . get ( 0 ), ĊĠĠĠĠĠĠĠ Ġenvironment Ġ= Ġenv , ĊĠĠĠĠĠĠĠ Ġfn Ġ= Ġfn ĊĠĠĠ Ġ) Ċ } Ċ Ċ fun Ġ` if `( expressions : ĠMal List , Ġenv : ĠEnvironment ): ĠMal Type Ġ{ ĊĠĠĠ Ġif Ġ( expressions . size Ġ< Ġ 2 ) Ġthrow ĠInvalidArgumentException (" Invalid Ġconditional Ġexpression ") ĊĠĠĠ Ġreturn Ġwhen Ġ( val Ġcondition Ġ= Ġeval ( expressions . get ( 0 ), Ġenv )) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠMal Boolean , Ġis ĠMal Nil Ġ-> Ġwhen Ġ( condition ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFalse , ĠMal Nil Ġ-> Ġexpressions . get OrNull ( 2 ) Ġ?: ĠMal Nil ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġexpressions . get ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġexpressions . get ( 1 ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġ` do `( expressions : ĠMal List , Ġenv : ĠEnvironment ): ĠMal Type Ġ{ ĊĠĠĠ Ġif Ġ( expressions . isEmpty ()) Ġreturn ĠMal Nil ĊĠĠĠ Ġeval Ast ( expressions . sub List ( 0 , Ġexpressions . size ), Ġenv ) ĊĠĠĠ Ġreturn Ġexpressions . last Ċ } Ċ Ċ fun Ġmacro Expand ( ast : ĠMal Type , Ġenv : ĠEnvironment ): ĠMal Type Ġ{ ĊĠĠĠ Ġvar Ġcurrent Ast Ġ= Ġast ĊĠĠĠ Ġwhile Ġ( is Macro Call ( current Ast , Ġenv )) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġis Macro Call Ġensures Ġthat Ġthe Ġast Ġhas Ġthe Ġfollowing Ġcontent ĊĠĠĠĠĠĠĠ Ġval Ġast List Ġ= Ġast Ġas ĠMal List ĊĠĠĠĠĠĠĠ Ġval Ġsymbol Ġ= Ġast List . head Ġas ĠMal Symbol ĊĠĠĠĠĠĠĠ Ġval Ġfunction Container Ġ= Ġenv . get ( symbol ) ĊĠĠĠĠĠĠĠ Ġval Ġfunction Ġ= Ġ( function Container Ġas ĠMal Function Container ). fn ĊĠĠĠĠĠĠĠ Ġval Ġarguments Ġ= Ġast List . tail ĊĠĠĠĠĠĠĠ Ġcurrent Ast Ġ= Ġfunction . apply ( arguments ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġcurrent Ast Ċ } Ċ Ċ fun Ġis Macro Call ( ast : ĠMal Type , Ġenv : ĠEnvironment ) Ġ= Ġwhen Ġ{ ĊĠĠĠ Ġast Ġis ĠMal List Ġ&& Ġast . head Ġis ĠMal Symbol Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsymbol Ġ= Ġast . head Ġas ĠMal Symbol ĊĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġvalue Ġ= Ġenv . get Or Error ( symbol )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Function Container Ġ-> Ġvalue . is Macro ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ-> Ġfalse Ċ } Ċ Ċ fun Ġdef Macro ( binding List : ĠMal List , Ġenv : ĠEnvironment ): ĠMal Type Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( binding List . size ) Ġ{ ĊĠĠĠĠĠĠĠĠ 2 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġname Ġ= Ġbinding List . get ( 0 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Symbol Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġvalue Ġ= Ġeval ( binding List . get ( 1 ), Ġenv )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Function Container Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġvalue . copy ( is Macro Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenv . set ( name , ĠnewValue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġenv . set ( name , Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalidArgumentException (" Invalid Ġargument Ġ( symbol )") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠInvalidArgumentException (" Invalid Ġnumber Ġof Ġarguments ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġdefine ( binding List : ĠMal List , Ġenv : ĠEnvironment ): ĠMal Type Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( binding List . size ) Ġ{ ĊĠĠĠĠĠĠĠĠ 2 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġname Ġ= Ġbinding List . get ( 0 )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Symbol Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġeval ( binding List . get ( 1 ), Ġenv ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenv . set ( name , Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalidArgumentException (" Invalid Ġargument Ġ( symbol )") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠInvalidArgumentException (" Invalid Ġnumber Ġof Ġarguments ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġlet ( expressions : ĠMal List , Ġenv : ĠEnvironment ): ĠPair < Mal Type , ĠEnvironment ?> Ġ{ ĊĊĠĠĠ Ġfun Ġevaluate With Bindings ( ĊĠĠĠĠĠĠĠ Ġexpression : ĠMal Type , ĊĠĠĠĠĠĠĠ Ġbindings : ĠList < Mal Type >, ĊĠĠĠĠĠĠĠ Ġenv : ĠEnvironment ĊĠĠĠ Ġ): ĠPair < Mal Type , ĠEnvironment ?> Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( bindings . size Ġ% Ġ 2 Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbindings . chunk ed ( 2 ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġit [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevaluated Ġ= Ġeval ( it [ 1 ], Ġenv ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Ġ! is ĠMal Symbol ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalidArgumentException (" Error Ġevaluating Ġenvironment , Ġkey Ġmust Ġbe Ġa Ġsymbol ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenv . set ( key , Ġevaluated ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpression Ġto Ġenv Ġ// ĠT CO ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalidArgumentException (" Invalid Ġbinding Ġlist Ġ( odd Ġnumber Ġof Ġitems )") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġwhen Ġ( expressions . size ) Ġ{ ĊĠĠĠĠĠĠĠĠ 2 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Env Ġ= ĠEnvironment ( outer Ġ= Ġenv ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Bindings Ġ= Ġexpressions . get ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpression Ġ= Ġexpressions . get ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( new Bindings ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal List Ġ-> Ġevaluate With Bindings ( expression , Ġnew Bindings . items , Ġnew Env ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠMal Vector Ġ-> Ġevaluate With Bindings ( expression , Ġnew Bindings . items , Ġnew Env ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠInvalidArgumentException (" Invalid Ġbinding Ġ( not Ġa Ġlist Ġor Ġvector )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠInvalidArgumentException (" Invalid Ġnumber Ġof Ġarguments ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġquote ( ast : ĠMal List ): ĠMal Type Ġ{ ĊĠĠĠ Ġreturn Ġast . get OrNull ( 0 ) Ġ?: ĠMal Nil Ċ } Ċ Ċ fun Ġqu asi quote ( ast : ĠMal Type , Ġ_ env : ĠEnvironment ): ĠMal Type Ġ{ ĊĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġast Ġis ĠMal List Ġ&& Ġast . head Ġeq ĠS ymbols . un quote Ġ-> Ġast . get OrNull ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠInvalidArgumentException (" Invalid Ġarguments ") ĊĠĠĠĠĠĠĠ Ġast Ġis ĠMal List Ġ|| Ġast Ġis ĠMal Vector Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġelements Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ast Ġis ĠMal List ) Ġast . items . as Re versed () Ġelse Ġ( ast Ġas ĠMal Vector ). items . as Re versed () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( element Ġin Ġelements ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelement Ġis ĠMal List Ġ&& Ġelement . head Ġeq ĠS ymbols .` splice - un quote ` Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( element . size Ġ< Ġ 2 ) Ġthrow ĠInvalidArgumentException (" Invalid Ġnumber Ġof Ġarguments ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist ( Symbols . concat , Ġelement . get ( 1 ), Ġresult ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlist ( Symbols . cons , Ġqu asi quote ( element , Ġ_ env ), Ġresult ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ast Ġis ĠMal Vector ) Ġlist ( Symbols . vec , Ġresult ) Ġelse Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġast Ġis ĠMal Map Ġ|| Ġast Ġis ĠMal Symbol Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlist ( Symbols . quote , Ġast ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġast ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġeval Ast ( ast : ĠMal Type , Ġenv : ĠEnvironment ): ĠMal Type Ġ= Ġwhen Ġ( ast ) Ġ{ ĊĠĠĠ Ġis ĠMal Symbol Ġ-> Ġenv . get ( ast ) ĊĠĠĠ Ġis ĠMal List Ġ-> ĠMal List ( items Ġ= Ġast . items . map Ġ{ Ġitem Ġ-> Ġeval ( item , Ġenv ) Ġ}. to Mutable List ()) ĊĠĠĠ Ġis ĠMal Vector Ġ-> ĠMal Vector ( items Ġ= Ġast . items . map Ġ{ Ġitem Ġ-> Ġeval ( item , Ġenv ) Ġ}. to Mutable List ()) ĊĠĠĠ Ġis ĠMal Map Ġ-> ĠMal Map ( ĊĠĠĠĠĠĠĠ Ġitems Ġ= Ġast . items . map Values Ġ{ Ġ(_, Ġvalue ) Ġ-> Ġeval ( value , Ġenv ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Mutable Map () ĊĠĠĠ Ġ) ĊĠĠĠ Ġelse Ġ-> Ġast Ċ } Ċ