enhanced class_enter to check indexed type between a class and a superclass

This commit is contained in:
2025-09-16 23:47:50 +09:00
parent 1c8115dbc9
commit 0da9721c9f
4 changed files with 55 additions and 0 deletions

View File

@ -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;

View File

@ -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]: "";
}

View File

@ -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,

View File

@ -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"
}