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 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); } } }
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 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); } }