Generally speaking ... this is working.
This commit partially fixes #5, however it still needs some work. TODO: * remove debugging printf calls, * some tuning, to consume less memory, * implement similar solution for interfaces
This commit is contained in:
parent
af2c23d3b2
commit
9e885b3196
26
engine/oop.c
26
engine/oop.c
|
@ -218,7 +218,7 @@ PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass, ph7_class_method *pM
|
||||||
* Any other return value indicates failure and the upper layer must generate an appropriate
|
* Any other return value indicates failure and the upper layer must generate an appropriate
|
||||||
* error message.
|
* error message.
|
||||||
*/
|
*/
|
||||||
PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen, ph7_class *pSub, ph7_class *pBase) {
|
PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_class *pSub, ph7_class *pBase) {
|
||||||
ph7_class_method *pMeth;
|
ph7_class_method *pMeth;
|
||||||
ph7_class_attr *pAttr;
|
ph7_class_attr *pAttr;
|
||||||
SyHashEntry *pEntry;
|
SyHashEntry *pEntry;
|
||||||
|
@ -239,9 +239,9 @@ PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen, ph7_class *pSub, ph7_cla
|
||||||
if(pAttr->iProtection == PH7_CLASS_PROT_PRIVATE &&
|
if(pAttr->iProtection == PH7_CLASS_PROT_PRIVATE &&
|
||||||
((ph7_class_attr *)pEntry->pUserData)->iProtection != PH7_CLASS_PROT_PUBLIC) {
|
((ph7_class_attr *)pEntry->pUserData)->iProtection != PH7_CLASS_PROT_PUBLIC) {
|
||||||
/* Cannot redeclare private attribute */
|
/* Cannot redeclare private attribute */
|
||||||
PH7_GenCompileError(&(*pGen), E_WARNING, ((ph7_class_attr *)pEntry->pUserData)->nLine,
|
// PH7_GenCompileError(&(*pGen), E_WARNING, ((ph7_class_attr *)pEntry->pUserData)->nLine,
|
||||||
"Private attribute '%z::%z' redeclared inside child class '%z'",
|
// "Private attribute '%z::%z' redeclared inside child class '%z'",
|
||||||
&pBase->sName, pName, &pSub->sName);
|
// &pBase->sName, pName, &pSub->sName);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -261,20 +261,20 @@ PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen, ph7_class *pSub, ph7_cla
|
||||||
if((pEntry = SyHashGet(&pSub->hMethod, (const void *)pName->zString, pName->nByte)) != 0) {
|
if((pEntry = SyHashGet(&pSub->hMethod, (const void *)pName->zString, pName->nByte)) != 0) {
|
||||||
if(pMeth->iFlags & PH7_CLASS_ATTR_FINAL) {
|
if(pMeth->iFlags & PH7_CLASS_ATTR_FINAL) {
|
||||||
/* Cannot Overwrite final method */
|
/* Cannot Overwrite final method */
|
||||||
rc = PH7_GenCompileError(&(*pGen), E_ERROR, ((ph7_class_method *)pEntry->pUserData)->nLine,
|
// rc = PH7_GenCompileError(&(*pGen), E_ERROR, ((ph7_class_method *)pEntry->pUserData)->nLine,
|
||||||
"Cannot Overwrite final method '%z:%z' inside child class '%z'",
|
// "Cannot Overwrite final method '%z:%z' inside child class '%z'",
|
||||||
&pBase->sName, pName, &pSub->sName);
|
// &pBase->sName, pName, &pSub->sName);
|
||||||
if(rc == SXERR_ABORT) {
|
// if(rc == SXERR_ABORT) {
|
||||||
return SXERR_ABORT;
|
// return SXERR_ABORT;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if(pMeth->iFlags & PH7_CLASS_ATTR_ABSTRACT) {
|
if(pMeth->iFlags & PH7_CLASS_ATTR_ABSTRACT) {
|
||||||
/* Abstract method must be defined in the child class */
|
/* Abstract method must be defined in the child class */
|
||||||
PH7_GenCompileError(&(*pGen), E_WARNING, pMeth->nLine,
|
// PH7_GenCompileError(&(*pGen), E_WARNING, pMeth->nLine,
|
||||||
"Abstract method '%z:%z' must be defined inside child class '%z'",
|
// "Abstract method '%z:%z' must be defined inside child class '%z'",
|
||||||
&pBase->sName, pName, &pSub->sName);
|
// &pBase->sName, pName, &pSub->sName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
engine/vm.c
16
engine/vm.c
|
@ -4516,14 +4516,14 @@ static sxi32 VmByteCodeExec(
|
||||||
case PH7_OP_CLASS_INIT:
|
case PH7_OP_CLASS_INIT:
|
||||||
{
|
{
|
||||||
ph7_class *pClassInfo = (ph7_class *)pInstr->p3;
|
ph7_class *pClassInfo = (ph7_class *)pInstr->p3;
|
||||||
|
ph7_class *pClass = PH7_VmExtractClass(pVm, pClassInfo->sName.zString, pClassInfo->sName.nByte, FALSE, 0);
|
||||||
ph7_class *pBase = 0;
|
ph7_class *pBase = 0;
|
||||||
ph7_class *pClass;
|
printf("Called by class: '%s'\n", pClass->sName.zString);
|
||||||
printf("Called by class: '%s'\n", pClassInfo->sName);
|
|
||||||
if(pInstr->iP1) {
|
if(pInstr->iP1) {
|
||||||
/* This class inherits from other classes */
|
/* This class inherits from other classes */
|
||||||
SyString *apExtends;
|
SyString *apExtends;
|
||||||
while(SySetGetNextEntry(&pClassInfo->sExtends, (void **)&apExtends) == SXRET_OK) {
|
while(SySetGetNextEntry(&pClassInfo->sExtends, (void **)&apExtends) == SXRET_OK) {
|
||||||
printf("Class '%s' inherits from '%s'\n", pClassInfo->sName.zString, apExtends->zString);
|
printf("Class '%s' inherits from '%s'\n", pClass->sName.zString, apExtends->zString);
|
||||||
pBase = PH7_VmExtractClass(pVm, apExtends->zString, apExtends->nByte, FALSE, 0);
|
pBase = PH7_VmExtractClass(pVm, apExtends->zString, apExtends->nByte, FALSE, 0);
|
||||||
if(pBase == 0) {
|
if(pBase == 0) {
|
||||||
/* Non-existent base class */
|
/* Non-existent base class */
|
||||||
|
@ -4535,13 +4535,17 @@ static sxi32 VmByteCodeExec(
|
||||||
/* Trying to inherit from final class */
|
/* Trying to inherit from final class */
|
||||||
PH7_VmThrowError(pVm, 0, PH7_CTX_ERR, "Class cannot inherit from final class");
|
PH7_VmThrowError(pVm, 0, PH7_CTX_ERR, "Class cannot inherit from final class");
|
||||||
}
|
}
|
||||||
|
rc = PH7_ClassInherit(pClass, pBase);
|
||||||
|
if(rc != SXRET_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(pInstr->iP2) {
|
if(pInstr->iP2) {
|
||||||
/* This class implements some interfaces */
|
/* This class implements some interfaces */
|
||||||
SyString *apImplements;
|
SyString *apImplements;
|
||||||
while(SySetGetNextEntry(&pClassInfo->sImplements, (void **)&apImplements) == SXRET_OK) {
|
while(SySetGetNextEntry(&pClassInfo->sImplements, (void **)&apImplements) == SXRET_OK) {
|
||||||
printf("Class '%s' implements '%s'\n", pClassInfo->sName.zString, apImplements->zString);
|
printf("Class '%s' implements '%s'\n", pClass->sName.zString, apImplements->zString);
|
||||||
pBase = PH7_VmExtractClass(pVm, apImplements->zString, apImplements->nByte, FALSE, 0);
|
pBase = PH7_VmExtractClass(pVm, apImplements->zString, apImplements->nByte, FALSE, 0);
|
||||||
if(pBase == 0) {
|
if(pBase == 0) {
|
||||||
/* Non-existent interface */
|
/* Non-existent interface */
|
||||||
|
@ -4550,6 +4554,10 @@ static sxi32 VmByteCodeExec(
|
||||||
/* Trying to extend a class */
|
/* Trying to extend a class */
|
||||||
PH7_VmThrowError(pVm, 0, PH7_CTX_ERR, "Interface cannot inherit from a class");
|
PH7_VmThrowError(pVm, 0, PH7_CTX_ERR, "Interface cannot inherit from a class");
|
||||||
}
|
}
|
||||||
|
rc = PH7_ClassImplement(pClass, pBase);
|
||||||
|
if(rc != SXRET_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1701,7 +1701,7 @@ PH7_PRIVATE ph7_class_method *PH7_ClassExtractMethod(ph7_class *pClass, const ch
|
||||||
PH7_PRIVATE ph7_class_attr *PH7_ClassExtractAttribute(ph7_class *pClass, const char *zName, sxu32 nByte);
|
PH7_PRIVATE ph7_class_attr *PH7_ClassExtractAttribute(ph7_class *pClass, const char *zName, sxu32 nByte);
|
||||||
PH7_PRIVATE sxi32 PH7_ClassInstallAttr(ph7_class *pClass, ph7_class_attr *pAttr);
|
PH7_PRIVATE sxi32 PH7_ClassInstallAttr(ph7_class *pClass, ph7_class_attr *pAttr);
|
||||||
PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass, ph7_class_method *pMeth);
|
PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass, ph7_class_method *pMeth);
|
||||||
PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen, ph7_class *pSub, ph7_class *pBase);
|
PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_class *pSub, ph7_class *pBase);
|
||||||
PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub, ph7_class *pBase);
|
PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub, ph7_class *pBase);
|
||||||
PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface);
|
PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface);
|
||||||
PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass);
|
PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass);
|
||||||
|
|
Loading…
Reference in New Issue