merge add
This commit is contained in:
197
mcode.cm
197
mcode.cm
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user