private BlockSyntax TranslateBlock_Block(Statement statement, TranslatorState state) { var body = SyntaxFactory.Block(); (var children, _) = TranslateBlock_Members(statement, state); if (children.IsError) { return(body.WithTrailingTrivia(children.Errors)); } foreach (var child in children.Syntax) { switch (child) { case StatementSyntax childStatement: body = body.AddStatements(childStatement); break; default: var comment = SyntaxFactory.Comment($"// py2cs: Unexpected child statement ({child.GetType()})"); body = body.WithTrailingTrivia(comment); break; } } return(body); }
private PythonNode ExtractStatement_Function(FunctionDefinition definition, TranslatorState state) { var node = PythonNode.CreateFunction(definition, state); (node, _) = Extract_Children(node, definition.Body, state); return(node); }
private ExpressionResult TranslateExpression(Expression pyExpression, TranslatorState state) { switch (pyExpression) { case UnaryExpression unaryExpression: return(TranslateExpression_Unary(unaryExpression, state)); case BinaryExpression binaryExpression: return(TranslateExpression_Binary(binaryExpression, state)); // case AndExpression andExpression: // return TranslateExpression_And(andExpression, state); // case OrExpression orExpression: // return TranslateExpression_Or(orExpression, state); // case ParenthesisExpression parenthesisExpression: // return TranslateExpression_Parenthesis(parenthesisExpression, state); case ConstantExpression constantExpression: return(TranslateExpression_Constant(constantExpression)); // case ListExpression listExpression: // return TranslateExpression_List(listExpression, state); // case DictionaryExpression dictionaryExpression: // return TranslateExpression_Dictionary(dictionaryExpression, state); case NameExpression nameExpression: return(TranslateExpression_Name(nameExpression, state)); case MemberExpression memberExpression: return(TranslateExpression_Member(memberExpression, state)); // case IndexExpression indexExpression: // return TranslateExpression_Index(indexExpression, state); // case TupleExpression tupleExpression: // return TranslateExpression_Tuple(tupleExpression, state); case CallExpression callExpression: return(TranslateExpression_Call(callExpression, state)); default: return(ExpressionResult.WithError($"// py2cs: Unknown expression type ({pyExpression.NodeName}, {pyExpression.GetType()})")); } }
private ExpressionResult TranslateExpression_Member(MemberExpression memberExpression, TranslatorState state) { return(GetMemberExpression(memberExpression.Target, memberExpression.Name, state)); }
// private ExpressionResult TranslateExpression_List(ListExpression listExpression, TranslatorState state) // { // var items = listExpression.Items.Select(item => TranslateExpression(item, state)); // if (items.Count(item => item.IsError) > 0) // { // var errors = items.SelectMany(item => item.Errors); // return ExpressionResult.WithErrors(errors.ToList()); // } // var arrayType = SyntaxFactory.ArrayType(SyntaxFactory.ParseTypeName("object[]")); // var itemExpressions = SyntaxFactory.SeparatedList<ExpressionSyntax>(items.Select(item => item.Syntax)); // var initializer = SyntaxFactory.InitializerExpression(SyntaxKind.ArrayInitializerExpression, itemExpressions); // return SyntaxFactory.ArrayCreationExpression(arrayType, initializer); // } // private ExpressionResult TranslateExpression_Dictionary(DictionaryExpression dictionaryExpression, TranslatorState state) // { // var dictionaryType = SyntaxFactory.ParseTypeName("Dictionary<object,object>"); // var dictionaryCreator = SyntaxFactory.ObjectCreationExpression(dictionaryType); // if (dictionaryExpression.Items.Count > 0) // { // var items = SyntaxFactory.SeparatedList<ExpressionSyntax>(); // foreach (var item in dictionaryExpression.Items) // { // if (item.SliceStep != null || item.StepProvided == true) // return ExpressionResult.WithError("// py2cs: Unsupported slice step in dictionary expression"); // var keyExpression = TranslateExpression(item.SliceStart, state); // var valueExpression = TranslateExpression(item.SliceStop, state); // if (keyExpression.IsError || valueExpression.IsError) // return ExpressionResult.WithErrors(Enumerable.Concat(keyExpression.Errors, valueExpression.Errors)); // var keyValueList = SyntaxFactory.SeparatedList<ExpressionSyntax>(new[] { keyExpression.Syntax, valueExpression.Syntax }); // var keyValuePair = SyntaxFactory.InitializerExpression(SyntaxKind.ComplexElementInitializerExpression, keyValueList); // items = items.Add(keyValuePair); // } // var itemExpressions = SyntaxFactory.SeparatedList<ExpressionSyntax>(items); // var initializer = SyntaxFactory.InitializerExpression(SyntaxKind.CollectionInitializerExpression, itemExpressions); // dictionaryCreator = dictionaryCreator.WithInitializer(initializer); // } // return dictionaryCreator; // } private ExpressionResult TranslateExpression_Name(NameExpression nameExpression, TranslatorState state) { switch (nameExpression.Name) { case "True": return(ExpressionResult.Result(SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression), PythonTypes.Bool)); case "False": return(ExpressionResult.Result(SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression), PythonTypes.Bool)); default: if (state.Variables.TryGetValue(nameExpression.Name, out ExpressionResult variable)) { return(variable); } else { return(ExpressionResult.WithError($"// py2cs: Unknown name expression called: {nameExpression.Name}")); } } }
// private ExpressionResult TranslateExpression_Unary(UnaryExpression unaryExpression, TranslatorState state) // { // var operatorKind = TranslateOperator(unaryExpression.Op); // if (operatorKind == SyntaxKind.None) // return ExpressionResult.WithError($"// py2cs: Unknown unary expression type ({unaryExpression.Op})"); // return TranslateExpression_Unary(operatorKind, unaryExpression.Expression, state); // } // private ExpressionResult TranslateExpression_Unary(SyntaxKind kind, Expression expression, TranslatorState state) // { // var exp = TranslateExpression(expression, state); // if (exp.IsError) // return ExpressionResult.WithErrors(exp.Errors); // return SyntaxFactory.PrefixUnaryExpression(kind, exp.Syntax); // } private ExpressionResult TranslateExpression_Binary(BinaryExpression binaryExpression, TranslatorState state) { var operatorName = $"PythonOperator_{binaryExpression.Operator}"; var operatorMethod = GetMemberExpression(binaryExpression.Left, operatorName, state); if (operatorMethod.IsError) { return(ExpressionResult.WithErrors(operatorMethod.Errors)); } var operatorCall = GetCallExpression(operatorMethod, new Arg[] { new Arg(binaryExpression.Right) }, state); return(operatorCall); }
private (SyntaxResult <SyntaxNode[]>, TranslatorState) TranslateBlock_Members(Statement statement, TranslatorState state) { if (statement is SuiteStatement suiteStatement) { var errors = new List <SyntaxTrivia>(); var members = new List <SyntaxNode>(); foreach (Statement memberStatement in suiteStatement.Statements) { SyntaxResult <SyntaxNode> member; (member, state) = TranslateStatement(memberStatement, state); if (member.IsError) { errors.AddRange(member.Errors); } else { members.Add(member.Syntax.WithLeadingTrivia(errors)); errors.Clear(); } } if (errors.Count != 0) { if (members.Count > 0) { members[members.Count - 1] = members[members.Count - 1].WithTrailingTrivia(errors); } else { return(SyntaxResult <SyntaxNode[]> .WithErrors(errors), state); } } return(members.ToArray(), state); } else { return(SyntaxResult <SyntaxNode[]> .WithError($"// py2cs: Expected SuiteStatement"), state); } }
private SyntaxResult <StatementSyntax> TranslateStatement_If(IList <IfStatementTest> tests, Statement elseStatement, TranslatorState state) { var expression = TranslateExpression(tests[0].Test, state); var body = TranslateBlock_Block(tests[0].Body, state); if (expression.IsError) { return(SyntaxResult <StatementSyntax> .WithErrors(expression.Errors)); } IfStatementSyntax ifStatementSyntax = SyntaxFactory.IfStatement(expression.Syntax, body); if (tests.Count > 1) { var elseIf = TranslateStatement_If(tests.Skip(1).ToList(), elseStatement, state); if (elseIf.IsError) { return(SyntaxResult <StatementSyntax> .WithErrors(expression.Errors)); } var elseClause = SyntaxFactory.ElseClause(elseIf.Syntax); ifStatementSyntax = ifStatementSyntax.WithElse(elseClause); } else if (elseStatement != null) { var elseBody = TranslateBlock_Block(elseStatement, state); var elseClause = SyntaxFactory.ElseClause(elseBody); ifStatementSyntax = ifStatementSyntax.WithElse(elseClause); } return(ifStatementSyntax); }
private SyntaxResult <SyntaxNode> TranslateStatement_Assignment(AssignmentStatement assignmentStatement, TranslatorState state) { if (assignmentStatement.Left.Count != 1) { return(SyntaxResult <SyntaxNode> .WithError($"// py2cs: Unsupported assignment left expression count")); } var leftExpression = TranslateExpression(assignmentStatement.Left[0], state); var rightExpression = TranslateExpression(assignmentStatement.Right, state); if (leftExpression.IsError || rightExpression.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(Enumerable.Concat(leftExpression.Errors, rightExpression.Errors))); } var expression = SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, leftExpression.Syntax, rightExpression.Syntax); return(SyntaxFactory.ExpressionStatement(expression)); }
private ExpressionResult GetCallExpression(ExpressionResult target, IEnumerable <Arg> args, TranslatorState state) { var targetFunction = target.Type.Node as PythonFunction; if (targetFunction == null) { return(ExpressionResult.WithError($"// py2cs: Call expression on non-method type: {target.Type} ({target.Type.Node.GetType()})")); } var argumentList = SyntaxFactory.SeparatedList <ArgumentSyntax>(); foreach (Arg arg in args) { var argumentExpression = TranslateExpression(arg.Expression, state); if (argumentExpression.IsError) { return(ExpressionResult.WithErrors(argumentExpression.Errors)); } var argument = SyntaxFactory.Argument(argumentExpression.Syntax); if (arg.Name != null) { var name = SyntaxFactory.NameColon(arg.Name); argument = argument.WithNameColon(name); } argumentList = argumentList.Add(argument); } var expression = SyntaxFactory.InvocationExpression(target.Syntax, SyntaxFactory.ArgumentList(argumentList)); var expressionType = targetFunction.ReturnType; return(ExpressionResult.Result(expression, expressionType)); }
private SyntaxResult <SyntaxNode> TranslateStatement_Assert(AssertStatement assertStatement, TranslatorState state) { var argumentList = SyntaxFactory.SeparatedList <ArgumentSyntax>(); var test = TranslateExpression(assertStatement.Test, state); if (test.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(test.Errors)); } argumentList = argumentList.Add(SyntaxFactory.Argument(test.Syntax)); if (assertStatement.Message != null) { var message = TranslateExpression(assertStatement.Message, state); if (message.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(message.Errors)); } argumentList = argumentList.Add(SyntaxFactory.Argument(message.Syntax)); } var target = SyntaxFactory.ParseName("System.Diagnostics.Debug.Assert"); var invocationExpression = SyntaxFactory.InvocationExpression(target, SyntaxFactory.ArgumentList(argumentList)); return(SyntaxFactory.ExpressionStatement(invocationExpression)); }
// private (SyntaxResult<SyntaxNode>, TranslatorState) TranslateStatement_FromImportStatement(FromImportStatement fromImportStatement, TranslatorState state) // { // for (int nameIndex = 0; nameIndex < fromImportStatement.Names.Count; nameIndex++) // { // var name = fromImportStatement.Names[nameIndex]; // var asName = fromImportStatement.AsNames[nameIndex] ?? name; // state = state.WithVariable(asName, name); // } // return (SyntaxFactory.EmptyStatement(), state); // } private SyntaxResult <SyntaxNode> TranslateStatement_Expression(ExpressionStatement expressionStatement, TranslatorState state) { if (expressionStatement.Expression is ConstantExpression constantExpression) { return(SyntaxResult <SyntaxNode> .WithError("/* " + constantExpression.Value + " */")); } var expression = TranslateExpression(expressionStatement.Expression, state); if (expression.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(expression.Errors)); } return(SyntaxFactory.ExpressionStatement(expression.Syntax)); }
private SyntaxResult <SyntaxNode> TranslateStatement_With(WithStatement withStatement, TranslatorState state) { var contextManager = TranslateExpression(withStatement.ContextManager, state); var body = TranslateBlock_Block(withStatement.Body, state); if (contextManager.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(contextManager.Errors)); } var usingStatement = SyntaxFactory.UsingStatement(body).WithExpression(contextManager.Syntax); if (withStatement.Variable != null) { if (withStatement.Variable is NameExpression nameExpression) { var declarationType = SyntaxFactory.ParseTypeName("object"); var variable = SyntaxFactory.VariableDeclarator(nameExpression.Name); var declaration = SyntaxFactory.VariableDeclaration(declarationType, SyntaxFactory.SingletonSeparatedList(variable)); usingStatement = usingStatement.WithDeclaration(declaration); } else { return(SyntaxResult <SyntaxNode> .WithError($"// py2cs: Unknown with statment variable ({withStatement.Variable})")); } } return(usingStatement); }
private SyntaxResult <SyntaxNode> TranslateStatement_Raise(RaiseStatement raiseStatement, TranslatorState state) { var value = TranslateExpression(raiseStatement.ExceptType, state); if (value.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(value.Errors)); } return(SyntaxFactory.ThrowStatement(value.Syntax)); }
private SyntaxResult <SyntaxNode> TranslateStatement_While(WhileStatement whileStatement, TranslatorState state) { var expression = TranslateExpression(whileStatement.Test, state); var body = TranslateBlock_Block(whileStatement.Body, state); if (expression.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(expression.Errors)); } return(SyntaxFactory.WhileStatement(expression.Syntax, body)); }
private ExpressionResult GetMemberExpression(Expression pythonTargetExpression, string memberName, TranslatorState state) { var target = TranslateExpression(pythonTargetExpression, state); if (target.IsError) { return(ExpressionResult.WithErrors(target.Errors)); } var targetClass = target.Type.Node as PythonClass; if (targetClass == null) { return(ExpressionResult.WithError($"// py2cs: Unknown target for member expression: {target.Type}.{memberName}")); } if (!targetClass.Children.TryGetValue(memberName, out var memberNode)) { return(ExpressionResult.WithError($"// py2cs: Unknown member expression on type {targetClass}: {memberName}")); } var name = SyntaxFactory.IdentifierName(memberName); var expression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, target.Syntax, name); var expressionType = GetMemberType(memberNode); return(ExpressionResult.Result(expression, expressionType)); }
private SyntaxResult <SyntaxNode> TranslateStatement_Return(ReturnStatement returnStatement, TranslatorState state) { ReturnStatementSyntax returnStatementSyntax = SyntaxFactory.ReturnStatement(); if (returnStatement.Expression != null) { var expression = TranslateExpression(returnStatement.Expression, state); if (expression.IsError) { returnStatementSyntax = returnStatementSyntax.WithTrailingTrivia(expression.Errors); } else { returnStatementSyntax = returnStatementSyntax.WithExpression(expression.Syntax); } } return(returnStatementSyntax); }
// private ExpressionResult TranslateExpression_Index(IndexExpression indexExpression, TranslatorState state) // { // var target = TranslateExpression(indexExpression.Target, state); // var index = TranslateExpression(indexExpression.Index, state); // if (target.IsError || index.IsError) // return ExpressionResult.WithErrors(Enumerable.Concat(target.Errors, index.Errors)); // var indexArgument = SyntaxFactory.Argument(index.Syntax); // var argumentList = SyntaxFactory.BracketedArgumentList(SyntaxFactory.SingletonSeparatedList(indexArgument)); // return SyntaxFactory.ElementAccessExpression(target.Syntax, argumentList); // } // private ExpressionResult TranslateExpression_Tuple(TupleExpression tupleExpression, TranslatorState state) // { // var argumentList = SyntaxFactory.SeparatedList<ArgumentSyntax>(); // foreach (Expression expression in tupleExpression.Items) // { // var argumentExpression = TranslateExpression(expression, state); // if (argumentExpression.IsError) // return ExpressionResult.WithErrors(argumentExpression.Errors); // argumentList = argumentList.Add(SyntaxFactory.Argument(argumentExpression.Syntax)); // } // return SyntaxFactory.TupleExpression(argumentList); // } private ExpressionResult TranslateExpression_Call(CallExpression callExpression, TranslatorState state) { var target = TranslateExpression(callExpression.Target, state); if (target.IsError) { return(ExpressionResult.WithErrors(target.Errors)); } return(GetCallExpression(target, callExpression.Args, state)); }
private (PythonNode, TranslatorState) Extract_Children(PythonNode node, Statement statement, TranslatorState state) { if (statement is SuiteStatement suiteStatement) { foreach (Statement memberStatement in suiteStatement.Statements) { switch (memberStatement) { // case FromImportStatement fromImportStatement: // state = ExtractStatement_FromImportStatement(fromImportStatement, state); // break; case ClassDefinition classDefinition: var pythonClass = ExtractStatement_Class(classDefinition, state); node = node.WithChild(pythonClass); break; case FunctionDefinition functionDefinition: var pythonFunction = ExtractStatement_Function(functionDefinition, state); node = node.WithChild(pythonFunction); break; } } return(node, state); } else { throw new NotImplementedException(); } }
// private SyntaxKind TranslateOperator(PythonOperator pythonOperator) // { // switch (pythonOperator) // { // // Unary expressions // case PythonOperator.Not: return SyntaxKind.LogicalNotExpression; // // TODO : Pos // // TODO : Invert // // TODO : Negate // // Binary expressions // case PythonOperator.Add: return SyntaxKind.AddExpression; // case PythonOperator.Subtract: return SyntaxKind.SubtractExpression; // case PythonOperator.Multiply: return SyntaxKind.MultiplyExpression; // case PythonOperator.Divide: return SyntaxKind.DivideExpression; // case PythonOperator.TrueDivide: return SyntaxKind.DivideExpression; // case PythonOperator.Mod: return SyntaxKind.ModuloExpression; // case PythonOperator.BitwiseAnd: return SyntaxKind.BitwiseAndExpression; // // TODO : Xor // case PythonOperator.BitwiseOr: return SyntaxKind.BitwiseOrExpression; // case PythonOperator.ExclusiveOr: return SyntaxKind.ExclusiveOrExpression; // case PythonOperator.LeftShift: return SyntaxKind.LeftShiftExpression; // case PythonOperator.RightShift: return SyntaxKind.RightShiftExpression; // // TODO : Power // // TODO : FloorDivide // case PythonOperator.LessThan: return SyntaxKind.LessThanExpression; // case PythonOperator.LessThanOrEqual: return SyntaxKind.LessThanOrEqualExpression; // case PythonOperator.GreaterThan: return SyntaxKind.GreaterThanExpression; // case PythonOperator.GreaterThanOrEqual: return SyntaxKind.GreaterThanOrEqualExpression; // // TODO : Equal // case PythonOperator.Equals: return SyntaxKind.EqualsExpression; // // TODO : NotEqual // case PythonOperator.NotEquals: return SyntaxKind.NotEqualsExpression; // // TODO : In // // TODO : NotIn // // Note: IsNot is implemented as a special case // case PythonOperator.Is: return SyntaxKind.IsExpression; // default: return SyntaxKind.None; // } // } private ExpressionResult TranslateExpression_Unary(UnaryExpression unaryExpression, TranslatorState state) { var operatorName = $"$operator_{unaryExpression.Op}"; var operatorMethod = GetMemberExpression(unaryExpression.Expression, operatorName, state); if (operatorMethod.IsError) { return(ExpressionResult.WithErrors(operatorMethod.Errors)); } var operatorCall = GetCallExpression(operatorMethod, new Arg[] { }, state); return(operatorCall); }
private SyntaxResult <SyntaxNode> TranslateStatement_If(IfStatement ifStatement, TranslatorState state) { var ifSyntax = TranslateStatement_If(ifStatement.Tests, ifStatement.ElseStatement, state); if (ifSyntax.IsError) { return(SyntaxResult <SyntaxNode> .WithErrors(ifSyntax.Errors)); } return(ifSyntax.Syntax); }
public static PythonNode CreateFunction(FunctionDefinition definition, TranslatorState state) { return(new PythonNode(PythonNodeType.Function, definition, definition.Name, state, ImmutableList <PythonNode> .Empty)); }
private (SyntaxResult <SyntaxNode>, TranslatorState) TranslateStatement(Statement statement, TranslatorState state) { switch (statement) { // case FromImportStatement fromImportStatement: // return TranslateStatement_FromImportStatement(fromImportStatement, state); case ExpressionStatement expressionStatement: return(TranslateStatement_Expression(expressionStatement, state), state); case AssignmentStatement assignmentStatement: return(TranslateStatement_Assignment(assignmentStatement, state), state); case ReturnStatement returnStatement: return(TranslateStatement_Return(returnStatement, state), state); case IfStatement ifStatement: return(TranslateStatement_If(ifStatement, state), state); case WhileStatement whileStatement: return(TranslateStatement_While(whileStatement, state), state); case WithStatement withStatement: return(TranslateStatement_With(withStatement, state), state); case RaiseStatement raiseStatement: return(TranslateStatement_Raise(raiseStatement, state), state); case AssertStatement assertStatement: return(TranslateStatement_Assert(assertStatement, state), state); default: return(SyntaxResult <SyntaxNode> .WithError($"// py2cs: Unknown statement type ({statement.NodeName})"), state); } }
private PythonNode(PythonNodeType nodeType, Statement statement, string name, TranslatorState state, ImmutableList <PythonNode> children) { this.NodeType = nodeType; this.Statement = statement; this.Name = name; this.State = state; this.Children = children; }
public BlockSyntax TranslateFunctionBody(PythonFunction function, TranslatorState state) { var body = TranslateBlock_Block(function.PythonDefinition.Body, state); return(body); }