Exemple #1
0
        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());
        }
Exemple #2
0
        public static object Funcall(string functionName, params object[] args)
        {
            var sym = Runtime.FindSymbol(functionName);

            return(Runtime.Apply(sym, args));
        }
Exemple #3
0
        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));
            }
        }
Exemple #5
0
        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);
        }