public static Object process(Object o) { if (o is string) { string s = (string)o; if (s[0] == '"') { return(s.Substring(1, s.Length - 2)); } if (s[0] == '&') { if ((s.Length > 1) && s[1] == '\"') { return(Symbol.make(s.Substring(2, s.Length - 3))); } else { return(Symbol.make(s)); } } if (s[0] >= '0' && s[0] <= '9') { return(tryNum(s)); } if ((s[0] == '-' || s[0] == '+') && s.Length > 1 && (s[1] >= '0' && s[1] <= '9')) { return(tryNum(s)); } if (s.Equals("#f")) { return(Runtime._false); } if (s.Equals("#t")) { return(Runtime._true); } if (s.StartsWith("#\\")) { if (s.Length == 3) { return(s[2]); } string ss = s.Substring(2, s.Length - 2); switch (ss) { case "Newline": return('\n'); case "Tab": return('\t'); case "Space": return(' '); case "LBR": return('('); case "RBR": return(')'); case "Semicolon": return(';'); } if (ss.Length > 5) { if (ss.Substring(0, 5).Equals("ASCII")) { return((char)(Int32.Parse(ss.Substring(5, ss.Length - 5)))); } } if (s.Equals("#\\")) { return('\\'); } return(Symbol.make("Char(" + s + ")")); } Symbol sym = Symbol.make(s); return(sym); } else if (o is pospair) { pospair pp = (pospair)o; return(new Pair(annotatetag, new Pair(new Pair(pp.sfile, new Pair(pp.line, new Pair(pp.col, null))), new Pair(process(pp.s), null)))); } else if (o is Pair) { Pair p = (Pair)o; if (p.car != null) { string pc = null; if (p.car is string) { pc = (string)p.car; } else if (p.car is pospair) { pc = ((pospair)(p.car)).s; } if (pc != null) { Object oo = null; if (pc.Equals("'")) { oo = thequote; } else if (pc.Equals(",")) { oo = theunquote; } else if (pc.Equals("`")) { oo = thequasiquote; } else if (pc.Equals(",@")) { oo = thesplicing; } if (oo != null) { return(new Pair(new Pair(oo, new Pair(process(p.cadr()), null)), process(p.cddr()))); } } } p.car = process(p.car); p.cdr = process(p.cdr); return(p); } return(o); }
public static Object aread(ExtendedReader r) { Object prev_p = null; Stack top = new Stack(); char[] c = new char[1]; bool rd = true; bool annotate = r.annotate; int state = 0; string s = ""; pospair strt = null; pospair crnt = null; System.Collections.Stack st = new System.Collections.Stack(); System.Collections.Stack pos = new System.Collections.Stack(); while (true) { char ch; if (!rd) { if (top.Count > 0) { return(top.Pop()); } else { return(null); } } int n = r.Read(c, 0, 1); if (annotate) { crnt = new pospair(r.file, r.linepos, r.cpos); } if (n == 0) { rd = false; // stop ch = ' '; // simulate end of something goto cont; } ch = c[0]; //Console.Write(ch); cont: if (state == 0) { switch (ch) { case '(': { // start a new list; Pair p = new Pair(null, null); top.Push(p); st.Push(p); pos.Push(0); // will fill car first prev_p = p; break; } case ')': { // pop a list if (top.Count < 1) { throw new Meta.Scripting.MBaseException(new Pair(Symbol.make("READER-ERROR-AT:"), prev_p)); } Object p = top.Pop(); if (p is Pair) { Pair pp = (Pair)p; if (pp.car == null && pp.cdr == null) { p = null; } } st.Pop(); // discard it pos.Pop(); //discard it if (!popper(st, pos, p)) { return(p); } if (p != null) { prev_p = p; } state = 0; break; } case '.': { s = "" + ch; strt = crnt; state = 6; break; } case ';': { state = 4; // comment started break; } case ' ': case '\n': case '\t': case '\r': case '\f': { // just skip break; } case '\"': // start a string literal { s = "" + ch; strt = crnt; state = 2; break; } case '\'': case '`': // immediate { s = "" + ch; strt = crnt; if (!popper(st, pos, s)) { return(s); } s = ""; break; } case ',': // delay { s = "" + ch; strt = crnt; state = 5; break; } case '&': // another delayed reader { s = "" + ch; strt = crnt; state = 7; break; } default: // all other chars starts atoms { s = "" + ch; // start a new one; strt = crnt; state = 1; // atom processing break; } } } else if (state == 1) { if (ch == '(' || ch == ')' || Char.IsWhiteSpace(ch) || ch == ';') { // atom ends here, sorry if (annotate) { strt.s = s; if (!popper(st, pos, strt)) { return(strt); } } else { if (!popper(st, pos, s)) { return(s); } } if (s != null) { prev_p = s; } s = ""; state = 0; goto cont; // now process the termination character in a new state } else { s = s + ch; // add a char to an atom } } else if (state == 2) { if (ch == '\\') { state = 3; } else if (ch == '\"') { s = s + ch; state = 1; ch = ' '; // simulate an end of atom goto cont; } else { s = s + ch; } } else if (state == 3) { if (ch == 'n') { ch = '\n'; } else if (ch == 't') { ch = '\t'; } s = s + ch; state = 2; } else if (state == 4) { if (ch == '\n') { state = 0; // comment line finished } } else if (state == 5) { if (ch == '@') { s += ch; } if (!popper(st, pos, s)) { return(s); } state = 0; if (ch != '@') { goto cont; // otherwise read next char } } else if (state == 6) { if (ch == '.') { s += ch; state = 1; } else { state = 0; pos.Pop(); pos.Push(1); // will fill cdr, not a new cons cell goto cont; } } else if (state == 7) { if (ch == '\"') { s += ch; state = 2; } else { state = 1; goto cont; } } } }