Beispiel #1
0
        Expression ParseSimpleExpr(Scope scope)
        {
            if (reader.Is(TokenType.Number))
            {
                return new NumberExpr {
                           Value = reader.Get().Data
                }
            }
            ;
            else if (reader.Is(TokenType.DoubleQuoteString) || reader.Is(TokenType.SingleQuoteString) || reader.Is(TokenType.LongString))
            {
                StringExpr s = new StringExpr
                {
                    Value      = reader.Peek().Data,
                    StringType = reader.Peek().Type
                };

                reader.Get();
                return(s);
            }
            else if (reader.ConsumeKeyword("nil"))
            {
                return(new NilExpr());
            }
            else if (reader.IsKeyword("false") || reader.IsKeyword("true"))
            {
                return new BoolExpr {
                           Value = reader.Get().Data == "true"
                }
            }
            ;
            else if (reader.ConsumeSymbol("..."))
            {
                return(new VarargExpr());
            }
            else if (reader.ConsumeSymbol('{'))
            {
                TableConstructorExpr v = new TableConstructorExpr();
                while (true)
                {
                    if (reader.IsSymbol('['))
                    {
                        // key
                        reader.Get(); // eat '['
                        Expression key = ParseExpr(scope);

                        if (!reader.ConsumeSymbol(']'))
                        {
                            error("']' expected");
                            break;
                        }

                        if (!reader.ConsumeSymbol('='))
                        {
                            error("'=' Expected");
                            break;
                        }

                        Expression value = ParseExpr(scope);

                        v.EntryList.Add(new TableConstructorKeyExpr
                        {
                            Key   = key,
                            Value = value,
                        });
                    }
                    else if (reader.Is(TokenType.Ident))
                    {
                        // value or key
                        Token lookahead = reader.Peek(1);
                        if (lookahead.Type == TokenType.Symbol && lookahead.Data == "=")
                        {
                            // we are a key
                            Token key = reader.Get();
                            if (!reader.ConsumeSymbol('='))
                            {
                                error("'=' Expected");
                            }

                            Expression value = ParseExpr(scope);

                            v.EntryList.Add(new TableConstructorStringKeyExpr
                            {
                                Key   = key.Data,
                                Value = value,
                            });
                        }
                        else
                        {
                            // we are a value
                            Expression val = ParseExpr(scope);

                            v.EntryList.Add(new TableConstructorValueExpr
                            {
                                Value = val
                            });
                        }
                    }
#if !VANILLA_LUA
                    else if (reader.ConsumeKeyword("function"))
                    {
                        if (reader.Peek().Type != TokenType.Ident)
                        {
                            error("function name expected");
                        }
                        string            name = reader.Get().Data;
                        FunctionStatement fs   = ParseFunctionArgsAndBody(scope);
                        fs.IsLocal = false;
                        fs.Name    = new StringExpr(name);
                        v.EntryList.Add(new TableConstructorNamedFunctionExpr
                        {
                            Value = fs
                        });
                    }
#endif
                    else if (reader.ConsumeSymbol('}'))
                    {
                        break;
                    }
                    else
                    {
                        //value
                        Expression value = ParseExpr(scope);
                        v.EntryList.Add(new TableConstructorValueExpr
                        {
                            Value = value
                        });
                    }

                    if (reader.ConsumeSymbol(';') || reader.ConsumeSymbol(','))
                    {
                        // I could have used just an empty statement (';') here, instead of { }
                        // but that leaves a warning, which clutters up the output
                        // other than that, all is good
                    }
                    else if (reader.ConsumeSymbol('}'))
                    {
                        break;
                    }
                    else
                    {
                        error("'}' or table entry Expected");
                        break;
                    }
                }
                return(v);
            }
            else if (reader.ConsumeKeyword("function"))
            {
                AnonymousFunctionExpr func = ParseExprFunctionArgsAndBody(scope);
                //func.IsLocal = true;
                return(func);
            }
#if !VANILLA_LUA
            else if (reader.ConsumeSymbol('|'))
            {
                // inline function... |<arg list>| -> <expr>, <expr>
                InlineFunctionExpression func = new InlineFunctionExpression();
                func.Scope = new Scope(scope);
                // arg list
                List <Variable> arglist  = new List <Variable>();
                bool            isVarArg = false;
                while (reader.ConsumeSymbol('|') == false)
                {
                    if (reader.Is(TokenType.Ident))
                    {
                        Variable arg = new Variable();
                        arg.Name = reader.Get().Data;
                        func.Scope.AddLocal(arg);
                        arglist.Add(arg);
                        if (!reader.ConsumeSymbol(','))
                        {
                            if (reader.ConsumeSymbol('|'))
                            {
                                break;
                            }
                            else
                            {
                                error("'|' expected");
                                break;
                            }
                        }
                    }
                    else if (reader.ConsumeSymbol("..."))
                    {
                        isVarArg = true;
                        if (!reader.ConsumeSymbol('|'))
                        {
                            error("'...' must be the last argument of a function");
                        }
                        break;
                    }
                    else
                    {
                        error("Argument name or '...' expected");
                        break;
                    }
                }
                if (!reader.ConsumeSymbol("->"))
                {
                    error("'->' expected");
                }
                // body
                List <Expression> body = new List <Expression> {
                    ParseExpr(func.Scope)
                };
                while (reader.ConsumeSymbol(','))
                {
                    body.Add(ParseExpr(func.Scope));
                }
                // end

                //nodeFunc.AstType = AstType.Function;
                func.Arguments   = arglist;
                func.Expressions = body;
                func.IsVararg    = isVarArg;

                return(func);
            }
#endif
            else
            {
                return(ParseSuffixedExpr(scope));
            }
        }