public static Expression Parse(object a) { if (a is Symbol) { if (((Symbol) a).val.IndexOf(".") == -1) return new Var(a as Symbol); else { string aString = ((Symbol) a).val; int posLastDot = aString.LastIndexOf("."); Expression[] rands = new Expression[2]; rands[0] = Expression.Parse(Symbol.Create(aString.Substring(0, posLastDot))); rands[1] = new Lit(Symbol.Create(aString.Substring(posLastDot + 1, aString.Length - posLastDot - 1))); return new App(Expression.Parse(Symbol.Create("get-property")), rands); } } if (a is Pair) { Pair pair = a as Pair; object car = pair.car; switch (car.ToString()) { case "begin": Expression[] exps = new Expression[pair.cdr.Count]; int pos = 0; foreach (object obj in pair.cdr) { exps[pos] = Parse(obj); // exps[pos].Mark(obj); pos++; } Begin beginExps = new Begin(exps); // beginExps.Mark(pair); return beginExps; case "if": Pair curr = pair.cdr; Expression test_exp = Parse(curr.car); // test_exp.Mark(curr.car); curr = curr.cdr; Expression true_exp = Parse(curr.car); // true_exp.Mark(curr.car); curr = curr.cdr; Expression false_exp = Parse(curr.car); // false_exp.Mark(curr.car); return new If(test_exp, true_exp, false_exp); case "quote": return new Lit(pair.cdr.car); case "set!": { Symbol var = pair.cdr.car as Symbol; if (var == null) throw new Exception("set! error -> variable must be a symbol: " + Util.Dump(pair)); Expression exp = Parse(pair.cdr.cdr.car) as Expression; // exp.Mark(pair.cdr.cdr.car); if (var.val.IndexOf('.') == -1) { Assignment assignment = new Assignment(var, exp); // assignment.Mark(pair); return assignment; } else { string aString = var.val; int posLastDot = aString.LastIndexOf("."); Expression[] rands = new Expression[3]; rands[0] = Expression.Parse(Symbol.Create(aString.Substring(0, posLastDot))); rands[1] = new Lit(Symbol.Create(aString.Substring(posLastDot + 1, aString.Length - posLastDot - 1))); rands[2] = exp; App app = new App(Expression.Parse(Symbol.Create("set-property")), rands); // app.Mark(pair); return app; } } case "lambda": // Debug.WriteLine("sparsing lambda " + pair.ToString()); curr = pair.cdr as Pair; Symbol[] ids = null; bool all_in_one = false; if (curr.car != null) { if (curr.car is Pair) { Object[] ids_as_obj = (curr.car as Pair).ToArray(); ids = new Symbol[ids_as_obj.Length]; for (int i=0; i<ids_as_obj.Length; i++) { ids[i] = ids_as_obj[i] as Symbol; if (ids[i] == null) throw new Exception("lambda error -> params must be symbols: " + Util.Dump(pair)); } } else { all_in_one = true; ids = new Symbol[1]; ids[0] = curr.car as Symbol; if (ids[0] == null) throw new Exception("lambda error -> params must be symbols: " + Util.Dump(pair)); } } curr = curr.cdr as Pair; // insert implied begin if neccessary Expression body; if (curr.cdr == null) { body = Parse(curr.car); // if (curr.car is Pair) // body.Mark(curr.car); // else // body.Mark(curr); } else { Expression[] begin = new Expression[curr.Count]; pos = 0; foreach (object obj in curr) { begin[pos] = Parse(obj); // begin[pos].Mark(obj); pos++; } body = new Begin(begin); } return new Proc(ids, body, all_in_one); default: // app if (pair.hasMember) { Expression[] rands = new Expression[2]; if (pair.member.IndexOf('.') != -1) { string currentMember = pair.member; int posLastDot = currentMember.LastIndexOf("."); pair.member = currentMember.Substring(0, posLastDot); rands[0] = Expression.Parse(pair); pair.member = currentMember; rands[1] = new Lit(Symbol.Create(currentMember.Substring(posLastDot + 1, currentMember.Length - posLastDot - 1))); } else { pair.hasMember = false; rands[0] = Expression.Parse(pair); pair.hasMember = true; rands[1] = new Lit(Symbol.Create(pair.member)); } return new App(Expression.Parse(Symbol.Create("get-property")), rands); } else { Expression[] rands = null; if (pair.cdr != null) { rands = new Expression[pair.cdr.Count]; pos = 0; foreach (object obj in pair.cdr) { rands[pos] = Expression.Parse(obj); // rands[pos].Mark(obj); pos++; } } IPrim prim = Primitives.getPrim(pair.car.ToString()); if (prim != null) { Primapp primapp = new Primapp(prim, rands); // primapp.Mark(pair); return primapp; } else { App app = new App(Expression.Parse(pair.car), rands); // app.Mark(pair); return app; } } } } else return new Lit(a); }
static public Expression Parse(object a) { if (a is Symbol) { if (((Symbol)a).val.IndexOf(".") == -1) { return(new Var(a as Symbol)); } else { string aString = ((Symbol)a).val; int posLastDot = aString.LastIndexOf("."); Expression[] rands = new Expression[2]; rands[0] = Expression.Parse(Symbol.Create(aString.Substring(0, posLastDot))); rands[1] = new Lit(Symbol.Create(aString.Substring(posLastDot + 1, aString.Length - posLastDot - 1))); return(new App(Expression.Parse(Symbol.Create("get-property")), rands)); } } if (a is Pair) { Pair pair = a as Pair; object car = pair.car; switch (car.ToString()) { case "begin": Expression[] exps = new Expression[pair.cdr.Count]; int pos = 0; foreach (object obj in pair.cdr) { exps[pos] = Parse(obj); // exps[pos].Mark(obj); pos++; } Begin beginExps = new Begin(exps); // beginExps.Mark(pair); return(beginExps); case "if": Pair curr = pair.cdr; Expression test_exp = Parse(curr.car); // test_exp.Mark(curr.car); curr = curr.cdr; Expression true_exp = Parse(curr.car); // true_exp.Mark(curr.car); curr = curr.cdr; Expression false_exp = Parse(curr.car); // false_exp.Mark(curr.car); return(new If(test_exp, true_exp, false_exp)); case "quote": return(new Lit(pair.cdr.car)); case "set!": { Symbol var = pair.cdr.car as Symbol; if (var == null) { throw new Exception("set! error -> variable must be a symbol: " + Util.Dump(pair)); } Expression exp = Parse(pair.cdr.cdr.car) as Expression; // exp.Mark(pair.cdr.cdr.car); if (var.val.IndexOf('.') == -1) { Assignment assignment = new Assignment(var, exp); // assignment.Mark(pair); return(assignment); } else { string aString = var.val; int posLastDot = aString.LastIndexOf("."); Expression[] rands = new Expression[3]; rands[0] = Expression.Parse(Symbol.Create(aString.Substring(0, posLastDot))); rands[1] = new Lit(Symbol.Create(aString.Substring(posLastDot + 1, aString.Length - posLastDot - 1))); rands[2] = exp; App app = new App(Expression.Parse(Symbol.Create("set-property")), rands); // app.Mark(pair); return(app); } } case "lambda": // Debug.WriteLine("sparsing lambda " + pair.ToString()); curr = pair.cdr as Pair; Symbol[] ids = null; bool all_in_one = false; if (curr.car != null) { if (curr.car is Pair) { Object[] ids_as_obj = (curr.car as Pair).ToArray(); ids = new Symbol[ids_as_obj.Length]; for (int i = 0; i < ids_as_obj.Length; i++) { ids[i] = ids_as_obj[i] as Symbol; if (ids[i] == null) { throw new Exception("lambda error -> params must be symbols: " + Util.Dump(pair)); } } } else { all_in_one = true; ids = new Symbol[1]; ids[0] = curr.car as Symbol; if (ids[0] == null) { throw new Exception("lambda error -> params must be symbols: " + Util.Dump(pair)); } } } curr = curr.cdr as Pair; // insert implied begin if neccessary Expression body; if (curr.cdr == null) { body = Parse(curr.car); // if (curr.car is Pair) // body.Mark(curr.car); // else // body.Mark(curr); } else { Expression[] begin = new Expression[curr.Count]; pos = 0; foreach (object obj in curr) { begin[pos] = Parse(obj); // begin[pos].Mark(obj); pos++; } body = new Begin(begin); } return(new Proc(ids, body, all_in_one)); default: // app if (pair.hasMember) { Expression[] rands = new Expression[2]; if (pair.member.IndexOf('.') != -1) { string currentMember = pair.member; int posLastDot = currentMember.LastIndexOf("."); pair.member = currentMember.Substring(0, posLastDot); rands[0] = Expression.Parse(pair); pair.member = currentMember; rands[1] = new Lit(Symbol.Create(currentMember.Substring(posLastDot + 1, currentMember.Length - posLastDot - 1))); } else { pair.hasMember = false; rands[0] = Expression.Parse(pair); pair.hasMember = true; rands[1] = new Lit(Symbol.Create(pair.member)); } return(new App(Expression.Parse(Symbol.Create("get-property")), rands)); } else { Expression[] rands = null; if (pair.cdr != null) { rands = new Expression[pair.cdr.Count]; pos = 0; foreach (object obj in pair.cdr) { rands[pos] = Expression.Parse(obj); // rands[pos].Mark(obj); pos++; } } IPrim prim = Primitives.getPrim(pair.car.ToString()); if (prim != null) { Primapp primapp = new Primapp(prim, rands); // primapp.Mark(pair); return(primapp); } else { App app = new App(Expression.Parse(pair.car), rands); // app.Mark(pair); return(app); } } } } else { return(new Lit(a)); } }