type propagation

This commit is contained in:
2026-02-21 04:13:21 -06:00
parent 74e0923629
commit 700b640cf1

View File

@@ -89,6 +89,8 @@ var mcode = function(ast) {
var s_filename = null
var s_has_disruption = false
var s_slot_types = {}
var s_num_err_label = null
var s_num_err_emitted = false
// Shared closure vars for binop helpers (avoids >4 param functions)
var _bp_dest = 0
@@ -118,7 +120,9 @@ var mcode = function(ast) {
cur_line: s_cur_line,
cur_col: s_cur_col,
has_disruption: s_has_disruption,
slot_types: s_slot_types
slot_types: s_slot_types,
num_err_label: s_num_err_label,
num_err_emitted: s_num_err_emitted
}
}
@@ -141,6 +145,8 @@ var mcode = function(ast) {
s_cur_col = saved.cur_col
s_has_disruption = saved.has_disruption
s_slot_types = saved.slot_types
s_num_err_label = saved.num_err_label
s_num_err_emitted = saved.num_err_emitted
}
// Slot allocation
@@ -413,29 +419,37 @@ var mcode = function(ast) {
var emit_numeric_binop = function(op_str) {
var left_known = is_known_number(_bp_ln) || slot_is_num(_bp_left)
var right_known = is_known_number(_bp_rn) || slot_is_num(_bp_right)
var t0 = null
var done = null
if (left_known && right_known) {
emit_3(op_str, _bp_dest, _bp_left, _bp_right)
mark_slot(_bp_dest, "num")
return null
}
var t0 = alloc_slot()
var err = gen_label("num_err")
var done = gen_label("num_done")
if (s_num_err_label == null) {
s_num_err_label = gen_label("num_err")
}
t0 = alloc_slot()
if (!left_known) {
emit_2("is_num", t0, _bp_left)
emit_jump_cond("jump_false", t0, err)
emit_jump_cond("jump_false", t0, s_num_err_label)
mark_slot(_bp_left, "num")
}
if (!right_known) {
emit_2("is_num", t0, _bp_right)
emit_jump_cond("jump_false", t0, err)
emit_jump_cond("jump_false", t0, s_num_err_label)
mark_slot(_bp_right, "num")
}
emit_3(op_str, _bp_dest, _bp_left, _bp_right)
emit_jump(done)
emit_label(err)
emit_log_error("cannot apply '" + _bp_op_sym + "': operands must be numbers")
emit_0("disrupt")
emit_label(done)
if (!s_num_err_emitted) {
done = gen_label("num_done")
emit_jump(done)
emit_label(s_num_err_label)
emit_log_error("operands must be numbers")
emit_0("disrupt")
emit_label(done)
s_num_err_emitted = true
}
mark_slot(_bp_dest, "num")
return null
}
@@ -460,23 +474,30 @@ var mcode = function(ast) {
// emit_neg_decomposed: emit type-guarded negate
var emit_neg_decomposed = function(dest, src, src_node) {
var t0 = null
var done = null
if (is_known_number(src_node) || slot_is_num(src)) {
emit_2("negate", dest, src)
mark_slot(dest, "num")
return null
}
var t0 = alloc_slot()
var err = gen_label("neg_err")
var done = gen_label("neg_done")
if (s_num_err_label == null) {
s_num_err_label = gen_label("num_err")
}
t0 = alloc_slot()
emit_2("is_num", t0, src)
emit_jump_cond("jump_false", t0, err)
emit_jump_cond("jump_false", t0, s_num_err_label)
mark_slot(src, "num")
emit_2("negate", dest, src)
emit_jump(done)
emit_label(err)
emit_log_error("cannot negate: operand must be a number")
emit_0("disrupt")
emit_label(done)
if (!s_num_err_emitted) {
done = gen_label("num_done")
emit_jump(done)
emit_label(s_num_err_label)
emit_log_error("operands must be numbers")
emit_0("disrupt")
emit_label(done)
s_num_err_emitted = true
}
mark_slot(dest, "num")
return null
}
@@ -2605,6 +2626,8 @@ var mcode = function(ast) {
s_vars = []
s_intrinsic_cache = []
s_slot_types = {}
s_num_err_label = null
s_num_err_emitted = false
s_loop_break = null
s_loop_continue = null
s_label_map = {}
@@ -2804,6 +2827,8 @@ var mcode = function(ast) {
s_label_counter = 0
s_func_counter = 0
s_slot_types = {}
s_num_err_label = null
s_num_err_emitted = false
s_loop_break = null
s_loop_continue = null
s_label_map = {}