Beispiel #1
0
 public static void ResolveFunction(DecompileContext ctx, ASTFunction func)
 {
     // Handle code-entry-specific types
     if (ctx.CodeAssetTypes.HasValue)
     {
         if (ctx.CodeAssetTypes.Value.FunctionArgs != null &&
             ctx.CodeAssetTypes.Value.FunctionArgs.TryGetValue(func.Function.Name.Content, out AssetType[] types))
Beispiel #2
0
    void ParseProgram()
    {
        while (lexer.IsReading)
        {
            if (lexer.PeekNext() == TokenType.Def)                     // Function definition
            {
                lexer.NextToken();                                     // Eat the def keyword

                Token funcNameToken = MatchNext(TokenType.Identifier); // Function name

                MatchNext(TokenType.BracketOpen);

                ASTFunction function = new ASTFunction(funcNameToken.Source);
                program.AddFunction(function);

                // Parameters
                while (true)
                {
                    if (lexer.PeekNext() == TokenType.BracketClose)
                    {
                        lexer.NextToken();
                        break;
                    }

                    Token argToken = MatchNext(TokenType.Identifier);
                    function.AddArg(argToken.Source);

                    if (lexer.PeekNext() == TokenType.BracketClose)
                    {
                        lexer.NextToken();
                        break;
                    }

                    MatchNext(TokenType.Comma);
                }

                MatchNext(TokenType.Do);

                // Statements
                while (lexer.PeekNext() != TokenType.End)
                {
                    function.AddStatement(ParseStatement());
                }

                lexer.NextToken();
            }
            else
            {
                program.Statements.AddStatement(ParseStatement());
            }
        }
    }
Beispiel #3
0
        /// <summary>
        /// Creates and loads a function declaration from an AST node.
        /// </summary>
        private bool LoadFunctionFromAST(ASTFunction astFunction)
        {
            var args = new List <FunctionParam>(astFunction.Params.Count);

            foreach (var astParam in astFunction.Params)
            {
                var type = Context.LookupType(astParam.Type);
                // Since types and alias types are declared at the beginning of the
                // story header, we shold have full type information here, so any
                // unresolved types will be flagged as an error.
                if (type == null)
                {
                    Context.Log.Error(null, DiagnosticCode.UnresolvedTypeInSignature,
                                      String.Format("Function \"{0}({1})\" argument \"{2}\" has unresolved type \"{3}\"",
                                                    astFunction.Name, astFunction.Params.Count, astParam.Name, astParam.Type));
                    continue;
                }

                var param = new FunctionParam
                {
                    Name      = astParam.Name,
                    Type      = type,
                    Direction = astParam.Direction
                };
                args.Add(param);
            }

            var signature = new FunctionSignature
            {
                Name       = astFunction.Name,
                Type       = astFunction.Type,
                Params     = args,
                FullyTyped = true,
                Inserted   = false,
                Deleted    = false,
                Read       = false
            };

            var func = new BuiltinFunction
            {
                Signature = signature,
                Meta1     = astFunction.Meta1,
                Meta2     = astFunction.Meta2,
                Meta3     = astFunction.Meta3,
                Meta4     = astFunction.Meta4
            };

            return(Context.RegisterFunction(signature, func));
        }
Beispiel #4
0
            public bool Evaluate(DecompileContext ctx, ASTNode node, ASTNode parent)
            {
                if (parent.Kind != ASTNode.StatementKind.Function)
                {
                    return(false);
                }
                ASTFunction func = parent as ASTFunction;

                if (Index >= func.Children.Count)
                {
                    return(false);
                }
                ASTNode arg = func.Children[Index];

                if (arg.Kind != NodeKind)
                {
                    return(false);
                }
                if (arg.ToString() != NodeValue)
                {
                    return(false);
                }
                return(true);
            }
Beispiel #5
0
 public void AddFunction(ASTFunction function)
 {
     functions.Add(function);
 }
Beispiel #6
0
 public void RegisterFuncion(ASTFunction function)
 {
     userFunctions.Add(function.Name, function);
 }
Beispiel #7
0
        public static List <ASTClass> Parse(this Compiler compiler, List <TokenBase> tokens)
        {
            currentTokens = tokens;
            currentToken  = 0;
            List <ASTClass> classes = new List <ASTClass>();

            while (currentToken < currentTokens.Count)
            {
                if (currentTokens[currentToken].Token == "class")
                {
                    currentToken++;

                    currentClassName = currentTokens[currentToken].Token;
                    currentToken++;

                    if (currentTokens[currentToken].Token != "{")
                    {
                        throw new ParserException("Expected '{'.", currentTokens[currentToken].LineNumber);
                    }
                    currentToken++;

                    List <ASTConstructor>    constructors = new List <ASTConstructor>();
                    List <ASTFunction>       functions    = new List <ASTFunction>();
                    List <ASTClassAttribute> attributes   = new List <ASTClassAttribute>();
                    while (currentToken < currentTokens.Count)
                    {
                        if (currentTokens[currentToken].Token == "function")
                        {
                            currentToken++;
                            ASTFunction func = ParseFunction();
                            if (func is ASTConstructor)
                            {
                                constructors.Add((ASTConstructor)func);
                            }
                            else
                            {
                                functions.Add(func);
                            }
                        }
                        else if (currentTokens[currentToken].Token == "number" ||
                                 currentTokens[currentToken].Token == "string" ||
                                 currentTokens[currentToken].Token == "object")
                        {
                            ASTNode node = ParseSingleStatement();
                            if (node is ASTLocalVariable)
                            {
                                ASTLocalVariable lv = (ASTLocalVariable)node;
                                attributes.Add(new ASTClassAttribute()
                                {
                                    Type = lv.Type,
                                    Name = lv.Name
                                });

                                if (currentTokens[currentToken].Token == ";")
                                {
                                    currentToken++;
                                }
                                else
                                {
                                    throw new ParserException("Expected ';'.", currentTokens[currentToken].LineNumber);
                                }
                            }
                            else
                            {
                                throw new ParserException("Expected '}' or attribute or function.", currentTokens[currentToken].LineNumber);
                            }
                        }
                        else if (currentTokens[currentToken].Token == "}")
                        {
                            currentToken++;

                            classes.Add(new ASTClass()
                            {
                                Name         = currentClassName,
                                Constructors = constructors,
                                Functions    = functions,
                                Attributes   = attributes
                            });

                            break;
                        }
                        else
                        {
                            throw new ParserException("Expected '}' or attribute or function.", currentTokens[currentToken].LineNumber);
                        }
                    }
                }
                else
                {
                    throw new ParserException("Expected class.", currentTokens[currentToken].LineNumber);
                }
            }
            return(classes);
        }
        private static void PrintNode(ASTNode node, int incident)
        {
            if (node == null)
            {
                return;
            }
            for (int i = 0; i < incident; i++)
            {
                sw.Write("\t");
            }
            if (node is ASTString)
            {
                sw.WriteLine("ASTString: " + ((ASTString)node).String.Replace("\n", "\\n"));
            }
            else if (node is ASTNumber)
            {
                sw.WriteLine("ASTNumber: " + ((ASTNumber)node).Number);
            }
            else if (node is ASTIdentifier)
            {
                sw.WriteLine("ASTIdentifier: " + ((ASTIdentifier)node).Identifier);
            }
            else if (node is ASTOperator)
            {
                ASTOperator op = (ASTOperator)node;
                sw.WriteLine("ASTOperator: " + op.Operator);
                PrintNode(op.Left, incident + 1);
                PrintNode(op.Right, incident + 1);
            }
            else if (node is ASTStatement)
            {
                ASTStatement stm = (ASTStatement)node;
                sw.WriteLine("ASTStatement: ");
                PrintNode(stm.Statement, incident + 1);
            }
            else if (node is ASTFunctionCall)
            {
                ASTFunctionCall call = (ASTFunctionCall)node;
                sw.WriteLine("ASTFunctionCall: " + call.Scope + "." + call.FunctionName);
                foreach (ASTNode param in call.Parameter)
                {
                    PrintNode(param, incident + 1);
                }
            }
            else if (node is ASTClassParameter)
            {
                ASTClassParameter classP = (ASTClassParameter)node;
                sw.WriteLine("ASTClassParameter: " + classP.Scope);
                PrintNode(classP.Parameter, incident + 1);
            }
            else if (node is ASTIf)
            {
                ASTIf ifNode = (ASTIf)node;
                sw.WriteLine("ASTIf:");
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCondition:");
                PrintNode(ifNode.Condition, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in ifNode.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
                if (ifNode.ElseCodeBlock != null)
                {
                    for (int i = 0; i < incident; i++)
                    {
                        sw.Write("\t");
                    }
                    sw.WriteLine("\tElse:");
                    foreach (ASTNode codeBlock in ifNode.ElseCodeBlock)
                    {
                        PrintNode(codeBlock, incident + 2);
                    }
                }
            }
            else if (node is ASTFor)
            {
                ASTFor forNode = (ASTFor)node;
                sw.WriteLine("ASTFor:");
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tInit:");
                PrintNode(forNode.Initialise, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCondition:");
                PrintNode(forNode.Condition, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCounter:");
                PrintNode(forNode.Count, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in forNode.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
            }
            else if (node is ASTWhile)
            {
                ASTWhile wNode = (ASTWhile)node;
                sw.WriteLine("ASTWhile:");
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCondition:");
                PrintNode(wNode.Condition, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in wNode.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
            }
            else if (node is ASTFunction)
            {
                ASTFunction func = (ASTFunction)node;
                if (node is ASTConstructor)
                {
                    sw.WriteLine("ASTConstructor:");
                }
                else
                {
                    sw.WriteLine("ASTFunction: " + func.ReturnValue.ToString() + " " + func.Name);
                }
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tParameter:");
                foreach (ASTNode n in func.Parameter)
                {
                    PrintNode(n, incident + 2);
                }
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in func.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
            }
            else if (node is ASTFunctionParameter)
            {
                ASTFunctionParameter param = (ASTFunctionParameter)node;
                switch (param.Type)
                {
                case VMType.Object:
                    sw.WriteLine("Object: " + param.Name);
                    break;

                case VMType.String:
                    sw.WriteLine("String: " + param.Name);
                    break;

                case VMType.Number:
                    sw.WriteLine("Number: " + param.Name);
                    break;
                }
            }
            else if (node is ASTLocalVariable)
            {
                ASTLocalVariable param = (ASTLocalVariable)node;
                switch (param.Type)
                {
                case VMType.Object:
                    sw.WriteLine("var Object: " + param.Name);
                    break;

                case VMType.String:
                    sw.WriteLine("var String: " + param.Name);
                    break;

                case VMType.Number:
                    sw.WriteLine("var Number: " + param.Name);
                    break;
                }
            }
            else if (node is ASTReturn)
            {
                sw.WriteLine("ASTReturn:");
                PrintNode(((ASTReturn)node).Return, incident + 1);
            }
            else if (node is ASTClass)
            {
                ASTClass cNode = (ASTClass)node;
                sw.WriteLine("ASTClass: " + cNode.Name);
                sw.WriteLine("\tAttributes:");
                foreach (ASTNode n in cNode.Attributes)
                {
                    PrintNode(n, incident + 2);
                }
                sw.WriteLine("\tConstructors:");
                foreach (ASTNode n in cNode.Constructors)
                {
                    PrintNode(n, incident + 2);
                }
                sw.WriteLine("\tFunctions:");
                foreach (ASTNode n in cNode.Functions)
                {
                    PrintNode(n, incident + 2);
                }
            }
        }