Skip to content

Commit

Permalink
refactoring of the instruction table; removed unused instructions PUS…
Browse files Browse the repository at this point in the history
…HTYPTYP and ERROR; new modulo operator %; new examples fibonacci.noja and isprime.noja
  • Loading branch information
cozis committed Dec 7, 2022
1 parent d483822 commit 98374ee
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 11,453 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ vgcore.*
*.gcov
lib*.a

*.noja
./*.noja
17 changes: 17 additions & 0 deletions examples/fibonacci.noja
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

fun fibonacci(n: int) {

if n < 0:
error("Only non-negative integers allowed");

if n == 0 or n == 1:
return 1;

if n == 2:
return 2;

return fibonacci(n-1)
+ fibonacci(n-2);
}

print(fibonacci(10), "\n");
50 changes: 50 additions & 0 deletions examples/isprime.noja
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

fun isPrime(n: int) {
prime = true; # First assumption
if n < 3: {
if n == 2:
prime = true;
else
prime = false;
} else {
i = 2;
sqrt = math.sqrt(n/1.0);
do {
if n % i == 0: {
prime = false;
break;
}
i = i+1;
} while i <= sqrt;
}
return prime;
}

numbers = [
[-1, false],
[ 0, false],
[ 1, false],
[ 2, true],
[ 3, true],
[ 4, false],
[ 5, true],
[ 6, false],
[ 7, true],
[ 9, false],
[10, false],
[11, true],
[12, false],
[13, true],
[14, false],
[15, false]
];

i = 0;
while i < count(numbers): {
num = numbers[i][0];
exp = numbers[i][1];
res = isPrime(numbers[i][0]);
print("isPrime(", num, ") == ", res, "\n");
assert(res == exp);
i = i+1;
}
11,352 changes: 0 additions & 11,352 deletions large-file.json

This file was deleted.

140 changes: 80 additions & 60 deletions src/lib/common/executable.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "executable.h"

#define MAX_OPS 3
#define MAX_OPCODE_NAME_SIZE 127

typedef struct {
Opcode opcode;
Expand All @@ -62,84 +63,104 @@ struct xExeBuilder {
};

typedef struct {
Opcode opcode;
const char *name;
int opcount;
int opcount;
OperandType *optypes;
} InstrInfo;

#define INSTR(name, ...) \
{ \
OPCODE_##name, \
#name, \
sizeof((OperandType[]) { __VA_ARGS__ }) / sizeof(OperandType), \
(OperandType[]) { __VA_ARGS__ }, \
},

static const InstrInfo instr_table[] = {
[OPCODE_NOPE] = {"NOPE", 0, NULL},
[OPCODE_POS] = {"POS", 0, NULL},
[OPCODE_NEG] = {"NEG", 0, NULL},
[OPCODE_NOT] = {"NOT", 0, NULL},
[OPCODE_ADD] = {"ADD", 0, NULL},
[OPCODE_SUB] = {"SUB", 0, NULL},
[OPCODE_MUL] = {"MUL", 0, NULL},
[OPCODE_DIV] = {"DIV", 0, NULL},
[OPCODE_EQL] = {"EQL", 0, NULL},
[OPCODE_NQL] = {"NQL", 0, NULL},
[OPCODE_LSS] = {"LSS", 0, NULL},
[OPCODE_GRT] = {"GRT", 0, NULL},
[OPCODE_LEQ] = {"LEQ", 0, NULL},
[OPCODE_GEQ] = {"GEQ", 0, NULL},
[OPCODE_NLB] = {"NLB", 0, NULL},
[OPCODE_STP] = {"STP", 0, NULL},
[OPCODE_ASS] = {"ASS", 1, (OperandType[]) {OPTP_STRING}},
[OPCODE_POP] = {"POP", 1, (OperandType[]) {OPTP_INT}},
[OPCODE_CHECKTYPE] = {"CHECKTYPE", 2, (OperandType[]) {OPTP_INT, OPTP_STRING}},
[OPCODE_CALL] = {"CALL", 2, (OperandType[]) {OPTP_INT, OPTP_INT}},
[OPCODE_SELECT] = {"SELECT", 0, NULL},
[OPCODE_INSERT] = {"INSERT", 0, NULL},
[OPCODE_INSERT2] = {"INSERT2", 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_PUSHFUN] = {"PUSHFUN", 2, (OperandType[]) {OPTP_IDX, OPTP_INT}},
[OPCODE_PUSHLST] = {"PUSHLST", 1, (OperandType[]) {OPTP_INT}},
[OPCODE_PUSHMAP] = {"PUSHMAP", 1, (OperandType[]) {OPTP_INT}},
[OPCODE_PUSHTYP] = {"PUSHTYP", 0, NULL},
[OPCODE_PUSHTYPTYP] = {"PUSHTYPTYP", 0, NULL},
[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}},
INSTR(NOPE)
INSTR(POS)
INSTR(NEG)
INSTR(NOT)
INSTR(ADD)
INSTR(SUB)
INSTR(MUL)
INSTR(DIV)
INSTR(EQL)
INSTR(NQL)
INSTR(LSS)
INSTR(GRT)
INSTR(LEQ)
INSTR(GEQ)
INSTR(NLB)
INSTR(STP)
INSTR(ASS, OPTP_STRING)
INSTR(POP, OPTP_INT)
INSTR(CHECKTYPE, OPTP_INT, OPTP_STRING)
INSTR(CALL, OPTP_INT, OPTP_INT)
INSTR(SELECT)
INSTR(INSERT)
INSTR(INSERT2)
INSTR(PUSHINT, OPTP_INT)
INSTR(PUSHFLT, OPTP_FLOAT)
INSTR(PUSHSTR, OPTP_STRING)
INSTR(PUSHVAR, OPTP_STRING)
INSTR(PUSHTRU)
INSTR(PUSHFLS)
INSTR(PUSHNNE)
INSTR(PUSHFUN, OPTP_IDX, OPTP_INT)
INSTR(PUSHLST, OPTP_INT)
INSTR(PUSHMAP, OPTP_INT)
INSTR(PUSHTYP)
INSTR(PUSHNNETYP)
INSTR(RETURN, OPTP_INT)
INSTR(EXIT)
INSTR(JUMPIFNOTANDPOP, OPTP_IDX)
INSTR(JUMPIFANDPOP, OPTP_IDX)
INSTR(JUMP, OPTP_IDX)
};

_Bool Executable_GetOpcodeBinaryFromName(const char *name, size_t name_len, Opcode *opcode)
static const size_t instr_count = sizeof(instr_table)/sizeof(instr_table[0]);

_Bool Executable_GetOpcodeBinaryFromName(const char *name, size_t len, Opcode *opcode)
{
// The input name is assumed not zero-terminated,
// so to simplify things we duplicate it to add
// an extra null byte.
char buff[128]; // No opcode should have a name this big.
ASSERT(name_len < sizeof(buff)); // If this is triggered, [buff] should be made bigger.

memcpy(buff, name, name_len);
buff[name_len] = '\0';

char buff[MAX_OPCODE_NAME_SIZE+1]; // No opcode should have a name this big.
if (len >= sizeof(buff))
return false;
memcpy(buff, name, len);
buff[len] = '\0';
name = buff;

// Now name is zero terminated.
ASSERT(name[name_len] == '\0');
ASSERT(name[len] == '\0');

for(size_t i = 0; i < sizeof(instr_table)/sizeof(instr_table[0]); i += 1) {
for(size_t i = 0; i < instr_count; i += 1) {
if(!strcmp(name, instr_table[i].name)) {
*opcode = i; // Is this safe?
if (opcode != NULL)
*opcode = instr_table[i].opcode;
return 1;
}
}
return 0;
}

static const InstrInfo *Executable_GetInstrByOpcode(Opcode opcode)
{
for (size_t i = 0; i < instr_count; i++)
if (instr_table[i].opcode == opcode)
return instr_table + i;
return NULL;
}

const char *Executable_GetOpcodeName(Opcode opcode)
{
return instr_table[opcode].name;
const InstrInfo *instr = Executable_GetInstrByOpcode(opcode);
if (instr == NULL)
return NULL;
return instr->name;
}

Executable *Executable_Copy(Executable *exe)
Expand Down Expand Up @@ -172,8 +193,8 @@ void Executable_Dump(Executable *exe)
int opc = MAX_OPS;

(void) Executable_Fetch(exe, i, &opcode, ops, &opc);

const InstrInfo *info = instr_table + exe->body[i].opcode;
const InstrInfo *info = Executable_GetInstrByOpcode(opcode);

fprintf(stderr, "%d: %s ", i, info->name);

Expand Down Expand Up @@ -250,7 +271,7 @@ _Bool Executable_Fetch(Executable *exe, int index, Opcode *opcode, Operand *ops,
return 0;

const Instruction *instr = exe->body + index;
const InstrInfo *info = instr_table + instr->opcode;
const InstrInfo *info = Executable_GetInstrByOpcode(instr->opcode);

if(opcode)
*opcode = instr->opcode;
Expand Down Expand Up @@ -497,7 +518,7 @@ _Bool ExeBuilder_Append(ExeBuilder *exeb, Error *error, Opcode opcode, Operand *
[OPTP_STRING] = membersizeof(Operand, as_string),
};

const InstrInfo *info = instr_table + opcode;
const InstrInfo *info = Executable_GetInstrByOpcode(opcode);

if(opc != info->opcount)
{
Expand Down Expand Up @@ -633,5 +654,4 @@ int ExeBuilder_InstrCount(ExeBuilder *exeb)
ASSERT(raw_size % sizeof(Instruction) == 0);

return raw_size / sizeof(Instruction);
}

}
3 changes: 1 addition & 2 deletions src/lib/common/executable.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ typedef enum {
OPCODE_SUB,
OPCODE_MUL,
OPCODE_DIV,
OPCODE_MOD,
OPCODE_EQL,
OPCODE_NQL,
OPCODE_LSS,
Expand All @@ -86,10 +87,8 @@ typedef enum {
OPCODE_PUSHLST,
OPCODE_PUSHMAP,
OPCODE_PUSHTYP,
OPCODE_PUSHTYPTYP,
OPCODE_PUSHNNETYP,
OPCODE_RETURN,
OPCODE_ERROR,
OPCODE_EXIT,
OPCODE_JUMPIFANDPOP,
OPCODE_JUMPIFNOTANDPOP,
Expand Down
1 change: 1 addition & 0 deletions src/lib/compiler/ASTi.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ typedef enum {
EXPR_SUB,
EXPR_MUL,
EXPR_DIV,
EXPR_MOD,

EXPR_EQL,
EXPR_NQL,
Expand Down
16 changes: 2 additions & 14 deletions src/lib/compiler/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,6 @@ static void emitInstr_EQL(CodegenContext *ctx, int off, int len)
CodegenContext_EmitInstr(ctx, OPCODE_EQL, NULL, 0, off, len);
}

static void emitInstr_ERROR(CodegenContext *ctx, const char *msg, int off, int len)
{
Operand opv[1] = {
{ .type = OPTP_STRING, .as_string = msg },
};
CodegenContext_EmitInstr(ctx, OPCODE_ERROR, opv, 1, off, len);
}

static void emitInstr_CHECKTYPE(CodegenContext *ctx, int arg_index, const char *arg_name, int off, int len)
{
Operand opv[2] = {
Expand All @@ -167,11 +159,6 @@ static void emitInstr_PUSHTYP(CodegenContext *ctx, int off, int len)
CodegenContext_EmitInstr(ctx, OPCODE_PUSHTYP, NULL, 0, off, len);
}

static void emitInstr_PUSHTYPTYP(CodegenContext *ctx, int off, int len)
{
CodegenContext_EmitInstr(ctx, OPCODE_PUSHTYPTYP, NULL, 0, off, len);
}

static void emitInstr_PUSHNNETYP(CodegenContext *ctx, int off, int len)
{
CodegenContext_EmitInstr(ctx, OPCODE_PUSHNNETYP, NULL, 0, off, len);
Expand All @@ -192,6 +179,7 @@ static Opcode exprkind_to_opcode(ExprKind kind)
case EXPR_SUB: return OPCODE_SUB;
case EXPR_MUL: return OPCODE_MUL;
case EXPR_DIV: return OPCODE_DIV;
case EXPR_MOD: return OPCODE_MOD;
case EXPR_EQL: return OPCODE_EQL;
case EXPR_NQL: return OPCODE_NQL;
case EXPR_LSS: return OPCODE_LSS;
Expand Down Expand Up @@ -391,7 +379,7 @@ static void emitInstrForExprNode(CodegenContext *ctx, ExprNode *expr,

case EXPR_NULLABLETYPE:
case EXPR_SUMTYPE:
case EXPR_NOT:
case EXPR_NOT: case EXPR_MOD:
case EXPR_POS: case EXPR_NEG:
case EXPR_ADD: case EXPR_SUB:
case EXPR_MUL: case EXPR_DIV:
Expand Down
Loading

0 comments on commit 98374ee

Please sign in to comment.