elna/source/main.d

86 lines
2.3 KiB
D

import core.stdc.stdio;
import core.stdc.string;
import core.stdc.stdlib;
import elna.lexer;
import elna.parser;
import elna.generator;
import elna.ir;
import elna.extended;
import elna.arguments;
import std.algorithm;
import std.range;
import std.sumtype;
import std.typecons;
import tanya.container.array;
import tanya.container.string;
import tanya.memory.allocator;
import tanya.memory.mmappool;
import tanya.os.error;
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 main(string[] args)
{
defaultAllocator = MmapPool.instance;
return Arguments.parse(args).match!(
(ArgumentError argumentError) => 4,
(Arguments arguments) {
auto sourceText = readSource(arguments.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);
String outputFilename;
if (arguments.output is null)
{
auto slashIndex = max(0, arguments.inFile.retro.countUntil('/'));
outputFilename.insertBack(arguments.inFile[$ - slashIndex .. $ - 4]);
outputFilename.insertBack(arguments.assembler ? "s" : "o");
}
else
{
outputFilename = String(arguments.output);
}
if (arguments.assembler)
{
generate(ir, outputFilename);
}
else
{
writeObject(ir, outputFilename);
}
return 0;
}
);
}