first draft of import builtin function

This commit is contained in:
cozis
2022-08-16 17:35:58 +02:00
parent 9935142a1e
commit 0a090c4cfa
12 changed files with 168 additions and 187 deletions
+131 -3
View File
@@ -37,9 +37,8 @@
#include "files.h"
#include "../utils/utf8.h"
#include "../objects/objects.h"
#include "../compiler/compile.h"
#include "../runtime/runtime.h"
static int bin_print(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error)
{
(void) runtime;
@@ -52,6 +51,134 @@ static int bin_print(Runtime *runtime, Object **argv, unsigned int argc, Object
return 0;
}
static int bin_import(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error)
{
assert(argc == 1);
Heap *heap = Runtime_GetHeap(runtime);
assert(heap != NULL);
Object *o_path = argv[0];
const char *path;
size_t path_len;
{
if(!Object_IsString(o_path))
{
Error_Report(error, 0, "Argument #%d is not a string", 1);
return -1;
}
int n;
path = Object_ToString(o_path, &n, Runtime_GetHeap(runtime), error);
if (path == NULL)
return -1;
assert(n >= 0);
path_len = (size_t) n;
}
Error sub_error;
Error_Init(&sub_error);
Source *src = Source_FromFile(path, &sub_error);
if(src == NULL) {
if(maxretc == 0)
return 0;
Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL)
return -1;
if(maxretc == 1) {
rets[0] = o_none;
return 1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL)
return -1;
Error_Free(&sub_error);
rets[0] = o_none;
rets[1] = o_err;
return 2;
}
CompilationErrorType errtyp;
Executable *exe = compile(src, &sub_error, &errtyp);
if(exe == NULL) {
const char *errname;
switch(errtyp) {
default:
case CompilationErrorType_INTERNAL: errname = NULL; break;
case CompilationErrorType_SYNTAX: errname = "Syntax"; break;
case CompilationErrorType_SEMANTIC: errname = "Semantic"; break;
}
(void) errname;
{
if(maxretc == 0)
return 0;
Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL)
return -1;
if(maxretc == 1) {
rets[0] = o_none;
return 1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL)
return -1;
Error_Free(&sub_error);
rets[0] = o_none;
rets[1] = o_err;
return 2;
}
}
{
Object *sub_rets[8];
int sub_maxretc = sizeof(sub_rets)/sizeof(sub_rets[0]);
int retc = run(runtime, &sub_error, exe, 0, NULL, NULL, 0, sub_rets, sub_maxretc);
if(retc < 0)
{
const char *errname = "Runtime";
// Snapshot?
(void) errname;
{
if(maxretc == 0)
return 0;
Object *o_none = Object_NewNone(heap, error);
if(o_none == NULL)
return -1;
if(maxretc == 1) {
rets[0] = o_none;
return 1;
}
Object *o_err = Object_FromString(sub_error.message, -1, heap, error);
if(o_err == NULL)
return -1;
Error_Free(&sub_error);
rets[0] = o_none;
rets[1] = o_err;
return 2;
}
}
assert(retc == 1);
if(maxretc == 0)
return 0;
rets[0] = sub_rets[0];
return 1;
}
return 0;
}
static int bin_type(Runtime *runtime, Object **argv, unsigned int argc, Object **rets, unsigned int maxretc, Error *error)
{
assert(argc == 1);
@@ -412,6 +539,7 @@ StaticMapSlot bins_basic[] = {
// { "files", SM_SMAP, .as_smap = bins_files, },
// { "net", SM_SMAP, .as_smap = bins_net, },
{ "import", SM_FUNCT, .as_funct = bin_import, .argc = 1, },
{ "newBuffer", SM_FUNCT, .as_funct = bin_newBuffer, .argc = 1 },
{ "sliceBuffer", SM_FUNCT, .as_funct = bin_sliceBuffer, .argc = 3 },
{ "bufferToString", SM_FUNCT, .as_funct = bin_bufferToString, .argc = 1 },
+1
View File
@@ -105,6 +105,7 @@ static const InstrInfo instr_table[] = {
[OPCODE_PUSHNNETYP] = {"PUSHNNETYP", 0, NULL},
[OPCODE_RETURN] = {"RETURN", 1, (OperandType[]) {OPTP_INT}},
[OPCODE_ERROR] = {"ERROR", 1, (OperandType[]) {OPTP_STRING}},
[OPCODE_EXIT] = {"EXIT", 0, NULL},
[OPCODE_JUMPIFNOTANDPOP] = {"JUMPIFNOTANDPOP", 1, (OperandType[]) {OPTP_IDX}},
[OPCODE_JUMPIFANDPOP] = {"JUMPIFANDPOP", 1, (OperandType[]) {OPTP_IDX}},
[OPCODE_JUMP] = {"JUMP", 1, (OperandType[]) {OPTP_IDX}},
+1
View File
@@ -90,6 +90,7 @@ typedef enum {
OPCODE_PUSHNNETYP,
OPCODE_RETURN,
OPCODE_ERROR,
OPCODE_EXIT,
OPCODE_JUMPIFANDPOP,
OPCODE_JUMPIFNOTANDPOP,
OPCODE_JUMP,
+7 -1
View File
@@ -84,6 +84,12 @@ static void emitInstr_RETURN(CodegenContext *ctx,
CodegenContext_EmitInstr(ctx, OPCODE_RETURN, opv, 1, off, len);
}
static void emitInstr_EXIT(CodegenContext *ctx,
int off, int len)
{
CodegenContext_EmitInstr(ctx, OPCODE_EXIT, NULL, 0, off, len);
}
static void emitInstr_JUMP(CodegenContext *ctx,
Label *op0,
int off, int len)
@@ -850,7 +856,7 @@ Executable *codegen(AST *ast, BPAlloc *alloc, Error *error)
CodegenContext_SetJumpDest(ctx, &env);
emitInstrForNode(ctx, ast->root, NULL);
emitInstr_RETURN(ctx, 0, Source_GetSize(ast->src), 0);
emitInstr_EXIT(ctx, Source_GetSize(ast->src), 0);
assert(error->occurred == false);
return CodegenContext_MakeExecutableAndFree(ctx, ast->src);
+1
View File
@@ -1671,6 +1671,7 @@ static Node *parse_expression_2(Context *ctx, Node *left_expr, int min_prec, _Bo
if(right_expr == NULL)
return NULL;
#warning "Should this break also trigger when the token is a = and allow_assignments is false?"
if(ctx->token->kind == ',' && allow_toplev_tuples == 0)
break;
}
+18 -1
View File
@@ -123,6 +123,7 @@ Runtime *Runtime_New(int stack_size, int heap_size, void *callback_userp, _Bool
return Runtime_New2(stack_size, heap, 1, callback_userp, callback_addr);
}
void Runtime_Free(Runtime *runtime)
{
if(runtime->free_heap)
@@ -1192,6 +1193,18 @@ static _Bool step(Runtime *runtime, Error *error)
return 1;
}
case OPCODE_EXIT:
{
assert(opc == 0);
Object *vars = runtime->frame->locals;
assert(vars != NULL);
if(!Runtime_Push(runtime, error, vars))
return 0;
return 0;
}
case OPCODE_RETURN:
{
assert(opc == 1);
@@ -1316,7 +1329,11 @@ static _Bool collect(Runtime *runtime, Error *error)
return Heap_StopCollection(runtime->heap);
}
int run(Runtime *runtime, Error *error, Executable *exe, int index, Object *closure, Object **argv, int argc, Object **rets, int maxretc)
int run(Runtime *runtime, Error *error,
Executable *exe, int index,
Object *closure,
Object **argv, int argc,
Object **rets, int maxretc)
{
assert(runtime != NULL);
assert(error != NULL);