Ejemplo n.º 1
0
 // This on is to be invoked; it performs pretty printing, and then invokes the protected (real/overridden) one.
 public AbstractSyntaxTree GenerateCodeForValueWithPrettyPrint(CodeGenContext context, EvaluationIntention purpose)
 {
     context.PrettyPrint(this);
     return(GenerateCodeForValue(context, purpose));
 }
Ejemplo n.º 2
0
 public virtual void GenerateCodeForConditionalBranchWithPrettyPrint(CodeGenContext context, BranchTargetLabel label, bool reverse)
 {
     context.PrettyPrint(this);                  // prints && operator
     GenerateCodeForConditionalBranch(context, label, reverse);
 }
Ejemplo n.º 3
0
 /// <summary>
 ///		Generates code for the given tree node.
 /// </summary>
 /// <param name="context">
 ///		where the generated code is output to, and some helper functions
 /// </param>
 /// <param name="purpose">
 ///		A tree can be evalutated for code generation:
 ///			for side effects only:
 ///				used to evaluate statements that discard results
 ///				expect null for return value
 ///			for the value produced by the expression (unconditionally):
 ///				used to evaluate most operators in an expression context
 ///				expect null for return value meaning the result is in the "temporary" location
 ///			for the value produced by the expression when complex, or the node when a simple variable
 ///				used to evaluate function expressions
 ///				expect null meaning the result is in the "temporary" location, or,
 ///				a variable if the expression evaluates to a simple variable
 ///			for the address of the expression when complex, or the node when a simple variable
 ///				used to evaluate left-hand-side of assignment operators
 ///				expect null when the result is in the "temporary" location, or,
 ///				variable if the result is the address of a variable
 ///		Note: a tree can also be evalutated for conditional branch, but that is done with GenerateCodeForConditionalBranch, below.
 ///		See EvaluationIntention for more details.
 /// </param>
 /// <returns>
 ///		The return value takes on meaning in the context of the intended purpose of evaluation.
 ///		It is a tree node that captures the mode of the loaded value:
 ///			null		-- indicating the expression result is a "temporary", or is nothing
 ///			variable	-- if the temporary result is a variable or address
 /// </returns>
 /// This is meant to be overridden by subclasses, but not called; hence protected!
 protected abstract AbstractSyntaxTree GenerateCodeForValue(CodeGenContext context, EvaluationIntention purpose);
Ejemplo n.º 4
0
 protected override void GenerateCode(CodeGenContext context)
 {
     Expression.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.SideEffectsOnly);
 }
Ejemplo n.º 5
0
        protected override void GenerateCode(CodeGenContext context)
        {
            var target = ThenPart.GetBranchTarget();

            if (target.HasValue)
            {
                //
                // Normally, we evaluate
                //		if ( a ) { b = 1; }
                //	such that if "a" evaluates to false, then we branch around the then-part
                //		and if "a" evaluates to true, we fall-thru to the then-part
                // But when the then-part is itself a goto statement of some sort:
                //		if ( a ) { goto L; }
                //		if ( a ) { break; }
                //		if ( a ) { continue; }
                // Then instead of branching around a branch instruction,
                //	we reverse the evaluation condition and supply the control flow target:
                //	so that if "a" evaluates to true, then we branch (goto/break/continue),
                //		and if "a" evaluates to false, we don't branch
                //
                context.SetPrettyPrintProlog("If-Goto\t");
                Condition.GenerateCodeForConditionalBranchWithPrettyPrint(context, target.Value, true);
                Dump.WriteLine("<then part branch incorporated into preceding condition>");

                context.SetPrettyPrintProlog("ElsePart\t");
                ElsePart?.GenerateCodeWithPrettyPrint(context);
            }
            else if (ElsePart == null)
            {
                context.SetPrettyPrintProlog("Condition\t");
                var joinPoint = context.CreateLabel();
                Condition.GenerateCodeForConditionalBranchWithPrettyPrint(context, joinPoint, false);

                context.SetPrettyPrintProlog("ThenPart");
                ThenPart.GenerateCodeWithPrettyPrint(context);

                context.InsertComment("if-then rejoin");
                context.PlaceLabelHere(joinPoint);
            }
            /* else if ( ElsePart.IsBranchStatement () { }*/
            else
            {
                var elsePartLabel = context.CreateLabel();
                context.SetPrettyPrintProlog("Condition\t");

                Condition.GenerateCodeForConditionalBranchWithPrettyPrint(context, elsePartLabel, false);
                context.SetPrettyPrintProlog("ThenPart\t");
                ThenPart.GenerateCodeWithPrettyPrint(context);

                var joinPoint = context.CreateLabel();
                context.InsertComment("end of ThenPart");
                context.GenerateUnconditionalBranch(joinPoint);

                context.SetPrettyPrintProlog("ElsePart\t");

                context.PlaceLabelHere(elsePartLabel);

                context.InsertComment("start of ElsePart");
                ElsePart.GenerateCodeWithPrettyPrint(context);

                context.InsertComment("if-then-else rejoin");
                context.PlaceLabelHere(joinPoint);
            }
        }
Ejemplo n.º 6
0
 protected override void GenerateCode(CodeGenContext context)
 {
     context.InsertComment("declaration statement");
     // do nothing?
 }
Ejemplo n.º 7
0
        protected override void GenerateCode(CodeGenContext context)
        {
            var label = GotoTarget.GetBranchTargetLabel(context);

            context.GenerateUnconditionalBranch(label);
        }
Ejemplo n.º 8
0
 protected override void GenerateCode(CodeGenContext context)
 {
     context.InsertComment("empty statement");
     // do nothing!
 }
Ejemplo n.º 9
0
 protected override void GenerateCode(CodeGenContext context)
 {
     context.InsertComment("return statement");
     ReturnValue?.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);
     context.GenerateInstruction("RET");
 }
Ejemplo n.º 10
0
        protected override AbstractSyntaxTree GenerateCodeForValue(CodeGenContext context, EvaluationIntention purpose)
        {
            // When we ask for AddressOrNode, we will get either an address
            //		e.g. for a[i] += ..., we'll get a+i on the stack, or,
            //		for i += ..., we'll get nothing on the stack, so we can pop directly into i
            var target   = Left.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.AddressOrNode);
            var variable = target as VariableTreeNode;

            if (Op != Assignment)
            {
                GenerateLHSValue(context, target, variable);
            }

            Right.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);

            var keep = false;

            switch (purpose)
            {
            case EvaluationIntention.Value:
            case EvaluationIntention.ValueOrNode:
                keep = true;
                break;

            case EvaluationIntention.SideEffectsOnly:
                break;

            default:
                throw new AssertionFailedException("unexpected evaluation intention" + purpose);
            }

            if (Op != Assignment)
            {
                GenerateAssignmentComputation(context);
            }

            if (target == null)
            {
                // this case is that we generated an address onto the stack for the target
                //	so, we need to use indirection operators
                if (keep)
                {
                    // Stack has LeftY | RightTop <-- stack top
                    //	This instruction does *LeftY = RightTop
                    //		and pops only Left off the stack, leaving Right
                    context.GenerateInstruction("ISTORE");
                }
                else
                {
                    // Stack has LeftY | RightTop <-- stack top
                    //	This instruction does *LeftYT = RightTop
                    //		and pops both Left and Right off the stack
                    context.GenerateInstruction("IPOP");
                }
            }
            else
            {
                // this case is that we generated nothing onto the stack for the left hand side
                //	so, we'll pop or store directly into
                if (keep)
                {
                    // Stack has RightTop <-- stack top
                    //	This instruction does var = RightTop
                    //		and does not pop Right
                    //	This form is used when the assignment is used
                    //		as in f(a=b); in which b is assigned into a, and the value is passed to f
                    context.GenerateInstruction("STORE", variable.Value.ToString());
                }
                else
                {
                    // Stack has RightTop <-- stack top
                    //	This instruction does var = RightTop
                    //		and does pop Right off the stack, because the value is not wanted.
                    context.GenerateInstruction("POP", variable.Value.ToString());
                }
            }

            return(null);
        }