コード例 #1
0
ファイル: CodeGenContext.cs プロジェクト: erikeidt/Draconum
 /// <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);
 }
コード例 #2
0
ファイル: CodeGenContext.cs プロジェクト: erikeidt/Draconum
 public void PlaceLabelHere(BranchTargetLabel label)
 {
     if (_labelList [label.Id])
     {
         throw new AssertionFailedException("label already defined: L" + label.Id);
     }
     _labelList [label.Id] = true;
     OutLine(String.Format("L{0}:", label.Id));
 }
コード例 #3
0
ファイル: CodeGenContext.cs プロジェクト: erikeidt/Draconum
        /// <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);
        }
コード例 #4
0
ファイル: CodeGenContext.cs プロジェクト: erikeidt/Draconum
        public void GenerateBinaryCompareConditionalBranch(Operator op, BranchTargetLabel label, bool reverse)
        {
            //Handle the Relational Operators: LessThan,LessOrEqual,GreaterThan,GreaterOrEqual,EqualEqual,NotEqual,
            var branchOpcode = "";

            switch (op)
            {
            case Operator.LessThan:
                branchOpcode = reverse ? "B.LT" : "B.GE";
                break;

            case Operator.LessOrEqual:
                branchOpcode = reverse ? "B.LE" : "B.GT";
                break;

            case Operator.GreaterThan:
                branchOpcode = reverse ? "B.GT" : "B.LE";
                break;

            case Operator.GreaterOrEqual:
                branchOpcode = reverse ? "B.GE" : "B.LT";
                break;

            case Operator.EqualEqual:
                branchOpcode = reverse ? "B.EQ" : "B.NE";
                break;

            case Operator.NotEqual:
                branchOpcode = reverse ? "B.NE" : "B.EQ";
                break;

            default:
                throw new AssertionFailedException("Operator is not one of the relational operators: " + op.ToString());
            }

            OutLine(String.Format("    {0}{2}L{1}", branchOpcode, label.Id, _argumentPosition.Substring(branchOpcode.Length)));
        }
コード例 #5
0
ファイル: CodeGenContext.cs プロジェクト: erikeidt/Draconum
        public void GenerateUnaryTestConditionalBranch(BranchTargetLabel label, bool reverse)
        {
            var opcode = reverse ? "B.TRUE" : "B.FALSE";

            OutLine(String.Format("    {0}{2}L{1}", opcode, label.Id, _argumentPosition.Substring(opcode.Length)));
        }
コード例 #6
0
ファイル: CodeGenContext.cs プロジェクト: erikeidt/Draconum
        public void GenerateUnconditionalBranch(BranchTargetLabel label)
        {
            var opcode = "JUMP";

            OutLine(String.Format("    {0}{2}L{1}", opcode, label.Id, _argumentPosition.Substring(opcode.Length)));
        }
コード例 #7
0
 public virtual void GenerateCodeForConditionalBranchWithPrettyPrint(CodeGenContext context, BranchTargetLabel label, bool reverse)
 {
     context.PrettyPrint(this);                  // prints && operator
     GenerateCodeForConditionalBranch(context, label, reverse);
 }
コード例 #8
0
        /// <summary>
        ///		Generates code for the given tree node, with the purpose of accomplishing a conditional branch to target
        ///			or falling thru to whatever comes after this generated code.
        /// </summary>
        /// <param name="context">
        ///		where the generated code is output to, and some helper functions
        /// </param>
        /// <param name="label">
        ///		the desired target of the conditional branch
        /// </param>
        /// <param name="reverse">
        ///     the reverse parameter's meaning:
        ///
        ///			false --> use the normal if-then-style evaluation:
        ///						take branch on condition false and fall thru on condition true
        ///
        ///			true  --> use the reverse of the normal sense of if-then evaluation:
        ///						take branch on condition true and fall thru on condition false
        ///						one might use this, if for some reason
        ///							we had choosen to swap the code ordering of the then-part and else-part
        ///						or, we need to evaluate something involving negation
        ///						or, we're evaluating a do ... while instead of while.
        ///
        ///		NB: The normal approach for an if-then-statement, e.g. in:
        ///				if ( a ) { b=1; }
        ///			is that we evaluate "a" and
        ///				conditionally branch: take branch around the then-part on "a" being false, or else,
        ///					fall thru to then-part (e.g. { b=1; } ) on "a" being true.
        ///
        ///     *If* statements and *While* statements and *For* statements evaluate their condition to
        ///			take the branch (around the then or the loop) on the expressed condition being false, and
        ///				fall-thru (into the then-part or loop-body) on it being true.
        ///
        ///		Sometimes we need to reverse things, e.g.:
        ///			To accomplish negation operator as in
        ///					if ( ! a ) { b=1; }
        ///				We would start by evaluating "! a" as with any if-statemetn: for conditional branch with reverse=false,
        ///					(meaning take branch on false, and fall thru on true)
        ///				However, the "!" will be handled by reversing the evaluation condition (for the further evaluation of "a")
        ///					rather than generating any actual negation code.
        ///
        ///			Also, *do while* statements evaluate the conditional for branch oppositely than regular while:
        ///				take branch (backward, to repeat the loop) on true, and fall-thru (exiting the loop) on false.
        ///			So, *do while* should evaluate its conditional expression using reverse=true.
        ///
        ///			Further note that the short-circut boolean || operator requires
        ///				evaluation of the left/first operand under reversed conditions:
        ///					this in order to branch around the right/second operand (short-circuting it).
        ///				So, to accomplish the fall thru to the then-part or loop-body,
        ///					the left/first operand is evaluated to take branch (condition true) into the then-part
        ///					and the right/second operand is evaluated to take branch (condition false) around the then-part
        ///
        ///			Combinations of &&, || and ! will reverse evaluation conditions as needed.
        ///
        ///			See the overrides:
        ///				ShortCircutAndTreeNode.GenerateCodeForConditionalBranch, and,
        ///				ShortCircutOrTreeNode.GenerateCodeForConditionalBranch
        ///
        /// </param>
        protected virtual void GenerateCodeForConditionalBranch(CodeGenContext context, BranchTargetLabel label, bool reverse)
        {
            //
            // This implementation is used by any operator that does not customize the evaluation for conditional branch:
            // This default implementation generates the value to be tested, and then does a test & branch on that value.
            //
            GenerateCodeForValue/*WithPrettyPrint*/ (context, EvaluationIntention.Value);               // pretty print already done at this level
            context.GenerateUnaryTestConditionalBranch(label, reverse);

            // Note: ! && || operators can generate substantially better code using custom implementation rather than this generic one.
            // Negation is discussed above:
            //	rather than generating code to negate a boolean and test & branch on that,
            //		negation simply evaluates the negated expression with reversed branch condition.
            // The short-circut operators also need not generate a boolean value to be tested & branched on,
            //	and can instead directly branch on the conditions of the left-hand and right-hand side expressions.
        }