66 lines
1.5 KiB
D
66 lines
1.5 KiB
D
module elna.backend;
|
|
|
|
import core.stdc.stdio;
|
|
import elna.elf;
|
|
import elna.ir;
|
|
import elna.extended;
|
|
import elna.riscv;
|
|
import elna.lexer;
|
|
import elna.parser;
|
|
import std.algorithm;
|
|
import std.sumtype;
|
|
import std.typecons;
|
|
import tanya.os.error;
|
|
import tanya.container.array;
|
|
import tanya.container.string;
|
|
|
|
private Nullable!String readSource(string source) @nogc
|
|
{
|
|
enum size_t bufferSize = 255;
|
|
auto sourceFilename = String(source);
|
|
|
|
return readFile(sourceFilename).match!(
|
|
(ErrorCode errorCode) {
|
|
perror(sourceFilename.toStringz);
|
|
return Nullable!String();
|
|
},
|
|
(Array!ubyte contents) => nullable(String(cast(char[]) contents.get))
|
|
);
|
|
}
|
|
|
|
int generate(string inFile, ref String outputFilename) @nogc
|
|
{
|
|
auto sourceText = readSource(inFile);
|
|
if (sourceText.isNull)
|
|
{
|
|
return 3;
|
|
}
|
|
auto tokens = lex(sourceText.get.get);
|
|
if (tokens.length == 0)
|
|
{
|
|
printf("Lexical analysis failed.\n");
|
|
return 1;
|
|
}
|
|
auto ast = parse(tokens);
|
|
if (!ast.valid)
|
|
{
|
|
auto compileError = ast.error.get;
|
|
printf("%lu:%lu: %s\n", compileError.line, compileError.column, compileError.message.ptr);
|
|
return 2;
|
|
}
|
|
auto ir = transform(ast.result);
|
|
|
|
auto handle = File.open(outputFilename.toStringz, BitFlags!(File.Mode)(File.Mode.truncate));
|
|
if (!handle.valid)
|
|
{
|
|
return 1;
|
|
}
|
|
auto programText = writeNext(ir);
|
|
auto elf = Elf(move(handle));
|
|
elf.addCode("main", programText);
|
|
|
|
elf.finish();
|
|
|
|
return 0;
|
|
}
|