From 191458111a02407e5841b4247d85a120d33ca46c Mon Sep 17 00:00:00 2001 From: "David P. Chassin" Date: Wed, 11 Nov 2020 07:11:50 -0800 Subject: [PATCH] Add support for parent class definition in loader --- gldcore/class.cpp | 7 +++++- gldcore/load.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++ gldcore/load.h | 1 + 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/gldcore/class.cpp b/gldcore/class.cpp index 3034aaedd..9e198c062 100644 --- a/gldcore/class.cpp +++ b/gldcore/class.cpp @@ -351,7 +351,12 @@ PROPERTY *class_add_extended_property(CLASS *oclass, /**< the class to whic prop->width = property_type[ptype].size; prop->access = PA_PUBLIC; prop->unit = pUnit; - prop->addr = (void*)(int64)oclass->size; + int64 offset = (int64)oclass->size; + for ( CLASS *parent = oclass->parent ; parent != NULL ; parent = parent->parent ) + { + offset += parent->size; + } + prop->addr = (void*)offset; prop->delegation = NULL; prop->keywords = NULL; prop->description = NULL; diff --git a/gldcore/load.cpp b/gldcore/load.cpp index 1553fa440..a062cff1d 100755 --- a/gldcore/load.cpp +++ b/gldcore/load.cpp @@ -340,6 +340,12 @@ std::string GldLoader::setup_class(CLASS *oclass) snprintf(buffer,sizeof(buffer),"\toclass->size = sizeof(%s);\n", oclass->name); result.append(buffer); + if ( oclass->parent != NULL ) + { + snprintf(buffer,sizeof(buffer),"\toclass->parent = (*(callback->class_getname(\"%s\")));",oclass->parent->name); + result.append(buffer); + } + PROPERTY *prop; for (prop=oclass->pmap; prop!=NULL; prop=prop->next) { @@ -3296,6 +3302,53 @@ int GldLoader::class_event_handler(PARSER, CLASS *oclass) DONE; } +int GldLoader::class_parent_definition(PARSER, CLASS *oclass) +{ + char classname[1024]; + START; + if WHITE ACCEPT; + if ( LITERAL("parent") ) + { + if WHITE ACCEPT; + if ( TERM(name(HERE,classname,sizeof(classname))) ) + { + if ( oclass->module != NULL ) + { + syntax_error(filename,linenum,"cannot set parent of class defined in module"); + REJECT; + } + else + { + oclass->parent = class_get_class_from_classname(classname); + if ( oclass->parent == NULL ) + { + syntax_error(filename,linenum,"parent class '%s' not found", classname); + REJECT; + } + else if ( WHITE,LITERAL(";") ) + { + ACCEPT; + } + else + { + syntax_error(filename,linenum,"missing semicolon after parent class name"); + REJECT; + } + } + } + else + { + syntax_error(filename,linenum,"missing or invalid parent class name"); + REJECT; + } + } + else + { + REJECT; + } + DONE; +} + int GldLoader::class_properties(PARSER, CLASS *oclass, int64 *functions, char *initcode, int initsize) { static char code[65536]; @@ -3336,6 +3389,10 @@ int GldLoader::class_properties(PARSER, CLASS *oclass, int64 *functions, char *i *functions |= FN_EXPORT; ACCEPT; } + else if TERM(class_parent_definition(HERE,oclass) ) + { + ACCEPT; + } else if (TERM(property_type(HERE,&type,&keys)) && (WHITE,(TERM(nameunit(HERE,propname,sizeof(propname),&pUnit))||TERM(name(HERE,propname,sizeof(propname))))) && (WHITE,LITERAL(";")) ) { PROPERTY *prop = class_find_property(oclass,propname); diff --git a/gldcore/load.h b/gldcore/load.h index e8c6ed36f..c8f7253bf 100644 --- a/gldcore/load.h +++ b/gldcore/load.h @@ -300,6 +300,7 @@ class GldLoader int class_explicit_definition(PARSER, CLASS *oclass); int class_external_function(PARSER, CLASS *oclass, CLASS **eclass,char *fname, int fsize); int class_event_handler(PARSER, CLASS *oclass); + int class_parent_definition(PARSER, CLASS *oclass); int class_properties(PARSER, CLASS *oclass, int64 *functions, char *initcode, int initsize); int class_block(PARSER); int set_flags(OBJECT *obj, char *propval);