]> Nishi Git Mirror - gwion.git/commitdiff
big comiit :sad:
authorfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 24 Apr 2019 00:06:41 +0000 (02:06 +0200)
committerfennecdjay <astor.jeremie@wanadoo.fr>
Wed, 24 Apr 2019 00:06:41 +0000 (02:06 +0200)
59 files changed:
help/test.sh
include/env.h
include/escape.h
include/gwi.h
include/gwion.h
include/import.h
include/object.h
include/operator.h
include/optim.h
include/parse.h
include/plug.h
include/switch.h
include/traverse.h
include/type.h
include/vm.h
opt/fold.c
opt/optim.c
src/compile.c
src/emit/emit.c
src/emit/escape.c
src/gwion.c
src/lib/array.c
src/lib/engine.c
src/lib/func.c
src/lib/import.c
src/lib/instr.c
src/lib/object.c
src/lib/opfunc.c
src/lib/prim.c
src/lib/ptr.c
src/lib/shred.c
src/oo/env_utils.c
src/oo/switch.c
src/oo/type.c
src/parse/check.c
src/parse/did_you_mean.c
src/parse/func.c
src/parse/operator.c
src/parse/scan0.c
src/parse/scan1.c
src/parse/scan2.c
src/parse/template.c
src/parse/type_decl.c
src/vm/driver.c
src/vm/shreduler.c
src/vm/vm.c
src/vm/vm_code.c
tests/import/Makefile
tests/import/array.c
tests/import/class_template.c
tests/import/enum.c
tests/import/extend_array.c
tests/import/extend_event.c
tests/import/extend_pair.c
tests/import/invalid_type1.c
tests/import/invalid_type2.c
tests/import/invalid_type3.c
tests/import/no_import.c
util

index 9ef987260d6ecf449ef6846def38ea9cfb4a465d..23edf17cd1ea5af5b78a358b2538b67a47e216d6 100644 (file)
@@ -1,5 +1,6 @@
 #!/bin/bash
 
+: "${PRG:=gwion}"
 : "${VALGRIND:=valgrind}"
 : "${GWION_TEST_DIR:=/tmp}"
 : "${GWION_TEST_PREFIX:=gwt_}"
@@ -180,10 +181,10 @@ test_gw(){
   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
index 11ce53bc1793227507fcbf52f6d5870094a9fe86..50756c3bb7ef89ceb9486a9ae26c63065426b5ca 100644 (file)
@@ -11,6 +11,7 @@ struct Switch_ {
   Vector vec;
   vtype iter;
   size_t default_case_index;
+  size_t depth;
   uint ok;
 };
 
@@ -50,14 +51,14 @@ ANN Type type_decl_resolve(const Env, const Type_Decl*);
 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
index ad75d95b90f21ecce86d8d8a1de39697e07328eb..805a569a120c4480cf678800ad4d3264405c9c94 100644 (file)
@@ -1,6 +1,6 @@
 #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
index 9438c03719fd4c9ae39a13dbe3b428105232fd05..9bf83375d7b277354c88098d5e5a858435870a4a 100644 (file)
@@ -55,5 +55,6 @@ struct Gwi_ {
   DL_Oper oper;
   void* addr;
   Templater templater;
+  loc_t loc;
 };
 #endif
index 97766423408fb906d812e45bee7d4a1b4b54affe..9db27f2fcb1ef93dc3b50430acf69d1639e76232 100644 (file)
@@ -13,10 +13,12 @@ struct Gwion_ {
   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
index b976519817993d2b9685f5b92044491819ece3ba..5ef706b910a2103e8b794a0eda217262cfbba6a1 100644 (file)
@@ -23,7 +23,8 @@ typedef struct Gwi_* Gwi;
 #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);
index 1b3e326b54dd12a01d56eb192b18c8b83646de18..9d3bfbc88cf29e78e6becd096412e3afc073a8ea 100644 (file)
@@ -7,7 +7,7 @@ struct M_Object_ {
 //  Nspc nspc;//
   Vector vtable;
   struct pool* p;
-  size_t ref;
+  volatile size_t ref;
 };
 
 ANN void instantiate_object(const VM_Shred, const Type);
@@ -19,7 +19,8 @@ ANEW M_Object new_string(MemPool, const VM_Shred, const m_str);
 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);
index c34e34f7ae905ce0e29551e809e2d6f581251284..533db1af08de4708da11410269faedae5b482fc0 100644 (file)
@@ -9,7 +9,7 @@ struct Op_Import {
   opck ck;
   opem em;
   uintptr_t data;
-  uint pos;
+  loc_t pos;
   Operator op;
   m_bool mut;
 };
index 158075b9806176e2c1898ee5d645a30bd1f4b32a..f90783e4a927ce2a93f2b0990e1222467d931709 100644 (file)
@@ -2,10 +2,10 @@
 #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
index 02ac871d69b1764308af87c2b34c8a872adafd4e..fdab1b648230098e5d76f3e719bd2a2d91194158 100644 (file)
@@ -8,6 +8,8 @@
 #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;        \
index db19cbfc130318218764e20eee70e021c396a300..32cbd810729e136b9ca47d5c3f3a6ddd15a56a14 100644 (file)
@@ -23,8 +23,8 @@ ANN void free_plug(const Gwion gwion);
 #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);
index fc99ca9c8754441c1090ff79335cf8412aab74b0..b6080cb8602a075c38d44834e075130743daac90 100644 (file)
@@ -6,16 +6,17 @@ ANN void switch_expset(const Env env, const Exp);
 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
index da037c272248b7c44f2cf14bbc226ad9af5cce65..bd1f9db308eff5fc1f1222a6fa5a6183b1af2de5 100644 (file)
@@ -8,4 +8,37 @@ m_bool traverse_stmt_union(const Env, const Stmt_Union);
 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
index 83f0efd0cb650742eef73c8787190d683286ab29..a8edfa2ce4b5a6862afd7a0f7d2e3bab86ba8d95 100644 (file)
@@ -29,7 +29,7 @@ ANN m_str get_type_name(const Env, const m_str, const m_uint);
 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);
index c326c5db898831b07a127e4476b87ed3db00d61b..5b6522c2870a6a3e2ca1b32ef04c1245017905d6 100644 (file)
@@ -71,7 +71,7 @@ ANN static inline void vm_shred_exit(const VM_Shred shred) { shreduler_remove(sh
 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));
index ec60d6efacb296909277aac816da425329ce652f..937c9b3704d6dddd999831337c5ddf052801b2ad 100644 (file)
@@ -2,9 +2,13 @@
 #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;
@@ -34,21 +38,22 @@ describe_xxx_exp(float, m_float, float, fnum)
     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;
@@ -57,17 +62,17 @@ describe_fold_xxx(ff, m_float, fnum, fnum, float,)
 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;
 }
index dc54aee7c7832932eb28cec66f4af059c2462523..004af0da65fbf2f2a3fef821a13cc8ead9ff7872 100644 (file)
@@ -7,6 +7,6 @@
 #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);
 }
index b9fdeeeb3fab971bc8cb5fed52424d89e7d2093b..3f7c9d97055f931a50b4bce41c12240f3d634ec8 100644 (file)
@@ -47,7 +47,7 @@ static void compiler_clean(MemPool p, const struct Compiler* c) {
     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);
@@ -58,6 +58,16 @@ static m_bool compiler_open(struct Compiler* c) {
   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 };
index a2a48242e7e4b9817ff2c7192cdfef5c518069e1..2e32a6733539c28cfa144e0cbd937eb6e4f7a340 100644 (file)
@@ -22,6 +22,7 @@
 #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))
@@ -225,9 +226,9 @@ ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type,
   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)
@@ -272,7 +273,8 @@ static const f_instr allocmember[]  = { RegPushImm, RegPushImm2, RegPushImm3, Al
 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;
 }
@@ -286,7 +288,8 @@ ANN static inline Exp dot_this_exp(const Emitter emit, const Exp_Primary* prim,
 
 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;
@@ -513,9 +516,12 @@ ANN static m_bool emit_exp_primary(const Emitter emit, const Exp_Primary* prim)
 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;
@@ -534,11 +540,11 @@ ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const
   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,
@@ -623,16 +629,15 @@ ANN static m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) { GWDE
   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
@@ -717,7 +722,7 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
 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);
@@ -768,8 +773,7 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
 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];
@@ -780,7 +784,7 @@ static inline m_bool push_func_code(const Emitter emit, const Func f) {
     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;
@@ -909,8 +913,8 @@ static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop)
 #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);
 }
@@ -1112,6 +1116,11 @@ ANN static void emit_pop_stack(const Emitter emit, const m_uint index) {
 }
 
 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;
@@ -1204,7 +1213,7 @@ ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) { GWD
   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);
@@ -1245,27 +1254,27 @@ ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) { GWD
     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;
 }
@@ -1308,7 +1317,7 @@ ANN static m_bool emit_stmt_switch(const Emitter emit, const Stmt_Switch stmt) {
     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;
 }
@@ -1388,10 +1397,14 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { G
     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;
@@ -1427,11 +1440,19 @@ ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { G
     } 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;
@@ -1526,6 +1547,7 @@ ANN static void emit_vararg_end(const Emitter emit, const m_uint offset) { GWDEB
   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
@@ -1569,14 +1591,9 @@ ANN static m_bool emit_member_func(const Emitter emit, const Exp_Dot* member, co
     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;
   }
@@ -1594,11 +1611,13 @@ ANN static inline m_bool emit_member(const Emitter emit, const Value v, const ui
 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);
@@ -1692,8 +1711,28 @@ ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def) { G
   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;
@@ -1761,19 +1800,23 @@ ANN static m_bool emit_class_def(const Emitter emit, const Class_Def class_def)
   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
index 98f8de4ea095a276d829c80cfa6cb5ac3fb682d4..c171c14a3579d30a98fe07966dafae64bbc0e3ae 100644 (file)
@@ -24,7 +24,10 @@ char* escape_table(void) {
 }
 
 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) {
@@ -33,8 +36,10 @@ 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') {
@@ -45,8 +50,10 @@ m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) {
           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;
@@ -55,8 +62,10 @@ m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) {
         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)))
     }
index 2300232c7836a4324dffb978a63ef30cbbbd432b..a81912c299da006671effe7c3947e95d78afcb3f 100644 (file)
@@ -14,6 +14,7 @@
 #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;
@@ -45,7 +46,7 @@ ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
 #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;
@@ -59,7 +60,7 @@ ANN VM* gwion_cpy(const VM* src) {
 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;
@@ -90,6 +91,10 @@ ANN void gwion_end(const Gwion gwion) {
   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);
@@ -100,19 +105,15 @@ ANN void gwion_end(const Gwion gwion) {
   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
+}
index dc6e349ce4e3b8b3afa7f1df59755c77b7694677..e98bd44e9b86928fa1c38c2c97aa956f17005655 100644 (file)
@@ -13,6 +13,7 @@
 #include "emit.h"
 #include "import.h"
 #include "operator.h"
+#include "parse.h"
 
 struct M_Vector_ {
   m_bit* ptr;
index 6773a7085ca3b00fe698d1913ce665014a1ef277..2f1e71c16f29184bba0269e5896ba99cacecbca0 100644 (file)
@@ -16,6 +16,7 @@
 #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);
@@ -97,6 +98,7 @@ ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) {
   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) {
@@ -104,5 +106,6 @@ ANN m_bool type_engine_init(VM* vm, const Vector plug_dirs) {
     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
index 588a8f9106f4b7460cbed0aa8a688ef94299bcb8..15037e0122eaf39f3d50a4a15ca21af4fd28113b 100644 (file)
@@ -27,6 +27,8 @@ static INSTR(LambdaAssign) { GWDEBUG_EXE
 
 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;
@@ -37,7 +39,9 @@ static OP_CHECK(opck_func_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;
   }
@@ -71,7 +75,8 @@ ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner,
   }
   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) {
index 823801e8a2c2de33779a569f3dec6ed52eda74e5..45036d0606779d304fbc6a981d51b7f0eb6f4d13 100644 (file)
 #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];
@@ -76,7 +79,7 @@ ANN static void dl_func_func_arg(DL_Func* a, const restrict m_str t, const restr
 
 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;
 }
@@ -89,7 +92,8 @@ ANN static m_bool check_illegal(char* curr, const char c, const m_uint i) {
   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++) {
@@ -103,20 +107,20 @@ ANN static m_bool name_valid(Env env, const m_str a) {
     }
     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;
@@ -131,22 +135,22 @@ ANN static void path_valid_inner(const m_str curr) {
   }
 }
 
-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;
       }
     }
@@ -160,7 +164,7 @@ ANN /* static */ ID_List str2list(const Env env, const m_str path, m_uint* array
   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] == '[') {
@@ -196,7 +200,7 @@ ANN2(1,2) Type gwi_mk_type(const Gwi gwi NUSED, const m_str name, const m_uint s
 
 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;
 }
@@ -221,10 +225,10 @@ ANN2(1,2) static void import_class_ini(const Env env, const Type type,
 
 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);
@@ -237,13 +241,13 @@ ANN2(1,2) m_int gwi_class_ini(const Gwi gwi, const Type type, const f_xtor pre_c
 
 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)
@@ -270,7 +274,7 @@ ANN m_int gwi_class_ext(const Gwi gwi, Type_Decl* td) {
 
 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);
@@ -310,7 +314,7 @@ ANN m_int gwi_item_ini(const Gwi gwi, const restrict m_str type, const restrict
   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;
@@ -332,7 +336,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr
   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);
@@ -343,6 +347,7 @@ ANN2(1) m_int gwi_item_end(const Gwi gwi, const ae_flag flag, const m_uint* addr
     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);
@@ -393,7 +398,8 @@ ANN Type_Decl* str2decl(const Env env, const m_str s, m_uint *depth) {
   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;
@@ -405,7 +411,7 @@ ANN static Arg_List make_dll_arg_list(const Env env, DL_Func * dl_fun) {
     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)))
@@ -414,17 +420,18 @@ ANN static Arg_List make_dll_arg_list(const Env env, DL_Func * dl_fun) {
       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;
@@ -435,7 +442,8 @@ ANN static Func_Def make_dll_as_fun(const Env env, DL_Func * dl_fun, ae_flag fla
   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) {
@@ -445,23 +453,21 @@ ANN static Func_Def make_dll_as_fun(const Env env, DL_Func * dl_fun, ae_flag fla
     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);
   }
@@ -487,13 +493,14 @@ static Type get_type(const Env env, const m_str str) {
   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);
 }
 
@@ -523,7 +530,7 @@ ANN void gwi_oper_mut(const Gwi gwi, const m_bool mut) {
 
 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;
@@ -534,15 +541,16 @@ ANN m_int gwi_fptr_ini(const Gwi gwi, const restrict m_str type, const restrict
   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;
   }
@@ -551,19 +559,20 @@ ANN static Stmt import_fptr(const Env env, DL_Func* dl_fun, ae_flag flag) {
 }
 
 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;
@@ -575,7 +584,7 @@ ANN static Exp make_exp(const Env env, const m_str type, const m_str name) {
   }
   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);
 }
@@ -587,11 +596,11 @@ ANN2(1) m_int gwi_union_ini(const Gwi gwi, const m_str name) {
 }
 
 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);
@@ -600,8 +609,8 @@ ANN m_int gwi_union_add(const Gwi gwi, const restrict m_str type, const restrict
 
 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);
@@ -623,7 +632,7 @@ ANN2(1) m_int gwi_enum_ini(const Gwi gwi, const m_str type) {
 }
 
 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);
index ed8ed6706501f5fd9d89b5344591a9d665dc5f78..53420788d99aa4a50474bf23d82ab92238a2771c 100644 (file)
@@ -70,7 +70,7 @@ ANN static Func_Def from_base(const Env env, const struct dottmpl_ *dt, const Ty
   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;
index 8d971c50e99dd44136f8b729059129b5e394bf57..ff421025a28c758f3dc04ec035123b2daabdb4ee 100644 (file)
@@ -121,8 +121,10 @@ static OP_CHECK(at_object) {
     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;
 }
index 8d0dc2928acd9300410a4bba536afad4abd09e2f..28934e678e853bd5283ca8ef5f7806d6177bb3bf 100644 (file)
@@ -9,6 +9,7 @@
 #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";
index eb28ceeeab409ec50b1c32bbbc9d0c6089a6f862..3ce66da9511209f689ae2dac188f43508a7a6ce6 100644 (file)
@@ -12,6 +12,7 @@
 #include "emit.h"
 #include "operator.h"
 #include "driver.h"
+#include "parse.h"
 
 #define CHECK_OP(op, check, func) _CHECK_OP(op, check, int_##func)
 
@@ -233,6 +234,8 @@ static GWION_IMPORT(time) {
   _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))
index 95a4298f167c9def657686396ac39909373ab21f..2b677e9cac32936ed277e6c52c72578cde152d7b 100644 (file)
@@ -19,8 +19,10 @@ static OP_CHECK(opck_ptr_assign) {
   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;
     }
@@ -44,8 +46,10 @@ static OP_CHECK(opck_implicit_ptr) {
   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;
@@ -57,8 +61,10 @@ static INSTR(instr_ptr_deref) { GWDEBUG_EXE
   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) {
index 6fc2af16cd681b9c77cffc9f461cc4573f4061f2..a404adffc1e59614698799ea3da80b2845aca049 100644 (file)
 #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);
@@ -55,11 +57,14 @@ static MFUN(shred_yield) {
 
 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) {
@@ -117,6 +122,7 @@ static DTOR(fork_dtor) {
 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);
@@ -155,15 +161,39 @@ static ANN void* fork_run(void* data) {
   } 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);
 }
 
@@ -241,6 +271,8 @@ GWION_IMPORT(shred) {
   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"))
index 6e86a9516b219f1d416e41ddaf6e3c41be5e5650..27155e5f79da613da45960d4ecef0898ea59cbc8 100644 (file)
@@ -59,14 +59,16 @@ ANN Type find_type(const Env env, ID_List path) {
   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;
   }
@@ -75,7 +77,10 @@ ANN Type find_type(const Env env, ID_List path) {
 
 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;
 }
 
index ed5bb366b869bbce686f6a26a87b046508aa6339..169b03162d6a50712a4345dabba5e688b9f00eae 100644 (file)
@@ -11,6 +11,8 @@
 #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); }
@@ -26,8 +28,8 @@ static Switch new_switch(MemPool p) {
 }
 
 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);
@@ -46,6 +48,7 @@ ANN static Switch new_swinfo(const Env env, const Stmt_Switch stmt) {
   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;
 }
 
@@ -69,6 +72,14 @@ ANN m_bool switch_add(const Env env, const Stmt_Switch stmt) {
   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);
@@ -80,7 +91,8 @@ void switch_reset(const Env env) {
     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);
@@ -112,6 +124,7 @@ ANN m_bool switch_dup(const Env env, const m_int value, const loc_t pos) {
   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;
 }
 
@@ -153,14 +166,18 @@ ANN m_uint switch_idx(const Env env) {
   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;
 }
index dc9efe323d3b28e6dafa3686069c27b8e53af3c9..e6979bb1ac637c73d28da4915e9774ef82b1200a 100644 (file)
@@ -49,9 +49,11 @@ ANN Type find_common_anc(const restrict Type lhs, const restrict Type rhs) {
 
 #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)
index 95d39887e122050a565b502d9df61aebb4af7fc4..b2e62da88f0eacde90f814c9549c5928a9bd1d36 100644 (file)
@@ -46,7 +46,12 @@ ANN static inline void decl_##a(const Nspc nspc, const Value v) { \
   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;
@@ -80,9 +85,9 @@ ANN Type check_td(const Env env, Type_Decl *td) {
   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);
   }
@@ -91,7 +96,7 @@ ANN Type check_td(const Env env, Type_Decl *td) {
 
 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)
@@ -102,15 +107,15 @@ ANN Type check_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
   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;
@@ -330,7 +335,7 @@ ANN static Type_List mk_type_list(const Env env, const Type type) {
   }
   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);
@@ -433,7 +438,7 @@ ANN static Func _find_template_match(const Env env, const Value v, const Exp_Cal
         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);
     }
@@ -581,7 +586,8 @@ ANN static Type check_lambda_call(const Env env, const Exp_Call *exp) {
   }
   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);
@@ -858,7 +864,7 @@ stmt_func_xxx(loop, Stmt_Loop,, !(!check_exp(env, stmt->cond) ||
   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
@@ -896,6 +902,7 @@ describe_check_stmt_stack(breaks, break)
 
 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)
@@ -920,13 +927,8 @@ ANN static m_bool check_stmt_jump(const Env env, const Stmt_Jump stmt) { GWDEBUG
   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;
 }
index 5be923d82e798f287a4babb691c5cf3b0f52ec12..e936ec4b2da719554e83249db19e332fb94ad22d 100644 (file)
@@ -52,7 +52,7 @@ ANN static void ressembles(const Vector v, const Nspc nspc, const char* name) {
 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));
@@ -64,7 +64,7 @@ ANN void did_you_mean_type(Type type, const char* name) {
   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);
index 130592bcc0dfd971abbc39bab2ccf1ee9dee4396..3ad395edfe71f00e9e96f79a47935f531ed69a83 100644 (file)
@@ -12,6 +12,8 @@
 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)
index bfc20339d5faf8863e35a74af95fc1ffca13e1ec..d8ce2f3861f87f7a12f6b650f16bd549f3088bd1 100644 (file)
@@ -85,10 +85,12 @@ ANN m_bool add_op(const Gwion gwion, const Nspc nspc, const struct Op_Import* op
     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) {
@@ -170,7 +172,7 @@ ANN Type op_check(const Env env, struct Op_Import* opi) {
     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;
 }
@@ -186,8 +188,8 @@ ANN m_bool operator_set_func(const struct Op_Import* opi) {
 
 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);
index d91216bc36914ce96e006f16383696691fca08d1..1ef5fc73beb4fb627b1d9476fc825a2b9e35f9fe 100644 (file)
@@ -23,7 +23,7 @@ ANN static Value mk_class(const Env env, const Type base) {
 }
 
 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);
 }
@@ -43,7 +43,7 @@ ANN m_bool scan0_stmt_fptr(const Env env, const Stmt_Fptr stmt) { GWDEBUG_EXE
   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)
@@ -61,7 +61,8 @@ ANN static m_bool scan0_stmt_type(const Env env, const Stmt_Type stmt) { GWDEBUG
       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;
   }
@@ -107,7 +108,7 @@ ANN static Type union_type(const Env env, const Nspc nspc, const Symbol s, const
   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))
@@ -120,19 +121,33 @@ ANN static m_bool scan0_stmt_union(const Env env, const Stmt_Union stmt) { GWDEB
     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)
@@ -141,11 +156,24 @@ ANN static m_bool scan0_Stmt(const Env env, const Stmt stmt) { GWDEBUG_EXE
     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;
 }
@@ -179,11 +207,17 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def class_def) {
   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;
 }
 
index 1e0b36a54a83a8bd0a04c09fd35310c37bca0a57..d7e85abc46ac849de9dab211aa38217a39cd254c 100644 (file)
@@ -8,8 +8,7 @@
 #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);
@@ -17,16 +16,16 @@ ANN static m_bool scan1_stmt_list(const Env env, Stmt_List list);
 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;
@@ -49,27 +48,28 @@ ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
   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"
@@ -90,7 +90,7 @@ ANN m_bool scan1_exp_decl(const Env env, Exp_Decl* decl) { GWDEBUG_EXE
     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;
@@ -120,9 +120,11 @@ ANN static inline m_bool scan1_exp_cast(const Env env, const Exp_Cast* cast) { G
 
 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
@@ -167,7 +169,8 @@ describe_ret_nspc(auto, Stmt_Auto,, !(scan1_exp(env, stmt->exp) < 0 ||
     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)
@@ -188,6 +191,8 @@ ANN static inline m_bool scan1_stmt_case(const Env env, const Stmt_Exp stmt) { G
 }
 
 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))
@@ -211,21 +216,27 @@ ANN static m_bool scan1_args(const Env env, Arg_List list) { GWDEBUG_EXE
     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) {
@@ -235,7 +246,9 @@ ANN m_bool scan1_stmt_union(const Env env, const Stmt_Union stmt) { GWDEBUG_EXE
   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));
@@ -335,6 +348,8 @@ ANN static m_bool scan1_class_body(const Env env, const Class_Def class_def) {
 }
 
 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)
index ca8e30c8b27cd9ddad5f8b879f30ef5e10c78212..6de500ea63a2b3fcff0468e7af18baa34d0c208e 100644 (file)
@@ -32,10 +32,8 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
   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;
@@ -51,7 +49,7 @@ ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl* decl) { GWDEBUG_EXE
 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;
@@ -91,7 +89,7 @@ ANN static Value scan2_func_assign(const Env env, const Func_Def d,
 
 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;
@@ -265,11 +263,8 @@ ANN static Map scan2_label_map(const Env env) { GWDEBUG_EXE
 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);
   }
@@ -307,7 +302,7 @@ ANN static m_bool scan2_stmt_list(const Env env, Stmt_List list) { GWDEBUG_EXE
 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")
@@ -344,8 +339,12 @@ ANN2(1,2) static Value func_value(const Env env, const Func f,
     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;
 }
index 424fa2d21219870c40176ee1065cd1050f31c4c2..565aeed3cea6237a9840eaaf115925a2cef0392a 100644 (file)
@@ -25,10 +25,10 @@ ANEW ANN static Vector get_types(const Env env, Type t) {
 }
 
 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;
 }
 
@@ -116,7 +116,8 @@ ANN m_bool template_match(ID_List base, Type_List call) {
 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) {
index b93a72a6d63dd890f8ac80fe57c42d80ef636c97..5e2e59b754bb0b59ca4468cfba603d7a7add9d79 100644 (file)
@@ -76,7 +76,7 @@ ANEW ANN m_str tl2str(const Env env, 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;
 }
index b91a1a4eb18f06b524ab0cb0569ed2aa73fd9d81..37b095b684e2be4dc2beb1ec8770ee263f0c25c3 100644 (file)
@@ -14,7 +14,7 @@
 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;
index 896467407cd6872fedd5772050a7e06636f1d8f1..c63be5693941a3cd3ae7e33065e80a40e28a2af4 100644 (file)
@@ -45,8 +45,10 @@ ANN static void unwind(const VM_Shred shred) {
     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;
   }
 }
@@ -54,12 +56,13 @@ ANN static void unwind(const VM_Shred shred) {
 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)
@@ -82,7 +85,7 @@ ANN void shreduler_remove(const Shreduler s, const VM_Shred out, const m_bool er
   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);
 }
index b1753ef137682be14a3b9cf301076681fd64d063..8da46b8cae7f68aff34ecce31de3811802bd6f61 100644 (file)
@@ -49,18 +49,6 @@ uint32_t gw_rand(uint32_t s[2]) {
   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
@@ -76,8 +64,8 @@ ANN void free_vm(VM* vm) {
   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);
 }
 
@@ -165,7 +153,7 @@ ANN static inline VM_Shred init_fork_shred(const VM_Shred shred, const Instr ins
   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;\
@@ -235,9 +223,28 @@ __attribute__((hot))
     (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[] = {
     &&regsetimm,
     &&regpushimm, &&regpushfloat, &&regpushother, &&regpushaddr,
     &&regpushmem, &&regpushmemfloat, &&regpushmemother, &&regpushmemaddr,
@@ -291,6 +298,8 @@ static const void* dispatch[] = {
 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;
@@ -448,8 +457,10 @@ intrassign:
 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(&)
@@ -536,7 +547,7 @@ firassign:
 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;
@@ -559,8 +570,10 @@ timeadv:
 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;
@@ -592,7 +605,9 @@ overflow:
   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;
@@ -623,7 +638,7 @@ sporkexp:
     *(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()
@@ -749,15 +764,18 @@ staticfloat:
   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));
@@ -797,8 +815,22 @@ DISPATCH()
     } 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;
+}
index e59f28c48a245dce3c31f88154669458c933a193..8db52b6f3ce7f95e6113a4751de42bc1eb42ecee 100644 (file)
@@ -14,7 +14,7 @@
 #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) ?:
@@ -23,14 +23,18 @@ ANN static void free_code_instr(const Vector v, const Gwion gwion) {
       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);
 }
index 561da2f734b71b6237e8d295e9e5e5a1436d2d68..f6253570b429a2850649c78a627ec1209f81bc5f 100644 (file)
@@ -3,7 +3,7 @@ CC       ?= gcc
 
 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
index a256dda6044fa26c00d6802a9fe703628392e842..43ba2ad83c6424ede1e892f5ce8a2caf156c6df3 100644 (file)
@@ -12,7 +12,7 @@ MFUN(test_mfun){}
 
 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
index 0a6a26ded9d30a5ff20857da9c99c41808ca8462..f1ab7f5d5a515a21f5c4978c94b205906683cfff 100644 (file)
@@ -23,10 +23,6 @@ static CTOR(class_template_ctor) {
   /**(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" };
index 8618b58caadef133bad69e9093acf813bc87400e..c50129bfbc7dd556a33a7d9aba5a8148b91cf8f0 100644 (file)
@@ -62,7 +62,7 @@ GWION_IMPORT(enum_test) {
       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;
index 7e1240905758861b47e0c717fa18cc53c2fb2246..e72c24f21c01434f816c12bef8acc35db019a34e 100644 (file)
@@ -16,8 +16,8 @@ GWION_IMPORT(extend_array_test) {
   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))
index dc38469a3cf9a19eebed874e223fe272d684b4fa..2f2cb06fff8ea7a5a0dfcc0f3d667e023297f388 100644 (file)
@@ -18,7 +18,7 @@ GWION_IMPORT(extend_event_test) {
   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;
index 801841cd22e65651479b71916f8db5d7749fed80..33dfae1e72dbc91ae20bd886da96a4c4baa6783e 100644 (file)
@@ -19,9 +19,9 @@ GWION_IMPORT(extend_pair_test) {
   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;
index 99bed3f15ca9b59408bd56efcd43d81b2a036df8..b9e72bde049b4ce53acf4be941d01a65cf5e40f2 100644 (file)
@@ -8,7 +8,6 @@
 #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",
index b2242ecb1de0b6c1d192cf9aa36500582a286de5..1dc5c8e252d58b2508ae46f7ca04b3210bb5356a 100644 (file)
@@ -8,7 +8,6 @@
 #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",
index f8e8c9fb79448d9db81bf9e463a5e26b5886fd15..2a207d207aa1633f75228f79d617791bb664cd14 100644 (file)
@@ -9,7 +9,6 @@
 #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",
index 9a10bead8cde7865ec151aa7de2f4610040b1950..39ff84dced6af11b41afdf922dd0ada74f898e12 100644 (file)
@@ -7,6 +7,3 @@
 #include "object.h"
 #include "instr.h"
 #include "import.h"
-
-
-static MFUN(test_mfun){}
diff --git a/util b/util
index c09b4ef1af52812816a0cb2fde12e0d81ccc3b06..d225ae77804624fbfd1d904a1dd028e392139f62 160000 (submodule)
--- a/util
+++ b/util
@@ -1 +1 @@
-Subproject commit c09b4ef1af52812816a0cb2fde12e0d81ccc3b06
+Subproject commit d225ae77804624fbfd1d904a1dd028e392139f62