better errors
This commit is contained in:
37
mcode.cm
37
mcode.cm
@@ -22,6 +22,12 @@ var mcode = function(ast) {
|
||||
"~!": "bitnot", "[]!": "load"
|
||||
}
|
||||
|
||||
var binop_sym = {
|
||||
add: "+", subtract: "-", multiply: "*", divide: "/",
|
||||
modulo: "%", pow: "**",
|
||||
lt: "<", le: "<=", gt: ">", ge: ">="
|
||||
}
|
||||
|
||||
var compound_map = {
|
||||
"+=": "add", "-=": "subtract", "*=": "multiply", "/=": "divide",
|
||||
"%=": "modulo", "&=": "bitand", "|=": "bitor", "^=": "bitxor",
|
||||
@@ -67,6 +73,7 @@ var mcode = function(ast) {
|
||||
var _bp_right = 0
|
||||
var _bp_ln = null
|
||||
var _bp_rn = null
|
||||
var _bp_op_sym = null
|
||||
|
||||
// State save/restore for nested function compilation
|
||||
var save_state = function() {
|
||||
@@ -240,6 +247,27 @@ var mcode = function(ast) {
|
||||
emit_1("null", dest)
|
||||
}
|
||||
|
||||
var emit_log_error = function(msg) {
|
||||
var log_slot = alloc_slot()
|
||||
add_instr(["access", log_slot, {kind: "name", name: "log", make: "intrinsic"}])
|
||||
var name_slot = alloc_slot()
|
||||
emit_const_str(name_slot, "error")
|
||||
var msg_slot = alloc_slot()
|
||||
emit_const_str(msg_slot, msg)
|
||||
var args_arr = alloc_slot()
|
||||
add_instr(["array", args_arr, 0])
|
||||
emit_2("push", args_arr, msg_slot)
|
||||
var result = alloc_slot()
|
||||
var frame_slot = alloc_slot()
|
||||
emit_3("frame", frame_slot, log_slot, 2)
|
||||
var null_slot = alloc_slot()
|
||||
emit_1("null", null_slot)
|
||||
emit_3("setarg", frame_slot, 0, null_slot)
|
||||
emit_3("setarg", frame_slot, 1, name_slot)
|
||||
emit_3("setarg", frame_slot, 2, args_arr)
|
||||
emit_2("invoke", frame_slot, result)
|
||||
}
|
||||
|
||||
var emit_jump = function(label) {
|
||||
add_instr(["jump", label])
|
||||
}
|
||||
@@ -321,6 +349,7 @@ var mcode = function(ast) {
|
||||
emit_jump(done)
|
||||
|
||||
emit_label(err)
|
||||
emit_log_error("cannot apply '+': operands must both be text or both be numbers")
|
||||
emit_0("disrupt")
|
||||
emit_label(done)
|
||||
return null
|
||||
@@ -345,6 +374,7 @@ var mcode = function(ast) {
|
||||
emit_jump(done)
|
||||
|
||||
emit_label(err)
|
||||
emit_log_error("cannot apply '" + _bp_op_sym + "': operands must be numbers")
|
||||
emit_0("disrupt")
|
||||
emit_label(done)
|
||||
return null
|
||||
@@ -569,6 +599,7 @@ var mcode = function(ast) {
|
||||
emit_jump(done)
|
||||
|
||||
emit_label(err)
|
||||
emit_log_error("cannot compare with '" + _bp_op_sym + "': operands must be same type")
|
||||
emit_0("disrupt")
|
||||
emit_label(done)
|
||||
return null
|
||||
@@ -589,6 +620,7 @@ var mcode = function(ast) {
|
||||
emit_jump(done)
|
||||
|
||||
emit_label(err)
|
||||
emit_log_error("cannot negate: operand must be a number")
|
||||
emit_0("disrupt")
|
||||
emit_label(done)
|
||||
return null
|
||||
@@ -607,6 +639,7 @@ var mcode = function(ast) {
|
||||
_bp_dest = dest
|
||||
_bp_left = left
|
||||
_bp_right = right
|
||||
_bp_op_sym = binop_sym[op_str] || op_str
|
||||
if (op_str == "add") {
|
||||
emit_add_decomposed()
|
||||
} else if (op_str == "eq") {
|
||||
@@ -760,6 +793,7 @@ var mcode = function(ast) {
|
||||
|
||||
// Error path: non-text key on function disrupts
|
||||
emit_label(error_path)
|
||||
emit_log_error("cannot access: key must be text")
|
||||
emit_0("disrupt")
|
||||
emit_jump(done_label)
|
||||
|
||||
@@ -1427,6 +1461,7 @@ var mcode = function(ast) {
|
||||
emit_2("push", arr_slot, val_slot)
|
||||
emit_jump(guard_done)
|
||||
emit_label(guard_err)
|
||||
emit_log_error("cannot push: target must be an array")
|
||||
emit_0("disrupt")
|
||||
emit_label(guard_done)
|
||||
return val_slot
|
||||
@@ -1785,6 +1820,7 @@ var mcode = function(ast) {
|
||||
emit_2("push", a0, a1)
|
||||
emit_jump(guard_done)
|
||||
emit_label(guard_err)
|
||||
emit_log_error("cannot push: target must be an array")
|
||||
emit_0("disrupt")
|
||||
emit_label(guard_done)
|
||||
return a1
|
||||
@@ -2156,6 +2192,7 @@ var mcode = function(ast) {
|
||||
emit_2("pop", local_slot, arr_slot)
|
||||
emit_jump(guard_done)
|
||||
emit_label(guard_err)
|
||||
emit_log_error("cannot pop: target must be an array")
|
||||
emit_0("disrupt")
|
||||
emit_label(guard_done)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user