From: Elijah Cohen Date: Thu, 18 Sep 2025 23:37:47 +0000 (-0500) Subject: reference counting X-Git-Url: https://git.eli173.com/?a=commitdiff_plain;h=a547ba4d0ac1d279bd5f4d82aa7ce2288a362dd7;p=klapaucius reference counting --- diff --git a/klsrc/combinators.kl b/klsrc/combinators.kl index 431ef57..0bee665 100644 --- a/klsrc/combinators.kl +++ b/klsrc/combinators.kl @@ -27,3 +27,5 @@ (def C3 (C* (B C2))) (def Cn (Z (B (S (C (eq 0) C)) (B (B (B C)) (B D (C B (C - 1))))))) + +(def C?n (Z (B (S (C (eq 0) C)) (B (S (R B (B C))) (C B (C - 1)))))) \ No newline at end of file diff --git a/klsrc/util.kl b/klsrc/util.kl index 8e8a40c..6cb8483 100644 --- a/klsrc/util.kl +++ b/klsrc/util.kl @@ -1,4 +1,6 @@ +(def printthen (D (D evalarg (K I) print))) + (def range (abstract-rec (eq 0) (C cons) (C - 1) nil)) (def x-times-n (C (C (D abstract-rec (eq 0) (D B K cons)) (C - 1)) nil)) diff --git a/src/eval.c b/src/eval.c index d07236d..f48e179 100644 --- a/src/eval.c +++ b/src/eval.c @@ -65,10 +65,12 @@ Sexpr* apply_builtin(Sexpr* func, Sexpr* rest, Sexpr* env) { if(func->type != BUILTIN) { return dispatch_others(func, rest, env); } + // should i find a nice way to move these next few lines to its own function in sexpr.c? Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = BUILTIN; ret->value.b.opcode = func->value.b.opcode; ret->value.b.args = cons(clone(car(rest)), clone(func->value.b.args)); + ret->refcount = 1; Sexpr* cdrrest = clone(cdr(rest)); sexpr_free(rest); return dispatch(ret, cdrrest, env); diff --git a/src/sexpr.c b/src/sexpr.c index f57edc8..bac1d11 100644 --- a/src/sexpr.c +++ b/src/sexpr.c @@ -14,6 +14,7 @@ Sexpr* from_nil() { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = NIL; ret->value.n = NULL; + ret->refcount = 1; return ret; } @@ -21,6 +22,7 @@ Sexpr* from_t() { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = T; ret->value.t = NULL; + ret->refcount = 1; return ret; } @@ -29,6 +31,7 @@ Sexpr* from_sym(char* s) { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = SYM; ret->value.s = strdup(s); + ret->refcount = 1; return ret; } @@ -36,6 +39,7 @@ Sexpr* from_string(char* s) { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = STR; ret->value.str = strdup(s); + ret->refcount = 1; return ret; } @@ -43,6 +47,7 @@ Sexpr* from_uint(K_UINT_TYPE u) { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = UINT; ret->value.u = u; + ret->refcount = 1; return ret; } @@ -51,6 +56,7 @@ Sexpr* from_opcode(uint64_t u) { ret->type = BUILTIN; ret->value.b.opcode = u; ret->value.b.args = from_nil(); + ret->refcount = 1; return ret; } @@ -58,6 +64,7 @@ Sexpr* from_quote(Sexpr* s) { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = QUOTE; ret->value.q = s; + ret->refcount = 1; return ret; } @@ -65,6 +72,7 @@ Sexpr* from_pointer(void* p) { Sexpr* ret = malloc(sizeof(Sexpr)); ret->type = PTR; ret->value.p = p; + ret->refcount = 1; return ret; } @@ -75,6 +83,7 @@ Sexpr* cons(Sexpr* car, Sexpr* cdr) { c->cdr = cdr; s->type = CONS; s->value.c = c; + s->refcount = 1; return s; } @@ -129,6 +138,10 @@ Sexpr* equal(Sexpr* a, Sexpr* b) { } void sexpr_free(Sexpr* s) { + if(s->refcount > 1) { + s->refcount--; + return; + } if(s->type == CONS) { sexpr_free(car(s)); sexpr_free(cdr(s)); @@ -150,6 +163,9 @@ void sexpr_free(Sexpr* s) { } Sexpr* clone(Sexpr* s) { + s->refcount++; + return s; + /* Sexpr* ret; switch(s->type) { case UINT: @@ -184,6 +200,7 @@ Sexpr* clone(Sexpr* s) { break; } return ret; + */ } diff --git a/src/types.h b/src/types.h index eaff3ab..583aa07 100644 --- a/src/types.h +++ b/src/types.h @@ -32,6 +32,7 @@ typedef struct Builtin { typedef struct Sexpr { Sexpr_Type type; + size_t refcount; union { K_UINT_TYPE u; char* str;