From 7f0cb1b2deb0c46cbef02eded30a16f0432d5bdc Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Fri, 19 Oct 2018 14:35:35 +0300 Subject: remote work commit --- src/compiler/compiler.lm | 57 +++++++++++++++++++++++------------------------- src/compiler/native.c | 30 ++++++++++--------------- 2 files changed, 38 insertions(+), 49 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/compiler.lm b/src/compiler/compiler.lm index 1ca7705..502422d 100644 --- a/src/compiler/compiler.lm +++ b/src/compiler/compiler.lm @@ -167,6 +167,7 @@ if (!source) { struct scope names:map> + roff:int end global g_scopes:list = new list() @@ -281,21 +282,23 @@ global INS_VERSION:int = 0 global INS_REG:int = 1 global INS_PUSH:int = 2 global INS_PUSHR:int = 3 -global INS_STORE:int = 4 -global INS_OP:int = 5 -global INS_QUEUE:int = 6 -global INS_IO:int = 7 -global INS_EXEC:int = 8 -global INS_CALL:int = 9 -global INS_JMP:int = 10 -global INS_JMPIF:int = 11 +global INS_POP:int = 4 +global INS_INCR:int = 5 +global INS_OP:int = 6 +global INS_QUEUE:int = 7 +global INS_IO:int = 8 +global INS_EXEC:int = 9 +global INS_CALL:int = 10 +global INS_JMP:int = 11 +global INS_JMPIF:int = 12 int insbuf_written() = c_insbuf_written str flush_insbuf() = c_flush_insbuf void write_ins(ins:int, num:int) = c_write_ins void write_ins_with_data(ins:int, data:str) = c_write_ins_with_data -global g_regc:int = 1 +global g_r1:int = 1 +global g_regc:int = g_r1 + 1 void new_reg(v:any, data:str) @@ -329,6 +332,8 @@ find_data_in(s:any) } write_ins(INS_VERSION, 1) +write_ins_with_data(INS_REG, '') + for e:expr::paren::type in source find_data_in(e.collapsed) for e:expr::bracket::type in source @@ -344,10 +349,6 @@ for d:fspec::declaration::type in source { write_data_if_not_there($d.container.data.name) } -global g_fcr:int = g_regc -write_ins_with_data(INS_REG, '') -g_regc = g_regc + 1 - void write_expr(expr:collapser::reducer::collapsed) { @@ -381,7 +382,7 @@ write_expr(expr:collapser::reducer::collapsed) off = g_offs->find(%d.container) } } - write_ins(INS_PUSHR, off + g_regs->find(%d)) + write_ins(INS_PUSHR, off + g_regs->find(%d) - off) } else { write_ins(INS_OP, g_ops->find($vop.op)) } @@ -417,6 +418,9 @@ write_declaration(d:fspec::declaration::type, index:int) c:fspec::container::type = d.container if (d.cref) c = lookup($d.cref, $d.parent, nil) + if (!c && index > 0) + write_ins(INS_INCR, g_r1) + locs:map = new map() if (d.extra) { for l:fspec::declaration::dimension in repeat(d.extra.dimension) { @@ -432,15 +436,9 @@ write_declaration(d:fspec::declaration::type, index:int) } if (!c) { - write_ins(INS_PUSHR, g_fcr) - if (index != 0) { - write_ins(INS_PUSH, index) - write_ins(INS_OP, g_ops->find('#+')) - } write_ins(INS_IO, d.primitive.bits) } else { write_ins(INS_PUSH, g_offs->find(%c)) - write_ins(INS_STORE, g_fcr) write_ins(INS_EXEC, g_regs->find(%c)) } @@ -453,20 +451,19 @@ write_declaration(d:fspec::declaration::type, index:int) void walk1(d:fspec::declaration::type) { - if (!d.container) { - print('something went wrong!\n') - exit(1) - } + c:fspec::container::type = d.container + if (d.cref) c = lookup($d.cref, $d.parent, nil) + + if (!c || !d.name) + return 0 for i:fspec::container::strukt::item in repeat(d.container.data.items) - if (i.data.container) - walk1(i.data) + walk1(i.data) for i:fspec::container::select::item in repeat(d.container.data.items) - if (i.data.container) - walk1(i.data) + walk1(i.data) - g_offs->insert(%d.container, g_regc) + g_offs->insert(%d, g_regc) for i:fspec::container::enum::item in repeat(d.container.data.items) { # somehow need to get this constant time (not reg) @@ -515,7 +512,7 @@ walk2(d:fspec::declaration::type) if (!d.name) { write_ins(INS_PUSH, g_offs->find(%d.container)) - write_ins(INS_STORE, g_fcr) + write_ins(INS_POP, g_r1) } index:int = 0 diff --git a/src/compiler/native.c b/src/compiler/native.c index bbb0060..feac349 100644 --- a/src/compiler/native.c +++ b/src/compiler/native.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -110,36 +111,27 @@ c_op_stack_pop(program_t *prg, tree_t **sp, value_t a) return r; } -static uint8_t -bits_for_n(const uint8_t n, const uint8_t used) -{ - return 16 * (1 << n) - used; -} - static uint8_t n_for_v(const uint64_t v, const uint8_t used) { - const uint8_t bits = __builtin_ctzl((v ? v : 1)); - if (used <= 16 && bits < bits_for_n(0, used)) - return 0; - else if (used <= 32 && bits < bits_for_n(1, used)) - return 1; - else if (used <= 64 && bits < bits_for_n(2, used)) - return 2; - - errx(EXIT_FAILURE, "numbers over 57 bits not supported right now.. sorry :D"); + for (uint8_t n = 0; n < 4; ++n) { + const uint8_t bits = CHAR_BIT * (1 << n); + if (used < bits && v < (uint64_t)(1 << (bits - used))) + return n; + } + errx(EXIT_FAILURE, "number `%" PRIu64 "` is too big to be compiled in instruction", v); return 3; } static void -vle_instruction(const uint8_t name, const uint64_t v, uint8_t out[16], uint8_t *out_written) +vle_instruction(const uint8_t name, const uint64_t v, uint8_t out[8], uint8_t *out_written) { assert(out && out_written); const union { struct { unsigned name:5; unsigned n:2; uint64_t v:57; } ins; - uint8_t v[16]; + uint8_t v[sizeof(uint64_t)]; } u = { .ins = { .name = name, .n = n_for_v(v, 7), .v = v } }; - *out_written = sizeof(uint16_t) * (1 << u.ins.n); + *out_written = sizeof(u.v[0]) * (1 << u.ins.n); memcpy(out, u.v, *out_written); } @@ -165,7 +157,7 @@ c_insbuf_written(program_t *prg, tree_t **sp) void c_write_ins(program_t *prg, tree_t **sp, value_t a, value_t b) { - uint8_t out[16], written; + uint8_t out[8], written; vle_instruction(a, b, out, &written); memcpy(&insbuf.data[insbuf.written], out, written); insbuf.written += written; -- cgit v1.2.3