Пример #1
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            //Jumps need special treatment for label resolution

            if (Instruction.Arguments == -1)
            {
                switch (Instruction.OpCode)
                {
                    case OpCode.jump:
                        target.EmitJump(Position, Instruction.Id);
                        break;
                    case OpCode.jump_t:
                        target.EmitJumpIfTrue(Position, Instruction.Id);
                        break;
                    case OpCode.jump_f:
                        target.EmitJumpIfFalse(Position, Instruction.Id);
                        break;
                    case OpCode.leave:
                        target.EmitLeave(Position, Instruction.Id);
                        break;
                    default:
                        goto emitNormally;
                }
            }
            else
                goto emitNormally;

            return;
            emitNormally:
            target.Emit(Position, Instruction);
        }
Пример #2
0
 //Called by either AstLogicalAnd or AstLogicalOr
 protected override void DoEmitCode(CompilerTarget target, string trueLabel,
     string falseLabel)
 {
     var labelNs = @"And\" + Guid.NewGuid().ToString("N");
     var nextLabel = @"Next\" + labelNs;
     foreach (var expr in Conditions)
     {
         var or = expr as AstLogicalOr;
         if (or != null)
         {
             or.EmitCode(target, nextLabel, falseLabel);
             //ResolveOperator pending jumps to Next
             target.EmitLabel(Position, nextLabel);
             target.FreeLabel(nextLabel);
             //Future references of to nextLabel will be resolved in the next iteration
         }
         else
         {
             expr.EmitValueCode(target);
             target.EmitJumpIfFalse(Position, falseLabel);
         }
     }
     target.EmitJump(Position, trueLabel);
 }
Пример #3
0
        public void DoEmitPartialApplicationCode(CompilerTarget target)
        {
            AstPlaceholder.DeterminePlaceholderIndices(Expressions.OfType<AstPlaceholder>());

            var count = Expressions.Count;
            if (count == 0)
            {
                this.ConstFunc(null).EmitValueCode(target);
                return;
            }

            //only the very last condition may be a placeholder
            for (var i = 0; i < count; i++)
            {
                var value = Expressions[i];
                var isPlaceholder = value.IsPlaceholder();
                if (i == count - 1)
                {
                    if (!isPlaceholder)
                    {
                        //there is no placeholder at all, wrap expression in const
                        Debug.Assert(Expressions.All(e => !e.IsPlaceholder()));
                        DoEmitCode(target,StackSemantics.Value);
                        target.EmitCommandCall(Position, 1, Const.Alias);
                        return;
                    }
                }
                else
                {
                    if (isPlaceholder)
                    {
                        _reportInvalidPlaceholders(target);
                        return;
                    }
                }
            }

            if (count == 0)
            {
                this.ConstFunc().EmitValueCode(target);
            }
            else if (count == 1)
            {
                Debug.Assert(Expressions[0].IsPlaceholder(),
                    "Singleton ??-chain expected to consist of placeholder.");
                var placeholder = (AstPlaceholder) Expressions[0];
                placeholder.IdFunc().EmitValueCode(target);
            }
            else
            {
                Debug.Assert(Expressions[count - 1].IsPlaceholder(),
                    "Last expression in ??-chain expected to be placeholder.");
                var placeholder = (AstPlaceholder) Expressions[count - 1];
                var prefix = new AstCoalescence(File, Line, Column);
                prefix.Expressions.AddRange(Expressions.Take(count - 1));

                //check for null (keep a copy of prefix on stack)
                var constLabel = _generateEndLabel();
                var endLabel = _generateEndLabel();
                prefix._emitCode(target, constLabel, StackSemantics.Value);
                target.EmitDuplicate(Position);
                target.Emit(Position,OpCode.check_null);
                target.EmitJumpIfFalse(Position, constLabel);
                //prefix is null, identity function
                target.EmitPop(Position);
                placeholder.IdFunc().EmitValueCode(target);
                target.EmitJump(Position, endLabel);
                //prefix is not null, const function
                target.EmitLabel(Position, constLabel);
                target.EmitCommandCall(Position, 1, Const.Alias);
                target.EmitLabel(Position, endLabel);
            }
        }
Пример #4
0
 public static void EmitJumpUnlessCondition(
     CompilerTarget target, AstExpr cond, string targetLabel)
 {
     if (cond == null)
         throw new ArgumentNullException("cond", Resources.AstLazyLogical__Condition_must_not_be_null);
     if (target == null)
         throw new ArgumentNullException("target", Resources.AstNode_Compiler_target_must_not_be_null);
     if (String.IsNullOrEmpty(targetLabel))
         throw new ArgumentException(
             Resources.AstLazyLogical__targetLabel_must_neither_be_null_nor_empty, "targetLabel");
     var logical = cond as AstLazyLogical;
     if (logical != null)
     {
         var continueLabel = "Continue\\Lazy\\" + Guid.NewGuid().ToString("N");
         logical.EmitCode(target, continueLabel, targetLabel); //inverted
         target.EmitLabel(cond.Position, continueLabel);
     }
     else
     {
         cond.EmitValueCode(target);
         target.EmitJumpIfFalse(cond.Position, targetLabel);
     }
 }
Пример #5
0
        private void _emitCode(CompilerTarget target, string endLabel, StackSemantics stackSemantics)
        {
            for (var i = 0; i < _expressions.Count; i++)
            {
                var expr = _expressions[i];

                // Value semantics: duplicate of previous, rejected value needs to be popped
                // Effect semantics: no duplicates were created in the first place
                if (i > 0 && stackSemantics == StackSemantics.Value)
                    target.EmitPop(Position);

                //For value semantics, we always generate a value
                //For effect semantics, we only need the intermediate expressions to create a value
                StackSemantics needValue;
                if (stackSemantics == StackSemantics.Value || i < _expressions.Count - 1)
                    needValue = StackSemantics.Value;
                else 
                    needValue = StackSemantics.Effect;

                expr.EmitCode(target, needValue);

                //The last element doesn't need special handling, control just 
                //  falls into the surrounding code with the correct value on top of the stack
                if (i + 1 >= _expressions.Count)
                    continue;

                if(stackSemantics == StackSemantics.Value)
                    target.EmitDuplicate(Position);
                target.Emit(Position,OpCode.check_null);
                target.EmitJumpIfFalse(Position, endLabel);
            }
        }