예제 #1
0
 public Statement FromSPAGS(SPAGS.Function spagsFunc, SPAGS.Statement spagsStatement, ScopedBlock jsScope)
 {
     SPAGS.Function callFunction;
     List<SPAGS.Expression> callParams;
     List<SPAGS.Expression> callVarargs;
     if (spagsStatement.TryGetSimpleCall(out callFunction, out callParams, out callVarargs))
     {
         return (Statement)FromSPAGS(callFunction, callParams, callVarargs);
     }
     switch (spagsStatement.Type)
     {
         case SPAGS.StatementType.Block:
             SPAGS.Statement.Block spagsBlock = (SPAGS.Statement.Block)spagsStatement;
             Statement.GenericBlock jsBlock = new Statement.GenericBlock();
             foreach (SPAGS.Statement statement in spagsBlock.ChildStatements)
             {
                 jsBlock.Block.Add(FromSPAGS(spagsFunc, statement, jsScope));
             }
             return jsBlock;
         case SPAGS.StatementType.Assign:
             SPAGS.Statement.Assign spagsAssign = (SPAGS.Statement.Assign)spagsStatement;
             PossibleValueTypes assignType = GetValueTypes(spagsAssign.Target.GetValueType());
             Expression jsAssign = new Expression.InfixOperation(
                 FromSPAGS(spagsAssign.Target),
                 Infix.Assign,
                 FromSPAGS(spagsAssign.SimpleAssignValue()).Cast(assignType));
             return (Statement)jsAssign;
         case SPAGS.StatementType.If:
             SPAGS.Statement.If spagsIf = (SPAGS.Statement.If)spagsStatement;
             Statement.If jsIf = new Statement.If(
                 FromSPAGS(spagsIf.IfThisIsTrue).Cast(PossibleValueTypes.Boolean));
             if (spagsIf.ThenDoThis.Type == SPAGS.StatementType.Block)
             {
                 SPAGS.Statement.Block thenBlock = (SPAGS.Statement.Block)spagsIf.ThenDoThis;
                 foreach (SPAGS.Statement statement in thenBlock.ChildStatements)
                 {
                     jsIf.ThenDoThis.Add(FromSPAGS(spagsFunc, statement, jsScope));
                 }
             }
             else
             {
                 jsIf.ThenDoThis.Add(FromSPAGS(spagsFunc, spagsIf.ThenDoThis, jsScope));
             }
             if (spagsIf.ElseDoThis != null)
             {
                 if (spagsIf.ElseDoThis.Type == SPAGS.StatementType.Block)
                 {
                     SPAGS.Statement.Block elseBlock = (SPAGS.Statement.Block)spagsIf.ElseDoThis;
                     foreach (SPAGS.Statement statement in elseBlock.ChildStatements)
                     {
                         jsIf.ElseDoThis.Add(FromSPAGS(spagsFunc, statement, jsScope));
                     }
                 }
                 else
                 {
                     jsIf.ElseDoThis.Add(FromSPAGS(spagsFunc, spagsIf.ElseDoThis, jsScope));
                 }
             }
             return jsIf;
         case SPAGS.StatementType.Return:
             SPAGS.Statement.Return spagsReturn = (SPAGS.Statement.Return)spagsStatement;
             if (spagsReturn.Value == null)
             {
                 if (spagsFunc.Signature.ReturnType.Category == SPAGS.ValueTypeCategory.Void)
                 {
                     return new Statement.Return();
                 }
                 else
                 {
                     return new Statement.Return(FromSPAGS(spagsFunc.Signature.ReturnType.CreateDefaultValueExpression()));
                 }
             }
             else
             {
                 PossibleValueTypes returnType = GetValueTypes(spagsFunc.Signature.ReturnType);
                 return new Statement.Return(FromSPAGS(spagsReturn.Value).Cast(returnType));
             }
         case SPAGS.StatementType.VariableDeclaration:
             SPAGS.Statement.VariableDeclaration varDef = (SPAGS.Statement.VariableDeclaration)spagsStatement;
             Statement.InitVariables assignment = new Statement.InitVariables();
             foreach (SPAGS.Variable variable in varDef.Variables)
             {
                 Variable v;
                 if (jsScope.Variables.ContainsKey(variable.Name))
                 {
                     v = jsScope.Variables[variable.Name];
                 }
                 else
                 {
                     v = new Variable(variable.Name, GetValueTypes(variable.Type));
                     jsScope.Variables.Add(variable.Name, v);
                 }
                 SetReference(variable, v);
                 SPAGS.Expression val = variable.InitialValue ?? variable.Type.CreateDefaultValueExpression();
                 PossibleValueTypes variableType = GetValueTypes(variable.Type);
                 if (val.IsConstant())
                 {
                     v.InitialValue = FromSPAGS(val).Cast(variableType);
                 }
                 else
                 {
                     assignment.Add(v, FromSPAGS(val).Cast(variableType));
                 }
             }
             return assignment;
         case SPAGS.StatementType.While:
             SPAGS.Statement.While spagsLoop = (SPAGS.Statement.While)spagsStatement;
             Statement.While jsLoop = new Statement.While(
                 FromSPAGS(spagsLoop.WhileThisIsTrue).Cast(PossibleValueTypes.Boolean));
             if (spagsLoop.KeepDoingThis.Type == SPAGS.StatementType.Block)
             {
                 SPAGS.Statement.Block body = (SPAGS.Statement.Block)spagsLoop.KeepDoingThis;
                 foreach (SPAGS.Statement statement in body.ChildStatements)
                 {
                     jsLoop.KeepDoingThis.Add(FromSPAGS(spagsFunc, statement, jsScope));
                 }
             }
             else
             {
                 jsLoop.KeepDoingThis.Add(FromSPAGS(spagsFunc, spagsLoop.KeepDoingThis, jsScope));
             }
             return jsLoop;
     }
     return (Statement)(new Expression.Custom("(" + spagsStatement.Type + ")"));
 }
예제 #2
0
 public Expression FromSPAGS(SPAGS.Expression spagsExpr)
 {
     SPAGS.Function callFunction;
     List<SPAGS.Expression> callParameters, callVarargs;
     if (spagsExpr.TryGetSimpleCall(out callFunction, out callParameters, out callVarargs))
     {
         return FromSPAGS(callFunction, callParameters, callVarargs);
     }
     switch (spagsExpr.Type)
     {
         case SPAGS.ExpressionType.AllocateArray:
             SPAGS.Expression.AllocateArray arr = (SPAGS.Expression.AllocateArray)spagsExpr;
             if (arr.ElementType.Category == SPAGS.ValueTypeCategory.Struct
                 && !((SPAGS.ValueType.Struct)arr.ElementType).IsManaged)
             {
                 List<Expression> arguments = new List<Expression>();
                 arguments.Add(GetReference((SPAGS.ValueType.Struct)arr.ElementType));
                 arguments.Add(FromSPAGS(arr.Length));
                 return OtherLibraries.Util.structArray.Call(arguments);
             }
             else
             {
                 return new FillArrayExpression(
                     FromSPAGS(arr.ElementType.CreateDefaultValueExpression()),
                     FromSPAGS(arr.Length));
             }
         case SPAGS.ExpressionType.AllocStringBuffer:
             return new AllocateStringBufferExpression();
         case SPAGS.ExpressionType.AllocStruct:
             SPAGS.Expression.AllocateStruct allocStruct = (SPAGS.Expression.AllocateStruct)spagsExpr;
             Expression structCtor = GetReference(allocStruct.TheStructType);
             return new Expression.New(structCtor);
         case SPAGS.ExpressionType.ArrayIndex:
             SPAGS.Expression.ArrayIndex arrayIndex = (SPAGS.Expression.ArrayIndex)spagsExpr;
             return FromSPAGS(arrayIndex.Target).Index(FromSPAGS(arrayIndex.Index));
         case SPAGS.ExpressionType.BinaryOperator:
             SPAGS.Expression.BinaryOperator spagsBinOp = (SPAGS.Expression.BinaryOperator)spagsExpr;
             Expression left = FromSPAGS(spagsBinOp.Left);
             Expression right = FromSPAGS(spagsBinOp.Right);
             PossibleValueTypes mathCast;
             if (spagsBinOp.Left.GetValueType().Category == SPAGS.ValueTypeCategory.Int)
             {
                 mathCast = PossibleValueTypes.Int32;
             }
             else
             {
                 mathCast = PossibleValueTypes.Any;
             }
             switch (spagsBinOp.Token.Type)
             {
                 case SPAGS.TokenType.Add:
                     return left.BinOp(Infix.Add, right).Cast(mathCast);
                 case SPAGS.TokenType.BitwiseAnd:
                     return left.BinOp(Infix.BitwiseAnd, right);
                 case SPAGS.TokenType.BitwiseLeftShift:
                     return left.BinOp(Infix.BitwiseLeftShift, right);
                 case SPAGS.TokenType.BitwiseOr:
                     return left.BinOp(Infix.BitwiseOr, right);
                 case SPAGS.TokenType.BitwiseRightShift:
                     return left.BinOp(Infix.BitwiseSignedRightShift, right);
                 case SPAGS.TokenType.BitwiseXor:
                     return left.BinOp(Infix.BitwiseXor, right);
                 case SPAGS.TokenType.Divide:
                     return left.BinOp(Infix.Divide, right).Cast(mathCast);
                 case SPAGS.TokenType.IsEqualTo:
                     return left.BinOp(Infix.IsEqualTo, right).Cast(PossibleValueTypes.UInt8);
                 case SPAGS.TokenType.IsGreaterThan:
                     return left.BinOp(Infix.IsGreaterThan, right).Cast(PossibleValueTypes.UInt8);
                 case SPAGS.TokenType.IsGreaterThanOrEqualTo:
                     return left.BinOp(Infix.IsGreaterThanOrEqualTo, right).Cast(PossibleValueTypes.UInt8);
                 case SPAGS.TokenType.IsLessThan:
                     return left.BinOp(Infix.IsLessThan, right).Cast(PossibleValueTypes.UInt8);
                 case SPAGS.TokenType.IsLessThanOrEqualTo:
                     return left.BinOp(Infix.IsLessThanOrEqualTo, right).Cast(PossibleValueTypes.UInt8);
                 case SPAGS.TokenType.IsNotEqualTo:
                     return left.BinOp(Infix.IsNotEqualTo, right).Cast(PossibleValueTypes.UInt8);
                 case SPAGS.TokenType.LogicalAnd:
                     return left.BinOp(Infix.LogicalAnd, right);
                 case SPAGS.TokenType.LogicalOr:
                     return left.BinOp(Infix.LogicalOr, right);
                 case SPAGS.TokenType.Modulus:
                     return left.BinOp(Infix.Modulus, right);
                 case SPAGS.TokenType.Multiply:
                     if (mathCast == PossibleValueTypes.Int32)
                     {
                         bool useSpecialFunction = true;
                         SPAGS.ValueType leftType = spagsBinOp.Left.GetValueType();
                         SPAGS.ValueType rightType = spagsBinOp.Right.GetValueType();
                         if (leftType.IntType != "int32" || rightType.IntType != "int32"
                             || left.ValueTypes == PossibleValueTypes.Int16
                             || right.ValueTypes == PossibleValueTypes.Int16
                             || left.ValueTypes == PossibleValueTypes.UInt8
                             || right.ValueTypes == PossibleValueTypes.UInt8)
                         {
                             useSpecialFunction = false;
                         }
                         else
                         {
                             int leftVal, rightVal;
                             if (spagsBinOp.Left.TryGetIntValue(out leftVal)
                                 && (leftVal > -1000000) && (leftVal < 1000000))
                             {
                                 useSpecialFunction = false;
                             }
                             if (spagsBinOp.Right.TryGetIntValue(out rightVal)
                                 && (rightVal > -1000000) && (rightVal < 1000000))
                             {
                                 useSpecialFunction = false;
                             }
                         }
                         if (useSpecialFunction)
                         {
                             return new MultiplyIntExpression(left, right);
                         }
                         else
                         {
                             return left.BinOp(Infix.Multiply, right).Cast(PossibleValueTypes.Int32);
                         }
                     }
                     return left.BinOp(Infix.Multiply, right);
                 case SPAGS.TokenType.Subtract:
                     return left.BinOp(Infix.Subtract, right.Cast(mathCast));
                 default:
                     throw new Exception("Unknown binop: " + spagsBinOp.Token);
             }
         case SPAGS.ExpressionType.CharLiteral:
             return (Expression)(int)((SPAGS.Expression.CharLiteral)spagsExpr).Value;
         case SPAGS.ExpressionType.Constant:
             return FromSPAGS(((SPAGS.Expression.Constant)spagsExpr).TheConstant.TheExpression);
         case SPAGS.ExpressionType.EnumValue:
             return (Expression)((SPAGS.Expression.EnumValue)spagsExpr).TheValue.Value;
         case SPAGS.ExpressionType.Field:
             SPAGS.Expression.Field field = (SPAGS.Expression.Field)spagsExpr;
             return FromSPAGS(field.Target).Index(new Expression.StringLiteral(field.TheField.Name));
         case SPAGS.ExpressionType.FloatLiteral:
             return (Expression)((SPAGS.Expression.FloatLiteral)spagsExpr).Value;
         case SPAGS.ExpressionType.IntegerLiteral:
             return (Expression)((SPAGS.Expression.IntegerLiteral)spagsExpr).Value;
         case SPAGS.ExpressionType.Null:
             return Expression.Null;
         case SPAGS.ExpressionType.StringLiteral:
             //return new Expression.StringLiteral(((SPAGS.Expression.StringLiteral)spagsExpr).Value);
             return new Expression.ObfuscatedStringLiteral(((SPAGS.Expression.StringLiteral)spagsExpr).Value);
         case SPAGS.ExpressionType.UnaryOperator:
             SPAGS.Expression.UnaryOperator spagsUnOp = (SPAGS.Expression.UnaryOperator)spagsExpr;
             Expression operand = FromSPAGS(spagsUnOp.Operand);
             switch(spagsUnOp.Token.Type)
             {
                 case SPAGS.TokenType.Subtract:
                     if (spagsUnOp.Operand.GetValueType().Category == SPAGS.ValueTypeCategory.Int)
                     {
                         return operand.UnOp(Prefix.Negative).Cast(PossibleValueTypes.Int32);
                     }
                     else
                     {
                         return operand.UnOp(Prefix.Negative);
                     }
                 case SPAGS.TokenType.LogicalNot:
                     return operand.BinOp(Infix.IsEqualTo, (Expression)0).Cast(PossibleValueTypes.UInt8);
                 default:
                     throw new Exception("Unknown unop: " + spagsUnOp.Token.Type);
             }
         case SPAGS.ExpressionType.Variable:
             SPAGS.Expression.Variable spagsVar = (SPAGS.Expression.Variable)spagsExpr;
             Expression expr = GetReference(spagsVar.TheVariable);
             // TODO: string buffers...
             return expr;
     }
     return new Expression.Custom("(" + spagsExpr.Type + ")");
 }