예제 #1
0
        /// <summary>
        /// Emits an instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            ICodeEmitter emitter = null;

            if (mEmitters.TryGetValue(instruction.OpCode.Code, out emitter))
            {
                emitter.Emit(instruction, context, builder);
            }
            else
            {
                throw new NotImplementedException("Instruction with opcode " + instruction.OpCode.Code + " is not implemented");
            }
        }
예제 #2
0
        public void Emit(CompilationContext context)
        {
            context.EmitComment(";For");

            context.NewScope();
            context.StartPossiblyNonExecutedBlock();

            int testLabel = context.CreateNewLabel();
            int doneLabel = context.CreateNewLabel();

            Initializer.Emit(context);
            context.EmitLabel(testLabel);
            Condition.Emit(context);
            context.EmitInstruction(new IRPop()
            {
                To = "eax"
            });
            context.EmitInstruction(new IRCompareImmediate()
            {
                Left = "eax", Right = new ImmediateValue(0)
            });
            context.EmitInstruction(new IRJumpEQ()
            {
                Address = new LabelAddressValue(doneLabel)
            });

            foreach (var token in Body)
            {
                if (token is ICodeEmitter)
                {
                    ((ICodeEmitter)token).Emit(context);
                }
            }

            Update.Emit(context);
            context.EmitInstruction(new IRJumpImmediate()
            {
                Address = new LabelAddressValue(testLabel)
            });
            context.EmitLabel(doneLabel);

            context.EndPossiblyNonExecutedBlock();
            context.EndScope(false);
        }