示例#1
0
        public GenericForStatementGenerator(GeneratorFactory factory, BlockGenerator block, GenericForBlockSyntaxNode stat)
        {
            //Create a wrapper block.
            //Actually this is not necessary with the current design. We could add everything to parent block.
            //But let's still have a separation.
            //Note that this block does not contain any upvals and statements and won't be used in emit step.
            _forBlock = new BlockGenerator(factory, block.Stack, stat);

            var v1g = factory.Function.Locals[stat.HiddenVariableF];
            var v2g = factory.Function.Locals[stat.HiddenVariableS];
            var v3g = factory.Function.Locals[stat.HiddenVariableV];


            //To calculate the f,s,var tuple.
            //This will be inserted as the first statement of _forBlock.
            _assignment = new AssignmentStatementGenerator(factory, _forBlock, new() { v1g, v2g, v3g }, stat.ExpressionList);

            //Store the stack slot for f and var1.
            var ctrlVarOnStack = v1g.TryGetFromStack(out _hiddenVariableStack);

            Debug.Assert(ctrlVarOnStack);
            var var1OnStack = factory.Function.Locals[stat.LoopVariables[0]].TryGetFromStack(out _firstLoopVarStack);

            Debug.Assert(var1OnStack);

            //Get the return sig type.
            var sigWriter = new SignatureWriter();

            foreach (var loopVar in stat.LoopVariables)
            {
                factory.Function.Locals[loopVar].WritSig(sigWriter);
            }
            (_loopVarSigType, _loopVarSig) = sigWriter.GetSignature(factory.Function.SignatureManager);
        }
示例#2
0
        public ConditionGenerator(GeneratorFactory factory, BlockGenerator block,
                                  ExpressionSyntaxNode expr, LabelStatementSyntaxNode falseLabel, bool reverseCondition)
        {
            while (expr is UnaryExpressionSyntaxNode unary && unary.Operator == UnaryOperator.Not)
            {
                expr             = unary.Operand;
                reverseCondition = !reverseCondition;
            }

            if (expr is BinaryExpressionSyntaxNode bin && IsComparisonExpr(bin, out _opcode, out _exchangeComparison))
            {
                _isComparison = true;
                //Normally, reverse the cmp (jump to false label if condition is not met).
                if (!reverseCondition)
                {
                    ReverseComparisonResult(ref _opcode);
                }
                _expr1 = factory.CreateExpression(block, bin.Left);
                _expr2 = factory.CreateExpression(block, bin.Right);
                if (!_expr1.TryGetFromStack(out _))
                {
                    _expr1Stack = block.TempAllocator.Allocate(_expr1.GetSingleType());
                }
                if (!_expr2.TryGetFromStack(out _))
                {
                    _expr2Stack = block.TempAllocator.Allocate(_expr2.GetSingleType());
                }
            }
示例#3
0
        public RepeatStatementGenerator(GeneratorFactory factory, BlockGenerator block, RepeatBlockSyntaxNode stat)
        {
            _repeatLabel = new LabelStatementSyntaxNode();
            _block       = new BlockGenerator(factory, block.Stack, stat);

            //Jump to _repeatLabel (falseLabel) if false.
            _cond = new ConditionGenerator(factory, _block, stat.StopCondition, _repeatLabel, reverseCondition: false);
        }
示例#4
0
        //This is used by the public ctor and ComparisonBinaryExpressionGenerator.
        protected BinaryExpressionGenerator(GeneratorFactory factory, BlockGenerator block,
                                            ExpressionGenerator left, ExpressionGenerator right, VMSpecializationType type)
            : base(factory)
        {
            _type = type;

            _left  = left;
            _right = right;
            var leftType  = left.GetSingleType();
            var rightType = right.GetSingleType();

            if (leftType != VMSpecializationType.Polymorphic ||
                rightType != VMSpecializationType.Polymorphic ||
                _type != VMSpecializationType.Polymorphic)
            {
                throw new NotImplementedException();
            }

            //Determine whether we can share the dest slot with one of the operands.
            //This saves a stack slot.
            //  ? = (expr) + a
            //will be generated as
            //  dest = (expr)
            //  dest = dest + a

            //Note that at this point we have no idea what variable (or temp variable)
            //will be assigned to this binary expr, so for the code
            //  a = (expr) + a
            //we will get an invalid code if we use the above pattern:
            //  a = (expr)
            //  a = a + a --> Wrong, the value that was in the second a has been lost!
            //This special case is handled during emit stage.
            var leftOnStack  = left.TryGetFromStack(out _);
            var rightOnStack = right.TryGetFromStack(out _);

            if (leftType == _type && !leftOnStack)
            {
                _mode      = CalcMode.LeftToDest;
                _rightTemp = block.TempAllocator.Allocate(rightType);
            }
            else if (rightType == _type && !rightOnStack)
            {
                _mode     = CalcMode.RightToDest;
                _leftTemp = block.TempAllocator.Allocate(leftType);
            }
            else
            {
                _mode = CalcMode.Normal;
                if (!leftOnStack)
                {
                    _leftTemp = block.TempAllocator.Allocate(leftType);
                }
                if (!rightOnStack)
                {
                    _rightTemp = block.TempAllocator.Allocate(rightType);
                }
            }
        }
示例#5
0
        public StatementGenerator CreateStatement(BlockGenerator parentBlock, StatementSyntaxNode statement)
        {
            switch (statement)
            {
            case AssignmentStatementSyntaxNode assignment:
                return(new AssignmentStatementGenerator(this, parentBlock,
                                                        assignment.Variables.Select(v => CreateVariable(parentBlock, v)).ToList(),
                                                        assignment.Values));

            case GenericForBlockSyntaxNode genericFor:
                return(new GenericForStatementGenerator(this, parentBlock, genericFor));

            case GotoStatementSyntaxNode @goto:
                return(new GotoStatementGenerator(@goto.Target.Target));

            case IfStatementSyntaxNode @if:
                return(new IfStatementGenerator(this, parentBlock, @if));

            case InvocationStatementSyntaxNode invocation:
                return(new InvocationStatementGenerator(this, parentBlock, invocation));

            case LabelStatementSyntaxNode label:
                return(new LabelStatementGenerator(label));

            case LocalStatementSyntaxNode local:
                return(new AssignmentStatementGenerator(this, parentBlock,
                                                        local.Variables.Select(v => Function.Locals[v]).ToList(),
                                                        local.ExpressionList));

            case NumericForBlockSyntaxNode numericFor:
                return(new NumericForStatementGenerator(this, parentBlock, numericFor));

            case RepeatBlockSyntaxNode repeat:
                return(new RepeatStatementGenerator(this, parentBlock, repeat));

            case ReturnStatementSyntaxNode @return:
                if (@return.Values.Expressions.Count == 0)
                {
                    return(new ZeroReturnStatementGenerator());
                }
                else
                {
                    return(new MultiReturnStatementGenerator(this, parentBlock, @return));
                }

            case WhileBlockSyntaxNode @while:
                return(new WhileStatementGenerator(this, parentBlock, @while));

            case BlockSyntaxNode block:
                //Block as the last (should only match simple block and function definition).
                return(new BlockGenerator(this, parentBlock?.Stack ?? Function.LocalFragment, block));

            default:
                break;
            }
            throw new Exception();
        }
示例#6
0
 public UnaryExpressionGenerator(GeneratorFactory factory, BlockGenerator block, UnaryExpressionSyntaxNode expr)
     : base(factory)
 {
     _operand  = factory.CreateExpression(block, expr.Operand);
     _operator = expr.Operator;
     _type     = expr.SpecializationType.GetVMSpecializationType();
     if (!_operand.TryGetFromStack(out _))
     {
         _tmpSlot = block.TempAllocator.Allocate(_operand.GetSingleType());
     }
 }
示例#7
0
 //This public ctor works for arithmetic binary ops.
 public BinaryExpressionGenerator(GeneratorFactory factory, BlockGenerator block, BinaryExpressionSyntaxNode expr)
     : this(factory, block, factory.CreateExpression(block, expr.Left), factory.CreateExpression(block, expr.Right),
            expr.SpecializationType.GetVMSpecializationType())
 {
     _opcode = expr.Operator.V switch
     {
         BinaryOperator.Raw.Add => OpCodes.ADD,
         BinaryOperator.Raw.Sub => OpCodes.SUB,
         BinaryOperator.Raw.Mul => OpCodes.MUL,
         BinaryOperator.Raw.Div => OpCodes.DIV,
         BinaryOperator.Raw.Mod => OpCodes.MOD,
         BinaryOperator.Raw.Pow => OpCodes.POW,
         _ => throw new Exception(), //Should not get here.
     };
 }
 public IndexVariableGenerator(GeneratorFactory factory, BlockGenerator block, IndexVariableSyntaxNode expr)
     : base(factory)
 {
     _table = factory.CreateExpression(block, expr.Table);
     _key   = factory.CreateExpression(block, expr.Key);
     _type  = expr.SpecializationType.GetVMSpecializationType();
     if (!_table.TryGetFromStack(out _))
     {
         _tableStack = block.TempAllocator.Allocate(expr.Table);
     }
     if (!_key.TryGetFromStack(out _))
     {
         _keyStack = block.TempAllocator.Allocate(expr.Key);
     }
 }
示例#9
0
 public AndOrExpressionGenerator(GeneratorFactory factory, BlockGenerator block, BinaryExpressionSyntaxNode expr)
     : base(factory)
 {
     _type  = expr.SpecializationType.GetVMSpecializationType();
     _left  = factory.CreateExpression(block, expr.Left);
     _right = factory.CreateExpression(block, expr.Right);
     if (_left.GetSingleType() != _type)
     {
         _leftStack = block.TempAllocator.Allocate(_left.GetSingleType());
     }
     if (_right.GetSingleType() != _type)
     {
         _rightStack = block.TempAllocator.Allocate(_right.GetSingleType());
     }
     _opcode = expr.Operator.V == BinaryOperator.Raw.And ? OpCodes.ISFC : OpCodes.ISTC;
 }
示例#10
0
        public ExpressionGenerator CreateVariable(BlockGenerator parentBlock, VariableSyntaxNode expr)
        {
            switch (expr)
            {
            case NamedVariableSyntaxNode namedVariable:
                //Same as expr (LocalVariableExprGen and UpvalueExprGen handles both get and set).
                return(CreateExpression(parentBlock, namedVariable));

            case IndexVariableSyntaxNode indexVariable:
                return(new IndexVariableGenerator(this, parentBlock, indexVariable));

            default:
                break;
            }
            throw new Exception();
        }
示例#11
0
        public NumericForStatementGenerator(GeneratorFactory factory, BlockGenerator block, NumericForBlockSyntaxNode stat)
        {
            var stack = new GroupStackFragment();

            block.Stack.Add(stack);

            _e1 = factory.CreateExpression(block, stat.From);
            _e2 = factory.CreateExpression(block, stat.To);
            var stepExpr = stat.Step ?? new LiteralExpressionSyntaxNode()
            {
                DoubleValue = 1
            };

            _e3 = factory.CreateExpression(block, stepExpr);
            var e1t = _e1.GetSingleType();
            var e2t = _e2.GetSingleType();
            var e3t = _e3.GetSingleType();

            if (e1t == VMSpecializationType.Polymorphic &&
                e2t == VMSpecializationType.Polymorphic &&
                e3t == VMSpecializationType.Polymorphic)
            {
                _initOp = Opcodes.FORI;
                _loopOp = Opcodes.FORL;
            }
            else
            {
                throw new NotImplementedException();
            }

            var ctrlStack = new BlockStackFragment();

            stack.Add(ctrlStack);
            _e1Stack = ctrlStack.AddSpecializedType(e1t);
            _e2Stack = ctrlStack.AddSpecializedType(e2t);
            _e3Stack = ctrlStack.AddSpecializedType(e3t);

            //Use stack (so it's after control variables).
            //This will also handle the aux block for us.
            _forBlock = new BlockGenerator(factory, stack, stat);

            var loopVar        = factory.Function.Locals[stat.Variable];
            var loopVarOnStack = loopVar.TryGetFromStack(out _loopVar);

            Debug.Assert(loopVarOnStack);
        }
示例#12
0
 public IndexExpressionGenerator(GeneratorFactory factory, BlockGenerator block, IndexVariableSyntaxNode expr)
     : base(factory, block, GetTable(factory, block, expr, out var key, out var type), key, type)
示例#13
0
 public WhileStatementGenerator(GeneratorFactory factory, BlockGenerator block, WhileBlockSyntaxNode stat)
 {
     _exitLabel = new LabelStatementSyntaxNode();
     _cond      = new ConditionGenerator(factory, block, stat.Condition, _exitLabel, reverseCondition: false);
     _block     = new BlockGenerator(factory, block.Stack, stat);
 }
示例#14
0
        public ExpressionGenerator CreateExpression(BlockGenerator parentBlock, ExpressionSyntaxNode expr)
        {
            switch (expr)
            {
            case BinaryExpressionSyntaxNode binary:
            {
                switch (binary.Operator.V)
                {
                case BinaryOperator.Raw.Add:
                case BinaryOperator.Raw.Sub:
                case BinaryOperator.Raw.Mul:
                case BinaryOperator.Raw.Div:
                case BinaryOperator.Raw.Pow:
                case BinaryOperator.Raw.Mod:
                    return(new BinaryExpressionGenerator(this, parentBlock, binary));

                case BinaryOperator.Raw.Conc:
                    return(new ConcatBinaryExpressionGenerator(this, parentBlock, binary));

                case BinaryOperator.Raw.L:
                case BinaryOperator.Raw.LE:
                case BinaryOperator.Raw.G:
                case BinaryOperator.Raw.GE:
                case BinaryOperator.Raw.E:
                case BinaryOperator.Raw.NE:
                    return(new ComparisonBinaryExpressionGenerator(this, parentBlock, binary));

                case BinaryOperator.Raw.And:
                case BinaryOperator.Raw.Or:
                    return(new AndOrExpressionGenerator(this, parentBlock, binary));

                default:
                    break;
                }
                break;
            }

            case FunctionExpressionSyntaxNode function:
                return(new FunctionExpressionGenerator(this, function));

            case IndexVariableSyntaxNode indexVariable:
                return(new IndexExpressionGenerator(this, parentBlock, indexVariable));

            case InvocationExpressionSyntaxNode invocation:
                return(new InvocationExpressionGenerator(this, parentBlock, invocation));

            case LiteralExpressionSyntaxNode literal:
                return(new LiteralExpressionGenerator(Function, literal));

            case NamedVariableSyntaxNode nameVariable:
            {
                //We don't create from the expr syntax node, so confirm the type is correct.
                var ret = Function.Locals[nameVariable.Variable.Target];
                Debug.Assert(nameVariable.SpecializationType.GetVMSpecializationType() == ret.GetSingleType());
                return(ret);
            }

            case TableExpressionSyntaxNode table:
                return(new TableExpressionGenerator(this, parentBlock, table));

            case UnaryExpressionSyntaxNode unary:
                return(new UnaryExpressionGenerator(this, parentBlock, unary));

            case VarargExpressionSyntaxNode vararg:
                return(new VarargExpressionGenerator(Function.FunctionDefinition, vararg));

            default:
                break;
            }
            throw new Exception();
        }
示例#15
0
 public InvocationStatementGenerator(GeneratorFactory factory, BlockGenerator block, InvocationStatementSyntaxNode stat)
 {
     _expr = factory.CreateExpression(block, stat.Invocation);
 }
 public ComparisonBinaryExpressionGenerator(GeneratorFactory factory, BlockGenerator block,
                                            BinaryExpressionSyntaxNode expr)
     : base(factory, block, CheckSwap(factory, block, expr, out var right, out var op, out var r), right,