139 lines
3.6 KiB
C
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;
|
|
}
|