diff --git a/samples/if-else.noja b/samples/if-else.noja index 2c88993..f2d4105 100644 --- a/samples/if-else.noja +++ b/samples/if-else.noja @@ -1,2 +1,2 @@ -if false 1; \ No newline at end of file +if true 3; else none; \ No newline at end of file diff --git a/src/common/executable.c b/src/common/executable.c index e9ccbc8..ea11885 100644 --- a/src/common/executable.c +++ b/src/common/executable.c @@ -1,5 +1,6 @@ #include #include +#include #include "../utils/defs.h" #include "../utils/bucketlist.h" #include "executable.h" @@ -31,53 +32,34 @@ struct xExeBuilder { typedef struct { const char *name; - int stacksz; int opcount; OperandType *optypes; } InstrInfo; static const InstrInfo instr_table[] = { - [OPCODE_NOPE] = {"NOPE", 0, 0, NULL}, + [OPCODE_NOPE] = {"NOPE", 0, NULL}, - [OPCODE_POS] = {"POS", 1, 0, NULL}, - [OPCODE_NEG] = {"NEG", 1, 0, NULL}, + [OPCODE_POS] = {"POS", 0, NULL}, + [OPCODE_NEG] = {"NEG", 0, NULL}, - [OPCODE_ADD] = {"ADD", 2, 0, NULL}, - [OPCODE_SUB] = {"SUB", 2, 0, NULL}, - [OPCODE_MUL] = {"MUL", 2, 0, NULL}, - [OPCODE_DIV] = {"DIV", 2, 0, NULL}, + [OPCODE_ADD] = {"ADD", 0, NULL}, + [OPCODE_SUB] = {"SUB", 0, NULL}, + [OPCODE_MUL] = {"MUL", 0, NULL}, + [OPCODE_DIV] = {"DIV", 0, NULL}, - [OPCODE_PUSHINT] = {"PUSHINT", 0, 1, (OperandType[]) {OPTP_INT}}, - [OPCODE_PUSHFLT] = {"PUSHFLT", 0, 1, (OperandType[]) {OPTP_FLOAT}}, - [OPCODE_PUSHSTR] = {"PUSHSTR", 0, 1, (OperandType[]) {OPTP_STRING}}, - [OPCODE_PUSHVAR] = {"PUSHVAR", 0, 1, (OperandType[]) {OPTP_STRING}}, - [OPCODE_PUSHTRU] = {"PUSHTRU", 0, 0, NULL}, - [OPCODE_PUSHFLS] = {"PUSHFLS", 0, 0, NULL}, - [OPCODE_PUSHNNE] = {"PUSHNNE", 0, 0, NULL}, + [OPCODE_PUSHINT] = {"PUSHINT", 1, (OperandType[]) {OPTP_INT}}, + [OPCODE_PUSHFLT] = {"PUSHFLT", 1, (OperandType[]) {OPTP_FLOAT}}, + [OPCODE_PUSHSTR] = {"PUSHSTR", 1, (OperandType[]) {OPTP_STRING}}, + [OPCODE_PUSHVAR] = {"PUSHVAR", 1, (OperandType[]) {OPTP_STRING}}, + [OPCODE_PUSHTRU] = {"PUSHTRU", 0, NULL}, + [OPCODE_PUSHFLS] = {"PUSHFLS", 0, NULL}, + [OPCODE_PUSHNNE] = {"PUSHNNE", 0, NULL}, - [OPCODE_RETURN] = {"RETURN", 0, 0, NULL}, + [OPCODE_RETURN] = {"RETURN", 0, NULL}, - [OPCODE_JUMPIFNOTANDPOP] = {"JUMPIFNOTANDPOP", 1, 1, (OperandType[]) {OPTP_INT}}, - [OPCODE_JUMP] = {"JUMP", 0, 1, (OperandType[]) {OPTP_INT}}, -}; - -static const char *operand_type_names[] = { - [OPTP_INT] = "int", - [OPTP_FLOAT] = "float", - [OPTP_STRING] = "string", -}; - -static const char *operand_type_arts[] = { - [OPTP_INT] = "an", - [OPTP_FLOAT] = "a", - [OPTP_STRING] = "a", -}; - -static unsigned int operand_type_sizes[] = { - [OPTP_INT] = membersizeof(Operand, as_int), - [OPTP_FLOAT] = membersizeof(Operand, as_float), - [OPTP_STRING] = membersizeof(Operand, as_string), + [OPCODE_JUMPIFNOTANDPOP] = {"JUMPIFNOTANDPOP", 1, (OperandType[]) {OPTP_INT}}, + [OPCODE_JUMP] = {"JUMP", 1, (OperandType[]) {OPTP_INT}}, }; Executable *Executable_Copy(Executable *exe) @@ -101,6 +83,46 @@ void Executable_Free(Executable *exe) } } +void Executable_Dump(Executable *exe) +{ + for(int i = 0; i < exe->bodyl; i += 1) + { + Opcode opcode; + Operand ops[MAX_OPS]; + int opc = MAX_OPS; + + (void) Executable_Fetch(exe, i, &opcode, ops, &opc); + + const InstrInfo *info = instr_table + exe->body[i].opcode; + + fprintf(stderr, "%d: %s ", i, info->name); + + for(int j = 0; j < opc; j += 1) + { + switch(ops[j].type) + { + case OPTP_INT: + fprintf(stderr, "%lld ", ops[j].as_int); + break; + + case OPTP_FLOAT: + fprintf(stderr, "%f ", ops[j].as_float); + break; + + case OPTP_STRING: + fprintf(stderr, "[%s] ", ops[j].as_string); + break; + + case OPTP_PROMISE: + UNREACHABLE; + break; + } + } + + fprintf(stderr, "\n"); + } +} + _Bool Executable_SetSource(Executable *exe, Source *src) { src = Source_Copy(src); @@ -248,6 +270,24 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand * assert(exeb != NULL); assert(opc >= 0); + static const char *operand_type_names[] = { + [OPTP_INT] = "int", + [OPTP_FLOAT] = "float", + [OPTP_STRING] = "string", + }; + + static const char *operand_type_arts[] = { + [OPTP_INT] = "an", + [OPTP_FLOAT] = "a", + [OPTP_STRING] = "a", + }; + + static const unsigned int operand_type_sizes[] = { + [OPTP_INT] = membersizeof(Operand, as_int), + [OPTP_FLOAT] = membersizeof(Operand, as_float), + [OPTP_STRING] = membersizeof(Operand, as_string), + }; + const InstrInfo *info = instr_table + opcode; if(opc != info->opcount) diff --git a/src/common/executable.h b/src/common/executable.h index f68300c..39050d2 100644 --- a/src/common/executable.h +++ b/src/common/executable.h @@ -45,6 +45,7 @@ typedef struct xExeBuilder ExeBuilder; Executable *Executable_Copy(Executable *exe); void Executable_Free(Executable *exe); +void Executable_Dump(Executable *exe); _Bool Executable_Fetch(Executable *exe, int index, Opcode *opcode, Operand *ops, int *opc); _Bool Executable_SetSource(Executable *exe, Source *src); Source *Executable_GetSource(Executable *exe); diff --git a/src/main.c b/src/main.c index 1841e77..5320651 100644 --- a/src/main.c +++ b/src/main.c @@ -181,6 +181,8 @@ int main(int argc, char **argv) BPAlloc_Free(alloc); } + Executable_Dump(exe); + // Execute { Runtime *runtime = Runtime_New(-1, -1); diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index a667103..c186a17 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -495,6 +495,10 @@ static _Bool step(Runtime *runtime, Error *error) } Object *top = Stack_Top(runtime->stack, 0); + + if(!Runtime_Pop(runtime, error, 1)) + return 0; + assert(top != NULL); if(!Object_IsBool(top)) @@ -503,7 +507,7 @@ static _Bool step(Runtime *runtime, Error *error) return 0; } - if(Object_ToBool(top, error)) // This can't fail because we know it's a bool. + if(!Object_ToBool(top, error)) // This can't fail because we know it's a bool. runtime->frame->index = target; return 1; diff --git a/vgcore.11297 b/vgcore.11297 new file mode 100644 index 0000000..38b6ece Binary files /dev/null and b/vgcore.11297 differ