Beispiel #1
0
        public static InlineFunctionExpression InlineFunction(AnonymousFunctionExpr e)
        {
            if (!CanInline(e))
                throw new Exception("Cannot inline function!");

            ReturnStatement rs = e.Body[0] as ReturnStatement;

            InlineFunctionExpression ife = new InlineFunctionExpression();
            foreach (Variable v in e.Arguments)
                ife.Arguments.Add(v);
            ife.IsVararg = e.IsVararg;

            foreach (Expression expr in rs.Arguments)
                ife.Expressions.Add(expr);

            ife.Scope = e.Scope;
            rs.Scope = e.Scope;
            return ife;
        }
Beispiel #2
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);
        }