Пример #1
0
        private static Expression ParseEntityWithoutSuffixChain(TokenStream tokens, Executable owner)
        {
            string next = tokens.PeekValue();

            if (next == "null")
            {
                return(new NullConstant(tokens.Pop(), owner));
            }
            if (next == "true")
            {
                return(new BooleanConstant(tokens.Pop(), true, owner));
            }
            if (next == "false")
            {
                return(new BooleanConstant(tokens.Pop(), false, owner));
            }

            Token peekToken = tokens.Peek();

            if (next.StartsWith("'"))
            {
                return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner));
            }
            if (next.StartsWith("\""))
            {
                return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner));
            }
            if (next == "new")
            {
                return(ParseInstantiate(tokens, owner));
            }

            char firstChar = next[0];

            if (VARIABLE_STARTER.Contains(firstChar))
            {
                Token varToken = tokens.Pop();
                return(new Variable(varToken, varToken.Value, owner));
            }

            if (firstChar == '[')
            {
                Token             bracketToken = tokens.PopExpected("[");
                List <Expression> elements     = new List <Expression>();
                bool previousHasCommaOrFirst   = true;
                while (!tokens.PopIfPresent("]"))
                {
                    if (!previousHasCommaOrFirst)
                    {
                        tokens.PopExpected("]");                           // throws appropriate error
                    }
                    elements.Add(Parse(tokens, owner));
                    previousHasCommaOrFirst = tokens.PopIfPresent(",");
                }
                return(new ListDefinition(bracketToken, elements, owner));
            }

            if (firstChar == '{')
            {
                Token             braceToken = tokens.PopExpected("{");
                List <Expression> keys       = new List <Expression>();
                List <Expression> values     = new List <Expression>();
                bool previousHasCommaOrFirst = true;
                while (!tokens.PopIfPresent("}"))
                {
                    if (!previousHasCommaOrFirst)
                    {
                        tokens.PopExpected("}");                           // throws appropriate error
                    }
                    keys.Add(Parse(tokens, owner));
                    tokens.PopExpected(":");
                    values.Add(Parse(tokens, owner));
                    previousHasCommaOrFirst = tokens.PopIfPresent(",");
                }
                return(new DictionaryDefinition(braceToken, keys, values, owner));
            }

            if (next.Length > 2 && next.Substring(0, 2) == "0x")
            {
                Token intToken = tokens.Pop();
                int   intValue = IntegerConstant.ParseIntConstant(intToken, intToken.Value);
                return(new IntegerConstant(intToken, intValue, owner));
            }

            if (Parser.IsInteger(next))
            {
                Token  numberToken = tokens.Pop();
                string numberValue = numberToken.Value;

                if (tokens.IsNext("."))
                {
                    Token decimalToken = tokens.Pop();
                    if (decimalToken.HasWhitespacePrefix)
                    {
                        throw new ParserException(decimalToken, "Decimals cannot have whitespace before them.");
                    }

                    Token afterDecimal = tokens.Pop();
                    if (afterDecimal.HasWhitespacePrefix)
                    {
                        throw new ParserException(afterDecimal, "Cannot have whitespace after the decimal.");
                    }
                    if (!Parser.IsInteger(afterDecimal.Value))
                    {
                        throw new ParserException(afterDecimal, "Decimal must be followed by an integer.");
                    }

                    numberValue += "." + afterDecimal.Value;

                    double floatValue = FloatConstant.ParseValue(numberToken, numberValue);
                    return(new FloatConstant(numberToken, floatValue, owner));
                }

                int intValue = IntegerConstant.ParseIntConstant(numberToken, numberToken.Value);
                return(new IntegerConstant(numberToken, intValue, owner));
            }

            if (tokens.IsNext("."))
            {
                Token  dotToken    = tokens.PopExpected(".");
                string numberValue = "0.";
                Token  postDecimal = tokens.Pop();
                if (postDecimal.HasWhitespacePrefix || !Parser.IsInteger(postDecimal.Value))
                {
                    throw new ParserException(dotToken, "Unexpected dot.");
                }

                numberValue += postDecimal.Value;

                double floatValue;
                if (double.TryParse(numberValue, out floatValue))
                {
                    return(new FloatConstant(dotToken, floatValue, owner));
                }

                throw new ParserException(dotToken, "Invalid float literal.");
            }

            throw new ParserException(tokens.Peek(), "Encountered unexpected token: '" + tokens.PeekValue() + "'");
        }
Пример #2
0
        private Expression ParseEntityWithoutSuffixChain(TokenStream tokens, Node owner)
        {
            tokens.EnsureNotEof();

            Token  nextToken = tokens.Peek();
            string next      = nextToken.Value;

            if (next == this.parser.Keywords.NULL)
            {
                return(new NullConstant(tokens.Pop(), owner));
            }
            if (next == this.parser.Keywords.TRUE)
            {
                return(new BooleanConstant(tokens.Pop(), true, owner));
            }
            if (next == this.parser.Keywords.FALSE)
            {
                return(new BooleanConstant(tokens.Pop(), false, owner));
            }
            if (next == this.parser.Keywords.THIS)
            {
                return(new ThisKeyword(tokens.Pop(), owner));
            }
            if (next == this.parser.Keywords.BASE)
            {
                return(new BaseKeyword(tokens.Pop(), owner));
            }

            Token peekToken = tokens.Peek();

            if (next.StartsWith("'"))
            {
                return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner));
            }
            if (next.StartsWith("\""))
            {
                return(new StringConstant(tokens.Pop(), StringConstant.ParseOutRawValue(peekToken), owner));
            }
            if (next == "@") // Raw strings (no escape sequences, a backslash is a literal backslash)
            {
                Token atToken         = tokens.Pop();
                Token stringToken     = tokens.Pop();
                char  stringTokenChar = stringToken.Value[0];
                if (stringTokenChar != '"' && stringTokenChar != '\'')
                {
                    throw new ParserException(atToken, "Unexpected token: '@'");
                }
                string stringValue = stringToken.Value.Substring(1, stringToken.Value.Length - 2);
                return(new StringConstant(atToken, stringValue, owner));
            }
            if (next == this.parser.Keywords.NEW)
            {
                return(this.ParseInstantiate(tokens, owner));
            }

            char firstChar = next[0];

            if (nextToken.Type == TokenType.WORD)
            {
                Token varToken = tokens.Pop();
                if (tokens.IsNext("=>"))
                {
                    return(this.ParseLambda(
                               tokens,
                               varToken,
                               new AType[] { AType.Any() },
                               new Token[] { varToken },
                               owner));
                }
                else
                {
                    return(new Variable(varToken, varToken.Value, owner));
                }
            }

            if (firstChar == '[' && nextToken.File.CompilationScope.IsCrayon)
            {
                Token             bracketToken = tokens.PopExpected("[");
                List <Expression> elements     = new List <Expression>();
                bool previousHasCommaOrFirst   = true;
                while (!tokens.PopIfPresent("]"))
                {
                    if (!previousHasCommaOrFirst)
                    {
                        tokens.PopExpected("]");                           // throws appropriate error
                    }
                    elements.Add(Parse(tokens, owner));
                    previousHasCommaOrFirst = tokens.PopIfPresent(",");
                }
                return(new ListDefinition(bracketToken, elements, AType.Any(), owner, false, null));
            }

            if (firstChar == '{' && nextToken.File.CompilationScope.IsCrayon)
            {
                Token             braceToken = tokens.PopExpected("{");
                List <Expression> keys       = new List <Expression>();
                List <Expression> values     = new List <Expression>();
                bool previousHasCommaOrFirst = true;
                while (!tokens.PopIfPresent("}"))
                {
                    if (!previousHasCommaOrFirst)
                    {
                        tokens.PopExpected("}");                           // throws appropriate error
                    }
                    keys.Add(Parse(tokens, owner));
                    tokens.PopExpected(":");
                    values.Add(Parse(tokens, owner));
                    previousHasCommaOrFirst = tokens.PopIfPresent(",");
                }
                return(new DictionaryDefinition(braceToken, AType.Any(), AType.Any(), keys, values, owner));
            }

            if (nextToken.Type == TokenType.NUMBER)
            {
                if (next.Contains("."))
                {
                    double floatValue;
                    if (double.TryParse(next, out floatValue))
                    {
                        return(new FloatConstant(tokens.Pop(), floatValue, owner));
                    }
                    throw new ParserException(nextToken, "Invalid float literal.");
                }
                return(new IntegerConstant(
                           tokens.Pop(),
                           IntegerConstant.ParseIntConstant(nextToken, next),
                           owner));
            }

            throw new ParserException(tokens.Peek(), "Encountered unexpected token: '" + tokens.PeekValue() + "'");
        }