public IEnumerable <NasmInstruction> CompileInstructions() { int stackSize = StackEnd; yield return(NasmInstruction.Call("sub", Param(Register.Get(RegisterName.RSP)), new LiteralParameter(stackSize.ToString())).WithComment("Allocate stack")); yield return(NasmInstruction.Empty()); if (Parameters.Count >= 2) { yield return(Move(GetMemory(Parameters[1]), ParameterLocation(1))); } foreach (var instruction in Instructions.SelectMany((x, i) => CompileInstruction(i, x))) { yield return(instruction); } yield return(NasmInstruction.Label(".__exit").WithComment("Function exit/return label")); yield return(NasmInstruction.Call("add", Param(Register.Get(RegisterName.RSP)), new LiteralParameter(stackSize.ToString())).WithComment("Return stack")); yield return(NasmInstruction.Call(name: "ret")); yield return(NasmInstruction.Empty()); }
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)) })