lower ops directly

This commit is contained in:
2026-02-18 21:18:18 -06:00
parent a05d0e2525
commit 27ca008f18
5 changed files with 482 additions and 20 deletions

View File

@@ -41,6 +41,28 @@ var mcode = function(ast) {
length: "length"
}
// Numeric intrinsic lowering maps (Tier 1 direct mcode).
var intrinsic_num_unary_ops = {
abs: "abs",
sign: "sign",
fraction: "fraction",
integer: "integer",
whole: "integer",
neg: "negate"
}
var intrinsic_num_binary_ops = {
modulo: "modulo",
remainder: "remainder",
max: "max",
min: "min"
}
var intrinsic_num_place_ops = {
floor: "floor",
ceiling: "ceiling",
round: "round",
trunc: "trunc"
}
// Compiler state
var s_instructions = null
var s_data = null
@@ -877,6 +899,56 @@ var mcode = function(ast) {
}
}
// Intrinsic numeric helpers:
// preserve native intrinsic behavior for bad argument types by returning null.
var emit_intrinsic_num_unary = function(op, arg_slot) {
var dest = alloc_slot()
var t = alloc_slot()
var bad = gen_label(op + "_arg_bad")
var done = gen_label(op + "_arg_done")
emit_2("is_num", t, arg_slot)
emit_jump_cond("jump_false", t, bad)
emit_2(op, dest, arg_slot)
emit_jump(done)
emit_label(bad)
emit_1("null", dest)
emit_label(done)
return dest
}
var emit_intrinsic_num_binary = function(op, left_slot, right_slot) {
var dest = alloc_slot()
var t0 = alloc_slot()
var t1 = alloc_slot()
var bad = gen_label(op + "_arg_bad")
var done = gen_label(op + "_arg_done")
emit_2("is_num", t0, left_slot)
emit_jump_cond("jump_false", t0, bad)
emit_2("is_num", t1, right_slot)
emit_jump_cond("jump_false", t1, bad)
emit_3(op, dest, left_slot, right_slot)
emit_jump(done)
emit_label(bad)
emit_1("null", dest)
emit_label(done)
return dest
}
var emit_intrinsic_num_place = function(op, value_slot, place_slot) {
var dest = alloc_slot()
var t = alloc_slot()
var bad = gen_label(op + "_arg_bad")
var done = gen_label(op + "_arg_done")
emit_2("is_num", t, value_slot)
emit_jump_cond("jump_false", t, bad)
emit_3(op, dest, value_slot, place_slot)
emit_jump(done)
emit_label(bad)
emit_1("null", dest)
emit_label(done)
return dest
}
// Scan scope record for variable declarations
var scan_scope = function() {
var scope = find_scope_record(s_function_nr)
@@ -1796,6 +1868,28 @@ var mcode = function(ast) {
if (callee_kind == "name" && callee.intrinsic == true) {
fname = callee.name
nargs = args_list != null ? length(args_list) : 0
mop = intrinsic_num_unary_ops[fname]
if (mop != null && nargs == 1) {
a0 = gen_expr(args_list[0], -1)
return emit_intrinsic_num_unary(mop, a0)
}
mop = intrinsic_num_binary_ops[fname]
if (mop != null && nargs == 2) {
a0 = gen_expr(args_list[0], -1)
a1 = gen_expr(args_list[1], -1)
return emit_intrinsic_num_binary(mop, a0, a1)
}
mop = intrinsic_num_place_ops[fname]
if (mop != null && (nargs == 1 || nargs == 2)) {
a0 = gen_expr(args_list[0], -1)
if (nargs == 2) {
a1 = gen_expr(args_list[1], -1)
} else {
a1 = alloc_slot()
emit_1("null", a1)
}
return emit_intrinsic_num_place(mop, a0, a1)
}
// 1-arg type check intrinsics → direct opcode
if (nargs == 1 && sensory_ops[fname] != null) {
a0 = gen_expr(args_list[0], -1)