#!/bin/bash
+: "${PRG:=gwion}"
: "${VALGRIND:=valgrind}"
: "${GWION_TEST_DIR:=/tmp}"
: "${GWION_TEST_PREFIX:=gwt_}"
vlog=${GWION_TEST_DIR}/${GWION_TEST_PREFIX}$(printf "%04i" "$n").valgrind.log
rlog=${GWION_TEST_DIR}/${GWION_TEST_PREFIX}$(printf "%04i" "$n").log
if [ "$VALGRIND" == "NO_VALGRIND" ]
- then ./gwion "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |:
+ then ./"$PRG" "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |:
else
"$VALGRIND" --suppressions=help/supp --log-file="$vlog" \
- ./gwion "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |:
+ ./"$PRG" "$GWOPT" -d "$DRIVER" "$file" > "$slog" 2>"$elog" |:
fi
ret=$?
#enable skip
Vector vec;
vtype iter;
size_t default_case_index;
+ size_t depth;
uint ok;
};
ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c
ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def);
ANN Type known_type(const Env env, const Type_Decl*);
-ANN m_bool env_access(const Env env, const ae_flag flag, const uint pos);
-ANN m_bool env_storage(const Env env, ae_flag flag, const uint pos);
+ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos);
+ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos);
ANN void env_add_type(const Env, const Type);
ANN Type find_type(const Env, ID_List);
-ANN m_bool already_defined(const Env env, const Symbol s, const uint pos);
+ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos);
ANN m_bool type_engine_check_prog(const Env, const Ast);
ANN Func get_func(const Env, const Func_Def);
ANN m_bool traverse_func_template(const Env env, const Func_Def def, const Type_List types);
ANN ID_List str2list(const Env, const m_str path, m_uint* array_depth);
-ANN void env_err(const Env, const uint pos, const m_str fmt, ...);
+ANN2(1,3) void env_err(const Env, const struct YYLTYPE *pos, const m_str fmt, ...);
#endif
#ifndef __ESCAPE
#define __ESCAPE
char* escape_table(void);
-ANN m_int str2char(const Emitter, const m_str, const uint);
-ANN m_bool escape_str(const Emitter, m_str, const uint);
+ANN m_int str2char(const Emitter, const m_str, const loc_t);
+ANN m_bool escape_str(const Emitter, m_str, const loc_t);
#endif
DL_Oper oper;
void* addr;
Templater templater;
+ loc_t loc;
};
#endif
struct Map_ freearg;
SymTable *st;
MemPool p;
+ struct Vector_ child;
};
ANN m_bool gwion_ini(const Gwion, struct Arg_*);
ANN VM* gwion_cpy(const VM*);
ANN void gwion_run(const Gwion gwion);
ANN void gwion_end(const Gwion gwion);
+void free_code_instr(const Vector v, const Gwion gwion);
#endif
#define _CHECK_OP(op, check, func)\
CHECK_BB(gwi_oper_add(gwi, opck_##check))\
CHECK_BB(gwi_oper_end(gwi, op_##op, func))
-#define ERR_N(a,...) { err_msg(a,__VA_ARGS__); return t_null; }
+#define GWI_LOC new_loc(gwi->gwion->p, __LINE__)
+
ANN VM* gwi_vm(const Gwi);
ANN2(1,2) ANEW Type gwi_mk_type(const Gwi, const m_str, const m_uint, const Type);
// Nspc nspc;//
Vector vtable;
struct pool* p;
- size_t ref;
+ volatile size_t ref;
};
ANN void instantiate_object(const VM_Shred, const Type);
ANEW M_Object new_string2(MemPool, const VM_Shred, const m_str);
ANEW M_Object gwion_new_string(const struct Gwion_*, const m_str);
ANEW M_Object new_shred(const VM_Shred, const m_bool);
-ANN void fork_launch(const M_Object, const m_uint);
+ANN void fork_launch(const VM*, const M_Object, const m_uint);
+ANN void fork_clean(const VM *vm, const Vector v);
ANN void __release(const M_Object, const VM_Shred);
ANN void exception(const VM_Shred, const m_str);
ANN void broadcast(const M_Object);
opck ck;
opem em;
uintptr_t data;
- uint pos;
+ loc_t pos;
Operator op;
m_bool mut;
};
#define __OPTIM
#ifdef OPTIMIZE
#define OPTIMIZE_CONST(a) CHECK_BO(optimize_const(a))
-ANN m_bool optimize_const(MemPool mp, const Exp_Binary*);
+ANN m_bool optimize_const(const Env, const Exp_Binary*);
//ANN2(1) void constprop_prim(const Exp_Primary* p, m_uint* ptr);
#else
#define OPTIMIZE_CONST(a)
#endif
-m_bool constant_folding(MemPool mp, const Exp_Binary* bin);
+m_bool constant_folding(const Env, const Exp_Binary*);
#endif
#define ERR_B(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return GW_ERROR; }
#undef ERR_O
#define ERR_O(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return NULL; }
+#undef ERR_N
+#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return t_null; }
#define RET_NSPC(exp) \
++env->scope->depth; \
#define GWMODEND_NAME gwmodend
#define GWDRIVER_NAME gwmodend
#define GWMODSTR(a) m_str GWMODSTR_NAME() { return #a; }
-#define GWMODINI(a) ANN2(1) void* GWMODINI_NAME(const Gwion gwion, const Vector args)
-#define GWMODEND(a) ANN void GWMODEND_NAME(const Gwion gwion, void* self)
+#define GWMODINI(a) ANN2(1) void* GWMODINI_NAME(const Gwion gwion NUSED, const Vector args NUSED)
+#define GWMODEND(a) ANN void GWMODEND_NAME(const Gwion gwion NUSED, void* self NUSED)
#define GWDRIVER(a) ANN void GWDRIVER_NAME(DriverData* d)
ANN Vector split_args(MemPool, const m_str str);
ANN Exp switch_expget(const Env env);
ANN void switch_pc(const Env env, const m_uint pc);
ANN void switch_dynpc(const Env env, const m_int val, const m_uint pc);
-ANN m_bool switch_dup(const Env env, const m_int value, const uint pos);
+ANN m_bool switch_dup(const Env env, const m_int value, const loc_t pos);
ANN m_bool switch_pop(const Env env);
-ANN void switch_end(const Env env);
+ANN m_bool switch_end(const Env env, const loc_t pos);
ANN m_uint switch_idx(const Env);
ANN Vector switch_vec(const Env);
ANN m_bool switch_add(const Env env, const Stmt_Switch stmt);
-ANN m_bool switch_default(const Env env, const m_uint pc, const uint pos);
-ANN m_bool switch_inside(const Env env, const uint pos);
+ANN m_bool switch_default(const Env env, const m_uint pc, const loc_t pos);
+ANN m_bool switch_inside(const Env env, const loc_t pos);
ANN m_bool switch_dyn(const Env env);
-ANN m_bool switch_reset(const Env env);
-ANN m_bool switch_release(const Scope);
-ANN void switch_get(const Env env, const Stmt_Switch stmt);
+ANN m_bool switch_decl(const Env env, const loc_t pos);
+ANN void switch_reset(const Env env);
+ANN void switch_release(const Scope);
+ANN void switch_get(const Env env, const Stmt_Switch stmt);
#endif
m_bool traverse_stmt_enum(const Env, const Stmt_Enum);
m_bool traverse_stmt_fptr(const Env, const Stmt_Fptr );
m_bool traverse_decl(const Env, const Exp_Decl*);
+
+ANN m_bool scan0_ast(const Env env, Ast ast);
+ANN m_bool scan1_ast(const Env env, Ast ast);
+ANN m_bool scan2_ast(const Env env, Ast ast);
+ANN m_bool check_ast(const Env env, Ast ast);
+
+ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl);
+ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl);
+ANN Type check_exp_decl(const Env env, const Exp_Decl* decl);
+
+ANN m_bool scan1_func_def(const Env env, const Func_Def def);
+ANN m_bool scan2_func_def(const Env env, const Func_Def def);
+ANN m_bool check_func_def(const Env env, const Func_Def def);
+
+ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr def);
+ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr def);
+ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr def);
+//ANN m_bool check_stmt_fptr(const Env env, const Stmt_Fptr def);
+
+ANN m_bool scan0_stmt_union(const Env env, const Stmt_Union def);
+ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union def);
+ANN m_bool scan2_stmt_union(const Env env, const Stmt_Union def);
+ANN m_bool check_stmt_union(const Env env, const Stmt_Union def);
+
+ANN m_bool scan0_stmt_enum(const Env env, const Stmt_Enum def);
+ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum def);
+//ANN m_bool scan2_stmt_enum(const Env env, const Stmt_Enum def);
+ANN m_bool check_stmt_enum(const Env env, const Stmt_Enum def);
+
+ANN m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt);
+ANN m_bool scan1_class_def(const Env env, const Class_Def def);
+ANN m_bool scan2_class_def(const Env env, const Class_Def def);
+ANN m_bool check_class_def(const Env env, const Class_Def def);
#endif
ANN Value find_value(const Type, const Symbol);
ANN Func find_func(const Type, const Symbol);
ANN m_bool isa(const Type, const Type) __attribute__((pure));
-ANN m_bool isres(const Env, const Symbol, const uint pos);
+ANN m_bool isres(const Env, const Symbol, const loc_t pos);
ANN Type array_type(const Env, const Type, const m_uint);
ANN Type find_common_anc(const Type, const Type) __attribute__((pure));
ANN m_uint id_list_len(ID_List);
void free_vm_shred(const VM_Shred shred)__attribute__((hot, nonnull));
ANN void vm_run(const VM* vm) __attribute__((hot));
-ANEW VM* new_vm(MemPool);
+ANEW VM* new_vm(MemPool, const m_bool);
ANN void free_vm(VM* vm);
ANN m_uint vm_add_shred(const VM* vm, const VM_Shred shred)__attribute__((hot));
ANN void vm_remove(const VM* vm, const m_uint index)__attribute__((hot));
#include "gwion_ast.h"
#include "oo.h"
#include "env.h"
+#include "vm.h"
+#include "instr.h"
+#include "emit.h"
#include "type.h"
#include "optim.h"
#include "constant.h"
+#include "parse.h"
ANN static void fold_exp(MemPool mp, const Exp_Binary* bin) {
const Exp n = exp_self(bin)->next;
CASE(mul, l, /, r) \
case op_div: DIV_BY_ZERO(l, / , r) break;
-#define describe_fold_xxx(name, type, _l, _r, etype, opt) \
-ANN static m_bool fold_##name(MemPool mp, const Exp_Binary* bin) { \
- const union exp_primary_data *l = &bin->lhs->d.exp_primary.d; \
- const union exp_primary_data *r = &bin->rhs->d.exp_primary.d; \
- type ret = 0; \
- switch(bin->op) { \
- COMMON_CASE(l->_l, r->_r) \
- opt \
- default: \
- return GW_OK; \
- } \
- const Exp e = exp_self(bin); \
- fold_exp(mp, bin); \
- etype##_exp(e, ret); \
- return GW_OK; \
+#define describe_fold_xxx(name, type, _l, _r, etype, opt) \
+ANN static m_bool fold_##name(const Env env, const Exp_Binary* bin) { \
+ MemPool mp = env->gwion->p; \
+ const union exp_primary_data *l = &bin->lhs->d.exp_primary.d; \
+ const union exp_primary_data *r = &bin->rhs->d.exp_primary.d; \
+ type ret = 0; \
+ switch(bin->op) { \
+ COMMON_CASE(l->_l, r->_r) \
+ opt \
+ default: \
+ return GW_OK; \
+ } \
+ const Exp e = exp_self(bin); \
+ fold_exp(mp, bin); \
+ etype##_exp(e, ret); \
+ return GW_OK; \
}
describe_fold_xxx(ii, m_int, num, num, int,
case op_mod: DIV_BY_ZERO(l->num, % , r->num) break;
describe_fold_xxx(if, m_float, num, fnum, float,)
describe_fold_xxx(fi, m_float, fnum, num, float,)
-m_bool constant_folding(MemPool mp, const Exp_Binary* bin) {
+m_bool constant_folding(const Env env, const Exp_Binary* bin) {
if(constant_int(bin->lhs)) {
if(constant_int(bin->rhs))
- CHECK_BB(fold_ii(mp, bin))
+ CHECK_BB(fold_ii(env, bin))
else if(constant_float(bin->rhs))
- CHECK_BB(fold_if(mp, bin))
+ CHECK_BB(fold_if(env, bin))
} else if(constant_float(bin->lhs)) {
if(constant_float(bin->rhs))
- CHECK_BB(fold_ff(mp, bin))
+ CHECK_BB(fold_ff(env, bin))
else if(constant_int(bin->rhs))
- CHECK_BB(fold_fi(mp, bin))
+ CHECK_BB(fold_fi(env, bin))
}
return GW_OK;
}
#include "optim.h"
#include "constant.h"
-m_bool optimize_const(MemPool mp, const Exp_Binary* bin) {
- return constant_folding(mp, bin);
+m_bool optimize_const(const Env env, const Exp_Binary* bin) {
+ return constant_folding(env, bin);
}
free_ast(p, c->ast);
}
-static m_bool compiler_open(struct Compiler* c) {
+static m_bool _compiler_open(struct Compiler* c) {
if(c->type == COMPILE_NAME) {
m_str name = c->name;
c->name = realpath(name, NULL);
return GW_OK;
}
+static inline m_bool compiler_open(struct Compiler* c) {
+ char name[strlen(c->name)];
+ strcpy(name, c->name);
+ if(_compiler_open(c) < 0) {
+ gw_err("'%s': no such file\n", name);
+ return GW_ERROR;
+ }
+ return GW_OK;
+}
+
static m_bool check(struct Gwion_* gwion, struct Compiler* c) {
CHECK_BB(compiler_open(c))
struct ScannerArg_ arg = { c->name, c->file, gwion->st };
#include "operator.h"
#include "import.h"
#include "switch.h"
+#include "parser.h"
#undef insert_symbol
#define insert_symbol(a) insert_symbol(emit->env->gwion->st, (a))
Array_Sub array = arr;
if(type->array_depth) {
if(!array || array->depth < type->array_depth) { // from typeof xxx[]...
- Exp base = new_exp_prim_int(emit->gwion->p, 0, 0), e = base;
+ Exp base = new_exp_prim_int(emit->gwion->p, 0, new_loc(emit->gwion->p, __LINE__)), e = base;
for(m_uint i = (array ? array->depth : 0); i < type->array_depth; ++i)
- e = (e->next = new_exp_prim_int(emit->gwion->p, 0, 0));
+ e = (e->next = new_exp_prim_int(emit->gwion->p, 0, new_loc(emit->gwion->p, __LINE__)));
if(array) {
Exp array_base = array->exp;
while(array_base->next)
static const f_instr allocword[] = { AllocWord, AllocWord2, AllocWord3, AllocWord4 };
ANN static inline Exp this_exp(const Emitter emit, const Type t, const loc_t pos) {
- const Exp exp = new_exp_prim_id(emit->gwion->p, insert_symbol("this"), pos);
+ const Exp exp = new_exp_prim_id(emit->gwion->p, insert_symbol("this"),
+ loc_cpy(emit->gwion->p, pos));
exp->type = t;
return exp;
}
ANN static inline Exp dot_static_exp(const Emitter emit, const Exp_Primary* prim, const Type t) {
const Symbol s = insert_symbol(t->name);
- const Exp e = new_exp_prim_id(emit->gwion->p, s, exp_self(prim)->pos);
+ const Exp e = new_exp_prim_id(emit->gwion->p, s,
+ loc_cpy(emit->gwion->p, exp_self(prim)->pos));
const Value val = nspc_lookup_value1(t->nspc->parent, s);
const Exp dot = new_exp_dot(emit->gwion->p, e, prim->d.var);
dot->d.exp_dot.t_base = val->type;
ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) { GWDEBUG_EXE
const m_uint size = v->type->size;
if(isa(v->type, t_class) < 0) {
- const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
- instr->m_val = (m_uint)(v->owner->info->class_data + v->offset);
- instr->m_val2 = size;
+ if(isa(v->type, t_union) < 0) {
+printf("%s %lu %p·\n", v->name, v->offset, v->owner->info->class_data);
+ const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
+ instr->m_val = (m_uint)(v->owner->info->class_data + v->offset);
+ instr->m_val2 = size;
+ } else exit(2);
} else {
const Instr instr = emit_add_instr(emit, RegPushImm);
instr->m_val = (m_uint)v->type;
return GW_OK;
}
-ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref) { GWDEBUG_EXE
+ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref, const uint emit_addr) { GWDEBUG_EXE
const Value value = var_decl->value;
if(isa(value->type, t_object) > 0 && !is_ref)
CHECK_BB(decl_static(emit, var_decl, 0))
- return emit_dot_static_data(emit, value, 1);
+ return emit_dot_static_data(emit, value, emit_addr);
}
ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Var_Decl var_decl,
const uint var = exp_self(decl)->emit_var;
if(GET_FLAG(decl->type, template))
CHECK_BB(emit_exp_decl_template(emit, decl))
- m_uint scope;
const m_bool global = GET_FLAG(decl->td, global);
- if(global)
- scope = emit_push_global(emit);
+ const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
do {
+puts(s_name(list->self->xid));
const uint r = (uint)(GET_FLAG(list->self->value, ref) + ref);
- if(!GET_FLAG(list->self->value, used))
- continue;
+// if(!GET_FLAG(list->self->value, used))
+// continue;
if(GET_FLAG(decl->td, static))
- CHECK_BB(emit_exp_decl_static(emit, list->self, r))
+ CHECK_BB(emit_exp_decl_static(emit, list->self, r, var))
else if(!global)
CHECK_BB(emit_exp_decl_non_static(emit, list->self, r, var))
else
ANN static m_bool emit_exp_binary(const Emitter emit, const Exp_Binary* bin) { GWDEBUG_EXE
const Exp lhs = bin->lhs;
const Exp rhs = bin->rhs;
- struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type, .data = (uintptr_t)bin };
+ struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type, .pos=exp_self(bin)->pos, .data = (uintptr_t)bin };
CHECK_BB(emit_exp(emit, lhs, 1))
CHECK_BB(emit_exp(emit, rhs, 1))
return op_emit(emit, &opi);
static inline m_bool push_func_code(const Emitter emit, const Func f) {
if(GET_FLAG(f, template) && f->value_ref->owner_class) {
const Instr instr = (Instr)vector_back(&emit->code->instr);
-// assert(instr->execute == DotTmplVal);
- assert(instr->opcode == DotTmplVal);
+ assert(instr->opcode == eDotTmplVal);
size_t len = strlen(f->name);
size_t sz = len - strlen(f->value_ref->owner_class->name);
char c[sz + 1];
dt->overload = f->def->tmpl->base;
dt->tl = tmpl_tl(emit->env, c);
dt->base = f->def;
- instr->opcode = OP_MAX;
+ instr->opcode = eOP_MAX;
instr->m_val = (m_uint)dt;
instr->m_val2 = strlen(c);
instr->execute = DotTmpl;
#define SPORK_CODE_PREFIX "spork~code:%i"
#define FORK_CODE_PREFIX "fork~code:%i"
-static void push_spork_code(const Emitter emit, const m_str prefix, const int pos) {
- char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos) + 1];
+static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t pos) {
+ char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos->first_line) + 1];
sprintf(c, prefix, pos);
emit_push_code(emit, c);
}
}
ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
+ if(e->next) {
+ free_exp(emit->gwion->p, e->next);
+ e->next = NULL;
+ env_err(emit->env, e->pos, "expression after comma won't be executed");
+ }
CHECK_BO(emit_exp(emit, e, 0))
const f_instr instr_i = b ? BranchEqInt : BranchNeqInt;
const f_instr instr_f = b ? BranchEqFloat : BranchNeqFloat;
emit_add_instr(emit, GWOP_EXCEPT);
const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop);
const Instr end = emit_add_instr(emit, BranchEqInt);
- const m_uint offset = emit_local(emit, 2*SZ_INT, 0);
+ const m_uint offset = emit_local(emit, SZ_INT + stmt->v->type->size, 0);
stmt->v->offset = offset + SZ_INT;
CHECK_BB(emit_stmt(emit, stmt->body, 1))
const m_uint end_pc = emit_code_size(emit);
stmt->data.instr = emit_add_instr(emit, Goto);
else {
if(switch_inside(emit->env, stmt_self(stmt)->pos) && !strcmp(s_name(stmt->name), "default")) {
- if(!strcmp(s_name(stmt->name), "default"))
- vector_release(&stmt->data.v);
+// if(!strcmp(s_name(stmt->name), "default"))
+// vector_release(&stmt->data.v);
return switch_default(emit->env, emit_code_size(emit), stmt_self(stmt)->pos);
}
if(!stmt->data.v.ptr)
ERR_B(stmt_self(stmt)->pos, "illegal case")
const m_uint size = vector_size(&stmt->data.v);
if(!size) {
- vector_release(&stmt->data.v);
+// vector_release(&stmt->data.v);
ERR_B(stmt_self(stmt)->pos, "label '%s' defined but not used.", s_name(stmt->name))
}
LOOP_OPTIM
for(m_uint i = size + 1; --i;) {
const Stmt_Jump label = (Stmt_Jump)vector_at(&stmt->data.v, i - 1);
if(!label->data.instr) {
- vector_release(&stmt->data.v);
+// vector_release(&stmt->data.v);
ERR_B(stmt_self(label)->pos, "you are trying to use a upper label.")
}
label->data.instr->m_val = emit_code_size(emit);
}
- vector_release(&stmt->data.v);
+// vector_release(&stmt->data.v);
}
return GW_OK;
}
Vector v = (Vector)(push[1]->m_val = (m_uint)switch_vec(emit->env));
push[0]->m_val = vector_size(v) * SZ_INT;
}
- switch_end(emit->env);
+ CHECK_BB(switch_end(emit->env, stmt->stmt->pos))
pop_vector(&emit->code->stack_break, emit_code_size(emit));
return GW_OK;
}
stmt->value->type->nspc->info->offset = stmt->s;
if(!stmt->value->type->p)
stmt->value->type->p = mp_ini(emit->gwion->p, (uint32_t)stmt->value->type->size);
- Type_Decl *type_decl = new_type_decl(emit->gwion->p, new_id_list(emit->gwion->p, stmt->xid, stmt_self(stmt)->pos),
- emit->env->class_def ? ae_flag_member : 0);
- type_decl->flag = stmt->flag;// ???
- const Var_Decl var_decl = new_var_decl(emit->gwion->p, stmt->xid, NULL, 0);
+ Type_Decl *type_decl = new_type_decl(emit->gwion->p,
+ new_id_list(emit->gwion->p, stmt->xid, loc_cpy(emit->gwion->p, loc_cpy(emit->gwion->p, stmt_self(stmt)->pos))),
+// emit->env->class_def ? ae_flag_member : 0);
+ stmt->flag);
+//if(emit->env->class_def && !GET_FLAG(stmt, static))
+//SET_FLAG(type_decl, member);
+// type_decl->flag = stmt->flag;// ???
+ const Var_Decl var_decl = new_var_decl(emit->gwion->p, stmt->xid, NULL, loc_cpy(emit->gwion->p, stmt_self(stmt)->pos));
const Var_Decl_List var_decl_list = new_var_decl_list(emit->gwion->p, var_decl, NULL);
const Exp exp = new_exp_decl(emit->gwion->p, type_decl, var_decl_list);
exp->d.exp_decl.type = stmt->value->type;
} while((l = l->next));
SET_FLAG(stmt->l->self->d.exp_decl.list->self->value, enum);
}
- emit_union_offset(stmt->l, stmt->o);
- if(stmt->xid) {
- const Instr instr = emit_add_instr(emit, RegPop);
- instr->m_val = SZ_INT;
+ if(stmt->xid){
+// if(!emit->env->class_def) {
+ const Instr instr = emit_add_instr(emit, RegPop);
+ instr->m_val = !GET_FLAG(stmt, static) ? SZ_INT : SZ_INT*2;
+/*
+ } else if(!GET_FLAG(stmt, static)) {
+ const Instr instr = emit_add_instr(emit, RegPop);
+ instr->m_val = SZ_INT;
+ printf("stmt->o %lu\n", stmt->o);
+ }
+*/
}
+ emit_union_offset(stmt->l, stmt->o);
if(stmt->xid || stmt->type_xid || global)
emit_pop(emit, scope);
return GW_OK;
instr->m_val = offset;
instr->m_val2 = emit->env->func->variadic->m_val2;
emit->env->func->variadic->m_val2 = emit_code_size(emit);
+ SET_FLAG(emit->env->func, empty);// mark vararg func as complete
}
ANN static m_bool emit_vararg(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE
func_i->m_val = (m_uint)(func->code ?: (VM_Code)func);
return GW_OK;
}
- if(func->def->tmpl) {
-//const Instr push = emit_add_instr(emit, RegPushImm);
-//push->m_val = func;
- const Instr instr = emit_add_instr(emit, DotTmplVal);
-//printf("func %p\n", func);
-// instr->m_val = func;
-// instr->m_val2 = SZ_INT;
- } else {
+ if(func->def->tmpl)
+ emit_add_instr(emit, DotTmplVal);
+ else {
const Instr instr = emit_add_instr(emit, GET_FLAG(func, member) ? DotFunc : DotStaticFunc);
instr->m_val = func->vt_index;
}
ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) { GWDEBUG_EXE
if(is_special(member->t_base) > 0)
return emit_exp_dot_special(emit, member);
- if(isa(member->t_base, t_class) < 0) {
+ const Value value = find_value(actual_type(member->t_base), member->xid);
+ if(isa(member->t_base, t_class) < 0 && (GET_FLAG(value, member) ||
+(isa(exp_self(member)->type, t_function) > 0 && isa(exp_self(member)->type, t_fptr) < 0))
+) {
CHECK_BB(emit_exp(emit, member->base, 0))
emit_add_instr(emit, GWOP_EXCEPT);
}
- const Value value = find_value(actual_type(member->t_base), member->xid);
if(isa(exp_self(member)->type, t_function) > 0 && isa(exp_self(member)->type, t_fptr) < 0)
return emit_member_func(emit, member, value->d.func_ref);
return (GET_FLAG(value, member) ? emit_member : emit_dot_static_import_data) (emit, value, exp_self(member)->emit_var);
emit_push_scope(emit);
emit->env->func = func;
CHECK_BB(emit_func_def_body(emit, func_def))
- if(GET_FLAG(func_def, variadic) && !emit->env->func->variadic)
- ERR_B(func_def->pos, "invalid variadic use")
+// if(GET_FLAG(func_def, variadic) && !emit->env->func->variadic)
+ if(GET_FLAG(func_def, variadic)) {
+ if(!emit->env->func->variadic)
+ ERR_B(func_def->pos, "invalid variadic use")
+ if(!GET_FLAG(func, empty))
+ ERR_B(func_def->pos, "invalid variadic use")
+//printf("opcode %p %p %p\n", emit->env->func->variadic->execute, VarargTop, VarargEnd);
+
+/*
+ if(emit->env->func->variadic->execute == VarargIni ||
+ emit->env->func->variadic->execute == VarargTop
+) {
+//assert(emit->env->func->variadic->execute == VarargTop);
+//free_code(emit->gwion->p, emit->code);
+// emit_func_def_code(emit, func);
+// REM_REF(func->code, emit->gwion);
+// emit->env->func = former;
+// emit_pop_code(emit);
+ ERR_B(func_def->pos, "invalid variadic use")
+ }
+*/
+ }
emit_func_def_return(emit);
emit_func_def_code(emit, func);
emit->env->func = former;
return GW_OK;
}
-ANN static void emit_free_code(MemPool p, Code* code) {
- LOOP_OPTIM
- for(m_uint j = vector_size(&code->instr) + 1; --j;)
- mp_free(p, Instr, (Instr)vector_at(&code->instr, j - 1));
- free_code(p, code);
+ANN static void emit_free_code(const Emitter emit, Code* code) {
+// LOOP_OPTIM
+// for(m_uint j = vector_size(&code->instr) + 1; --j;) {
+// mp_free(p, Instr, (Instr)vector_at(&code->instr, j - 1));
+if(vector_size(&code->instr))
+ free_code_instr(&code->instr, emit->gwion);
+//vector_release(&code->instr);
+// }
+ free_code(emit->gwion->p, code);
}
ANN static void emit_free_stack(const Emitter emit) { GWDEBUG_EXE
LOOP_OPTIM
for(m_uint i = vector_size(&emit->stack) + 1; --i;)
- emit_free_code(emit->gwion->p, (Code*)vector_at(&emit->stack, i - 1));
+ emit_free_code(emit, (Code*)vector_at(&emit->stack, i - 1));
vector_clear(&emit->stack);
- emit_free_code(emit->gwion->p, emit->code);
+ emit_free_code(emit, emit->code);
}
ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) { GWDEBUG_EXE
}
static int get_escape(const Emitter emit, const char c, const loc_t pos) {
- return emit->escape[(int)c] ?: err_msg(pos, "unrecognized escape sequence '\\%c'", c);
+ if(emit->escape[(int)c])
+ return emit->escape[(int)c];
+ env_err(emit->env, pos, "unrecognized escape sequence '\\%c'", c);
+ return GW_ERROR;
}
m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) {
while(*str_lit) {
if(*str_lit == '\\') {
++str_lit;
- if(*str_lit == '\0')
- ERR_B(pos, "invalid: string ends with escape charactor '\\'")
+ if(*str_lit == '\0') {
+ env_err(emit->env, pos, "invalid: string ends with escape charactor '\\'");
+ return GW_ERROR;
+ }
const unsigned char c = *(str_lit);
const unsigned char c2 = *(str_lit+1);
if(c >= '0' && c <= '7') {
if(c2 >= '0' && c2 <= '7' && c3 >= '0' && c3 <= '7') {
*str++ = (char)((c-'0') * 64 + (c2-'0') * 8 + (c3-'0'));
str_lit += 2;
- } else
- ERR_B(pos, "malformed octal escape sequence '\\%c%c%c'", c, c2, c3)
+ } else {
+ env_err(emit->env, pos, "malformed octal escape sequence '\\%c%c%c'", c, c2, c3);
+ return GW_ERROR;
+ }
}
} else if(c == 'x') {
++str_lit;
if(c1 >= '0' && c1 <= 'F' && c3 >= '0' && c3 <= 'F') {
*str++ = (char)((c1-'0') * 16 + (c3-'0'));
++str_lit;
- } else
- ERR_B(pos, "malformed hex escape sequence '\\%c%c'", c1, c3)
+ } else {
+ env_err(emit->env, pos, "malformed hex escape sequence '\\%c%c'", c1, c3);
+ return GW_ERROR;
+ }
} else
CHECK_BB((*str++ = (char)get_escape(emit, (char)c, pos)))
}
#include "arg.h"
#include "gwion.h"
#include "compile.h"
+#include "object.h" // fork_clean
ANN m_bool gwion_audio(const Gwion gwion) {
Driver* di = gwion->vm->bbq;
#include "shreduler_private.h"
ANN VM* gwion_cpy(const VM* src) {
const Gwion gwion = mp_alloc(src->gwion->p, Gwion);
- gwion->vm = new_vm(src->gwion->p);
+ gwion->vm = new_vm(src->gwion->p, 0);
gwion->vm->gwion = gwion;
gwion->vm->bbq->si = soundinfo_cpy(src->gwion->p, src->bbq->si);
gwion->emit = src->gwion->emit;
ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
gwion->p = mempool_ini((sizeof(VM_Shred) + SIZEOF_REG + SIZEOF_MEM) / SZ_INT);
gwion->st = new_symbol_table(gwion->p, 65347);
- gwion->vm = new_vm(gwion->p);
+ gwion->vm = new_vm(gwion->p, 1);
gwion->emit = new_emitter();
gwion->env = new_env(gwion->p);
gwion->emit->env = gwion->env;
const VM_Code code = new_vm_code(gwion->p, NULL, 0, ae_flag_builtin, "in code dtor");
gwion->vm->cleaner_shred = new_vm_shred(gwion->p, code);
vm_add_shred(gwion->vm, gwion->vm->cleaner_shred);
+ MUTEX_LOCK(gwion->vm->shreduler->mutex);
+ if(gwion->child.ptr)
+ fork_clean(gwion->vm, &gwion->child);
+ MUTEX_UNLOCK(gwion->vm->shreduler->mutex);
free_env(gwion->env);
free_vm_shred(gwion->vm->cleaner_shred);
free_emitter(gwion->emit);
mempool_end(gwion->p);
}
-ANN void env_err(const Env env, const loc_t pos, const m_str fmt, ...) {
- gw_err("in file: '%s'\n", env->name);
+ANN void env_err(const Env env, const struct YYLTYPE* pos, const m_str fmt, ...) {
+ loc_err(pos, env->name);
if(env->class_def)
gw_err("in class: '%s'\n", env->class_def->name);
if(env->func)
gw_err("in function: '%s'\n", env->func->name);
- if(pos)
- fprintf(stderr, "line: %u\t", pos);
- else
- fprintf(stderr, "\t");
va_list arg;
va_start(arg, fmt);
vfprintf(stderr, fmt, arg);
va_end(arg);
fprintf(stderr, "\n");
-}
\ No newline at end of file
+}
#include "emit.h"
#include "import.h"
#include "operator.h"
+#include "parse.h"
struct M_Vector_ {
m_bit* ptr;
#include "gwion.h"
#include "operator.h"
#include "engine.h"
+#include "parser.h"
static FREEARG(freearg_switchini) {
free_vector(((Gwion)gwion)->p, (Vector)instr->m_val);
struct Gwi_ gwi;
memset(&gwi, 0, sizeof(struct Gwi_));
gwi.gwion = vm->gwion;
+ gwi.loc = new_loc(vm->gwion->p, 0);
CHECK_BB(import_core_libs(&gwi))
vm->gwion->env->name = "[imported]";
for(m_uint i = 0; i < vector_size(plug_dirs); ++i) {
if(import && import(&gwi) < 0)
env_reset(gwi.gwion->env);
}
+ free_loc(vm->gwion->p, gwi.loc);
return GW_OK;
}
\ No newline at end of file
static OP_CHECK(opck_func_call) {
Exp_Binary* bin = (Exp_Binary*)data;
+ if(bin->rhs->exp_type == ae_exp_decl)
+ ERR_N(bin->rhs->pos, "calling fptr decl, this is forbidden.")
Exp_Call call = { .func=bin->rhs, .args=bin->lhs };
Exp e = exp_self(bin);
e->exp_type = ae_exp_call;
static OP_EMIT(opem_func_assign) {
Exp_Binary* bin = (Exp_Binary*)data;
emit_add_instr(emit, int_r_assign);
- if(bin->lhs->type != t_lambda && GET_FLAG(bin->rhs->type->d.func, member)) {
+ if(bin->lhs->type != t_lambda && GET_FLAG(bin->rhs->type->d.func, member)
+ && !emit->env->class_def
+) {
const Instr instr = emit_add_instr(emit, LambdaAssign);
instr->m_val = SZ_INT;
}
}
if(base || arg)
ERR_B(exp_self(l)->pos, "argument number does not match for lambda")
- l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, def->base->td, l->name, l->args), l->code, def->flag, def->pos);
+ l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, def->base->td, l->name, l->args), l->code, def->flag,
+ loc_cpy(env->gwion->p, def->pos));
const m_bool ret = traverse_func_def(env, l->def);
arg = l->args;
while(arg) {
#undef ERR_O
#define ERR_O(a, b, ...) { env_err(gwi->gwion->env, (a), (b), ## __VA_ARGS__); return NULL; }
+#include "parser.h"
struct Path {
m_str path, curr;
m_uint len;
+ YYLTYPE loc;
};
-ANN static ID_List templater_def(SymTable *st, const Templater* templater) {
+ANN static ID_List templater_def(SymTable *st, const Gwi gwi) {
+ const Templater* templater = &gwi->templater;
ID_List list[templater->n];
- list[0] = new_id_list(st->p, insert_symbol(st, templater->list[0]), 0);
+ list[0] = new_id_list(st->p, insert_symbol(st, templater->list[0]), loc_cpy(gwi->gwion->p, gwi->loc));
for(m_uint i = 1; i < templater->n; i++) {
- list[i] = new_id_list(st->p, insert_symbol(st, templater->list[i]), 0);
+ list[i] = new_id_list(st->p, insert_symbol(st, templater->list[i]), loc_cpy(gwi->gwion->p, gwi->loc));
list[i - 1]->next = list[i];
}
return list[0];
ANN m_int gwi_func_arg(const Gwi gwi, const restrict m_str t, const restrict m_str n) {
if(gwi->func.narg == DLARG_MAX - 1)
- ERR_B(0, "too many arguments for function '%s'.", gwi->func.name)
+ ERR_B(gwi->loc, "too many arguments for function '%s'.", gwi->func.name)
dl_func_func_arg(&gwi->func, t, n);
return GW_OK;
}
return GW_OK;
}
-ANN static m_bool name_valid(Env env, const m_str a) {
+ANN static m_bool name_valid(const Gwi gwi, const m_str a) {
+ const Env env = gwi->gwion->env;
const m_uint len = strlen(a);
m_uint lvl = 0;
for(m_uint i = 0; i < len; i++) {
}
if(c == ',') {
if(!lvl) {
- env_err(env, 0, "illegal use of ',' outside of templating in name '%s'.", a);
+ env_err(env, gwi->loc, "illegal use of ',' outside of templating in name '%s'.", a);
return GW_ERROR;
}
continue;
}
if(c == '>') {
if(!lvl) {
- env_err(env, 0, "illegal templating in name '%s'.", a);
+ env_err(env, gwi->loc, "illegal templating in name '%s'.", a);
return GW_ERROR;
}
lvl--;
continue;
}
- env_err(env, 0, "illegal character '%c' in name '%s'.", c, a);
+ env_err(env, gwi->loc, "illegal character '%c' in name '%s'.", c, a);
return GW_ERROR;
}
return !lvl ? 1 : -1;
}
}
-ANN static m_bool path_valid(const Env env,ID_List* list, const struct Path* p) {
+ANN static m_bool path_valid(const Env env, ID_List* list, const struct Path* p) {
char last = '\0';
for(m_uint i = p->len + 1; --i;) {
const char c = p->path[i - 1];
if(c != '.' && check_illegal(p->curr, c, i) < 0) {
- env_err(env, 0, "illegal character '%c' in path '%s'.", c, p->path);
+ env_err(env, &p->loc, "illegal character '%c' in path '%s'.", c, p->path);
return GW_ERROR;
}
if(c == '.' || i == 1) {
if((i != 1 && last != '.' && last != '\0') ||
(i == 1 && c != '.')) {
path_valid_inner(p->curr);
- *list = prepend_id_list(env->gwion->st->p, insert_symbol(env->gwion->st, p->curr), *list, 0);
+ *list = prepend_id_list(env->gwion->st->p, insert_symbol(env->gwion->st, p->curr), *list, loc_cpy(env->gwion->p, &p->loc));
memset(p->curr, 0, p->len + 1);
} else {
- env_err(env, 0, "path '%s' must not ini or end with '.'.", p->path);
+ env_err(env, &p->loc, "path '%s' must not ini or end with '.'.", p->path);
return GW_ERROR;
}
}
ID_List list = NULL;
m_uint depth = 0;
char curr[len + 1];
- struct Path p = { path, curr, len };
+ struct Path p = { path, curr, len, { 1,1,1,1} };
memset(curr, 0, len + 1);
while(p.len > 2 && path[p.len - 1] == ']' && path[p.len - 2] == '[') {
ANN m_int gwi_add_type(const Gwi gwi, const Type type) {
if(type->name[0] != '@')
- CHECK_BB(name_valid(gwi->gwion->env, type->name));
+ CHECK_BB(name_valid(gwi, type->name));
env_add_type(gwi->gwion->env, type);
return (m_int)type->xid;
}
ANN2(1,2) m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_ctor, const f_xtor dtor) {
if(type->nspc)
- ERR_B(0, "during import: class '%s' already imported.", type->name)
+ ERR_B(gwi->loc, "during import: class '%s' already imported.", type->name)
if(gwi->templater.n) {
- const ID_List types = templater_def(gwi->gwion->st,&gwi->templater);
- type->def = new_class_def(gwi->gwion->p, 0, insert_symbol(gwi->gwion->st, type->name), NULL, NULL, 0);
+ const ID_List types = templater_def(gwi->gwion->st, gwi);
+ type->def = new_class_def(gwi->gwion->p, 0, insert_symbol(gwi->gwion->st, type->name), NULL, NULL, loc_cpy(gwi->gwion->p, gwi->loc));
type->def->tmpl = new_tmpl_class(gwi->gwion->p, types, -1);
type->def->base.type = type;
SET_FLAG(type, template);
ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td) {
if(!gwi->gwion->env->class_def)
- ERR_B(0, "gwi_class_ext invoked before gwi_class_ini")
+ ERR_B(gwi->loc, "gwi_class_ext invoked before gwi_class_ini")
const VM_Code ctor = gwi->gwion->env->class_def->nspc->pre_ctor;
if(gwi->gwion->env->class_def->parent ||
(gwi->gwion->env->class_def->def && gwi->gwion->env->class_def->def->base.ext))
- ERR_B(0, "class extend already set")
+ ERR_B(gwi->loc, "class extend already set")
if(td->array && !td->array->exp)
- ERR_B(0, "class extend array can't be empty")
+ ERR_B(gwi->loc, "class extend array can't be empty")
if(!gwi->gwion->env->class_def->def) {
const Type t = known_type(gwi->gwion->env, td);
CHECK_OB(t)
ANN m_int gwi_class_end(const Gwi gwi) {
if(!gwi->gwion->env->class_def)
- ERR_B(0, "import: too many class_end called.")
+ ERR_B(gwi->loc, "import: too many class_end called.")
const Type t = gwi->gwion->env->class_def;
if(t->nspc && t->nspc->info->offset)
t->p = mp_ini(gwi->gwion->p, (uint32_t)t->nspc->info->offset);
DL_Var* v = &gwi->var;
memset(v, 0, sizeof(DL_Var));
if(!(v->t.xid = str2list(gwi->gwion->env, type, &v->array_depth)))
- ERR_B(0, "\t...\tduring var import '%s.%s'.",
+ ERR_B(gwi->loc, "\t...\tduring var import '%s.%s'.",
gwi->gwion->env->class_def->name, name)
v->var.xid = insert_symbol(gwi->gwion->st, name);
return GW_OK;
v->var.addr = (void*)addr;
if(gwi->gwion->env->class_def && GET_FLAG(gwi->gwion->env->class_def, template)) {
Type_Decl *type_decl = new_type_decl(gwi->gwion->p, v->t.xid, flag);
- const Var_Decl var_decl = new_var_decl(gwi->gwion->p, v->var.xid, v->var.array, 0);
+ const Var_Decl var_decl = new_var_decl(gwi->gwion->p, v->var.xid, v->var.array, loc_cpy(gwi->gwion->p, gwi->loc));
const Var_Decl_List var_decl_list = new_var_decl_list(gwi->gwion->p, var_decl, NULL);
const Exp exp = new_exp_decl(gwi->gwion->p, type_decl, var_decl_list);
const Stmt stmt = new_stmt_exp(gwi->gwion->p, ae_stmt_exp, exp);
gwi_body(gwi, body);
return GW_OK;
}
+ v->exp.pos = gwi->loc;
CHECK_BB(traverse_decl(gwi->gwion->env, &v->exp.d.exp_decl))
SET_FLAG(v->var.value, builtin);
dl_var_release(gwi->gwion->p, v);
return td;
}
-ANN static Arg_List make_dll_arg_list(const Env env, DL_Func * dl_fun) {
+ANN static Arg_List make_dll_arg_list(const Gwi gwi, DL_Func * dl_fun) {
+ const Env env = gwi->gwion->env;
Arg_List arg_list = NULL;
for(m_uint i = dl_fun->narg + 1; --i; ) {
m_uint array_depth = 0, array_depth2 = 0;
if(!(type_decl = str2decl(env, arg->type, &array_depth))) {
if(arg_list)
free_arg_list(env->gwion->p, arg_list);
- env_err(env, 0, "\t...\tat argument '%i'", i + 1);
+ env_err(env, gwi->loc, "\t...\tat argument '%i'", i + 1);
return NULL;
}
if((type_path2 = str2list(env, arg->name, &array_depth2)))
free_type_decl(env->gwion->p, type_decl);
if(arg_list)
free_arg_list(env->gwion->p, arg_list);
- env_err(env, 0, "array subscript specified incorrectly for built-in module");
+ env_err(env, gwi->loc, "array subscript specified incorrectly for built-in module");
return NULL;
}
array_sub = make_dll_arg_list_array(env->gwion->p, array_sub, &array_depth, array_depth2);
- var_decl = new_var_decl(env->gwion->p, insert_symbol(env->gwion->st, arg->name), array_sub, 0);
+ var_decl = new_var_decl(env->gwion->p, insert_symbol(env->gwion->st, arg->name), array_sub, loc_cpy(gwi->gwion->p, gwi->loc));
arg_list = new_arg_list(env->gwion->p, type_decl, var_decl, arg_list);
}
return arg_list;
}
-ANN static Func_Def make_dll_as_fun(const Env env, DL_Func * dl_fun, ae_flag flag) {
+ANN static Func_Def make_dll_as_fun(const Gwi gwi, DL_Func * dl_fun, ae_flag flag) {
+ const Env env = gwi->gwion->env;
Func_Def func_def = NULL;
ID_List type_path = NULL;
Type_Decl* type_decl = NULL;
flag |= ae_flag_builtin;
if(!(type_path = str2list(env, dl_fun->type, &array_depth)) ||
!(type_decl = new_type_decl(env->gwion->p, type_path, 0))) {
- env_err(env, 0, "\t...\tduring @ function import '%s' (type).", dl_fun->name);
+ if(type_path)free_id_list(env->gwion->p, type_path);
+ env_err(env, gwi->loc, "\t...\tduring @ function import '%s' (type).", dl_fun->name);
return NULL;
}
if(array_depth) {
type_decl = add_type_decl_array(type_decl, array_sub);
}
name = dl_fun->name;
- arg_list = make_dll_arg_list(env, dl_fun);
- func_def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, type_decl, insert_symbol(env->gwion->st, name), arg_list), NULL, flag, 0);
+ arg_list = make_dll_arg_list(gwi, dl_fun);
+ func_def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, type_decl, insert_symbol(env->gwion->st, name), arg_list),
+ NULL, flag, loc_cpy(gwi->gwion->p, gwi->loc));
func_def->d.dl_func_ptr = (void*)(m_uint)dl_fun->addr;
return func_def;
}
-ANN static Func_Def import_fun(const Env env, DL_Func * mfun, const ae_flag flag) {
- CHECK_BO(name_valid(env, mfun->name));
- return make_dll_as_fun(env, mfun, flag);
-}
-
ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag) {
- Func_Def def = import_fun(gwi->gwion->env, &gwi->func, flag);
+ CHECK_BB(name_valid(gwi, gwi->func.name));
+ Func_Def def = make_dll_as_fun(gwi, &gwi->func, flag);
+// Func_Def def = import_fun(gwi->gwion->env, &gwi->func, flag);
CHECK_OB(def)
if(gwi->templater.n) {
- def = new_func_def(gwi->gwion->p, new_func_base(gwi->gwion->p, NULL, NULL, NULL), NULL, 0, 0);
- const ID_List list = templater_def(gwi->gwion->st, &gwi->templater);
+ def = new_func_def(gwi->gwion->p, new_func_base(gwi->gwion->p, NULL, NULL, NULL), NULL, 0, loc_cpy(gwi->gwion->p, gwi->loc));
+ const ID_List list = templater_def(gwi->gwion->st, gwi);
def->tmpl = new_tmpl_list(gwi->gwion->p, list, -1);
SET_FLAG(def, template);
}
return t ? (depth ? array_type(env, t, depth) : t) : NULL;
}
-ANN2(1,2) static int import_op(const Env env, const DL_Oper* op,
+ANN2(1,2) static int import_op(const Gwi gwi, const DL_Oper* op,
const f_instr f) {
+ const Env env = gwi->gwion->env;
const Type lhs = op->lhs ? get_type(env, op->lhs) : NULL;
const Type rhs = op->rhs ? get_type(env, op->rhs) : NULL;
const Type ret = get_type(env, op->ret);
const struct Op_Import opi = { lhs, rhs, ret,
- op->ck, op->em, (uintptr_t)f, 0, op->op, op->mut };
+ op->ck, op->em, (uintptr_t)f, gwi->loc, op->op, op->mut };
return env_add_op(env, &opi);
}
ANN m_int gwi_oper_end(const Gwi gwi, const Operator op, const f_instr f) {
gwi->oper.op = op;
- const m_bool ret = import_op(gwi->gwion->env, &gwi->oper, f);
+ const m_bool ret = import_op(gwi, &gwi->oper, f);
gwi->oper.ck = NULL;
gwi->oper.em = NULL;
return ret;
return GW_OK;
}
-ANN static Stmt import_fptr(const Env env, DL_Func* dl_fun, ae_flag flag) {
+ANN static Stmt import_fptr(const Gwi gwi, DL_Func* dl_fun, ae_flag flag) {
+ const Env env = gwi->gwion->env;
m_uint array_depth;
ID_List type_path;
Type_Decl* type_decl = NULL;
- const Arg_List args = make_dll_arg_list(env, dl_fun);
+ const Arg_List args = make_dll_arg_list(gwi, dl_fun);
flag |= ae_flag_builtin;
if(!(type_path = str2list(env, dl_fun->type, &array_depth)) ||
!(type_decl = new_type_decl(env->gwion->p, type_path, 0))) {
- env_err(env, 0, "\t...\tduring fptr import '%s' (type).",
+ env_err(env, gwi->loc, "\t...\tduring fptr import '%s' (type).",
dl_fun->name);
return NULL;
}
}
ANN Type gwi_fptr_end(const Gwi gwi, const ae_flag flag) {
- const Stmt stmt = import_fptr(gwi->gwion->env, &gwi->func, flag);
+ const Stmt stmt = import_fptr(gwi, &gwi->func, flag);
CHECK_BO(traverse_stmt_fptr(gwi->gwion->env, &stmt->d.stmt_fptr))
if(gwi->gwion->env->class_def)
SET_FLAG(stmt->d.stmt_fptr.base->func->def, builtin);
else
SET_FLAG(stmt->d.stmt_fptr.base->func, builtin);
const Type t = stmt->d.stmt_fptr.type;
- ADD_REF(t);
+// ADD_REF(t);
free_stmt(gwi->gwion->p, stmt);
return t;
}
-ANN static Exp make_exp(const Env env, const m_str type, const m_str name) {
+ANN static Exp make_exp(const Gwi gwi, const m_str type, const m_str name) {
+ const Env env = gwi->gwion->env;
Type_Decl *type_decl;
ID_List id_list;
m_uint array_depth;
}
type_decl = new_type_decl(env->gwion->p, id_list, 0);
const Var_Decl var_decl = new_var_decl(env->gwion->p,
- insert_symbol(env->gwion->st, name), array, 0);
+ insert_symbol(env->gwion->st, name), array, loc_cpy(env->gwion->p, gwi->loc));
const Var_Decl_List var_decl_list = new_var_decl_list(env->gwion->p, var_decl, NULL);
return new_exp_decl(env->gwion->p, type_decl, var_decl_list);
}
}
ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict m_str name) {
- const Exp exp = make_exp(gwi->gwion->env, type, name);
+ const Exp exp = make_exp(gwi, type, name);
CHECK_OB(exp);
const Type t = type_decl_resolve(gwi->gwion->env, exp->d.exp_decl.td);
if(!t)
- ERR_B(0, "type '%s' unknown in union declaration.", type)
+ ERR_B(gwi->loc, "type '%s' unknown in union declaration.", type)
if(isa(t, t_object) > 0)
SET_FLAG(exp->d.exp_decl.td, ref);
gwi->union_data.list = new_decl_list(gwi->gwion->p, exp, gwi->union_data.list);
ANN Type gwi_union_end(const Gwi gwi, const ae_flag flag) {
if(!gwi->union_data.list)
- ERR_O(0, "union is empty");
- const Stmt stmt = new_stmt_union(gwi->gwion->p, gwi->union_data.list, 0);
+ ERR_O(gwi->loc, "union is empty");
+ const Stmt stmt = new_stmt_union(gwi->gwion->p, gwi->union_data.list, loc_cpy(gwi->gwion->p, gwi->loc));
stmt->d.stmt_union.flag = flag;
CHECK_BO(traverse_stmt_union(gwi->gwion->env, &stmt->d.stmt_union))
emit_union_offset(stmt->d.stmt_union.l, stmt->d.stmt_union.o);
}
ANN m_int gwi_enum_add(const Gwi gwi, const m_str name, const m_uint i) {
- const ID_List list = new_id_list(gwi->gwion->p, insert_symbol(gwi->gwion->st, name), 0);
+ const ID_List list = new_id_list(gwi->gwion->p, insert_symbol(gwi->gwion->st, name), loc_cpy(gwi->gwion->p, gwi->loc));
DL_Enum* d = &gwi->enum_data;
ALLOC_PTR(gwi->gwion->p, addr, m_int, i);
vector_add(&gwi->enum_data.addr, (vtype)addr);
CHECK_OO(v)
const Func_Def base = v->d.func_ref->def;
const Func_Def def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, base->base->td, insert_symbol(env->gwion->st, v->name),
- base->base->args), base->d.code, base->flag, base->pos);
+ base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->p, base->pos));
def->tmpl = new_tmpl_list(env->gwion->p, base->tmpl->list, dt->overload);
SET_FLAG(def, template);
return def;
return t_null;
if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, ref);
- if(l != t_null && isa(l, r) < 0)
- ERR_N(exp_self(bin)->pos, "'%s' @=> '%s': not allowed", l->name, r->name)
+ if(l != t_null && isa(l, r) < 0) {
+ env_err(env, exp_self(bin)->pos, "'%s' @=> '%s': not allowed", l->name, r->name);
+ return t_null;
+ }
bin->rhs->emit_var = 1;
return r;
}
#include "object.h"
#include "import.h"
#include "emit.h"
+#include "parse.h"
static inline m_str access(ae_Exp_Meta meta) {
return meta == ae_meta_value ? "non-mutable" : "protected";
#include "emit.h"
#include "operator.h"
#include "driver.h"
+#include "parse.h"
#define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func)
_CHECK_OP(chuck, rassign, Time_Advance)
CHECK_BB(gwi_oper_ini(gwi, "@now", "@now", NULL))
_CHECK_OP(chuck, chuck_now, NULL)
+ CHECK_BB(gwi_oper_ini(gwi, NULL, "@now", NULL))
+ CHECK_BB(gwi_oper_end(gwi, op_not, NULL))
CHECK_BB(gwi_oper_ini(gwi, "time", "time", "int"))
CHECK_BB(gwi_oper_end(gwi, op_gt, float_gt))
CHECK_BB(gwi_oper_end(gwi, op_ge, float_ge))
Type t = bin->lhs->type;
do {
if(!strcmp(t->name, get_type_name(env, bin->rhs->type->name, 1))) {
- if(bin->lhs->meta != ae_meta_var)
- ERR_N(0, "left side operand is constant")
+ if(bin->lhs->meta != ae_meta_var) {
+ env_err(env, exp_self(bin)->pos, "left side operand is constant");
+ return t_null;
+ }
bin->lhs->emit_var = 1;
return bin->lhs->type;
}
const struct Implicit* imp = (struct Implicit*)data;
const Exp e = (Exp)imp->e;
if(!strcmp(get_type_name(env, imp->t->name, 1), e->type->name)) {
- if(e->meta == ae_meta_value)
- ERR_N(0, "can't cast constant to Ptr");
+ if(e->meta == ae_meta_value) {
+ env_err(env, 0, "can't cast constant to Ptr");
+ return t_null;
+ }
e->cast_to = imp->t;
e->emit_var = 1;
return imp->t;
const M_Object o = *(M_Object*)REG(-SZ_INT);
if(instr->m_val2)
memcpy(REG(-SZ_INT), o->data, SZ_INT);
- else
- memcpy(REG(-SZ_INT), *(m_bit**)o->data, instr->m_val);
+ else {
+ shred->reg -= SZ_INT - instr->m_val;
+ memcpy(REG(-instr->m_val), *(m_bit**)o->data, instr->m_val);
+ }
}
static OP_EMIT(opem_ptr_deref) {
#include "shreduler_private.h"
#include "gwion.h"
-static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval;
+static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval,
+ o_fork_orig;
#define FORK_THREAD(o) *(THREAD_TYPE*)(o->data + o_fork_thread)
#define FORK_RETSIZE(o) *(m_int*)(o->data + o_fork_retsize)
#define FORK_RETVAL(o) (o->data + o_fork_retval)
+#define FORK_ORIG(o) (*(VM**)((o)->data + o_fork_orig))
M_Object new_shred(const VM_Shred shred, m_bool is_spork) {
const M_Object obj = new_object(shred->info->mp, NULL, is_spork ? t_shred : t_fork);
static SFUN(vm_shred_from_id) {
const m_int index = *(m_int*)MEM(0);
- const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, (vtype)index);
- if(s)
- *(M_Object*)RETURN = s->info->me;
- else
- *(m_uint*)RETURN = 0;
+// TODO vector_size_safe()
+ if(index <= 0 && (m_uint)index < vector_size(&shred->tick->shreduler->shreds)) {
+ const VM_Shred s = (VM_Shred)vector_at(&shred->tick->shreduler->shreds, (vtype)index);
+ if(s)
+ *(M_Object*)RETURN = s->info->me;
+ else
+ *(m_uint*)RETURN = 0;
+ }
}
static MFUN(shred_args) {
static MFUN(fork_join) {
MUTEX_LOCK(ME(o)->tick->shreduler->mutex);
MUTEX_LOCK(shred->tick->shreduler->mutex);
+ release(o, shred);
if(*(m_int*)(o->data + o_fork_done)) {
MUTEX_UNLOCK(shred->tick->shreduler->mutex);
MUTEX_UNLOCK(ME(o)->tick->shreduler->mutex);
} while(vm->bbq->is_running);
fork_retval(me);
MUTEX_LOCK(vm->shreduler->mutex);
+// MUTEX_LOCK(FORK_ORIG(me)->shreduler->mutex);
+ vector_rem2(&FORK_ORIG(me)->gwion->child, (vtype)me);
+// MUTEX_UNLOCK(FORK_ORIG(me)->shreduler->mutex);
*(m_int*)(me->data + o_fork_done) = 1;
broadcast(*(M_Object*)(me->data + o_fork_ev));
MUTEX_UNLOCK(vm->shreduler->mutex);
THREAD_RETURN(NULL);
}
-void fork_launch(const M_Object o, const m_uint sz) {
+ANN void fork_clean(const VM *vm, const Vector v) {
+ for(m_uint i = 0; i < vector_size(v); ++i) {
+ const M_Object o = (M_Object)vector_at(v, i);
+ THREAD_JOIN(FORK_THREAD(o));
+ release(o, vm->cleaner_shred);
+ }
+ vector_release(v);
+}
+
+void fork_launch(const VM* vm, const M_Object o, const m_uint sz) {
+ ++o->ref;
++o->ref;
+// Gwion gwion = ME(o)->info->vm->gwion;
+// if(!gwion->child.ptr)
+// vector_init(&gwion->child);
+// vector_add(&gwion->child, (vtype)o);
+// o->ref += 2;
+ if(!vm->gwion->child.ptr) {
+ vector_init(&vm->gwion->child);
+ }
+ vector_add(&vm->gwion->child, (vtype)o);
+ FORK_ORIG(o) = (VM*)vm;
FORK_RETSIZE(o) = sz;
+//printf("sz %lu\n", vector_size(&gwion->child));
THREAD_CREATE(FORK_THREAD(o), fork_run, o);
}
CHECK_BB((o_fork_ev = gwi_item_end(gwi, ae_flag_const, NULL)))
gwi_item_ini(gwi, "int", "retsize");
CHECK_BB((o_fork_retsize = gwi_item_end(gwi, ae_flag_const, NULL)))
+ gwi_item_ini(gwi, "int", "@orig");
+ CHECK_BB((o_fork_orig = gwi_item_end(gwi, ae_flag_const, NULL)))
o_fork_retval = t_fork->nspc->info->offset;
CHECK_BB(gwi_union_ini(gwi, NULL))
CHECK_BB(gwi_union_add(gwi, "int", "i"))
path = path->next;
while(path) {
const Symbol xid = path->xid;
- Type t = nspc_lookup_type1(nspc, xid);
- while(!t && type && type->parent) {
- t = nspc_lookup_type1(type->parent->nspc, xid); // was lookup2
- type = type->parent;
+ if(nspc) {
+ Type t = nspc_lookup_type1(nspc, xid);
+ while(!t && type && type->parent && type->parent) {
+ t = nspc_lookup_type1(type->parent->nspc, xid); // was lookup2
+ type = type->parent;
+ }
+ if(!t)
+ ERR_O(path->pos, "...(cannot find class '%s' in nspc '%s')", s_name(xid), nspc->name)
+ type = t;
}
- if(!t)
- ERR_O(path->pos, "...(cannot find class '%s' in nspc '%s')", s_name(xid), nspc->name)
- type = t;
nspc = type->nspc;
path = path->next;
}
ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos) {
const Value v = nspc_lookup_value0(env->curr, s);
- return v ? err_msg(pos,
- "'%s' already declared as variable of type '%s'.", s_name(s), v->type->name) : GW_OK;
+ if(!v)
+ return GW_OK;
+ env_err(env, pos,
+ "'%s' already declared as variable of type '%s'.", s_name(s), v->type->name);
+ return GW_ERROR;
}
#include "type.h"
#include "context.h"
#include "nspc.h"
+#include "parse.h"
+#include "switch.h"
static inline void _scope_add(Scope s, Switch sw) { vector_add((Vector)(void*)s, (vtype)sw); }
static inline vtype _scope_pop(Scope s) { return vector_pop((Vector)(void*)s); }
}
ANN static void free_switch(MemPool p, const Switch sw) {
-// if(!sw->ok)
-// free_map(sw->cases);
+ if(!sw->ok)
+ free_map(p, sw->cases);
free_vector(p, sw->vec); // only for dynamic
vector_release(&sw->exp);
mp_free(p, Switch, sw);
info->f = env->func;
const Switch sw = new_switch(env->gwion->p);
map_set(&env->scope->swi.map, (vtype)info, (vtype)sw);
+ sw->depth = env->scope->depth + 2;
return sw;
}
return GW_OK;
}
+ANN m_bool switch_decl(const Env env, const loc_t pos) {
+ const Switch sw = (Switch)(VLEN(&env->scope->swi.map) ?
+ VVAL(&env->scope->swi.map, VLEN(&env->scope->swi.map) - 1): 0);
+ if(sw && sw->depth == env->scope->depth)
+ ERR_B(pos, "Declaration in switch is prohibited.")
+ return GW_OK;
+}
+
ANN void switch_get(const Env env, const Stmt_Switch stmt) {
const struct SwInfo_ info = { stmt, env->class_def, env->func };
const Switch sw = swinfo_get(env, &info);
struct SwInfo_ *info = (struct SwInfo_ *)VKEY(&env->scope->swi.map, i - 1);
mp_free(env->gwion->p, SwInfo, info);
Switch sw = (Switch)VVAL(&env->scope->swi.map, i - 1);
- free_map(env->gwion->p, sw->cases);
+//if(sw->cases)
+// free_map(env->gwion->p, sw->cases);
free_switch(env->gwion->p, sw);
}
_scope_clear(&env->scope->swi);
const Switch sw = (Switch)_scope_back(&env->scope->swi);
if(map_get(sw->cases, (vtype)value))
ERR_B(pos, "duplicated cases value %i", value)
+ sw->ok = 1;
return GW_OK;
}
return sw->default_case_index;
}
-ANN void switch_pop(const Env env) {
+ANN m_bool switch_pop(const Env env) {
_scope_pop(&env->scope->swi);
+ return GW_OK;
}
-ANN void switch_end(const Env env) {
+ANN m_bool switch_end(const Env env, const loc_t pos) {
const Switch sw = (Switch)_scope_pop(&env->scope->swi);
const vtype index = VKEY(&env->scope->swi.map, VLEN(&env->scope->swi.map) - 1);
+ sw->ok = 1;
+ if(!VLEN(sw->cases) && !VLEN(&sw->exp))
+ ERR_B(pos, "switch statement with no cases.")
map_remove(&env->scope->swi.map, index);
free_switch(env->gwion->p, sw);
-// return sw->ok = 1;
+ return GW_OK;
}
#define describe_find(name, t) \
ANN t find_##name(const Type type, const Symbol xid) { \
+ if(type->nspc) { \
const t val = nspc_lookup_##name##0(type->nspc, xid); \
if(val) \
return val; \
+ } \
return type->parent ? find_##name(type->parent, xid) : NULL; \
}
describe_find(value, Value)
nspc->info->b += v->type->size; \
}
describe_check_decl(member, offset)
-describe_check_decl(static, class_data_size)
+//describe_check_decl(static, class_data_size)
+ANN static inline void decl_static(const Nspc nspc, const Value v) { \
+ SET_FLAG(v, static);
+ v->offset = nspc->info->class_data_size;
+ nspc->info->class_data_size += v->type->size;
+}
ANN static m_bool check_fptr_decl(const Env env, const Var_Decl var) {
const Value v = var->value;
td->xid = str2list(env, t->name, &depth);
if(depth) {
- Exp base = new_exp_prim_int(env->gwion->p, 0, 0), e = base;
+ Exp base = new_exp_prim_int(env->gwion->p, 0, new_loc(env->gwion->p, __LINE__)), e = base;
for(m_uint i = 0; i < depth - 1; ++i) {
- e = (e->next = new_exp_prim_int(env->gwion->p, 0, 0));
+ e = (e->next = new_exp_prim_int(env->gwion->p, 0, new_loc(env->gwion->p, __LINE__)));
}
td->array = new_array_sub(env->gwion->p, base);
}
ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
Var_Decl_List list = decl->list;
-
+ CHECK_BO(switch_decl(env, exp_self(decl)->pos))
if(!decl->td->xid) {
const Type t = check_td(env, decl->td);
CHECK_OO(t)
if(decl->td->xid->xid == insert_symbol("auto")) { // should be better
CHECK_BO(scan1_exp(env, exp_self(decl)))
CHECK_BO(scan2_exp(env, exp_self(decl)))
+ if(decl->type == t_auto)
+ ERR_O(td_pos(decl->td), "can't infer type.");
}
if(GET_FLAG(decl->type , template)) {
const Type t = typedef_base(decl->type);
CHECK_BO(traverse_template(env, t->def))
}
- m_uint scope;
const m_bool global = GET_FLAG(decl->td, global);
- if(global)
- scope = env_push_global(env);
+ const m_uint scope = !global ? env->scope->depth : env_push_global(env);
do {
const Var_Decl var = list->self;
const Value v = var->value;
}
ID_List id = NULL;
for(m_uint i = vector_size(&v) + 1; --i;)
- id = prepend_id_list(env->gwion->p, (Symbol)vector_at(&v, i - 1), id, 0);
+ id = prepend_id_list(env->gwion->p, (Symbol)vector_at(&v, i - 1), id, new_loc(env->gwion->p, __LINE__));
vector_release(&v);
assert(id);
Type_Decl* td = new_type_decl(env->gwion->p, id, 0);
continue;
base = value->d.func_ref->def;
def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, base->base->td, insert_symbol(v->name),
- base->base->args), base->d.code, base->flag, base->pos);
+ base->base->args), base->d.code, base->flag, loc_cpy(env->gwion->p, base->pos));
def->tmpl = new_tmpl_list(env->gwion->p, base->tmpl->list, (m_int)i);
SET_FLAG(def, template);
}
}
if(arg || e)
ERR_O(exp_self(exp)->pos, "argument number does not match for lambda")
- l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, NULL, l->name, l->args), l->code, 0, exp_self(exp)->pos);
+ l->def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, NULL, l->name, l->args),
+ l->code, 0, loc_cpy(env->gwion->p, exp_self(exp)->pos));
CHECK_BO(traverse_func_def(env, l->def))
if(env->class_def)
SET_FLAG(l->def, member);
check_conts(env, stmt_self(stmt), stmt->body) < 0) ? 1 : -1)
stmt_func_xxx(switch, Stmt_Switch,, !(!check_exp(env, stmt->val) ||
cond_type(env, stmt->val) < 0 || !switch_add(env, stmt) ||
- check_breaks(env, stmt_self(stmt), stmt->stmt) < 0 || !switch_pop(env)) ? 1 : -1)
+ check_breaks(env, stmt_self(stmt), stmt->stmt) < 0 || switch_pop(env) < 0) ? 1 : -1)
stmt_func_xxx(auto, Stmt_Auto,, do_stmt_auto(env, stmt))
ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) { GWDEBUG_EXE
ANN Value case_value(const Exp exp);
ANN static m_bool check_stmt_case(const Env env, const Stmt_Exp stmt) { GWDEBUG_EXE
+ CHECK_BB(switch_inside(env, stmt_self(stmt)->pos));
const Type t = check_exp(env, stmt->val);
CHECK_OB(t);
if(isa(t, t_int) < 0)
if(!m)
ERR_B(stmt_self(stmt)->pos, "label '%s' used but not defined", s_name(stmt->name))
const Stmt_Jump ref = (Stmt_Jump)map_get(m, (vtype)stmt->name);
- if(!ref) {
- for(m_uint i = 0; i < map_size(m); ++i) {
- const Stmt_Jump s = (Stmt_Jump)map_at(m, i);
- vector_release(&s->data.v);
- }
+ if(!ref)
ERR_B(stmt_self(stmt)->pos, "label '%s' used but not defined", s_name(stmt->name))
- }
vector_add(&ref->data.v, (vtype)stmt);
return GW_OK;
}
ANN void did_you_mean_nspc(Nspc nspc, const char* name) {
struct Vector_ v;
vector_init(&v);
- do ressembles(&v, nspc, name);
+ do ressembles(&v, nspc, name);
while((nspc = nspc->parent));
for(m_uint i = 0; i < vector_size(&v); ++i)
gw_err("\t(did you mean '%s'?)\n", (m_str)vector_at(&v, i));
struct Vector_ v;
vector_init(&v);
do ressembles(&v, t->nspc, name);
- while((t = t->parent));
+ while((t = t->parent) && t->nspc);
for(m_uint i = 0; i < vector_size(&v); ++i)
gw_err("\t(did you mean '%s'?)\n", (m_str)vector_at(&v, i));
did_you_mean_nspc(type->nspc, name);
ANN static void free_func(Func a, Gwion gwion) {
if(GET_FLAG(a, template)) {
free_tmpl_list(gwion->p, a->def->tmpl);
+ free_func_base(gwion->p, a->def->base);
+ free_loc(gwion->p, a->def->pos);
mp_free(gwion->p, Func_Def, a->def);
}
if(a->code)
if(!n->info->op_map.ptr)
continue;
const Vector v = (Vector)map_get(&n->info->op_map, (vtype)opi->op);
- if(v && (mo = operator_find(v, opi->lhs, opi->rhs)))
- ERR_B(opi->pos, "operator '%s', for type '%s' and '%s' already imported",
+ if(v && (mo = operator_find(v, opi->lhs, opi->rhs))) {
+ env_err(gwion->env, opi->pos, "operator '%s', for type '%s' and '%s' already imported",
op2str(opi->op), opi->lhs ? opi->lhs->name : NULL,
- opi->rhs ? opi->rhs->name : NULL)
+ opi->rhs ? opi->rhs->name : NULL);
+ return GW_ERROR;
+ }
} while((n = n->parent));
Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
if(!v) {
nspc = nspc->parent;
} while(nspc);
if(opi->op == op_cast || (ret != t_null && opi->op != op_impl))
- err_msg(opi->pos, "%s %s %s: no match found for operator",
+ env_err(env, opi->pos, "%s %s %s: no match found for operator",
type_name(opi->lhs), op2str(opi->op), type_name(opi->rhs));
return NULL;
}
ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) {
if(mo->func) {
- const Instr instr = emit_add_instr(emit, RegPushImm);
- instr->m_val = (m_uint)mo->func->code;
+ const Instr instr = emit_add_instr(emit, mo->func->code ? RegPushImm : PushStaticCode);
+ instr->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
return emit_exp_call1(emit, mo->func);
}
emit_add_instr(emit, mo->instr);
}
ANN static inline m_bool scan0_defined(const Env env, const Symbol s, const loc_t pos) {
- if(nspc_lookup_type1(env->curr, s))
+ if(nspc_lookup_type0(env->curr, s))
ERR_B(pos, "type '%s' already defined", s_name(s));
return already_defined(env, s, pos);
}
return GW_OK;
}
-ANN static m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG_EXE
+ANN /*static */ m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG_EXE
CHECK_BB(env_access(env, stmt->ext->flag, stmt_self(stmt)->pos))
const Type base = known_type(env, stmt->ext);
CHECK_OB(base)
SET_FLAG(t, empty);
} else {
const ae_flag flag = base->def ? base->def->flag : 0;
- const Class_Def def = new_class_def(env->gwion->p, flag, stmt->xid, stmt->ext, NULL, stmt->ext->xid->pos);
+ const Class_Def def = new_class_def(env->gwion->p, flag, stmt->xid, stmt->ext, NULL,
+ loc_cpy(env->gwion->p, td_pos(stmt->ext)));
CHECK_BB(scan0_class_def(env, def))
stmt->type = def->base.type;
}
return t;
}
-ANN static m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE
+ANN /* static */m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE
CHECK_BB(env_storage(env, stmt->flag, stmt_self(stmt)->pos))
if(stmt->xid) {
CHECK_BB(scan0_defined(env, stmt->xid, stmt_self(stmt)->pos))
stmt->value->owner = nspc;
nspc_add_value(nspc, stmt->xid, stmt->value);
SET_FLAG(stmt->value, checked | stmt->flag);
- if(env->class_def && !GET_FLAG(stmt, static))
+ if(env->class_def && !GET_FLAG(stmt, static)) {
SET_FLAG(stmt->value, member);
+ SET_FLAG(stmt, member);
+ }
if(!stmt->type_xid)
SET_FLAG(t, op);
} else if(stmt->type_xid) {
const Nspc nspc = !GET_FLAG(stmt, global) ?
env->curr : env->global_nspc;
stmt->type = union_type(env, nspc, stmt->type_xid, 1);
+ } else {
+ const Nspc nspc = !GET_FLAG(stmt, global) ?
+ env->curr : env->global_nspc;
+ const Type t = union_type(env, nspc, insert_symbol("union"), 1);
+ stmt->value = new_value(env->gwion->p, t, "union");
+ stmt->value->owner_class = env->class_def;
+ stmt->value->owner = nspc;
+ nspc_add_value(nspc, stmt->xid, stmt->value);
+ SET_FLAG(stmt->value, checked | stmt->flag);
+
}
return GW_OK;
}
-ANN static m_bool scan0_Stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE
+ANN static m_bool scan0_stmt_switch(const Env env, const Stmt_Switch stmt);
+ANN static m_bool scan0_stmt_code(const Env env, const Stmt_Code stmt);
+ANN static m_bool scan0_stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE
if(stmt->stmt_type == ae_stmt_fptr)
return scan0_stmt_fptr(env, &stmt->d.stmt_fptr);
if(stmt->stmt_type == ae_stmt_type)
return scan0_stmt_enum(env, &stmt->d.stmt_enum);
if(stmt->stmt_type == ae_stmt_union)
return scan0_stmt_union(env, &stmt->d.stmt_union);
+ if(stmt->stmt_type == ae_stmt_code)
+ return scan0_stmt_code(env, &stmt->d.stmt_code);
+ if(stmt->stmt_type == ae_stmt_switch)
+ return scan0_stmt_switch(env, &stmt->d.stmt_switch);
return GW_OK;
}
-ANN static m_bool scan0_Stmt_List(const Env env, Stmt_List l) { GWDEBUG_EXE
- do CHECK_BB(scan0_Stmt(env, l->stmt))
+ANN static m_bool scan0_stmt_list(const Env env, Stmt_List l);
+ANN static m_bool scan0_stmt_switch(const Env env, const Stmt_Switch stmt) {
+// CHECK_BB(scan0_exp(env, stmt->val))
+ return scan0_stmt(env, stmt->stmt);
+}
+ANN static m_bool scan0_stmt_code(const Env env, const Stmt_Code stmt) { GWDEBUG_EXE
+ return stmt->stmt_list ? scan0_stmt_list(env, stmt->stmt_list) : GW_OK;
+}
+
+ANN static m_bool scan0_stmt_list(const Env env, Stmt_List l) { GWDEBUG_EXE
+ do CHECK_BB(scan0_stmt(env, l->stmt))
while((l = l->next));
return GW_OK;
}
return t;
}
+ANN static m_bool scan0_func_def(const Env env, const Func_Def def) {
+ return def->d.code ? scan0_stmt(env, def->d.code) : GW_OK;
+}
+
ANN static m_bool scan0_section(const Env env, const Section* section) { GWDEBUG_EXE
if(section->section_type == ae_section_stmt)
- return scan0_Stmt_List(env, section->d.stmt_list);
+ return scan0_stmt_list(env, section->d.stmt_list);
if(section->section_type == ae_section_class)
return scan0_class_def(env, section->d.class_def);
+ if(section->section_type == ae_section_func)
+ return scan0_func_def(env, section->d.func_def);
return GW_OK;
}
#include "optim.h"
#include "vm.h"
#include "parse.h"
-
-//#define FAKE_FUNC ((Func)1)
+#include "traverse.h"
ANN m_bool scan0_class_def(const Env env, const Class_Def class_def);
ANN /* static */ m_bool scan1_exp(const Env env, Exp exp);
ANN m_bool scan1_class_def(const Env env, const Class_Def class_def);
ANN static m_bool scan1_stmt(const Env env, Stmt stmt);
-ANN static Type void_type(const Env env, const Type_Decl* td, const loc_t pos) {
+ANN static Type void_type(const Env env, const Type_Decl* td) {
const Type t = known_type(env, td);
CHECK_OO(t)
if(t->size)
return t;
- ERR_O(pos, "cannot declare variables of size '0' (i.e. 'void')...")
+ ERR_O(td_pos(td), "cannot declare variables of size '0' (i.e. 'void')...")
}
ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
- const Type t = void_type(env, decl->td, exp_self(decl)->pos);
+ const Type t = void_type(env, decl->td);
CHECK_OO(t);
if(decl->td->xid && decl->td->xid->xid == insert_symbol("auto") && decl->type)
return decl->type;
return t;
}
-ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE
+ANN m_bool scan1_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos))
Var_Decl_List list = decl->list;
((Exp_Decl*)decl)->type = scan1_exp_decl_type(env, (Exp_Decl*)decl);
CHECK_OB(decl->type)
const m_bool global = GET_FLAG(decl->td, global);
- m_uint scope = !global ? env->scope->depth : env_push_global(env);
+ const m_uint scope = !global ? env->scope->depth : env_push_global(env);
const Nspc nspc = !global ? env->curr : env->global_nspc;
- if(global)
- scope = env_push_global(env);
do {
Type t = decl->type;
const Var_Decl var = list->self;
const Value former = nspc_lookup_value0(env->curr, var->xid);
CHECK_BB(isres(env, var->xid, exp_self(decl)->pos))
- if(!decl->td->exp && decl->td->xid->xid != insert_symbol("auto") &&
- former && (!env->class_def || // cuold be better
- (!GET_FLAG(env->class_def, template) || !GET_FLAG(env->class_def, scan1))))
+ if(former && !decl->td->exp &&
+/*!(decl->td->xid->xid == insert_symbol("auto") && former->type != t_auto) &&*/
+//(decl->td->xid->xid == insert_symbol("auto") && former->type != t_auto) &&
+//(!env->class_def ||
+// (!GET_FLAG(env->class_def, template) || !GET_FLAG(env->class_def, scan1))))
+ (!env->class_def || !(GET_FLAG(env->class_def, template) || GET_FLAG(env->class_def, scan1))))
ERR_B(var->pos, "variable %s has already been defined in the same scope...",
s_name(var->xid))
- if(var->array && decl->type != t_undefined) {
+ if(var->array && decl->type != t_undefined && decl->type != t_auto) {
if(var->array->exp) {
if(GET_FLAG(decl->td, ref))
ERR_B(td_pos(decl->td), "ref array must not have array expression.\n"
v->owner = !env->func ? env->curr : NULL;
v->owner_class = env->scope->depth ? NULL : env->class_def;
} while((list = list->next));
- decl->type = decl->list->self->value->type;
+ ((Exp_Decl*)decl)->type = decl->list->self->value->type;
if(global)
env_pop(env, scope);
return GW_OK;
ANN static m_bool scan1_exp_post(const Env env, const Exp_Postfix* post) { GWDEBUG_EXE
CHECK_BB(scan1_exp(env, post->exp))
- return post->exp->meta == ae_meta_var ? 1 :
- err_msg(post->exp->pos, "post operator '%s' cannot be used"
- " on non-mutable data-type...", op2str(post->op));
+ if(post->exp->meta == ae_meta_var)
+ return GW_OK;
+ env_err(env, post->exp->pos, "post operator '%s' cannot be used"
+ " on non-mutable data-type...", op2str(post->op));
+ return GW_ERROR;
}
ANN static m_bool scan1_exp_call(const Env env, const Exp_Call* exp_call) { GWDEBUG_EXE
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
describe_ret_nspc(loop, Stmt_Loop,, !(scan1_exp(env, stmt->cond) < 0 ||
scan1_stmt(env, stmt->body) < 0) ? 1 : -1)
-describe_ret_nspc(switch, Stmt_Switch,, scan1_exp(env, stmt->val))
+describe_ret_nspc(switch, Stmt_Switch,, !(scan1_exp(env, stmt->val) < 0 ||
+ scan1_stmt(env, stmt->stmt) < 0) ? 1 : -1)
describe_ret_nspc(if, Stmt_If,, !(scan1_exp(env, stmt->cond) < 0 ||
scan1_stmt(env, stmt->if_body) < 0 ||
(stmt->else_body && scan1_stmt(env, stmt->else_body) < 0)) ? 1 : -1)
}
ANN m_bool scan1_stmt_enum(const Env env, const Stmt_Enum stmt) { GWDEBUG_EXE
+ if(!stmt->t)
+ CHECK_BB(scan0_stmt_enum(env, stmt))
ID_List list = stmt->list;
do {
CHECK_BB(already_defined(env, list->xid, stmt_self(stmt)->pos))
if(var->xid)
CHECK_BB(isres(env, var->xid, var->pos))
if(list->td)
- CHECK_OB((list->type = void_type(env, list->td, var->pos)))
+ CHECK_OB((list->type = void_type(env, list->td)))
} while((list = list->next));
return GW_OK;
}
-ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr ptr) { GWDEBUG_EXE
- CHECK_OB((ptr->base->ret_type = known_type(env, ptr->base->td)))
- return ptr->base->args ? scan1_args(env, ptr->base->args) : GW_OK;
+ANN m_bool scan1_stmt_fptr(const Env env, const Stmt_Fptr stmt) { GWDEBUG_EXE
+ if(!stmt->type)
+ CHECK_BB(scan0_stmt_fptr(env, stmt))
+ CHECK_OB((stmt->base->ret_type = known_type(env, stmt->base->td)))
+ return stmt->base->args ? scan1_args(env, stmt->base->args) : GW_OK;
}
ANN static inline m_bool scan1_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG_EXE
+ if(!stmt->type)
+ CHECK_BB(scan0_stmt_type(env, stmt))
return stmt->type->def ? scan1_class_def(env, stmt->type->def) : 1;
}
ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE
+ if(!stmt->value)
+ CHECK_BB(scan0_stmt_union(env, stmt))
Decl_List l = stmt->l;
const m_uint scope = union_push(env, stmt);
if(stmt->xid || stmt->type_xid) {
do {
const Exp_Decl decl = l->self->d.exp_decl;
SET_FLAG(decl.td, checked | stmt->flag);
- if(GET_FLAG(stmt, static))
+ if(GET_FLAG(stmt, member))
+ SET_FLAG(decl.td, member);
+ else if(GET_FLAG(stmt, static))
SET_FLAG(decl.td, static);
CHECK_BB(scan1_exp(env, l->self))
} while((l = l->next));
}
ANN m_bool scan1_class_def(const Env env, const Class_Def class_def) { GWDEBUG_EXE
+ if(!class_def->base.type)
+ CHECK_BB(scan0_class_def(env, class_def))
if(tmpl_class_base(class_def->tmpl))
return GW_OK;
if(class_def->base.ext)
const Type type = decl->type;
if(GET_FLAG(type, template) && !GET_FLAG(type, scan2))
CHECK_BB(scan2_exp_decl_template(env, decl))
- m_uint scope;
const m_bool global = GET_FLAG(decl->td, global);
- if(global)
- scope = env_push_global(env);
+ const m_uint scope = !global ? env->scope->depth : env_push_global(env);
do {
const Var_Decl var = list->self;
const Array_Sub array = var->array;
ANN static Value arg_value(MemPool p, const Arg_List list) {
const Var_Decl var = list->var_decl;
if(!var->value) {
- const Value v = new_value(p, list->type, s_name(var->xid));
+ const Value v = new_value(p, list->type, var->xid ? s_name(var->xid) : (m_str)__func__);
if(list->td)
v->flag = list->td->flag | ae_flag_arg;
return v;
ANN m_bool scan2_stmt_fptr(const Env env, const Stmt_Fptr ptr) { GWDEBUG_EXE
const Func_Def def = new_func_def(env->gwion->p, new_func_base(env->gwion->p, ptr->base->td, ptr->base->xid, ptr->base->args),
- NULL,ptr->base->td->flag, stmt_self(ptr)->pos);
+ NULL,ptr->base->td->flag, loc_cpy(env->gwion->p, stmt_self(ptr)->pos));
def->base->ret_type = ptr->base->ret_type;
ptr->base->func = new_func(env->gwion->p, s_name(ptr->base->xid), def);
ptr->value->d.func_ref = ptr->base->func;
ANN static m_bool scan2_stmt_jump(const Env env, const Stmt_Jump stmt) { GWDEBUG_EXE
if(stmt->is_label) {
const Map m = scan2_label_map(env);
- if(map_get(m, (vtype)stmt->name)) {
- const Stmt_Jump l = (Stmt_Jump)map_get(m, (vtype)stmt->name);
- vector_release(&l->data.v);
+ if(map_get(m, (vtype)stmt->name))
ERR_B(stmt_self(stmt)->pos, "label '%s' already defined", s_name(stmt->name))
- }
map_set(m, (vtype)stmt->name, (vtype)stmt);
vector_init(&stmt->data.v);
}
ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, const Value overload) { GWDEBUG_EXE
const m_bool base = tmpl_list_base(f->tmpl);
const m_bool tmpl = GET_FLAG(overload, template);
- if(isa(overload->type, t_function) < 0)
+ if(isa(overload->type, t_function) < 0 || isa(overload->type, t_fptr) > 0)
ERR_B(f->pos, "function name '%s' is already used by another value", overload->name)
if((!tmpl && base) || (tmpl && !base && !GET_FLAG(f, template)))
ERR_B(f->pos, "must overload template function with template")
ADD_REF(v);
nspc_add_value(env->curr, f->def->base->xid, v);
} else /* if(!GET_FLAG(f->def, template)) */ {
+// f->next = overload->d.func_ref->next;
+if(overload->d.func_ref) {
f->next = overload->d.func_ref->next;
overload->d.func_ref->next = f;
+} else
+ overload->d.func_ref = f;
}
return v;
}
}
ANEW ANN static ID_List id_list_copy(MemPool p, ID_List src) {
- const ID_List list = new_id_list(p, src->xid, src->pos);
+ const ID_List list = new_id_list(p, src->xid, loc_cpy(p, src->pos));
ID_List tmp = list;
while((src = src->next))
- tmp = (tmp->next = new_id_list(p, src->xid, src->pos));
+ tmp = (tmp->next = new_id_list(p, src->xid, loc_cpy(p, src->pos)));
return list;
}
ANN static Class_Def template_class(const Env env, const Class_Def def, const Type_List call) {
const Symbol name = template_id(env, def, call);
const Type t = nspc_lookup_type1(env->curr, name);
- return t ? t->def : new_class_def(env->gwion->p, def->flag, name, def->base.ext, def->body, def->pos);
+ return t ? t->def : new_class_def(env->gwion->p, def->flag, name, def->base.ext, def->body,
+ loc_cpy(env->gwion->p, def->pos));
}
ANN m_bool template_push_types(const Env env, ID_List base, Type_List tl) {
ANN static inline void* type_unknown(const Env env, const ID_List id) {
char path[id_list_len(id)];
type_path(path, id);
- err_msg(id->pos, "unknown type '%s'", path);
+ env_err(env, id->pos, "unknown type '%s'", path);
did_you_mean_nspc(env->curr, s_name(id->xid));
return NULL;
}
ANN Driver* new_driver(MemPool p) {
Driver* di = (Driver*)mp_alloc(p, BBQ);
di->func = dummy_driver;
- di->run = vm_run;
+// di->run = vm_run;
di->driver = (DriverData*)mp_alloc(p, DriverData);
di->is_running = 1;
return di;
const m_bit exec = (m_bit)((Instr)vector_back(code->instr))->opcode;
if(exec == eFuncReturn) {
code = *(VM_Code*)(shred->mem - SZ_INT*3);
+if(!code)break;
REM_REF(code, shred->info->vm->gwion);
shred->mem -= *(m_uint*)(shred->mem - SZ_INT);
+// shred->mem -= *(m_uint*)(shred->mem - SZ_INT*4);
} else break;
}
}
ANN static void shreduler_child(const Vector v) {
for(m_uint i = vector_size(v) + 1; --i;) {
const VM_Shred child = (VM_Shred)vector_at(v, i - 1);
- unwind(child);
+// unwind(child);
shreduler_remove(child->info->vm->shreduler, child, 1);
}
}
ANN static void shreduler_erase(const Shreduler s, struct ShredTick_ *tk) {
+ unwind(tk->self);
if(tk->parent)
shreduler_parent(tk->self, &tk->parent->child);
if(tk->child.ptr)
tk->prev = tk->next = NULL;
if(erase) {
shreduler_erase(s, tk);
- _release(out->info->me, out);
+ /*shred_*/release(out->info->me, out);
}
MUTEX_UNLOCK(s->mutex);
}
return ret;
}
-VM* new_vm(MemPool p) {
- VM* vm = (VM*)mp_alloc(p, VM);
- vector_init(&vm->ugen);
- vm->bbq = new_driver(p);
- vm->shreduler = (Shreduler)mp_alloc(p, Shreduler);
- vector_init(&vm->shreduler->shreds);
- MUTEX_SETUP(vm->shreduler->mutex);
- vm->shreduler->bbq = vm->bbq;
- gw_seed(vm->rand, (uint64_t)time(NULL));
- return vm;
-}
-
void vm_remove(const VM* vm, const m_uint index) {
const Vector v = (Vector)&vm->shreduler->shreds;
LOOP_OPTIM
vector_release(&vm->ugen);
if(vm->bbq)
free_driver(vm->bbq, vm);
- mp_free(vm->gwion->p, Shreduler, vm->shreduler);
MUTEX_CLEANUP(vm->shreduler->mutex);
+ mp_free(vm->gwion->p, Shreduler, vm->shreduler);
mp_free(vm->gwion->p, VM, vm);
}
DISPATCH();
#define INT_OP(op, ...) OP(m_int, SZ_INT, op, __VA_ARGS__)
-#define FLOAT_OP(op) OP(m_float, SZ_FLOAT, op)
+#define FLOAT_OP(op, ...) OP(m_float, SZ_FLOAT, op, __VA_ARGS__)
#define LOGICAL(t, sz0, sz, op)\
reg -= sz0;\
(m_int)(*(m_float*)(reg-SZ_INT))); \
DISPATCH()
+
+#define STRINGIFY_NX(a) #a
+#define STRINGIFY(a) STRINGIFY_NX(a)
+#define PPCAT_NX(A, B) A ## B
+#define PPCAT(A, B) PPCAT_NX(A, B)
+
+#if defined(__clang__)
+#define COMPILER clang
+#define UNINITIALIZED "-Wuninitialized")
+#elif defined(__GNUC__) || defined(__GNUG__)
+#define COMPILER GCC
+#define UNINITIALIZED "-Wmaybe-uninitialized")
+#endif
+
+#define PRAGMA_PUSH() \
+_Pragma(STRINGIFY(COMPILER diagnostic push)) \
+_Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED)
+#define PRAGMA_POP() _Pragma(STRINGIFY(COMPILER diagnostic pop)) \
+
__attribute__ ((optimize("-O2")))
ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto]
-static const void* dispatch[] = {
+ static const void* dispatch[] = {
&®setimm,
&®pushimm, &®pushfloat, &®pushother, &®pushaddr,
&®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr,
register m_bit next;
while((shred = shreduler_get(s))) {
register VM_Code code = shred->code;
+//if(!code->instr)
+// exit(2);
register m_uint* ip = code->instr->ptr + OFFSET;
register
size_t pc = shred->pc;
intradd: INT_R(+)
intrsub: INT_R(-)
intrmul: INT_R(*)
-intrdiv: INT_R(/, TEST0(m_int, -SZ_INT))
-intrmod: INT_R(%, TEST0(m_int, -SZ_INT))
+//intrdiv: INT_R(/, TEST0(m_int, -SZ_INT))
+//intrmod: INT_R(%, TEST0(m_int, -SZ_INT))
+intrdiv: INT_R(/, TEST0(m_int, SZ_INT))
+intrmod: INT_R(%, TEST0(m_int, SZ_INT))
intrsl: INT_R(<<)
intrsr: INT_R(>>)
intrsand: INT_R(&)
firadd: FI_R(+)
firsub: FI_R(-)
firmul: FI_R(*)
-firdiv: FI_R(/, TEST0(m_int, -SZ_INT))
+firdiv: FI_R(/, TEST0(m_float, SZ_INT))
itof:
reg -= SZ_INT - SZ_FLOAT;
setcode:
a.code = *(VM_Code*)(reg-SZ_INT);
funcptr:
+PRAGMA_PUSH()
if(!GET_FLAG((VM_Code)a.code, builtin))
goto funcusr;
+PRAGMA_POP()
funcmember:
reg -= SZ_INT;
a.code = *(VM_Code*)reg;
if(overflow_(mem, shred))
Except(shred, "StackOverflow");
next:
+PRAGMA_PUSH()
goto *dispatch[next];
+PRAGMA_POP()
funcusrend:
ip = (code = a.code)->instr->ptr + OFFSET;
pc = 0;
*(m_uint*)(a.child->mem + i) = *(m_uint*)(mem+i);
DISPATCH()
forkend:
- fork_launch(a.child->info->me, instr->m_val2);
+ fork_launch(vm, a.child->info->me, instr->m_val2);
sporkend:
*(M_Object*)(reg-SZ_INT) = a.child->info->me;
DISPATCH()
DISPATCH()
staticother:
// LOOP_OPTIM
- for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT)
- *(m_uint*)(reg+i) = *(m_uint*)((m_bit*)instr->m_val + i);
+// for(m_uint i = 0; i <= instr->m_val2; i += SZ_INT)
+// *(m_uint*)(reg+i) = *(m_uint*)((m_bit*)instr->m_val + i);
+ memcpy(reg, (m_bit*)instr->m_val, instr->m_val2);
reg += instr->m_val2;
DISPATCH()
dotfunc:
assert(a.obj);
reg += SZ_INT;
dotstaticfunc:
+PRAGMA_PUSH()
*(VM_Code*)(reg-SZ_INT) = ((Func)vector_at(a.obj->vtable, instr->m_val))->code;
+PRAGMA_POP()
DISPATCH()
staticcode:
instr->m_val = (m_uint)(a.code = (*(VM_Code*)reg = ((Func)instr->m_val)->code));
} while(s->curr);
MUTEX_UNLOCK(s->mutex);
}
- if(!vm->bbq->is_running)
- return;
- if(vector_size(&vm->ugen))
- vm_ugen_init(vm);
-}
\ No newline at end of file
+}
+
+static void vm_run_audio(const VM *vm) {
+ vm_run(vm);
+ vm_ugen_init(vm);
+}
+
+VM* new_vm(MemPool p, const m_bool audio) {
+ VM* vm = (VM*)mp_alloc(p, VM);
+ vector_init(&vm->ugen);
+ vm->bbq = new_driver(p);
+ vm->bbq->run = audio ? vm_run_audio : vm_run;
+ vm->shreduler = (Shreduler)mp_alloc(p, Shreduler);
+ vector_init(&vm->shreduler->shreds);
+ MUTEX_SETUP(vm->shreduler->mutex);
+ vm->shreduler->bbq = vm->bbq;
+ gw_seed(vm->rand, (uint64_t)time(NULL));
+ return vm;
+}
#include "gwion.h"
#include "import.h"
-ANN static void free_code_instr(const Vector v, const Gwion gwion) {
+ANN /*static*/ void free_code_instr(const Vector v, const Gwion gwion) {
for(m_uint i = vector_size(v) + 1; --i;) {
const Instr instr = (Instr)vector_at(v, i - 1);
const f_freearg f = (f_freearg)(map_get(&gwion->freearg, instr->opcode) ?:
f(instr, gwion);
mp_free(gwion->p, Instr, instr);
}
- free_vector(gwion->p, v);
+// free_vector(gwion->p, v);
}
+ANN static void _free_code_instr(const Vector v, const Gwion gwion) {
+ free_code_instr(v, gwion);
+ free_vector(gwion->p, v);
+}
ANN static void free_vm_code(VM_Code a, Gwion gwion) {
if(a->memoize)
memoize_end(gwion->p, a->memoize);
if(!GET_FLAG(a, builtin))
- free_code_instr(a->instr, gwion);
+ _free_code_instr(a->instr, gwion);
xfree(a->name);
mp_free(gwion->p , VM_Code, a);
}
SRC = ${NAME}.c
OBJ = $(SRC:.c=.o)
-CFLAGS = -std=c99 $(../../gwion -k 2>&1 | grep CFLAGS) ${INC} ${CICFLAGS}
+CFLAGS = -std=c99 $(../../gwion -k 2>&1 | grep CFLAGS | sed 's/CFLAGS: //') ${INC} ${CICFLAGS} -Wall -Wextra
LDFLAGS = $(../../gwion -k 2>&1 | grep LDFLAGS)
# os specific
GWION_IMPORT(array_test) {
Type t_invalid_var_name;
- CHECK_BB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object)))
+ CHECK_OB((t_invalid_var_name = gwi_mk_type(gwi, "invalid_var_name", SZ_INT, t_object)))
CHECK_BB(gwi_class_ini(gwi, t_invalid_var_name, NULL, NULL))
CHECK_BB(gwi_item_ini(gwi,"int[]", "int_array"))
CHECK_BB(gwi_item_end(gwi, 0, NULL)) // import array var
/**(M_Object*)(o->data + SZ_INT) = new_array(t2->size, 0, t2->array_depth);*/
}
-static MFUN(class_template_set) {
-
-}
-
GWION_IMPORT(class_template) {
Type t_class_template;
const m_str list[2] = { "A", "B" };
CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM7", 7))
CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM8", 8))
CHECK_BB(gwi_enum_add(gwi, "TYPED_ENUM9", 9))
- CHECK_BB(gwi_enum_end(gwi))
+ CHECK_OB(gwi_enum_end(gwi))
CHECK_OB(gwi_class_end(gwi))
return GW_OK;
Type t_array_ext;
CHECK_OB((t_array_ext = gwi_mk_type(gwi, "ArrayExt", SZ_INT, NULL)))
CHECK_BB(gwi_class_ini(gwi, t_array_ext, NULL, NULL))
- Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "float"), 0), 0);
- Exp e = new_exp_prim_int(gwi->gwion->st->p, 1, 0);
+ Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "float"), GWI_LOC), 0);
+ Exp e = new_exp_prim_int(gwi->gwion->st->p, 1, GWI_LOC);
Array_Sub array = new_array_sub(gwi->gwion->st->p, e);
add_type_decl_array(td, array);
CHECK_BB(gwi_class_ext(gwi, td))
Type t_ev ;
CHECK_OB((t_ev = gwi_mk_type(gwi, "Ev", SZ_INT , NULL)))
CHECK_BB(gwi_class_ini(gwi, t_ev, ev_ctor, NULL))
- Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Event"), 0), 0);
+ Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Event"), GWI_LOC), 0);
CHECK_BB(gwi_class_ext(gwi, td))
CHECK_BB(gwi_class_end(gwi))
return GW_OK;
CHECK_BB(gwi_tmpl_ini(gwi, 2, types))
CHECK_BB(gwi_class_ini(gwi, t_pair_ext, NULL, NULL))
CHECK_BB(gwi_tmpl_end(gwi))
- Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Pair"), 0), 0);
- Type_Decl* td0 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "A"), 0), 0);
- Type_Decl* td1 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "B"), 0), 0);
+ Type_Decl* td = new_type_decl(gwi->gwion->st->p, new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "Pair"), GWI_LOC), 0);
+ Type_Decl* td0 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "A"), GWI_LOC), 0);
+ Type_Decl* td1 = new_type_decl(gwi->gwion->st->p ,new_id_list(gwi->gwion->st->p, insert_symbol(gwi->gwion->st, "B"), GWI_LOC), 0);
Type_List tl1 = new_type_list(gwi->gwion->st->p, td1, NULL);
Type_List tl0 = new_type_list(gwi->gwion->st->p,td0, tl1);
td->types = tl0;
#include "instr.h"
#include "import.h"
-static MFUN(test_mfun){}
GWION_IMPORT(invalid_type1_test) {
Type t_invalid_var_type;
CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type",
#include "instr.h"
#include "import.h"
-static MFUN(test_mfun){}
GWION_IMPORT(invalid_type2_test) {
Type t_invalid_var_type ;
CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, "invalid_var_type",
#include "instr.h"
#include "import.h"
-static MFUN(test_mfun){}
GWION_IMPORT(invalid_type3_test) {
Type t_invalid_var_type ;
CHECK_OB((t_invalid_var_type = gwi_mk_type(gwi, ".invalid_var_type",
#include "object.h"
#include "instr.h"
#include "import.h"
-
-
-static MFUN(test_mfun){}
-Subproject commit c09b4ef1af52812816a0cb2fde12e0d81ccc3b06
+Subproject commit d225ae77804624fbfd1d904a1dd028e392139f62