159 lines
4.5 KiB
Plaintext
159 lines
4.5 KiB
Plaintext
// ArgsExtractorBox - Extract and load arguments from MirCall JSON
|
|
// Single Responsibility: Parse args array, load values from registers
|
|
|
|
using selfhost.shared.common.string_ops as StringOps
|
|
using selfhost.shared.common.string_helpers as StringHelpers
|
|
using selfhost.vm.hakorune-vm.value_manager as ValueManagerBox
|
|
|
|
static box ArgsExtractorBox {
|
|
// Extract args array from mir_call object and load values from registers
|
|
// mir_call_json: JSON string like '{"args":[1,2,3],...}'
|
|
// regs: register MapBox
|
|
// Returns: ArrayBox containing argument values (in order)
|
|
extract_and_load(mir_call_json, regs) {
|
|
// Create result array
|
|
local args_array = new ArrayBox()
|
|
|
|
// Find "args" field
|
|
local args_key = "\"args\":["
|
|
local args_start = mir_call_json.indexOf(args_key)
|
|
if args_start < 0 {
|
|
// No args field, return empty array
|
|
return args_array
|
|
}
|
|
args_start = args_start + args_key.length()
|
|
|
|
// Find array end
|
|
local args_end = StringOps.index_of_from(mir_call_json, "]", args_start)
|
|
if args_end < 0 {
|
|
// Malformed args array, return empty
|
|
return args_array
|
|
}
|
|
|
|
// Extract args array content (between [ and ])
|
|
local args_content = mir_call_json.substring(args_start, args_end)
|
|
|
|
// If empty array, return immediately
|
|
if args_content.length() == 0 {
|
|
return args_array
|
|
}
|
|
|
|
// Parse comma-separated ValueIds
|
|
local pos = 0
|
|
local content_len = args_content.length()
|
|
|
|
loop(pos < content_len) {
|
|
// Skip whitespace
|
|
loop(pos < content_len) {
|
|
local ch = args_content.substring(pos, pos + 1)
|
|
if ch != " " && ch != "\t" && ch != "\n" && ch != "\r" {
|
|
break
|
|
}
|
|
pos = pos + 1
|
|
}
|
|
|
|
if pos >= content_len {
|
|
break
|
|
}
|
|
|
|
// Find next comma or end
|
|
local next_comma = StringOps.index_of_from(args_content, ",", pos)
|
|
local value_end = 0
|
|
if next_comma < 0 {
|
|
value_end = content_len
|
|
} else {
|
|
value_end = next_comma
|
|
}
|
|
|
|
// Extract ValueId string
|
|
local value_str = args_content.substring(pos, value_end)
|
|
|
|
// Convert to integer (ValueId)
|
|
local value_id = StringHelpers.to_i64(value_str)
|
|
|
|
// Load value from register
|
|
local arg_value = ValueManagerBox.get(regs, value_id)
|
|
|
|
// Add to result array
|
|
args_array.push(arg_value)
|
|
|
|
// Move to next argument
|
|
if next_comma < 0 {
|
|
break
|
|
}
|
|
pos = next_comma + 1
|
|
}
|
|
|
|
return args_array
|
|
}
|
|
|
|
// Get argument count without loading values
|
|
// mir_call_json: JSON string like '{"args":[1,2,3],...}'
|
|
// Returns: number of arguments
|
|
count_args(mir_call_json) {
|
|
// Find "args" field
|
|
local args_key = "\"args\":["
|
|
local args_start = mir_call_json.indexOf(args_key)
|
|
if args_start < 0 {
|
|
return 0
|
|
}
|
|
args_start = args_start + args_key.length()
|
|
|
|
// Find array end
|
|
local args_end = StringOps.index_of_from(mir_call_json, "]", args_start)
|
|
if args_end < 0 {
|
|
return 0
|
|
}
|
|
|
|
// Extract args array content
|
|
local args_content = mir_call_json.substring(args_start, args_end)
|
|
if args_content.length() == 0 {
|
|
return 0
|
|
}
|
|
|
|
// Count commas + 1
|
|
local count = 1
|
|
local pos = 0
|
|
loop(pos < args_content.length()) {
|
|
local ch = args_content.substring(pos, pos + 1)
|
|
if ch == "," {
|
|
count = count + 1
|
|
}
|
|
pos = pos + 1
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
// Extract argument ValueIds without loading register values
|
|
extract_ids(mir_call_json) {
|
|
local ids = new ArrayBox()
|
|
local args_key = "\"args\":["
|
|
local args_start = mir_call_json.indexOf(args_key)
|
|
if args_start < 0 { return ids }
|
|
args_start = args_start + args_key.length()
|
|
local args_end = StringOps.index_of_from(mir_call_json, "]", args_start)
|
|
if args_end < 0 { return ids }
|
|
local content = mir_call_json.substring(args_start, args_end)
|
|
if content.length() == 0 { return ids }
|
|
local pos = 0
|
|
loop(pos < content.length()) {
|
|
loop(pos < content.length()) {
|
|
local ch = content.substring(pos, pos+1)
|
|
if ch == " " || ch == "\n" || ch == "\r" || ch == "\t" { pos = pos + 1 continue }
|
|
break
|
|
}
|
|
if pos >= content.length() { break }
|
|
local comma = StringOps.index_of_from(content, ",", pos)
|
|
local end = comma < 0 ? content.length() : comma
|
|
local token = content.substring(pos, end)
|
|
if token.length() > 0 {
|
|
ids.push(StringHelpers.to_i64(token))
|
|
}
|
|
if comma < 0 { break }
|
|
pos = comma + 1
|
|
}
|
|
return ids
|
|
}
|
|
}
|