merge add

This commit is contained in:
2026-02-13 08:09:12 -06:00
parent f7e2ff13b5
commit 0acaabd5fa
14 changed files with 98386 additions and 107814 deletions

197
mcode.cm
View File

@@ -273,157 +273,19 @@ var mcode = function(ast) {
return node.kind == "null"
}
// emit_add_decomposed: int path -> text path -> float path -> disrupt
// emit_add_decomposed: emit generic add (VM dispatches int/float/text)
// reads _bp_dest, _bp_left, _bp_right, _bp_ln, _bp_rn from closure
var emit_add_decomposed = function() {
var dest = _bp_dest
var left = _bp_left
var right = _bp_right
var t0 = 0
var t1 = 0
var left_is_int = is_known_int(_bp_ln)
var left_is_text = is_known_text(_bp_ln)
var left_is_num = is_known_number(_bp_ln)
var right_is_int = is_known_int(_bp_rn)
var right_is_text = is_known_text(_bp_rn)
var right_is_num = is_known_number(_bp_rn)
var not_int = null
var not_text = null
var done = null
var err = null
// Both sides known int
if (left_is_int && right_is_int) {
emit_3("add_int", dest, left, right)
// Known text+text → concat directly (skip numeric check in VM)
if (is_known_text(_bp_ln) && is_known_text(_bp_rn)) {
emit_3("concat", _bp_dest, _bp_left, _bp_right)
return null
}
// Both sides known text
if (left_is_text && right_is_text) {
emit_3("concat", dest, left, right)
return null
}
// Both sides known number (but not both int)
if (left_is_num && right_is_num) {
if (left_is_int && right_is_int) {
emit_3("add_int", dest, left, right)
} else {
emit_3("add_float", dest, left, right)
}
return null
}
not_int = gen_label("add_ni")
not_text = gen_label("add_nt")
done = gen_label("add_done")
err = gen_label("add_err")
// Int path
t0 = alloc_slot()
if (!left_is_int) {
emit_2("is_int", t0, left)
emit_jump_cond("jump_false", t0, not_int)
}
t1 = alloc_slot()
if (!right_is_int) {
emit_2("is_int", t1, right)
emit_jump_cond("jump_false", t1, not_int)
}
emit_3("add_int", dest, left, right)
emit_jump(done)
// Text path
emit_label(not_int)
if (!left_is_text) {
emit_2("is_text", t0, left)
emit_jump_cond("jump_false", t0, not_text)
}
if (!right_is_text) {
emit_2("is_text", t1, right)
emit_jump_cond("jump_false", t1, not_text)
}
emit_3("concat", dest, left, right)
emit_jump(done)
// Float path
emit_label(not_text)
if (!left_is_num) {
emit_2("is_num", t0, left)
emit_jump_cond("jump_false", t0, err)
}
if (!right_is_num) {
emit_2("is_num", t1, right)
emit_jump_cond("jump_false", t1, err)
}
emit_3("add_float", dest, left, right)
emit_jump(done)
emit_label(err)
emit_0("disrupt")
emit_label(done)
emit_3("add", _bp_dest, _bp_left, _bp_right)
return null
}
// emit_numeric_binop: int path -> float path -> disrupt
// reads _bp_dest, _bp_left, _bp_right, _bp_ln, _bp_rn from closure
var emit_numeric_binop = function(int_op, float_op) {
var dest = _bp_dest
var left = _bp_left
var right = _bp_right
var t0 = 0
var t1 = 0
var left_is_int = is_known_int(_bp_ln)
var left_is_num = is_known_number(_bp_ln)
var right_is_int = is_known_int(_bp_rn)
var right_is_num = is_known_number(_bp_rn)
var not_int = null
var done = null
var err = null
// Both sides known int
if (left_is_int && right_is_int) {
emit_3(int_op, dest, left, right)
return null
}
// Both sides known number (but not both int)
if (left_is_num && right_is_num) {
emit_3(float_op, dest, left, right)
return null
}
not_int = gen_label("num_ni")
done = gen_label("num_done")
err = gen_label("num_err")
t0 = alloc_slot()
if (!left_is_int) {
emit_2("is_int", t0, left)
emit_jump_cond("jump_false", t0, not_int)
}
t1 = alloc_slot()
if (!right_is_int) {
emit_2("is_int", t1, right)
emit_jump_cond("jump_false", t1, not_int)
}
emit_3(int_op, dest, left, right)
emit_jump(done)
emit_label(not_int)
if (!left_is_num) {
emit_2("is_num", t0, left)
emit_jump_cond("jump_false", t0, err)
}
if (!right_is_num) {
emit_2("is_num", t1, right)
emit_jump_cond("jump_false", t1, err)
}
emit_3(float_op, dest, left, right)
emit_jump(done)
emit_label(err)
emit_0("disrupt")
emit_label(done)
return null
}
// emit_numeric_binop removed — generic ops emitted directly via passthrough
// emit_eq_decomposed: identical -> int -> float -> text -> null -> bool -> mismatch(false)
// reads _bp_dest, _bp_left, _bp_right from closure
@@ -649,41 +511,9 @@ var mcode = function(ast) {
return null
}
// emit_neg_decomposed: int path -> float path -> disrupt
// emit_neg_decomposed: emit generic negate (VM dispatches int/float)
var emit_neg_decomposed = function(dest, src, src_node) {
var t0 = 0
var not_int = null
var done = null
var err = null
if (is_known_int(src_node)) {
emit_2("neg_int", dest, src)
return null
}
if (is_known_number(src_node)) {
emit_2("neg_float", dest, src)
return null
}
not_int = gen_label("neg_ni")
done = gen_label("neg_done")
err = gen_label("neg_err")
t0 = alloc_slot()
emit_2("is_int", t0, src)
emit_jump_cond("jump_false", t0, not_int)
emit_2("neg_int", dest, src)
emit_jump(done)
emit_label(not_int)
emit_2("is_num", t0, src)
emit_jump_cond("jump_false", t0, err)
emit_2("neg_float", dest, src)
emit_jump(done)
emit_label(err)
emit_0("disrupt")
emit_label(done)
emit_2("negate", dest, src)
return null
}
@@ -695,14 +525,6 @@ var mcode = function(ast) {
_bp_right = right
if (op_str == "add") {
emit_add_decomposed()
} else if (op_str == "subtract") {
emit_numeric_binop("sub_int", "sub_float")
} else if (op_str == "multiply") {
emit_numeric_binop("mul_int", "mul_float")
} else if (op_str == "divide") {
emit_numeric_binop("div_int", "div_float")
} else if (op_str == "modulo") {
emit_numeric_binop("mod_int", "mod_float")
} else if (op_str == "eq") {
emit_eq_decomposed()
} else if (op_str == "ne") {
@@ -716,7 +538,8 @@ var mcode = function(ast) {
} else if (op_str == "ge") {
emit_relational("ge_int", "ge_float", "ge_text")
} else {
// Passthrough for bitwise, pow, in, etc.
// Passthrough for subtract, multiply, divide, modulo,
// bitwise, pow, in, etc.
emit_3(op_str, dest, left, right)
}
return null