2021-11-02 08:41:03 +00:00
|
|
|
module compiler.codegen.emit.core;
|
2021-06-01 14:18:09 +01:00
|
|
|
|
|
|
|
import compiler.symbols.data;
|
2021-11-02 08:41:03 +00:00
|
|
|
import compiler.typecheck.core;
|
2021-11-02 13:13:44 +00:00
|
|
|
import std.container.slist : SList;
|
|
|
|
import compiler.codegen.instruction;
|
|
|
|
import std.stdio;
|
|
|
|
import std.file;
|
2022-12-12 13:36:07 +00:00
|
|
|
import compiler.codegen.instruction : Instruction;
|
2022-12-12 17:12:39 +00:00
|
|
|
import std.range : walkLength;
|
2021-06-01 14:18:09 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* TODO: Perhaps have an interface that can emit(Context/Parent, Statement)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* TODO: Module linking (general overhaul required) */
|
|
|
|
|
2021-11-02 08:41:03 +00:00
|
|
|
public abstract class CodeEmitter
|
2021-06-01 14:18:09 +01:00
|
|
|
{
|
2021-11-02 13:13:44 +00:00
|
|
|
protected TypeChecker typeChecker;
|
2021-11-02 08:41:03 +00:00
|
|
|
|
2021-11-02 13:13:44 +00:00
|
|
|
/**
|
2022-12-11 15:37:27 +00:00
|
|
|
* Required queues
|
2021-11-02 13:13:44 +00:00
|
|
|
*/
|
2022-12-12 17:12:39 +00:00
|
|
|
private Instruction[] initQueue;
|
|
|
|
private Instruction[] codeQueue;
|
2022-12-11 15:37:27 +00:00
|
|
|
|
2022-12-12 17:12:39 +00:00
|
|
|
// alias instructions = codeQueue;
|
2021-11-02 13:13:44 +00:00
|
|
|
|
|
|
|
protected File file;
|
|
|
|
|
2022-12-12 14:56:54 +00:00
|
|
|
|
2022-12-12 17:12:39 +00:00
|
|
|
private ulong codeQueueIdx = 0;
|
2022-12-12 14:56:54 +00:00
|
|
|
|
2022-12-12 17:12:39 +00:00
|
|
|
|
|
|
|
public final Instruction getCurrentCodeInstruction()
|
2022-12-12 14:56:54 +00:00
|
|
|
{
|
2022-12-12 17:12:39 +00:00
|
|
|
return codeQueue[codeQueueIdx];
|
2022-12-12 14:56:54 +00:00
|
|
|
}
|
|
|
|
|
2022-12-12 17:12:39 +00:00
|
|
|
public final bool hasCodeInstructions()
|
2022-12-12 14:56:54 +00:00
|
|
|
{
|
2022-12-12 17:12:39 +00:00
|
|
|
return codeQueueIdx < codeQueue.length;
|
2022-12-12 14:56:54 +00:00
|
|
|
}
|
|
|
|
|
2022-12-12 17:12:39 +00:00
|
|
|
public final void nextCodeInstruction()
|
|
|
|
{
|
|
|
|
codeQueueIdx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final void previousCodeInstruction()
|
|
|
|
{
|
|
|
|
codeQueueIdx--;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public final ulong getInitQueueLen()
|
|
|
|
{
|
|
|
|
return initQueue.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final ulong getCodeQueueLen()
|
|
|
|
{
|
|
|
|
return codeQueue.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-02 13:13:44 +00:00
|
|
|
this(TypeChecker typeChecker, File file)
|
2021-06-01 14:18:09 +01:00
|
|
|
{
|
2021-11-02 08:41:03 +00:00
|
|
|
this.typeChecker = typeChecker;
|
2022-12-11 15:37:27 +00:00
|
|
|
|
|
|
|
/* Extract the allocation queue, the code queue */
|
2022-12-12 17:12:39 +00:00
|
|
|
foreach(Instruction currentInstruction; typeChecker.getInitQueue())
|
|
|
|
{
|
|
|
|
initQueue~=currentInstruction;
|
|
|
|
}
|
|
|
|
foreach(Instruction currentInstruction; typeChecker.getCodeQueue())
|
|
|
|
{
|
|
|
|
codeQueue~=currentInstruction;
|
|
|
|
}
|
2022-12-11 15:37:27 +00:00
|
|
|
|
2021-11-02 13:13:44 +00:00
|
|
|
this.file = file;
|
2021-06-01 14:18:09 +01:00
|
|
|
}
|
2021-06-01 14:24:13 +01:00
|
|
|
|
2022-12-12 13:36:07 +00:00
|
|
|
/**
|
|
|
|
* Begins the emit process
|
|
|
|
*/
|
2021-11-02 08:41:03 +00:00
|
|
|
public abstract void emit();
|
2022-12-11 19:41:15 +00:00
|
|
|
|
2022-12-12 13:36:07 +00:00
|
|
|
/**
|
|
|
|
* Finalizes the emitting process (only
|
|
|
|
* to be called after the `emit()` finishes)
|
|
|
|
*/
|
2022-12-11 19:41:15 +00:00
|
|
|
public abstract void finalize();
|
2022-12-12 13:36:07 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Transforms or emits a single Instruction
|
|
|
|
* and returns the transformation
|
|
|
|
*
|
|
|
|
* Params:
|
|
|
|
* instruction = The Instruction to transform/emit
|
|
|
|
* Returns: The Instruction emit as a string
|
|
|
|
*/
|
|
|
|
public abstract string transform(Instruction instruction);
|
2021-06-01 14:18:09 +01:00
|
|
|
}
|