emit_src := $(wildcard src/emit/*.c)
opt_src := $(wildcard opt/*.c)
+test_dir := $(filter-out tests/benchmark, $(wildcard tests/*))
+
# add boolean
ifeq (${DEBUG_STACK}, 1)
CFLAGS += -DDEBUG_STACK
rm ${PREFIX}/${PRG}
test:
- @bash help/test.sh tests/* examples
+ @bash help/test.sh ${test_dir}
include $(wildcard .d/*.d)
include util/intl.mk
Code* code;
struct Gwion_ *gwion;
struct Vector_ stack;
+ struct Vector_ pure;
struct Vector_ variadic;
char *escape;
m_bool memoize;
};
-ANEW ANN Emitter new_emitter(void/*const Env*/);
-ANN void free_emitter(Emitter);
+ANEW ANN Emitter new_emitter(MemPool);
+ANN void free_emitter(MemPool, Emitter);
ANEW ANN VM_Code emit_code(const Emitter);
ANN VM_Code emit_ast(const Emitter emit, Ast ast);
ANN m_bool emit_exp_call1(const Emitter, const Func);
#ifndef __ESCAPE
#define __ESCAPE
-char* escape_table(void);
+char* escape_table(MemPool);
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
eRegPop,
eRegPush,
eReg2Mem,
+ eReg2Mem4,
eOverflow,
eNext,
eFuncUsrEnd,
#define RegPop (f_instr)eRegPop
#define RegPush (f_instr)eRegPush
#define Reg2Mem (f_instr)eReg2Mem
+#define Reg2Mem4 (f_instr)eReg2Mem4
#define Overflow (f_instr)eOverflow
#define Next (f_instr)eNext
#define FuncUsrEnd (f_instr)eFuncUsrEnd
RegPop
RegPush
Reg2Mem
+Reg2Mem4
Overflow
Next
FuncUsrEnd
Instr instr = emit_add_instr(emit, ObjectRelease);
instr->m_val = (m_uint)offset;
}
+ vector_pop(&emit->pure);
}
ANN static inline void emit_push_code(const Emitter emit, const m_str name) {
ANN static inline void emit_push_scope(const Emitter emit) {
frame_push(emit->code->frame);
+ vector_add(&emit->pure, 0);
}
ANN static inline m_uint emit_code_size(const Emitter emit) {
return GW_OK;
}
+ANN static inline void emit_notpure(const Emitter emit) {
+ ++VPTR(&emit->pure, VLEN(&emit->pure));
+}
+
ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type,
const Array_Sub arr, const uint is_ref) {
Array_Sub array = arr;
instr->m_val2 = (m_uint)type;
emit_pre_ctor(emit, type);
}
+ emit_notpure(emit);
return GW_OK;
}
instr->m_val = (m_uint)type;
instr->m_val2 = type->array_depth == 1 ? array_base(type)->size : SZ_INT;
emit_add_instr(emit, GcAdd);
+ emit_notpure(emit);
return GW_OK;
}
return instr;
}
+ANN static void emit_args(const Emitter emit, const Func f) {
+ const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+ if((f->def->stack_depth - member) == SZ_INT) {
+ const Instr instr = emit_add_instr(emit, Reg2Mem);
+ instr->m_val = member;
+ } else {
+ const Instr instr = emit_add_instr(emit, Reg2Mem4);
+ instr->m_val = member;
+ instr->m_val2 = f->def->stack_depth - member;
+ }
+}
+
ANN static Instr emit_call(const Emitter emit, const Func f) {
const Instr memoize = !(emit->memoize && GET_FLAG(f, pure)) ? NULL : emit_add_instr(emit, MemoizeCall);
- f_instr exec;
const Instr prelude = get_prelude(emit, f);
- if(f->def->stack_depth) {
- const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
- prelude->m_val = f->def->stack_depth;
- if(member) {
- const Instr instr = emit_add_instr(emit, Reg2Mem);
- instr->m_val2 = f->def->stack_depth - SZ_INT;
- ++prelude->m_val2;
- }
- for(m_uint i = 0; i < f->def->stack_depth - member; i += SZ_INT) {
- const Instr instr = emit_add_instr(emit, Reg2Mem);
- instr->m_val = (instr->m_val2 = i) + member;
- ++prelude->m_val2;
- }
+ prelude->m_val = f->def->stack_depth;
+ const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
+ if(member) {
+ const Instr instr = emit_add_instr(emit, Reg2Mem);
+ instr->m_val2 = f->def->stack_depth - SZ_INT;
+ ++prelude->m_val2;
+ }
+ if(f->def->stack_depth - member) {
+ emit_args(emit, f);
+ ++prelude->m_val2;
}
- exec = Overflow;
if(memoize)
memoize->m_val = prelude->m_val2 + 1;
- return emit_add_instr(emit, exec);
+ return emit_add_instr(emit, Overflow);
}
ANN m_bool emit_exp_call1(const Emitter emit, const Func f) {
static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
++emit->env->scope->depth;
emit_push_scope(emit);
- const m_bool pure = SAFE_FLAG(emit->env->func, pure);
+ const m_bool pure = !vector_back(&emit->pure);
if(!pure)
emit_add_instr(emit, GcIni);
CHECK_BB(emit_stmt(emit, stmt, pop))
}
ANN static m_bool optimize_taill_call(const Emitter emit, const Exp_Call* e) {
- Exp arg = e->args;
- if(arg)
+ if(e->args) {
CHECK_BB(emit_exp(emit, e->args, 0))
- regpop(emit, SZ_INT);
- for(m_uint i = 0; i < e->m_func->def->stack_depth; i += SZ_INT) {
- const Instr instr = emit_add_instr(emit, Reg2Mem);
- instr->m_val = instr->m_val2 = i;
+ regpop(emit, SZ_INT);
+ emit_args(emit, e->m_func);
}
emit_add_instr(emit, Goto);
return GW_OK;
ANN static m_uint get_decl_size(Var_Decl_List a) {
m_uint size = 0;
- do if(GET_FLAG(a->self->value, used))
+ do //if(GET_FLAG(a->self->value, used))
size += a->self->value->type->size;
while((a = a->next));
return size;
emit->env->class_def->nspc->dtor = func->code;
ADD_REF(func->code)
}
- // TODO: find why we need this
- assert(func->def->stack_depth == func->code->stack_depth);
- func->def->stack_depth = func->code->stack_depth;
}
ANN static m_bool _fdef_body(const Emitter emit, const Func_Def fdef) {
for(m_uint i = vector_size(&emit->stack) + 1; --i;)
emit_free_code(emit, (Code*)vector_at(&emit->stack, i - 1));
vector_clear(&emit->stack);
+ vector_clear(&emit->pure);
emit_free_code(emit, emit->code);
return NULL;
}
#include "emit.h"
#include "escape.h"
-ANEW Emitter new_emitter(void) {
- Emitter emit = (Emitter)xcalloc(1, sizeof(struct Emitter_));
+ANEW Emitter new_emitter(MemPool p) {
+ Emitter emit = (Emitter)mp_calloc(p, Emitter);
vector_init(&emit->stack);
+ vector_init(&emit->pure);
vector_init(&emit->variadic);
- emit->escape = escape_table();
+ emit->escape = escape_table(p);
return emit;
}
-ANN void free_emitter(Emitter a) {
+ANN void free_emitter(MemPool p, Emitter a) {
vector_release(&a->stack);
+ vector_release(&a->pure);
vector_release(&a->variadic);
- xfree(a->escape);
- xfree(a);
+ mp_free2(p, 256, a->escape);
+ mp_free(p, Emitter, a);
}
__attribute__((returns_nonnull))
#include "emit.h"
#include "escape.h"
-char* escape_table(void) {
- char *escape = (char*)calloc(256, sizeof(char));
+char* escape_table(MemPool p) {
+ char *escape = (char*)mp_calloc2(p, 256);
escape['0'] = '0';
escape['\''] = '\'';
escape['"'] = '"';
gwion->mp = mempool_ini((sizeof(VM_Shred) + SIZEOF_REG + SIZEOF_MEM) / SZ_INT);
gwion->st = new_symbol_table(gwion->mp, 65347);
gwion->vm = new_vm(gwion->mp, 1);
- gwion->emit = new_emitter();
+ gwion->emit = new_emitter(gwion->mp);
gwion->env = new_env(gwion->mp);
gwion->emit->env = gwion->env;
gwion->emit->gwion = gwion;
MUTEX_UNLOCK(gwion->vm->shreduler->mutex);
free_env(gwion->env);
free_vm_shred(gwion->vm->cleaner_shred);
- free_emitter(gwion->emit);
+ free_emitter(gwion->mp, gwion->emit);
free_vm(gwion->vm);
free_plug(gwion);
free_gwiondata(gwion->mp, gwion->data);
arg_release(&arg);
if(ini > 0)
gwion_run(&gwion);
+#ifndef NDEBUG
gwion_end(&gwion);
+#endif
THREAD_RETURN(EXIT_SUCCESS);
}
Value v;
if(!a->is_union) {
while(scope_iter(&iter, &v) > 0) {
-const Type t = (GET_FLAG(v, builtin) && v->type->array_depth) ?
- v->type : NULL;
if(isa(v->type, t_object) > 0)
nspc_release_object(a, v, gwion);
REM_REF(v, gwion);
-if(t)
- REM_REF(t, gwion);
}
}
free_scope(gwion->mp, a->info->value);
&&itof, &&ftoi,
&&timeadv,
&&setcode, &&funcptr, &&funcmember,
- &&funcusr, &®pop, &®push, &®tomem, &&overflow, &&next, &&funcusrend, &&funcmemberend,
+ &&funcusr, &®pop, &®push, &®tomem, &®tomemother, &&overflow, &&next, &&funcusrend, &&funcmemberend,
&&sporkini, &&sporkini, &&sporkfunc, &&sporkexp, &&forkend, &&sporkend,
&&brancheqint, &&branchneint, &&brancheqfloat, &&branchnefloat,
&&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid,
regtomem:
*(m_uint*)(mem+VAL) = *(m_uint*)(reg+VAL2);
DISPATCH()
+regtomemother:
+ memcpy(mem+VAL, reg, VAL2);
+ DISPATCH()
overflow:
if(overflow_(mem, shred)) {
exception(shred, "StackOverflow");
--- /dev/null
+//int count = 0;
+fun int recursive_fib(int n)
+{
+// ++count;
+ if (n < 2)
+ return n;
+ else
+ return recursive_fib(n - 2) + recursive_fib(n - 1);
+}
+<<<recursive_fib(40)>>>;
--- /dev/null
+fun int recursive_fib(int n) {
+ if (n < 2)
+ return n;
+ else
+ return recursive_fib(n - 2) + recursive_fib(n - 1);
+}
+//<<<5 => recursive_fib>>>;
+<<<40 => recursive_fib>>>;
--- /dev/null
+fib :: Int -> Int
+fib n
+ | n < 2 = n
+ | otherwise = (fib (n-2)) + (fib (n-1))
+
+main = print $ fib 40
--- /dev/null
+local function fib(n)
+ if n <= 2 then return 1 end
+ return fib(n - 1) + fib(n - 2)
+end
+
+print(fib(40))
--- /dev/null
+sub fibonacci_recurs {
+ my ($number) = @_;
+ if ($number < 2) { # base case
+ return $number;
+ }
+ return fibonacci_recurs($number-1) + fibonacci_recurs($number-2);
+}
+
+print fibonacci_recurs(40) , "\n";
--- /dev/null
+def fibonacci_recurs(n):
+ if n < 2:
+ return n;
+ else:
+ return (fibonacci_recurs(n-1) + fibonacci_recurs(n-2))
+
+print(fibonacci_recurs(40))
--- /dev/null
+def fibonacci_recurs( n )
+ if n < 2 then return n end
+ return ( fibonacci_recurs( n - 1 ) + fibonacci_recurs( n - 2 ) )
+end
+puts fibonacci_recurs(40)
--- /dev/null
+class Fib {
+ static get(n) {
+ if (n < 2) return n
+ return get(n - 1) + get(n - 2)
+ }
+}
+
+System.print(Fib.get(40))
-----------------------------------------------------------
function main ()
- local start = os.clock()
local N = 100000
local val = 1
val = ntoggle:activate():value()
end
print(val and "true" or "false")
- io.write(string.format("elapsed: %.8f\n", os.clock() - start))
end
main()