Esempio n. 1
0
static KMETHOD Statement_class(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_Statement(stmt, gma);
	kToken *tokenClassName = SUGAR kStmt_GetToken(kctx, stmt, SYM_("$ClassName"), NULL);
	kNameSpace *ns = Stmt_ns(stmt);
	int isNewlyDefinedClass = false;
	KonohaClassVar *definedClass = (KonohaClassVar *)KLIB kNameSpace_GetClassByFullName(kctx, ns, S_text(tokenClassName->text), S_size(tokenClassName->text), NULL);
	if(definedClass == NULL) {   // Already defined
		kshortflag_t cflag = kStmt_ParseClassFlag(kctx, stmt, kClass_Virtual);
		KMakeTraceUL(trace, sfp, stmt->uline);
		definedClass = kNameSpace_DefineClassName(kctx, ns, cflag, tokenClassName->text, trace);
		isNewlyDefinedClass = true;
	}
	kBlock *bk = kStmt_ParseClassBlockNULL(kctx, stmt, tokenClassName);
	size_t declsize = kBlock_countFieldSize(kctx, bk);
	if(isNewlyDefinedClass) {   // Already defined
		KonohaClass *superClass = CT_Object;
		kToken *tokenSuperClass= SUGAR kStmt_GetToken(kctx, stmt, SYM_("extends"), NULL);
		if(tokenSuperClass != NULL) {
			DBG_ASSERT(Token_isVirtualTypeLiteral(tokenSuperClass));
			superClass = CT_(Token_typeLiteral(tokenSuperClass));
			if(CT_is(Final, superClass)) {
				SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s is final", CT_t(superClass));
				KReturnUnboxValue(false);
			}
			if(CT_is(Virtual, superClass)) {
				SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s is still virtual", CT_t(superClass));
				KReturnUnboxValue(false);
			}
		}
		size_t initsize = (bk != NULL) ? declsize : initFieldSizeOfVirtualClass(superClass);
		KonohaClass_InitField(kctx, definedClass, superClass, initsize);
	}
	else {
		if(declsize > 0 && !CT_is(Virtual, definedClass)) {
			SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "%s has already defined", CT_t(definedClass));
			KReturnUnboxValue(false);
		}
	}
	if(bk != NULL) {
		if(!kBlock_declClassField(kctx, bk, gma, definedClass)) {
			KReturnUnboxValue(false);
		}
		CT_set(Virtual, definedClass, false);
	}
	kToken_setTypeId(kctx, tokenClassName, ns, definedClass->typeId);
	kBlock_AddMethodDeclStmt(kctx, bk, tokenClassName, stmt);
	kStmt_done(kctx, stmt);
	KReturnUnboxValue(true);
}
Esempio n. 2
0
static KMETHOD Statement_class(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck(stmt, ns, reqc);
	kToken *tokenClassName = SUGAR kNode_GetToken(kctx, stmt, KSymbol_("$ClassName"), NULL);
	int isNewlyDefinedClass = false;
	KClassVar *definedClass = (KClassVar *)KLIB kNameSpace_GetClassByFullName(kctx, ns, kString_text(tokenClassName->text), kString_size(tokenClassName->text), NULL);
	if(definedClass == NULL) {   // Already defined
		kshortflag_t cflag = kNode_ParseClassFlag(kctx, stmt, KClassFlag_Virtual);
		KMakeTraceUL(trace, sfp, kNode_uline(stmt));
		definedClass = kNameSpace_DefineClassName(kctx, ns, cflag, tokenClassName->text, trace);
		isNewlyDefinedClass = true;
	}
	kNode *block = kNode_ParseClassNodeNULL(kctx, stmt, tokenClassName);
	size_t declsize = kNode_countFieldSize(kctx, block);
	if(isNewlyDefinedClass) {   // Already defined
		KClass *superClass = KClass_Object;
		kToken *tokenSuperClass= SUGAR kNode_GetToken(kctx, stmt, KSymbol_("extends"), NULL);
		if(tokenSuperClass != NULL) {
			DBG_ASSERT(Token_isVirtualTypeLiteral(tokenSuperClass));
			superClass = KClass_(Token_typeLiteral(tokenSuperClass));
			if(KClass_Is(Final, superClass)) {
				KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s is final", KClass_text(superClass)));
			}
			if(KClass_Is(Virtual, superClass)) {
				KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s is still virtual", KClass_text(superClass)));
			}
		}
		size_t initsize = (block != NULL) ? declsize : initFieldSizeOfVirtualClass(superClass);
		KClass_InitField(kctx, definedClass, superClass, initsize);
	}
	else {
		if(declsize > 0 && !KClass_Is(Virtual, definedClass)) {
			KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s has already defined", KClass_text(definedClass)));
		}
	}
	if(block != NULL) {
		if(!kNode_declClassField(kctx, block, ns, definedClass)) {
			KReturnUnboxValue(false);
		}
		KClass_Set(Virtual, definedClass, false);
	}
	kToken_SetTypeId(kctx, tokenClassName, ns, definedClass->typeId);
	kNode_AddMethodDeclNode(kctx, block, tokenClassName, stmt);
	KReturn(kNode_Type(kctx, stmt, KNode_Done, KType_void));
}
Esempio n. 3
0
static KClass *CreateEnvClass(KonohaContext *kctx, kNameSpace *ns, kToken *typeTk, KClass **EnvObjectClass)
{
	INIT_GCSTACK();
	size_t i = 0, esize = ns->genv->localScope.varsize;
	size_t start = 0, end = esize;
	KGammaStackDecl *oldenv = ns->genv->localScope.varItems;
	kparamtype_t *p = ALLOCA(kparamtype_t, esize);
	char buf[256] = {'_', '_', '_', 'E', 'N', 'V', 0}, *text = buf + 6;
	if(ns->genv->thisClass == KClass_NameSpace) {
		start = 1;
		end = esize - 1;
	}
	assert(end < 256);
	for(i = start; i <= end; i++) {
		p[i-1].name       = oldenv[i].name;
		p[i-1].attrTypeId = oldenv[i].attrTypeId;
		*(text++) = (KType_text(p[i-1].attrTypeId))[0];
	}

	*EnvObjectClass = KLIB kNameSpace_GetClassByFullName(kctx, ns, buf, text - buf, NULL);
	if(*EnvObjectClass == NULL) {
		*EnvObjectClass = kNameSpace_DefineClassName(kctx, ns, buf, text - buf);
	}

	KClass *ct = KLIB KClass_Generics(kctx, KClass_Func, typeTk->resolvedTypeId, end, p);
	if(end >= 1) {
		((KClassVar *)ct)->classMethodList = new_(MethodArray, end*2, OnGlobalConstList);
		for(i = start; i <= end; i++) {
			int n = i - 1;
			ksymbol_t sym    = p[n].name;
			ktypeattr_t type = KTypeAttr_Unmask(p[n].attrTypeId);
			kMethod *getter = new_FunctionGetter(kctx, _GcStack, ct->typeId, sym, type, n);
			kMethod *setter = new_FunctionSetter(kctx, _GcStack, ct->typeId, sym, type, n);
			KLIB kArray_Add(kctx, ct->classMethodList, getter);
			KLIB kArray_Add(kctx, ct->classMethodList, setter);
		}
	}
	RESET_GCSTACK();
	return ct;
}