Files
fz-lang/src/vm/handlers/group_str.c
T
2026-10-29 17:46:20 +03:00

139 lines
3.6 KiB
C

#include <stdio.h>
#include <string.h>
#include <vm/fzl_vm.h>
#include <vm/internals/opcode.h>
char build_result[512];
// Build string from specified count using stack values
int op_build_str(fzl_vm_t *vm)
{
uint64_t n = vm->ops[++vm->ip];
if (vm->dtop < n)
{
snprintf(last_err, sizeof(last_err),
"runtime error - expected %zu value(s) in dstack", n);
print_err_data(vm);
return -1;
}
char temp[64];
size_t gi = 0;
memset(build_result, 0, sizeof(build_result));
for (size_t i = 0; i < n; i++)
{
if (gi >= 512)
{
for (size_t i = 511; i > 508; i--)
build_result[i] = '.';
break;
}
memset(temp, 0, sizeof(temp));
fzl_value_t val = vm->dstack[vm->dtop - n + i];
switch (val.type)
{
case FZL_TYPE_UINT:
snprintf(temp, sizeof(temp), "%zu", val.as.u);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_UINT64:
snprintf(temp, sizeof(temp), "%lu", val.as.u64);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_UINT32:
snprintf(temp, sizeof(temp), "%u", val.as.u32);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_UINT16:
snprintf(temp, sizeof(temp), "%u", val.as.u16);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_UINT8:
snprintf(temp, sizeof(temp), "%u", val.as.u8);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_INT:
snprintf(temp, sizeof(temp), "%zd", val.as.i);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_INT64:
snprintf(temp, sizeof(temp), "%ld", val.as.i64);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_INT32:
snprintf(temp, sizeof(temp), "%d", val.as.i32);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_INT16:
snprintf(temp, sizeof(temp), "%d", val.as.i16);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_INT8:
snprintf(temp, sizeof(temp), "%d", val.as.i8);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_BOOL:
snprintf(build_result + gi, sizeof(build_result) - gi, "%s",
val.as.b ? "true" : "false");
gi += val.as.b ? 4 : 5;
break;
case FZL_TYPE_CHAR:
snprintf(build_result + gi, sizeof(build_result) - gi, "%d", val.as.c);
gi += 1;
break;
case FZL_TYPE_STRING:
snprintf(build_result + gi, sizeof(build_result) - gi, "%s",
val.as.s.value);
gi += val.as.s.length;
break;
case FZL_TYPE_EXTERN_FN:
snprintf(temp, sizeof(temp), "<extern:%zu>", val.as.u);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_OBJECT:
snprintf(temp, sizeof(temp), "<ref:%p>", val.as.obj);
strcpy(build_result + gi, temp);
gi += strlen(temp);
break;
case FZL_TYPE_NULL:
snprintf(build_result + gi, sizeof(build_result) - gi, "<null>");
gi += 6;
break;
}
}
vm->dtop -= n;
vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_STRING,
.as.s.length = strlen(build_result),
.as.s.value = build_result};
return 0;
}