#include #include #include #include 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), "", val.as.u); strcpy(build_result + gi, temp); gi += strlen(temp); break; case FZL_TYPE_OBJECT: snprintf(temp, sizeof(temp), "", val.as.obj); strcpy(build_result + gi, temp); gi += strlen(temp); break; case FZL_TYPE_NULL: snprintf(build_result + gi, sizeof(build_result) - gi, ""); 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; }