From 7f47491491e6d4e64069e2b2cc2e5e2b7297efe8 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Mon, 13 Apr 2026 18:27:42 +1000 Subject: [PATCH] Duplicator support --- src/interpreter.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/interpreter.c b/src/interpreter.c index 9d6a5e2..f52c65d 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -769,6 +769,33 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop if (in->args.args[i].type == VALREF) { GroundVariable* variable = findVariable(*scope->variables, in->args.args[i].value.refName); if (variable) { + // If there is a duplicator, call it (except when returning and getting fields) + if (variable->value.type == CUSTOM && in->type != RETURN && in->type != GETFIELD) { + GroundObject* obj = variable->value.data.customVal; + GroundObjectField* duplicator = findField(*obj, "duplicator"); + if (duplicator != NULL) { + if (duplicator->value.type != FUNCTION) { + runtimeError(ARG_TYPE_MISMATCH, "duplicator is not a function", in, currentInstruction); + } + GroundInstruction gi = createGroundInstruction(CALLMETHOD); + addArgToInstruction(&gi, createRefGroundArg(DIRREF, in->args.args[i].value.refName)); + addArgToInstruction(&gi, createRefGroundArg(FNREF, "duplicator")); + addArgToInstruction(&gi, createValueGroundArg(variable->value)); + addArgToInstruction(&gi, createRefGroundArg(DIRREF, "__ground_tmp_duplicate")); + GroundValue gv = interpretGroundInstruction(gi, scope); + if (gv.type == ERROR) { + return gv; + } + GroundVariable* tmp = findVariable(*scope->variables, "__ground_tmp_duplicate"); + if (tmp == NULL) { + runtimeError(FIXME, "Couldn't find temporary variable (this should never happen)", in, currentInstruction); + } + in->args.args[i].value.value = copyGroundValue(&tmp->value); + in->args.args[i].type = VALUE; + deleteVariable(scope->variables, tmp); + continue; + } + } free(in->args.args[i].value.refName); // Free the strdup'd refName in->args.args[i].value.value = copyGroundValue(&variable->value); in->args.args[i].type = VALUE;