simplifying stuff

This commit is contained in:
cozis
2022-03-12 23:38:23 +01:00
parent 2dcfbd194e
commit af089fb81f
+91 -124
View File
@@ -42,159 +42,126 @@ static void print_error(const char *type, Error *error)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
static _Bool interpret(Source *src) static Executable *build(Source *src)
{ {
// Compile the code. This section transforms // Compile the code. This section transforms
// a [Source] into an [Executable]. // a [Source] into an [Executable].
Executable *exe; Executable *exe;
{
// Create a bump-pointer allocator to hold the AST.
BPAlloc *alloc = BPAlloc_Init(-1);
if(alloc == NULL) // Create a bump-pointer allocator to hold the AST.
{ BPAlloc *alloc = BPAlloc_Init(-1);
fprintf(stderr, "Internal Error: Couldn't allocate bump-pointer allocator to hold the AST.\n");
return 0;
}
Error error; if(alloc == NULL)
Error_Init(&error); {
fprintf(stderr, "Internal Error: Couldn't allocate bump-pointer allocator to hold the AST.\n");
return 0;
}
// NOTE: The AST is stored in the BPAlloc. It's Error error;
// lifetime is the same as the pool. Error_Init(&error);
AST *ast = parse(src, alloc, &error);
if(ast == NULL) // NOTE: The AST is stored in the BPAlloc. It's
{ // lifetime is the same as the pool.
assert(error.occurred); AST *ast = parse(src, alloc, &error);
print_error("Parsing", &error);
Error_Free(&error);
BPAlloc_Free(alloc);
return 0;
}
exe = compile(ast, alloc, &error); if(ast == NULL)
{
assert(error.occurred);
print_error("Parsing", &error);
Error_Free(&error);
BPAlloc_Free(alloc);
return 0;
}
// We're done with the AST, independently from exe = compile(ast, alloc, &error);
// the compilation result.
BPAlloc_Free(alloc);
if(exe == NULL) // We're done with the AST, independently from
{ // the compilation result.
assert(error.occurred); BPAlloc_Free(alloc);
print_error("Compilation", &error);
Error_Free(&error);
return 0;
}
}
// Now execute it. if(exe == NULL)
{ {
Runtime *runt = Runtime_New(-1, -1, NULL, NULL); assert(error.occurred);
print_error("Compilation", &error);
Error_Free(&error);
return 0;
}
if(runt == NULL) return exe;
{ }
Error error;
Error_Init(&error);
Error_Report(&error, 1, "Couldn't initialize runtime");
print_error(NULL, &error);
Error_Free(&error);
Executable_Free(exe);
return 0;
}
// We use a [RuntimeError] instead of a simple [Error] static _Bool interpret(Source *src)
// because the [RuntimeError] makes a snapshot of the {
// runtime state when an error is reported. Other than Executable *exe = build(src);
// this fact they are interchangable. Any function that
// expects a pointer to [Error] can receive a [RuntimeError]
// upcasted to [Error].
RuntimeError error;
RuntimeError_Init(&error, runt); // Here we specify the runtime to snapshot in case of failure.
Object *bins = Object_NewStaticMap(bins_basic, runt, (Error*) &error); if(exe == NULL)
return 0;
if(bins == NULL) Runtime *runt = Runtime_New(-1, -1, NULL, NULL);
{
assert(error.base.occurred == 1);
print_error(NULL, (Error*) &error);
RuntimeError_Free(&error);
Executable_Free(exe);
Runtime_Free(runt);
return 0;
}
Runtime_SetBuiltins(runt, bins); if(runt == NULL)
{
Error error;
Error_Init(&error);
Error_Report(&error, 1, "Couldn't initialize runtime");
print_error(NULL, &error);
Error_Free(&error);
Executable_Free(exe);
return 0;
}
Object *o = run(runt, (Error*) &error, exe, 0, NULL, NULL, 0); // We use a [RuntimeError] instead of a simple [Error]
// because the [RuntimeError] makes a snapshot of the
// runtime state when an error is reported. Other than
// this fact they are interchangable. Any function that
// expects a pointer to [Error] can receive a [RuntimeError]
// upcasted to [Error].
RuntimeError error;
RuntimeError_Init(&error, runt); // Here we specify the runtime to snapshot in case of failure.
// NOTE: The pointer to the builtins object is invalidated Object *bins = Object_NewStaticMap(bins_basic, runt, (Error*) &error);
// now because it may be moved by the garbage collector.
if(o == NULL) if(bins == NULL)
{ {
print_error("Runtime", (Error*) &error); assert(error.base.occurred == 1);
print_error(NULL, (Error*) &error);
RuntimeError_Free(&error);
Executable_Free(exe);
Runtime_Free(runt);
return 0;
}
if(error.snapshot == NULL) Runtime_SetBuiltins(runt, bins);
fprintf(stderr, "No snapshot available.\n");
else
Snapshot_Print(error.snapshot, stderr);
RuntimeError_Free(&error); Object *o = run(runt, (Error*) &error, exe, 0, NULL, NULL, 0);
}
Runtime_Free(runt); // NOTE: The pointer to the builtins object is invalidated
Executable_Free(exe); // now because it may be moved by the garbage collector.
return o != NULL; if(o == NULL)
} {
print_error("Runtime", (Error*) &error);
if(error.snapshot == NULL)
fprintf(stderr, "No snapshot available.\n");
else
Snapshot_Print(error.snapshot, stderr);
RuntimeError_Free(&error);
}
Runtime_Free(runt);
Executable_Free(exe);
return o != NULL;
} }
static _Bool disassemble(Source *src) static _Bool disassemble(Source *src)
{ {
// Compile the code. This section transforms Executable *exe = build(src);
// a [Source] into an [Executable].
Executable *exe;
{
// Create a bump-pointer allocator to hold the AST.
BPAlloc *alloc = BPAlloc_Init(-1);
if(alloc == NULL) if(exe == NULL)
{ return 0;
fprintf(stderr, "Internal Error: Couldn't allocate bump-pointer allocator to hold the AST.\n");
return 0;
}
Error error;
Error_Init(&error);
// NOTE: The AST is stored in the BPAlloc. It's
// lifetime is the same as the pool.
AST *ast = parse(src, alloc, &error);
if(ast == NULL)
{
assert(error.occurred);
print_error("Parsing", &error);
Error_Free(&error);
BPAlloc_Free(alloc);
return 0;
}
exe = compile(ast, alloc, &error);
// We're done with the AST, independently from
// the compilation result.
BPAlloc_Free(alloc);
if(exe == NULL)
{
assert(error.occurred);
print_error("Compilation", &error);
Error_Free(&error);
return 0;
}
}
Executable_Dump(exe); Executable_Dump(exe);
return 1; return 1;