cd gwion-coverage-report
bash badge.sh
- - name: Make html mail
- uses: docker://pandoc/core:2.9
- with:
- args: "--from gfm --to html -o diff.html gwion-coverage-report/diff.md"
-
- name: Push Report
if: github.event_name == 'push'
run: |
branch=$(basename ${{ github.event.ref }})
- cp diff.html gwion-coverage-report/html/$branch
cd gwion-coverage-report
+ cp diff.md html/$branch
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git remote set-url origin https://${{ secrets.COVERAGE_TOKEN }}@github.com/Gwion/gwion-coverage-report.git
*.a
*.o
*.so
+*.gcda
+*.gcno
GWION_TEST_DIR ?= /tmp
GWION_PACKAGE=gwion
-CFLAGS += -DGWION_PACKAGE='"${GWION_PACKAGE}"'
src := $(wildcard src/*.c)
src += $(wildcard src/*/*.c)
test_dir_all := $(wildcard tests/*)
-test_ignore = tests/import
+test_ignore = tests/plug test/driver tests/module
test_dir := $(filter-out $(test_ignore), $(test_dir_all))
test_dir += examples
-Subproject commit 7a595b66afa08bb840222b7297e08e030e2232eb
+Subproject commit f75d51f0b87497057ccf739063a1a6b58fe3da2f
typedef struct Arg_ {
struct CArg arg;
+ struct Map_ mod;
struct Vector_ add;
struct Vector_ lib;
- struct Vector_ mod;
struct Vector_ config;
struct SoundInfo_ *si;
m_bool loop;
- m_bool read_stdin;
} Arg;
ANN void arg_release(Arg*);
ANN m_bool arg_parse(const Gwion, Arg*);
+ANN void arg_compile(const Gwion, Arg*);
#endif
#ifndef __ENGINE
#define __ENGINE
-ANN m_bool type_engine_init(const Gwion gwion, const Vector);
+ANN m_bool type_engine_init(const Gwion gwion);
#endif
Ast tree;
Nspc nspc;
struct Map_ lbls;
- HAS_OBJ
+ uint16_t ref;
m_bool error;
m_bool global;
};
-ANN2(2) ANEW Context new_context(MemPool p, const Ast, const m_str);
+ANN void free_context(const Context, struct Gwion_*const);
+ANN static inline void context_addref(const Context c) { ++c->ref; }
+ANN static inline void context_remref(const Context c, struct Gwion_ *const gwion) { if(!--c->ref) free_context(c, gwion); }
+ANN2(1,3) ANEW Context new_context(MemPool p, const Ast, const m_str);
ANN void load_context(const Context, const Env);
ANN void unload_context(const Context, const Env);
#endif
const envset_func func;
const void *data;
const m_int scope;
- const ae_flag flag;
+ const enum tflag flag;
m_bool run;
};
#ifndef __FUNC
#define __FUNC
+
+enum fflag {
+ fflag_none = 1 << 0,
+ fflag_pure = 1 << 1,
+ fflag_ftmpl = 1 << 2,
+ fflag_tmpl = 1 << 3,
+ fflag_valid = 1 << 4,
+} __attribute__((packed));
+
struct Func_ {
m_str name;
Func_Def def;
Value value_ref;
Func next;
size_t vt_index;
- HAS_OBJ
+ uint16_t ref;
ae_flag flag;
+ enum fflag fflag;
};
+ANN void free_func(const Func, struct Gwion_*const);
+ANN static inline void func_addref(const Func f) { ++f->ref; }
+ANN static inline void func_remref(const Func f, struct Gwion_ *const gwion) { if(!--f->ref) free_func(f, gwion); }
+
+static inline int fflag(const Func f, const enum fflag flag) {
+ return (f->fflag & flag) == flag;
+}
+#ifndef __cplusplus
+static inline void set_fflag(const Func f, const enum fflag flag) {
+ f->fflag |= flag;
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+ f->fflag &= ~flag;
+}
+#else
+static inline void set_fflag(const Func f, const enum fflag flag) {
+ const auto ff = f->fflag | flag;
+ f->fflag = static_cast<enum fflag>(ff);
+}
+
+static inline void unset_fflag(const Func f, const enum fflag flag) {
+ const auto ff = f->fflag & ~flag;
+ f->fflag = static_cast<enum fflag>(ff);
+}
+#endif
+
ANEW ANN Func new_func(MemPool, const m_str, const Func_Def);
ANN2(1,2) Symbol func_symbol(const Env, const m_str, const m_str, const m_str, const m_uint);
ANN m_bool check_lambda(const Env, const Type, Exp_Lambda*);
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr);
#endif
struct VM_Code_* pre_ctor;
struct VM_Code_* dtor;
struct NspcInfo_* info;
- HAS_OBJ
+ uint16_t ref;
};
+ANN void free_nspc(const Nspc, struct Gwion_*const);
+ANN static inline void nspc_addref(const Nspc n) { ++n->ref; }
+ANN static inline void nspc_remref(const Nspc n, struct Gwion_ *const gwion) { if(!--n->ref) free_nspc(n, gwion); }
extern ANEW ANN Nspc new_nspc(MemPool p, const m_str name);
extern ANN void nspc_commit(const Nspc);
#ifndef __OO
#define __OO
+typedef struct Gwion_ * Gwion;
+
typedef struct Type_ * Type;
typedef struct Nspc_ * Nspc;
typedef struct Value_ * Value;
typedef struct Func_ * Func;
-typedef struct RefCount_ {
- void (*free)(void*,void*);
- uint16_t count; // could be an unsigned short
-} RefCount;
-
-#define HAS_OBJ RefCount* ref;
-ANN static inline RefCount* new_refcount(MemPool mp, void(*free)(void*,void*)) {
- RefCount *ref = (RefCount*)mp_calloc(mp, RefCount);
- ref->count = 1;
- ref->free= free;
- return ref;
-}
-#define new_refcount(a, b) new_refcount(a, (void(*)(void*,void*))b)
-ANN static inline void rem_ref(MemPool mp, RefCount* a, void* ptr, void *gwion) {
- if(--a->count)
- return;
- a->free(ptr, gwion);
- mp_free(mp, RefCount, a);
-}
-#define ADD_REF(a) { ++(a)->ref->count; }
-#define REM_REF(a, b) { rem_ref(((Gwion)(b))->mp, (a)->ref, (a), (b)); }
#endif
Type parent;
Nspc owner;
Type owner_class;
- Class_Def def;
+ union {
+ Union_Def udef;
+ Class_Def cdef;
+ };
union type_data {
Func func;
Type base_type;
struct Context_ *ctx;
};
+enum tflag {
+ tflag_none = 1 << 0,
+ tflag_scan0 = 1 << 1,//
+ tflag_scan1 = 1 << 2,//
+ tflag_scan2 = 1 << 3,//
+ tflag_check = 1 << 4,//
+ tflag_emit = 1 << 5,//
+ tflag_infer = 1 << 6,
+ tflag_empty = 1 << 7,
+ tflag_ftmpl = 1 << 8,
+ tflag_ntmpl = 1 << 9, // do NOT need types
+ tflag_ctmpl = 1 << 10, // child template
+ tflag_udef = 1 << 11,
+ tflag_cdef = 1 << 12,
+ tflag_struct = 1 << 13,
+ tflag_ctor = 1 << 14,
+ tflag_dtor = 1 << 15,
+ tflag_tmpl = 1 << 16,
+ tflag_typedef = 1 << 17,
+ tflag_nonnull = 1 << 18,
+ tflag_force = 1 << 19,
+} __attribute__((packed));
+
struct Type_ {
m_str name;
Nspc nspc;
size_t xid;
size_t size;
size_t array_depth;
- HAS_OBJ
+ uint16_t ref;
ae_flag flag;
+ enum tflag tflag;
};
+ANN void free_type(const Type, struct Gwion_*const);
+ANN static inline void type_addref(const Type t) { ++t->ref; }
+ANN static inline void type_remref(const Type t, struct Gwion_ *const gwion) { if(!--t->ref) free_type(t, gwion); }
+ANN static inline int tflag(const Type t, const enum tflag flag) {
+ return (t->tflag & flag) == flag;
+}
+static inline int safe_tflag(const Type t, const enum tflag flag) {
+ return t ? ((t->tflag & flag) == flag) : 0;
+}
+#ifndef __cplusplus
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+ t->tflag |= flag;
+}
+#else
+ANN static inline void set_tflag(const Type t, const enum tflag flag) {
+ auto ff = t->tflag | flag;
+ t->tflag = static_cast<enum tflag>(ff);
+}
+#endif
ANN2(1,3) ANEW Type new_type(MemPool, const m_uint xid, const m_str name, const Type);
ANEW ANN Type type_copy(MemPool, const Type type);
ANN m_str get_type_name(const Env, const Type t, const m_uint);
__attribute__((returns_nonnull))
ANN Type get_type(const Type t);
ANN static inline int is_special(const Type t) {
- return GET_FLAG(t, nonnull) || GET_FLAG(t, force);
+ return tflag(t, tflag_nonnull) || tflag(t, tflag_force);
}
typedef enum {
size_t offset;
};
+enum vflag {
+ vflag_none = 1 << 0,
+ vflag_func = 1 << 1,
+ vflag_union = 1 << 2,
+ vflag_enum = 1 << 3,
+ vflag_freeme = 1 << 4,
+ vflag_fglobal = 1 << 5,
+ vflag_valid = 1 << 6,
+ vflag_direct = 1 << 7,
+ vflag_builtin = 1 << 8,
+ vflag_member = 1 << 9
+// vflag_used = 1 << 3
+} __attribute__((packed));
+
struct Value_ {
Type type;
m_str name;
m_uint* ptr;
Func func_ref;
} d;
- HAS_OBJ
+ uint16_t ref;
ae_flag flag;
+ enum vflag vflag;
};
+ANN void free_value(const Value, struct Gwion_*const);
+ANN static inline void value_addref(const Value v) { ++v->ref; }
+ANN static inline void value_remref(const Value v, struct Gwion_ *const gwion) { if(!--v->ref) free_value(v, gwion); }
+static inline int vflag(const Value v, const enum vflag flag) {
+ return (v->vflag & flag) == flag;
+}
+
+#ifndef __cplusplus
+static inline void set_vflag(const Value v, const enum vflag flag) {
+ v->vflag |= flag;
+}
+#else
+static inline void set_vflag(const Value v, const enum vflag flag) {
+ auto ff = v->vflag | flag;
+ v->vflag = static_cast<enum vflag>(ff);
+}
+#endif
+
ANEW ANN Value new_value(MemPool p, const Type type, const m_str name);
ANN void valuefrom(const Env, struct ValueFrom_*);
#endif
#define loc(gwi) loc_cpy(gwi->gwion->mp, gwi->loc)
struct Gwi_ {
- struct Gwion_* gwion;
+ struct Gwion_ *const gwion;
Ast body;
struct ImportCK *ck;
struct OperCK *oper; // _misc
static inline Tmpl* gwi_tmpl(const Gwi gwi) {
return new_tmpl_base(gwi->gwion->mp, gwi->ck->tmpl);
}
+
+ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi));
#endif
struct Vector_ child2;
struct Vector_ reserved;
struct Passes_ *passes;
- PlugInfo* plug;
+ struct Map_ plug;
} GwionData;
ANN GwionData* new_gwiondata(MemPool);
ANN2(1,2) Type gwi_struct_ini(const Gwi gwi, const m_str);
ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor);
ANN m_int gwi_class_end(const Gwi gwi);
+#define gwi_struct_end(a) gwi_class_end(a)
ANN void inherit(const Type);
#endif
ID_List curr;// enum
};
ae_flag flag; // ????
+ uint variadic;
enum importck_type type;
} ImportCK;
Nspc owner;
size_t vt_index;
Type_List tl;
+ void* xfun;// (type is f_xfun)
};
ANN void free_dottmpl(struct dottmpl_*);
ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt);
ANN m_uint union_push(const Env, const Union_Def);
ANN void union_pop(const Env, const Union_Def, const m_uint);
-ANN void union_flag(const Union_Def, const ae_flag);
+ANN void union_flag(const Union_Def, const enum tflag);
ANN m_bool check_stmt(const Env env, const Stmt stmt);
typedef m_bool (*_exp_func)(const void*, const void*);
}
#define env_body(a,b,c) env_body(a,b,(_exp_func)c)
-ANN m_bool scanx_cdef(const Env, void *,const Class_Def,
+ANN m_bool scanx_cdef(const Env, void *, const Type,
const _exp_func f_cdef, const _exp_func f_union);
-#define xxx_cdef(prefix) \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
- return scanx_cdef(env, env, cdef, \
- (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
+#define xxx_cdef(prefix) \
+static inline m_bool prefix##_cdef(const Env env, const Type t) { \
+ return scanx_cdef(env, env, t, \
+ (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
}
-#define xxx_cdef_flag(prefix) \
-static inline m_bool prefix##_cdef(const Env env, const Class_Def cdef) { \
- SET_FLAG(cdef, prefix); \
- return scanx_cdef(env, env, cdef, \
- (_exp_func)prefix##_class_def, (_exp_func)prefix##_union_def); \
-}
-xxx_cdef_flag(scan0)
-xxx_cdef_flag(scan1)
-xxx_cdef_flag(scan2)
-xxx_cdef_flag(check)
+xxx_cdef(scan0)
+xxx_cdef(scan1)
+xxx_cdef(scan2)
+xxx_cdef(check)
xxx_cdef(traverse)
ANN m_bool scanx_fdef(const Env, void *, const Func_Def, const _exp_func);
#ifndef __PLUG
#define __PLUG
-enum plug_t {
- GWPLUG_DL,
- GWPLUG_IMPORT,
- GWPLUG_MODULE,
- GWPLUG_LAST
-};
-
-typedef struct PlugInfo_ {
- struct Map_ drv;
- struct Vector_ vec[GWPLUG_LAST];
-} PlugInfo;
-
-ANN PlugInfo* new_pluginfo(MemPool, Vector);
-ANN void plug_run(const struct Gwion_*, const Vector);
+ANN m_bool plug_ini(const struct Gwion_*, const Vector);
+ANN m_bool driver_ini(const struct Gwion_*);
+ANN void plug_run(const struct Gwion_*, const Map);
ANN void free_plug(const struct Gwion_*);
ANN void* get_module(const struct Gwion_*, const m_str);
+ANN void set_module(const struct Gwion_ *gwion, const m_str name, void *const ptr);
+ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname);
+
#define GWIMPORT_NAME import
-#define GWMODSTR_NAME gwmodstr
#define GWMODINI_NAME gwmodini
#define GWMODEND_NAME gwmodend
-#define GWDRIVER_NAME gwmodend
-#define GWMODSTR(a) m_str GWMODSTR_NAME() { return #a; }
+#define GWDRIVER_NAME gwdriver
+#define GWDEPEND_NAME gwdepend
#define GWMODINI(a) ANN2(1) void* GWMODINI_NAME(const struct Gwion_ *gwion NUSED, const Vector args NUSED)
#define GWMODEND(a) ANN void GWMODEND_NAME(const struct Gwion_ *gwion NUSED, void* self NUSED)
#define GWDRIVER(a) ANN void GWDRIVER_NAME(DriverData* d)
+#define GWDEPEND ANN m_str const* GWDEPEND_NAME(void)
#endif
size_t stack_depth;
void* memoize;
m_str name;
- HAS_OBJ
+ uint16_t ref;
ae_flag flag;
+ int builtin;
};
typedef struct Shreduler_* Shreduler;
struct ShredTick_ * tick;
struct ShredInfo_ * info;
};
-ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const ae_flag, const m_str name);
+
+ANN void free_vm_code(const VM_Code, struct Gwion_*const);
+ANN static inline void vmcode_addref(const VM_Code c) { ++c->ref; }
+ANN static inline void vmcode_remref(const VM_Code c, struct Gwion_ *const gwion) { if(!--c->ref) free_vm_code(c, gwion); }
+ANN2(1,5) ANEW VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth, const int builtin, const m_str name);
ANN VM_Shred shreduler_get(const Shreduler s) __attribute__((hot));
ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool erase)__attribute__((hot));
-Subproject commit 3004e1d43e8cdfae9a4cdabaa372ab6e936e634c
+Subproject commit 300d07d9139a2580ade87bed2e23961c241116df
grep '\.sh' <<< "$(ls "$1")" &> /dev/null && found=1
if [ "$found" -eq 1 ]
then
- local old_async=$async
- async=0;
+# local old_async=$async
+# async=0;
# [ -f ${GWION_TEST_DIR}/${GWION_TEST_PREFIX}bailout ] && exit 1
for file in "$1"/*.sh
do
bash "$file" "$((n))"
n=$((n+count))
done
- async=$old_async
+# async=$old_async
fi
}
#include "gwion.h"
#include "arg.h"
#include "pass.h"
+#include "compile.h"
#define GWIONRC ".gwionrc"
return plug_dir;
}
+enum arg_type {
+ ARG_FILE,
+ ARG_STDIN,
+ ARG_DEFINE,
+ ARG_UNDEF,
+ ARG_INCLUDE
+};
+
ANN static void arg_init(Arg* arg) {
+ map_init(&arg->mod);
vector_init(&arg->add);
vector_init(&arg->lib);
- vector_init(&arg->mod);
vector_init(&arg->config);
vector_add(&arg->lib, (vtype)plug_dir());
}
ANN void arg_release(Arg* arg) {
+ map_release(&arg->mod);
vector_release(&arg->add);
xfree((m_str)vector_front(&arg->lib));
vector_release(&arg->lib);
- vector_release(&arg->mod);
config_end(&arg->config);
vector_release(&arg->config);
}
+ANN void arg_compile(const Gwion gwion, Arg *arg) {
+ const Vector v = &arg->add;
+ for(m_uint i = 0; i < vector_size(v); i++) {
+ switch(vector_at(v, i)) {
+ case ARG_FILE:
+ compile_filename(gwion, (m_str)VPTR(v, ++i));
+ break;
+ case ARG_STDIN:
+ compile_file(gwion, "stdin", stdin);
+ break;
+ case ARG_DEFINE:
+ pparg_add(gwion->ppa, (m_str)VPTR(v, ++i));
+ break;
+ case ARG_UNDEF:
+ pparg_rem(gwion->ppa, (m_str)VPTR(v, ++i));
+ break;
+ case ARG_INCLUDE:
+ pparg_inc(gwion->ppa, (m_str)VPTR(v, ++i));
+ break;
+ }
+ }
+}
+
static const char usage[] =
"usage: Gwion <options>\n"
" -h : this help\n"
free_vector(gwion->mp, v);
}
+ANN2(1) static void module_arg(const Map map, m_str str) {
+ m_str val = strchr(str, '=');
+ if(val) {
+ *val = '\0';
+ ++val;
+ }
+ map_set(map, (vtype)str, (vtype)val);
+}
+
ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
struct CArg *ca = &arg->arg;
for(ca->idx = 1; ca->idx < ca->argc; ++ca->idx) {
break;
case 'm':
CHECK_OB((tmp = option_argument(ca)))
- vector_add(&arg->mod, (vtype)tmp);
+ module_arg(&arg->mod, tmp);
break;
case 'l':
CHECK_OB((tmp = option_argument(ca)))
arg_set_pass(gwion, tmp);
break;
case '\0':
- arg->read_stdin = !arg->read_stdin;
+ vector_add(&arg->add, (vtype)ARG_STDIN);
+ break;
+ case 'D':
+ CHECK_OB((tmp = option_argument(ca)))
+ vector_add(&arg->add, (vtype)ARG_DEFINE);
+ vector_add(&arg->add, (vtype)tmp);
+ break;
+ case 'U':
+ CHECK_OB((tmp = option_argument(ca)))
+ vector_add(&arg->add, (vtype)ARG_UNDEF);
+ vector_add(&arg->add, (vtype)tmp);
+ break;
+ case 'I':
+ CHECK_OB((tmp = option_argument(ca)))
+ vector_add(&arg->add, (vtype)ARG_INCLUDE);
+ vector_add(&arg->add, (vtype)tmp);
break;
default:
gw_err(_("invalid arguments"));
return GW_ERROR;
}
} else
+{
+ vector_add(&arg->add, (vtype)ARG_FILE);
vector_add(&arg->add, (vtype)ca->argv[ca->idx]);
+}
}
return GW_OK;
}
if(b->array)
clean_array_sub(a, b->array);
if(a->scope && b->value)
- REM_REF(b->value, a->gwion)
+ value_remref(b->value, a->gwion);
}
ANN static void clean_var_decl_list(Clean *a, Var_Decl_List b) {
clean_exp(a, b->exp);
clean_stmt(a, b->body);
if(b->v)
- REM_REF(b->v, a->gwion)
+ value_remref(b->v, a->gwion);
--a->scope;
}
ANN static void clean_func_def(Clean *a, Func_Def b) {
clean_func_base(a, b->base);
++a->scope;
- if(b->d.code && !GET_FLAG(b->base, builtin))
+ if(b->d.code && !(b->base->func && vflag(b->base->func->value_ref, vflag_builtin)))
clean_stmt(a, b->d.code);
else
b->d.code = NULL;
ANN static void clean_fptr_def(Clean *a, Fptr_Def b) {
clean_func_base(a, b->base);
if(b->type)
- REM_REF(b->type, a->gwion)
+ type_remref(b->type, a->gwion);
}
ANN static void clean_type_def(Clean *a, Type_Def b) {
}
ANN static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) {
-// CHECK_BB(compiler_open(gwion->mp, c))
if(compiler_open(gwion->mp, c) < 0)
return 0;
if(_check(gwion, c) < 0) {
if(isa(t, emit->gwion->type[et_object]) > 0) {
const Instr instr = emit_add_instr(emit, ObjectRelease);
instr->m_val = offset + vector_at(&type->e->tuple->offset, i);
- } else if(GET_FLAG(t, struct))
+ } else if(tflag(t, tflag_struct))
struct_pop(emit, t, offset + vector_at(&type->e->tuple->offset, i));
}
}
Frame *frame = emit->code->frame;
DECL_OB(const Local*, l, = (Local*)vector_pop(&frame->stack))
frame->curr_offset -= l->type->size;
- if(GET_FLAG(l->type, struct)) {
+ if(tflag(l->type, tflag_struct)) {
struct_pop(emit, l->type, l->offset);
return frame_pop(emit);
}
ANN void emit_ext_ctor(const Emitter emit, const Type t);
ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
- if(!is_special(t) && GET_FLAG(t, ctor))
+ if(!is_special(t) && tflag(t, tflag_ctor))
emit_ext_ctor(emit, t);
}
if(type->e->parent)
emit_pre_ctor(emit, type->e->parent);
maybe_ctor(emit, type);
- if(GET_FLAG(type, typedef) && type->e->parent->array_depth)
- emit_array_extend(emit, type->e->parent, type->e->def->base.ext->array->exp);
+ if(tflag(type, tflag_typedef) && type->e->parent->array_depth)
+ emit_array_extend(emit, type->e->parent, type->e->cdef->base.ext->array->exp);
}
#define regxxx(name, instr) \
const m_uint start_index = emit_code_size(emit);
const Instr top = emit_add_instr(emit, ArrayTop);
top->m_val2 = (m_uint)type;
- if(GET_FLAG(type, struct)) {
+ if(tflag(type, tflag_struct)) {
const Instr instr = emit_add_instr(emit, ArrayStruct);
instr->m_val = type->size;
}
emit_pre_ctor(emit, type);
- if(!GET_FLAG(type, struct))
+ if(!tflag(type, tflag_struct))
emit_add_instr(emit, ArrayBottom);
else
regpop(emit, SZ_INT);
ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) {
const Value v = prim_self(data)->value;
- if(GET_FLAG(v, union)) {
+ if(vflag(v, vflag_direct)) {
const m_uint size = v->type->size;
const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), dotstatic);
instr->m_val = (m_uint)v->d.ptr;
}
if(v->from->owner_class)
return emit_symbol_owned(emit, data);
- if(GET_FLAG(v, builtin) || GET_FLAG(v, union) || GET_FLAG(v, enum))
+ if(vflag(v, vflag_builtin) || vflag(v, vflag_direct) || vflag(v, vflag_enum))
return emit_symbol_builtin(emit, data);
const m_uint size = v->type->size;
- const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !GET_FLAG(v, global) ? regpushmem : regpushbase);
+ const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase);
instr->m_val = v->from->offset;
return GW_OK;
}
}
ANN m_bool emit_array_access(const Emitter emit, struct ArrayAccessInfo *const info) {
- if(GET_FLAG(info->array.type, typedef)) {
+ if(tflag(info->array.type, tflag_typedef)) {
info->array.type = info->array.type->e->parent;
return emit_array_access(emit, info);
}
regseti(emit, (m_uint)e->info->type);
interp_size(emit, e->info->type);
const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
- if(isobj && !GET_FLAG(e->info->type, force))
+ if(isobj && !tflag(e->info->type, tflag_force))
emit_add_instr(emit, GackType);
const Instr instr = emit_add_instr(emit, Gack);
instr->m_val = emit_code_offset(emit);
}
ANN static inline int struct_ctor(const Value v) {
- return GET_FLAG(v->type, struct) && 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) {
const m_bool is_array = (array && array->exp) /*|| GET_FLAG(decl->td, force)*/;
const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
f_instr *exec = (f_instr*)allocmember;
- if(!GET_FLAG(v, member)) {
+ if(!vflag(v, vflag_member)) {
v->from->offset = emit_local(emit, type);
exec = (f_instr*)(allocword);
- if(GET_FLAG(v, ref)) { // ref or emit_var ?
+ if(GET_FLAG(decl->td, ref)) { // ref or emit_var ?
const Instr clean = emit_add_instr(emit, MemSetImm);
clean->m_val = v->from->offset;
}
}
- const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ?
+ const Instr instr = !(safe_tflag(emit->env->class_def, tflag_struct) && !emit->env->scope->depth) ?
emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
instr->m_val = v->from->offset;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
if(!emit_var)
emit_add_instr(emit, Assign);
else {
instr->m_val = -SZ_INT;
}
const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
- if(missing_depth && !GET_FLAG(decl->td, force)) {
+ if(missing_depth) {
const Instr push = emit_add_instr(emit, Reg2Reg);
push->m_val = -(missing_depth) * SZ_INT;
}
const m_bool is_array = array && array->exp;
const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref))
CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
const Instr instr = emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, dotstatic);
v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
- SET_FLAG(v, union);
+if(isa(type, emit->gwion->type[et_union]) < 0)
+ set_vflag(v, vflag_direct);// mpalloc
instr->m_val = (m_uint)v->d.ptr;
instr->m_val2 = v->type->size;
- if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
+ if(is_obj && (is_array || !is_ref) && !GET_FLAG(decl->td, ref)) {
const Instr assign = emit_add_instr(emit, Assign);
const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
- if(missing_depth && !GET_FLAG(decl->td, force)) {
+ if(missing_depth) {
const Instr push = emit_add_instr(emit, Reg2Reg);
push->m_val = -(missing_depth) * SZ_INT;
}
}
ANN static m_bool emit_class_def(const Emitter, const Class_Def);
-ANN static m_bool emit_cdef(const Emitter, const Class_Def);
+ANN static m_bool emit_cdef(const Emitter, const Type);
ANN static inline m_bool ensure_emit(const Emitter emit, const Type t) {
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+ .scope=emit->env->scope->depth, .flag=tflag_emit };
return envset_run(&es, t);
}
ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
const Type t = get_type(decl->type);
- if(!GET_FLAG(t, emit) && t->e->def)
+ if(!tflag(t, tflag_emit))
CHECK_BB(ensure_emit(emit, t))
const m_bool global = GET_FLAG(decl->td, global);
const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
CHECK_BB(emit_exp(emit, exp_call->args))
emit_exp_addref(emit, exp_call->args, -exp_totalsize(exp_call->args));
}
- if(exp_call->m_func && GET_FLAG(exp_call->m_func->def->base, variadic))
+ if(exp_call->m_func && fbflag(exp_call->m_func->def->base, fbflag_variadic))
emit_func_arg_vararg(emit, exp_call);
return GW_OK;
}
const Instr instr = emit_add_instr(emit, Reg2RegAddr);
instr->m_val = -SZ_INT;
instr->m_val2 = -SZ_INT;
- } else if(!exp_call->m_func && GET_FLAG(e->info->type, struct))
+ } else if(!exp_call->m_func && tflag(e->info->type, tflag_struct))
regpop(emit, SZ_INT);
return GW_OK;
}
ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
const m_uint scope = emit->env->scope->depth;
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=scope, .flag=ae_flag_emit };
+ .scope=scope, .flag=tflag_emit };
CHECK_BB(envset_push(&es, dt->owner_class, dt->owner))
(void)emit_push(emit, dt->owner_class, dt->owner);
const m_bool ret = traverse_emit_func_def(emit, dt->def);
const Value v = f->value_ref;
const size_t scope = emit->env->scope->depth;
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=scope, .flag=ae_flag_emit };
+ .scope=scope, .flag=tflag_emit };
CHECK_BB(envset_push(&es, v->from->owner_class, v->from->owner))
(void)emit_push(emit, v->from->owner_class, v->from->owner);
const m_bool ret = emit_func_def(emit, f->def);
}
ANN static void emit_args(const Emitter emit, const Func f) {
- const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+ const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
if((f->def->stack_depth - member) == SZ_INT) {
const Instr instr = emit_add_instr(emit, Reg2Mem);
instr->m_val = member;
ANN static Instr emit_call(const Emitter emit, const Func f) {
const Instr prelude = get_prelude(emit, f);
prelude->m_val = f->def->stack_depth;
- const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+ const m_uint member = vflag(f->value_ref, vflag_member) ? SZ_INT : 0;
if(member) {
const Instr instr = emit_add_instr(emit, Reg2Mem);
instr->m_val2 = f->def->stack_depth - SZ_INT;
}
ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
- if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
- if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) {
+ const int tmpl = fflag(f, fflag_tmpl);
+ if(!f->code || (fflag(f, fflag_ftmpl) && !vflag(f->value_ref, vflag_builtin))) {
+ if(tmpl && !is_fptr(emit->gwion, f->value_ref->type)) {
if(emit->env->func != f)
CHECK_BO(emit_template_code(emit, f))
else { // recursive function. (maybe should be used only for global funcs)
back->m_val = 0;
}
} else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
- if(GET_FLAG(f->def->base, op)) {
+ if(fbflag(f->def->base, fbflag_op)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
back->m_val = (m_uint)f;
} else {
instr->m_val2 = -SZ_INT;
}
}
- } else if((f->value_ref->from->owner_class && GET_FLAG(f->value_ref->from->owner_class, struct)) ||
- !f->value_ref->from->owner_class || (GET_FLAG(f, template) &&
+ } else if((f->value_ref->from->owner_class && tflag(f->value_ref->from->owner_class, tflag_struct)) ||
+ !f->value_ref->from->owner_class || (tmpl &&
!is_fptr(emit->gwion, f->value_ref->type)))
push_func_code(emit, f);
else if(vector_size(&emit->code->instr)) {
if((f_instr)(m_uint)back->opcode == DotFunc || (f_instr)(m_uint)back->opcode == DotStaticFunc)
back->m_val = f->vt_index;
}
- if(vector_size(&emit->code->instr) && GET_FLAG(f, member) &&
+ if(vector_size(&emit->code->instr) && vflag(f->value_ref, vflag_member) &&
is_fptr(emit->gwion, f->value_ref->type)) {
const Instr back = (Instr)vector_back(&emit->code->instr);
m_bit exec = back->opcode;
emit->code->stack_depth += SZ_INT;
}
-static inline void stack_alloc_this(const Emitter emit) {
- SET_FLAG(emit->code, member);
- stack_alloc(emit);
-}
-
static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
++emit->env->scope->depth;
emit_push_scope(emit);
}
ANN static m_bool call_spork_func(const Emitter emit, const Exp_Call *exp) {
- if(GET_FLAG(exp->m_func, member))
- SET_FLAG(emit->code, member);
return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR;
}
ANN static m_bool spork_prepare_code(const Emitter emit, const struct Sporker *sp) {
emit_add_instr(emit, RegPushImm);
push_spork_code(emit, sp->is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, sp->code->pos);
- if(SAFE_FLAG(emit->env->func, member))
- stack_alloc_this(emit);
+ if(emit->env->func && vflag(emit->env->func->value_ref, vflag_member))
+ stack_alloc(emit);
return scoped_stmt(emit, sp->code, 0);
}
ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
const Func f = sp->exp->d.exp_call.m_func;
- if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) {
+ if(vflag(f->value_ref, vflag_member) && is_fptr(emit->gwion, f->value_ref->type)) {
regpush(emit, SZ_INT*2);
// (re-)emit owner
if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot)
ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
const Type t = exp_self(unary)->info->type;
const Type base = get_type(actual_type(emit->gwion, t));
- if(base->e->def && !GET_FLAG(base, emit))
+ if(base->e->cdef && !tflag(base, tflag_emit)) // ???
CHECK_BB(ensure_emit(emit, base))
// no pos ?
struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda * lambda) {
CHECK_BB(emit_func_def(emit, lambda->def))
- if(GET_FLAG(lambda->def->base, member) && !exp_getvar(exp_self(lambda)))
+ if(vflag(lambda->def->base->func->value_ref, vflag_member) && !exp_getvar(exp_self(lambda)))
emit_add_instr(emit, RegPushMem);
regpushi(emit, (m_uint)lambda->def->base->func->code);
return GW_OK;
return GW_OK;
}
struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
- .scope=emit->env->scope->depth, .flag=ae_flag_emit };
+ .scope=emit->env->scope->depth, .flag=tflag_emit };
CHECK_BB(envset_push(&es, lambda->owner, lambda->def->base->func->value_ref->from->owner))
const m_bool ret = emit_lambda(emit, lambda);
if(es.run)
const Instr instr = emit_addref(emit, emit_var);
instr->m_val = size;
instr->m_val2 = vector_at(&type->e->tuple->offset, i);
- } else if(GET_FLAG(t, struct))
+ } else if(tflag(t, tflag_struct))
struct_addref(emit, t, size, offset + vector_at(&type->e->tuple->offset, i), emit_var);
}
}
(exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
const Instr instr = emit_addref(emit, exp_getvar(exp));
instr->m_val = size;
- } else if(GET_FLAG(exp->info->type, struct)) // check cast_to ?
+ } else if(tflag(exp->info->type, tflag_struct)) // check cast_to ?
struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
}
}
ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
- return tdef->type->e->def ? emit_class_def(emit, tdef->type->e->def) : GW_OK;
+ return tdef->type->e->cdef ? emit_class_def(emit, tdef->type->e->cdef) : GW_OK;
}
ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
if(global) {
const M_Object o = new_object(emit->gwion->mp, NULL, udef->value->type);
udef->value->d.ptr = (m_uint*)o;
- SET_FLAG(udef->value, builtin);
- UNSET_FLAG(udef->value, union);
+ set_vflag(udef->value, vflag_builtin);
}
scope = emit_push_type(emit, udef->value->type);
} else if(udef->type_xid) {
void* ptr = (void*)xcalloc(1, udef->s);
l = udef->l;
udef->value->d.ptr = ptr;
- SET_FLAG(udef->value, enum);
- SET_FLAG(udef->value, dtor);
+ udef->value->vflag |= (vflag_enum | vflag_freeme);
do {
Var_Decl_List list = l->self->d.exp_decl.list;
list->self->value->d.ptr = ptr;
- SET_FLAG(list->self->value, union);
+ set_vflag(list->self->value, vflag_direct);// xcalloc
} while((l = l->next));
- SET_FLAG(udef->l->self->d.exp_decl.list->self->value, enum);
- SET_FLAG(udef->l->self->d.exp_decl.list->self->value, dtor);
+ udef->l->self->d.exp_decl.list->self->value->vflag |= (vflag_enum | vflag_freeme);
}
if(udef->xid)
regpop(emit, SZ_INT);
emit_union_offset(udef->l, udef->o);
if(udef->xid || udef->type_xid || global)
emit_pop(emit, scope);
- union_flag(udef, ae_flag_emit);
+ union_flag(udef, tflag_emit);
return GW_OK;
}
instr->m_val = val;
}
vector_clear(&emit->code->stack_return);
- if(emit->info->memoize && GET_FLAG(emit->env->func, pure)) {
+ if(emit->info->memoize && fflag(emit->env->func, fflag_pure)) {
const Instr instr = emit_add_instr(emit, MemoizeStore);
instr->m_val = emit->env->func->def->stack_depth;
}
ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
if(f->def->base->xid == insert_symbol("@dtor")) {
emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC);
- ADD_REF(f->code)
+ vmcode_addref(f->code);
return f->code;
} else if(f->def->base->xid == insert_symbol("@gack")) {
regpop(emit, SZ_INT + f->value_ref->from->owner_class->size);
}
ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
- if(GET_FLAG(func->def->base, typedef))
+ if(fbflag(func->def->base, fbflag_internal))
return emit_internal(emit, func);
else
return finalyze(emit, FuncReturn);
ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
if(fdef->base->args)
emit_func_def_args(emit, fdef->base->args);
- if(GET_FLAG(fdef->base, variadic))
+ if(fbflag(fdef->base, fbflag_variadic))
stack_alloc(emit);
if(fdef->d.code)
CHECK_BB(scoped_stmt(emit, fdef->d.code, 1))
}
ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) {
- if(emit->info->memoize && GET_FLAG(fdef->base->func, pure))
+ if(emit->info->memoize && fflag(fdef->base->func, fflag_pure))
CHECK_BB(emit_memoize(emit, fdef))
CHECK_BB(emit_func_def_body(emit, fdef))
emit_func_def_return(emit);
func->code = emit_func_def_code(emit, func);
if(fdef_is_file_global(emit, fdef))
emit_func_def_global(emit, func->value_ref);
- if(emit->info->memoize && GET_FLAG(func, pure))
+ if(emit->info->memoize && fflag(func, fflag_pure))
func->code->memoize = memoize_ini(emit, func);
}
const Func former = emit->env->func;
if(func->code || tmpl_base(fdef->base->tmpl))
return GW_OK;
- if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
+ if(vflag(func->value_ref, vflag_builtin) && safe_tflag(emit->env->class_def, tflag_tmpl))
return GW_OK;
if(fdef_is_file_global(emit, fdef))
func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]);
emit_func_def_init(emit, func);
- if(GET_FLAG(func, member))
- stack_alloc_this(emit);
+ if(vflag(func->value_ref, vflag_member))
+ stack_alloc(emit);
emit->env->func = func;
emit_push_scope(emit);
if(!strcmp(s_name(fdef->base->xid), "@gack")) {
char c[len];
snprintf(c, len, "class %s", name);
emit_push_code(emit, c);
- stack_alloc_this(emit);
+ stack_alloc(emit);
return emit->code;
}
ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
const Type parent = cdef->base.type->e->parent;
- return !GET_FLAG(parent, emit) ? ensure_emit(emit, parent) : GW_OK;
+ return !tflag(parent, tflag_emit) ? ensure_emit(emit, parent) : GW_OK;
}
-ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
- return scanx_cdef(emit->env, emit, cdef,
+ANN static inline m_bool emit_cdef(const Emitter emit, const Type t) {
+ return scanx_cdef(emit->env, emit, t,
(_exp_func)emit_class_def, (_exp_func)emit_union_def);
}
-ANN void emit_class_finish(const Emitter emit, const Nspc nspc) {
- nspc->pre_ctor = finalyze(emit, FuncReturn);
- SET_FLAG(nspc->pre_ctor, ctor);
-}
-
ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
if(cdef->base.tmpl && cdef->base.tmpl->list)
CHECK_BB(template_push_types(emit->env, cdef->base.tmpl))
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(GET_FLAG(t, emit))
+ if(tflag(t, tflag_emit))
return GW_OK;
- SET_FLAG(t, emit);
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, emit))
+ set_tflag(t, tflag_emit);
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_emit))
CHECK_BB(ensure_emit(emit, t->e->owner_class))
- if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
+ if(cdef->base.ext && t->e->parent->e->cdef && !tflag(t->e->parent, tflag_emit)) // ?????
CHECK_BB(cdef_parent(emit, cdef))
nspc_allocdata(emit->gwion->mp, t->nspc);
if(cdef->body) {
emit_class_code(emit, t->name);
if(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit) > 0)
- emit_class_finish(emit, t->nspc);
+ t->nspc->pre_ctor = finalyze(emit, FuncReturn);
else {
free_code(emit->gwion->mp, emit->code);
emit_pop_code(emit);
static ANEW ANN VM_Code emit_code(const Emitter emit) {
Code* const c = emit->code;
- const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth,
- c->flag, c->name);
+ const VM_Code code = new_vm_code(emit->gwion->mp, &c->instr, c->stack_depth, 0, c->name);
return code;
}
#include "vm.h"
#include "gwion.h"
-ANN static void free_context(const Context a, Gwion gwion) {
- REM_REF(a->nspc, gwion)
+ANN void free_context(const Context a, Gwion gwion) {
+ nspc_remref(a->nspc, gwion);
free_mstr(gwion->mp, a->name);
mp_free(gwion->mp, Context, a);
}
context->name = mstrdup(p, str);
context->nspc = new_nspc(p, context->name);
context->tree = ast;
- context->ref = new_refcount(p, free_context);
+ context->ref = 1;
return context;
}
ANN void load_context(const Context context, const Env env) {
- ADD_REF((env->context = context))
+ context_addref((env->context = context));
vector_add(&env->scope->nspc_stack, (vtype)env->curr);
context->nspc->parent = env->curr;
env->curr = context->nspc;
free_map(env->gwion->mp, (Map)map_at(&context->lbls, i));
map_release(&context->lbls);
}
- REM_REF(context, env->gwion)
+ context_remref(context, env->gwion);
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
}
ANN void release_ctx(struct Env_Scope_ *a, struct Gwion_ *gwion) {
const m_uint size = vector_size(&a->known_ctx);
for(m_uint i = size + 1; --i;)
- REM_REF((Context)vector_at(&a->known_ctx, i - 1), gwion);
+ context_remref((Context)vector_at(&a->known_ctx, i - 1), gwion);
}
ANN static void free_env_scope(struct Env_Scope_ *a, Gwion gwion) {
}
ANN void env_add_type(const Env env, const Type type) {
- const Type v_type = type_copy(env->gwion->mp, env->gwion->type[et_class]);
- ADD_REF(v_type);
- v_type->e->d.base_type = type;
- SET_FLAG(type, builtin);
+ type->e->owner = env->curr;
+ type->e->owner_class = env->class_def; // t owner_class ?
const Symbol sym = insert_symbol(type->name);
nspc_add_type_front(env->curr, sym, type);
- const Value v = new_value(env->gwion->mp, v_type, s_name(sym));
- SET_FLAG(v, valid | ae_flag_const | ae_flag_global | ae_flag_builtin);
- nspc_add_value(env->curr, insert_symbol(type->name), v);
- v->from->owner = type->e->owner = env->curr;
- v->from->owner_class = type->e->owner_class = env->class_def; // t owner_class ?
+ const Value v = mk_class(env, type);
+ SET_FLAG(v, global);
+ set_vflag(v, vflag_builtin);
+ set_tflag(type, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
type->xid = ++env->scope->type_xid;
}
if(ret > 0 || env->context->global)
vector_add(&env->scope->known_ctx, (vtype)ctx);
else //nspc_rollback(env->global_nspc);
- REM_REF(ctx, env->gwion);
+ context_remref(ctx, env->gwion);
unload_context(ctx, env);
return ret;
}
t->e->parent = t_class;
t->e->ctx = base->e->ctx;
t->e->d.base_type = base;
- SET_FLAG(t, infer);
+ set_tflag(t, tflag_infer);
return t;
}
const Symbol sym = insert_symbol(base->name);
const Value v = new_value(env->gwion->mp, t, s_name(sym));
valuefrom(env, v->from);
- SET_FLAG(v, const | ae_flag_valid);
+ SET_FLAG(v, const);
+ set_vflag(v, vflag_valid);
nspc_add_value_front(base->e->owner, sym, v);
return v;
}
}
ANN static m_bool push(struct EnvSet *es, const Type t) {
+ es->env->scope->depth = 0;
if(t->e->owner_class)
CHECK_BB(push(es, t->e->owner_class))
else
env_push(es->env, NULL, t->e->ctx ? t->e->ctx->nspc : es->env->curr);
- if(es->func && !(t->flag & es->flag))
- CHECK_BB(es->func((void*)es->data, t->e->def))
- if(GET_FLAG(t, template))
- CHECK_BB(template_push_types(es->env, t->e->def->base.tmpl))
+ if(es->func && !(t->tflag & es->flag))
+ CHECK_BB(es->func((void*)es->data, t))
+ if(tflag(t, tflag_tmpl))
+ CHECK_BB(template_push_types(es->env, t->e->cdef->base.tmpl)) // incorrect templates
env_push_type((void*)es->env, t);
return GW_OK;
}
env_pop(es->env, es->scope);
if(!t)
return;
- if(GET_FLAG(t, template))
+ if(tflag(t, tflag_tmpl))
nspc_pop_type(es->env->gwion->mp, es->env->curr);
if(t->e->owner_class)
envset_pop(es, t->e->owner_class);
check(es, t);
if(es->run)
CHECK_BB(push(es, t->e->owner_class))
- const m_bool ret = !(t->flag & es->flag) ?
- es->func(es->data, t->e->def) : GW_OK;
+ const m_bool ret = t->e->cdef &&
+ !(t->tflag & es->flag) ?
+ es->func(es->data, t) : GW_OK;
if(es->run)
envset_pop(es, t->e->owner_class);
return ret;
#include "gwion.h"
#include "clean.h"
-ANN static void free_func(Func a, Gwion gwion) {
- if(GET_FLAG(a, template))
+ANN void free_func(Func a, Gwion gwion) {
+ if(fflag(a, fflag_tmpl))
func_def_cleaner(gwion, a->def);
if(a->code)
- REM_REF(a->code, gwion);
+ vmcode_remref(a->code, gwion);
mp_free(gwion->mp, Func, a);
}
Func func = mp_calloc(p, Func);
func->name = name;
func->def = def;
- func->ref = new_refcount(p, free_func);
+ func->ref = 1;
return func;
}
i, nspc))
return insert_symbol(env->gwion->st, name);
}
+
+ANN void builtin_func(const MemPool mp, const Func f, void* func_ptr) {
+ set_vflag(f->value_ref, vflag_builtin);
+ f->code = new_vm_code(mp, NULL, f->def->stack_depth, 1, f->name);
+ f->code->native_func = (m_uint)func_ptr;
+}
}
ANN static inline void nspc_release_object(const Nspc a, Value value, Gwion gwion) {
- if(!GET_FLAG(value, pure) && ((GET_FLAG(value, static) && a->info->class_data) ||
- (value->d.ptr && GET_FLAG(value, builtin)))) {
+ if(!vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+ (value->d.ptr && vflag(value, vflag_builtin)))) {
const M_Object obj = value->d.ptr ? (M_Object)value->d.ptr :
*(M_Object*)(a->info->class_data + value->from->offset);
release(obj, gwion->vm->cleaner_shred);
}
ANN2(1,3) static inline void nspc_release_struct(const Nspc a, Value value, Gwion gwion) {
- if(!SAFE_FLAG(value, pure) && ((SAFE_FLAG(value, static) && a->info->class_data) ||
- (SAFE_FLAG(value, builtin) && value->d.ptr))) {
+ if(value && !vflag(value, vflag_union) && ((GET_FLAG(value, static) && a->info->class_data) ||
+ (vflag(value, vflag_builtin) && value->d.ptr))) {
const m_bit *ptr = (value && value->d.ptr) ? (m_bit*)value->d.ptr:
(m_bit*)(a->info->class_data + value->from->offset);
for(m_uint i = 0; i < vector_size(&value->type->e->tuple->types); ++i) {
const Type t = (Type)vector_at(&value->type->e->tuple->types, i);
if(isa(t, gwion->type[et_object]) > 0)
release(*(M_Object*)(ptr + vector_at(&value->type->e->tuple->offset, i)), gwion->vm->cleaner_shred);
- else if(GET_FLAG(t, struct))
+ else if(tflag(t, tflag_struct))
nspc_release_struct(t->nspc, NULL, gwion);
}
}
while(scope_iter(&iter, &v) > 0) {
if(isa(v->type, gwion->type[et_object]) > 0)
nspc_release_object(a, v, gwion);
- else if(GET_FLAG(v->type, struct))
+ else if(tflag(v->type, tflag_struct))
nspc_release_struct(a, v, gwion);
- REM_REF(v, gwion);
+ value_remref(v, gwion);
}
free_scope(gwion->mp, a->info->value);
}
struct scope_iter iter = { n->info->b, 0, 0 };\
A a;\
while(scope_iter(&iter, &a) > 0) \
- REM_REF(a, gwion);\
+ b##_remref(a, gwion);\
free_scope(gwion->mp, n->info->b);\
}
describe_nspc_free(Func, func)
describe_nspc_free(Type, type)
-ANN static void free_nspc(Nspc a, Gwion gwion) {
+ANN void free_nspc(const Nspc a, const Gwion gwion) {
free_nspc_value(a, gwion);
nspc_free_func(a, gwion);
if(a->info->op_map.ptr)
vector_release(&a->info->vtable);
mp_free(gwion->mp, NspcInfo, a->info);
if(a->pre_ctor)
- REM_REF(a->pre_ctor, gwion);
+ vmcode_remref(a->pre_ctor, gwion);
if(a->dtor)
- REM_REF(a->dtor, gwion);
+ vmcode_remref(a->dtor, gwion);
mp_free(gwion->mp, Nspc, a);
}
a->info->value = new_scope(p);
a->info->type = new_scope(p);
a->info->func = new_scope(p);
- a->ref = new_refcount(p, free_nspc);
+ a->ref = 1;
return a;
}
const Vector v = &env->class_def->e->tuple->contains;
const m_int idx = vector_size(v) ? vector_find(v, (vtype)t) : -1;
if(idx == -1) {
- ADD_REF(t);
+ type_addref(t);
vector_add(v, (vtype)t);
}
}
ANN void free_tupleform(const TupleForm tuple, const struct Gwion_ *gwion) {
for(m_uint i = 0; i < vector_size(&tuple->contains); ++i)
- REM_REF((Type)vector_at(&tuple->contains, i), (void*)gwion);
+ type_remref((Type)vector_at(&tuple->contains, i), (void*)gwion);
vector_release(&tuple->contains);
vector_release(&tuple->types);
vector_release(&tuple->offset);
#include "object.h"
ANN static inline m_bool freeable(const Type a) {
- return !GET_FLAG(a, nonnull) && GET_FLAG(a, template);
+ return !(tflag(a, tflag_force) || tflag(a, tflag_nonnull)) && (tflag(a, tflag_tmpl) ||GET_FLAG(a, global));
}
-ANN static void free_type(Type a, Gwion gwion) {
+ANN void free_type(const Type a, struct Gwion_ *const gwion) {
if(freeable(a)) {
- if(GET_FLAG(a, union)) {
- if(a->e->def->union_def) {
- if(!GET_FLAG(a, pure))
- free_union_def(gwion->mp, a->e->def->union_def);
- else
- free_decl_list(gwion->mp, a->e->def->list);
- }
- a->e->def->union_def = NULL;
- }
- if(a->e->def)
- class_def_cleaner(gwion, a->e->def);
+ if(tflag(a, tflag_udef))
+ free_union_def(gwion->mp, a->e->udef);
+ if(tflag(a, tflag_cdef))
+ class_def_cleaner(gwion, a->e->cdef);
}
if(a->nspc)
- REM_REF(a->nspc, gwion);
+ nspc_remref(a->nspc, gwion);
if(a->e->tuple)
free_tupleform(a->e->tuple, gwion);
mp_free(gwion->mp, TypeInfo, a->e);
mp_free(gwion->mp, Type, a);
+
}
Type new_type(MemPool p, const m_uint xid, const m_str name, const Type parent) {
type->e->parent = parent;
if(parent)
type->size = parent->size;
- type->ref = new_refcount(p, free_type);
+ type->ref = 1;
return type;
}
//describe_find(func, Func)
ANN Type typedef_base(Type t) {
- while(GET_FLAG(t, typedef))
+ while(tflag(t, tflag_typedef))
t = t->e->parent;
return t;
}
inherit(t);
t->nspc->info->class_data_size = SZ_INT;
nspc_allocdata(env->gwion->mp, t->nspc);
- *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !GET_FLAG(src, struct)) ?
+ *(f_release**)(t->nspc->info->class_data) = (depth > 1 || !tflag(src, tflag_struct)) ?
object_release : struct_release;
} else
- ADD_REF((t->nspc = env->gwion->type[et_array]->nspc))
- SET_FLAG(t, valid);
+ nspc_addref((t->nspc = env->gwion->type[et_array]->nspc));
mk_class(env, t);
nspc_add_type_front(src->e->owner, sym, t);
return t;
ANN m_bool type_ref(Type t) {
do {
- if(GET_FLAG(t, empty))
+ if(tflag(t, tflag_empty))
return GW_OK;
- if(GET_FLAG(t, typedef) && t->e->def)
- if(t->e->def->base.ext && t->e->def->base.ext->array) {
- if(!t->e->def->base.ext->array->exp)
+ if(tflag(t, tflag_typedef) && t->e->cdef)
+ if(t->e->cdef->base.ext && t->e->cdef->base.ext->array) {
+ if(!t->e->cdef->base.ext->array->exp)
return GW_OK;
else {
const Type type = t->e->parent->e->d.base_type;
- if(SAFE_FLAG(type, empty))
+ if(tflag(type, tflag_empty))
return GW_OK;
}
}
static m_str const special_name[] = { "^nonnull", "^force" };
#define SPECIAL_LEN strlen(special_name[0]) + strlen(special_name[1])
-static const ae_flag special_flag[] = { ae_flag_nonnull, ae_flag_force };
+static const enum tflag special_flag[] = { tflag_nonnull, tflag_force };
typedef struct {
const Type type;
Symbol name;
- ae_flag flag;
+ enum tflag flag;
uint st_type;
} SpecialType;
ANN static Type specialtype_create(const Env env, const SpecialType *s) {
const Type t = type_copy(env->gwion->mp, s->type);
if(t->nspc)
- ADD_REF(t->nspc)
+ nspc_addref(t->nspc);
t->name = s_name(s->name);
- t->flag = s->type->flag | s->flag;
+ t->flag = s->type->flag;
+ t->tflag |= s->type->tflag | s->flag;
t->e->parent = unflag_type(s->type);
nspc_add_type_front(s->type->e->owner, s->name, t);
mk_class(env, t);
return t;
}
-static inline int get_flag(const Type t, const ae_flag flag) {
- return (t->flag & flag) == flag;
+static inline int get_flag(const Type t, const enum tflag flag) {
+ return (t->tflag & flag) == flag;
}
ANN static void specialtype_flag(SpecialType *s, m_str c, const uint i) {
- const ae_flag flag = special_flag[i];
+ const enum tflag flag = special_flag[i];
if(i == s->st_type || get_flag(s->type, flag)) {
strcat(c, special_name[i]);
s->flag |= flag;
#include "vm.h"
#include "gwion.h"
-ANN static void free_value(Value a, Gwion gwion) {
+ANN void free_value(Value a, Gwion gwion) {
const Type t = a->type;
- if(!GET_FLAG(a, func) && a->d.ptr && !GET_FLAG(a, union) &&
- !(GET_FLAG(a, enum) && GET_FLAG(a, builtin) && a->from->owner_class)
+ if(!vflag(a, vflag_func) && a->d.ptr && !vflag(a, vflag_direct) &&
+ !(vflag(a, vflag_enum) && vflag(a, vflag_builtin) && a->from->owner_class)
&& isa(t, gwion->type[et_object]) < 0)
_mp_free(gwion->mp, t->size, a->d.ptr);
- else if(GET_FLAG(a, enum) && GET_FLAG(a, dtor))
+ else if(vflag(a, vflag_freeme))
xfree(a->d.ptr);
if(is_class(gwion, t))
- REM_REF(t, gwion)
+ type_remref(t, gwion);
mp_free(gwion->mp, ValueFrom, a->from);
mp_free(gwion->mp, Value, a);
}
a->from = mp_calloc(p, ValueFrom);
a->type = type;
a->name = name;
- a->ref = new_refcount(p, free_value);
+ a->ref = 1;
return a;
}
#include "pass.h" // fork_clean
#include "shreduler_private.h"
-ANN static void driver_arg(const Gwion gwion, Driver *di) {
- for(m_uint i = 0; i < map_size(&gwion->data->plug->drv); ++i) {
- const m_str name = (m_str)VKEY(&gwion->data->plug->drv, i);
- const size_t len = strlen(name);
- if(!strncmp(name, di->si->arg, len)) {
- di->func = (f_bbqset)VVAL(&gwion->data->plug->drv, i);
- break;
- }
- }
-}
-
ANN m_bool gwion_audio(const Gwion gwion) {
Driver *const di = gwion->vm->bbq;
if(di->si->arg)
- driver_arg(gwion, di);
+ driver_ini(gwion);
di->func(di->driver);
CHECK_BB(di->driver->ini(gwion->vm, di));
driver_alloc(di);
}
ANN static inline m_bool gwion_engine(const Gwion gwion) {
- return type_engine_init(gwion, &gwion->data->plug->vec[GWPLUG_IMPORT]) > 0;
-}
-
-ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
- for(m_uint i = 0; i < vector_size(v); i++)
- compile_filename(gwion, (m_str)vector_at(v, i));
+ return type_engine_init(gwion) > 0;
}
ANN static void gwion_cleaner(const Gwion gwion) {
- const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
+ const VM_Code code = new_vm_code(gwion->mp, NULL, 0, 1, "in code dtor");
gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
}
}
ANN static m_bool gwion_ok(const Gwion gwion, Arg* arg) {
- gwion->data->plug = new_pluginfo(gwion->mp, &arg->lib);
+ CHECK_BB(plug_ini(gwion, &arg->lib))
shreduler_set_loop(gwion->vm->shreduler, arg->loop);
if(gwion_audio(gwion) > 0) {
plug_run(gwion, &arg->mod);
if(gwion_engine(gwion)) {
gwion_cleaner(gwion);
- gwion_compile(gwion, &arg->add);
- if(arg->read_stdin)
- compile_file(gwion, "stdin", stdin);
+ (void)arg_compile(gwion, arg);
return GW_OK;
}
}
ANN Nspc pop_global(struct Gwion_ *gwion) {
const Nspc nspc = gwion->env->global_nspc->parent;
- REM_REF(gwion->env->global_nspc, gwion)
+ nspc_remref(gwion->env->global_nspc, gwion);
return gwion->env->curr = gwion->env->global_nspc = nspc;
}
map_release(&data->id);
vector_release(&data->reserved);
free_passes(gwion->mp, data->passes);
- if(data->plug)
+ if(data->plug.ptr)
free_plug(gwion);
free_gwiondata_cpy(gwion->mp, data);
}
#include "specialid.h"
#include "template.h"
-ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const ae_flag e) {
- VM_Code* code = e == ae_flag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
+ANN static m_bool mk_xtor(MemPool p, const Type type, const m_uint d, const enum tflag e) {
+ VM_Code* code = e == tflag_ctor ? &type->nspc->pre_ctor : &type->nspc->dtor;
const m_str name = type->name;
- *code = new_vm_code(p, NULL, SZ_INT, e | ae_flag_member | ae_flag_builtin, name);
+ *code = new_vm_code(p, NULL, SZ_INT, 1, name);
(*code)->native_func = (m_uint)d;
- type->flag |= e;
+ type->tflag |= e;
return GW_OK;
}
ANN2(1,2) static inline m_bool class_parent(const Env env, Type t) {
do {
- if(GET_FLAG(t, valid))
+ if(tflag(t, tflag_check))
break;
- if(t->e->def)
- CHECK_BB(traverse_class_def(env, t->e->def))
+ if(t->e->cdef)
+ CHECK_BB(traverse_class_def(env, t->e->cdef))
} while((t = t->e->parent));
return GW_OK;
}
inherit(t);
t->e->owner = env->curr;
t->e->owner_class = env->class_def;
- SET_FLAG(t, valid);
env_push_type(env, t);
}
ANN2(1) void gwi_class_xtor(const Gwi gwi, const f_xtor ctor, const f_xtor dtor) {
const Type t = gwi->gwion->env->class_def;
if(ctor)
- mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, ae_flag_ctor);
+ mk_xtor(gwi->gwion->mp, t, (m_uint)ctor, tflag_ctor);
if(dtor)
- mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, ae_flag_dtor);
+ mk_xtor(gwi->gwion->mp, t, (m_uint)dtor, tflag_dtor);
}
ANN static inline void gwi_type_flag(const Type t) {
- SET_FLAG(t, scan1 | ae_flag_scan2 | ae_flag_check | ae_flag_emit);
+ set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
}
ANN static Type type_finish(const Gwi gwi, const Type t) {
CHECK_BO(template_push_types(gwi->gwion->env, tmpl))
const Type base = find_type(gwi->gwion->env, td);
const Type_List tl = td->types;
- if(GET_FLAG(base, unary))
+ if(tflag(base, tflag_ntmpl))
td->types = NULL;
const Type p = !td->types ? handle_class(gwi, td) : NULL;
td->types = tl;
nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
CHECK_OO(p)
const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, s_name(ck.sym), p);
- t->e->def = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
- t->e->def->base.tmpl = tmpl;
- t->e->def->base.type = t;
+ t->e->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
+ t->e->cdef->base.tmpl = tmpl;
+ t->e->cdef->base.type = t;
t->e->tuple = new_tupleform(gwi->gwion->mp, p);
t->e->parent = p;
if(td->array)
- SET_FLAG(t, typedef);
+ set_tflag(t, tflag_typedef);
if(ck.tmpl)
- SET_FLAG(t, template);
+ set_tflag(t, tflag_tmpl);
else
gwi_type_flag(t);
return type_finish(gwi, t);
const Type t = new_type(gwi->gwion->mp, ++gwi->gwion->env->scope->type_xid, name, gwi->gwion->type[et_compound]);
t->e->tuple = new_tupleform(gwi->gwion->mp, NULL);
gwi_type_flag(t);
- SET_FLAG(t, struct);
+ set_tflag(t, tflag_struct);
return type_finish(gwi, t);
}
ANN Type str2type(const Gwion gwion, const m_str str, const loc_t pos) {
DECL_OO(Type_Decl *, td, = str2decl(gwion, str, pos))
const Type t = known_type(gwion->env, td);
- if(t)
- return t;
free_type_decl(gwion->mp, td);
- return NULL;
+ return t;
}
ANN static inline m_bool ac_finish(const Gwion gwion, const struct AC *ac) {
for(m_uint i = 0; i < vector_size(v); i++) {
const Value value = (Value)vector_at(v, i);
const m_uint addr = vector_at(&ck->v, i);
- SET_FLAG(value, builtin);
+ set_vflag(value, vflag_builtin);
// ADD_REF(value->type); // what ?
if(!gwi->gwion->env->class_def)
value->d.ptr = (m_uint*)(addr ? addr : i);
ANEW ANN static Func_Base* gwi_func_base(const Gwi gwi, ImportCK *ck) {
const Arg_List arg_list = make_dll_arg_list(&gwi->ck->v);
- Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag | ae_flag_builtin);
+ Func_Base *base = new_func_base(gwi->gwion->mp, ck->td, ck->sym, arg_list, ck->flag);
+ if(ck->variadic)
+ base->fbflag |= fbflag_variadic;
ck->td = NULL;
if(ck->tmpl) {
base->tmpl = gwi_tmpl(gwi);
ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
Func_Base* base = gwi_func_base(gwi, ck);
const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, loc(gwi));
- fdef->d.dl_func_ptr = (void*)(m_uint)ck->addr;
- if(base->tmpl)
- SET_FLAG(fdef->base, template);
return fdef;
}
ANN m_int gwi_func_valid(const Gwi gwi, ImportCK *ck) {
const Func_Def fdef = import_fdef(gwi, ck);
- if(SAFE_FLAG(gwi->gwion->env->class_def, template))
+ if(safe_tflag(gwi->gwion->env->class_def, tflag_tmpl))
/*return*/ section_fdef(gwi, fdef);
if(traverse_func_def(gwi->gwion->env, fdef) < 0)
return error_fdef(gwi, fdef);
+ builtin_func(gwi->gwion->mp, fdef->base->func, ck->addr);
ck_end(gwi);
return GW_OK;
}
ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) {
CHECK_BB(ck_ok(gwi, ck_fdef))
+ if(gwi->ck->variadic)
+ GWI_ERR_B(_("already declared as variadic"));
+ if(!strcmp(n, "...")) {
+ gwi->ck->variadic = 1;
+ return GW_OK;
+ }
DECL_OB(Type_Decl*, td, = gwi_str2decl(gwi, t))
const Var_Decl var = gwi_str2var(gwi, n);
if(var) {
vector_add(&gwi->ck->v, (vtype)arg);
return GW_OK;
}
- free_type_decl(gwi->gwion->mp, td);
+ free_type_decl(gwi->gwion->mp, td); // ???
return GW_ERROR;
}
// what happens if it is in a template class ?
const m_bool ret = traverse_fptr_def(gwi->gwion->env, fptr);
if(fptr->base->func) // is it needed ?
- SET_FLAG(fptr->base->func, builtin);
+ set_vflag(fptr->base->func->value_ref, vflag_builtin);
const Type t = ret > 0 ? fptr->type : NULL;
free_fptr_def(gwi->gwion->mp, fptr);
if(fptr->type)
- REM_REF(fptr->type, gwi->gwion)
+ type_remref(fptr->type, gwi->gwion);
ck_end(gwi);
return t;
}
#include "gwi.h"
void gwi_body(const Gwi gwi, const Ast body) {
- const Class_Def cdef = gwi->gwion->env->class_def->e->def;
+ const Class_Def cdef = gwi->gwion->env->class_def->e->cdef;
if(!cdef->body)
cdef->body = body;
else
}
env_reset(gwi->gwion->env);
}
+
+ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
+ const m_str name = gwion->env->name;
+ struct loc_t_ loc = {};
+ OperCK oper = {};
+ struct Gwi_ gwi = { .gwion=gwion, .loc=&loc, .oper=&oper };
+ const m_bool ret = f(&gwi);
+ if(ret < 0)
+ gwi_reset(&gwi);
+ gwion->env->name = name;
+ return ret;
+}
const Env env = gwi->gwion->env;
gwi->ck->exp->d.exp_decl.list->self->addr = (m_uint*)addr;
gwi->ck->exp->d.exp_decl.td->flag = flag;
- if(env->class_def && GET_FLAG(env->class_def, template))
+ if(env->class_def && tflag(env->class_def, tflag_tmpl))
return gwi_item_tmpl(gwi);
CHECK_BB(traverse_exp(env, gwi->ck->exp))
const Value value = gwi->ck->exp->d.exp_decl.list->self->value;
- SET_FLAG(value, builtin);
+ set_vflag(value, vflag_builtin);
+ if(!env->class_def)
+ SET_FLAG(value, global);
const m_uint offset = value->from->offset;
free_exp(gwi->gwion->mp, gwi->ck->exp);
ck_end(gwi);
}
ANN static m_bool mk_gack(MemPool p, const Type type, const f_gack d) {
- const VM_Code code = new_vm_code(p, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@gack");
+ const VM_Code code = new_vm_code(p, NULL, SZ_INT, 1, "@gack");
code->native_func = (m_uint)d;
- SET_FLAG(code, builtin);
type->e->gack = code;
return GW_OK;
}
gwi->ck->tmpl = NULL;
const m_bool ret = traverse_type_def(gwi->gwion->env, tdef);
const Type t = tdef->type;
+ set_tflag(t, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
free_type_def(gwi->gwion->mp, tdef);
ck_end(gwi);
return ret > 0 ? t : NULL;
gwi->gwion->env->class_def->nspc->info->offset =
udef->o + udef->s;
if(udef->xid || !udef->type_xid) {
- SET_FLAG(udef->value, builtin);
+ set_vflag(udef->value, vflag_builtin);
const M_Object o = new_object(gwi->gwion->mp, NULL, udef->value->type);
udef->value->d.ptr = (m_uint*)o;
return udef->value->type;
gwi->ck->tmpl = NULL;
}
const Type t = union_type(gwi, udef);
- if(!SAFE_FLAG(t, template))
+ if(!safe_tflag(t, tflag_tmpl))
free_union_def(gwi->gwion->mp, udef);
ck_end(gwi);
return t;
OP_EMIT(opem_object_dot);
ANN static m_bool import_core_libs(const Gwi gwi) {
const Type t_class = gwi_mk_type(gwi, "@Class", SZ_INT, NULL);
+ set_tflag(t_class, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_class, et_class))
GWI_BB(gwi_gack(gwi, t_class, gack_class)) // not working yet
- GWI_BB(gwi_add_type(gwi, t_class))
GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_object_dot))
GWI_BB(gwi_oper_emi(gwi, opem_object_dot))
const Type t_undefined = gwi_mk_type(gwi, "@Undefined", SZ_INT, NULL);
GWI_BB(gwi_set_global_type(gwi, t_undefined, et_undefined))
const Type t_auto = gwi_mk_type(gwi, "auto", SZ_INT, NULL);
- SET_FLAG(t_auto, infer);
+ set_tflag(t_auto, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_auto, et_auto))
- SET_FLAG(t_class, infer);
const Type t_void = gwi_mk_type(gwi, "void", 0, NULL);
GWI_BB(gwi_gack(gwi, t_void, gack_void))
GWI_BB(gwi_set_global_type(gwi, t_void, et_void))
GWI_BB(gwi_gack(gwi, t_fptr, gack_fptr))
GWI_BB(gwi_set_global_type(gwi, t_fptr, et_fptr))
const Type t_lambda = gwi_mk_type(gwi, "@lambda", SZ_INT, "@function");
- SET_FLAG(t_lambda, infer);
+ set_tflag(t_lambda, tflag_infer);
GWI_BB(gwi_set_global_type(gwi, t_lambda, et_lambda))
GWI_BB(gwi_typedef_ini(gwi, "int", "@internal"))
return GW_OK;
}
-ANN m_bool type_engine_init(const Gwion gwion, const Vector plug_dirs) {
+ANN m_bool type_engine_init(const Gwion gwion) {
gwion->env->name = "[builtin]";
- struct loc_t_ loc = {};
- OperCK oper = {};
- struct Gwi_ gwi = { .gwion=gwion, .loc=&loc, .oper=&oper };
- CHECK_BB(import_core_libs(&gwi))
- push_global(gwion, "[plugins]");
- gwion->env->name = "[imported]";
- for(m_uint i = 0; i < vector_size(plug_dirs); ++i) {
- m_bool (*import)(Gwi) = (m_bool(*)(Gwi))vector_at(plug_dirs, i);
- if(import && import(&gwi) < 0)
- gwi_reset(&gwi);
- }
+ CHECK_BB(gwi_run(gwion, import_core_libs))
push_global(gwion, "[user]");
return GW_OK;
}
gwi->gwion->type[et_event] = t_event; // use func
GWI_BB(gwi_item_ini(gwi, "@internal", "@shreds"))
- GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
GWI_BB(gwi_func_ini(gwi, "void", "signal"))
GWI_BB(gwi_func_end(gwi, event_signal, ae_flag_none))
GWI_BB(gwi_func_ini(gwi, "void", "broadcast"))
DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid))
if(isa(v->type, env->gwion->type[et_class]) > 0)
return NULL;
+ if(vflag(v, vflag_builtin)) {
+ dt->xfun = v->d.func_ref->def->d.dl_func_ptr;
+ v->d.func_ref->def->d.dl_func_ptr = NULL;
+ }
const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
+ if(vflag(v, vflag_builtin))
+ v->d.func_ref->def->d.dl_func_ptr = dt->xfun;
def->base->tmpl->call = cpy_type_list(env->gwion->mp, dt->tl);
def->base->tmpl->base = dt->vt_index;
dt->def = def;
dt->owner = v->from->owner;
dt->owner_class = v->from->owner_class;
- SET_FLAG(def->base, template);
return def;
}
ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, const Nspc nspc) {
DECL_OO(const Func_Def, def, = from_base(emit->env, dt, nspc))
CHECK_BO(traverse_dot_tmpl(emit, dt))
+ if(dt->xfun)
+ builtin_func(emit->gwion->mp, def->base->func, dt->xfun);
return def;
}
struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
const m_str name = dt->name;
const M_Object o = *(M_Object*)REG(-SZ_INT);
- Type t = !GET_FLAG(o->type_ref, nonnull) ? o->type_ref : o->type_ref->e->parent;
+ Type t = !tflag(o->type_ref, tflag_nonnull) ? o->type_ref : o->type_ref->e->parent;
do {
const Emitter emit = shred->info->vm->gwion->emit;
emit->env->name = "runtime";
if(f) {
if(!f->code)
break;
- if(GET_FLAG(f, member))
+ if(vflag(f->value_ref, vflag_member))
shred->reg += SZ_INT;
*(VM_Code*)(shred->reg-SZ_INT) = f->code;
return;
if(!def)
continue;
const Func f = def->base->func;
- if(GET_FLAG(f, member))
+ if(vflag(f->value_ref, vflag_member))
shred->reg += SZ_INT;
*(VM_Code*)(shred->reg-SZ_INT) = f->code;
return;
if(bin->rhs->info->type->e->d.func->def->base->tmpl)
fptr_instr(emit, bin->lhs->info->type->e->d.func, 2);
const Instr instr = emit_add_instr(emit, int_r_assign);
- if(!is_fptr(emit->gwion, bin->lhs->info->type) && GET_FLAG(bin->rhs->info->type->e->d.func, member)) {
+ if(!is_fptr(emit->gwion, bin->lhs->info->type) && vflag(bin->rhs->info->type->e->d.func->value_ref, vflag_member)) {
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = SZ_INT;
const Instr cpy = emit_add_instr(emit, Reg2Reg);
ERR_B(info->pos, _("can't assign non member function to member function pointer"))
} else if(l_type && isa(r_type, l_type) < 0)
ERR_B(info->pos, _("can't assign member function to a pointer of an other class"))
- if(GET_FLAG(info->rhs, member)) {
- if(!GET_FLAG(info->lhs, member))
+ if(vflag(info->rhs->value_ref, vflag_member)) {
+ if(!vflag(info->lhs->value_ref, vflag_member))
ERR_B(info->pos, _("can't assign static function to member function pointer"))
- } else if(GET_FLAG(info->lhs, member))
+ } else if(vflag(info->lhs->value_ref, vflag_member))
ERR_B(info->pos, _("can't assign member function to static function pointer"))
return GW_OK;
}
}
ANN static inline m_bool fptr_arity(struct FptrInfo *info) {
- return GET_FLAG(info->lhs->def->base, variadic) ==
- GET_FLAG(info->rhs->def->base, variadic);
+ return fbflag(info->lhs->def->base, fbflag_variadic) ==
+ fbflag(info->rhs->def->base, fbflag_variadic);
}
ANN static Type fptr_type(const Env env, struct FptrInfo *info) {
ERR_B(exp_self(l)->pos, _("argument number does not match for lambda"))
l->def->base->flag = def->base->flag;
l->def->base->td = cpy_type_decl(env->gwion->mp, def->base->td);
- SET_FLAG(l->def->base, abstract); // mark as non immediate lambda
map_set(&env->curr->info->func->map, (m_uint)l->def->base, env->scope->depth);
const m_bool ret = check_traverse_fdef(env, l->def);
map_remove(&env->curr->info->func->map, (m_uint)l->def->base);
ANN m_bool check_lambda(const Env env, const Type t, Exp_Lambda *l) {
const Func_Def fdef = t->e->d.func->def;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
l->owner = t->e->owner_class;
CHECK_BB(envset_push(&es, l->owner, t->e->owner))
const m_bool ret = _check_lambda(env, l, fdef);
ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
if(isa(info->exp->info->type, env->gwion->type[et_lambda]) < 0) {
- m_bool nonnull = GET_FLAG(info->exp->info->type, nonnull);
+ m_bool nonnull = tflag(info->exp->info->type, tflag_nonnull);
CHECK_BB(fptr_check(env, info))
DECL_OB(const Type, t, = fptr_type(env, info))
info->exp->info->type = !nonnull ? t : nonnul_type(env, t);
const m_bool ret = traverse_fptr_def(env, fptr_def);
const Type t = fptr_def->type;
free_fptr_def(env->gwion->mp, fptr_def);
- REM_REF(t, env->gwion)
+ type_remref(t, env->gwion);
bin->rhs->d.exp_decl.list->self->value->type = bin->rhs->info->type = bin->rhs->d.exp_decl.type = t;
exp_setvar(bin->rhs, 1);
return ret > 0 ? t : env->gwion->type[et_null];
}
static int is_member(const Type from, const Type to) {
- return GET_FLAG(from->e->d.func, member) &&
- !(GET_FLAG(from, nonnull) || GET_FLAG(to, nonnull));
+ return vflag(from->e->d.func->value_ref, vflag_member) &&
+ !(tflag(from, tflag_nonnull) || tflag(to, tflag_nonnull));
}
static OP_EMIT(opem_fptr_cast) {
return env->gwion->type[et_fork];
char c[21 + strlen(t->name)];
sprintf(c, "nonnull TypedFork:[%s]", t->name);
- return str2type(env->gwion, c, exp_self(unary)->pos);
+ const Type fork = env->gwion->type[et_fork];
+ UNSET_FLAG(fork, final);
+ const Type typed = str2type(env->gwion, "TypedFork", exp_self(unary)->pos);
+ UNSET_FLAG(typed, final);
+ const Type ret = str2type(env->gwion, c, exp_self(unary)->pos);
+ SET_FLAG(typed, final);
+ SET_FLAG(fork, final);
+ return ret;
}
static OP_CHECK(opck_spork) {
}
static FREEARG(freearg_xork) {
- REM_REF((VM_Code)instr->m_val, gwion)
+ vmcode_remref((VM_Code)instr->m_val, gwion);
}
static FREEARG(freearg_dottmpl) {
if(!code)
Except(shred, "[NullTickException]");
uu->shred = new_vm_shred(shred->info->vm->gwion->mp, *(VM_Code*)(shred->reg-offset));
- ADD_REF(*(VM_Code*)(shred->reg - offset));
+ vmcode_addref(*(VM_Code*)(shred->reg - offset));
uu->shred->info->vm = shred->info->vm;
code_prepare(uu->shred->code);
shreduler_ini(uu->shred->info->vm->shreduler, uu->shred);
ANN static void handle_dtor(const M_Object o, const VM_Shred shred) {
const VM_Shred sh = new_vm_shred(shred->info->mp, o->type_ref->nspc->dtor);
- ADD_REF(o->type_ref->nspc->dtor);
+ vmcode_addref(o->type_ref->nspc->dtor);
sh->base = shred->base;
*(M_Object*)sh->mem = o;
vm_add_shred(shred->info->vm, sh);
struct scope_iter iter = { t->nspc->info->value, 0, 0 };\
Value v;
while(scope_iter(&iter, &v) > 0) {
- if(!GET_FLAG(v, static) && !GET_FLAG(v, pure) &&
+ if(!GET_FLAG(v, static) && !vflag(v, vflag_union) &&
isa(v->type, shred->info->vm->gwion->type[et_object]) > 0)
release(*(M_Object*)(o->data + v->from->offset), shred);
- else if(GET_FLAG(v->type, struct) &&
- !GET_FLAG(v, static) && !GET_FLAG(v, pure) && v->type->e->tuple) {
+ else if(tflag(v->type, tflag_struct) &&
+ !GET_FLAG(v, static) && !vflag(v, vflag_union) && v->type->e->tuple) {
const TupleForm tf = v->type->e->tuple;
for(m_uint i = 0; i < vector_size(&tf->types); ++i) {
const m_bit *data = o->data + v->from->offset;
}
}
}
- if(GET_FLAG(t, dtor) && t->nspc->dtor) {
- if(GET_FLAG(t->nspc->dtor, builtin))
+ if(tflag(t, tflag_dtor) && t->nspc->dtor) {
+ // check flag for array types
+ if(t->nspc->dtor->builtin)
((f_xtor)t->nspc->dtor->native_func)(o, NULL, shred);
else {
o->type_ref = t;
static ID_CHECK(opck_this) {
if(!env->class_def)
ERR_O(exp_self(prim)->pos, _("keyword 'this' can be used only inside class definition..."))
- if(env->func && !GET_FLAG(env->func, member))
+ if(env->func && !vflag(env->func->value_ref, vflag_member))
ERR_O(exp_self(prim)->pos, _("keyword 'this' cannot be used inside static functions..."))
if(env->func && !strcmp(s_name(env->func->def->base->xid), "@gack"))
return force_type(env, get_gack(env->class_def->e->parent)); // get_gack ?
}
static ID_EMIT(opem_this) {
- if(!exp_getvar(exp_self(prim)) && GET_FLAG(exp_self(prim)->info->type, struct)) {
+ if(!exp_getvar(exp_self(prim)) && tflag(exp_self(prim)->info->type, tflag_struct)) {
const Instr instr = emit_add_instr(emit, RegPushMemDeref);
instr->m_val2 = emit->env->class_def->size;
return (Instr)GW_OK;
describe_logical(Eq, ==)
describe_logical(Neq, !=)
static inline m_bool nonnull_check(const Type l, const Type r) {
- return !GET_FLAG(l, nonnull) && GET_FLAG(r, nonnull);
+ return !tflag(l, tflag_nonnull) && tflag(r, tflag_nonnull);
}
static inline Type check_nonnull(const Env env, const Type l, const Type r,
const m_str action, const loc_t pos) {
- if(GET_FLAG(r, nonnull)) {
+ if(tflag(r, tflag_nonnull)) {
if(isa(l, env->gwion->type[et_null]) > 0)
ERR_N(pos, _("can't %s '%s' to '%s'"), action, l->name, r->name);
if(isa(l, r) < 0)
return env->gwion->type[et_null];
if(check_nonnull(env, l, r, "assign", exp_self(bin)->pos) == env->gwion->type[et_null])
return env->gwion->type[et_null];
- if(bin->rhs->exp_type == ae_exp_decl) {
+ if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, ref);
- SET_FLAG(bin->rhs->d.exp_decl.list->self->value, ref);
- }
exp_setvar(bin->rhs, 1);
return r;
}
static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
ANN static void emit_dot_static_import_data(const Emitter emit, const Value v, const uint emit_addr) {
- if(v->d.ptr && GET_FLAG(v, builtin) && GET_FLAG(v, const)) {
+ if(v->d.ptr && vflag(v, vflag_builtin) && GET_FLAG(v, const)) {
const m_uint size = v->type->size;
const Instr instr = emit_kind(emit, size, emit_addr, regpushimm);
instr->m_val = (m_uint)v->d.ptr;
if(f->def->base->tmpl)
emit_add_instr(emit, DotTmplVal);
else
- if(is_class(emit->gwion, member->t_base) || GET_FLAG(member->base->info->type, force)) {
+ if(is_class(emit->gwion, member->t_base) || tflag(member->base->info->type, tflag_force)) {
const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
func_i->m_val = (m_uint)f->code ?: (m_uint)f;
return;
// if(f->def->base->tmpl)
// emit_add_instr(emit, DotTmplVal);
else {
- if(GET_FLAG(member->t_base, struct)) {
+ if(tflag(member->t_base, tflag_struct)) {
if(!GET_FLAG(f->def->base, static)) {
exp_setvar(member->base, 1);
emit_exp(emit, member->base);
func_i->m_val = (m_uint)f->code ?: (m_uint)f;
return;
}
- const Instr instr = emit_add_instr(emit, GET_FLAG(f, member) ? DotFunc : DotStaticFunc);
+ const Instr instr = emit_add_instr(emit, vflag(f->value_ref, vflag_member) ? DotFunc : DotStaticFunc);
instr->m_val = f->vt_index;
}
return;
else if(GET_FLAG(value, protect))
exp_setprot(exp_self(member), 1);
}
- if(base_static && GET_FLAG(value, member))
+ if(base_static && vflag(value, vflag_member))
ERR_N(exp_self(member)->pos,
_("cannot access member '%s.%s' without object instance..."),
the_base->name, str)
const Exp_Dot *member = (Exp_Dot*)data;
const Type t_base = actual_type(emit->gwion, member->t_base);
const Value value = find_value(t_base, member->xid);
- if(!is_class(emit->gwion, member->t_base) && (GET_FLAG(value, member) ||
+ if(!is_class(emit->gwion, member->t_base) && (vflag(value, vflag_member) ||
(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 &&
!is_fptr(emit->gwion, exp_self(member)->info->type)))) {
- if(!GET_FLAG(t_base, struct))
+ if(!tflag(t_base, tflag_struct))
CHECK_BO(emit_exp(emit, member->base))
if(isa(member->t_base, emit->env->gwion->type[et_object]) > 0)
emit_except(emit, member->t_base);
}
if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->info->type))
emit_member_func(emit, member);
- else if(GET_FLAG(value, member)) {
- if(!GET_FLAG(t_base, struct))
+ else if(vflag(value, vflag_member)) {
+ if(!tflag(t_base, tflag_struct))
emit_member(emit, value, exp_getvar(exp_self(member)));
else {
// exp_setvar(member->base, exp_getvar(exp_self(member)));
}
struct tmpl_info {
- const Class_Def cdef;
+// const Class_Def cdef;
+ Symbol name;
+ ID_List list;
Type_List call;
+ Type ret;
+ Type base;
struct Vector_ type;
struct Vector_ size;
uint8_t index;
}
ANN static ssize_t template_size(const Env env, struct tmpl_info* info) {
- ID_List base = info->cdef->base.tmpl->list;
+ ID_List base = info->list; // ???
Type_List call = info->call;
size_t size = 0;
do {
DECL_OB(const Type, t, = known_type(env, call->td))
size += tmpl_set(info, t);
} while((call = call->next) && (base = base->next) && ++size);
- size += tmpl_set(info, info->cdef->base.type);
+// } while((call = call->next) && ++size);
+ size += tmpl_set(info, info->base);
return size + 4;
}
*str = '\0';
}
-ANEW ANN static Symbol template_id(const Env env, const Class_Def c, const Type_List call) {
- struct tmpl_info info = { .cdef=c, .call=call };
- vector_init(&info.type);
- vector_init(&info.size);
- ssize_t sz = template_size(env, &info);
+ANEW ANN static Symbol template_id(const Env env, struct tmpl_info* info) {
+ vector_init(&info->type);
+ vector_init(&info->size);
+ ssize_t sz = template_size(env, info);
char name[sz];
if(sz > GW_ERROR)
- template_name(&info, name);
- vector_release(&info.type);
- vector_release(&info.size);
+ template_name(info, name);
+ vector_release(&info->type);
+ vector_release(&info->size);
return sz > GW_ERROR ? insert_symbol(env->gwion->st, name) : NULL;
}
return !call ? GW_OK : GW_ERROR;
}
-ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
- DECL_OO(const Symbol, name, = template_id(env, def, call))
+ANN static Type tmpl_exists(const Env env, const Symbol name) {
if(env->class_def && name == insert_symbol(env->gwion->st, env->class_def->name))
- return env->class_def->e->def;
- const Type t = nspc_lookup_type1(env->curr, name);
- if(t)
- return t->e->def;
- const Class_Def c = cpy_class_def(env->gwion->mp, def);
- c->base.xid = name;
- SET_FLAG(c, template | ae_flag_ref);
- UNSET_FLAG(c, scan0 | ae_flag_scan1 | ae_flag_scan2 |
- ae_flag_check | ae_flag_emit | ae_flag_valid);
- return c;
-}
-
-ANN static m_bool class2udef(const Env env, const Class_Def a, const Type t) {
- a->union_def = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, a->list),
- loc_cpy(env->gwion->mp, t->e->def->pos));
- a->union_def->type_xid = a->base.xid;
- if(GET_FLAG(t, global))
- SET_FLAG(a->union_def, global);
- CHECK_BB(scan0_union_def(env, a->union_def))
- a->base.type = a->union_def->type;
- a->base.type->e->def = a;
- a->union_def->tmpl = cpy_tmpl(env->gwion->mp, a->base.tmpl);
- return GW_OK;
+ return env->class_def;
+ return nspc_lookup_type1(env->curr, name);
+}
+
+ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
+ const Class_Def c = info->base->e->cdef;
+ const Class_Def cdef = new_class_def(env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
+ c->body ?cpy_ast(env->gwion->mp, c->body) : NULL,
+ loc_cpy(env->gwion->mp, c->pos));
+ cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->call);
+ const m_bool ret = scan0_class_def(env, cdef);
+ if((info->ret = cdef->base.type)) {
+ info->ret->e->cdef = cdef;
+ set_tflag(info->ret, tflag_cdef);
+ set_tflag(info->ret, tflag_ctmpl);
+ } else
+ free_class_def(env->gwion->mp, cdef);
+ return ret;
+}
+
+ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
+ const Union_Def u = info->base->e->udef;
+ const Union_Def udef = new_union_def(env->gwion->mp, cpy_decl_list(env->gwion->mp, u->l),
+ loc_cpy(env->gwion->mp, u->pos));
+ udef->type_xid = info->name;
+ udef->tmpl = mk_tmpl(env, u->tmpl, info->call);
+ if(GET_FLAG(info->base, global))
+ SET_FLAG(udef, global);
+ const m_bool ret = scan0_union_def(env, udef);
+ if(udef->type) {
+ udef->type->e->udef = udef;// mark as udef
+ info->ret = udef->type;
+ set_tflag(info->ret, tflag_udef);
+// set_tflag(info->ret, tflag_tmpl);
+ } else
+ free_union_def(env->gwion->mp, udef);
+ return ret;
}
-ANN static m_bool _scan_class(const Env env, const Type t, const Class_Def a) {
- if(t->e->parent != env->gwion->type[et_union])
- CHECK_BB(scan0_class_def(env, a))
+ANN static Type _scan_class(const Env env, struct tmpl_info *info) {
+ if(info->base->e->parent != env->gwion->type[et_union])
+ CHECK_BO(scantmpl_class_def(env, info))
else
- CHECK_BB(class2udef(env, a, t))
- SET_FLAG(a->base.type, template);
- if(GET_FLAG(t, builtin))
- SET_FLAG(a->base.type, builtin);
- return GW_OK;
+ CHECK_BO(scantmpl_union_def(env, info))
+ return info->ret;
}
ANN Type scan_class(const Env env, const Type t, const Type_Decl* td) {
- if(template_match(t->e->def->base.tmpl->list, td->types) < 0)
- ERR_O(td->pos, _("invalid template types number"))
- DECL_OO(const Class_Def, a, = template_class(env, t->e->def, td->types))
- if(a->base.type)
- return a->base.type;
+ if(template_match(t->e->cdef->base.tmpl->list, td->types) < 0) // invalid template
+ ERR_O(td->pos, _("invalid template types number"))
+ struct tmpl_info info = { .base=t, .call=td->types, .list=t->e->cdef->base.tmpl->list };
+ DECL_OO(const Symbol, name, = info.name = template_id(env, &info))
+ const Type exists = tmpl_exists(env, name);
+ if(exists)
+ return exists;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan0_cdef,
- .scope=env->scope->depth, .flag=ae_flag_scan0 };
-// CHECK_BO(envset_push(&es, t->e->owner_class, env->context ? env->context->nspc : env->curr))
+ .scope=env->scope->depth, .flag=tflag_scan0 };
CHECK_BO(envset_push(&es, t->e->owner_class, t->e->ctx ? t->e->ctx->nspc : env->curr))
- a->base.tmpl = mk_tmpl(env, t->e->def->base.tmpl, td->types);
- const m_bool ret = _scan_class(env, t, a);
+ const Type ret = _scan_class(env, &info);
if(es.run)
envset_pop(&es, t->e->owner_class);
- if(ret > 0)
- return a->base.type;
- if(!a->base.type)
- free_class_def(env->gwion->mp, a);
- return NULL;
+ return ret;
}
ANN static inline Symbol dot_symbol(SymTable *st, const Value v) {
if(isa(t, shred->info->vm->gwion->type[et_compound]) < 0)
continue;
const m_uint offset = vector_at(offsets, i);
- if(!GET_FLAG(t, struct))
+ if(!tflag(t, tflag_struct))
release(*(M_Object*)(ptr + offset), shred);
else
struct_release(shred, t, *(m_bit**)(ptr + offset));
ERR_N(exp_self(cast)->pos, "'Ptr' needs types to cast")
DECL_ON(const Type, t, = known_type(env, cast->td))
const Type _t = get_type(t);
- if(_t->e->def && !GET_FLAG(_t, check))
+ if(_t->e->cdef && !tflag(_t, tflag_check))
CHECK_BN(ensure_traverse(env, _t))
const Type to = known_type(env, cast->td->types->td);
if(isa(cast->exp->info->type, to) > 0)
e->info->cast_to = imp->t;
exp_setvar(e, 1);
const Type t = get_type(imp->t);
- if(!GET_FLAG(t, check))
- CHECK_BN(traverse_class_def(env, t->e->def))
+ if(!tflag(t, tflag_check))
+ CHECK_BN(traverse_class_def(env, t->e->cdef))
return imp->t;
}
return NULL;
static OP_CHECK(opck_ptr_scan) {
struct TemplateScan *ts = (struct TemplateScan*)data;
DECL_ON(const Type, t, = (Type)scan_class(env, ts->t, ts->td))
- const Type base = known_type(env, t->e->def->base.tmpl->call->td);
+set_tflag(t, tflag_tmpl);
+//if(!tflag(t, tflag_scan1))exit(3);
+ const Type base = known_type(env, t->e->cdef->base.tmpl->call->td);
if(isa(base, env->gwion->type[et_compound]) > 0 && !t->nspc->dtor) {
- t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, ae_flag_member | ae_flag_builtin, "@PtrDtor");
- if(!GET_FLAG(t, struct))
+ t->nspc->dtor = new_vm_code(env->gwion->mp, NULL, SZ_INT, 1, "@PtrDtor");
+ if(!tflag(t, tflag_struct))
t->nspc->dtor->native_func = (m_uint)ptr_object_dtor;
else
t->nspc->dtor->native_func = (m_uint)ptr_struct_dtor;
- SET_FLAG(t, dtor);
+ set_tflag(t, tflag_dtor);
}
return t;
}
GWION_IMPORT(ptr) {
const Type _t_ptr = gwi_class_ini(gwi, "@Ptr", NULL);
GWI_BB(gwi_class_end(gwi))
- SET_FLAG(_t_ptr, unary);
+ set_tflag(_t_ptr, tflag_ntmpl);
+// set_tflag(_t_ptr, tflag_tmpl);
GWI_BB(gwi_oper_ini(gwi, "@Ptr", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_ptr_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
GWI_BB(gwi_item_ini(gwi, "@internal", "@val"))
GWI_BB(gwi_item_end(gwi, 0, NULL))
GWI_BB(gwi_class_end(gwi))
- SET_FLAG(t_ptr, unary);
+ set_tflag(t_ptr, tflag_ntmpl);
+// set_tflag(t_ptr, tflag_tmpl);
GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "nonnull Ptr", NULL))
GWI_BB(gwi_oper_add(gwi, opck_ptr_assign))
GWI_BB(gwi_oper_end(gwi, ":=>", instr_ptr_assign))
VM_Shred new_shred_base(const VM_Shred shred, const VM_Code code) {
const VM_Shred sh = new_vm_shred(shred->info->mp, code);
- ADD_REF(code)
+ vmcode_addref(code);
sh->base = shred->base;
return sh;
}
if(!parent->gwion->data->child2.ptr)
vector_init(&parent->gwion->data->child2);
vector_add(&parent->gwion->data->child2, (vtype)ME(o)->info->vm->gwion);
- REM_REF(ME(o)->code, ME(o)->info->vm->gwion);
+ vmcode_remref(ME(o)->code, ME(o)->info->vm->gwion);
MUTEX_UNLOCK(parent->shreduler->mutex);
}
gwi_func_ini(gwi, "float", "get_now");
GWI_BB(gwi_func_end(gwi, shred_now, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
- gwi_set_global_type(gwi, t_shred, et_shred);
+ SET_FLAG(t_shred, abstract | ae_flag_final);
+ gwi->gwion->type[et_shred] = t_shred;
struct SpecialId_ spid = { .type=t_shred, .exec=RegPushMe, .is_const=1 };
gwi_specialid(gwi, "me", &spid);
- SET_FLAG(t_shred, abstract);
-
const Type t_fork= gwi_class_ini(gwi, "Fork", "Shred");
gwi_class_xtor(gwi, NULL, fork_dtor);
gwi->gwion->type[et_fork] = t_fork;
gwi_func_ini(gwi, "void", "test_cancel");
GWI_BB(gwi_func_end(gwi, fork_test_cancel, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
- SET_FLAG((t_fork), abstract);
+ SET_FLAG(t_fork, abstract | ae_flag_final);
const Type t_typed = gwi_class_ini(gwi, "TypedFork:[A]", "Fork");
gwi_item_ini(gwi, "A", "retval");
GWI_BB((gwi_item_end(gwi, ae_flag_const, NULL)))
GWI_BB(gwi_class_end(gwi))
- SET_FLAG((t_typed), abstract);
-
+ SET_FLAG(t_typed, abstract | ae_flag_final);
+ set_tflag(t_typed, tflag_ntmpl);
return GW_OK;
}
}
static MFUN(string_find) {
- const m_str str = STRING(o);
- m_int i = 0, ret = -1;
- char arg = *(m_int*)MEM(SZ_INT);
- while(str[i] != '\0') {
- if(str[i] == arg) {
- ret = i;
- break;
- }
- i++;
- }
- *(m_uint*)RETURN = ret;
+ const m_str base = STRING(o);
+ char c = *(m_int*)MEM(SZ_INT);
+ char *str = strchr(base, c);
+ *(m_uint*)RETURN = str ? str - base : -1;
}
static MFUN(string_findStart) {
- const m_str str = STRING(o);
- const char pos = *(m_int*)MEM(SZ_INT);
- const char arg = *(m_int*)MEM(SZ_INT * 2);
- m_int i = pos, ret = -1;
- if(!strlen(str)) {
- *(M_Object*)RETURN = NULL;
- return;
- }
- while(str[i] != '\0') {
- if(str[i] == arg) {
- ret = i;
- break;
- }
- i++;
- }
- *(m_uint*)RETURN = ret;
+ const m_str base = STRING(o);
+ const size_t sz = strlen(base);
+ const char pos = *(m_int*)MEM(SZ_INT *2);
+ if(pos >= 0 && (size_t)pos < sz) {
+ const char arg = *(m_int*)MEM(SZ_INT);
+ char *str = strchr(base + pos, arg);
+ *(m_uint*)RETURN = str ? str - pos - base : -1;
+ } else
+ *(m_uint*)RETURN = -1;
}
static MFUN(string_findStr) {
- if(!strlen(STRING(o))) {
- *(M_Object*)RETURN = NULL;
- return;
- }
- char str[strlen(STRING(o)) + 1];
- strcpy(str, STRING(o));
- m_int ret = -1;
+ const m_str base = STRING(o);
+ const size_t sz = strlen(base);
const M_Object obj = *(M_Object*)MEM(SZ_INT);
- if(!obj) {
- *(m_uint*)RETURN = 0;
- return;
- }
- const m_str arg = STRING(obj);
- const m_int len = strlen(str);
- m_int i = 0;
- const m_int arg_len = strlen(arg);
- while(i < len) {
- if(!strncmp(str + i, arg, arg_len)) {
- ret = i;
- break;
- }
- i++;
- }
+ if(sz) {
+ const m_str arg = STRING(obj);
+ const m_str str = strstr(base, arg);
+ *(m_uint*)RETURN = str ? str - base : -1;
+ } else
+ *(m_uint*)RETURN = -1;
release(obj, shred);
- *(m_uint*)RETURN = ret;
}
static MFUN(string_findStrStart) {
- if(!strlen(STRING(o))) {
- *(M_Object*)RETURN = NULL;
- return;
- }
- char str[strlen(STRING(o)) + 1];
- strcpy(str, STRING(o));
- m_int ret = -1;
- const m_int start = *(m_int*)MEM(SZ_INT);
- const M_Object obj = *(M_Object*)MEM(SZ_INT * 2);
- if(!obj) {
- *(M_Object*)RETURN = NULL;
- return;
- }
- const m_str arg = STRING(obj);
- const m_int len = strlen(str);
- m_int i = start;
- const m_int arg_len = strlen(arg);
- while(i < len) {
- if(!strncmp(str + i, arg, arg_len)) {
- ret = i;
- break;
- }
- i++;
- }
+ const m_str base = STRING(o);
+ const size_t sz = strlen(base);
+ const char pos = *(m_int*)MEM(SZ_INT*2);
+ const M_Object obj = *(M_Object*)MEM(SZ_INT);
+ if(pos >= 0 && (size_t)pos < sz) {
+ const m_str arg = STRING(obj);
+ const m_str str = strstr(base + pos, arg);
+ *(m_uint*)RETURN = str ? str - pos- base : -1;
+ } else
+ *(m_uint*)RETURN = -1;
release(obj, shred);
- *(m_uint*)RETURN = ret;
}
static MFUN(string_rfind) {
- const m_str str = STRING(o);
- m_int i = strlen(str) - 1, ret = -1;
- const char arg = *(m_int*)MEM(SZ_INT);
- while(i > -1 && str[i] != '\0') {
- if(str[i] == arg) {
- ret = i;
- break;
- }
- i--;
- }
- *(m_uint*)RETURN = ret;
+ const m_str base = STRING(o);
+ char c = *(m_int*)MEM(SZ_INT);
+ char *str = strrchr(base, c);
+ *(m_uint*)RETURN = str ? str - base : -1;
}
static MFUN(string_rfindStart) {
- if(!strlen(STRING(o))) {
- *(M_Object*)RETURN = NULL;
- return;
- }
- char str[strlen(STRING(o)) + 1];
- strcpy(str, STRING(o));
+ const m_str base = STRING(o);
+ const size_t sz = strlen(base);
const char pos = *(m_int*)MEM(SZ_INT);
- const char arg = *(m_int*)MEM(SZ_INT * 2);
- m_int i = pos, ret = -1;
- while(i > 0 && str[i] != '\0') {
- if(str[i] == arg) {
- ret = i;
- break;
- }
- i--;
- }
- *(m_uint*)RETURN = ret;
+ if(pos >= 0 && (size_t)pos < sz) {
+ const char arg = *(m_int*)MEM(SZ_INT * 2);
+ char *str = strrchr(base + pos, arg);
+ *(m_uint*)RETURN = str ? str - pos - base : -1;
+ } else
+ *(m_uint*)RETURN = -1;
}
static MFUN(string_rfindStr) {
- if(!strlen(STRING(o))) {
- *(M_Object*)RETURN = NULL;
- return;
- }
- char str[strlen(STRING(o)) + 1];
- strcpy(str, STRING(o));
- m_int ret = -1;
+ const m_str base = STRING(o);
+ const size_t sz = strlen(base);
const M_Object obj = *(M_Object*)MEM(SZ_INT);
- const m_str arg = STRING(o);
- const m_int len = strlen(str);
- m_int i = len - 1;
- const m_int arg_len = strlen(arg);
- while(i) {
- if(!strncmp(str + i, arg, arg_len)) {
- ret = i;
- break;
- }
- i--;
- }
+ if(sz) {
+ const m_str arg = STRING(obj);
+ m_str tmp = base, str = NULL;
+ while((tmp = strstr(tmp, arg)))
+ str = tmp++;
+ *(m_uint*)RETURN = str ? str - base : -1;
+ } else
+ *(m_uint*)RETURN = -1;
release(obj, shred);
- *(m_uint*)RETURN = ret;
}
static MFUN(string_rfindStrStart) {
- if(!strlen(STRING(o))) {
- *(M_Object*)RETURN = NULL;
- return;
- }
- char str[strlen(STRING(o)) + 1];
- strcpy(str, STRING(o));
- m_int ret = -1;
- m_int start = *(m_int*)MEM(SZ_INT);
+ const m_str base = STRING(o);
+ const size_t sz = strlen(base);
+ const char pos = *(m_int*)MEM(SZ_INT *2);
const M_Object obj = *(M_Object*)MEM(SZ_INT * 2);
- if(!obj) {
- *(m_uint*)RETURN = 0;
- return;
- }
- m_str arg = STRING(obj);
-
- m_int i = start;
- const m_int arg_len = strlen(arg);
- while(i > -1) {
- if(!strncmp(str + i, arg, arg_len)) {
- ret = i;
- break;
- }
- i--;
- }
+ if(sz) {
+ const m_str arg = STRING(obj);
+ m_str tmp = base + pos, str = NULL;
+ while((tmp = strstr(tmp, arg)))
+ str = tmp++;
+ *(m_uint*)RETURN = str ? str - pos - base : -1;
+ } else
+ *(m_uint*)RETURN = -1;
release(obj, shred);
- *(m_uint*)RETURN = ret;
}
static MFUN(string_erase) {
GWION_IMPORT(string) {
const Type t_string = gwi_class_ini(gwi, "string", NULL);
+ gwi->gwion->type[et_string] = t_string; // use func
gwi_class_xtor(gwi, string_ctor, NULL);
GWI_BB(gwi_gack(gwi, t_string, gack_string))
- gwi->gwion->type[et_string] = t_string; // use func
gwi_item_ini(gwi, "@internal", "@data");
GWI_BB(gwi_item_end(gwi, ae_flag_const, NULL))
gwi_func_ini(gwi, "string", "trim");
GWI_BB(gwi_func_end(gwi, string_trim, ae_flag_none))
- gwi_func_ini(gwi, "int", "charAt");
+ gwi_func_ini(gwi, "char", "charAt");
gwi_func_arg(gwi, "int", "pos");
GWI_BB(gwi_func_end(gwi, string_charAt, ae_flag_none))
- gwi_func_ini(gwi, "int", "charAt");
+ gwi_func_ini(gwi, "char", "charAt");
gwi_func_arg(gwi, "int", "pos");
gwi_func_arg(gwi, "char", "c");
GWI_BB(gwi_func_end(gwi, string_setCharAt, ae_flag_none))
GWI_BB(gwi_func_end(gwi, string_find, ae_flag_none))
gwi_func_ini(gwi, "int", "find");
- gwi_func_arg(gwi, "int", "pos");
gwi_func_arg(gwi, "char", "c");
+ gwi_func_arg(gwi, "int", "pos");
GWI_BB(gwi_func_end(gwi, string_findStart, ae_flag_none))
gwi_func_ini(gwi, "int", "find");
- gwi_func_arg(gwi, "string", "str");
+ gwi_func_arg(gwi, "nonnull string", "str");
GWI_BB(gwi_func_end(gwi, string_findStr, ae_flag_none))
gwi_func_ini(gwi, "int", "find");
+ gwi_func_arg(gwi, "nonnull string", "str");
gwi_func_arg(gwi, "int", "pos");
- gwi_func_arg(gwi, "string", "str");
GWI_BB(gwi_func_end(gwi, string_findStrStart, ae_flag_none))
gwi_func_ini(gwi, "int", "rfind");
GWI_BB(gwi_func_end(gwi, string_rfind, ae_flag_none))
gwi_func_ini(gwi, "int", "rfind");
- gwi_func_arg(gwi, "int", "pos");
gwi_func_arg(gwi, "char", "c");
+ gwi_func_arg(gwi, "int", "pos");
GWI_BB(gwi_func_end(gwi, string_rfindStart, ae_flag_none))
gwi_func_ini(gwi, "int", "rfind");
- gwi_func_arg(gwi, "string", "str");
+ gwi_func_arg(gwi, "nonnull string", "str");
GWI_BB(gwi_func_end(gwi, string_rfindStr, ae_flag_none))
gwi_func_ini(gwi, "int", "rfind");
+ gwi_func_arg(gwi, "nonnull string", "str");
gwi_func_arg(gwi, "int", "pos");
- gwi_func_arg(gwi, "string", "str");
GWI_BB(gwi_func_end(gwi, string_rfindStrStart, ae_flag_none))
gwi_func_ini(gwi, "void", "erase");
gwi->gwion->type[et_ugen] = t_ugen; // use func
GWI_BB(gwi_item_ini(gwi, "@internal", "@ugen"))
- GWI_BB(gwi_item_end(gwi, ae_flag_member, NULL))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
GWI_BB(gwi_func_ini(gwi, "UGen", "chan"))
GWI_BB(gwi_func_arg(gwi, "int", "arg0"))
const Type t = (Type)vector_at(&arg->t, i);
if(isa(t, shred->info->vm->gwion->type[et_object]) > 0)
release(*(M_Object*)(arg->d + offset), shred);
- else if(GET_FLAG(t, struct))
+ else if(tflag(t, tflag_struct))
struct_release(shred, t, *(m_bit**)(arg->d + offset));
offset += t->size;
}
}
static ID_CHECK(idck_vararg) {
- if(env->func && GET_FLAG(env->func->def->base, variadic))
+ if(env->func && fbflag(env->func->def->base, fbflag_variadic))
return nonnul_type(env, exp_self(prim)->info->type);
ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
}
const Type t_vararg = gwi_class_ini(gwi, "Vararg", "Object");
gwi_class_xtor(gwi, NULL, vararg_dtor);
gwi_gack(gwi, t_vararg, gack_vararg);
- CHECK_BB(gwi_item_ini(gwi, "@internal", "@data"))
- CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL))
- CHECK_BB(gwi_item_ini(gwi, "int", "@inLoop"))
- CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL))
- CHECK_BB(gwi_item_ini(gwi, "int", "@len"))
- CHECK_BB(gwi_item_end(gwi, ae_flag_none, NULL))
- CHECK_BB(gwi_func_ini(gwi, "Vararg", "cpy"))
- CHECK_BB(gwi_func_end(gwi, mfun_vararg_cpy, ae_flag_none))
+ GWI_BB(gwi_item_ini(gwi, "@internal", "@data"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+ GWI_BB(gwi_item_ini(gwi, "int", "@inLoop"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+ GWI_BB(gwi_item_ini(gwi, "int", "@len"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+ GWI_BB(gwi_func_ini(gwi, "Vararg", "cpy"))
+ GWI_BB(gwi_func_end(gwi, mfun_vararg_cpy, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
- SET_FLAG(t_vararg, abstract);
- CHECK_BB(gwi_set_global_type(gwi, t_vararg, et_vararg))
+ SET_FLAG(t_vararg, abstract | ae_flag_final);
+ gwi->gwion->type[et_vararg] = t_vararg;
GWI_BB(gwi_oper_ini(gwi, "nonnull Vararg", (m_str)OP_ANY_TYPE, NULL))
GWI_BB(gwi_oper_add(gwi, opck_vararg_cast))
GWI_BB(gwi_oper_emi(gwi, opem_vararg_cast))
return GW_OK;
}
-#define describe_check_decl(a, b) \
+#define describe_check_decl(a, b, flag) \
ANN static inline void decl_##a(const Env env, const Value v) { \
- const Nspc nspc = env->curr;\
- SET_FLAG(v, a); \
+ const Nspc nspc = env->curr; \
+ flag; \
v->from->offset = nspc->info->b; \
nspc->info->b += v->type->size; \
}
-describe_check_decl(member, offset)
-describe_check_decl(static, class_data_size)
+describe_check_decl(member, offset, v->vflag |= vflag_member)
+describe_check_decl(static, class_data_size, SET_FLAG(v, static))
ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
const Value v = var->value;
Type t = v->type;
- while(GET_FLAG(t, typedef))
+ while(tflag(t, tflag_typedef))
t = t->e->parent;
if(!t->e->d.func)
return GW_ERROR;
const Type type = func->value_ref->from->owner_class;
if(type && isa(type, env->class_def) < 0 && !GET_FLAG(func, global))
ERR_B(var->pos, _("can't use non global fptr of other class."))
- if(GET_FLAG(func, member) && GET_FLAG(v, static))
+ if(vflag(func->value_ref, vflag_member) && GET_FLAG(v, static))
ERR_B(var->pos, _("can't use static variables for member function."))
return GW_OK;
}
ANN Type check_td(const Env env, Type_Decl *td) {
CHECK_BO(check_td_exp(env, td))
const Type t = actual_type(env->gwion, td->exp->info->type);
- assert(t);
- if(GET_FLAG(t, template) && !GET_FLAG(t, ref))
- ERR_O(td_pos(td), _("type '%s' needs template types"), t->name)
td->xid = insert_symbol("auto");
return t;
}
ANN static m_bool check_var_td(const Env env, const Var_Decl var, Type_Decl *const td) {
const Value v = var->value;
if(env->class_def) {
- if(GET_FLAG(td, member)) {
+ if(vflag(v, vflag_member)) {
decl_member(env, v);
if(env->class_def->e->tuple)
tuple_info(env, v);
CHECK_BB(check_var_td(env, var, decl->td))
if(is_fptr(env->gwion, decl->type))
CHECK_BB(check_fptr_decl(env, var))
- SET_FLAG(var->value, valid | ae_flag_used);
+ set_vflag(var->value, vflag_valid);
+ //set_vflag(var->value, vflag_used));
nspc_add_value(env->curr, var->xid, var->value);
} while((list = list->next));
return GW_OK;
ANN static inline m_bool ensure_check(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
return envset_run(&es, t);
}
ANN m_bool ensure_traverse(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)traverse_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
return envset_run(&es, t);
}
ANN static inline m_bool inferable(const Env env, const Type t, const loc_t pos) {
- if(!GET_FLAG(t, infer))
+ if(!tflag(t, tflag_infer))
return GW_OK;
ERR_B(pos, _("can't infer type."))
}
{
const Type t = get_type(decl->type);
CHECK_BO(inferable(env, t, td_pos(decl->td)))
- if(!GET_FLAG(t, check) && t->e->def)
+ if(!tflag(t, tflag_check))
CHECK_BO(ensure_check(env, t))
}
const m_bool global = GET_FLAG(decl->td, global);
CHECK_BO(not_from_owner_class(env, env->class_def, value, prim_pos(data)))
const Value v = value ?: find_value(env->class_def, var);
if(v) {
- if(env->func && GET_FLAG(env->func->def->base, static) && GET_FLAG(v, member))
+ if(env->func && GET_FLAG(env->func->def->base, static) && vflag(v, vflag_member))
ERR_O(prim_pos(data),
_("non-static member '%s' used from static function."), s_name(var))
}
return v;
} else if(SAFE_FLAG(env->class_def, global) || (env->func && GET_FLAG(env->func->def->base, global))) {
- if(!SAFE_FLAG(value, abstract))
+ if(!value || !GET_FLAG(value, global))
ERR_O(prim_pos(data),
_("non-global variable '%s' used from global function/class."), s_name(var))
}
const Symbol sym = insert_symbol(val->name);
const Vector vec = (Vector)&env->curr->info->value->ptr;
const m_uint scope = map_get(&env->curr->info->func->map, (m_uint)env->func->def->base);
- if(GET_FLAG(val, abstract))
+ if(GET_FLAG(val, global))
return GW_OK;
if(val->from->owner_class && isa(val->from->owner_class, env->class_def) > 0)
return GW_OK;
ANN static Type prim_id_non_res(const Env env, const Symbol *data) {
const Symbol sym = *data;
const Value v = check_non_res_value(env, data);
- if(!v || !GET_FLAG(v, valid) || (v->from->ctx && v->from->ctx->error)) {
+ if(!v || !vflag(v, vflag_valid) || (v->from->ctx && v->from->ctx->error)) {
env_err(env, prim_pos(data),
_("variable %s not legit at this point."), s_name(sym));
if(v)
}
prim_self(data)->value = v;
if(env->func) {
- if(GET_FLAG(env->func->def->base, abstract))
+ if(isa(env->func->value_ref->type, env->gwion->type[et_lambda]) > 0)
CHECK_BO(lambda_valid(env, prim_self(data)))
- if(env->func && !GET_FLAG(v, const) && v->from->owner)
- UNSET_FLAG(env->func, pure);
+ if(env->func && !GET_FLAG(v, const) && v->from->owner)
+ unset_fflag(env->func, fflag_pure);
}
- SET_FLAG(v, used);
+ //v->vflag |= used;
if(GET_FLAG(v, const))
exp_setmeta(prim_exp(data), 1);
if(v->from->owner_class) {
ANN static Type check_prim_hack(const Env env, const Exp *data) {
if(env->func)
- UNSET_FLAG(env->func, pure);
+ unset_fflag(env->func, fflag_pure);
CHECK_OO(check_prim_interp(env, data))
return env->gwion->type[et_gack];
}
Arg_List e1 = func->def->base->args;
while(e) {
if(!e1) {
- if(GET_FLAG(func->def->base, variadic))
+ if(fbflag(func->def->base, fbflag_variadic))
return func;
CHECK_OO(func->next);
return find_func_match_actual(env, func->next, args, implicit, specific);
ANN m_bool check_traverse_fdef(const Env env, const Func_Def fdef) {
struct Vector_ v = {};
const m_uint scope = env->scope->depth;
- env->scope->depth = 1;
+ env->scope->depth = 0;
vector_init(&v);
while(vector_size((Vector)&env->curr->info->value->ptr) > 1)
vector_add(&v, vector_pop((Vector)&env->curr->info->value->ptr));
CHECK_OB((arg_list->type = v->type = check_td(env, arg_list->td)))
// TODO: use coumpound instead of object?
if(isa(v->type, env->gwion->type[et_object]) > 0 || isa(v->type, env->gwion->type[et_function]) > 0)
- UNSET_FLAG(env->func, pure);
+ unset_fflag(env->func, fflag_pure);
CHECK_BB(already_defined(env, decl->xid, decl->pos))
- SET_FLAG(v, valid);
+ set_vflag(v, vflag_valid);
nspc_add_value(env->curr, decl->xid, v);
} while((arg_list = arg_list->next));
return GW_OK;
DECL_OO(const Func, func, = v->d.func_ref ?: predefined_func(env, v, exp, tm))
if(!fdef->base->ret_type) { // template fptr
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=env->scope->depth, .flag=ae_flag_check };
+ .scope=env->scope->depth, .flag=tflag_check };
CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
- SET_FLAG(func->def->base, typedef);
+ func->def->base->fbflag |= fbflag_internal;
const m_bool ret = check_traverse_fdef(env, func->def);
if(es.run)
envset_pop(&es, v->from->owner_class);
ERR_O(exp_self(exp)->pos, _("argument number does not match for lambda"))
CHECK_BO(check_traverse_fdef(env, l->def))
if(env->class_def)
- SET_FLAG(l->def->base, member);
+ set_vflag(l->def->base->func->value_ref, vflag_member);
((Exp_Call*)exp)->m_func = l->def->base->func;
return l->def->base->ret_type ?: (l->def->base->ret_type = env->gwion->type[et_void]);
}
}
if(exp->func->info->type == env->gwion->type[et_lambda])
return check_lambda_call(env, exp);
- if(GET_FLAG(exp->func->info->type->e->d.func, ref)) {
+ if(fflag(exp->func->info->type->e->d.func, fflag_ftmpl)) {
const Value value = exp->func->info->type->e->d.func->value_ref;
- if(value->from->owner_class && !GET_FLAG(value->from->owner_class, check))
+ if(value->from->owner_class && !tflag(value->from->owner_class, tflag_check))
CHECK_BO(ensure_traverse(env, value->from->owner_class))
}
if(exp->args)
CHECK_OO(check_exp(env, exp->args))
- if(GET_FLAG(exp->func->info->type, func))
+ if(tflag(exp->func->info->type, tflag_ftmpl))
return check_exp_call_template(env, (Exp_Call*)exp);
const Func func = find_func_match(env, exp->func->info->type->e->d.func, exp->args);
if((exp_self(exp)->d.exp_call.m_func = func)) {
env_err(env, pos, _("Type '%s' has '%s' as pre-defined types."),
t->name, str);
free_mstr(env->gwion->mp, str);
- if(GET_FLAG(t, typedef)) {
+ if(tflag(t, tflag_typedef)) {
loc_header(t->e->d.func->def->pos, env->name);
gw_err(_("from definition:\n"));
loc_err(t->e->d.func->def->pos, env->name);
return NULL;
DECL_OO(const Type, ret, = op_check(env, &opi))
const Type t = get_type(actual_type(env->gwion, ret));
- if(t->e->def && !GET_FLAG(t, check))
+ if(!tflag(t, tflag_check))
CHECK_BO(ensure_traverse(env, t))
return ret;
}
}
ANN m_bool check_type_def(const Env env, const Type_Def tdef) {
- return tdef->type->e->def ? check_class_def(env, tdef->type->e->def) : GW_OK;
+ return tdef->type->e->cdef ? check_class_def(env, tdef->type->e->cdef) : GW_OK;
}
ANN static Type check_exp_lambda(const Env env,
const Exp_If* exp_if NUSED) { return env->gwion->type[et_lambda]; }
do {
CHECK_OO((curr->info->type = check_exp_func[curr->exp_type](env, &curr->d)))
if(env->func && isa(curr->info->type, env->gwion->type[et_lambda]) < 0 && isa(curr->info->type, env->gwion->type[et_function]) > 0 &&
- !GET_FLAG(curr->info->type->e->d.func, pure))
- UNSET_FLAG(env->func, pure);
+ !fflag(curr->info->type->e->d.func, fflag_pure))
+ unset_fflag(env->func, fflag_pure);
} while((curr = curr->next));
return exp->info->type;
}
ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
DECL_OB(Type, t, = check_exp(env, stmt->exp))
- while(GET_FLAG(t, typedef))
+ while(tflag(t, tflag_typedef))
t = t->e->parent;
Type ptr = array_base(t);
const m_uint depth = t->array_depth - 1;
sprintf(c, "nonnull Ptr:[%s]", ptr->name);
ptr = str2type(env->gwion, c, stmt->exp->pos);
const Type base = get_type(ptr);
- if(!GET_FLAG(base, check))
+ if(!tflag(base, tflag_check))
CHECK_BB(ensure_traverse(env, base))
}
t = (!stmt->is_ptr && depth) ? array_type(env, ptr, depth) : ptr;
stmt->v = new_value(env->gwion->mp, t, s_name(stmt->sym));
- SET_FLAG(stmt->v, valid);
+ set_vflag(stmt->v, vflag_valid);
nspc_add_value(env->curr, stmt->sym, stmt->v);
return check_conts(env, stmt_self(stmt), stmt->body);
}
do {
CHECK_OB(check_exp(env, l->self))
Var_Decl_List list = l->self->d.exp_decl.list;
- do SET_FLAG(list->self->value, pure);
+ do set_vflag(list->self->value, vflag_union);
while((list = list->next));
if(l->self->info->type->size > udef->s)
udef->s = l->self->info->type->size;
if(!udef->xid && !udef->type_xid && env->class_def && !GET_FLAG(udef, static))
env->class_def->nspc->info->offset = udef->o + udef->s;
union_pop(env, udef, scope);
- union_flag(udef, ae_flag_check);
- union_flag(udef, ae_flag_valid);
+ union_flag(udef, tflag_check);
return ret;
}
const Symbol sym = prim->d.var;
const Value v = new_value(env->gwion->mp,
((Exp)VKEY(&env->scope->match->map, i))->info->type, s_name(sym));
- SET_FLAG(v, valid);
+ set_vflag(v, vflag_valid);
nspc_add_value(env->curr, sym, v);
VVAL(&env->scope->match->map, i) = (vtype)v;
return v;
}
ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) {
+ if(GET_FLAG(parent->def->base, final))
+ ERR_B(td_pos(fdef->base->td), _("can't override final function '%s'\n"), parent->name)
if(GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
const m_str c_name = fdef->base->func->value_ref->from->owner_class->name;
const m_str p_name = parent->value_ref->from->owner_class->name;
ANN m_bool check_fdef(const Env env, const Func_Def fdef) {
if(fdef->base->args)
CHECK_BB(check_func_args(env, fdef->base->args))
- if(!GET_FLAG(fdef->base, builtin)) {
- if(fdef->d.code)
- CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
- } else
- fdef->base->func->code->stack_depth = fdef->stack_depth;
+ if(fdef->d.code)
+ CHECK_BB(check_stmt_code(env, &fdef->d.code->d.stmt_code))
return GW_OK;
}
++env->scope->depth;
nspc_push_value(env->gwion->mp, env->curr);
struct Op_Import opi = { };
- if(GET_FLAG(fdef->base, op)) {
+ if(fbflag(fdef->base, fbflag_op)) {
func_operator(f, &opi);
operator_suspend(env->curr, &opi);
}
const m_bool ret = scanx_fdef(env, env, fdef, (_exp_func)check_fdef);
- if(GET_FLAG(fdef->base, op))
+ if(fbflag(fdef->base, fbflag_op))
operator_resume(&opi);
nspc_pop_value(env->gwion->mp, env->curr);
--env->scope->depth;
env->func = former;
if(ret > 0)
- SET_FLAG(fdef->base, valid);
+ set_fflag(fdef->base->func, fflag_valid);
if(GET_FLAG(fdef->base, global))
env_pop(env,scope);
return ret;
const Type_Decl *td = cdef->base.ext;
if(td->array)
CHECK_BB(check_subscripts(env, td->array, 1))
- if(parent->e->def && !GET_FLAG(parent, check))
+ if(!tflag(parent, tflag_check))
CHECK_BB(ensure_check(env, parent))
- if(GET_FLAG(parent, typedef))
- SET_FLAG(cdef->base.type, typedef);
+ if(tflag(parent, tflag_typedef)) {
+ set_tflag(cdef->base.type, tflag_typedef);
+ }
return GW_OK;
}
return ret;
}
+ANN m_bool check_abstract(const Env env, const Class_Def cdef) {
+ if(!cdef->base.type->nspc->info->vtable.ptr)
+ return GW_OK;
+ for(m_uint i = 0; i < vector_size(&cdef->base.type->nspc->info->vtable); ++i) {
+ Func f = (Func)vector_at(&cdef->base.type->nspc->info->vtable, i);
+ if(GET_FLAG(f->def->base, abstract))
+ ERR_B(cdef->pos, _("'%s' must be declared 'abstract'"), s_name(cdef->base.xid))
+ }
+ return GW_OK;
+}
+
ANN m_bool check_class_def(const Env env, const Class_Def cdef) {
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, check))
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_check))
CHECK_BB(ensure_check(env, t->e->owner_class))
- if(GET_FLAG(t, check))return GW_OK;
- SET_FLAG(t, check);
+ if(tflag(t, tflag_check))
+ return GW_OK;
+ set_tflag(t, tflag_check);
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
- if(!GET_FLAG(cdef, struct))
+ if(!tflag(t, tflag_struct))
inherit(t);
if(cdef->body) {
CHECK_BB(env_body(env, cdef, check_section))
- SET_FLAG(t, ctor);
+ set_tflag(t, tflag_ctor);
}
- SET_FLAG(t, valid);
+ if(!GET_FLAG(cdef, abstract))
+ CHECK_BB(check_abstract(env, cdef))
return GW_OK;
}
ANN void func_operator(const Func_Def fdef, struct Op_Import *opi) {
opi->op =fdef->base->xid;
const m_str str = s_name(fdef->base->xid);
- const uint is_unary = GET_FLAG(fdef->base, unary) +
+ const uint is_unary = fbflag(fdef->base, fbflag_unary) +
(!strcmp(str, "@conditionnal") || !strcmp(str, "@unconditionnal"));
const Arg_List args = fdef->base->args;
opi->lhs = is_unary ? NULL :
}
ANN static Func ensure_tmpl(const Env env, const Func_Def fdef, const Exp_Call *exp) {
- const m_bool ret = GET_FLAG(fdef->base, valid) || check_traverse_fdef(env, fdef) > 0;
+ const m_bool ret = (fdef->base->func && fflag(fdef->base->func, fflag_valid)) || check_traverse_fdef(env, fdef) > 0;
if(ret) {
const Func f = fdef->base->func;
const Func next = f->next;
const Func func = find_func_match(env, f, exp->args);
f->next = next;
if(func) {
- SET_FLAG(func, valid | ae_flag_template);
+ set_fflag(func, fflag_tmpl);
+ set_fflag(func, fflag_valid);
return func;
}
}
if(exists)
return exists->e->d.func;
- Func m_func = f_ptr_args->m_func;
+ Func m_func = f_ptr_args->m_func;
Func_Def base = v->d.func_ref ? v->d.func_ref->def : exp->func->info->type->e->d.func->def;
Func_Base *fbase = cpy_func_base(env->gwion->mp, base->base);
fbase->xid = sym;
nspc_add_type_front(v->from->owner, sym, actual_type(env->gwion, m_func->value_ref->type));
}
if(fptr->type)
- REM_REF(fptr->type, env->gwion)
+ type_remref(fptr->type, env->gwion);
free_fptr_def(env->gwion->mp, fptr);
}
return m_func;
const Value v = f_ptr_args->v;
const m_str tmpl_name = f_ptr_args->tmpl_name;
const Exp_Call *exp = f_ptr_args->e;
- Func m_func = f_ptr_args->m_func;
+ Func m_func = f_ptr_args->m_func;
Type_List types = f_ptr_args->types;
for(m_uint i = 0; i < v->from->offset + 1; ++i) {
const Value exists = template_get_ready(env, v, tmpl_name, i);
const Value value = template_get_ready(env, v, "template", i);
if(!value)
continue;
- if(GET_FLAG(v, builtin)) {
- SET_FLAG(value, builtin);
- SET_FLAG(value->d.func_ref, builtin);
- }
+ if(vflag(v, vflag_builtin))
+ set_vflag(value, vflag_builtin);
const Func_Def fdef = (Func_Def)cpy_func_def(env->gwion->mp, value->d.func_ref->def);
- SET_FLAG(fdef->base, template);
fdef->base->tmpl->call = cpy_type_list(env->gwion->mp, types);
fdef->base->tmpl->base = i;
if((m_func = ensure_tmpl(env, fdef, exp))) {
DECL_OO(const m_str, tmpl_name, = tl2str(env, types))
const m_uint scope = env->scope->depth;
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)check_cdef,
- .scope=scope, .flag=ae_flag_check };
+ .scope=scope, .flag=tflag_check };
struct ResolverArgs f_ptr_args = {.v = v, .e = exp, .tmpl_name = tmpl_name, m_func = m_func, .types = types};
CHECK_BO(envset_push(&es, v->from->owner_class, v->from->owner))
(void)env_push(env, v->from->owner_class, v->from->owner);
}
ANN static Type op_parent(const Env env, const Type t) {
- if(GET_FLAG(t, template) && GET_FLAG(t, ref)) {
+ if(tflag(t, tflag_ctmpl)) {
const Type type = typedef_base(t);
char name[strlen(type->name) + 1];
strcpy(name, type->name);
if(t == OP_ANY_TYPE || mo == OP_ANY_TYPE)
return GW_OK;
Type type = t;
- while(SAFE_FLAG(type, template) && type->e->def && type->e->def->base.tmpl && type->e->def->base.tmpl->call) type = type->e->parent;
if((type && mo && mo->xid == type->xid) || (!type && !mo))
return GW_OK;
return 0;
}
ANN static inline void set_nonnull(const Type t, const Exp exp) {
- if(t != OP_ANY_TYPE && GET_FLAG(t, nonnull))
+ if(t != OP_ANY_TYPE && tflag(t, tflag_nonnull))
exp_setnonnull(exp, 1);
}
SET_FLAG(fptr->base->func, global);
SET_FLAG(def->base, global);
} else if(!GET_FLAG(fptr->base, static)) {
- SET_FLAG(fptr->value, member);
- SET_FLAG(fptr->base->func, member);
- SET_FLAG(def->base, member);
+ set_vflag(fptr->value, vflag_member);
+ set_vflag(fptr->base->func->value_ref, vflag_member);
def->stack_depth += SZ_INT;
} else {
SET_FLAG(fptr->value, static);
SET_FLAG(fptr->base->func, static);
SET_FLAG(def->base, static);
}
- if(GET_FLAG(def->base, variadic))
+ if(fbflag(def->base, fbflag_variadic))
def->stack_depth += SZ_INT;
- fptr->value->from->owner_class = env->class_def;
}
static void fptr_def(const Env env, const Fptr_Def fptr) {
if(GET_FLAG(fptr->base, global))
context_global(env);
t->nspc = new_nspc(env->gwion->mp, name);
- t->flag = fptr->base->flag;
+ t->flag |= fptr->base->flag;
fptr->type = t;
fptr->value = mk_class(env, t);
valuefrom(env, fptr->value->from);
fptr_def(env, fptr);
if(env->class_def)
fptr_assign(env, fptr);
- SET_FLAG(fptr->value, func);
+ set_vflag(fptr->value, vflag_func);
add_type(env, t->e->owner, t);
mk_class(env, t);
- ADD_REF(t);
+ type_addref(t);
return GW_OK;
}
t->e->owner_class = env->class_def;
tdef->type = t;
if(base->nspc)
- ADD_REF((t->nspc = base->nspc));
- t->flag = tdef->ext->flag | ae_flag_valid;
+ nspc_addref((t->nspc = base->nspc));
+ t->flag = tdef->ext->flag;
scan0_implicit_similar(env, t, base);
if(tdef->ext->array && !tdef->ext->array->exp)
- SET_FLAG(t, empty);
+ set_tflag(t, tflag_empty);
}
ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) {
- const ae_flag flag = base->e->def ? base->e->def->flag : 0;
+ const ae_flag flag = base->e->cdef ? base->e->cdef->flag : 0;
const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid,
cpy_type_decl(env->gwion->mp, tdef->ext), NULL,
loc_cpy(env->gwion->mp, td_pos(tdef->ext)));
ANN static void typedef_fptr(const Env env, const Type_Def tdef, const Type base) {
tdef->type = type_copy(env->gwion->mp, base);
- ADD_REF(tdef->type->nspc)
+ nspc_addref(tdef->type->nspc);
tdef->type->name = s_name(tdef->xid);
tdef->type->e->parent = base;
add_type(env, env->curr, tdef->type);
mk_class(env, tdef->type);
if(base->e->d.func->def->base->tmpl)
- SET_FLAG(tdef->type, func);
+ set_tflag(tdef->type, tflag_ftmpl);
}
ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
CHECK_BB(typedef_complex(env, tdef, base))
} else
typedef_fptr(env, tdef, base);
- SET_FLAG(tdef->type, typedef);
+ set_tflag(tdef->type, tflag_typedef);
return GW_OK;
}
add_type(env, env->curr, t);
if(add)
mk_class(env, t);
- SET_FLAG(t, union);
return t;
}
ANN static void union_tmpl(const Env env, const Union_Def udef) {
if(tmpl_base(udef->tmpl)) {
- assert(udef->type_xid);
- const Class_Def cdef = new_class_def(env->gwion->mp, udef->flag, udef->type_xid,
- NULL, (Ast)cpy_decl_list(env->gwion->mp, udef->l), loc_cpy(env->gwion->mp, udef->pos));
- udef->type->e->def = cdef;
- cdef->base.tmpl = cpy_tmpl(env->gwion->mp, udef->tmpl);
- cdef->base.type = udef->type;
- SET_FLAG(cdef, union);
- SET_FLAG(udef->type, pure);
- SET_FLAG(udef, template);
- SET_FLAG(udef->type, template);
+ const Union_Def u = cpy_union_def(env->gwion->mp, udef);
+ u->type = udef->type;
+ udef->type->e->udef = u;
+ set_tflag(u->type, tflag_tmpl);
+ set_tflag(u->type, tflag_udef);
}
if(GET_FLAG(udef, global))
SET_FLAG(udef->type, global);
- SET_FLAG(udef->type, union);
}
ANN static Value union_value(const Env env, const Type t, const Symbol sym) {
const Value v = new_value(env->gwion->mp, t, s_name(sym));
valuefrom(env, v->from);
nspc_add_value(env->curr, sym, v);
- SET_FLAG(v, valid | ae_flag_pure);
+ set_vflag(v, vflag_union);
return v;
}
udef->value = union_value(env, t, udef->xid);
udef->value->flag |= udef->flag;
SET_ACCESS(udef, t);
- if(env->class_def && !GET_FLAG(udef, static)) {
- SET_FLAG(udef->value, member);
- SET_FLAG(udef, member);
- }
+ if(env->class_def && !GET_FLAG(udef, static))
+ set_vflag(udef->value, vflag_member);
} else if(udef->type_xid) {
CHECK_BB(scan0_defined(env, udef->type_xid, udef->pos))
udef->type = union_type(env, udef->type_xid, 1);
SET_ACCESS(udef, udef->type);
- SET_FLAG(udef->type, valid);
} else {
const Symbol sym = scan0_sym(env, "union", udef->pos);
CHECK_BB(scan0_defined(env, sym, udef->pos))
union_tmpl(env, udef);
if(GET_FLAG(udef, global))
env_pop(env, scope);
- union_flag(udef, ae_flag_scan0);
+ union_flag(udef, tflag_scan0);
return GW_OK;
}
}
ANN static void cdef_flag(const Class_Def cdef, const Type t) {
- if(cdef->base.tmpl) {
- SET_FLAG(t, template);
- SET_FLAG(cdef, template);
- }
+ if(cdef->base.tmpl)
+ set_tflag(t, tflag_tmpl);
if(cdef->base.ext && cdef->base.ext->array)
- SET_FLAG(t, typedef);
+ set_tflag(t, tflag_typedef);
}
ANN static Type get_parent_base(const Env env, Type_Decl *td) {
return t;
}
-ANN static Type check_abstract(const Env env, Type_Decl *td) {
+ANN static inline Type scan0_final(const Env env, Type_Decl *td) {
DECL_OO(const Type, t, = known_type(env, td))
- if(!GET_FLAG(t, abstract)) // could be final
+ if(!GET_FLAG(t, final))
return t;
- ERR_O(td_pos(td), _("can't inherit from abstract parent class '%s'\n."), t->name);
+ ERR_O(td_pos(td), _("can't inherit from final parent class '%s'\n."), t->name);
}
ANN static Type get_parent(const Env env, const Class_Def cdef) {
- if(GET_FLAG(cdef, struct))
+ if(cflag(cdef, cflag_struct))
return env->gwion->type[et_compound];
if(!cdef->base.ext)
return env->gwion->type[et_object];
return get_parent_base(env, cdef->base.ext);
if(cdef->base.tmpl)
template_push_types(env, cdef->base.tmpl);
- const Type t = check_abstract(env, cdef->base.ext);
+ const Type t = scan0_final(env, cdef->base.ext);
if(cdef->base.tmpl)
nspc_pop_type(env->gwion->mp, env->curr);
return t ?: (Type)GW_ERROR;
if(parent == (Type)GW_ERROR)
return NULL;
const Type t = scan0_type(env, ++env->scope->type_xid, s_name(cdef->base.xid), parent);
- if(GET_FLAG(cdef, struct))
- SET_FLAG(t, struct);
+ if(cflag(cdef, cflag_struct))
+ set_tflag(t, tflag_struct);
t->e->tuple = new_tupleform(env->gwion->mp, parent);
t->e->owner = env->curr;
t->e->owner_class = env->class_def;
t->nspc = new_nspc(env->gwion->mp, t->name);
t->nspc->parent = env->curr;
- t->e->def = cdef;
- t->flag = cdef->flag;
+ t->e->cdef = cdef;
+ t->flag |= cdef->flag;
add_type(env, t->e->owner, t);
cdef_flag(cdef, t);
if(cdef->base.ext && cdef->base.ext->array)
- SET_FLAG(t, typedef);
+ set_tflag(t, tflag_typedef);
return t;
}
ANN static m_bool scan0_stmt_list(const Env env, Stmt_List list) {
- do if(list->stmt->stmt_type == ae_stmt_pp && list->stmt->d.stmt_pp.pp_type == ae_pp_include)
- env->name = list->stmt->d.stmt_pp.data;
- while((list = list->next));
+ do if(list->stmt->stmt_type == ae_stmt_pp) {
+ if(list->stmt->d.stmt_pp.pp_type == ae_pp_include)
+ env->name = list->stmt->d.stmt_pp.data;
+ else if(list->stmt->d.stmt_pp.pp_type == ae_pp_require)
+ CHECK_BB(plugin_ini(env->gwion, list->stmt->d.stmt_pp.data))
+ } while((list = list->next));
return GW_OK;
}
ANN static m_bool scan0_class_def_inner(const Env env, const Class_Def cdef) {
CHECK_OB((cdef->base.type = scan0_class_def_init(env, cdef)))
- SET_FLAG(cdef->base.type, scan0);
+ set_tflag(cdef->base.type, tflag_scan0);
if(cdef->body)
CHECK_BB(env_body(env, cdef, scan0_section))
(void)mk_class(env, cdef->base.type);
}
ANN m_bool scan0_class_def(const Env env, const Class_Def c) {
- const Class_Def cdef = !tmpl_base(c->base.tmpl) ?
- c : cpy_class_def(env->gwion->mp, c);
- if(GET_FLAG(cdef, global)) {
+ const int cpy = tmpl_base(c->base.tmpl) || GET_FLAG(c, global);
+ const Class_Def cdef = !cpy ? c : cpy_class_def(env->gwion->mp, c);
+ if(GET_FLAG(cdef, global)) { // could be updated
vector_add(&env->scope->nspc_stack, (vtype)env->curr);
env->curr = env->global_nspc;
context_global(env);
scan0_class_def_inner(env, cdef) : GW_ERROR;
if(GET_FLAG(cdef, global))
env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
- CHECK_BB(ret)
- if(GET_FLAG(cdef, global) || (cdef->base.tmpl && !cdef->base.tmpl->call))
+ if(cpy && cdef->base.type) {
c->base.type = cdef->base.type;
- SET_FLAG(cdef->base.type, scan0);
- return GW_OK;
+ c->base.type->e->cdef = cdef;
+ set_tflag(c->base.type, tflag_cdef);
+ set_tflag(cdef->base.type, tflag_scan0);// redundant
+ }
+ return ret;
}
ANN m_bool scan0_ast(const Env env, Ast ast) {
ANN static inline m_bool ensure_scan1(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan1_cdef,
- .scope=env->scope->depth, .flag=ae_flag_scan1 };
+ .scope=env->scope->depth, .flag=tflag_scan1 };
return envset_run(&es, t);
}
const Type t = get_type(type);
if(!env->func && env->class_def && !GET_FLAG(td, ref))
CHECK_BO(type_cyclic(env, t, td))
- if(!GET_FLAG(t, scan1) && t->e->def)
+ if(!tflag(t, tflag_scan1))
CHECK_BO(ensure_scan1(env, t))
return type;
}
DECL_OO(const Type ,t, = void_type(env, decl->td))
if(decl->td->xid == insert_symbol("auto") && decl->type)
return decl->type;
- if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
- SET_FLAG(decl->td, member);
if(GET_FLAG(t, private) && t->e->owner != env->curr)
ERR_O(exp_self(decl)->pos, _("can't use private type %s"), t->name)
if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
Type t = decl->type;
CHECK_BB(scan1_defined(env, var))
- if(var->array) {
+ if(var->array) {
if(var->array->exp) {
if(GET_FLAG(decl->td, ref))
ERR_B(var->array->exp->pos, _("ref array must not have array expression.\n"
ERR_B(exp_self(decl)->pos, _("Type '%s' is abstract, declare as ref. (use @)"), t->name)
}
const Value v = var->value = var->value ?: new_value(env->gwion->mp, t, s_name(var->xid));
- if(SAFE_FLAG(env->class_def, struct) && !GET_FLAG(decl->td, static)) {
+// rewrite logic
+ if(!env->scope->depth && env->class_def && !GET_FLAG(decl->td, static))
+ set_vflag(v, vflag_member);
+ if(safe_tflag(env->class_def, tflag_struct) && !GET_FLAG(decl->td, static)) {
v->from->offset = env->class_def->size;
env->class_def->size += t->size;
}
nspc_add_value(env->curr, var->xid, v);
- v->flag = decl->td->flag;
+ v->flag |= decl->td->flag;
v->type = t;
if(var->array && !var->array->exp)
- SET_FLAG(v, ref);
+ SET_FLAG(decl->td, ref);
if(env->class_def) {
if(env->class_def->e->tuple)
tuple_contains(env, v);
} else if(!env->scope->depth)
- SET_FLAG(v, global);
+ set_vflag(v, vflag_fglobal);// file global
v->d.ptr = var->addr;
if(GET_FLAG(decl->td, global))
- SET_FLAG(v, abstract);
+ SET_FLAG(v, global);
if(!env->scope->depth)
valuefrom(env, v->from);
} while((list = list->next));
CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
CHECK_OB(decl->type)
- if(GET_FLAG(decl->type, const))
- exp_setmeta(exp_self(decl), 1);
const m_bool global = GET_FLAG(decl->td, global);
if(global) {
if(env->context)
SET_ACCESS(edef, v)
SET_ACCESS(edef, edef->t)
}
- SET_FLAG(v, const | ae_flag_enum | ae_flag_valid);
+ SET_FLAG(v, const);
+ set_vflag(v, vflag_valid);
+ set_vflag(v, vflag_enum);
nspc_add_value(edef->t->e->owner, list->xid, v);
vector_add(&edef->values, (vtype)v);
} while((list = list->next));
const Value v = new_value(env->gwion->mp, list->type, var->xid ? s_name(var->xid) : (m_str)__func__);
if(var->array)
v->type = list->type = array_type(env, list->type, var->array->depth);
- if(list->td)
- v->flag = list->td->flag | ae_flag_abstract;
+ if(list->td) {
+ v->flag = list->td->flag;
+// SET_FLAG(v, global); ???
+ }
return v;
}
ANN m_bool scan1_type_def(const Env env, const Type_Def tdef) {
if(!tdef->type)
tdef->type = nspc_lookup_type0(env->curr, tdef->xid);
- if(!tdef->type->e->def)return GW_OK;
- return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type->e->def) : GW_OK;
+ if(!tdef->type->e->cdef)return GW_OK;
+ return !is_fptr(env->gwion, tdef->type) ? scan1_cdef(env, tdef->type) : GW_OK;
}
ANN static m_bool scan1_union_def_action(const Env env, const Union_Def udef,
const Decl_List l) {
const Exp_Decl decl = l->self->d.exp_decl;
- SET_FLAG(decl.td, valid | udef->flag);
+ decl.td->flag |= udef->flag;
const m_bool global = GET_FLAG(udef, global);
if(global)
UNSET_FLAG(decl.td, global);
- if(GET_FLAG(udef, member))
- SET_FLAG(decl.td, member);
else if(GET_FLAG(udef, static))
SET_FLAG(decl.td, static);
CHECK_BB(scan1_exp(env, l->self))
Var_Decl_List list = decl.list;
- do ADD_REF(list->self->value)
+ do value_addref(list->self->value);
while((list = list->next));
if(global)
}
const m_bool ret = scan1_union_def_inner(env, udef);
union_pop(env, udef, scope);
- union_flag(udef, ae_flag_scan1);
+ union_flag(udef, tflag_scan1);
return ret;
}
ANN m_bool scan1_fbody(const Env env, const Func_Def fdef) {
if(fdef->base->args) {
- if(!GET_FLAG(fdef->base, builtin))
- CHECK_BB(scan1_fdef_args(env, fdef->base->args))
+ CHECK_BB(scan1_fdef_args(env, fdef->base->args))
CHECK_BB(scan1_args(env, fdef->base->args))
}
- if(!GET_FLAG(fdef->base, builtin) && fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
+ if(fdef->d.code && fdef->d.code->d.stmt_code.stmt_list)
CHECK_BB(scan1_stmt_list(env, fdef->d.code->d.stmt_code.stmt_list))
return GW_OK;
}
ANN m_bool scan1_fdef(const Env env, const Func_Def fdef) {
if(fdef->base->td)
CHECK_OB((fdef->base->ret_type = known_type(env, fdef->base->td)))
- if(GET_FLAG(fdef->base, typedef))
+ if(fbflag(fdef->base, fbflag_internal))
CHECK_BB(scan_internal(env, fdef->base))
- else if(GET_FLAG(fdef->base, op) && env->class_def)
+ else if(fbflag(fdef->base, fbflag_op) && env->class_def)
SET_FLAG(fdef->base, static);
RET_NSPC(scan1_fbody(env, fdef))
return GW_OK;
if(cdef->base.ext->array)
CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
+// if(GET_FLAG(parent, abstract)) // could be final
+//SET_FLAG(cdef->base.type, abstract);
+// ERR_B(td_pos(cdef->base.ext), _("can't inherit from abstract parent class '%s'\n."), parent->name);
if(isa(parent, env->gwion->type[et_object]) < 0)
ERR_B(pos, _("cannot extend primitive type '%s'"), parent->name)
- if(parent->e->def && !GET_FLAG(parent, scan1))
+ if(!tflag(parent, tflag_scan1))
CHECK_BB(ensure_scan1(env, parent))
if(type_ref(parent))
ERR_B(pos, _("can't use ref type in class extend"))
- if(GET_FLAG(parent, nonnull))
+ if(tflag(parent, tflag_nonnull))
ERR_B(pos, _("can't use nonnull type in class extend"))
return GW_OK;
}
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(GET_FLAG(t, scan1))
+ if(tflag(t, tflag_scan1))
return GW_OK;
- SET_FLAG(t, scan1);
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan1))
+ set_tflag(t, tflag_scan1);
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan1))
CHECK_BB(ensure_scan1(env, t->e->owner_class))
- SET_FLAG(cdef->base.type, scan1);
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
if(cdef->body)
ANN static inline m_bool ensure_scan2(const Env env, const Type t) {
struct EnvSet es = { .env=env, .data=env, .func=(_exp_func)scan2_cdef,
- .scope=env->scope->depth, .flag=ae_flag_scan2 };
+ .scope=env->scope->depth, .flag=tflag_scan2 };
return envset_run(&es, t);
}
ANN static m_bool scan2_decl(const Env env, const Exp_Decl* decl) {
const Type t = get_type(decl->type);
- if(t->e->def && !GET_FLAG(t, scan2))
+ if(!tflag(t, tflag_scan2))
CHECK_BB(ensure_scan2(env, t))
Var_Decl_List list = decl->list;
do {
ANN static Value scan2_func_assign(const Env env, const Func_Def d,
const Func f, const Value v) {
valuefrom(env, v->from);
- SET_FLAG(v, func | ae_flag_const);
+ SET_FLAG(v, const);
+ set_vflag(v, vflag_func);
if(!env->class_def)
- SET_FLAG(v, global);
+ set_vflag(v, vflag_fglobal);
else {
- if(GET_FLAG(f, member))
- SET_FLAG(v, member);
- else SET_FLAG(v, static);
+ if(GET_FLAG(d->base, static))
+ SET_FLAG(v, static);
+ else
+ set_vflag(v, vflag_member);
SET_ACCESS(d->base, v)
- }
+ }
d->base->func = v->d.func_ref = f;
return f->value_ref = v;
}
RET_NSPC(scan2_args(def))
}
} else
- SET_FLAG(fptr->type, func);
+ set_tflag(fptr->type, tflag_ftmpl);
return GW_OK;
}
ANN m_bool scan2_type_def(const Env env, const Type_Def tdef) {
- if(!tdef->type->e->def) return GW_OK;
- return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->def) : GW_OK;
+ if(!tdef->type->e->cdef) return GW_OK;
+ return !is_fptr(env->gwion, tdef->type) ? scan2_class_def(env, tdef->type->e->cdef) : GW_OK;
}
ANN static inline Value prim_value(const Env env, const Symbol s) {
if(prim->prim_type == ae_prim_hack || prim->prim_type == ae_prim_typeof ||
prim->prim_type == ae_prim_interp)
CHECK_BB(scan2_exp(env, prim->d.exp))
- else if(prim->prim_type == ae_prim_id) {
+/* else if(prim->prim_type == ae_prim_id) {
const Value v = prim_value(env, prim->d.var);
if(v)
- SET_FLAG(v, used);
- } else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
+ v->vflag |= used;
+ } */else if(prim->prim_type == ae_prim_array && prim->d.array->exp)
return scan2_exp(env, prim->d.array->exp);
else if(prim->prim_type == ae_prim_range)
return scan2_range(env, prim->d.range);
if(e->exp_type == ae_exp_decl) {
if(e->d.exp_decl.list->next)
ERR_B(e->pos, _("cant '%s' from/to a multi-variable declaration."), s_name(op))
- SET_FLAG(e->d.exp_decl.list->self->value, used);
+// set_vflag(e->d.exp_decl.list->self->value, vflag_used);
}
return GW_OK;
}
const m_uint scope = union_push(env, udef);
const m_bool ret = scan2_union_decl(env, udef->l);
union_pop(env, udef, scope);
- union_flag(udef, ae_flag_scan2);
+ union_flag(udef, tflag_scan2);
return ret;
}
}
ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) {
- const m_bool base = tmpl_base(f->base->tmpl);
- const m_bool tmpl = GET_FLAG(overload, template);
+ const m_bool fptr = is_fptr(env->gwion, overload->type);
if(isa(overload->type, env->gwion->type[et_function]) < 0 || is_fptr(env->gwion, overload->type)) {
- if(!GET_FLAG(f->base, typedef))
+ if(!fbflag(f->base, fbflag_internal))
ERR_B(f->pos, _("function name '%s' is already used by another value"), overload->name)
}
- if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f->base, template)))
+ const Func obase = !fptr ? overload->d.func_ref : overload->type->e->d.base_type->e->d.func;
+ if(GET_FLAG(obase->def->base, final))
+ ERR_B(f->pos, _("can't overload final function %s"), overload->name)
+ const m_bool base = tmpl_base(f->base->tmpl);
+ const m_bool tmpl = fflag(obase, fflag_tmpl);
+ if((!tmpl && base) || (tmpl && !base && !f->base->tmpl))
ERR_B(f->pos, _("must overload template function with template"))
return GW_OK;
}
ANN static Func scan_new_func(const Env env, const Func_Def f, const m_str name) {
const Func func = new_func(env->gwion->mp, name, f);
if(env->class_def) {
- if(GET_FLAG(env->class_def, template))
- SET_FLAG(func, ref);
- if(!GET_FLAG(f->base, static))
- SET_FLAG(func, member);
+ if(tflag(env->class_def, tflag_tmpl))
+ set_fflag(func, fflag_ftmpl);
}
return func;
}
t->name = func->name;
t->e->owner = env->curr;
t->e->owner_class = env->class_def;
- if(GET_FLAG(func, member))
- t->size += SZ_INT;
t->e->d.func = func;
return t;
}
valuefrom(env, v->from);
CHECK_OO(scan2_func_assign(env, f->def, f, v))
if(!overload) {
- ADD_REF(v);
+ value_addref(v);
nspc_add_value_front(env->curr, f->def->base->xid, v);
} else if(overload->d.func_ref) {
f->next = overload->d.func_ref->next;
overload->d.func_ref->next = f;
}
+ if(env->class_def && !GET_FLAG(f->def->base, static)) {
+ t->size += SZ_INT;
+ set_vflag(v, vflag_member);
+ }
return v;
}
-ANN static m_bool scan2_func_def_builtin(MemPool p, const Func func, const m_str name) {
- SET_FLAG(func, builtin);
- SET_FLAG(func->value_ref, builtin);
- func->code = new_vm_code(p, NULL, func->def->stack_depth, func->flag, name);
- func->code->native_func = (m_uint)func->def->d.dl_func_ptr;
- return GW_OK;
-}
-
ANN2(1, 2) static m_bool scan2_fdef_tmpl(const Env env, const Func_Def f, const Value overload) {
const m_str name = s_name(f->base->xid);
const Func func = scan_new_func(env, f, name);
const Value value = func_value(env, func, overload);
- SET_FLAG(value, valid | ae_flag_template);
- SET_FLAG(value->type, func); // the only types with func flag, name could be better
+ set_fflag(func, fflag_tmpl);
+ set_vflag(value, vflag_valid);
+ set_tflag(value->type, tflag_ftmpl); // the only types with func flag, name could be better
Type type = env->class_def;
Nspc nspc = env->curr;
uint i = 0;
"template", ff->vt_index);
nspc_add_value(env->curr, sym, value);
if(!overload) {
- ADD_REF(value)
+ value_addref(value);
nspc_add_value(env->curr, f->base->xid, value);
}
func->vt_index = ff->vt_index;
const Symbol sym = func_symbol(env, env->curr->name, name, "template", i);
nspc_add_value(env->curr, sym, value);
if(!overload) {
- ADD_REF(value)
+ value_addref(value);
nspc_add_value(env->curr, f->base->xid, value);
nspc_add_func(env->curr, f->base->xid, func);
} else
func->vt_index = ++overload->from->offset;
- if(GET_FLAG(f->base, builtin)) {
- CHECK_BB(scan2_func_def_builtin(env->gwion->mp, func, func->name))
- SET_FLAG(func, builtin);
- SET_FLAG(value, builtin);
- }
return GW_OK;
}
}
ANN static void scan2_func_def_flag(const Env env, const Func_Def f) {
- if(!GET_FLAG(f->base, builtin))
- SET_FLAG(f->base->func, pure);
+ set_fflag(f->base->func, fflag_pure);
if(f->base->xid == insert_symbol("@dtor"))
- SET_FLAG(env->class_def, dtor);
+ set_tflag(env->class_def, tflag_dtor);
}
ANN static m_str func_tmpl_name(const Env env, const Func_Def f) {
nspc_add_func(env->curr, insert_symbol(func->name), func);
const Value v = func_value(env, func, overload);
scan2_func_def_flag(env, f);
- if(GET_FLAG(f->base, builtin))
- CHECK_BO(scan2_func_def_builtin(env->gwion->mp, func, func->name))
nspc_add_value(env->curr, insert_symbol(func->name), v);
return v;
}
f->base->func = base;
if(f->base->args)
CHECK_BB(scan2_args(f))
- if(!GET_FLAG(f->base, builtin) && f->d.code)
+ if(f->d.code)
CHECK_BB(scan2_func_def_code(env, f))
if(!base) {
- if(GET_FLAG(f->base, op))
+ if(fbflag(f->base, fbflag_op))
CHECK_BB(scan2_func_def_op(env, f))
- SET_FLAG(f->base->func->value_ref, valid);
+ set_vflag(f->base->func->value_ref, vflag_valid);
}
return GW_OK;
}
fdef : scan2_cpy_fdef(env, fdef);
const m_uint scope = !GET_FLAG(f->base, global) ? env->scope->depth : env_push_global(env);
f->stack_depth = (env->class_def && !GET_FLAG(f->base, static) && !GET_FLAG(f->base, global)) ? SZ_INT : 0;
- if(GET_FLAG(f->base, variadic))
+ if(fbflag(f->base, fbflag_variadic))
f->stack_depth += SZ_INT;
const m_bool ret = scanx_fdef(env, env, f, (_exp_func)scan2_fdef);
if(GET_FLAG(f->base, global))
ANN static m_bool scan2_parent(const Env env, const Class_Def cdef) {
const Type parent = cdef->base.type->e->parent;
- if(parent->e->def && !GET_FLAG(parent, scan2))
+ if(!tflag(parent, tflag_scan2))
CHECK_BB(ensure_scan2(env, parent))
if(cdef->base.ext->array)
CHECK_BB(scan2_exp(env, cdef->base.ext->array->exp))
if(tmpl_base(cdef->base.tmpl))
return GW_OK;
const Type t = cdef->base.type;
- if(GET_FLAG(t, scan2))return GW_OK;
- if(t->e->owner_class && !GET_FLAG(t->e->owner_class, scan2))
+ if(tflag(t, tflag_scan2))
+ return GW_OK;
+ if(t->e->owner_class && !tflag(t->e->owner_class, tflag_scan2))
CHECK_BB(ensure_scan2(env, t->e->owner_class))
- SET_FLAG(t, scan2);
+ set_tflag(t, tflag_scan2);
if(cdef->base.ext)
CHECK_BB(cdef_parent(env, cdef))
if(cdef->body)
__attribute__((returns_nonnull))
ANN Type unflag_type(const Type t) {
- const Type type = !GET_FLAG(t, nonnull) ? t : t->e->parent;
- return !GET_FLAG(type, force) ? type : type->e->parent;
+ const Type type = !tflag(t, tflag_nonnull) ? t : t->e->parent;
+ return !tflag(type, tflag_force) ? type : type->e->parent;
}
__attribute__((returns_nonnull))
return unflag_type(type);
}
-ANN m_bool scanx_cdef(const Env env, void* opt, const Class_Def cdef,
+ANN m_bool scanx_cdef(const Env env, void* opt, const Type base,
const _exp_func f_cdef, const _exp_func f_union) {
- const Type t = get_type(cdef->base.type);
+ const Type t = get_type(base);
if(t->e->parent != env->gwion->type[et_union])
- return f_cdef(opt, t->e->def);
- CHECK_BB(template_push_types(env, t->e->def->base.tmpl))
- const m_bool ret = f_union(opt, t->e->def->union_def);
- nspc_pop_type(env->gwion->mp, env->curr);
+ return f_cdef(opt, t->e->cdef);
+ const m_bool ret = f_union(opt, t->e->udef);
return ret;
}
env_pop(env, scope);
}
-ANN void union_flag(const Union_Def udef, const ae_flag flag) {
+ANN void union_flag(const Union_Def udef, const enum tflag flag) {
const Type type = udef->xid || !udef->type_xid ?
udef->value->type : udef->type;
- type->flag |= flag;
+ type->tflag |= flag;
}
ANN static m_bool _template_push(const Env env, const Type t) {
if(t->e->owner_class)
CHECK_BB(template_push(env, t->e->owner_class))
- if(GET_FLAG(t, template))
- return push_types(env, t->e->def->base.tmpl);
+ if(tflag(t, tflag_tmpl))
+ return push_types(env, t->e->cdef->base.tmpl); // incorrect
return GW_OK;
}
if(base_type)
return base_type;
const Type ret = type_copy(env->gwion->mp, t);
- ADD_REF(ret->nspc)
ret->e->parent = t;
ret->name = s_name(sym);
- SET_FLAG(ret, func);
+ set_tflag(ret, tflag_ftmpl);
nspc_add_type_front(t->e->owner, sym, ret);
+ void* func_ptr = t->e->d.func->def->d.dl_func_ptr;
+ if(vflag(t->e->d.func->value_ref, vflag_builtin))
+ t->e->d.func->def->d.dl_func_ptr = NULL;
const Func_Def def = cpy_func_def(env->gwion->mp, t->e->d.func->def);
const Func func = ret->e->d.func = new_func(env->gwion->mp, s_name(sym), def);
const Value value = new_value(env->gwion->mp, ret, s_name(sym));
func->flag = def->base->flag;
+ if(vflag(t->e->d.func->value_ref, vflag_member))
+ set_vflag(value, vflag_member);
value->d.func_ref = func;
value->from->owner = t->e->owner;
value->from->owner_class = t->e->owner_class;
func->def->base->tmpl = mk_tmpl(env, t->e->d.func->def->base->tmpl, td->types);
def->base->func = func;
nspc_add_value_front(t->e->owner, sym, value);
+ if(vflag(t->e->d.func->value_ref, vflag_builtin)) {
+ builtin_func(env->gwion->mp, func, func_ptr);
+ t->e->d.func->def->d.dl_func_ptr = func_ptr;
+ }
return ret;
}
}
ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) {
- if(GET_FLAG(t, template) && isa(t, env->gwion->type[et_function]) < 0) {
- if(GET_FLAG(t, ref) || (GET_FLAG(t, unary) && !td->types))
+ if(tflag(t, tflag_tmpl) && isa(t, env->gwion->type[et_function]) < 0) {
+ if(tflag(t, tflag_ctmpl) || (tflag(t, tflag_ntmpl) && !td->types))
return t;
struct TemplateScan ts = { .t=t, .td=td };
struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td_pos(td), .op_type=op_scan };
if(!owner->nspc)
ERR_O(td_pos(td), "type '%s' has no namespace", owner->name)
struct EnvSet es = { .env=env, .data=env,
- .scope=env->scope->depth, .flag=ae_flag_none };
+ .scope=env->scope->depth, .flag=tflag_none };
envset_push(&es, owner, owner->nspc);
(void)env_push(env, owner, owner->nspc);// TODO: is this needed?
const Type ret = scan_type(env, t, td->next);
ANN m_bool traverse_class_def(const Env env, const Class_Def def) {
const Type t = def->base.type;
- if(!GET_FLAG(t, scan1))
+ if(!tflag(t, tflag_scan1))
CHECK_BB(scan1_class_def(env, def))
- if(!GET_FLAG(t, scan2))
+ if(!tflag(t, tflag_scan2))
CHECK_BB(scan2_class_def(env, def))
- if(!GET_FLAG(t, valid))
+ if(!tflag(t, tflag_check))
return check_class_def(env, def);
return GW_OK;
}
#ifndef BUILD_ON_WINDOWS
#include <glob.h>
#include <dlfcn.h>
+#include <limits.h>
#else
#include <windows.h>
#endif
#include "instr.h"
#include "object.h"
#include "import.h"
+#include "gwi.h"
-typedef m_bool (*import)(Gwi);
-typedef m_str (*modstr)(void);
+typedef m_bool (*plugin)(Gwi);
typedef void* (*modini)(const struct Gwion_*, const Vector);
-typedef void* (*modrun)(const struct Gwion_*, void*);
typedef void* (*modend)(const struct Gwion_*, void*);
+typedef m_str* (*gwdeps)(void);
-struct Plug_ {
- m_str name;
- modini ini;
- modend end;
- void* self;
-};
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
#ifndef BUILD_ON_WINDOWS
struct PlugHandle {
MemPool mp;
- PlugInfo* pi;
- void *dl;
- m_str file;
- m_str name;
+ Map map;
+ size_t len;
};
-ANN static struct Plug_* new_plug(MemPool p, const modini ini) {
+typedef struct Plug_ {
+ void *dl;
+ void *self;
+ int imp;
+} *Plug;
+
+ANN static struct Plug_* new_plug(MemPool p, void *dl) {
struct Plug_ *plug = mp_calloc(p, Plug);
- plug->ini = ini;
+ plug->dl = dl;
return plug;
}
-ANN static void plug_import(struct PlugHandle *h) {
- const import imp = DLSYM(h->dl, import, GWIMPORT_NAME);
- if(imp)
- vector_add(&h->pi->vec[GWPLUG_IMPORT], (vtype)imp);
-}
-
-ANN static void plug_module(struct PlugHandle *h) {
- const modini ini = DLSYM(h->dl, modini, GWMODINI_NAME);
- if(ini) {
- struct Plug_ *plug = new_plug(h->mp, ini);
- plug->name = h->name;
- plug->end = DLSYM(h->dl, modend, GWMODEND_NAME);
- vector_add(&h->pi->vec[GWPLUG_MODULE], (vtype)plug);
- }
-}
-
-ANN static void plug_driver(struct PlugHandle *h) {
- const f_bbqset drv = DLSYM(h->dl, f_bbqset, GWDRIVER_NAME);
- if(drv)
- map_set(&h->pi->drv, (vtype)h->name, (vtype)drv);
-}
-
-ANN static inline m_str plug_name(struct PlugHandle *h) {
- const modstr str = DLSYM(h->dl, modstr, GWMODSTR_NAME);
- return str ? str() : NULL;
-}
-
ANN static void plug_get(struct PlugHandle *h, const m_str c) {
- h->dl = DLOPEN(c, RTLD_LAZY | RTLD_GLOBAL);
- if(h->dl) {
- vector_add(&h->pi->vec[GWPLUG_DL], (vtype)h->dl);
- h->name = plug_name(h);
- plug_import(h);
- plug_module(h);
- plug_driver(h);
+ void *dl = DLOPEN(c, RTLD_LAZY | RTLD_GLOBAL);
+ const m_str pname = c + h->len + 1;
+ const size_t sz = strlen(pname) - 3;
+ char name[PATH_MAX];
+ memcpy(name, pname, sz);
+ name[sz] = '\0';
+ if(dl) {
+ Plug plug = new_plug(h->mp, dl);
+ map_set(h->map, (vtype)strdup(name), (vtype)plug);
} else
gw_err(_("error in %s."), DLERROR());
}
strcpy(c, name);
strcpy(c + strlen(name) - 4, filedata.cFileName);
plug_get(h, c);
- } while(FindNextFile(file,&filedata));
+ } while(FindNextFile(file, &filedata));
FindClose(file);
#endif
}
-ANN2(1) static void* pp_ini(const struct Gwion_ *gwion, const Vector v) {
- pparg_run(gwion->ppa, v);
- return NULL;
-}
-
-ANN static void register_pp(const struct PlugHandle* h) {
- struct Plug_ *plug = new_plug(h->mp, pp_ini);
- plug->name = "pp";
- vector_add(&h->pi->vec[GWPLUG_MODULE], (vtype)plug);
-}
-
-ANN PlugInfo* new_pluginfo(MemPool p, const Vector list) {
- PlugInfo *pi = (PlugInfo*)mp_calloc(p, PlugInfo);
- for(m_uint i = 0; i < GWPLUG_LAST; ++i)
- vector_init(&pi->vec[i]);
- map_init(&pi->drv);
- struct PlugHandle h = { .mp=p, .pi=pi };
- register_pp(&h);
+ANN m_bool plug_ini(const struct Gwion_ *gwion, const Vector list) {
+ const Map map = &gwion->data->plug;
+ map_init(map);
+ struct PlugHandle h = { .mp=gwion->mp, .map=map };
for(m_uint i = 0; i < vector_size(list); i++) {
const m_str dir = (m_str)vector_at(list, i);
- char name[strlen(dir) + 6];
+ h.len = strlen(dir);
+ char name[PATH_MAX];
sprintf(name, "%s/*.so", dir);
plug_get_all(&h, name);
}
- return pi;
+ return GW_OK;
}
-ANN static void plug_free_module(const struct Gwion_* gwion, const Vector v) {
- for(m_uint i = 0; i < vector_size(v); ++i) {
- struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
- if(plug->end)
- plug->end(gwion, plug->self);
- mp_free(gwion->mp, Plug, plug);
+void free_plug(const struct Gwion_ *gwion) {
+ const Map map = &gwion->data->plug;
+ for(m_uint i = 0; i < map_size(map); ++i) {
+ const Plug plug = (Plug)VVAL(map, i);
+ const modend end = DLSYM(plug->dl, modend, GWMODEND_NAME);
+ if(end)
+ end(gwion, plug->self);
+ free((m_str)VKEY(map, i));
+ DLCLOSE(plug->dl);
}
+ map_release(map);
}
-ANN static inline void plug_free_dls(const Vector v) {
+ANN static void plug_free_arg(MemPool p, const Vector v) {
for(m_uint i = 0; i < vector_size(v); ++i)
- DLCLOSE((void*)vector_at(v, i));
-}
-
-void free_plug(const struct Gwion_ *gwion) {
- PlugInfo *p = gwion->data->plug;
- struct Vector_ * const v = p->vec;
- plug_free_module(gwion, &v[GWPLUG_MODULE]);
- plug_free_dls(&v[GWPLUG_DL]);
- for(m_uint i = 0; i < GWPLUG_LAST; ++i)
- vector_release(&v[i]);
- map_release(&p->drv);
- mp_free(gwion->mp, PlugInfo, p);
+ free_mstr(p, (m_str)vector_at(v, i));
+ free_vector(p, v);
}
-ANN static Vector get_arg(MemPool p, const m_str name, const Vector v) {
- const size_t len = strlen(name);
- for(m_uint i = vector_size(v) + 1; --i;) {
- const m_str str = (m_str)vector_at(v, i - 1);
- if(!strncmp(name, str, len)) {
- vector_rem(v, i-1);
- const m_str arg = strchr(str, '=');
- return arg ? split_args(p, arg+1) : NULL;
+ANN void set_module(const struct Gwion_ *gwion, const m_str name, void *const ptr) {
+ const Map map = &gwion->data->plug;
+ for(m_uint j = 0; j < map_size(map); ++j) {
+ if(!strcmp(name, (m_str)VKEY(map, j))) {
+ Plug plug = (Plug)VVAL(map, j);
+ plug->self = ptr;
+ return;
}
}
- return NULL;
}
-ANN static void plug_free_arg(MemPool p, const Vector v) {
- for(m_uint i = 0; i < vector_size(v); ++i)
- free_mstr(p, (m_str)vector_at(v, i));
- free_vector(p, v);
+ANN void plug_run(const struct Gwion_ *gwion, const Map mod) {
+ const Map map = &gwion->data->plug;
+ for(m_uint i = 0; i < map_size(mod); ++i) {
+ const m_str name = (m_str)VKEY(mod, i);
+ const m_str opt = (m_str)VVAL(mod, i);
+ for(m_uint j = 0; j < map_size(map); ++j) {
+ if(!strcmp(name, (m_str)VKEY(map, j))) {
+ Plug plug = (Plug)VVAL(map, j);
+ const Vector arg = opt ? split_args(gwion->mp, opt) : NULL;
+ const modini ini = DLSYM(plug->dl, modini, GWMODINI_NAME);
+ plug->self = ini(gwion, arg);
+ if(arg)
+ plug_free_arg(gwion->mp, arg);
+ }
+ }
+ }
}
-ANN void plug_run(const struct Gwion_ *gwion, const Vector args) {
- const Vector v = &gwion->data->plug->vec[GWPLUG_MODULE];
- for(m_uint i = 0; i < vector_size(v); ++i) {
- struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
- const Vector arg = get_arg(gwion->mp, plug->name, args);
- plug->self = plug->ini(gwion, arg);
- if(arg)
- plug_free_arg(gwion->mp, arg);
+ANN static m_bool dependencies(struct Gwion_ *gwion, const Plug plug) {
+ const gwdeps dep = DLSYM(plug->dl, gwdeps, GWDEPEND_NAME);
+ if(dep) {
+ m_str *const base = dep();
+ m_str *deps = base;
+ while(*deps) {
+ CHECK_BB(plugin_ini(gwion, *deps))
+ ++deps;
+ }
}
+ return GW_OK;
+}
+
+ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname) {
+ const Map map = &gwion->data->plug;
+ for(m_uint i = 0; i < map_size(map); ++i) {
+ const Plug plug = (Plug)VVAL(map, i);
+ const m_str name = (m_str)VKEY(map, i);
+ if(!strcmp(name, iname)) {
+ if(plug->imp)
+ return GW_OK;
+ const plugin imp = DLSYM(plug->dl, plugin, GWIMPORT_NAME);
+ if(!imp)
+ break;
+ plug->imp = 1;
+ CHECK_BB(dependencies(gwion, plug))
+ const m_uint scope = env_push_global(gwion->env);
+ const m_bool ret = gwi_run(gwion, imp);
+ env_pop(gwion->env, scope);
+ return ret;
+ }
+ }
+ gw_err("no such plugin '%s'\n", iname);
+ return GW_ERROR;
+}
+
+ANN m_bool driver_ini(const struct Gwion_ *gwion) {
+ const Map map = &gwion->data->plug;
+ m_str dname = gwion->vm->bbq->si->arg;
+ m_str opt = strchr(dname, '=');
+ const char c = opt ? *opt : '\0';
+ if(opt)
+ *opt = '\0';
+ for(m_uint i = 0; i < map_size(map); ++i) {
+ const m_str name = (m_str)VKEY(map, i);
+ if(!strcmp(name, dname)) {
+ const Plug plug = (Plug)VVAL(map, i);
+ const f_bbqset drv = DLSYM(plug->dl, f_bbqset, GWDRIVER_NAME);
+ if(!drv)
+ break;
+ gwion->vm->bbq->func = drv;
+ if(opt)
+ *opt = c;
+ return GW_OK;
+ }
+ }
+ gw_err("can't find driver '%s'\n", dname);
+ return GW_ERROR;
}
ANN void* get_module(const struct Gwion_ *gwion, const m_str name) {
- const Vector v = &gwion->data->plug->vec[GWPLUG_MODULE];
- for(m_uint i = 0; i < vector_size(v); ++i) {
- struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
- if(!strcmp(name, plug->name))
+ const Map map = &gwion->data->plug;
+ for(m_uint i = 0; i < map_size(map); ++i) {
+ if(!strcmp(name, (m_str)VKEY(map, i))) {
+ const Plug plug = (Plug)VVAL(map, i);
return plug->self;
+ }
}
return NULL;
}
ANN void gack(const VM_Shred shred, const m_uint offset) {
const Type t = *(Type*)shred->reg;
const VM_Code code = get_gack(t)->e->gack;
- if(GET_FLAG(code, builtin)) {
+ if(code->builtin) {
const m_uint sz = *(m_uint*)(shred->reg + SZ_INT);
((f_gack)code->native_func)(t, (shred->reg - sz), shred);
POP_REG(shred, sz);
} else {
prepare_call(shred, offset);
- if(GET_FLAG(t, struct))
+ if(tflag(t, tflag_struct))
*(void**)(shred->mem) = (void*)(shred->reg - t->size);
else
*(M_Object*)(shred->mem) = *(M_Object*)(shred->reg - SZ_INT);
PRAGMA_PUSH()
reg -= SZ_INT;
a.code = *(VM_Code*)reg;
- if(!GET_FLAG((VM_Code)a.code, builtin)) {
+ if(!a.code->builtin) {
register const m_uint push = *(m_uint*)(reg + SZ_INT) + *(m_uint*)(mem-SZ_INT);
mem += push;
*(m_uint*) mem = push;mem += SZ_INT;
free_vector(gwion->mp, v);
}
-ANN static void free_vm_code(VM_Code a, Gwion gwion) {
+ANN void free_vm_code(VM_Code a, Gwion gwion) {
if(a->memoize)
memoize_end(gwion->mp, a->memoize);
- if(!GET_FLAG(a, builtin)) {
+ if(!a->builtin) {
_mp_free(gwion->mp, vector_size(a->instr) * SZ_INT, a->bytecode);
_free_code_instr(a->instr, gwion);
}
VM_Code new_vm_code(MemPool p, const Vector instr, const m_uint stack_depth,
- const ae_flag flag, const m_str name) {
+ const int builtin, const m_str name) {
VM_Code code = mp_calloc(p, VM_Code);
if(instr) {
code->instr = vector_copy(p, instr);
}
code->name = mstrdup(p, name);
code->stack_depth = stack_depth;
- code->flag = flag;
- code->ref = new_refcount(p, free_vm_code);
+ code->builtin = builtin;
+ code->ref = 1;
return code;
}
for(m_uint i = vector_size(&shred->gc) + 1; --i;)
release((M_Object)vector_at(&shred->gc, i - 1), shred);
vector_release(&shred->gc);
- REM_REF(shred->info->orig, shred->info->vm->gwion);
+ vmcode_remref(shred->info->orig, shred->info->vm->gwion);
const MemPool mp = shred->info->mp;
mp_free(mp, ShredTick, shred->tick);
free_shredinfo(mp, shred->info);
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#include "operator.h"
+#include "object.h"
+#include "instr.h"
+#include "import.h"
+
+GWION_IMPORT(end_class) {
+ (void)gwi;
+ return GW_OK;
+}
#include "gwion.h"
#include "plug.h"
-static DRVRUN(driver_test_run) {
+static DRVRUN(simple_driver_run) {
while(di->is_running) {
di->run(vm);
++di->pos;
}
}
-static DRVINI(driver_test_ini) {
+static DRVINI(simple_driver_ini) {
return GW_OK;
}
-static DRVDEL(driver_test_del) {}
+static DRVDEL(simple_driver_del) {}
-GWMODSTR(driver_test);
-
-GWDRIVER(driver_test) {
- d->ini = driver_test_ini;
- d->run = driver_test_run;
- d->del = driver_test_del;
+GWDRIVER(driver) {
+ d->ini = simple_driver_ini;
+ d->run = simple_driver_run;
+ d->del = simple_driver_del;
}
--- /dev/null
+#! [contains] override final
+class C {
+ fun final void test() { <<< "final" >>>;}
+}
+
+class D extends C {
+ fun void test() { <<< "final" >>>;}
+}
+var D d;
--- /dev/null
+#! [contains] inherit from final parent
+class final C {}
+
+class D extends C {}
--- /dev/null
+class C {
+ fun abstract void test(int i);
+}
--- /dev/null
+#! [contains] must be declared 'abstract'
+class abstract C {
+ fun abstract void test(int i);
+}
+
+class D extends C {}
+++ /dev/null
-#! [contains] can't inherit
-class C extends TypedFork:[int] {
-
-}
-
-var C c;
-c.exit();
--- /dev/null
+#require NonExisting
+
+var ftbl f;
+<<< var SinOsc s >>>;
return 12;
}
-fork test() @=> ref TypedFork:[int] sh;
+fork test() @=> ref auto sh;
<<< typeof(sh) >>>;
sh.ev => now;
<<< sh.retval >>>;
+++ /dev/null
-<<< testid >>>;
--- /dev/null
+INC = -I../../include -I../../util/include -I../../ast/include
+CC ?= gcc
+
+NAME := ${NAME}
+SRC = ${NAME}.c
+OBJ = $(SRC:.c=.o)
+CFLAGS += -std=c99 ${INC} -Wall -Wextra -g -Og
+
+# os specific
+ifeq ($(shell uname), Darwin)
+LDFLAGS += -bundle -undefined dynamic_lookup
+else
+ifeq ($(shell uname), Linux)
+LDFLAGS += -shared
+else
+LDFLAGS += -shared -lpsapi -fPIC -Wl,--export-all -Wl,--enable-auto-import
+LDFLAGS += -L../../ -lgwion
+LDLAGS += ../../libgwion.dll.a
+LDLAGS += ../../libgwion.a
+endif
+endif
+
+all: ${NAME}.so
+
+
+${NAME}.so: ${OBJ}
+ifeq (${USE_LD}, 1)
+ ${LD} $^ -o ${NAME}.so ${LDFLAGS}
+else
+ ${CC} $^ -o ${NAME}.so ${LDFLAGS}
+endif
+
+clean:
+ rm -f ${OBJ} ${NAME}.so
+
+.c.o:
+ ${CC} -fPIC ${CFLAGS} -c $< -o $(<:.c=.o) -g
+
+install: ${NAME}.so
+ install ${NAME}.so ${GWION_ADD_DIR}
+
+uninstall:
+ rm ${GWION_ADD_DIR}/${NAME}.so
#include "vm.h"
#include "gwion.h"
-GWMODSTR(basic_module)
-
GWMODINI(basic_module) {
puts("ini module");
if(args) {
#include "gwi.h"
#include "plug.h"
-GWMODSTR(dummy_module);
-
-GWMODINI(dummy_module) {
+GWMODINI(get_module) {
puts(__func__);
- return (void*)2; // we need to return something
+ return NULL;
}
-GWMODEND(dummy_module) {
+
+GWMODEND(get_module) {
puts(__func__);
}
GWION_IMPORT(dummy_module) {
- CHECK_OB(get_module(gwi->gwion, "dummy_module"))
+ set_module(gwi->gwion, "get_module", (void*)1);
+ CHECK_OB(get_module(gwi->gwion, "get_module"))
puts("test passed");
get_module(gwi->gwion, "non_existant_module");
return GW_OK;
--- /dev/null
+#require get_module
+<<< __file__ >>>;
#include "gwion.h"
#include "plug.h"
-GWMODSTR(dummy_module);
-
GWMODINI(dummy_module) {
puts(__func__);
return NULL;
--- /dev/null
+INC = -I../../include -I../../util/include -I../../ast/include
+CC ?= gcc
+
+NAME := ${NAME}
+SRC = ${NAME}.c
+OBJ = $(SRC:.c=.o)
+CFLAGS += -std=c99 ${INC} -Wall -Wextra -g -Og
+
+# os specific
+ifeq ($(shell uname), Darwin)
+LDFLAGS += -bundle -undefined dynamic_lookup
+else
+ifeq ($(shell uname), Linux)
+LDFLAGS += -shared
+else
+LDFLAGS += -shared -lpsapi -fPIC -Wl,--export-all -Wl,--enable-auto-import
+LDFLAGS += -L../../ -lgwion
+LDLAGS += ../../libgwion.dll.a
+LDLAGS += ../../libgwion.a
+endif
+endif
+
+all: ${NAME}.so
+
+
+${NAME}.so: ${OBJ}
+ifeq (${USE_LD}, 1)
+ ${LD} $^ -o ${NAME}.so ${LDFLAGS}
+else
+ ${CC} $^ -o ${NAME}.so ${LDFLAGS}
+endif
+
+clean:
+ rm -f ${OBJ} ${NAME}.so
+
+.c.o:
+ ${CC} -fPIC ${CFLAGS} -c $< -o $(<:.c=.o) -g
+
+install: ${NAME}.so
+ install ${NAME}.so ${GWION_ADD_DIR}
+
+uninstall:
+ rm ${GWION_ADD_DIR}/${NAME}.so
--- /dev/null
+#require array
+<<< __file__ >>>;
--- /dev/null
+#require array_in_var_name
+<<< __file__ >>>;
--- /dev/null
+#require array_in_var_name_fail
+<<< __file__ >>>;
--- /dev/null
+#require array_incoherent_in_var_name
+<<< __file__ >>>;
--- /dev/null
+#require array_invalid_in_var_name
+<<< __file__ >>>;
--- /dev/null
+#require callback
+<<< __file__ >>>;
GWI_OB(gwi_class_ini(gwi, ":[A,B]ClassTemplate", NULL))
gwi_class_xtor(gwi, class_template_ctor, NULL);
GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
- GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+ GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
- GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+ GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_func_ini(gwi, "int", ":[C,D]test"))
GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
+#require class_template
var ClassTemplate:[int, int] ct;
<<< ct.key >>>;
--- /dev/null
+#require class_template_fail
+<<< __file__ >>>;
GWION_IMPORT(class_template) {
GWI_OB(gwi_class_ini(gwi, "ClassTemplate:[A,B]", NULL))
GWI_BB(gwi_item_ini(gwi, "A[]", "key"))
- GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_member | ae_flag_template, NULL)))
+ GWI_BB((o_map_key = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_item_ini(gwi, "B[]", "value"))
- GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_member, NULL)))
+ GWI_BB((o_map_value = gwi_item_end(gwi, ae_flag_none, NULL)))
GWI_BB(gwi_func_ini(gwi, "int", "test:[C,D]"))
GWI_BB(gwi_func_end(gwi, (f_xfun)1, ae_flag_none))
--- /dev/null
+#require class_template_invalid
+<<< __file__ >>>;
--- /dev/null
+#require compile_file
+<<< __file__ >>>;
--- /dev/null
+#require compile_string
+<<< __file__ >>>;
+#require coverage
+#require coverage
+
<<< var float f >>>;
var Coverage c;
c.s_i;
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "object.h"
+#include "instr.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+
+GWION_IMPORT(deps) {
+ (void)gwi;
+ return GW_OK;
+}
+
+static const m_str deps[] = { "array", NULL };
+GWDEPEND { return deps; }
--- /dev/null
+#require deps
+
+<<< __file__ >>>;
--- /dev/null
+#require empty_union
+<<< __file__ >>>;
--- /dev/null
+#require end_class
+<<< __file__ >>>;
+#require enum
#! untyped global enum
<<< ENUM0 >>>;
<<< ENUM1 >>>;
--- /dev/null
+#require enum_fail
+<<< __file__ >>>;
--- /dev/null
+#require enum_fail2
+<<< __file__ >>>;
--- /dev/null
+#require enum_fail3
+<<< __file__ >>>;
+#require extend_array
var ArrayExt a;
<<< a >>>;
<<< a.size() >>>;
--- /dev/null
+#require fail_on_next_arg
+<<< __file__ >>>;
--- /dev/null
+#require fail_on_next_arg2
+<<< __file__ >>>;
+#require fptr
fun void test(){ <<< "test" >>>; }
var PtrType ptr;
test();
var FuncTypedef.PtrType _ptr;
<<< FuncTypedef.ptr >>>;
FuncTypedef.ptr();
-
--- /dev/null
+#require fptr_tmpl
+<<< __file__ >>>;
--- /dev/null
+#require fptr_tmpl_fail
+<<< __file__ >>>;
--- /dev/null
+#require func_fail
+<<< __file__ >>>;
--- /dev/null
+#require func_fail2
+<<< __file__ >>>;
--- /dev/null
+#require func_fail3
+<<< __file__ >>>;
--- /dev/null
+#require func_fail4
+<<< __file__ >>>;
--- /dev/null
+#require func_subscript_not_empty
+<<< __file__ >>>;
+#require func_tmpl
test:[int](1);
test(1);
--- /dev/null
+#require func_tmpl_fail
+<<< __file__ >>>;
--- /dev/null
+#require func_too_many_arg
+<<< __file__ >>>;
+#require global_func
<<< test >>>;
<<< 1 => test >>>;
-
+#require global_var
<<< i >>>;
<<< "other test" => i >>>;
<<< 12 => f >>>;
--- /dev/null
+#require invalid_arg
+<<< __file__ >>>;
--- /dev/null
+#require invalid_array
+<<< __file__ >>>;
--- /dev/null
+#require invalid_func
+<<< __file__ >>>;
--- /dev/null
+#require invalid_names
+<<< __file__ >>>;
--- /dev/null
+#require invalid_names0
+<<< __file__ >>>;
--- /dev/null
+#require invalid_names1
+<<< __file__ >>>;
--- /dev/null
+#require invalid_names2
+<<< __file__ >>>;
--- /dev/null
+#require invalid_names3
+<<< __file__ >>>;
--- /dev/null
+#require invalid_type1
+<<< __file__ >>>;
--- /dev/null
+#require invalid_type2
+<<< __file__ >>>;
--- /dev/null
+#require invalid_type3
+<<< __file__ >>>;
--- /dev/null
+#require mk_type_array
+<<< __file__ >>>;
--- /dev/null
+#require no_import
+<<< __file__ >>>;
--- /dev/null
+#require not_importing
+<<< __file__ >>>;
#include "import.h"
#include "gwi.h"
-
GWION_IMPORT(op_already_imported) {
GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
GWI_BB(gwi_oper_end(gwi, "=>", NULL))
+#require op_already_imported
#! [contains] already imported
<<< 1 >>>;
--- /dev/null
+#require pass
+<<< __file__ >>>;
--- /dev/null
+#require specialid_emit
+<<< testid >>>;
+#require static_string
#!<<< StaticString.self >>>;
<<< self >>>;
--- /dev/null
+#require str2decl
+<<< __file__ >>>;
--- /dev/null
+#require str2list_fail
+<<< __file__ >>>;
--- /dev/null
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "object.h"
+#include "instr.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
+#include "gwi.h"
+
+SFUN(coverage_int) { *(m_uint*)RETURN = 0; }
+SFUN(coverage_float) { *(m_float*)RETURN = 0; }
+
+GWION_IMPORT(coverage) {
+ GWI_OB(gwi_struct_ini(gwi, "Struct"))
+ GWI_BB(gwi_func_ini(gwi, "int", "i"))
+ GWI_BB(gwi_func_end(gwi, coverage_int, ae_flag_static))
+ GWI_BB(gwi_func_ini(gwi, "float", "f"))
+ GWI_BB(gwi_func_end(gwi, coverage_float, ae_flag_static))
+
+ ALLOC_PTR(gwi->gwion->mp, i, m_uint, 5);
+ GWI_BB(gwi_item_ini(gwi,"int", "s_i"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_static, i))
+
+ ALLOC_PTR(gwi->gwion->mp, f, m_float, 2.1);
+ GWI_BB(gwi_item_ini(gwi,"int", "s_f"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_static, (void*)f))
+
+ ALLOC_PTR(gwi->gwion->mp, ci, m_uint, 5);
+ GWI_BB(gwi_item_ini(gwi,"int", "sc_i"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, ci))
+
+ ALLOC_PTR(gwi->gwion->mp, cf, m_float, 2.1);
+ GWI_BB(gwi_item_ini(gwi,"float", "sc_f"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_static | ae_flag_const, (void*)cf))
+
+ GWI_BB(gwi_item_ini(gwi,"int[][]", "test_array"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+
+ GWI_BB(gwi_struct_end(gwi))
+ return GW_OK;
+}
--- /dev/null
+#require struct
+
+<<< var float f >>>;
+var Struct c;
+c.s_i;
+<<< Coverage.i() >>>;
+<<< Coverage.f() >>>;
+
+<<< Coverage.s_i >>>;
+<<< Coverage.s_f >>>;
+
+<<< Coverage.sc_i >>>;
+<<< Coverage.sc_f >>>;
+
+<<< 1 => Coverage.s_i >>>;
+<<< 1.2 => Coverage.s_f >>>;
+
+<<< c.test_array[0][0] >>>;
--- /dev/null
+#require template_arg
+<<< __file__ >>>;
+#require trig
var Trig trig => dac;
adc :=> trig;
adc :=< trig;
+#require typedef
var Typedef t;
#!fun int test(int i) { <<< i >>>; }
#!test @=> t;
--- /dev/null
+#require typedef_fail
+<<< __file__ >>>;
--- /dev/null
+#require typedef_tmpl
+<<< __file__ >>>;
--- /dev/null
+#require ugen_connect
+<<< __file__ >>>;
+#require union
var Union u;
<<< u.i >>>;
<<< 12 => u.f >>>;
--- /dev/null
+#require union_fail_exp
+<<< __file__ >>>;
--- /dev/null
+#require union_member
+<<< __file__ >>>;
+#require union_name
<<< my_union >>>;
<<<my_union.i>>>;
+#require union_tmpl
<<< var U:[Event] u>>>;
<<< u.a >>>;
--- /dev/null
+#require union_tmpl_fail
+<<< __file__ >>>;
--- /dev/null
+#require union_tmpl_fail2
+<<< __file__ >>>;
--- /dev/null
+#require union_tmpl_fail3
+<<< __file__ >>>;
GWI_OB(gwi_class_ini(gwi, "Variadic", NULL))
GWI_BB(gwi_func_ini(gwi, "void", "member"))
GWI_BB(gwi_func_arg(gwi, "string", "format"))
- GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_variadic))
+ GWI_BB(gwi_func_arg(gwi, "does not matter", "..."))
+ GWI_BB(gwi_func_end(gwi, m_variadic, ae_flag_none))
GWI_BB(gwi_func_ini(gwi, "void", "test"))
GWI_BB(gwi_func_end(gwi, m_test, ae_flag_none))
GWI_BB(gwi_class_end(gwi))
+#require variadic
<<< "test builtin variadic fun" >>>;
var Variadic v;
"iiii" => var string format;
+#require vm_remove
test(12);
test(1);
#!/bin/bash
-# [test] #77
+# [test] #79
n=0
[ "$1" ] && n="$1"
export GWION_ADD_DIR
test_plugin() {
- export NAME=$"$1"
- export PRG=$"../../gwion"
- export SUPP=$"../../scripts/supp"
+ export NAME="$1"
+ export PRG="../../gwion"
+ export SUPP="../../scripts/supp"
make
if [ -f "$NAME.gw" ]
- then GWOPT+=-p. test_gw "$NAME.gw" "$n"
- else GWOPT+=-p. test_gw "no_file" "$n"
+ then GWOPT+="-p." test_gw "$NAME.gw" "$n"
+ else GWOPT+="-p." test_gw "no_file" "$n"
fi
make clean
N=$(printf "% 4i" "$n")
BASE_DIR="$PWD"
-cd tests/import || exit
+pushd tests/plug || exit
for test_file in *.c
do test_plugin "$(basename "$test_file" .c)"
done
+PRG="../../gwion" make NAME="array"
+test_plugin "deps" "$n"
+make NAME="array" clean
+popd
-DRIVER="driver_test:arg" test_plugin driver
-MODULE="dummy_module=with,some,argument" test_plugin module
+
+pushd tests/driver || exit
+for test_file in *.c
+do
+ NAME="$(basename "$test_file" .c)"
+ DRIVER="$NAME=some_arg" test_plugin "$(basename "$test_file" .c)"
+done
+popd || exit
+
+pushd tests/module || exit
+for test_file in *.c
+do
+ NAME="$(basename "$test_file" .c)"
+ MODULE="$NAME=some_arg" test_plugin "$NAME"
+done
+popd || exit
# clean
rm -f ./*.gcda ./*.gcno vgcore.* ./*.o ./*.so
#!/bin/bash
-# [test] #20
+# [test] #21
n=0
[ "$1" ] && n="$1"
# config
n=$((n+1))
-RC=tmp_gwionrc
-cat << EOF >> "$RC"
+RC=./tmp_gwionrc
+cat << EOF > "$RC"
-p.
-l0
EOF
-run "$n" "config" "-c $RC" "file"
+run "$n" "config" "-c$RC" "file"
rm "$RC"
# loop
n=$((n+1))
run "$n" "option needs argument" "-p" "file"
+# option needs argument
+n=$((n+1))
+echo "<<< __file__ >>>;" | run "$n" "stdin" "-" "file"
+
# invalid global type
n=$((n+1))
run "$n" "invalid global type" "examples/complex/invalid_type0.gw examples/complex/invalid_type1.gw" "file"
--- /dev/null
+<<< "".charAt(-1) >>>;
+<<< "".charAt(2) >>>;
+<<< " test String ".charAt(2) >>>;
+
+<<< "test".charAt(-1, 'c') >>>;
+<<< "test".charAt(12, 'c') >>>;
+<<< "test".charAt(2, 'c') >>>;
<<< s0 != s0 >>>;
<<< s0 != s1 >>>;
+
+<<< null == s0 >>>;
+<<< null != s0 >>>;
+
+<<< s0 == null >>>;
+<<< s0 != null >>>;
+
+<<< null == null >>>;
+<<< null != null >>>;
--- /dev/null
+<<< "test".find('e') >>>;
+<<< "test".find('a') >>>;
+<<< "".find('a') >>>;
+
+<<< "test".find(-1, 'e') >>>;
+<<< "test".find(0, 'e') >>>;
+<<< "test".find(1, 'a') >>>;
+<<< "".find(1, 'a') >>>;
+
+<<< "test".find("es") >>>;
+<<< "test".find("a") >>>;
+<<< "".find("") >>>;
+
+<<< "test".find(-1, "es") >>>;
+<<< "test".find(0, "es") >>>;
+<<< "test".find(1, "a") >>>;
+<<< "".find(1, "") >>>;
+
+<<< "test".rfind("es") >>>;
+<<< "test".rfind("a") >>>;
+<<< "".rfind("") >>>;
+
+<<< "test".rfind(-1, "es") >>>;
+<<< "test".rfind(0, "e") >>>;
+<<< "test".rfind(1, "a") >>>;
+<<< "".rfind(1, "") >>>;
--- /dev/null
+<<< "Test String".lower() >>>;
--- /dev/null
+<<< "".ltrim() >>>;
+<<< " test String ".ltrim() >>>;
--- /dev/null
+<<< "".rtrim() >>>;
+<<< " test String ".rtrim() >>>;
--- /dev/null
+<<< "test".size() >>>;
--- /dev/null
+<<< "".trim() >>>;
+<<< " test String ".trim() >>>;
--- /dev/null
+<<< "test String".upper() >>>;
var A a1;
}
-var D:[int] si;
-var D:[float] sf;
+var S:[int] si;
+var S:[float] sf;
<<< si.a0 >>>;
<<< sf.a0 >>>;
-Subproject commit 45dd762586ca0cda722a07baef5077e9460c9442
+Subproject commit 3566515fee16924098da38bf99deb669cd617d5b