Пример #1
0
            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));
            }
Пример #2
0
            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);
            }
Пример #3
0
            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);
            }
Пример #4
0
            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);
            }
Пример #5
0
            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);
            }
Пример #6
0
            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));
            }
Пример #7
0
            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));
            }
Пример #8
0
            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);
            }
Пример #9
0
            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);
            }
Пример #10
0
            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));
            }
Пример #11
0
            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);
            }
Пример #12
0
            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);
            }
Пример #13
0
            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);
            }
Пример #14
0
            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);
            }
Пример #15
0
            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);
            }