From 0da9721c9fac4ad2221e49e7b5a5075ccce04526 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 16 Sep 2025 23:47:50 +0900 Subject: [PATCH] enhanced class_enter to check indexed type between a class and a superclass --- lib/exec.c | 14 ++++++++++++++ lib/hak.c | 12 ++++++++++++ lib/hak.h | 4 ++++ t/class-5001.err | 25 +++++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/lib/exec.c b/lib/exec.c index fab005a..5d0602f 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -4122,6 +4122,9 @@ static int execute (hak_t* hak) if (b1 > 0) { + hak_ooi_t super_spec; + hak_obj_type_t super_indexed_type; + HAK_STACK_POP_TO(hak, superclass); /* TODO: support more than 1 superclass later when the compiler supports more */ if (!HAK_IS_CLASS(hak, superclass)) { @@ -4129,6 +4132,17 @@ static int execute (hak_t* hak) if (do_throw_with_internal_errmsg(hak, fetched_instruction_pointer) >= 0) break; goto oops_with_errmsg_supplement; } + + super_spec = HAK_OOP_TO_SMOOI(((hak_oop_class_t)superclass)->spec); + super_indexed_type = HAK_CLASS_SPEC_INDEXED_TYPE(super_spec); + if (super_indexed_type != b5) + { + /* TODO: include the class indexed type in the message .. */ + hak_seterrbfmt(hak, HAK_ECALL, "incompatible %hs superclass %O with %hs class", + hak_obj_type_to_bcstr(super_indexed_type), superclass, hak_obj_type_to_bcstr(b5)); + if (do_throw_with_internal_errmsg(hak, fetched_instruction_pointer) >= 0) break; + goto oops_with_errmsg_supplement; + } } else superclass = hak->_nil; diff --git a/lib/hak.c b/lib/hak.c index 9fadb2f..664371e 100644 --- a/lib/hak.c +++ b/lib/hak.c @@ -1017,3 +1017,15 @@ hak_pfbase_t* hak_findpfbase (hak_t* hak, hak_pfinfo_t* pfinfo, hak_oow_t pfcoun return HAK_NULL; } +const hak_bch_t* hak_obj_type_to_bcstr (hak_obj_type_t type) +{ + static const hak_bch_t* names[] = { + "oop", + "char", + "byte", + "halfword", + "word", + }; + + return (type < HAK_COUNTOF(names))? names[type]: ""; +} diff --git a/lib/hak.h b/lib/hak.h index e2ad2bc..abaf5f6 100644 --- a/lib/hak.h +++ b/lib/hak.h @@ -2097,6 +2097,10 @@ typedef int (*hak_xchg_writer_t) ( extern "C" { #endif +HAK_EXPORT const hak_bch_t* hak_obj_type_to_bcstr ( + hak_obj_type_t type +); + HAK_EXPORT hak_t* hak_open ( hak_mmgr_t* mmgr, hak_oow_t xtnsize, diff --git a/t/class-5001.err b/t/class-5001.err index 3e116dc..bca0f24 100644 --- a/t/class-5001.err +++ b/t/class-5001.err @@ -321,3 +321,28 @@ class Kuduro (a (b) c) { var d e var(#class) b ##ERROR: syntax error - duplicate class variable name 'b' } + +--- + +## TODO: some of these can be detected as an error at the compile time.. + +class[#b] X (a) { + fun[#ci] new() { + ## the instance variable is a byte because the class is a byte-oriented class + self.a := -20 ##ERROR: exception not handled - "negative number - -20" + } +} + +X:new + +--- + +class[#b] X (a) { + fun[#ci] new() { + ## the instance variable is a byte because the class is a byte-oriented class + self.a := -20 ##ERROR: exception not handled - "negative number - -20" + } +} + +class Y: X { ##ERROR: exception not handled - "incompatible byte superclass X with oop class" +}