private object CompileBinary(CompileHelper leftHelper, CompileHelper rightHelper, params string[] opers) { var node1 = leftHelper(); var oper = Runtime.Find(Token, opers); if (oper != null) { Accept(); var node2 = rightHelper(); return(Runtime.MakeList(GetLispOperator(oper), node1, node2)); } return(node1); }
private void CompileList(Vector list, CompileHelper helper, params string[] opers) { var node1 = helper(); if (node1 == null) { return; } list.Add(node1); if (Tokens.Count != 0) { var oper = Runtime.Find(Token, opers); if (oper != null) { Accept(); list.Add(oper); CompileList(list, helper, opers); } } }
public Vector Scanner(string infix) { var v = new Vector(); var index = 0; while (index < infix.Length) { int pos = index; char ch = infix[index]; if (Char.IsWhiteSpace(ch)) { // Skip white space ++index; } else if (Char.IsDigit(ch)) { // Numbers can have decimal point. // No commas allowed since this would break function parameter list syntax. while (index < infix.Length) { ch = infix[index]; // Same as below. If there are letters, this will give runtime error. if (!(Char.IsLetterOrDigit(ch) || ch == '.' || ch == '_')) { break; } ++index; } var number = infix.Substring(pos, index - pos); v.Add(number.ParseNumber()); } else if (Char.IsLetter(ch) || ch == '_') { // ident while (index < infix.Length) { ch = infix[index]; if (!(Char.IsLetterOrDigit(ch) || ch == '_')) { break; } ++index; } var ident = infix.Substring(pos, index - pos); v.Add(Runtime.FindSymbol(ident)); } else if (index + 1 < infix.Length) { var oper = infix.Substring(index, 2); if (Runtime.Find(oper, Opers) == null) { oper = infix.Substring(index, 1); if (Runtime.Find(oper, Opers) == null) { throw new LispException("Invalid operator {0} in infix expression: {1}", oper, infix); } } index += oper.Length; v.Add(oper); } else { var oper = infix.Substring(index, 1); if (Runtime.Find(oper, Opers) == null) { throw new LispException("Invalid operator {0} in infix expression: {1}", oper, infix); } index += oper.Length; v.Add(oper); } } return(v); }