public static object CompileQuasiQuote(int level, object arg, Environment environment) { if (level == 0) { return(Compile1(arg, environment)); } if (arg is ISequence) { ISequence c = (ISequence)arg; if (c.First() == UNQUOTE) { return(new Pair(UNQUOTE, new Pair(CompileQuasiQuote(level - 1, Runtime.Car(Runtime.Cdr(arg)), environment)))); } if ((level == 1) && (c.First() == UNQUOTE_SPLICING)) { return(new Pair(UNQUOTE_SPLICING, new Pair(CompileQuasiQuote(level - 1, Runtime.Car(Runtime.Cdr(arg)), environment)))); } if (c.First() == QUASIQUOTE) { return(new Pair(QUASIQUOTE, new Pair(CompileQuasiQuote(level + 1, Runtime.Car(Runtime.Cdr(arg)), environment)))); } Pair r = null; foreach (object o in c) { r = new Pair(CompileQuasiQuote(level, o, environment), r); } return(r.Reverse()); } return(arg); }
public static Expression Compile1(Object s, Environment environment) { // Literals are constants if (Runtime.IsLiteral(s)) { return(Expression.Constant(s)); } // Special Syntax gets expanded and compiled if (Runtime.IsSsyntax(s)) { return(Compile1(Runtime.ExpandSSyntax(s), environment)); } // Symbols are variable references if (s is Symbol) { return(CompileVarRef((Symbol)s)); } // Special Syntax gets expanded and compiled if (Runtime.IsSsyntax(Runtime.Car(s))) { object expansion = Runtime.ExpandSSyntax(((Pair)s).First()); return(Compile1(new Pair(expansion, (Pair)s), environment)); } if (s is Pair) { object f = ((Pair)s).First(); // Special Forms if (f == Symbol.FromName("if")) { return(Compiler.CompileIf(((Pair)s).Rest(), environment)); } if (f == Symbol.FromName("quote")) { return(Compiler.CompileQuote(((Pair)s).Rest(), environment)); } if (f == Symbol.FromName("call-clr")) { return(Compiler.CompileCall((Pair)((Pair)s).Rest(), environment)); } if (f == Symbol.FromName("call-instance")) { return(Compiler.CompileInstanceCall((Pair)((Pair)s).Rest(), environment)); } if (f == Symbol.FromName("fn")) { return(Compiler.CompileFn((Pair)((Pair)s).Rest(), environment)); } if (f == Symbol.FromName("macro")) { return(Compiler.CompileMac((Pair)((Pair)s).Rest(), environment)); } if (f == Symbol.FromName("quasiquote")) { return(Compiler.CompileQuasiQuote((Pair)((Pair)s).Rest(), environment)); } if ((f is Symbol) && (environment.Contains((Symbol)f))) { object value = environment.GetValue((Symbol)f); // Macros get invoked at compile time, then their results are themeselves compiled if (value is Macro) { object expansion = ((Macro)value).Call(Runtime.AsArray(((Pair)s).Rest())); return(Compile1(expansion, environment)); } } // It must be a function call return(CompileFunctionCall(f, ((Pair)s).Rest(), environment)); } throw new LSharpException(string.Format("Bad object in expression: ", s), environment); }