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:
		
							
								
								
									
										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 | ||||
|  * 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_attr *pAttr; | ||||
| 	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 && | ||||
| 					((ph7_class_attr *)pEntry->pUserData)->iProtection != PH7_CLASS_PROT_PUBLIC) { | ||||
| 				/* Cannot redeclare private attribute */ | ||||
| 				PH7_GenCompileError(&(*pGen), E_WARNING, ((ph7_class_attr *)pEntry->pUserData)->nLine, | ||||
| 									"Private attribute '%z::%z' redeclared inside child class '%z'", | ||||
| 									&pBase->sName, pName, &pSub->sName); | ||||
| //				PH7_GenCompileError(&(*pGen), E_WARNING, ((ph7_class_attr *)pEntry->pUserData)->nLine, | ||||
| //									"Private attribute '%z::%z' redeclared inside child class '%z'", | ||||
| //									&pBase->sName, pName, &pSub->sName); | ||||
| 			} | ||||
| 			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(pMeth->iFlags & PH7_CLASS_ATTR_FINAL) { | ||||
| 				/* Cannot Overwrite final method */ | ||||
| 				rc = PH7_GenCompileError(&(*pGen), E_ERROR, ((ph7_class_method *)pEntry->pUserData)->nLine, | ||||
| 										 "Cannot Overwrite final method '%z:%z' inside child class '%z'", | ||||
| 										 &pBase->sName, pName, &pSub->sName); | ||||
| 				if(rc == SXERR_ABORT) { | ||||
| 					return SXERR_ABORT; | ||||
| 				} | ||||
| //				rc = PH7_GenCompileError(&(*pGen), E_ERROR, ((ph7_class_method *)pEntry->pUserData)->nLine, | ||||
| //										 "Cannot Overwrite final method '%z:%z' inside child class '%z'", | ||||
| //										 &pBase->sName, pName, &pSub->sName); | ||||
| //				if(rc == SXERR_ABORT) { | ||||
| //					return SXERR_ABORT; | ||||
| //				} | ||||
| 			} | ||||
| 			continue; | ||||
| 		} else { | ||||
| 			if(pMeth->iFlags & PH7_CLASS_ATTR_ABSTRACT) { | ||||
| 				/* Abstract method must be defined in the child class */ | ||||
| 				PH7_GenCompileError(&(*pGen), E_WARNING, pMeth->nLine, | ||||
| 									"Abstract method '%z:%z' must be defined inside child class '%z'", | ||||
| 									&pBase->sName, pName, &pSub->sName); | ||||
| //				PH7_GenCompileError(&(*pGen), E_WARNING, pMeth->nLine, | ||||
| //									"Abstract method '%z:%z' must be defined inside child class '%z'", | ||||
| //									&pBase->sName, pName, &pSub->sName); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										16
									
								
								engine/vm.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								engine/vm.c
									
									
									
									
									
								
							| @@ -4516,14 +4516,14 @@ static sxi32 VmByteCodeExec( | ||||
| 			case PH7_OP_CLASS_INIT: | ||||
| 				{ | ||||
| 					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 *pClass; | ||||
| 					printf("Called by class: '%s'\n", pClassInfo->sName); | ||||
| 					printf("Called by class: '%s'\n", pClass->sName.zString); | ||||
| 					if(pInstr->iP1) { | ||||
| 						/* This class inherits from other classes */ | ||||
| 						SyString *apExtends; | ||||
| 						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); | ||||
| 							if(pBase == 0) { | ||||
| 								/* Non-existent base class */ | ||||
| @@ -4535,13 +4535,17 @@ static sxi32 VmByteCodeExec( | ||||
| 								/* Trying to 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) { | ||||
| 						/* This class implements some interfaces */ | ||||
| 						SyString *apImplements; | ||||
| 						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); | ||||
| 							if(pBase == 0) { | ||||
| 								/* Non-existent interface */ | ||||
| @@ -4550,6 +4554,10 @@ static sxi32 VmByteCodeExec( | ||||
| 								/* Trying to extend 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; | ||||
|   | ||||
| @@ -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 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_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_ClassImplement(ph7_class *pMain, ph7_class *pInterface); | ||||
| PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user