public static Pair FromArrayAt(Object[] array, int pos) { Pair retval = null; for (int i = array.Length - 1; i >= pos; i--) { retval = Pair.Cons(array[i], retval); } return(retval); }
static public Pair read_list(Pair list_so_far, TextReader str) { object token = read_token(str); if (token == null) // at the end of the stream, but no list. this is bad. { throw new Exception("Error parsing list: " + Util.Dump(Pair.reverse(list_so_far)).TrimEnd(new char[] { ')' })); // a continuation would be handy here } if (right_paren_token.Equals(token)) { return(Pair.reverse(list_so_far)); // if this far we're cool } else if (start_vector_token.Equals(token)) { return(read_list(Pair.Cons(read_vector(str), list_so_far), str)); } else if (left_paren_token.Equals(token)) { // if (str is DocumentReader) // { // DocumentReader documentReader = (DocumentReader) str; // //EditPoint startEditPoint = documentReader.editPoint.CreateEditPoint(); // //startEditPoint.CharLeft(1); // int startEditPointLine = documentReader.Line; // int startEditPointCol = documentReader.Col; // Pair curList = read_list(null,str); // // if (curList != null) // // curList.marker = new Marker(documentReader.document, startEditPointLine, startEditPointCol, documentReader.Line, documentReader.Col + 1, "");//startEditPoint.GetText(documentReader.editPoint)); // return read_list(Pair.Cons(curList, list_so_far), str); // } // else return(read_list(Pair.Cons(read_list(null, str), list_so_far), str)); } else if (IsMember(list_so_far, token)) { AddMemberToCar(list_so_far, token); return(read_list(list_so_far, str)); } else { return(read_list(Pair.Cons(token, list_so_far), str)); } }
public static object read_token(TextReader str) { if (str.Peek() == -1) { return(null); } char c = (char)str.Read(); if (Char.IsWhiteSpace(c)) // is_char_whitespace(c)) // .IsWhiteSpace(c)) { return(read_token(str)); } else if (c.Equals(';')) { str.ReadLine(); /* * char curr = (char) str.Read(); * Console.WriteLine("skipping chars: "); * while (!c.Equals('\n') && !c.Equals('\r') && (str.Peek() != -1)) * { * * curr = (char) str.Read(); * Console.Write(curr); * } * Console.WriteLine("skipping line"); */ return(read_token(str)); } else if (c.Equals('(')) { return(left_paren_token); } else if (c.Equals(')')) { return(right_paren_token); } else if (c.Equals('\'')) // Quote { object curr = read(str); Pair newpair = new Pair(curr); return(Pair.Cons(Symbol.Create("quote"), newpair)); } else if (c.Equals('"')) { char curr = (char)str.Read(); string strtok = ""; while (!curr.Equals('"')) { strtok += curr; int curr_as_int = str.Read(); if (curr_as_int == -1) { throw new Exception("Error parsing string: \"" + strtok + "\""); } else { curr = (char)curr_as_int; } } return(strtok); } else if (c.Equals('#')) // Boolean OR Character OR Vector { char curr = (char)str.Read(); if (curr.Equals('\\')) // itsa char { return((char)str.Read()); } else if (curr.Equals('(')) { return(start_vector_token); } else // itsa bool { if (curr.Equals('t')) { return(true); } else { return(false); // should maybe also check for #a, etc. } } } else if (Char.IsNumber(c) || (c.Equals('-') && !Char.IsWhiteSpace((char)str.Peek()))) { string numstr = new string(c, 1); while (Char.IsNumber((char)str.Peek()) || ((char)str.Peek()).Equals('.')) { numstr += (char)str.Read(); } if (numstr.IndexOf('.') != -1) { return(Convert.ToSingle(numstr)); } else { return(Convert.ToInt32(numstr)); } } else //if (Char.IsLetter(c)) { string symstr = new string(c, 1); while (!Char.IsWhiteSpace((char)str.Peek()) && !((char)str.Peek()).Equals(')') && (str.Peek() != -1)) { symstr += (char)str.Read(); } return(Symbol.Create(symstr)); } }
public object Call(Object[] args) { return(Pair.Cons(args[0], args[1] as Pair)); }
public object Eval(TextReader str) { //Console.WriteLine("starting eval"); Object evaledObj = null; Object parsedObj = Util.read(str); if (parsedObj is Pair) { if (macros.Count > 0) { // bool curRunHidden = DebugInfo.RunHidden; // DebugInfo.RunHidden = true; //don't debug the macro expension code Closure macroExpand = initEnv.Apply(Symbol.Create("macro-expand")) as Closure; parsedObj = macroExpand.Eval(new Object[] { parsedObj }); // DebugInfo.RunHidden = curRunHidden; } Pair p = parsedObj as Pair; switch (p.car.ToString()) { case "define": Expression expr = null; Symbol def = null; if (p.cdr.car is Pair) // (define (fn x y) body) { Pair def_and_args = p.cdr.car as Pair; Pair body = p.cdr.cdr; Pair syms = def_and_args.cdr; def = Symbol.Create(def_and_args.car.ToString()); expr = Expression.Parse(Pair.Cons(Symbol.Create("lambda"), Pair.Cons(syms, body))); // Debug.WriteLine(def + "-->" + expr); } else // (define fn (lambda (x y) body)) { def = Symbol.Create(p.cdr.car.ToString()); expr = Expression.Parse(p.cdr.cdr.car); } //initEnv = new Extended_Env(new Pair(def), new Pair(null), initEnv); //Object value = Eval(expr); //Console.WriteLine("defining: " + def); // expr.Mark(p); initEnv.Bind(def, Eval(expr)); break; case "macro": Symbol name = p.cdr.car as Symbol; // Console.WriteLine("macrodef" + name + " " + Expression.Parse(p.cdr.cdr.car).Eval(initEnv).ToString()); Closure transformer = (Closure)Expression.Parse(p.cdr.cdr.car).Eval(initEnv); this.macros[name] = transformer; // Console.WriteLine("macro: " + name); break; default: // need to call macro-expand in here. but how? evaledObj = Util.Dump(Eval(Expression.Parse(parsedObj))); break; } } else { evaledObj = Util.Dump(Eval(Expression.Parse(parsedObj))); } if (str.Peek() == -1) { return(evaledObj); } else { return(Eval(str)); } }