debbuging failure to read from builtin map
This commit is contained in:
@@ -75,6 +75,7 @@ gcc src/main.c src/debug.c \
|
||||
temp/utils/bucketlist.o \
|
||||
temp/objects/o_map.o \
|
||||
temp/objects/o_none.o \
|
||||
temp/objects/o_list.o \
|
||||
temp/objects/o_bool.o \
|
||||
temp/objects/o_string.o \
|
||||
temp/runtime/runtime.o \
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
|
||||
l = [1, 2, 3];
|
||||
|
||||
print(count);
|
||||
print(count(l));
|
||||
print(l, '\n');
|
||||
@@ -58,6 +58,7 @@ static const InstrInfo instr_table[] = {
|
||||
[OPCODE_ASS] = {"ASS", 1, (OperandType[]) {OPTP_STRING}},
|
||||
[OPCODE_POP] = {"POP", 1, (OperandType[]) {OPTP_INT}},
|
||||
[OPCODE_CALL] = {"CALL", 1, (OperandType[]) {OPTP_INT}},
|
||||
[OPCODE_INSERT] = {"INSERT", 0, NULL},
|
||||
[OPCODE_PUSHINT] = {"PUSHINT", 1, (OperandType[]) {OPTP_INT}},
|
||||
[OPCODE_PUSHFLT] = {"PUSHFLT", 1, (OperandType[]) {OPTP_FLOAT}},
|
||||
[OPCODE_PUSHSTR] = {"PUSHSTR", 1, (OperandType[]) {OPTP_STRING}},
|
||||
@@ -66,6 +67,7 @@ static const InstrInfo instr_table[] = {
|
||||
[OPCODE_PUSHFLS] = {"PUSHFLS", 0, NULL},
|
||||
[OPCODE_PUSHNNE] = {"PUSHNNE", 0, NULL},
|
||||
[OPCODE_PUSHFUN] = {"PUSHFUN", 2, (OperandType[]) {OPTP_INT, OPTP_INT}},
|
||||
[OPCODE_PUSHLST] = {"PUSHLST", 1, (OperandType[]) {OPTP_INT}},
|
||||
|
||||
[OPCODE_RETURN] = {"RETURN", 0, NULL},
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef enum {
|
||||
OPCODE_ASS,
|
||||
OPCODE_POP,
|
||||
OPCODE_CALL,
|
||||
OPCODE_INSERT,
|
||||
OPCODE_PUSHINT,
|
||||
OPCODE_PUSHFLT,
|
||||
OPCODE_PUSHSTR,
|
||||
@@ -45,6 +46,7 @@ typedef enum {
|
||||
OPCODE_PUSHFLS,
|
||||
OPCODE_PUSHNNE,
|
||||
OPCODE_PUSHFUN,
|
||||
OPCODE_PUSHLST,
|
||||
OPCODE_RETURN,
|
||||
OPCODE_JUMPIFANDPOP,
|
||||
OPCODE_JUMPIFNOTANDPOP,
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef enum {
|
||||
EXPR_ASS,
|
||||
EXPR_INT,
|
||||
EXPR_CALL,
|
||||
EXPR_LIST,
|
||||
EXPR_NONE,
|
||||
EXPR_TRUE,
|
||||
EXPR_FALSE,
|
||||
@@ -78,6 +79,12 @@ typedef struct {
|
||||
int len;
|
||||
} StringExprNode;
|
||||
|
||||
typedef struct {
|
||||
ExprNode base;
|
||||
Node *items;
|
||||
int itemc;
|
||||
} ListExprNode;
|
||||
|
||||
typedef struct {
|
||||
ExprNode base;
|
||||
char *val;
|
||||
|
||||
@@ -113,6 +113,42 @@ static _Bool emit_instr_for_node(ExeBuilder *exeb, Node *node, Error *error)
|
||||
return ExeBuilder_Append(exeb, error, OPCODE_PUSHVAR, &op, 1, node->offset, node->length);
|
||||
}
|
||||
|
||||
case EXPR_LIST:
|
||||
{
|
||||
// PUSHLST
|
||||
// PUSHINT
|
||||
// <expr>
|
||||
// INSERT
|
||||
|
||||
ListExprNode *l = (ListExprNode*) node;
|
||||
|
||||
Operand op;
|
||||
|
||||
op = (Operand) { .type = OPTP_INT, .as_int = l->itemc };
|
||||
if(!ExeBuilder_Append(exeb, error, OPCODE_PUSHLST, &op, 1, node->offset, node->length))
|
||||
return 0;
|
||||
|
||||
Node *item = l->items;
|
||||
int i = 0;
|
||||
|
||||
while(item)
|
||||
{
|
||||
op = (Operand) { .type = OPTP_INT, .as_int = i };
|
||||
if(!ExeBuilder_Append(exeb, error, OPCODE_PUSHINT, &op, 1, item->offset, item->length))
|
||||
return 0;
|
||||
|
||||
if(!emit_instr_for_node(exeb, item, error))
|
||||
return 0;
|
||||
|
||||
if(!ExeBuilder_Append(exeb, error, OPCODE_INSERT, NULL, 0, item->offset, item->length))
|
||||
return 0;
|
||||
|
||||
i += 1;
|
||||
item = item->next;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case EXPR_CALL:
|
||||
{
|
||||
CallExprNode *p = (CallExprNode*) expr;
|
||||
|
||||
@@ -651,6 +651,96 @@ static Node *parse_string_primary_expression(Context *ctx)
|
||||
return (Node*) node;
|
||||
}
|
||||
|
||||
static Node *parse_list_primary_expression(Context *ctx)
|
||||
{
|
||||
assert(ctx != NULL);
|
||||
|
||||
if(done(ctx))
|
||||
{
|
||||
Error_Report(ctx->error, 0, "Source ended where a list literal was expected");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(current(ctx) != '[')
|
||||
{
|
||||
Error_Report(ctx->error, 0, "Got token \"%.*s\" where a list literal was expected", ctx->token->length, ctx->src + ctx->token->offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int offset = current_token(ctx)->offset;
|
||||
|
||||
Node *items = NULL;
|
||||
int itemc = 0;
|
||||
|
||||
next(ctx); // Skip the '['.
|
||||
|
||||
if(current(ctx) != ']')
|
||||
{
|
||||
Node *tail = NULL;
|
||||
|
||||
while(1)
|
||||
{
|
||||
// Parse.
|
||||
Node *item = parse_expression(ctx);
|
||||
|
||||
if(item == NULL)
|
||||
return NULL;
|
||||
|
||||
// Append.
|
||||
if(tail)
|
||||
tail->next = item;
|
||||
else
|
||||
items = item;
|
||||
tail = item;
|
||||
itemc += 1;
|
||||
|
||||
// Get ',' or ']'.
|
||||
|
||||
if(current(ctx) == ']')
|
||||
break;
|
||||
|
||||
if(current(ctx) != ',')
|
||||
{
|
||||
if(current(ctx) == TDONE)
|
||||
Error_Report(ctx->error, 0, "Source ended inside a list literal");
|
||||
else
|
||||
Error_Report(ctx->error, 0, "Got unexpected token \"%.*s\" inside list literal, where ',' or ']' were expected", ctx->token->length, ctx->src + ctx->token->offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
next(ctx); // Skip the ','.
|
||||
}
|
||||
}
|
||||
|
||||
int length = current_token(ctx)->offset
|
||||
+ current_token(ctx)->length
|
||||
- offset;
|
||||
|
||||
next(ctx); // Skip the ']'.
|
||||
|
||||
ListExprNode *list;
|
||||
{
|
||||
list = BPAlloc_Malloc(ctx->alloc, sizeof(ListExprNode));
|
||||
|
||||
if(list == NULL)
|
||||
{
|
||||
Error_Report(ctx->error, 1, "No memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->base.base.kind = NODE_EXPR;
|
||||
list->base.base.next = NULL;
|
||||
list->base.base.offset = offset;
|
||||
list->base.base.length = length;
|
||||
list->base.kind = EXPR_LIST;
|
||||
list->items = items;
|
||||
list->itemc = itemc;
|
||||
}
|
||||
|
||||
return (Node*) list;
|
||||
|
||||
}
|
||||
|
||||
static char *copy_token_text(Context *ctx)
|
||||
{
|
||||
char *copy = BPAlloc_Malloc(ctx->alloc, ctx->token->length + 1);
|
||||
@@ -705,6 +795,9 @@ static Node *parse_primary_expresion(Context *ctx)
|
||||
return (Node*) temp;
|
||||
}
|
||||
|
||||
case '[':
|
||||
return parse_list_primary_expression(ctx);
|
||||
|
||||
case '(':
|
||||
{
|
||||
next(ctx); // Consume the '('.
|
||||
|
||||
+1
-12
@@ -453,9 +453,6 @@ _Bool Debug_Callback(Runtime *runtime, void *userp)
|
||||
Stack *stack = Runtime_GetStack(runtime);
|
||||
assert(stack != NULL);
|
||||
|
||||
Error error;
|
||||
Error_Init(&error);
|
||||
|
||||
if(Stack_Size(stack) == 0)
|
||||
fprintf(stderr, "The stack is empty.\n");
|
||||
|
||||
@@ -465,15 +462,7 @@ _Bool Debug_Callback(Runtime *runtime, void *userp)
|
||||
assert(obj != NULL);
|
||||
|
||||
fprintf(stderr, " %d | ", i);
|
||||
Object_Print(obj, stderr, &error);
|
||||
|
||||
if(error.occurred)
|
||||
{
|
||||
Error_Free(&error);
|
||||
Error_Init(&error);
|
||||
fprintf(stderr, "(unprintable)");
|
||||
}
|
||||
|
||||
Object_Print(obj, stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ typedef struct {
|
||||
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
|
||||
static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *err);
|
||||
static int count(Object *self);
|
||||
static void print(Object *obj, FILE *fp);
|
||||
|
||||
static const Type t_list = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
@@ -19,6 +20,7 @@ static const Type t_list = {
|
||||
.select = select,
|
||||
.insert = insert,
|
||||
.count = count,
|
||||
.print = print,
|
||||
};
|
||||
|
||||
static inline int calc_capacity(int mapper_size)
|
||||
@@ -152,3 +154,16 @@ static int count(Object *self)
|
||||
|
||||
return list->count;
|
||||
}
|
||||
|
||||
static void print(Object *self, FILE *fp)
|
||||
{
|
||||
ListObject *list = (ListObject*) self;
|
||||
|
||||
for(int i = 0; i < list->count; i += 1)
|
||||
{
|
||||
Object_Print(list->vals[i], fp);
|
||||
|
||||
if(i+1 < list->count)
|
||||
fprintf(fp, ", ");
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ typedef struct {
|
||||
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
|
||||
static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *err);
|
||||
static int count(Object *self);
|
||||
static void print(Object *self, FILE *fp);
|
||||
|
||||
static const Type t_map = {
|
||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||
@@ -21,6 +22,7 @@ static const Type t_map = {
|
||||
.select = select,
|
||||
.insert = insert,
|
||||
.count = count,
|
||||
.print = print,
|
||||
};
|
||||
|
||||
static inline int calc_capacity(int mapper_size)
|
||||
@@ -74,6 +76,10 @@ static Object *select(Object *self, Object *key, Heap *heap, Error *error)
|
||||
assert(heap != NULL);
|
||||
assert(error != NULL);
|
||||
|
||||
fprintf(stderr, "Selecting from:\n\t");
|
||||
Object_Print(self, stderr);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
MapObject *map = (MapObject*) self;
|
||||
|
||||
int mask = map->mapper_size - 1;
|
||||
@@ -86,10 +92,15 @@ static Object *select(Object *self, Object *key, Heap *heap, Error *error)
|
||||
|
||||
int i = hash & mask;
|
||||
|
||||
#warning "TEMP"
|
||||
fprintf(stderr, "-----------------\n");
|
||||
|
||||
while(1)
|
||||
{
|
||||
int k = map->mapper[i];
|
||||
|
||||
fprintf(stderr, "map->mapper[%d] = %d\n", i, k);
|
||||
|
||||
if(k == -1)
|
||||
{
|
||||
// Empty slot.
|
||||
@@ -102,6 +113,10 @@ static Object *select(Object *self, Object *key, Heap *heap, Error *error)
|
||||
// Is it the right one?
|
||||
|
||||
assert(k >= 0);
|
||||
#warning "TEMP"
|
||||
fprintf(stderr, "map->keys[%d] = ", k);
|
||||
Object_Print(map->keys[k], stderr);
|
||||
fprintf(stderr, " (of type %s)\n", Object_GetName(map->keys[k]));
|
||||
|
||||
if(Object_Compare(key, map->keys[k], error))
|
||||
// Found it!
|
||||
@@ -114,8 +129,12 @@ static Object *select(Object *self, Object *key, Heap *heap, Error *error)
|
||||
// Not the one we wanted.
|
||||
}
|
||||
|
||||
int old_i = i;
|
||||
|
||||
pert >>= 5;
|
||||
i = (i * 5 + pert + 1) & mask;
|
||||
|
||||
fprintf(stderr, "%d -> %d\n", old_i, i);
|
||||
}
|
||||
|
||||
UNREACHABLE;
|
||||
@@ -259,3 +278,18 @@ static int count(Object *self)
|
||||
|
||||
return map->count;
|
||||
}
|
||||
|
||||
static void print(Object *self, FILE *fp)
|
||||
{
|
||||
MapObject *map = (MapObject*) self;
|
||||
|
||||
for(int i = 0; i < map->count; i += 1)
|
||||
{
|
||||
Object_Print(map->keys[i], fp);
|
||||
fprintf(fp, ": ");
|
||||
Object_Print(map->vals[i], fp);
|
||||
|
||||
if(i+1 < map->count)
|
||||
fprintf(fp, ", ");
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,12 @@ static _Bool op_eql(Object *self, Object *other)
|
||||
StringObject *s1 = (StringObject*) self;
|
||||
StringObject *s2 = (StringObject*) other;
|
||||
|
||||
return s1->size == s2->size && !strncmp(s1->body, s2->body, s1->size);
|
||||
_Bool match = s1->size == s2->size && !strncmp(s1->body, s2->body, s1->size);
|
||||
|
||||
#warning "TEMP"
|
||||
fprintf(stderr, "%s == %s ? %s\n", s1->body, s2->body, match ? "yes" : "no");
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static void print(Object *obj, FILE *fp)
|
||||
|
||||
@@ -106,22 +106,17 @@ Object *Object_Call(Object *obj, Object **argv, unsigned int argc, Heap *heap, E
|
||||
return type->call(obj, argv, argc, heap, err);
|
||||
}
|
||||
|
||||
_Bool Object_Print(Object *obj, FILE *fp, Error *error)
|
||||
void Object_Print(Object *obj, FILE *fp)
|
||||
{
|
||||
assert(error != NULL);
|
||||
assert(obj != NULL);
|
||||
|
||||
const Type *type = Object_GetType(obj);
|
||||
assert(type);
|
||||
|
||||
if(type->print == NULL)
|
||||
{
|
||||
Error_Report(error, 0, "Object %s doesn't implement %s", Object_GetName(obj), __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type->print(obj, fp);
|
||||
return 1;
|
||||
fprintf(fp, "<%s is unprintable>", Object_GetName(obj));
|
||||
else
|
||||
type->print(obj, fp);
|
||||
}
|
||||
|
||||
Object *Object_Select(Object *coll, Object *key, Heap *heap, Error *err)
|
||||
|
||||
@@ -74,7 +74,7 @@ unsigned int Object_GetDeepSize(const Object *obj, Error *err);
|
||||
int Object_Hash (Object *obj, Error *err);
|
||||
Object* Object_Copy (Object *obj, Heap *heap, Error *err);
|
||||
Object* Object_Call (Object *obj, Object **argv, unsigned int argc, Heap *heap, Error *err);
|
||||
_Bool Object_Print (Object *obj, FILE *fp, Error *error);
|
||||
void Object_Print (Object *obj, FILE *fp);
|
||||
Object* Object_Select(Object *coll, Object *key, Heap *heap, Error *err);
|
||||
Object* Object_Delete(Object *coll, Object *key, Heap *heap, Error *err);
|
||||
_Bool Object_Insert(Object *coll, Object *key, Object *val, Heap *heap, Error *err);
|
||||
|
||||
+13
-2
@@ -4,11 +4,21 @@
|
||||
static Object *bin_print(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
|
||||
{
|
||||
for(int i = 0; i < (int) argc; i += 1)
|
||||
Object_Print(argv[i], stdout, error);
|
||||
Object_Print(argv[i], stdout);
|
||||
|
||||
return Object_NewNone(Runtime_GetHeap(runtime), error);
|
||||
}
|
||||
|
||||
static Object *bin_count(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
|
||||
{
|
||||
int n = Object_Count(argv[0], error);
|
||||
|
||||
if(error->occurred)
|
||||
return NULL;
|
||||
|
||||
return Object_FromInt(n, Runtime_GetHeap(runtime), error);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int argc;
|
||||
@@ -17,6 +27,7 @@ typedef struct {
|
||||
|
||||
BuiltinNativeFunctions builtins[] = {
|
||||
{"print", -1, bin_print},
|
||||
{"count", 1, bin_count},
|
||||
};
|
||||
|
||||
_Bool add_builtins(Runtime *runtime, Error *error)
|
||||
@@ -29,7 +40,7 @@ _Bool add_builtins(Runtime *runtime, Error *error)
|
||||
if(dest == NULL)
|
||||
return 0;
|
||||
|
||||
for(int i = 0; i < (int) (sizeof(builtins) / sizeof(builtins[0])); i += 1)
|
||||
for(int i = 0; (unsigned int) i < sizeof(builtins) / sizeof(builtins[0]); i += 1)
|
||||
{
|
||||
Object *name = Object_FromString(builtins[i].name, -1, heap, error);
|
||||
|
||||
|
||||
+42
-2
@@ -641,6 +641,30 @@ static _Bool step(Runtime *runtime, Error *error)
|
||||
return 1;
|
||||
}
|
||||
|
||||
case OPCODE_INSERT:
|
||||
{
|
||||
assert(opc == 0);
|
||||
|
||||
if(runtime->frame->used < 3)
|
||||
{
|
||||
Error_Report(error, 1, "Frame has not enough values on the stack to run INSERT instruction");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Object *col = Stack_Top(runtime->stack, -2);
|
||||
Object *key = Stack_Top(runtime->stack, -1);
|
||||
Object *val = Stack_Top(runtime->stack, 0);
|
||||
|
||||
assert(col != NULL && key != NULL && val != NULL);
|
||||
|
||||
if(!Runtime_Pop(runtime, error, 2))
|
||||
return 0;
|
||||
|
||||
if(!Object_Insert(col, key, val, runtime->heap, error))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case OPCODE_PUSHINT:
|
||||
{
|
||||
assert(opc == 1);
|
||||
@@ -713,8 +737,9 @@ static _Bool step(Runtime *runtime, Error *error)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if(obj == NULL)
|
||||
return 0;
|
||||
else
|
||||
if(obj == NULL)
|
||||
return 0;
|
||||
|
||||
if(!Runtime_Push(runtime, error, obj))
|
||||
return 0;
|
||||
@@ -780,6 +805,21 @@ static _Bool step(Runtime *runtime, Error *error)
|
||||
return 1;
|
||||
}
|
||||
|
||||
case OPCODE_PUSHLST:
|
||||
{
|
||||
assert(opc == 1);
|
||||
assert(ops[0].type == OPTP_INT);
|
||||
|
||||
Object *obj = Object_NewList(ops[0].as_int, runtime->heap, error);
|
||||
|
||||
if(obj == NULL)
|
||||
return 0;
|
||||
|
||||
if(!Runtime_Push(runtime, error, obj))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
case OPCODE_RETURN:
|
||||
return 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user