Files
Toy/repl/repl_main.c

140 lines
2.7 KiB
C

#include "repl_tools.h"
#include "lib_standard.h"
#include "console_colors.h"
#include "lexer.h"
#include "parser.h"
#include "compiler.h"
#include "interpreter.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void repl() {
//repl does it's own thing for now
bool error = false;
const int size = 2048;
char input[size];
memset(input, 0, size);
Interpreter interpreter; //persist the interpreter for the scopes
initInterpreter(&interpreter);
//inject the libs
injectNativeHook(&interpreter, "standard", hookStandard);
for(;;) {
printf("> ");
fgets(input, size, stdin);
//escape the repl (length of 5 to accomodate the newline)
if (strlen(input) == 5 && (!strncmp(input, "exit", 4) || !strncmp(input, "quit", 4))) {
break;
}
//setup this iteration
Lexer lexer;
Parser parser;
Compiler compiler;
initLexer(&lexer, input);
initParser(&parser, &lexer);
initCompiler(&compiler);
//run this iteration
ASTNode* node = scanParser(&parser);
while(node != NULL) {
//pack up and restart
if (node->type == AST_NODEERROR) {
printf(ERROR "error node detected\n" RESET);
error = true;
freeNode(node);
break;
}
writeCompiler(&compiler, node);
freeNode(node);
node = scanParser(&parser);
}
if (!error) {
//get the bytecode dump
int size = 0;
unsigned char* tb = collateCompiler(&compiler, &size);
//run the bytecode
runInterpreter(&interpreter, tb, size);
}
//clean up this iteration
freeCompiler(&compiler);
freeParser(&parser);
error = false;
}
freeInterpreter(&interpreter);
}
//entry point
int main(int argc, const char* argv[]) {
initCommand(argc, argv);
//command specific actions
if (command.error) {
usageCommand(argc, argv);
return 0;
}
if (command.help) {
helpCommand(argc, argv);
return 0;
}
if (command.version) {
copyrightCommand(argc, argv);
return 0;
}
//TODO: remove this when the interpreter meets the specification
if (command.verbose) {
printf(NOTICE "Toy Programming Language Version %d.%d.%d\n" RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH);
}
//run source file
if (command.sourcefile) {
runSourceFile(command.sourcefile);
return 0;
}
//run from stdin
if (command.source) {
runSource(command.source);
return 0;
}
//compile source file
if (command.compilefile && command.outfile) {
size_t size = 0;
char* source = readFile(command.compilefile, &size);
unsigned char* tb = compileString(source, &size);
if (!tb) {
return 1;
}
writeFile(command.outfile, tb, size);
return 0;
}
//run binary
if (command.binaryfile) {
runBinaryFile(command.binaryfile);
return 0;
}
repl();
return 0;
}