diff --git a/lang/bytecode.c b/lang/bytecode.c index 6185849..72e93ab 100644 --- a/lang/bytecode.c +++ b/lang/bytecode.c @@ -16,15 +16,16 @@ OP_GET = 0x06, OP_SET = 0x07, OP_DROP = 0x08, + OP_DEPTH_CHECK = 0x09, }; // clang-format off static const unsigned char bytecode[] = { -0x05, 0x05, 0x05, 0x01, 0x6a, 0x02, 0x00, 0x00, 0x07, 0x01, -0x05, 0x06, 0x01, 0x06, 0x01, 0x04, 0x02, 0x41, 0x64, 0x64, -0x00, 0x07, 0x02, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x06, -0x02, 0x04, 0x02, 0x4d, 0x69, 0x6e, 0x75, 0x73, 0x00, 0x07, -0x03, 0x06, 0x03, 0x07, 0x00, 0x08, 0x03, 0x03, +0x09, 0x01, 0x05, 0x05, 0x05, 0x01, 0x6a, 0x02, 0x00, 0x00, +0x07, 0x01, 0x05, 0x06, 0x01, 0x06, 0x01, 0x04, 0x02, 0x41, +0x64, 0x64, 0x00, 0x07, 0x02, 0x05, 0x01, 0x02, 0x00, 0x00, +0x00, 0x06, 0x02, 0x04, 0x02, 0x4d, 0x69, 0x6e, 0x75, 0x73, +0x00, 0x07, 0x03, 0x06, 0x03, 0x07, 0x00, 0x08, 0x03, 0x03, }; // clang-format on @@ -68,6 +69,12 @@ vm_stack_drop(state, *pos_code++); break; } + case OP_DEPTH_CHECK: { + int depth = *pos_code++; + abort_if(vm_stack_depth(state) != depth, + "stack depth mismatch"); + break; + } default: // Skip over ASCII and unknown OPs break; diff --git a/lang/compile.py b/lang/compile.py index fe5efc4..f486d84 100755 --- a/lang/compile.py +++ b/lang/compile.py @@ -221,6 +221,13 @@ def __repr__(self): return 'IRFunction(name="%s", statements=%s)' % (self.name, self.statements) +class IRDepthCheck(): + def __init__(self, depth): + self.depth = depth + + def __repr__(self): + return '\n\tIRDepthCheck(depth=%i)' % (self.depth) + ## IR Generator def generate_ir_value(value): @@ -321,6 +328,7 @@ def replace_variables(ir, variables): new_ir = [] + new_ir.append(IRDepthCheck(1)) var_count = len(variables) - 1 # Ignore Return new_ir.append(IRAllocate(var_count)) for node in ir: @@ -386,6 +394,10 @@ bytes += b"\x00" # NULL terminator elif isinstance(node, IRReturn): bytes += b"\x03" # OP_RET + elif isinstance(node, IRDepthCheck): + depth = int(node.depth) + bytes += b"\x09" # OP_DEPTH_CHECK + bytes += depth.to_bytes(1) else: print("Unknown bytecode node: %s" % (node)) return None