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; } ); }