コード例 #1
0
ファイル: State.cs プロジェクト: Mgamerz/ME3Libs
 public State(String name, CodeBody body, List<Specifier> specs,
     State parent, List<Function> funcs, List<Function> ignores,
     List<StateLabel> labels, SourcePosition start, SourcePosition end)
     : base(ASTNodeType.State, start, end)
 {
     Name = name;
     Body = body;
     Specifiers = specs;
     Parent = parent;
     Functions = funcs;
     Ignores = ignores;
     Labels = labels;
     Locals = new List<VariableDeclaration>();
 }
コード例 #2
0
        public bool VisitNode(State node)
        {
            if (Symbols.SymbolExistsInCurrentScope(node.Name))
                return Error("The name '" + node.Name + "' is already in use in this class!", node.StartPos, node.EndPos);

            ASTNode overrideState;
            bool overrides = Symbols.TryGetSymbol(node.Name, out overrideState, NodeUtils.GetOuterClassScope(node))
                && overrideState.Type == ASTNodeType.State;

            if (node.Parent != null)
            {
                if (overrides)
                    return Error("A state is not allowed to both override a parent class's state and extend another state at the same time!", node.StartPos, node.EndPos);

                ASTNode parent;
                if (!Symbols.TryGetSymbolFromCurrentScope(node.Parent.Name, out parent))
                    Error("No parent state named '" + node.Parent.Name + "' found in the current class!", node.Parent.StartPos, node.Parent.EndPos);
                if (parent != null)
                {
                    if (parent.Type != ASTNodeType.State)
                        Error("Parent named '" + node.Parent.Name + "' is not a state!", node.Parent.StartPos, node.Parent.EndPos);
                    else
                        node.Parent = parent as State;
                }
            }

            int numFuncs = node.Functions.Count;
            Symbols.PushScope(node.Name);
            foreach (Function ignore in node.Ignores)
            {
                ASTNode original;
                if (!Symbols.TryGetSymbol(ignore.Name, out original, "") || original.Type != ASTNodeType.Function)
                    return Error("No function to ignore named '" + ignore.Name + "' found!", ignore.StartPos, ignore.EndPos);
                Function header = original as Function;
                Function emptyOverride = new Function(header.Name, header.ReturnType, new CodeBody(null, null, null), header.Specifiers, header.Parameters, ignore.StartPos, ignore.EndPos);
                node.Functions.Add(emptyOverride);
                Symbols.AddSymbol(emptyOverride.Name, emptyOverride);
            }

            foreach (Function func in node.Functions.GetRange(0, numFuncs))
            {
                func.Outer = node;
                Success = Success && func.AcceptVisitor(this);
            }
            //TODO: check functions overrides:
            //if the state overrides another state, we should be in that scope as well whenh we check overrides maybe?
            //if the state has a parent state, we should be in that scope
            //this is a royal mess, check that ignores also look-up from parent/overriding states as we are not sure if symbols are in the scope

            // if the state extends a parent state, use that as outer in the symbol lookup
            // if the state overrides another state, use that as outer
            // both of the above should apply to functions as well as ignores.

            //TODO: state code/labels

            Symbols.PopScope();
            return Success;
        }
コード例 #3
0
ファイル: CodeBuilderVisitor.cs プロジェクト: Mgamerz/ME3Libs
        public bool VisitNode(State node)
        {
            // [specifiers] state statename [extends parentstruct] { \n contents \n };
            Write("");
            if (node.Specifiers.Count > 0)
                Append("{0} ", String.Join(" ", node.Specifiers.Select(x => x.Value)));
            Append("state {0} ", node.Name);
            if (node.Parent != null)
                Append("extends {0} ", node.Parent.Name);
            Append("{0}", "{");
            NestingLevel++;

            if (node.Ignores.Count > 0)
                Write("ignores {0};", String.Join(", ", node.Ignores.Select(x => x.Name)));

            foreach (Function func in node.Functions)
                func.AcceptVisitor(this);

            if (node.Body.Statements.Count != 0)
            {
                Write("");
                Write("// State code");
                node.Body.AcceptVisitor(this);
            }

            NestingLevel--;
            Write("{0};", "}");

            return true;
        }
コード例 #4
0
ファイル: ME3ObjectConverter.cs プロジェクト: Mgamerz/ME3Libs
        public State ConvertState(ME3State obj)
        {
            // TODO: ignores and body/labels

            State parent = null;
            if (obj.SuperField != null)
                parent = new State(obj.SuperField.Name, null, null, null, null, null, null, null, null);

            var Funcs = new List<Function>();
            var Ignores = new List<Function>();
            foreach (var member in obj.DefinedFunctions)
            {
                if (member.FunctionFlags.HasFlag(FunctionFlags.Defined))
                    Funcs.Add(ConvertFunction(member));
                else
                    Ignores.Add(new Function(member.Name, null, null,
                         null, null, null, null));
                /* Ignored functions are not marked as defined, so we dont need to lookup the ignormask.
                 * They are defined though, each being its own proper object with simply a return nothing for bytecode.
                 * */
            }

            var ByteCode = new ME3ByteCodeDecompiler(obj, new List<FunctionParameter>());
            var body = ByteCode.Decompile();

            return new State(obj.Name, body, new List<Specifier>(), (State)parent, Funcs, new List<Function>(), new List<StateLabel>(), null, null);
        }