Improve printing for call

This commit is contained in:
gingerBill
2026-07-13 16:15:41 +01:00
parent 0696f46bfb
commit bfed392a0e
2 changed files with 67 additions and 39 deletions

View File

@@ -97,7 +97,7 @@ sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts := DEFAULT_WAT_OPTIONS
defer strings.write_string(sb, ")\n")
if name, ok := module_name(m); ok {
if wat_ident_ok(name) {
if ident_ok(name) {
strings.write_string(sb, " $")
strings.write_string(sb, name)
} else {
@@ -201,7 +201,7 @@ wat_write_imports :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Pars
if int(fi) < len(m.functions) {
name = m.functions[fi].name
}
wat_write_id_or_comment(sb, name, Id(fi))
write_id_or_comment(sb, name, Id(fi))
fmt.sbprintf(sb, " (type %d)", tidx)
fi += 1
case .TABLE:
@@ -240,7 +240,7 @@ wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []Reloc
strings.write_string(sb, unit)
strings.write_string(sb, "(func")
defer strings.write_string(sb, ")\n")
wat_write_id_or_comment(sb, f.name, f.id)
write_id_or_comment(sb, f.name, f.id)
fmt.sbprintf(sb, " (type %d)", f.signature)
type := &m.func_types[f.signature]
@@ -273,11 +273,13 @@ wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []Reloc
}
strings.write_byte(sb, '\n')
m := m
opts := DEFAULT_PRINT_OPTIONS
opts.indent = " "
assert(len(f.blocks) <= 1)
level := 0
for blk in f.blocks {
level := 0
for &op, i in blk.ops {
opcode := Opcode(op.opcode)
#partial switch opcode {
@@ -286,10 +288,8 @@ wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []Reloc
}
level = max(level, 0)
for _ in 0..<level {
strings.write_string(sb, " ")
}
write_operation(sb, &op, &opts)
indent_str(sb, " ", level)
write_operation(sb, &op, &opts, &m)
strings.write_string(sb, opts.separator)
#partial switch opcode {
@@ -477,14 +477,6 @@ wat_write_const_expr :: proc(sb: ^strings.Builder, m: Module, relocs: []Relocati
// }
}
wat_write_id_or_comment :: proc(sb: ^strings.Builder, name: string, index: Id) {
if name != "" && wat_ident_ok(name) {
strings.write_string(sb, " $")
strings.write_string(sb, name)
} else {
fmt.sbprintf(sb, " (;%d;)", index)
}
}
@(private)
indent_str :: proc(sb: ^strings.Builder, unit: string, level: int) {
@@ -493,26 +485,6 @@ indent_str :: proc(sb: ^strings.Builder, unit: string, level: int) {
}
}
@(require_results)
wat_ident_ok :: proc(s: string) -> bool {
if len(s) == 0 {
return false
}
#no_bounds_check for i in 0..<len(s) {
c := s[i]
switch c {
case '0'..='9', 'A'..='Z', 'a'..='z':
// okay
case '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '/',
':', '<', '=', '>', '?', '@', '\\', '^', '_', '`', '|',
'~':
// okay
case:
return false
}
}
return true
}
wat_write_quoted_string :: proc(sb: ^strings.Builder, bytes: []u8) {
@(rodata, static)

View File

@@ -3,6 +3,7 @@
package rexcode_wasm
import "core:fmt"
import "core:strings"
import "core:strconv"
@@ -40,6 +41,7 @@ import "core:strconv"
// print: disassemble `m` into the caller-owned builder `sb`. The canonical ir
// print verb; `sbprint` / `tprint` below are thin convenience sinks over it.
print :: proc(m: Module, sb: ^strings.Builder, options: ^Print_Options = nil) {
m := m
opts := DEFAULT_PRINT_OPTIONS
if options != nil { opts = options^ }
@@ -52,7 +54,7 @@ print :: proc(m: Module, sb: ^strings.Builder, options: ^Print_Options = nil) {
}
for blk in fn.blocks {
for &op in blk.ops {
write_operation(sb, &op, &opts)
write_operation(sb, &op, &opts, &m)
strings.write_string(sb, opts.separator)
}
}
@@ -66,7 +68,7 @@ sbprint :: proc(sb: ^strings.Builder, ops: []Operation, options: ^Print_Options
opts := DEFAULT_PRINT_OPTIONS
if options != nil { opts = options^ }
for &op in ops {
write_operation(sb, &op, &opts)
write_operation(sb, &op, &opts, nil)
strings.write_string(sb, opts.separator)
}
}
@@ -98,7 +100,7 @@ mnemonic_to_string :: proc(op: Opcode, uppercase := false, allocator := context.
// Per-operation writer
// =============================================================================
write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Options) {
write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Options, module: Maybe(^Module)) {
strings.write_string(sb, opts.indent)
opcode := Opcode(op.opcode)
@@ -138,6 +140,20 @@ write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Optio
}
}
case .CALL:
if m, ok := module.?; ok {
assert(len(op.operands) == 1)
o := op.operands[0]
if o.kind == .REF {
if o.imm < i64(len(m.functions)) {
name := m.functions[o.imm].name
write_name_or_id(sb, name, Id(o.imm))
break
}
}
}
fallthrough
case:
for &o in op.operands {
write_operand(sb, &o, opcode, opts)
@@ -145,6 +161,46 @@ write_operation :: proc(sb: ^strings.Builder, op: ^Operation, opts: ^Print_Optio
}
}
@(private, require_results)
ident_ok :: proc(s: string) -> bool {
if len(s) == 0 {
return false
}
#no_bounds_check for i in 0..<len(s) {
c := s[i]
switch c {
case '0'..='9', 'A'..='Z', 'a'..='z':
// okay
case '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '/',
':', '<', '=', '>', '?', '@', '\\', '^', '_', '`', '|',
'~':
// okay
case:
return false
}
}
return true
}
write_name_or_id :: proc(sb: ^strings.Builder, name: string, index: Id) {
if name != "" && ident_ok(name) {
strings.write_string(sb, " $")
strings.write_string(sb, name)
} else {
fmt.sbprintf(sb, " %d", index)
}
}
write_id_or_comment :: proc(sb: ^strings.Builder, name: string, index: Id) {
if name != "" && ident_ok(name) {
strings.write_string(sb, " $")
strings.write_string(sb, name)
} else {
fmt.sbprintf(sb, " (;%d;)", index)
}
}
// =============================================================================
// Internal writers
// =============================================================================