Example #1
0
        public bool VisitNode(Class node)
        {
            // class classname extends parentclass [within outerclass] [specifiers] ;
            Write("class {0} extends {1} ", node.Name, node.Parent.Name);
            if (node.OuterClass.Name != node.Parent.Name)
                Append("within {0} ", node.OuterClass.Name);
            if (node.Specifiers.Count > 0)
                Append("{0}", String.Join(" ", node.Specifiers.Select(x => x.Value)));
            Append(";");

            // print the rest of the class, according to the standard "anatomy of an unrealscript" article.
            if (node.TypeDeclarations.Count > 0)
            {
                Write("");
                Write("// Types");
                foreach (VariableType type in node.TypeDeclarations)
                    type.AcceptVisitor(this);
            }

            if (node.VariableDeclarations.Count > 0)
            {
                Write("");
                Write("// Variables");
                foreach (VariableDeclaration decl in node.VariableDeclarations.ToList())
                    decl.AcceptVisitor(this);
            }

            if (node.Operators.Count > 0)
            {
                Write("");
                Write("// Operators");
                foreach (OperatorDeclaration op in node.Operators)
                    op.AcceptVisitor(this);
            }

            if (node.Functions.Count > 0)
            {
                Write("");
                Write("// Functions");
                foreach (Function func in node.Functions)
                    func.AcceptVisitor(this);
            }

            if (node.States.Count > 0)
            {
                Write("");
                Write("// States");
                foreach (State state in node.States)
                    state.AcceptVisitor(this);
            }

            Write("");
            if (node.DefaultProperties != null)
                node.DefaultProperties.AcceptVisitor(this);

            return true;
        }
Example #2
0
        // TODO: this is only for text decompiling, should extend to a full ast for modification.
        public Class ConvertClass()
        {
            VariableType parent;
            if (Object.SuperField != null)
                parent = new VariableType(Object.SuperField.Name, null, null);
            else
                parent = new VariableType("object", null, null);

            VariableType outer;
            if (Object.OuterClass != null)
                outer = new VariableType(Object.OuterClass.Name, null, null);
            else
                outer = new VariableType(parent.Name, null, null);
            // TODO: specifiers
            // TODO: operators
            // TODO: components
            // TODO: constants
            // TODO: interfaces

            var Types = new List<VariableType>();
            foreach (var member in Object.Structs)
                Types.Add(ConvertStruct(member));
            foreach (var member in Object.Enums)
                Types.Add(ConvertEnum(member));

            var Vars = new List<VariableDeclaration>();
            foreach (var member in Object.Variables)
                Vars.Add(ConvertVariable(member));

            var Funcs = new List<Function>();
            foreach (var member in Object.DefinedFunctions)
                Funcs.Add(ConvertFunction(member));

            var States = new List<State>();
            foreach (var member in Object.States)
                States.Add(ConvertState(member));

            AST = new Class(Object.Name, new List<Specifier>(), Vars, Types, Funcs,
                States, parent, outer, new List<OperatorDeclaration>(), null, null);

            // Ugly quick fix:
            foreach (var member in Types)
                member.Outer = AST;
            foreach (var member in Vars)
                member.Outer = AST;
            foreach (var member in Funcs)
                member.Outer = AST;
            foreach (var member in States)
                member.Outer = AST;

            var propObject = PCC.GetExportObject(Object.DefaultPropertyIndex);
            if (propObject != null && propObject.DefaultProperties != null && propObject.DefaultProperties.Count != 0)
                AST.DefaultProperties = ConvertDefaultProperties(propObject.DefaultProperties);

            return AST;
        }
        public bool VisitNode(Class node)
        {
            // TODO: allow duplicate names as long as its in different packages!
            if (Symbols.SymbolExists(node.Name, ""))
                return Error("A class named '" + node.Name + "' already exists!", node.StartPos, node.EndPos);

            Symbols.AddSymbol(node.Name, node);

            ASTNode parent;
            if (!Symbols.TryGetSymbol(node.Parent.Name, out parent, ""))
                return Error("No parent class named '" + node.Parent.Name + "' found!", node.Parent.StartPos, node.Parent.EndPos);
            if (parent != null)
            {
                if (parent.Type != ASTNodeType.Class)
                    return Error("Parent named '" + node.Parent.Name + "' is not a class!", node.Parent.StartPos, node.Parent.EndPos);
                else if ((parent as Class).SameOrSubClass(node.Name)) // TODO: not needed due to no forward declarations?
                    return Error("Extending from '" + node.Parent.Name + "' causes circular extension!", node.Parent.StartPos, node.Parent.EndPos);
                else
                    node.Parent = parent as Class;
            }

            ASTNode outer;
            if (node.OuterClass != null)
            {
                if (!Symbols.TryGetSymbol(node.OuterClass.Name, out outer, ""))
                    return Error("No outer class named '" + node.OuterClass.Name + "' found!", node.OuterClass.StartPos, node.OuterClass.EndPos);
                else if (outer.Type != ASTNodeType.Class)
                    return Error("Outer named '" + node.OuterClass.Name + "' is not a class!", node.OuterClass.StartPos, node.OuterClass.EndPos);
                else if (node.Parent.Name == "Actor")
                    return Error("Classes extending 'Actor' can not be inner classes!", node.OuterClass.StartPos, node.OuterClass.EndPos);
                else if (!(outer as Class).SameOrSubClass((node.Parent as Class).OuterClass.Name))
                    return Error("Outer class must be a sub-class of the parents outer class!", node.OuterClass.StartPos, node.OuterClass.EndPos);
            }
            else
            {
                outer = (node.Parent as Class).OuterClass;
            }
            node.OuterClass = outer as Class;

            // TODO(?) validate class specifiers more than the initial parsing?

            Symbols.GoDirectlyToStack((node.Parent as Class).GetInheritanceString());
            Symbols.PushScope(node.Name);

            foreach (VariableType type in node.TypeDeclarations)
            {
                type.Outer = node;
                Success = Success && type.AcceptVisitor(this);
            }
            foreach (VariableDeclaration decl in node.VariableDeclarations.ToList())
            {
                decl.Outer = node;
                Success = Success && decl.AcceptVisitor(this);
            }
            foreach (OperatorDeclaration op in node.Operators)
            {
                op.Outer = node;
                Success = Success && op.AcceptVisitor(this);
            }
            foreach (Function func in node.Functions)
            {
                func.Outer = node;
                Success = Success && func.AcceptVisitor(this);
            }
            foreach (State state in node.States)
            {
                state.Outer = node;
                Success = Success && state.AcceptVisitor(this);
            }

            Symbols.PopScope();
            Symbols.RevertToObjectStack();

            node.Declaration = node;

            return Success;
        }
Example #4
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;
        }