예제 #1
0
        // TODO: replace this ugly-ass hack with proper AST support.
        public Expression DecompileNew()
        {
            PopByte();
            var parameters = new List<Expression>();
            for (int n = 0; n < 5; n++)
            {
                if (CurrentIs(StandardByteCodes.Nothing))
                {
                    parameters.Add(null);
                    continue;
                }

                var param = DecompileExpression();
                if (param == null)
                    return null; // ERROR

                parameters.Add(param);
            }

            Expression first = null;
            if ((parameters[0] ?? parameters[1] ?? parameters[2]) != null)
            {
                var innerParms = new List<Expression>();
                if (parameters[0] != null)
                    innerParms.Add(parameters[0]);
                if (parameters[1] != null)
                    innerParms.Add(parameters[1]);
                if (parameters[2] != null)
                    innerParms.Add(parameters[2]);
                first = new FunctionCall(new SymbolReference(null, null, null, "new"), innerParms, null, null);
            }
            else {
                first = new SymbolReference(null, null, null, "new");
            }

            var second = parameters[3] ?? new SymbolReference(null, null, null, "NoClass??");

            var op = new InOpDeclaration("", 0, true, null, null, null, null, null, null, null);
            var firstHalf = new InOpReference(op, first, second, null, null);
            StartPositions.Pop();

            if (parameters[4] != null)
                return new InOpReference(op, firstHalf, parameters[4], null, null);
            else
                return firstHalf;
        }
예제 #2
0
        public Expression DecompileNativeFunction(UInt16 index)
        {
            var parameters = new List<Expression>();
            while (!CurrentIs(StandardByteCodes.EndFunctionParms))
            {
                var param = DecompileExpression();
                if (param == null)
                    return null; // ERROR

                parameters.Add(param);
            }
            PopByte();

            var entry = NativeTable[index];
            Expression call = null;

            switch (entry.Type)
            {
                case NativeType.Function:
                    var func = new SymbolReference(null, null, null, entry.Name);
                    call = new FunctionCall(func, parameters, null, null);
                    break;

                case NativeType.Operator:   // TODO: table should hold precedence, currently all have 0 and it'll be a mess.
                    var op = new InOpDeclaration(entry.Name, entry.Precedence, false, null, null, null, null, null, null, null);
                    call = new InOpReference(op, parameters[0], parameters[1], null, null);
                    break;

                case NativeType.PreOperator:   // TODO: table should hold precedence, currently all have 0 and it'll be a mess.
                    var preOp = new PreOpDeclaration(entry.Name, false, null, null, null, null, null, null);
                    call = new PreOpReference(preOp, parameters[0], null, null);
                    break;

                case NativeType.PostOperator:   // TODO: table should hold precedence, currently all have 0 and it'll be a mess.
                    var postOp = new PostOpDeclaration(entry.Name, false, null, null, null, null, null, null);
                    call = new PostOpReference(postOp, parameters[0], null, null);
                    break;
            }

            StartPositions.Pop();
            return call;
        }
예제 #3
0
 public bool VisitNode(FunctionCall node)
 {
     throw new NotImplementedException();
 }
예제 #4
0
        public bool VisitNode(FunctionCall node)
        {
            ExpressionPrescedence.Push(NOPRESCEDENCE);
            // functionName( parameter1, parameter2.. )
            Append("{0}(", node.Function.Name);
            foreach(Expression expr in node.Parameters)
            {
                expr.AcceptVisitor(this);
                if (node.Parameters.IndexOf(expr) != node.Parameters.Count - 1)
                    Append(", ");
            }
            Append(")");

            ExpressionPrescedence.Pop();
            return true;
        }
예제 #5
0
        public Statement DecompileStatement()
        {
            StartPositions.Push((UInt16)Position);
            var token = CurrentByte;

            switch (token)
            {
                // return [expression];
                case (byte)StandardByteCodes.Return:
                    return DecompileReturn();

                // switch (expression)
                case (byte)StandardByteCodes.Switch:
                    return DecompileSwitch();

                // case expression :
                case (byte)StandardByteCodes.Case:
                    return DecompileCase();

                // if (expression) // while / for / do until
                case (byte)StandardByteCodes.JumpIfNot:
                    return DecompileConditionalJump();

                // continue
                case (byte)StandardByteCodes.Jump: // TODO: UDK seems to compile this from break when inside ForEach, handle?
                    return DecompileJump();

                // continue (iterator)
                case (byte)StandardByteCodes.IteratorNext:
                    PopByte(); // pop iteratornext token
                    return DecompileJump();

                // break;
                case (byte)StandardByteCodes.IteratorPop:
                    return DecompileIteratorPop();

                // stop;
                case (byte)StandardByteCodes.Stop:
                    PopByte();
                    var stopStatement = new StopStatement(null, null);
                    StatementLocations.Add(StartPositions.Pop(), stopStatement);
                    return stopStatement;

                // Goto label
                case (byte)StandardByteCodes.GotoLabel:
                    PopByte();
                    var labelExpr = DecompileExpression();
                    var func = new SymbolReference(null, null, null, "goto");
                    var call = new FunctionCall(func, new List<Expression>() { labelExpr }, null, null);
                    var gotoLabel = new ExpressionOnlyStatement(null, null, call);
                    StatementLocations.Add(StartPositions.Pop(), gotoLabel);
                    return gotoLabel;

                // assignable expression = expression;
                case (byte)StandardByteCodes.Let:
                case (byte)StandardByteCodes.LetBool:
                case (byte)StandardByteCodes.LetDelegate:
                    return DecompileAssign();

                // [skip x bytes]
                case (byte)StandardByteCodes.Skip: // TODO: this should never occur as statement, possibly remove?
                    PopByte();
                    ReadUInt16();
                    StartPositions.Pop();
                    return DecompileStatement();

                case (byte)StandardByteCodes.Nothing:
                    PopByte();
                    StartPositions.Pop();
                    return DecompileStatement(); // TODO, should probably have a nothing expression or statement, this is ugly

                // foreach IteratorFunction(...)
                case (byte)StandardByteCodes.Iterator:
                    return DecompileForEach();

                // foreach arrayName(valuevariable[, indexvariable])
                case (byte)StandardByteCodes.DynArrayIterator:
                    return DecompileForEach(isDynArray: true);

                case (byte)StandardByteCodes.LabelTable:
                    DecompileLabelTable();
                    StartPositions.Pop();
                    return DecompileStatement();

                #region unsupported

                case (byte)StandardByteCodes.OptIfLocal: // TODO: verify, handle syntax
                    return DecompileConditionalJump(isOpt: true);

                case (byte)StandardByteCodes.OptIfInstance: // TODO: verify, handle syntax
                    return DecompileConditionalJump(isOpt: true);

                #endregion

                default:
                    var expr = DecompileExpression();
                    if (expr != null)
                    {
                        var statement = new ExpressionOnlyStatement(null, null, expr);
                        StatementLocations.Add(StartPositions.Pop(), statement);
                        return statement;
                    }

                    // ERROR!
                    break;
            }

            return null;
        }
예제 #6
0
        // TODO: guess for loop, probably requires a large restructure
        public Statement DecompileForEach(bool isDynArray = false)
        {
            PopByte();
            var scopeStatements = new List<Statement>();

            var iteratorFunc = DecompileExpression();
            if (iteratorFunc == null)
                return null;

            Expression dynArrVar = null;
            Expression dynArrIndex = null;
            bool unknByte = false;
            if (isDynArray)
            {
                dynArrVar = DecompileExpression();
                unknByte = Convert.ToBoolean(ReadByte());
                dynArrIndex = DecompileExpression();
            }

            var scopeEnd = ReadUInt16(); // MemOff
            ForEachScopes.Push(scopeEnd);

            Scopes.Add(scopeStatements);
            CurrentScope.Push(Scopes.Count - 1);
            while (Position < Size)
            {
                if (CurrentIs(StandardByteCodes.IteratorNext) && PeekByte == (byte)StandardByteCodes.IteratorPop)
                {
                    PopByte(); // IteratorNext
                    PopByte(); // IteratorPop
                    break;
                }

                var current = DecompileStatement();
                if (current == null)
                    return null; // ERROR ?

                scopeStatements.Add(current);
            }
            CurrentScope.Pop();
            ForEachScopes.Pop();

            if (isDynArray)
            {
                var builder = new CodeBuilderVisitor(); // what a wonderful hack, TODO.
                iteratorFunc.AcceptVisitor(builder);
                var arrayName = new SymbolReference(null, null, null, builder.GetCodeString());
                var parameters = new List<Expression>() { dynArrVar, dynArrIndex };
                iteratorFunc = new FunctionCall(arrayName, parameters, null, null);
            }

            var statement = new ForEachLoop(iteratorFunc, new CodeBody(scopeStatements, null, null), null, null);
            StatementLocations.Add(StartPositions.Pop(), statement);
            return statement;
        }