summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-13 19:45:22 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-13 19:45:22 +0000
commit50d6dd8b50958271bf1ff13f99dc21d4cd8431f7 (patch)
tree504f2a16f29fefedc7ff0a326475f122d018590a /eval.c
parentb1b55e907a5aaf177344769d2b303351ba936bff (diff)
Implement basic reference counting for arrays, which so they
get freed when not in use anymore.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/eval.c b/eval.c
index ae7dbd7..2eb5abd 100644
--- a/eval.c
+++ b/eval.c
@@ -104,7 +104,13 @@ retry:
errormsg = L"No reduce rule. Syntax error.";
return nil;
}else{
- stmt->toks[offset] = fn(stmt->toks[offset],stmt->toks[offset+1]);
+ Datum new = fn(stmt->toks[offset],stmt->toks[offset+1]);
+ if(stmt->toks[offset].tag == ArrayTag)
+ freearray(stmt->toks[offset].array);
+ if(stmt->toks[offset+1].tag == ArrayTag)
+ freearray(stmt->toks[offset+1].array);
+
+ stmt->toks[offset] = new;
for(int i = offset+1; i < stmt->ntoks-1; i++)
stmt->toks[i] = stmt->toks[i+1];
stmt->ntoks--;
@@ -126,8 +132,13 @@ lookup(Datum var)
if(var.symbol->undefined){
errormsg = runesmprint("Variable undefined: %S\n", var.symbol->name);
return nil;
- }else
- return &var.symbol->value;
+ }else{
+ Datum *val = &var.symbol->value;
+ val->shy = 0;
+ if(val->tag == ArrayTag)
+ incref(val->array); /* since the value is now in the var AND in the code */
+ return val;
+ }
}
Datum
@@ -136,11 +147,13 @@ strand(Datum left, Datum right)
traceprint("Stranding (%d %d)\n", left.array->stranded, right.array->stranded);
Datum result;
result.shy = 0;
- Array *leftarr = left.array->stranded ? left.array : fnEnclose(left.array);
- Array *rightarr = right.array->stranded ? right.array : fnEnclose(right.array);
+ Array *leftarr = left.array->stranded ? fnSame(left.array) : fnEnclose(left.array);
+ Array *rightarr = right.array->stranded ? fnSame(right.array) : fnEnclose(right.array);
result.tag = ArrayTag;
result.array = fnCatenateFirst(leftarr, rightarr);
result.array->stranded = 1;
+ freearray(leftarr);
+ freearray(rightarr);
return result;
}
@@ -159,14 +172,17 @@ monadfun(Datum left, Datum right)
Symbol *alpha = getsym(currentsymtab, L"⍺");
alpha->value.tag = ArrayTag;
alpha->value.array = left.func.left;
+ /* no need to increment refs, since it was done on binding the arg */
alpha->undefined = 0;
}
Symbol *omega = getsym(currentsymtab, L"⍵");
omega->value = right;
omega->undefined = 0;
+ incref(right.array);
Datum *dfnres = evalline(left.func.dfn);
+ freesymtab(currentsymtab);
currentsymtab = tmpsymtab;
return *dfnres; /* TODO what if the evaluation failed */
}else{
@@ -176,6 +192,10 @@ monadfun(Datum left, Datum right)
else
result.array = monadfunctiondefs[left.func.code](right.array);
}
+
+ if(left.func.left)
+ freearray(left.func.left);
+
return result;
}
@@ -188,6 +208,7 @@ dyadfun(Datum left, Datum right)
result.tag = BoundFunctionTag,
result.func = right.func;
result.func.left = left.array;
+ incref(left.array);
return result;
}
@@ -219,8 +240,11 @@ assign(Datum left, Datum right)
{
left.symbol->value = right; /* TODO think about this*/
left.symbol->undefined = 0;
- if(left.symbol->value.tag == ArrayTag)
+ if(left.symbol->value.tag == ArrayTag){
left.symbol->value.array->stranded = 0;
+ incref(right.array); /* for the binding */
+ incref(right.array); /* for the returned array */
+ }
right.shy = 1;
return right;
} \ No newline at end of file