Esempio n. 1
0
        public void TestParseVarDecl()
        {
            var source =
                "var private struct transient twoStruct extends testStruct\n" +
                "{\n" +
                "   var etestnumeration num;\n" +
                "} structA, structB;";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            var decl = parser.TryParseVarDecl();

            Assert.IsNotNull(decl);
            Assert.AreEqual(decl.Specifiers[0].Value.ToLower(), "private");
            Assert.AreEqual(decl.VarType.Name.ToLower(), "twostruct");
            Assert.AreEqual(decl.Variables[1].Name.ToLower(), "structb");

            source = "var ;\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseVarDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected variable type or struct/enum type declaration!");

            source = "var int ;\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseVarDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed variable names!");

            source = "var int test\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseVarDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected semi-colon!");

            return;
        }
Esempio n. 2
0
        public void TestParseStruct()
        {
            var source =
                "struct transient testStruct\n" +
                "{ var float a, b, c; };\n";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            var s = parser.TryParseStruct();

            Assert.IsNotNull(s);
            Assert.AreEqual(s.Name.ToLower(), "teststruct");
            Assert.AreEqual(s.Members[0].Variables[1].Name.ToLower(), "b");

            source = "struct transient {\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseStruct());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected struct name!");

            source = "struct transient testStruct \n var float a; }";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseStruct());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected '{'!");

            source = "struct transient testStruct { \n var a; }";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseStruct());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed struct content!");

            return;
        }
Esempio n. 3
0
        public void TestParseSpecifier()
        {
            var source = "coerce native";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            Assert.AreEqual(parser.TryParseSpecifier(GlobalLists.ParameterSpecifiers).Value.ToLower(), "coerce");
            Assert.IsNull(parser.TryParseSpecifier(GlobalLists.ParameterSpecifiers));

            return;
        }
Esempio n. 4
0
        public void TestParseState()
        {
            var source =
                "auto state MyState\n" +
                "{\n" +
                "ignores MyFunc;\n" +
                "function StateFunc()\n" +
                "{\n" +
                "}\n" +
                "\n" +
                "Begin:\n" +
                "       moredragons\n" +
                "}\n";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            var state = parser.TryParseState();

            Assert.IsNotNull(state);
            Assert.AreEqual(state.Name.ToLower(), "mystate");
            Assert.AreEqual(state.Specifiers[0].Value.ToLower(), "auto");
            Assert.AreEqual(state.Ignores[0].Name.ToLower(), "myfunc");

            source = "auto state { \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseState());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected state name!");

            source = "auto state MyState ignores \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseState());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected '{'!");

            source = "auto state MyState { ignores ; \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseState());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed ignore statement!");

            source = "auto state MyState { ignores one, ; \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseState());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed ignore statement!");

            source = "auto state MyState { ignores one, two } \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseState());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected semi-colon!");

            source = "auto state MyState {  \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseState());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected '}'!");

            return;
        }
Esempio n. 5
0
        public void TestParseParameter()
        {
            var source = "coerce out int one float two[5] optional )";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            Assert.AreEqual(parser.TryParseParameter().Name.ToLower(), "one");
            Assert.AreEqual(parser.TryParseParameter().IsStaticArray, true);
            Assert.IsNull(parser.TryParseParameter());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected parameter type!");

            return;
        }
Esempio n. 6
0
        public static (ASTNode ast, MessageLog log) CompileAST(string script, string type)
        {
            var log    = new MessageLog();
            var parser = new ClassOutlineParser(new TokenStream <string>(new StringLexer(script, log)), log);

            try
            {
                ASTNode ast = parser.ParseDocument(type);
                log.LogMessage($"Parse{(ast is null ? " failed!" : "d!")}");
                return(ast, log);
            }
            catch (Exception e)
            {
                log.LogMessage($"Parse failed! Exception: {e}");
                return(null, log);
            }
        }
Esempio n. 7
0
        public void TestParseFunction()
        {
            var source =
                "private simulated function float MyFunc( out testStruct one, coerce optional float two ) \n" +
                "{\n" +
                "   return one.b + funcB(one, two);\n" +
                "}\n";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            var func = parser.TryParseFunction();

            Assert.IsNotNull(func);
            Assert.AreEqual(func.Name.ToLower(), "myfunc");
            Assert.AreEqual(func.Specifiers[0].Value.ToLower(), "private");
            Assert.AreEqual(func.Parameters[1].Name.ToLower(), "two");
            Assert.AreEqual(func.ReturnType.Name.ToLower(), "float");

            source = "private simulated function ( \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseFunction());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected function name or return type!");

            source = "function int funcA ) \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseFunction());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected '('!");

            source = "function int funcA ( out int, ) \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseFunction());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed parameter!");

            source = "function int funcA ( out int one two ) \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseFunction());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Unexpected parameter content!");

            source = "function int funcA ( out int one, int two) \n {";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseFunction());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed function body!");

            return;
        }
Esempio n. 8
0
        public void TestParseEnum()
        {
            var source =
                "enum ETestnumeration {\n" +
                "     TEST_value1,\n" +
                "     TEST_value2,\n" +
                "     TEST_value3,\n" +
                "};\n";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            var enumeration = parser.TryParseEnum();

            Assert.IsNotNull(enumeration);
            Assert.AreEqual(enumeration.Name.ToLower(), "etestnumeration");
            Assert.AreEqual(enumeration.Values[1].Name.ToLower(), "test_value2");

            source = "enum {\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseEnum());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected enumeration name!");

            source = "enum test \n test_value1, \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseEnum());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected '{'!");

            source = "enum test {\n } \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseEnum());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected non-empty enumeration!");

            source = "enum test {\n int value } \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseEnum());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed enumeration content!");

            return;
        }
Esempio n. 9
0
        public void TestParseOpDecl()
        {
            var source =
                "final static operator(254) int >>>( coerce float left, coerce float right )\n" +
                "{\n" +
                "   all the dragons\n" +
                "}\n";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            var decl = parser.TryParseOperatorDecl();

            Assert.IsNotNull(decl);
            Assert.AreEqual(decl.OperatorKeyword.ToLower(), ">>>");
            Assert.AreEqual((decl as InOpDeclaration).Precedence, 254);
            Assert.AreEqual(decl.ReturnType.Name.ToLower(), "int");
            Assert.AreEqual((decl as InOpDeclaration).RightOperand.Name.ToLower(), "right");

            source = "final static operator int \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected '('! (Did you forget to specify operator precedence?)");

            source = "final static operator(asd) int \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected an integer number!");

            source = "final static operator(54 int \n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected ')'!");

            source = "final static operator(54) (\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected operator name or return type!");

            source = "final static operator(254) int >>>\n {";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected '('!");

            source = "final static operator(254) int >>>( coerce left, coerce float right )\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed operand!");

            source = "final static operator(254) int >>>( coerce float left coerce float right )\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Unexpected operand content!");

            source = "final static operator(254) int >>>( coerce float left )\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "In-fix operators requires exactly 2 parameters!");

            source = "final static preoperator int >>>( coerce float left, coerce float right )\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Post/Pre-fix operators requires exactly 1 parameter!");

            source = "final static operator(254) int >>>( coerce float left, coerce float right )\n { asdasd";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseOperatorDecl());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed operator body!");

            return;
        }
Esempio n. 10
0
        public void BasicClassTest()
        {
            var source =
                "class Test Deprecated Transient; \n" +
                "var enum ETestnumeration {\n" +
                "     TEST_value1,\n" +
                "     TEST_value2,\n" +
                "     TEST_value3,\n" +
                "} inlineNumeration, testnum2;\n" +
                "var private deprecated int X; \n" +
                "VAR INT Y, Z; \n" +
                "var ETestnumeration testnum;\n" +
                "struct transient testStruct\n" +
                "{ var float a, b, c; };\n" +
                "var private struct transient twoStruct extends testStruct\n" +
                "{\n" +
                "   var etestnumeration num;\n" +
                "} structA, structB;\n" +
                "function float funcB( testStruct one, float two ) \n" +
                "{\n" +
                "   local float c;" +
                "   one.a = 1.3 * c;" +
                "   while (true)" +
                "   {" +
                "       c = c - c - c;" +
                "   }" +
                "   if (false) {" +
                "       switch(one.a) {" +
                "           case one.a:" +
                "               c = one.a;" +
                "               break;" +
                "           case 1.2:" +
                "           case 1.3:" +
                "               c = c + 0.5;" +
                "               break;" +
                "           default:" +
                "               c = 6.6;" +
                "       }" +
                "   }" +
                "   return one.a + 0.33 * (0.66 + 0.1) * 1.5;\n" +
                "}\n" +
                "private simulated function float MyFunc( out testStruct one, coerce optional float two ) \n" +
                "{\n" +
                "   return one.b + funcB(one, two);\n" +
                "}\n" +
                "auto state MyState\n" +
                "{\n" +
                "ignores MyFunc;\n" +
                "function StateFunc()\n" +
                "{\n" +
                "}\n" +
                "\n" +
                "Begin:\n" +
                "       moredragons\n" +
                "}\n" +
                "\n" +
                "final static operator(254) int >>>( coerce float left, coerce float right )\n" +
                "{\n" +
                "   all the dragons\n" +
                "}\n" +
                "\n" +
                "\n" +
                "\n";

            var parser  = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            var symbols = new SymbolTable();

            Class obj = new Class("Object", null, null, null, null, null, null, null, null, null, null);

            obj.OuterClass = obj;
            symbols.PushScope(obj.Name);
            symbols.AddSymbol(obj.Name, obj);

            VariableType integer = new VariableType("int", null, null);

            symbols.AddSymbol(integer.Name, integer);
            VariableType floatingpoint = new VariableType("float", null, null);

            symbols.AddSymbol(floatingpoint.Name, floatingpoint);

            InOpDeclaration plus_float = new InOpDeclaration("+", 20, false, null, floatingpoint, new FunctionParameter(floatingpoint, null, null, null, null),
                                                             new FunctionParameter(floatingpoint, null, null, null, null), null, null, null);

            symbols.AddOperator(plus_float);

            InOpDeclaration sub_float = new InOpDeclaration("-", 20, false, null, floatingpoint, new FunctionParameter(floatingpoint, null, null, null, null),
                                                            new FunctionParameter(floatingpoint, null, null, null, null), null, null, null);

            symbols.AddOperator(sub_float);

            InOpDeclaration mult_float = new InOpDeclaration("*", 16, false, null, floatingpoint, new FunctionParameter(floatingpoint, null, null, null, null),
                                                             new FunctionParameter(floatingpoint, null, null, null, null), null, null, null);

            symbols.AddOperator(mult_float);

            Class node           = (Class)parser.ParseDocument();
            var   ClassValidator = new ClassValidationVisitor(log, symbols);

            node.AcceptVisitor(ClassValidator);

            symbols.GoDirectlyToStack(node.GetInheritanceString());
            foreach (Function f in node.Functions)
            {
                symbols.PushScope(f.Name);
                var p = new CodeBodyParser(new TokenStream <String>(new StringLexer(source)), f.Body, symbols, f, log);
                var b = p.ParseBody();
                symbols.PopScope();
            }

            var CodeBuilder = new CodeBuilderVisitor();

            node.AcceptVisitor(CodeBuilder);
            Console.Write(CodeBuilder.GetCodeString());

            Assert.IsTrue(log.AllErrors.Count == 0);

            return;
        }
Esempio n. 11
0
        public void TestParseClass()
        {
            var source =
                "class Test Deprecated Transient; \n" +
                "var private deprecated int X; \n" +
                "struct transient testStruct\n" +
                "{ var float a, b, c; };\n" +
                "private simulated function float MyFunc( out testStruct one, coerce optional float two ) \n" +
                "{\n" +
                "   return one.b + funcB(one, two);\n" +
                "}\n" +
                "auto state MyState\n" +
                "{\n" +
                "ignores MyFunc;\n" +
                "function StateFunc()\n" +
                "{\n" +
                "}\n" +
                "Begin:\n" +
                "       moredragons\n" +
                "}\n" +
                "final static operator(254) int >>>( coerce float left, coerce float right )\n" +
                "{\n" +
                "   all the dragons\n" +
                "}\n" +
                "\n";
            var parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);

            var decl = parser.TryParseClass();

            Assert.IsNotNull(decl);
            Assert.AreEqual(decl.Name.ToLower(), "test");
            Assert.AreEqual(decl.Specifiers[1].Value.ToLower(), "transient");
            Assert.AreEqual(decl.VariableDeclarations[0].Variables[0].Name.ToLower(), "x");
            Assert.AreEqual(decl.TypeDeclarations[0].Name.ToLower(), "teststruct");
            Assert.AreEqual(decl.Functions[0].Name.ToLower(), "myfunc");
            Assert.AreEqual(decl.States[0].Name.ToLower(), "mystate");
            Assert.AreEqual(decl.Operators[0].OperatorKeyword.ToLower(), ">>>");
            Assert.AreEqual(log.Messages[log.Messages.Count - 1].Message.Substring(0, 10), "No parent ");

            source = "test ;\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseClass());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected class declaration!");

            source = "class ;\n";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseClass());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected class name!");

            source = "class Test deprecated\n var int local;";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseClass());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected semi-colon!");

            source = "class Test deprecated; \n var int ;";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseClass());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed instance variable!");

            source = "class Test deprecated; \n struct fail;";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseClass());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Malformed type declaration!");

            source = "class Test deprecated; \n struct fail { var int one; } struct next;";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseClass());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected semi-colon!");

            source = "class Test deprecated; \n struct fail { var int one; }; function myfunc() {} var int fail;";
            parser = new ClassOutlineParser(new TokenStream <String>(new StringLexer(source)), log);
            Assert.IsNull(parser.TryParseClass());
            Assert.AreEqual(log.AllErrors[log.AllErrors.Count - 1].Message, "Expected function/state/operator declaration!");

            return;
        }
Esempio n. 12
0
        public static bool ResolveAllClassesInPackage(IMEPackage pcc, ref SymbolTable symbols)
        {
            string fileName = Path.GetFileNameWithoutExtension(pcc.FilePath);

#if DEBUGSCRIPT
            string dumpFolderPath = Path.Combine(ME3Directory.gamePath, "ScriptDump", fileName);
            Directory.CreateDirectory(dumpFolderPath);
#endif
            var log = new MessageLog();
            Debug.WriteLine($"{fileName}: Beginning Parse.");
            var classes = new List <(Class ast, string scriptText)>();
            foreach (ExportEntry export in pcc.Exports.Where(exp => exp.IsClass))
            {
                Class  cls        = ME3ObjectToASTConverter.ConvertClass(export.GetBinaryData <UClass>(), false);
                string scriptText = "";
                try
                {
#if DEBUGSCRIPT
                    var codeBuilder = new CodeBuilderVisitor();
                    cls.AcceptVisitor(codeBuilder);
                    scriptText = codeBuilder.GetCodeString();
                    File.WriteAllText(Path.Combine(dumpFolderPath, $"{cls.Name}.uc"), scriptText);
                    var parser = new ClassOutlineParser(new TokenStream <string>(new StringLexer(scriptText, log)), log);
                    cls = parser.TryParseClass();
                    if (cls == null || log.Content.Any())
                    {
                        DisplayError(scriptText, log.ToString());
                        return(false);
                    }
#endif

                    if (export.ObjectName == "Object")
                    {
                        symbols = SymbolTable.CreateIntrinsicTable(cls);
                    }
                    else
                    {
                        symbols.AddType(cls);
                    }

                    classes.Add(cls, scriptText);
                }
                catch (Exception e) when(!App.IsDebug)
                {
                    DisplayError(scriptText, log.ToString());
                    return(false);
                }
            }
            Debug.WriteLine($"{fileName}: Finished parse.");
            foreach (var validationPass in Enums.GetValues <ValidationPass>())
            {
                foreach ((Class ast, string scriptText) in classes)
                {
                    try
                    {
                        var validator = new ClassValidationVisitor(log, symbols, validationPass);
                        ast.AcceptVisitor(validator);
                        if (log.Content.Any())
                        {
                            DisplayError(scriptText, log.ToString());
                            return(false);
                        }
                    }
                    catch (Exception e) when(!App.IsDebug)
                    {
                        DisplayError(scriptText, log.ToString());
                        return(false);
                    }
                }
                Debug.WriteLine($"{fileName}: Finished validation pass {validationPass}.");
            }

            switch (fileName)
            {
            case "Core":
                symbols.InitializeOperators();
                break;

            case "Engine":
                symbols.ValidateIntrinsics();
                break;
            }

#if DEBUGSCRIPT
            //parse function bodies for testing purposes
            foreach ((Class ast, string scriptText) in classes)
            {
                symbols.RevertToObjectStack();
                if (!ast.Name.CaseInsensitiveEquals("Object"))
                {
                    symbols.GoDirectlyToStack(((Class)ast.Parent).GetInheritanceString());
                    symbols.PushScope(ast.Name);
                }

                foreach (Function function in ast.Functions.Where(func => !func.IsNative && func.IsDefined))
                {
                    CodeBodyParser.ParseFunction(function, scriptText, symbols, log);
                    if (log.Content.Any())
                    {
                        DisplayError(scriptText, log.ToString());
                    }
                }
            }
#endif


            symbols.RevertToObjectStack();

            return(true);
        }