public CSExpression Translate(Expression value, CSClass csClassRef) { if (value == null) { return(new CSLiteral("null")); } if (value is Literal) { var expressionLiteral = (Literal)value; return(new CSLiteral(expressionLiteral.Value.ToJSString())); } else if (value is BinaryExpression) { var expressionBinary = (BinaryExpression)value; switch (expressionBinary.Operator) { case BinaryOperator.Equal: case BinaryOperator.NotEqual: case BinaryOperator.InstanceOf: { var @object = binaryTemplates[expressionBinary.Operator]; IfNeccessaryGenerateTemplateFunction(Program, @object); return(new CSCallExpression { callee = new CSMemberExpression { @object = new CSIdentifier { name = "Program" }, property = @object.name }, arguments = new CSExpression[] { Translate(expressionBinary.Left, csClassRef), Translate(expressionBinary.Right, csClassRef) } }); } case BinaryOperator.In: throw new ArgumentException("In base not supported."); default: break; } return(new CSBinaryExpression { left = Translate(expressionBinary.Left, csClassRef), right = Translate(expressionBinary.Right, csClassRef), @operator = expressionBinary.Operator.ToOperatorString() }); } else if (value is CallExpression) { var expressionCall = (CallExpression)value; CSExpression callee = Translate(expressionCall.Callee, csClassRef); CSExpression[] arguments = expressionCall.Arguments.ToList().ConvertAll(v => Translate(v, csClassRef)).ToArray(); return(new CSCallExpression { callee = callee, arguments = arguments }); } else if (value is Identifier) { var expressionIdentifier = (Identifier)value; var name = expressionIdentifier.Name; string newName; if (identiferTable.TryGetValue(name, out newName)) { name = newName; } return(new CSIdentifier { name = name }); } else if (value is MemberExpression) { var expressionMember = (MemberExpression)value; if (expressionMember.Computed) { return new CSIndexOperator { @object = Translate(expressionMember.Object, csClassRef), property = Translate(expressionMember.Property, csClassRef) } } ; else { return new CSMemberExpression { @object = Translate(expressionMember.Object, csClassRef), property = memberTable.ContainsKey(((Identifier)expressionMember.Property).Name) ? memberTable[((Identifier)expressionMember.Property).Name] : ((Identifier)expressionMember.Property).Name } }; } else if (value is AssignmentExpression) { var expressionAssignment = (AssignmentExpression)value; var left = expressionAssignment.Left; var @operator = expressionAssignment.Operator; var right = expressionAssignment.Right; return(new CSAssignmentExpression { left = Translate(left, csClassRef), right = Translate(right, csClassRef), @operator = @operator.ToOperatorString() }); } else if (value is UpdateExpression) { var expressionUpdate = (UpdateExpression)value; switch (expressionUpdate.Operator) { case UnaryOperator.BitwiseNot: break; case UnaryOperator.Void: break; case UnaryOperator.TypeOf: break; case UnaryOperator.Increment: return(new CSUnaryExpression { @operator = "++", valPos = expressionUpdate.Prefix ? CSUnaryExpression.Position.Right : CSUnaryExpression.Position.Left, value = Translate(expressionUpdate.Argument, csClassRef) }); case UnaryOperator.Decrement: return(new CSUnaryExpression { @operator = "--", valPos = expressionUpdate.Prefix ? CSUnaryExpression.Position.Right : CSUnaryExpression.Position.Left, value = Translate(expressionUpdate.Argument, csClassRef) }); default: break; } } else if (value is UnaryExpression) { var expressionUnary = (UnaryExpression)value; switch (expressionUnary.Operator) { case UnaryOperator.LogicalNot: return(new CSUnaryExpression { @operator = "!", value = Translate(expressionUnary.Argument, csClassRef), valPos = CSUnaryExpression.Position.Right }); case UnaryOperator.Plus: return(new CSCallExpression { arguments = new CSExpression[] { Translate(expressionUnary.Argument, csClassRef) }, callee = new CSMemberExpression { @object = new CSIdentifier { name = "double" }, property = "Parse" } }); case UnaryOperator.Minus: return(new CSUnaryExpression { @operator = "-", value = Translate(expressionUnary.Argument, csClassRef), valPos = CSUnaryExpression.Position.Right }); case UnaryOperator.Delete: return(new CSCallExpression { arguments = new CSExpression[] { Translate(expressionUnary.Argument, csClassRef) }, callee = new CSMemberExpression { @object = new CSIdentifier { name = "Script" }, property = "Delete" } }); } } else if (value is NewExpression) { var expressionNew = (NewExpression)value; return(new CSNewExpression { callee = Translate(expressionNew.Callee, csClassRef), arguments = expressionNew.Arguments.ToList().ConvertAll(v => Translate(v, csClassRef)).ToArray() }); } else if (value is ArrayExpression) { var expressionArray = (ArrayExpression)value; return(new CSArrayExpression { elements = expressionArray.Elements.ToList().ConvertAll(v => Translate(v, csClassRef)).ToArray() }); } else if (value is LogicalExpression) { var expressionLogical = (LogicalExpression)value; return(new CSBinaryExpression { left = Translate(expressionLogical.Left, csClassRef), right = Translate(expressionLogical.Right, csClassRef), @operator = expressionLogical.Operator.ToOperatorString() }); } else if (value is ObjectExpression) { var expressionObject = (ObjectExpression)value; return(new CSObjectExpression { value = expressionObject.Properties.ToDictionary(v => v.Key.GetKey(), v => Translate(v.Value, csClassRef)) }); } throw new NotImplementedException(); }
public CSStatement Translate(Statement value, CSClass csClassRef, bool functionNested = false) { if (value is ExpressionStatement) { var statementExpression = (ExpressionStatement)value; return(new CSExpressionStatement(Translate(statementExpression.Expression, csClassRef))); } else if (value is ReturnStatement) { var statementReturn = (ReturnStatement)value; return(new CSReturnStatement(Translate(statementReturn.Argument, csClassRef))); } else if (value is IfStatement) { var statementIf = (IfStatement)value; IEnumerable <CSStatement> consequent = Translate(GetBlockStatement(statementIf.Consequent), csClassRef); CSExpression test = Translate(statementIf.Test, csClassRef); IEnumerable <CSStatement> alternate = null; if (statementIf.Alternate != null) { alternate = Translate(GetBlockStatement(statementIf.Alternate), csClassRef); } return(new CSIfStatement { alternate = alternate, consequent = consequent, test = test }); } else if (value is WhileStatement) { var statementWhile = (WhileStatement)value; IEnumerable <CSStatement> body = Translate(GetBlockStatement(statementWhile.Body), csClassRef); CSExpression test = Translate(statementWhile.Test, csClassRef); return(new CSWhileStatement { body = body, @do = false, test = test }); } else if (value is ForStatement) { var statementFor = (ForStatement)value; var body = Translate(GetBlockStatement(statementFor.Body), csClassRef); var init = Translate(statementFor.Init, csClassRef); var test = Translate(statementFor.Test, csClassRef); var update = Translate(statementFor.Update, csClassRef); return(new CSForStatement { body = body, init = init, test = test, update = update }); } else if (value is DoWhileStatement) { var statementDoWhile = (DoWhileStatement)value; IEnumerable <CSStatement> body = Translate(GetBlockStatement(statementDoWhile.Body), csClassRef); CSExpression test = Translate(statementDoWhile.Test, csClassRef); return(new CSWhileStatement { body = body, @do = true, test = test }); } else if (value is EmptyStatement) { return(new CSEmptyStatement(true)); } else if (value is VariableDeclaration) { var statementVariableDeclaration = (VariableDeclaration)value; var varDeclTrans = statementVariableDeclaration.Declarations.ToList().ConvertAll(v => new CSVariableDeclaration.VariableDeclarator { id = new CSIdentifier { name = v.Id.Name }, type = "object" }); var init = Translate(statementVariableDeclaration.Declarations.Last().Init, csClassRef); if (functionNested) { return new CSVariableDeclaration { setTo = init, value = varDeclTrans } } ; else { csClassRef.declarables.Add(new CSStaticVariable { value = statementVariableDeclaration.Declarations.ToList().ConvertAll(v => Translate(v, csClassRef)), setTo = init }); return(new CSEmptyStatement(false)); } } else if (value is ForInStatement) { var statementForIn = (ForInStatement)value; string left = null; ForInLeftType type = ForInLeftType.String; if (statementForIn.Left is VariableDeclaration) { left = "\"" + ((VariableDeclaration)statementForIn.Left).Declarations.First().Id.Name + "\""; } else if (statementForIn.Right is Expression) { type = ForInLeftType.OutString; left = "out " + Translate((Expression)statementForIn.Left, csClassRef).GenerateCS(); } var right = Translate(statementForIn.Right, csClassRef); var body = GetBlockStatement(statementForIn.Body).ConvertAll(v => Translate(v, csClassRef)); IfNeccessaryGenerateTemplateFunction(csClassRef, new TemplateObj { name = "ForIn", parameters = new List <CSFunction.Parameter> { new CSFunction.Parameter("left", type == ForInLeftType.String ? "string" : "out string"), new CSFunction.Parameter("right", "object"), new CSFunction.Parameter("body", "Action<string>") }, returnType = "void", templateText = type == ForInLeftType.String ? "for (var {left:raw} in {right})\\n{body}({left:raw})" : "for ({left}.v in {right})\\n{body}({left}.v)", }); return(new CSExpressionStatement( new CSCallExpression { callee = new CSMemberExpression { @object = new CSIdentifier { name = "Program" }, property = "ForIn" }, arguments = new CSExpression[] { new CSLiteral(left), right, new CSFunction { blocks = body, parameters = new List <CSFunction.Parameter> { new CSFunction.Parameter(left.Split(' ').Last().Replace("\"", ""), "string") } } } })); } throw new NotImplementedException(); }