private object CompileUnary() { // unary-expr: postfix-expr // unary-expr: unary-op unary-expr // unary-op: '-' '!' '~' var str = Token as string; if (str != null) { switch (str) { case "(": { // fall thru into compilePostFix. break; } case "-": { Accept(); var node = CompileUnary(); return(Runtime.MakeList(Runtime.FindSymbol("-"), node)); } case "~": { Accept(); var node = CompileUnary(); return(Runtime.MakeList(Runtime.FindSymbol("bit-not"), node)); } case "!": { Accept(); var node = CompileUnary(); return(Runtime.MakeList(Runtime.FindSymbol("not"), node)); } default: { throw new LispException("Invalid operator {0} in infix expression: {1}", str, InfixStr); } } } return(CompilePow()); }
public static object Funcall(string functionName, params object[] args) { var sym = Runtime.FindSymbol(functionName); return(Runtime.Apply(sym, args)); }
private Symbol GetLispOperator(object oper) { switch ((string)oper) { case "==": { return(Symbols.Equality); } case "||": { return(Symbols.Or); } case "&&": { return(Symbols.And); } case "!": { return(Symbols.Not); } case "|": { return(Symbols.BitOr); } case "&": { return(Symbols.BitAnd); } case "~": { return(Symbols.BitNot); } case "^": { return(Symbols.BitXor); } case "**": { return(Symbols.Pow); } case "<<": { return(Symbols.BitShiftLeft); } case ">>": { return(Symbols.BitShiftRight); } default: { return(Runtime.FindSymbol((string)oper)); } } }
public object MaybeRead(object eofValue = null) { SkipWhitespace(); var code = ReadChar(); if (IsEof) { return(eofValue); } var item = GetEntry(code); if (item.Type == CharacterType.TerminatingMacro || item.Type == CharacterType.NonTerminatingMacro) { if (item.DispatchReadtable == null) { if (item.Handler == null) { throw MakeScannerException("Invalid character: '{0}'", code); } else { return(item.Handler(this, code)); } } else { var arg = ReadDecimalArg(); var ch = ReadChar(); var target = ch.ToString(); var handlers = item.DispatchReadtable.Where(x => x.Key[0] == ch).ToList(); if (handlers.Count > 1 || (handlers.Count > 0 && handlers[0].Key.Length > 1)) { // form target key from letters var buf = new StringBuilder(); buf.Append(ch); while (true) { ch = ReadChar(); if (IsEof) { break; } if (!char.IsLetter(ch)) { UnreadChar(); break; } buf.Append(ch); } target = buf.ToString(); handlers = handlers.Where(x => x.Key == target).ToList(); } if (handlers.Count != 0) { var handler = handlers[0]; var form = handler.Value(this, handler.Key, arg); return(form); } else { throw MakeScannerException("Invalid character combination: '{0}{1}'", code, target); } } } UnreadChar(); var token = ReadToken(); object numberValue; object timespan; if (symbolSuppression > 0) { return(null); } else if ((numberValue = token.TryParseNumber()) != null) { return(numberValue); } else if ((timespan = token.TryParseTime()) != null) { return(timespan); } else if (token == "true") { return(true); } else if (token == "false") { return(false); } else if (token == "null") { return(null); } else if (token.Length > 1 && token[0] == '.') { // .a.b.c maps to ( . "a" "b" "c" ) return(Runtime.MakeList(Symbols.Dot, token.Substring(1))); } else if (token.Length > 1 && token[0] == '?') { // ?a.b.c maps to ( ? "a" "b" "c" ) return(Runtime.MakeList(Symbols.NullableDot, token.Substring(1))); } else { return(Runtime.FindSymbol(token)); } }
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); }