public bool Compile(CompilationPass pass, ICompiler compiler, CompileToolContext context)
        {
            var sourceRefs = new SourceReference[] { this._sourceRef };
            var project = (IProjectScope)Parent;

            switch (pass)
            {
                case CompilationPass.Pass1RegisterIdentifiers:
                    IIdentifierScope scope;
                    var existingDef = project.Find(this._labelIdentifier, out scope);
                    if (existingDef != null && scope == project)
                    {
                        context.AddMessage(new BinaryCompileMessage { Filename = this._filename, Line = 0, Message = "Identifier already exists in this scope", MessageLevel = Level.Error });
                        return false;
                    }
                    this._labelInstruction = new LabelInstruction(sourceRefs);
                    project.Add(new BinaryFileLabel(this._labelIdentifier, this._labelInstruction, this._sourceRef));
                    break;

                case CompilationPass.Pass3GenerateCode:
                    compiler.AddInstruction(this._labelInstruction, context);
                    compiler.AddInstruction(new BinaryFileDataInstruction(this._filename, sourceRefs), context);
                    break;
            }

            return true;
        }
Beispiel #2
0
        public int Visit(FuncDeclaration declaration)
        {
            _frame = new Frame();
            _scope = new Scope(_frame, null);

            // TODO: emit func type
            _context.Emit(new LabelInstruction(declaration.Name.Contents));

            // prologue
            EmitFunctionPart(true);

            _return = new LabelInstruction(".return");

            // body
            declaration.Body.Accept(this);

            // epilogue
            _context.Emit(_return);
            EmitFunctionPart(false);

            _context.Emit(new Instruction(Opcode.Retn, new ImmediateOperand(declaration.Parameters.Count * 4)));

            _frame  = null;
            _scope  = null;
            _return = null;

            return(0);
        }
Beispiel #3
0
        public LabelOperand(LabelInstruction label)
            : base(OperandType.ImmD)
        {
            if (label == null)
            {
                throw new ArgumentNullException(nameof(label));
            }

            _label = label;
        }
        public void VisitLabelInstruction_Throws_NotSupportedException()
        {
            // arrange
            var computeAssembler = Substitute.For<IInstructionAssembler<ComputeInstruction>>();
            var addressAssembler = Substitute.For<IInstructionAssembler<AddressInstruction>>();
            IInstructionVisitor<string[]> visitor = new AssemblyInstructionVisitor(computeAssembler, addressAssembler);
            var instruction = new LabelInstruction("SOME_LABEL");

            // act
            TestDelegate testDelegate = () => visitor.VisitInstruction(instruction);

            // assert
            Assert.Throws<NotSupportedException>(testDelegate);
        }
Beispiel #5
0
        public void VisitLabelInstruction_Throws_NotSupportedException()
        {
            // arrange
            var computeAssembler = Substitute.For <IInstructionAssembler <ComputeInstruction> >();
            var addressAssembler = Substitute.For <IInstructionAssembler <AddressInstruction> >();
            IInstructionVisitor <string[]> visitor = new AssemblyInstructionVisitor(computeAssembler, addressAssembler);
            var instruction = new LabelInstruction("SOME_LABEL");

            // act
            TestDelegate testDelegate = () => visitor.VisitInstruction(instruction);

            // assert
            Assert.Throws <NotSupportedException>(testDelegate);
        }
Beispiel #6
0
        private IEnumerable <NasmInstruction> CompileInstruction(int i, IInstruction instruction)
        {
            yield return(NasmInstruction.Comment(instruction.ToString()));

            yield return(NasmInstruction.Comment("In = { " + string.Join(", ", RegisterAllocation.GetAllInAt(i)) + " }"));

            foreach (var inst in instruction switch
            {
                UnaryComputationAssignment inst => CompileCore(inst),
                BinaryComputationAssignment inst => CompileCore(inst),
                ConditionalJump inst => CompileCore(inst),
                UnconditionalJump inst => CompileCore(inst),
                LabelInstruction inst => CompileCore(inst),
                CallInstruction inst => CompileCore(i, inst),
                ReturnInstruction inst => CompileCore(inst),
                ParameterQueryAssignment inst => CompileCore(inst),
                _ => throw new ArgumentException(nameof(instruction))
            })
 public BinaryFileLabel(string name, LabelInstruction label, SourceReference sourceRef)
 {
     this._name = name;
     this._label = label;
     this._sourceRef = sourceRef;
 }
Beispiel #8
0
 public bool VisitInstruction(LabelInstruction instruction)
 {
     return(false);
 }
Beispiel #9
0
 public string[] VisitInstruction(LabelInstruction instruction)
 {
     throw new NotSupportedException("Symbols need to be resolved before they can be assembled");
 }