Example #1
0
        protected override AbstractSyntaxTree GenerateCodeForValue(CodeGenContext context, EvaluationIntention purpose)
        {
            bool evaluateForSideEffectsOnly = false;

            switch (purpose)
            {
            case EvaluationIntention.SideEffectsOnly:
                evaluateForSideEffectsOnly = true;
                break;

            case EvaluationIntention.Value:
            case EvaluationIntention.ValueOrNode:
                break;

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

            var what = Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.AddressOrNode);

            if (what == null)
            {
                // it is a temporary (and lvalue), so must be an address

                // stack has: address
                if (!evaluateForSideEffectsOnly)
                {
                    context.GenerateInstruction("DUP");                                 // stack has: address, address
                }
                context.GenerateInstruction("IDEC");                                    // stack has: address
                if (!evaluateForSideEffectsOnly)
                {
                    context.GenerateInstruction("Indirection");                         // stack has: value
                }
            }
            else if (what is VariableTreeNode variable)
            {
                context.GenerateInstruction("PUSH", variable.Value.ToString( ));
                // stack has: value
                context.GenerateInstruction("DEC");
                // stack has: value+1
                if (!evaluateForSideEffectsOnly)
                {
                    context.GenerateInstruction("DUP");                         // stack has value+1, value+1
                }
                context.GenerateInstruction("POP", variable.Value.ToString( ));
            }
            else
            {
                throw new AssertionFailedException("unexpected target" + what.ToString());
            }

            return(null);
        }
Example #2
0
        protected override AbstractSyntaxTree GenerateCodeForValue(CodeGenContext context, EvaluationIntention purpose)
        {
            // To take the address of a child expression, we capitalize on having an evaluation intention mode that matches this.
            //	We have this mode to support assignment and address of operations.
            //		Note that we must have a notion of evaluating an expression for its location rather than for its value, as
            //			we could not evaluate the left hand side of an assignment for value, and then take its address -- that doesn't work!
            //	By using the address evaluation intention for the child, there is then sometimes no code to generate for this operator.
            //	When it does need to generate code, the case of &a, for example, the it uses the PEA instruction
            //	Also note that this approach automatically detects and optimizes a sequence like &*
            //
            // Contrast this above with the Indirection operator
            //		The other operator, Indirection, needs to special case *& to collapse these two.
            //		This is because we don't have an evaluation intention mode for indirection,
            //		Instead we generate the indirection's value and the use an Indirection instruction to dereference it.
            //
            switch (purpose)
            {
            case EvaluationIntention.SideEffectsOnly:
                Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.SideEffectsOnly);
                break;

            case EvaluationIntention.Value:
                var ans = Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.AddressOrNode);

                if (ans != null)
                {
                    if (ans is VariableTreeNode variable)
                    {
                        // PEA == Push Effective Address
                        context.GenerateInstruction("PEA", variable.Value.ToString());
                    }
                    else
                    {
                        throw new AssertionFailedException("unexpected result for &");
                    }
                }
                break;

            case EvaluationIntention.ValueOrNode:
                return(Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.AddressOrNode));

            default:
                throw new AssertionFailedException("unexpected evaluation intention" + purpose);
            }
            return(null);
        }
Example #3
0
        protected override AbstractSyntaxTree GenerateCodeForValue(CodeGenContext context, EvaluationIntention purpose)
        {
            Arg.GenerateCodeForValueWithPrettyPrint(context, purpose);
            switch (purpose)
            {
            case EvaluationIntention.SideEffectsOnly:
                Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.SideEffectsOnly);
                return(null);

            case EvaluationIntention.Value:
            case EvaluationIntention.ValueOrNode:
                Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);
                context.GenerateInstruction("NEG");
                return(null);

            default:
                throw new AssertionFailedException("unexpected evaluation intention" + purpose);
            }
        }
        protected override AbstractSyntaxTree GenerateCodeForValue(CodeGenContext context, EvaluationIntention purpose)
        {
            switch (purpose)
            {
            case EvaluationIntention.SideEffectsOnly:
                Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.SideEffectsOnly);
                return(null);

            case EvaluationIntention.Value:
            case EvaluationIntention.ValueOrNode:
                Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);
                if (Op != Operators.Operator.FixPoint)
                {
                    context.GenerateInstruction(Op.ToString());
                }
                return(null);

//				case EvaluationIntention.AddressOrNode:
//					Arg.GenerateCodeForValueWithPrettyPrint ( context, EvaluationIntention.Value );
//					return null;
            default:
                throw new AssertionFailedException("unexpected evaluation intention" + purpose);
            }
        }
Example #5
0
        protected override AbstractSyntaxTree GenerateCodeForValue(CodeGenContext context, EvaluationIntention purpose)
        {
            // NB: a C string's value is its address.
            //	(There is no notion of a string's address as that would be an address of an address.)
            switch (purpose)
            {
            case EvaluationIntention.Value:
            case EvaluationIntention.ValueOrNode:
                // might be a case of *(p+i), which can be done as p[i];
                if (Arg is AddressOfTreeNode addrOf1)
                {
                    // 3404
                    // 3401: collapse *&(expr) on RHS and just generate code for the underlying expr
                    context.SetPrettyPrintProlog("<skipped> ");
                    context.PrettyPrint(Arg);
                    return(addrOf1.Arg.GenerateCodeForValueWithPrettyPrint(context, purpose));
                }
                else
                {
                    if (Arg is AdditionTreeNode addition)
                    {
                        context.SetPrettyPrintProlog("<skipped> ");
                        context.PrettyPrint(Arg);
                        addition.Left.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);
                        addition.Right.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);
                        context.GenerateInstruction("Subscript");
                    }
                    else
                    {
                        Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);
                        context.GenerateInstruction("Indirection");
                    }
                }
                break;

            case EvaluationIntention.SideEffectsOnly:
                Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.SideEffectsOnly);
                break;

            case EvaluationIntention.AddressOrNode:
                if (Arg is AddressOfTreeNode addrOf2)
                {
                    // 3401: collapse *&(expr) on LHS and just generate code for the underlying expr
                    context.SetPrettyPrintProlog("<skipped> ");
                    context.PrettyPrint(Arg);
                    return(addrOf2.Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.AddressOrNode));
                }
                else
                {
                    // NB: if we did ValueOrNode here, we'd have to handle Node results specially
                    //	as we cannot allow a Node from ValueOrNode unmodified as AddressOrNode
                    Arg.GenerateCodeForValueWithPrettyPrint(context, EvaluationIntention.Value);
                }
                break;

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

            return(null);
        }