From d300270cd8c846aad562619838c934fe266af371 Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Tue, 11 Oct 2022 12:21:11 +0200 Subject: [PATCH] :art: Add primitive --- ast | 2 +- include/emit.h | 1 + include/env/type.h | 1 + include/import/tdef.h | 4 + src/clean.c | 1 + src/emit/emit.c | 12 +- src/env/context.c | 4 +- src/import/import_prim.c | 235 ++++++++++++++++++++++++++++++++ src/import/import_tdef.c | 5 - src/lib/array.c | 17 ++- src/lib/prim.c | 51 ++----- src/parse/check.c | 10 +- src/parse/scan0.c | 17 +++ src/parse/scan1.c | 7 +- src/parse/scan2.c | 1 + tests/primitive/access.gw | 4 + tests/primitive/dyn_access.gw | 6 + tests/primitive/oob.gw | 4 + tests/primitive/static_oob.gw | 3 + tests/primitive/too_many_exp.gw | 3 + 20 files changed, 336 insertions(+), 52 deletions(-) create mode 100644 src/import/import_prim.c create mode 100644 tests/primitive/access.gw create mode 100644 tests/primitive/dyn_access.gw create mode 100644 tests/primitive/oob.gw create mode 100644 tests/primitive/static_oob.gw create mode 100644 tests/primitive/too_many_exp.gw diff --git a/ast b/ast index 310aab6d..f6c9ae7f 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit 310aab6d18d29f3bcb06fa1b5b12f2e7d2e79555 +Subproject commit f6c9ae7feb355a64345da5c99c479a32a310df11 diff --git a/include/emit.h b/include/emit.h index 46c3dfbf..942f67d4 100644 --- a/include/emit.h +++ b/include/emit.h @@ -125,4 +125,5 @@ ANN void emit_pop_scope(const Emitter emit); ANN m_bool ensure_emit(const Emitter, const Type); ANN m_bool emit_ensure_func(const Emitter emit, const Func f); +ANN m_bool get_emit_var(const Emitter emit, const Type t, bool is_var); #endif diff --git a/include/env/type.h b/include/env/type.h index fbe56d9e..6c528adc 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -41,6 +41,7 @@ enum tflag { tflag_union = 1 << 21, tflag_enum = 1 << 22, tflag_ref = 1 << 23, + tflag_packed = 1 << 24, } __attribute__((packed)); struct Type_ { diff --git a/include/import/tdef.h b/include/import/tdef.h index fb19235e..1c19a033 100644 --- a/include/import/tdef.h +++ b/include/import/tdef.h @@ -5,4 +5,8 @@ ANN m_int gwi_typedef_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name); ANN Type gwi_typedef_end(const Gwi gwi, const ae_flag flag); ANN void ck_clean_tdef(MemPool, ImportCK *); + +ANN Type mk_primitive(const Env env, const m_str name, const m_uint size); +//ANN Type gwi_primitive(const Gwi gwi, const m_str name, const m_uint size, const ae_flag flag); +ANN m_bool gwi_primitive(const Gwi gwi, const m_str name, const m_uint size, const ae_flag flag); #endif diff --git a/src/clean.c b/src/clean.c index 65f07230..69aea438 100644 --- a/src/clean.c +++ b/src/clean.c @@ -339,6 +339,7 @@ ANN static void clean_trait_def(Clean *a, Trait_Def b) { if (b->traits) clean_id_list(a, b->traits); if (b->body) clean_ast(a, b->body); } +ANN static void clean_prim_def(Clean *a NUSED, Prim_Def b NUSED) {} DECL_SECTION_FUNC(clean, void, Clean *); diff --git a/src/emit/emit.c b/src/emit/emit.c index e6e80fb0..62f1c7cc 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -757,9 +757,13 @@ ANN m_bool emit_array_access(const Emitter emit, } ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array *array) { - CHECK_BB(emit_exp(emit, array->base)); const Exp e = exp_self(array); - struct ArrayAccessInfo info = {*array->array, e->type, exp_getvar(e)}; + exp_setvar(array->base, get_emit_var(emit, array->base->type, exp_getvar(e))); + CHECK_BB(emit_exp(emit, array->base)); + struct ArrayAccessInfo info = { + .array = *array->array, + .type = e->type, + .is_var = exp_getvar(e)}; return emit_array_access(emit, &info); } @@ -965,7 +969,8 @@ ANN static m_bool decl_static(const Emitter emit, const Exp_Decl *decl, } ANN static inline int struct_ctor(const Value v) { - return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor; + return tflag(v->type, tflag_struct) && v->type->nspc && v->type->nspc->pre_ctor; +// return tflag(v->type, tflag_struct) && v->type->nspc->pre_ctor; } ANN static void decl_expand(const Emitter emit, const Type t) { @@ -2898,6 +2903,7 @@ ANN m_bool emit_func_def(const Emitter emit, const Func_Def fdef) { #define emit_fptr_def dummy_func #define emit_trait_def dummy_func #define emit_extend_def dummy_func +#define emit_prim_def dummy_func HANDLE_SECTION_FUNC(emit, m_bool, Emitter); diff --git a/src/env/context.c b/src/env/context.c index 760e6817..207062b3 100644 --- a/src/env/context.c +++ b/src/env/context.c @@ -9,7 +9,9 @@ ANN void free_context(const Context a, Gwion gwion) { const Nspc global = a->nspc->parent; if(!a->error) // this is quite a hack nspc_remref(a->nspc, gwion); - if(a->error) nspc_remref(global, gwion); +// if(a->error) // this is quite a hack + if(a->global) // this is quite a hack + nspc_remref(global, gwion); free_mstr(gwion->mp, a->name); ast_cleaner(gwion, a->tree); mp_free(gwion->mp, Context, a); diff --git a/src/import/import_prim.c b/src/import/import_prim.c new file mode 100644 index 00000000..3a2dc480 --- /dev/null +++ b/src/import/import_prim.c @@ -0,0 +1,235 @@ +#include +#include "gwion_util.h" +#include "gwion_ast.h" +#include "gwion_env.h" +#include "vm.h" +#include "instr.h" +#include "emit.h" +#include "gwion.h" +#include "object.h" +#include "operator.h" +#include "import.h" +#include "gwi.h" +#include "array.h" +#include "gack.h" + +static GACK(gack_prim) { + for(m_uint i = 0; i < t->actual_size; i++) { + const m_bit *value = VALUE + i; + for(unsigned char mask = 1U << (CHAR_BIT-1); mask; mask >>= 1) + INTERP_PRINTF("%c", *(uint8_t*)value & mask ? '1' : '0'); + if(i < t->actual_size - 1) + INTERP_PRINTF(" "); + } +} + +static INSTR(bit_set) { + POP_REG(shred, SZ_INT); + const m_int offset = *(m_int*)REG(0); + const m_uint byte = offset / CHAR_BIT; + const m_uint idx = offset % CHAR_BIT; + uint8_t *val = *(uint8_t**)REG(-SZ_INT); + val += byte; + const m_int key = *(m_int*)REG(-SZ_INT*2); + if(key) *val = ((1 << idx) | (*val)); + else **(m_bit**)REG(-SZ_INT) = ((*val) & (~(1 << (idx)))); + *(m_bit**)REG(-SZ_INT) = REG(0); +} + +static INSTR(bit_set_fast) { + uint8_t *val = *(uint8_t**)REG(-SZ_INT); + val += instr->m_val; + const m_uint idx = instr->m_val2; + const m_int key = *(m_int*)REG(-SZ_INT*2); + if(key) *val = ((1 << idx) | (*val)); + else **(m_bit**)REG(-SZ_INT) = ((*val) & (~(1 << (idx)))); + *(m_bit**)REG(-SZ_INT) = REG(0); +} + +static INSTR(bit_check) { + const m_int offset = *(m_int*)REG(-SZ_INT); + if(offset < 0 || offset >= (m_int)instr->m_val) + handle(shred, "OutOfBoundByteAccess"); +} + +ANN static bool _bit_get(const uint8_t val, const m_uint idx) { + const int mask = 1 << idx; + const int masked_n = val & mask; + return masked_n >> idx; +} + +static INSTR(bit_get) { + POP_REG(shred, instr->m_val); + const m_int offset = *(m_int*)REG(0); + const m_uint byte = offset / CHAR_BIT; + const uint8_t val = *(uint8_t*)REG(byte - SZ_INT); + *(m_int*)REG(-SZ_INT) = _bit_get(val, offset % CHAR_BIT); +} + +static INSTR(bit_get_fast) { + const uint8_t val = *(uint8_t*)REG((int16_t)instr->udata.two); + *(m_int*)REG(-instr->m_val) = _bit_get(val, instr->udata.one); +} + +static OP_EMIT(opem_bit_access) { + struct ArrayAccessInfo *const info = (struct ArrayAccessInfo *)data; + if(!is_prim_int(info->array.exp)) { + CHECK_BB(emit_exp(emit, info->array.exp)); + const Instr check = emit_add_instr(emit, bit_check); + check->m_val = info->array.type->actual_size * CHAR_BIT; + if(!info->is_var) { + const Instr instr = emit_add_instr(emit, bit_get); + instr->m_val = info->array.type->size; + } else emit_add_instr(emit, bit_set); + } else { + const m_uint offset = info->array.exp->d.prim.d.num; + if(!info->is_var) { + const Instr instr = emit_add_instr(emit, bit_get_fast); + instr->m_val = info->type->size; + instr->udata.one = offset % CHAR_BIT; + instr->udata.two = (m_int)((offset / CHAR_BIT) - SZ_INT); + } else { + const Instr instr = emit_add_instr(emit, bit_set_fast); + const m_uint offset = info->array.exp->d.prim.d.num; + instr->m_val2 = offset % CHAR_BIT; + instr->m_val = (offset / CHAR_BIT); + } + } + return GW_OK; +} + +static OP_EMIT(opem_bit_exp) { + bool *var = data; + var[1] = var[0]; + return GW_OK; +} + +static OP_CHECK(opck_bit_access) { + Array_Sub array = data; + const Exp e = array->exp; + if(e->next) ERR_N(e->next->pos, "too many expressions for bit access"); + if(is_prim_int(e)) { + m_int idx = e->d.prim.d.num; + if(idx < 0 || idx >= (m_int)array->type->size * CHAR_BIT) + ERR_N(e->pos, "bit access out of bound"); + } + return env->gwion->type[et_bool]; +} + +ANN static void scan_prim_op(const Env env, const Type t){ + struct Op_Func opfunc = { .ck = opck_bit_access, .em = opem_bit_access }; + struct Op_Import opi = { + .op = insert_symbol(env->gwion->st, "@array"), + .lhs = env->gwion->type[et_int], + .rhs = t, + .func = &opfunc + }; + add_op(env->gwion, &opi); +} + +ANN static void scan_prim_op2(const Env env, const Type t){ + struct Op_Func opfunc = {.em = opem_bit_exp }; + struct Op_Import opi = { + .op = insert_symbol(env->gwion->st, "@array_init"), + .lhs = t, + .ret = env->gwion->type[et_bool], + .func = &opfunc + }; + add_op(env->gwion, &opi); +} + +static INSTR(bitset) { + POP_REG(shred, SZ_INT); + memcpy(*(uint8_t**)REG(0), REG(-SZ_INT), instr->m_val); +} + +static OP_EMIT(opem_bitset) { + Exp_Binary *bin = data; + const Instr instr = emit_add_instr(emit, bitset); + const Type t = isa(bin->rhs->type, emit->gwion->type[et_int]) > 0 + ? bin->lhs->type + : bin->rhs->type; + instr->m_val = t->actual_size; + return GW_OK; +} + +static INSTR(bitcast) { + memset(REG((m_int)instr->m_val), 0, instr->m_val2); +} + +static OP_EMIT(opem_bitcast) { + Exp_Cast *cast = data; + const Type t = isa(cast->exp->type, emit->gwion->type[et_int]) > 0 + ? known_type(emit->env, cast->td) + : cast->exp->type; + const Instr instr = emit_add_instr(emit, bitcast); + instr->m_val = -SZ_INT + t->actual_size; + instr->m_val2 = SZ_INT - t->actual_size; + return GW_OK; +} + +ANN2(1,2,3,5) static void prim_op(const Env env, const Type t, const m_str op, const opck ck, const opem em){ + struct Op_Func opfunc = { .ck = ck, .em = em }; + struct Op_Import opi = { + .op = insert_symbol(env->gwion->st, op), + .lhs = env->gwion->type[et_int], + .rhs = t, + .ret = t, + .func = &opfunc + }; + add_op(env->gwion, &opi); + opi.lhs = t; + opi.rhs = opi.ret = env->gwion->type[et_int]; + add_op(env->gwion, &opi); +} + +ANN static void prim_implicit(const Env env, const Type t){ + struct Op_Import opi = { + .op = insert_symbol(env->gwion->st, "@implicit"), + .lhs = t, + .rhs = env->gwion->type[et_int], + .ret = env->gwion->type[et_int], + }; + add_op(env->gwion, &opi); +} + +ANN Type mk_primitive(const Env env, const m_str name, const m_uint size) { + m_uint sz = SZ_INT; + while(sz < size) sz += SZ_INT; + const Type t = new_type(env->gwion->mp, name, NULL); + t->size = sz; + t->actual_size = size; + scan_prim_op(env, t); + scan_prim_op2(env, t); + if(size < SZ_INT) { + prim_op(env, t, ":=>", opck_rassign, opem_bitset); + prim_op(env, t, "$", NULL, opem_bitcast); + prim_implicit(env, t); + } else if(size == SZ_INT) { + prim_op(env, t, ":=>", opck_rassign, (opem)dummy_func); + prim_op(env, t, "$", NULL, (opem)dummy_func); + prim_implicit(env, t); + } // else provide function to get slices + CHECK_BO(mk_gack(env->gwion->mp, t, gack_prim)); + return t; +} + +// actually we should make a Prim_Def +// and either execute and free it already +// or add it to the current ast + +ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef); + +//ANN Type gwi_primitive(const Gwi gwi, const m_str name, const m_uint size, const ae_flag flag) { +ANN m_bool gwi_primitive(const Gwi gwi, const m_str name, const m_uint size, const ae_flag flag) { + const Env env = gwi->gwion->env; + const Prim_Def pdef = new_prim_def(gwi->gwion->mp, insert_symbol(gwi->gwion->st, name), size, gwi->loc, flag); + if(!env->class_def || !tflag(env->class_def, tflag_tmpl)) { + const m_bool ret = scan0_prim_def(gwi->gwion->env, pdef); + free_prim_def(gwi->gwion->mp, pdef); + return ret; + } + Section section = MK_SECTION(primitive, prim_def, pdef); + gwi_body(gwi, §ion); + return GW_OK; +} diff --git a/src/import/import_tdef.c b/src/import/import_tdef.c index ab4a4092..22030732 100644 --- a/src/import/import_tdef.c +++ b/src/import/import_tdef.c @@ -1,6 +1,3 @@ -#include -#include -#include #include "gwion_util.h" #include "gwion_ast.h" #include "gwion_env.h" @@ -13,8 +10,6 @@ #include "operator.h" #include "import.h" #include "gwi.h" -#include "mpool.h" -#include "specialid.h" ANN m_int gwi_typedef_ini(const Gwi gwi, const restrict m_str type, const restrict m_str name) { diff --git a/src/lib/array.c b/src/lib/array.c index 419f3be7..eb7b6f67 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -348,6 +348,16 @@ ANN static inline m_bool array_do(const Emitter emit, const Array_Sub array, return GW_OK; } +ANN m_bool get_emit_var(const Emitter emit, const Type t, bool is_var) { + const Env env = emit->env; + bool vars[2] = { is_var }; + struct Op_Import opi = {.op = insert_symbol("@array_init"), + .lhs = t, + .data = (uintptr_t)vars}; + CHECK_BB(op_emit(emit, &opi)); + return vars[1]; +} + ANN static inline Exp emit_n_exp(const Emitter emit, struct ArrayAccessInfo *const info) { const Exp e = take_exp(info->array.exp, info->array.depth); @@ -355,7 +365,8 @@ ANN static inline Exp emit_n_exp(const Emitter emit, e->next = NULL; struct Array_Sub_ partial = {info->array.exp, info->array.type, info->array.depth}; - const m_bool ret = array_do(emit, &partial, 0); + const bool is_var = get_emit_var(emit, array_base(info->array.type), info->is_var); + const m_bool ret = array_do(emit, &partial, is_var); e->next = next; return ret > 0 ? next : NULL; } @@ -986,6 +997,10 @@ GWION_IMPORT(array) { GWI_BB(gwi_oper_ini(gwi, "Array", NULL, NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_scan)) GWI_BB(gwi_oper_end(gwi, "@scan", NULL)) + + GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, NULL, "bool")) + GWI_BB(gwi_oper_end(gwi, "@array_init", NoOp)) + gwi_register_freearg(gwi, ArrayAlloc, freearg_array); return GW_OK; } diff --git a/src/lib/prim.c b/src/lib/prim.c index 4e0fa1ab..c1cf7acd 100644 --- a/src/lib/prim.c +++ b/src/lib/prim.c @@ -1,3 +1,4 @@ +#include #include "gwion_util.h" #include "gwion_ast.h" #include "gwion_env.h" @@ -18,16 +19,6 @@ #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func) -static inline bool is_prim(const Exp e) { return e->exp_type == ae_exp_primary; } - -static inline bool is_prim_int(const Exp e) { - return (is_prim(e) && e->d.prim.prim_type == ae_prim_num); -} - -static inline bool is_prim_float(const Exp e) { - return (is_prim(e) && e->d.prim.prim_type == ae_prim_float); -} - #define POWEROF2_OPT(name, OP) \ if (is_prim_int(bin->rhs) && pot(bin->rhs->d.prim.d.num)) { \ bin->op = insert_symbol(#OP); \ @@ -622,38 +613,20 @@ static GWION_IMPORT(float) { return GW_OK; } -static GACK(gack_u8) { - INTERP_PRINTF("%u", *(uint8_t*)VALUE); -} - -static GACK(gack_u16) { - INTERP_PRINTF("%u", *(uint16_t*)VALUE); -} - -static GACK(gack_u32) { - INTERP_PRINTF("%u", *(uint32_t*)VALUE); +ANN static m_bool import_ux(const Gwi gwi) { + char c[8] = { 'u' }; + const Env env = gwi->gwion->env; + for(uint i = 1; i <= SZ_INT; i *= 2) { + sprintf(c+1, "%u", i * CHAR_BIT); + const Symbol s = insert_symbol(c); + GWI_OB(gwi_primitive(gwi, s_name(s), i, ae_flag_none)); + } + return GW_OK; } GWION_IMPORT(prim) { - GWI_BB(import_int(gwi)) // const folded + imm optimized - const Type t_u8 = gwi_mk_type(gwi, "u8", SZ_INT, "int"); - t_u8->actual_size = 1; - gwi_gack(gwi, t_u8, gack_u8); - gwi_add_type(gwi, t_u8); - GWI_BB(gwi_oper_ini(gwi, "int", "u8", "u8")) - GWI_BB(gwi_oper_end(gwi, "@implicit", NoOp)) - const Type t_u16 = gwi_mk_type(gwi, "u16", SZ_INT, "int"); - t_u16->actual_size = 2; - gwi_gack(gwi, t_u16, gack_u16); - gwi_add_type(gwi, t_u16); - GWI_BB(gwi_oper_ini(gwi, "int", "u16", "u16")) - GWI_BB(gwi_oper_end(gwi, "@implicit", NoOp)) - const Type t_u32 = gwi_mk_type(gwi, "u32", SZ_INT, "int"); - t_u32->actual_size = 4; - gwi_gack(gwi, t_u32, gack_u32); - gwi_add_type(gwi, t_u32); - GWI_BB(gwi_oper_ini(gwi, "int", "u32", "u32")) - GWI_BB(gwi_oper_end(gwi, "@implicit", NoOp)) + GWI_BB(import_int(gwi)) + GWI_BB(import_ux(gwi)); GWI_BB(import_float(gwi)) // const folded GWI_BB(import_intfloat(gwi)) // const folded GWI_BB(import_floatint(gwi)) // const folded diff --git a/src/parse/check.c b/src/parse/check.c index 656528b2..68756d4f 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -62,12 +62,19 @@ ANN static inline m_bool check_exp_decl_parent(const Env env, return GW_OK; } +ANN static m_uint get_decl_size(const Env env, const Value v) { + if(safe_tflag(env->class_def, tflag_packed) && v->type->actual_size) + return v->type->actual_size; + return v->type->size; + +} + #define describe_check_decl(a, b, flag) \ ANN static inline void decl_##a(const Env env, const Value v) { \ const Nspc nspc = env->curr; \ flag; \ v->from->offset = nspc->b; \ - nspc->b += v->type->size; \ + nspc->b += get_decl_size(env, v); \ } describe_check_decl(member, offset, v->vflag |= vflag_member); @@ -1919,6 +1926,7 @@ ANN m_bool check_fptr_def(const Env env, const Fptr_Def fptr) { return ret; } +#define check_prim_def dummy_func HANDLE_SECTION_FUNC(check, m_bool, Env) ANN static m_bool check_parent(const Env env, const Class_Def cdef) { diff --git a/src/parse/scan0.c b/src/parse/scan0.c index 6a4a7066..ae57aef3 100644 --- a/src/parse/scan0.c +++ b/src/parse/scan0.c @@ -482,6 +482,23 @@ ANN static m_bool scan0_trait_def(const Env env, const Trait_Def pdef) { return GW_OK; } +ANN m_bool scan0_prim_def(const Env env, const Prim_Def pdef) { + const loc_t loc = pdef->loc; + CHECK_BB(env_access(env, pdef->flag, loc)); + CHECK_BB(scan0_defined(env, pdef->name, loc)); + const bool global = GET_FLAG(pdef, global); + if(global) { + context_global(env); + env_push_global(env); + } + const Type t = mk_primitive(env, s_name(pdef->name), pdef->size); + add_type(env, env->curr, t); + mk_class(env, t, pdef->loc); + t->flag = pdef->flag; + if(global) env_pop(env, 0); + return GW_OK; +} + HANDLE_SECTION_FUNC(scan0, m_bool, Env) ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) { diff --git a/src/parse/scan1.c b/src/parse/scan1.c index e87d8985..0129144f 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -527,6 +527,10 @@ ANN static m_bool scan1_stmt_return(const Env env, const Stmt_Exp stmt) { ANN static m_bool scan1_stmt_pp(const Env env, const Stmt_PP stmt) { if (stmt->pp_type == ae_pp_include) env->name = stmt->data; + if (stmt->pp_type == ae_pp_pragma && !strcmp(stmt->data, "packed")) { + if(env->class_def && !tflag(env->class_def, tflag_union)) set_tflag(env->class_def, tflag_packed); + else ERR_B(stmt_self(stmt)->pos, "`packed` pragma outside of {G+}class{0} or {G+}struct{0} declaration"); + } return GW_OK; } @@ -649,6 +653,7 @@ ANN static inline m_bool scan1_fdef_defined(const Env env, const Value v = nspc_lookup_value1(env->curr, fdef->base->xid); if (!v) return GW_OK; if (is_func(env->gwion, actual_type(env->gwion, v->type))) return GW_OK; // is_callable + if(fdef->builtin) return GW_OK; if ((!env->class_def || !GET_FLAG(env->class_def, final)) && !nspc_lookup_value0(env->curr, fdef->base->xid)) ERR_B(fdef->base->pos, @@ -686,7 +691,6 @@ ANN static m_bool _scan1_func_def(const Env env, const Func_Def fdef) { return ret; } - ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { const uint16_t depth = env->scope->depth; env->scope->depth = 0; @@ -697,6 +701,7 @@ ANN m_bool scan1_func_def(const Env env, const Func_Def fdef) { #define scan1_trait_def dummy_func #define scan1_extend_def dummy_func +#define scan1_prim_def dummy_func HANDLE_SECTION_FUNC(scan1, m_bool, Env) ANN static Type scan1_get_parent(const Env env, const Type_Def tdef) { diff --git a/src/parse/scan2.c b/src/parse/scan2.c index dcf04cfd..c7aefd8f 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -586,6 +586,7 @@ ANN m_bool scan2_func_def(const Env env, const Func_Def fdef) { #define scan2_enum_def dummy_func #define scan2_trait_def dummy_func #define scan2_extend_def dummy_func +#define scan2_prim_def dummy_func HANDLE_SECTION_FUNC(scan2, m_bool, Env) ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) { diff --git a/tests/primitive/access.gw b/tests/primitive/access.gw new file mode 100644 index 00000000..a632e7b9 --- /dev/null +++ b/tests/primitive/access.gw @@ -0,0 +1,4 @@ +#! [contains] true +var u8 u; +true :=> u[2]; +<<< u[2] >>>; diff --git a/tests/primitive/dyn_access.gw b/tests/primitive/dyn_access.gw new file mode 100644 index 00000000..d98ac5ce --- /dev/null +++ b/tests/primitive/dyn_access.gw @@ -0,0 +1,6 @@ +#! [contains] true +var u8 u; +2 :=> var int i; +true :=> u[i]; +<<< u >>>; +<<< u[i] >>>; diff --git a/tests/primitive/oob.gw b/tests/primitive/oob.gw new file mode 100644 index 00000000..b247d640 --- /dev/null +++ b/tests/primitive/oob.gw @@ -0,0 +1,4 @@ +#! [contains] OutOfBoundByteAccess +9 :=> var int i; +var u8 u; +u[i]; diff --git a/tests/primitive/static_oob.gw b/tests/primitive/static_oob.gw new file mode 100644 index 00000000..5e4498f3 --- /dev/null +++ b/tests/primitive/static_oob.gw @@ -0,0 +1,3 @@ +#! [contains] out of bound +var u8 u; +u[-3]; diff --git a/tests/primitive/too_many_exp.gw b/tests/primitive/too_many_exp.gw new file mode 100644 index 00000000..839f4b75 --- /dev/null +++ b/tests/primitive/too_many_exp.gw @@ -0,0 +1,3 @@ +#! [contains] too many expressions +var u8 u; +u[1][2]; -- 2.43.0