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()); } }
//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); } }
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; }
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); }
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()); } }
public InvocationStatementGenerator(GeneratorFactory factory, BlockGenerator block, InvocationStatementSyntaxNode stat) { _expr = factory.CreateExpression(block, stat.Invocation); }