internal void Render(LuaBinaryExpressionSyntax node) { node.Left.Render(this); WriteSpace(); Write(node.OperatorToken); WriteSpace(); node.Right.Render(this); }
public override LuaSyntaxNode VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node) { bool isEmpty = functions_.Count == 0; if (isEmpty) { LuaFunctionExpressionSyntax function = new LuaFunctionExpressionSyntax(); PushFunction(function); blocks_.Push(function.Body); } var temp = GetTempIdentifier(node.Expression); conditionalTemps_.Push(temp); var expression = (LuaExpressionSyntax)node.Expression.Accept(this); CurBlock.Statements.Add(new LuaLocalVariableDeclaratorSyntax(temp, expression)); LuaBinaryExpressionSyntax condition = new LuaBinaryExpressionSyntax(temp, LuaSyntaxNode.Tokens.NotEquals, LuaIdentifierNameSyntax.Nil); LuaIfStatementSyntax ifStatement = new LuaIfStatementSyntax(condition); CurBlock.Statements.Add(ifStatement); blocks_.Push(ifStatement.Body); var whenNotNull = (LuaExpressionSyntax)node.WhenNotNull.Accept(this); blocks_.Pop(); conditionalTemps_.Pop(); if (node.Parent.IsKind(SyntaxKind.ExpressionStatement)) { if (isEmpty) { throw new InvalidOperationException(); } ifStatement.Body.Statements.Add(new LuaExpressionStatementSyntax(whenNotNull)); return(LuaExpressionSyntax.EmptyExpression); } else { LuaAssignmentExpressionSyntax assignment = new LuaAssignmentExpressionSyntax(temp, whenNotNull); ifStatement.Body.Statements.Add(new LuaExpressionStatementSyntax(assignment)); if (isEmpty) { var function = CurFunction; function.AddStatement(new LuaReturnStatementSyntax(temp)); blocks_.Pop(); PopFunction(); return(new LuaInvocationExpressionSyntax(new LuaParenthesizedExpressionSyntax(function))); } else { return(temp); } } }
private void AddStructEqualsObjMethod(INamedTypeSymbol symbol, LuaStructDeclarationSyntax declaration, LuaExpressionSyntax typeName, List <LuaIdentifierNameSyntax> fields) { var thisIdentifier = LuaIdentifierNameSyntax.This; LuaIdentifierNameSyntax obj = LuaIdentifierNameSyntax.Obj; LuaFunctionExpressionSyntax functionExpression = new LuaFunctionExpressionSyntax(); functionExpression.AddParameter(thisIdentifier); functionExpression.AddParameter(obj); var left = new LuaInvocationExpressionSyntax(LuaIdentifierNameSyntax.getmetatable, obj); LuaIfStatementSyntax ifStatement = new LuaIfStatementSyntax(new LuaBinaryExpressionSyntax(left, LuaSyntaxNode.Tokens.NotEquals, typeName)); ifStatement.Body.Statements.Add(new LuaReturnStatementSyntax(LuaIdentifierNameSyntax.False)); functionExpression.AddStatement(ifStatement); if (fields.Count > 0) { var equalsStatic = LuaIdentifierNameSyntax.EqualsStatic; LuaLocalVariableDeclaratorSyntax variableDeclarator = new LuaLocalVariableDeclaratorSyntax(equalsStatic, LuaIdentifierNameSyntax.SystemObjectEqualsStatic); functionExpression.AddStatement(variableDeclarator); LuaExpressionSyntax expression = null; foreach (LuaIdentifierNameSyntax field in fields) { LuaMemberAccessExpressionSyntax argument1 = new LuaMemberAccessExpressionSyntax(thisIdentifier, field); LuaMemberAccessExpressionSyntax argument2 = new LuaMemberAccessExpressionSyntax(obj, field); LuaInvocationExpressionSyntax invocation = new LuaInvocationExpressionSyntax(equalsStatic, argument1, argument2); if (expression == null) { expression = invocation; } else { expression = new LuaBinaryExpressionSyntax(expression, LuaSyntaxNode.Tokens.And, invocation); } } Contract.Assert(expression != null); functionExpression.AddStatement(new LuaReturnStatementSyntax(expression)); } declaration.AddMethod(LuaIdentifierNameSyntax.EqualsObj, functionExpression, false); }
private LuaTryAdapterExpressionSyntax VisitTryCatchesExpress(SyntaxList <CatchClauseSyntax> catches) { LuaTryAdapterExpressionSyntax functionExpress = new LuaTryAdapterExpressionSyntax(); PushFunction(functionExpress); var temp = GetTempIdentifier(catches.First()); functionExpress.CatchTemp = temp; functionExpress.AddParameter(temp); LuaIfStatementSyntax ifStatement = null; bool hasCatchRoot = false; foreach (var catchNode in catches) { bool isRootExceptionDeclaration = false; LuaExpressionSyntax ifCondition = null; if (catchNode.Filter != null) { ifCondition = (LuaExpressionSyntax)catchNode.Filter.Accept(this); } if (catchNode.Declaration != null) { var typeName = (LuaIdentifierNameSyntax)catchNode.Declaration.Type.Accept(this); if (typeName.ValueText != "System.Exception") { var mathcTypeInvocation = new LuaInvocationExpressionSyntax(LuaIdentifierNameSyntax.Is, temp, typeName); if (ifCondition != null) { ifCondition = new LuaBinaryExpressionSyntax(ifCondition, LuaSyntaxNode.Tokens.And, mathcTypeInvocation); } else { ifCondition = mathcTypeInvocation; } } else { if (!catchNode.Declaration.Identifier.IsKind(SyntaxKind.None)) { isRootExceptionDeclaration = true; } hasCatchRoot = true; } } else { hasCatchRoot = true; } var block = (LuaBlockSyntax)catchNode.Block.Accept(this); if (ifCondition != null) { LuaBlockSyntax body; if (ifStatement == null) { ifStatement = new LuaIfStatementSyntax(ifCondition); body = ifStatement.Body; } else { LuaElseIfStatementSyntax elseIfStatement = new LuaElseIfStatementSyntax(ifCondition); body = elseIfStatement.Body; ifStatement.ElseIfStatements.Add(elseIfStatement); } if (catchNode.Declaration != null && !catchNode.Declaration.Identifier.IsKind(SyntaxKind.None)) { var variableDeclarator = (LuaVariableDeclaratorSyntax)catchNode.Declaration.Accept(this); variableDeclarator.Initializer = new LuaEqualsValueClauseSyntax(temp); body.Statements.Add(new LuaLocalVariableDeclaratorSyntax(variableDeclarator)); } body.Statements.AddRange(block.Statements); } else { if (isRootExceptionDeclaration) { var variableDeclarator = (LuaVariableDeclaratorSyntax)catchNode.Declaration.Accept(this); variableDeclarator.Initializer = new LuaEqualsValueClauseSyntax(temp); block.Statements.Insert(0, new LuaLocalVariableDeclaratorSyntax(variableDeclarator)); } if (ifStatement != null) { LuaElseClauseSyntax elseClause = new LuaElseClauseSyntax(); elseClause.Body.Statements.AddRange(block.Statements); ifStatement.Else = elseClause; } else { functionExpress.AddStatements(block.Statements); } break; } } if (ifStatement != null) { if (!hasCatchRoot) { Contract.Assert(ifStatement.Else == null); LuaMultipleReturnStatementSyntax rethrowStatement = new LuaMultipleReturnStatementSyntax(); rethrowStatement.Expressions.Add(LuaIdentifierNameSyntax.One); rethrowStatement.Expressions.Add(temp); LuaBlockSyntax block = new LuaBlockSyntax(); block.Statements.Add(rethrowStatement); LuaElseClauseSyntax elseClause = new LuaElseClauseSyntax(); elseClause.Body.Statements.AddRange(block.Statements); ifStatement.Else = elseClause; } functionExpress.AddStatement(ifStatement); } PopFunction(); return(functionExpress); }
private LuaVariableListDeclarationSyntax GetMainFunctionSyntax(float left, float right, float top, float bottom, Tileset tileset, SoundEnvironment sound, params string[] initFunctions) { var localLeft = new LuaBinaryExpressionSyntax( new LuaFloatLiteralExpressionSyntax(left), LuaSyntaxNode.Tokens.Plus, new LuaInvocationExpressionSyntax("GetCameraMargin", "CAMERA_MARGIN_LEFT")); var localRight = new LuaBinaryExpressionSyntax( new LuaFloatLiteralExpressionSyntax(right), LuaSyntaxNode.Tokens.Sub, new LuaInvocationExpressionSyntax("GetCameraMargin", "CAMERA_MARGIN_RIGHT")); var localTop = new LuaBinaryExpressionSyntax( new LuaFloatLiteralExpressionSyntax(top), LuaSyntaxNode.Tokens.Sub, new LuaInvocationExpressionSyntax("GetCameraMargin", "CAMERA_MARGIN_TOP")); var localBottom = new LuaBinaryExpressionSyntax( new LuaFloatLiteralExpressionSyntax(bottom), LuaSyntaxNode.Tokens.Plus, new LuaInvocationExpressionSyntax("GetCameraMargin", "CAMERA_MARGIN_BOTTOM")); var locals = new[] { localLeft, localRight, localTop, localBottom, }; var statements = new List <LuaStatementSyntax> { new LuaLocalDeclarationStatementSyntax(new LuaLocalVariablesStatementSyntax( new[] { new LuaSymbolNameSyntax(new LuaIdentifierLiteralExpressionSyntax("left")), new LuaSymbolNameSyntax(new LuaIdentifierLiteralExpressionSyntax("right")), new LuaSymbolNameSyntax(new LuaIdentifierLiteralExpressionSyntax("top")), new LuaSymbolNameSyntax(new LuaIdentifierLiteralExpressionSyntax("bottom")), }, locals)), new LuaExpressionStatementSyntax( new LuaInvocationExpressionSyntax( "SetCameraBounds", "left", "bottom", "right", "top", "left", "top", "right", "bottom")), new LuaExpressionStatementSyntax(new LuaInvocationExpressionSyntax( "SetDayNightModels", new LuaStringLiteralExpressionSyntax(LightEnvironmentProvider.GetTerrainLightEnvironmentModel(tileset)), new LuaStringLiteralExpressionSyntax(LightEnvironmentProvider.GetUnitLightEnvironmentModel(tileset)))), new LuaExpressionStatementSyntax(new LuaInvocationExpressionSyntax("NewSoundEnvironment", new LuaStringLiteralExpressionSyntax(SoundEnvironmentProvider.GetSoundEnvironment(sound)))), new LuaExpressionStatementSyntax(new LuaInvocationExpressionSyntax("SetAmbientDaySound", new LuaStringLiteralExpressionSyntax(SoundEnvironmentProvider.GetAmbientDaySound(tileset)))), new LuaExpressionStatementSyntax(new LuaInvocationExpressionSyntax("SetAmbientNightSound", new LuaStringLiteralExpressionSyntax(SoundEnvironmentProvider.GetAmbientNightSound(tileset)))), new LuaExpressionStatementSyntax(new LuaInvocationExpressionSyntax( "SetMapMusic", new LuaStringLiteralExpressionSyntax("Music"), LuaIdentifierLiteralExpressionSyntax.False, LuaNumberLiteralExpressionSyntax.Zero)), }; foreach (var initFunction in initFunctions) { statements.Add(new LuaExpressionStatementSyntax(new LuaInvocationExpressionSyntax(initFunction))); } var functionSyntax = new LuaFunctionExpressionSyntax(); functionSyntax.AddStatements(statements); var mainFunctionDeclarator = new LuaVariableDeclaratorSyntax("main", functionSyntax); mainFunctionDeclarator.IsLocalDeclaration = false; var globalFunctionSyntax = new LuaVariableListDeclarationSyntax(); globalFunctionSyntax.Variables.Add(mainFunctionDeclarator); return(globalFunctionSyntax); }
private LuaNumericalForStatementSyntax GetNumericalForStatement(ForStatementSyntax node) { if (node.Declaration == null || node.Declaration.Variables.Count > 1) { goto Fail; } if (node.Condition == null) { goto Fail; } if (node.Incrementors.Count != 1) { goto Fail; } var variable = node.Declaration.Variables.First(); if (variable.Initializer == null) { goto Fail; } var conditionKind = node.Condition.Kind(); if (conditionKind < SyntaxKind.NotEqualsExpression || conditionKind > SyntaxKind.GreaterThanOrEqualExpression) { goto Fail; } var condition = (BinaryExpressionSyntax)node.Condition; if (!IsNumericalForVariableMatch(condition.Left, variable.Identifier)) { goto Fail; } var limitConst = semanticModel_.GetConstantValue(condition.Right); if (limitConst.HasValue) { if (!(limitConst.Value is int)) { goto Fail; } } else { bool isReadOnly = false; var symbol = semanticModel_.GetSymbolInfo(condition.Right).Symbol; if (symbol != null) { if (symbol.Kind == SymbolKind.Field) { isReadOnly = ((IFieldSymbol)symbol).IsReadOnly; } else if (symbol.Kind == SymbolKind.Property) { var propertySymbol = (IPropertySymbol)symbol; isReadOnly = propertySymbol.IsReadOnly && IsPropertyField(propertySymbol); } } if (!isReadOnly) { goto Fail; } } bool hasNoEqual; bool isPlus; var incrementor = node.Incrementors.First(); switch (incrementor.Kind()) { case SyntaxKind.PreIncrementExpression: case SyntaxKind.PreDecrementExpression: var prefixUnaryExpression = (PrefixUnaryExpressionSyntax)incrementor; if (!IsNumericalForVariableMatch(prefixUnaryExpression.Operand, variable.Identifier)) { goto Fail; } if (incrementor.IsKind(SyntaxKind.PreIncrementExpression)) { if (!IsNumericalForLess(conditionKind, out hasNoEqual)) { goto Fail; } isPlus = true; } else { if (!IsNumericalForGreater(conditionKind, out hasNoEqual)) { goto Fail; } isPlus = false; } break; case SyntaxKind.PostIncrementExpression: case SyntaxKind.PostDecrementExpression: var postfixUnaryExpression = (PostfixUnaryExpressionSyntax)incrementor; if (!IsNumericalForVariableMatch(postfixUnaryExpression.Operand, variable.Identifier)) { goto Fail; } if (incrementor.IsKind(SyntaxKind.PostIncrementExpression)) { if (!IsNumericalForLess(conditionKind, out hasNoEqual)) { goto Fail; } isPlus = true; } else { if (!IsNumericalForGreater(conditionKind, out hasNoEqual)) { goto Fail; } isPlus = false; } break; default: goto Fail; } LuaIdentifierNameSyntax identifier = new LuaIdentifierNameSyntax(variable.Identifier.ValueText); CheckLocalVariableName(ref identifier, variable); var startExpression = (LuaExpressionSyntax)variable.Initializer.Value.Accept(this); LuaExpressionSyntax limitExpression; LuaExpressionSyntax stepExpression = null; if (hasNoEqual) { if (limitConst.Value != null) { int limit = (int)limitConst.Value; if (isPlus) { --limit; } else { ++limit; stepExpression = new LuaPrefixUnaryExpressionSyntax(LuaIdentifierNameSyntax.One, LuaSyntaxNode.Tokens.Sub); } limitExpression = new LuaIdentifierLiteralExpressionSyntax(limit.ToString()); } else { limitExpression = (LuaExpressionSyntax)condition.Right.Accept(this); if (isPlus) { limitExpression = new LuaBinaryExpressionSyntax(limitExpression, LuaSyntaxNode.Tokens.Sub, LuaIdentifierNameSyntax.One); } else { limitExpression = new LuaBinaryExpressionSyntax(limitExpression, LuaSyntaxNode.Tokens.Plus, LuaIdentifierNameSyntax.One); stepExpression = new LuaPrefixUnaryExpressionSyntax(LuaIdentifierNameSyntax.One, LuaSyntaxNode.Tokens.Sub); } } } else { limitExpression = (LuaExpressionSyntax)condition.Right.Accept(this); if (!isPlus) { stepExpression = new LuaPrefixUnaryExpressionSyntax(LuaIdentifierNameSyntax.One, LuaSyntaxNode.Tokens.Sub); } } var numericalForStatement = new LuaNumericalForStatementSyntax(identifier, startExpression, limitExpression, stepExpression); VisitLoopBody(node.Statement, numericalForStatement.Body); return numericalForStatement; Fail: return null; }