Update the VM to handle data sections and the print_str import.
When the VM sees (data (i32.const ADDR) "..."), it copies the string bytes into vm_memory at the given address.
When the VM hits call $print_str, it pops addr and len, reads bytes from vm_memory, and prints them.
fn vm_load_data() void {
for (0..vm_line_count) |i| {
const line: []const u8 = vm_trim(vm_lines[i]);
if (starts_with(line, "(data (i32.const ")) {
const addr_start: usize = 17; // after "(data (i32.const "
const addr: usize = @as(usize, @intCast(parse_int(line, addr_start)));
// find the string content between quotes
var q1: usize = 0;
while (q1 < line.len and line[q1] != '"') { q1 += 1; }
q1 += 1; // skip first quote
var q2: usize = q1;
while (q2 < line.len and line[q2] != '"') {
if (line[q2] == '\\' and q2 + 2 < line.len) {
// hex escape
const hi: u8 = hex_val(line[q2 + 1]);
const lo: u8 = hex_val(line[q2 + 2]);
vm_memory[addr + (q2 - q1)] = hi * 16 + lo;
q2 += 3;
} else {
vm_memory[addr + (q2 - q1)] = line[q2];
q2 += 1;
}
}
}
}
}
fn hex_val(c: u8) u8 {
if (c >= '0' and c <= '9') { return c - '0'; }
if (c >= 'a' and c <= 'f') { return c - 'a' + 10; }
return 0;
}
Call vm_load_data() from vm_run_wat() after vm_scan_functions().