type propagation
This commit is contained in:
69
mcode.cm
69
mcode.cm
@@ -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 = {}
|
||||
|
||||
Reference in New Issue
Block a user