public RedILNode VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, State data) { var operand = CastUtilities.CastRedILNode <ExpressionNode>(unaryOperatorExpression.Expression.AcceptVisitor(this, data.NewState(unaryOperatorExpression, null))); if (OperatorUtilities.IsIncrement(unaryOperatorExpression.Operator)) { if (data.ParentNode.NodeType != NodeType.Statement) { throw new RedILException($"Incremental operators can only be used within statements"); } BinaryExpressionOperator binaryOp = default; switch (unaryOperatorExpression.Operator) { case UnaryOperatorType.Increment: case UnaryOperatorType.PostIncrement: binaryOp = BinaryExpressionOperator.Add; break; case UnaryOperatorType.Decrement: case UnaryOperatorType.PostDecrement: binaryOp = BinaryExpressionOperator.Subtract; break; } var constantOne = new ConstantValueNode(DataValueType.Integer, 1); return(new AssignNode(operand, VisitBinaryOperatorExpression(operand, constantOne, binaryOp, data.NewState(unaryOperatorExpression, null)))); } var op = OperatorUtilities.UnaryOperator(unaryOperatorExpression.Operator); return(new UnaryExpressionNode(op, operand)); }
public RedILNode VisitIndexerExpression(IndexerExpression indexerExpression, State data) { //TODO: set parent node var target = CastUtilities.CastRedILNode <ExpressionNode>(indexerExpression.Target.AcceptVisitor(this, data.NewState(indexerExpression, null))); foreach (var arg in indexerExpression.Arguments) { var argVisited = CastUtilities.CastRedILNode <ExpressionNode>(arg.AcceptVisitor(this, data.NewState(indexerExpression, null))); // In LUA, array indices start at 1 if (target.DataType == DataValueType.Array && argVisited.DataType == DataValueType.Integer) { if (argVisited.Type == RedILNodeType.Constant) { argVisited = new ConstantValueNode(DataValueType.Integer, int.Parse(((ConstantValueNode)argVisited).Value.ToString()) + 1); } else { argVisited = new BinaryExpressionNode(DataValueType.Integer, BinaryExpressionOperator.Add, argVisited, new ConstantValueNode(DataValueType.Integer, 1)); } } target = new TableKeyAccessNode(target, argVisited); } return(target); }
public RedILNode VisitReturnStatement(ReturnStatement returnStatement, State data) { var returnNode = new ReturnNode(); returnNode.Value = CastUtilities.CastRedILNode <ExpressionNode>(returnStatement.Expression.AcceptVisitor(this, data.NewState(returnStatement, returnNode))); return(returnNode); }
public RedILNode VisitForStatement(ForStatement forStatement, State data) { var blockNode = new BlockNode() { Explicit = false }; foreach (var initializer in forStatement.Initializers) { var visited = initializer.AcceptVisitor(this, data.NewState(forStatement, blockNode)); blockNode.Children.Add(visited); } var whileNode = new WhileNode(); whileNode.Condition = CastUtilities.CastRedILNode <ExpressionNode>(forStatement.Condition.AcceptVisitor(this, data.NewState(forStatement, whileNode))); whileNode.Body = RemoveFirstLevelContinue(CastUtilities.CastRedILNode <BlockNode>( forStatement.EmbeddedStatement.AcceptVisitor(this, data.NewState(forStatement, whileNode))), data); foreach (var iterator in forStatement.Iterators) { var visited = iterator.AcceptVisitor(this, data.NewState(forStatement, whileNode)); whileNode.Body.Children.Add(visited); } blockNode.Children.Add(whileNode); return(blockNode); }
public RedILNode VisitAssignmentExpression(AssignmentExpression assignmentExpression, State data) { if (data.ParentNode.NodeType != NodeType.Statement) { throw new RedILException("Assigment is only possible within a statement"); } var assignNode = new AssignNode(); var left = CastUtilities.CastRedILNode <ExpressionNode>(assignmentExpression.Left.AcceptVisitor(this, data.NewState(assignmentExpression, assignNode))); var right = CastUtilities.CastRedILNode <ExpressionNode>(assignmentExpression.Right.AcceptVisitor(this, data.NewState(assignmentExpression, assignNode))); if (assignmentExpression.Operator == AssignmentOperatorType.Assign) { assignNode.Left = left; assignNode.Right = right; } else { var op = OperatorUtilities.BinaryOperator(assignmentExpression.Operator); assignNode.Left = left; assignNode.Right = VisitBinaryOperatorExpression(left, right, op, data); } return(assignNode); }
public RedILNode VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, State data) { //Note: this handles explicit member references, invocations are handled solly by VisitInvocationExpression var isStatic = memberReferenceExpression.Target is TypeReferenceExpression; var resolveResult = memberReferenceExpression.Annotations.FirstOrDefault(annot => annot is MemberResolveResult) as MemberResolveResult; if (resolveResult is null) { throw new RedILException($"Unable to find member resolve annotation"); } //TODO: Consider caching var targetType = Type.GetType(resolveResult.TargetResult.Type.ReflectionName); var members = targetType.GetMember(memberReferenceExpression.MemberName, (isStatic ? BindingFlags.Static : BindingFlags.Instance) | BindingFlags.Public); var member = members.FirstOrDefault(); if (member is null) { throw new RedILException( $"Unable to find '{memberReferenceExpression.MemberName}' member in '{resolveResult.TargetResult.Type.ReflectionName}'"); } var redILResolveAttribute = member.CustomAttributes .FirstOrDefault(attr => attr.AttributeType == typeof(RedILResolve)); RedILResolver resolver; if (redILResolveAttribute is null) { resolver = _compiler._externalResolvers.FindResolver(resolveResult.TargetResult.Type.ReflectionName, resolveResult.TargetResult.Type.FullName, memberReferenceExpression.MemberName, EntryType.Member); if (resolver is null) { throw new RedILException($"Could not find resolver for '{memberReferenceExpression.MemberName}' of '{resolveResult.TargetResult.Type.ReflectionName}'"); } } else { var resolverTypeArg = redILResolveAttribute.ConstructorArguments.First().Value; var resolverCustomArgs = (redILResolveAttribute.ConstructorArguments.Skip(1).First().Value as ReadOnlyCollection <CustomAttributeTypedArgument>).Select(arg => arg.Value).ToArray(); var resolve = Activator.CreateInstance(redILResolveAttribute.AttributeType, resolverTypeArg, resolverCustomArgs) as RedILResolve; resolver = resolve.CreateResolver(); } var target = isStatic ? null : CastUtilities.CastRedILNode <ExpressionNode>(memberReferenceExpression.Target.AcceptVisitor(this, data.NewState(memberReferenceExpression, null))); return(resolver.Resolve(null, target, null)); }
public RedILNode VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, State data) { //TODO: send parent node var op = OperatorUtilities.BinaryOperator(binaryOperatorExpression.Operator); var left = CastUtilities.CastRedILNode <ExpressionNode>(binaryOperatorExpression.Left.AcceptVisitor(this, data.NewState(binaryOperatorExpression, null))); var right = CastUtilities.CastRedILNode <ExpressionNode>(binaryOperatorExpression.Right.AcceptVisitor(this, data.NewState(binaryOperatorExpression, null))); return(VisitBinaryOperatorExpression(left, right, op, data)); }
public RedILNode VisitDoWhileStatement(DoWhileStatement doWhileStatement, State data) { var doWhile = new DoWhileNode(); doWhile.Condition = CastUtilities.CastRedILNode <ExpressionNode>(doWhileStatement.Condition.AcceptVisitor(this, data.NewState(doWhileStatement, doWhile))); doWhile.Body = RemoveFirstLevelContinue(CastUtilities.CastRedILNode <BlockNode>( doWhileStatement.EmbeddedStatement.AcceptVisitor(this, data.NewState(doWhileStatement, doWhile))), data); return(doWhile); }
public RedILNode VisitConditionalExpression(ConditionalExpression conditionalExpression, State data) { var conditional = new ConditionalExpressionNode(); conditional.Condition = CastUtilities.CastRedILNode <ExpressionNode>(conditionalExpression.Condition.AcceptVisitor(this, data.NewState(conditionalExpression, conditional))); conditional.IfYes = CastUtilities.CastRedILNode <ExpressionNode>(conditionalExpression.TrueExpression.AcceptVisitor(this, data.NewState(conditionalExpression, conditional))); conditional.IfNo = CastUtilities.CastRedILNode <ExpressionNode>(conditionalExpression.FalseExpression.AcceptVisitor(this, data.NewState(conditionalExpression, conditional))); return(conditional); }
public RedILNode VisitInterpolatedStringExpression(InterpolatedStringExpression interpolatedStringExpression, State data) { //TODO: set parent node var strings = new List <ExpressionNode>(); foreach (var str in interpolatedStringExpression.Children) { var child = CastUtilities.CastRedILNode <ExpressionNode>(str.AcceptVisitor(this, data.NewState(interpolatedStringExpression, null))); strings.Add(child); } return(new UniformOperatorNode(DataValueType.String, BinaryExpressionOperator.StringConcat, strings)); }
public RedILNode VisitVariableInitializer(VariableInitializer variableInitializer, State data) { var varDeclareNode = new VariableDeclareNode() { Name = variableInitializer.Name }; varDeclareNode.Value = variableInitializer.Initializer != null ? CastUtilities.CastRedILNode <ExpressionNode>( variableInitializer.Initializer.AcceptVisitor(this, data.NewState(variableInitializer, varDeclareNode))) : null; return(varDeclareNode); }
public RedILNode VisitCastExpression(CastExpression castExpression, State data) { var type = castExpression.Type as PrimitiveType; if (type == null) { throw new RedILException($"Only supports casting to primitive types"); } var castNode = new CastNode(TypeUtilities.GetValueType(type.KnownTypeCode)); castNode.Argument = CastUtilities.CastRedILNode <ExpressionNode>(castExpression.Expression.AcceptVisitor(this, data.NewState(castExpression, castNode))); return(castNode); }
public RedILNode VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, State data) { var block = new BlockNode() { Explicit = false }; foreach (var variable in variableDeclarationStatement.Variables) { var decl = CastUtilities.CastRedILNode <VariableDeclareNode>( variable.AcceptVisitor(this, data.NewState(variableDeclarationStatement, block))); block.Children.Add(decl); } return(block); }
public RedILNode VisitIfElseStatement(IfElseStatement ifElseStatement, State data) { var ifNode = new IfNode(); ifNode.Condition = CastUtilities.CastRedILNode <ExpressionNode>(ifElseStatement.Condition.AcceptVisitor(this, data.NewState(ifElseStatement, ifNode))); ifNode.IfTrue = ifElseStatement.TrueStatement.AcceptVisitor(this, data.NewState(ifElseStatement, ifNode)); ifNode.IfFalse = ifElseStatement.FalseStatement.AcceptVisitor(this, data.NewState(ifElseStatement, ifNode)); if (ifNode.IfTrue is NilNode) { ifNode.IfTrue = null; } if (ifNode.IfFalse is NilNode) { ifNode.IfFalse = null; } return(ifNode); }
public RedILNode VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, State data) { var arrayTableDef = new ArrayTableDefinitionNode(); arrayTableDef.Elements = arrayCreateExpression.Initializer.Elements.Select(elem => CastUtilities.CastRedILNode <ExpressionNode>(elem.AcceptVisitor(this, data.NewState(arrayCreateExpression, arrayTableDef)))).ToArray(); return(arrayTableDef); }