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 |  * 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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user