public TernaryOperatorTreeNode(Operator op, AbstractSyntaxTree pre, AbstractSyntaxTree mid, AbstractSyntaxTree post) : base(op) { Pre = pre; Mid = mid; Post = post; }
/// <summary> /// Test two conditions, and conditionally branch vs. fall through: /// either branch to target or fall through to subsequent code; /// conditions are and'ed together: both together constitute "true". /// Another way of thinking of this is condition conjunction (both). /// </summary> /// <param name="left"> /// Initial/left test condition. /// </param> /// <param name="right"> /// Initial/right test condition -- possibly short-circuted. /// </param> /// <param name="target"> /// Conditional branch target (or else fall thru). /// </param> /// <param name="reverse"> /// false --> normal case, fall through on both true, otherwise on false: branch to target /// true --> reversed case, fall through at least one false, otherwise on true: branch to target /// </param> public void EvalBoth(AbstractSyntaxTree left, AbstractSyntaxTree right, BranchTargetLabel target, bool reverse) { // NB: "Both" means evaluating left/first and right/second operands in the normal way. // Each operand is evaluated to branch around the then-part or loop-body on condition false, // and fall thru into the then-part or loop-body on condition true (both sub conditions being true). left.GenerateCodeForConditionalBranchWithPrettyPrint(this, target, reverse); right.GenerateCodeForConditionalBranchWithPrettyPrint(this, target, reverse); }
/// <summary> /// Test two conditions, and conditionally branch vs. fall through: /// either branch to target or fall through to subsequent code; /// conditions are or'ed together: either one constitutes "true". /// Another way of thinking of this is condition disjunction (i.e. either). /// </summary> /// <param name="left"> /// Initial/left test condition. /// </param> /// <param name="right"> /// Initial/right test condition -- possibly short-circuted. /// </param> /// <param name="target"> /// Conditional branch target (or else fall thru). /// </param> /// <param name="reverse"> /// false --> normal case, fall through to following code on at least one true, otherwise on false: branch to target /// true --> reversed case, fall through both false, otherwise on true: branch to target /// </param> public void EvalEither(AbstractSyntaxTree left, AbstractSyntaxTree right, BranchTargetLabel target, bool reverse) { // NB: "Either" means evaluating left/first operand, and on true, taking branch around the right/second operand // and into the fall thru code of the then-part or loop-body! // This requires use of an intermediate label, and a reversal of the evaluation condition, but only for the left/first operand. // The second operand is evaluated as per normal, take brach around the then-part or loop-body on condition false. var around = CreateLabel(); left.GenerateCodeForConditionalBranchWithPrettyPrint(this, around, !reverse); right.GenerateCodeForConditionalBranchWithPrettyPrint(this, target, reverse); PlaceLabelHere(around); }
/// <summary> /// For evalutating function call arguments. /// /// NB: function calls have 0 or more arguments, but they are all stored in a binary tree-type structure. /// /// There is a special operator, ArgumentSeparatorTreeNode, for that. /// These will only appear (at the top or) as the left operand of itself. /// /// They are evaluated like the comma operator except they stack the operands for the invocation /// whereas the regular comma operator ignores left-hand side results. /// </summary> /// <param name="arg"> /// AST to evalutate as parameter list /// </param> /// <returns> /// Count of arguments passed to function, for processing of the stack frame. /// </returns> public int EvaluateArgumentList(AbstractSyntaxTree arg) { if (arg == null) { Dump.WriteLine("<empty>"); return(0); } if (arg is ArgumentSeparatorTreeNode comma) { var count = EvaluateArgumentList(comma.Left); comma.Right.GenerateCodeForValueWithPrettyPrint(this, EvaluationIntention.Value); return(count + 1); } arg.GenerateCodeForValueWithPrettyPrint(this, EvaluationIntention.Value); return(1); }
private AbstractStatementNode ParseForStatement() { _scanner.ExpectToken('('); AbstractSyntaxTree initializer = null; AbstractSyntaxTree condition = null; AbstractSyntaxTree increment = null; if (!_scanner.IfToken(';')) { initializer = _expressionParser.Parse(); _scanner.ExpectToken(';'); } if (!_scanner.IfToken(';')) { condition = _expressionParser.Parse(); _scanner.ExpectToken(';'); } if (!_scanner.IfToken(')')) { increment = _expressionParser.Parse(new CodePoint((byte)')')); _scanner.ExpectToken(')'); } var forLoop = new ForStatement(initializer, condition, increment); _breakables.Push(forLoop); _continueables.Push(forLoop); var body = ParseStatement(); _breakables.Pop(); _continueables.Pop(); forLoop.Body = body; return(forLoop); }
protected void GenerateLHSValue(CodeGenContext context, AbstractSyntaxTree target, VariableTreeNode variable) { if (target == null) { // An address was generated onto the stack. // We need to use this address twice, as in a[i] += 4; // we need to read a[i] once, and write a[i] once, // from the same pointer computation context.GenerateInstruction("DUP"); // and now we'll convert one of them into the value at that location context.GenerateInstruction("Indirection"); } else if (variable != null) { context.GenerateInstruction("PUSH", variable.Value.ToString()); } else { throw new AssertionFailedException("unexpected result for LHS"); } }
public IndirectionTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public LogicalNotTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public FixPointTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public IndirectSelectionTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public FunctionCallTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public ExpressionSeparatorTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public ModuloTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public SelectionReferenceTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public ExpressionStatement(AbstractSyntaxTree expression) { Expression = expression; }
public AssignmentSubtractionTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public AssignmentBitwiseRightShiftTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public AdditionTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public ArgumentSeparatorTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public GreaterThanTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public SubscriptTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public PostfixIncrementTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public PrefixDecrementTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public NotEqualTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public NegationTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public BitwiseOrTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public BitwiseComplementTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public ShortCircutOrTreeNode(Operator op, AbstractSyntaxTree left, AbstractSyntaxTree right) : base(op, left, right) { }
public AddressOfTreeNode(Operator op, AbstractSyntaxTree arg) : base(op, arg) { }
public TernaryChoiceTreeNode(Operator op, AbstractSyntaxTree pre, AbstractSyntaxTree mid, AbstractSyntaxTree post) : base(op, pre, mid, post) { }