Beispiel #1
0
static void kMethod_WriteToBuffer(KonohaContext *kctx, kMethod *mtd, KBuffer *wb)
{
	kParam *pa = kMethod_GetParam(mtd);
	Method_WriteAttributeToBuffer(kctx, mtd, wb);
	KLIB KBuffer_printf(kctx, wb, "%s %s.%s%s", KType_text(pa->rtype), KType_text(mtd->typeId), KMethodName_Fmt2(mtd->mn));
	{
		size_t i;
		KLIB KBuffer_Write(kctx, wb, "(", 1);
		for(i = 0; i < pa->psize; i++) {
			if(i > 0) {
				KLIB KBuffer_Write(kctx, wb, ", ", 2);
			}
			if(KTypeAttr_Is(ReadOnly, pa->paramtypeItems[i].attrTypeId)) {
				KLIB KBuffer_printf(kctx, wb, "@ReadOnly ");
			}
			if(KTypeAttr_Is(Coercion, pa->paramtypeItems[i].attrTypeId)) {
				KLIB KBuffer_printf(kctx, wb, "@Coercion ");
			}
			KLIB KBuffer_printf(kctx, wb, "%s %s", KType_text(pa->paramtypeItems[i].attrTypeId), KSymbol_text(pa->paramtypeItems[i].name));
		}
		KLIB KBuffer_Write(kctx, wb, ")", 1);
	}
}
Beispiel #2
0
static KMETHOD NameSpace_man(KonohaContext *kctx, KonohaStack *sfp)
{
	INIT_GCSTACK();
	kArray *list = kctx->stack->gcStack;
	size_t start = kArray_size(list);
	kNameSpace *ns = sfp[0].asNameSpace;
	KClass *ct = kObject_class(sfp[1].asObject);
	DBG_P("*** man %s", KType_text(ct->typeId));
	while(ns != NULL) {
		copyMethodList(kctx, ct->typeId, ns->methodList_OnList, list);
		ns = ns->parentNULL;
	}
	copyMethodList(kctx, ct->typeId, ct->classMethodList, list);
	dumpMethodList(kctx, sfp, start, list);
	RESET_GCSTACK();
}
Beispiel #3
0
static void DumpOpArgument(KonohaContext *kctx, KBuffer *wb, KVirtualCodeType type, KVirtualCode *c, size_t i, KVirtualCode *vcode_start)
{
	switch(type) {
	case VMT_VOID: break;
	case VMT_ADDR:
		KLIB KBuffer_printf(kctx, wb, " L%d", (int)((KVirtualCode *)c->p[i] - vcode_start));
		break;
	case VMT_UL: {
		kfileline_t uline = (kfileline_t)c->data[i];
		KLIB KBuffer_printf(kctx, wb, " (%s:%d)", PLATAPI shortFilePath(KFileLine_textFileName(uline)), (khalfword_t)uline);
		break;
	}
	case VMT_R: {
		KLIB KBuffer_printf(kctx, wb, " sfp[%d,r=%d]", (int)c->data[i]/2, (int)c->data[i]);
		break;
	}
	case VMT_FX: {
		khalfword_t index  = (khalfword_t)c->data[i];
		khalfword_t xindex = (khalfword_t)(c->data[i] >> (sizeof(khalfword_t)*8));
		KLIB KBuffer_printf(kctx, wb, " sfp[%d,r=%d][%d]", (int)index/2, (int)index, (int)xindex);
		break;
	}
	case VMT_U:
		KLIB KBuffer_printf(kctx, wb, " i%ld", (long)c->data[i]); break;
	case VMT_C:
	case VMT_TY:
		KLIB KBuffer_printf(kctx, wb, "(%s)", KClass_text(c->ct[i])); break;
	case VMT_F:
		KLIB KBuffer_printf(kctx, wb, " function(%p)", c->p[i]); break;
	case VMT_Object: {
		kObject *o = c->o[i];
		if(IS_Method(o)) {
			kMethod *mtd = (kMethod *)o;
			KLIB KBuffer_printf(kctx, wb, " %s.%s%s", KType_text(mtd->typeId), KMethodName_Fmt2(mtd->mn));
		}
		else {
			KLIB KBuffer_printf(kctx, wb, " (%s)", KClass_text(kObject_class(o)));
			KLIB kObject_WriteToBuffer(kctx, o, 0, wb, NULL, 0);
		}
		break;
	}
	case VMT_HCACHE:
		break;
	}/*switch*/
}
Beispiel #4
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;
}
Beispiel #5
0
static KMETHOD TypeCheck_to(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck2(stmt, expr, ns, reqc);
	kNode *targetNode = SUGAR TypeCheckNodeAt(kctx, expr, 2, ns, KClass_INFER, 0);
	kNode *selfNode   = SUGAR TypeCheckNodeAt(kctx, expr, 1, ns, KClass_(targetNode->attrTypeId), TypeCheckPolicy_NoCheck);
	if(selfNode != K_NULLNODE && targetNode != K_NULLNODE) {
		KClass *selfClass = KClass_(selfNode->attrTypeId), *targetClass = KClass_(targetNode->attrTypeId);
		if(selfNode->attrTypeId == targetNode->attrTypeId || selfClass->isSubType(kctx, selfClass, targetClass)) {
			SUGAR MessageNode(kctx, selfNode, NULL, ns, InfoTag, "no need: %s to %s", KType_text(selfNode->attrTypeId), KType_text(targetNode->attrTypeId));
			KReturn(selfNode);
		}
		kNameSpace *ns = kNode_ns(stmt);
		kMethod *mtd = KLIB kNameSpace_GetCoercionMethodNULL(kctx, ns, selfClass, targetClass);
		if(mtd == NULL) {
			mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, selfClass, KMethodName_("to"), 0, KMethodMatch_CamelStyle);
			DBG_ASSERT(mtd != NULL);  // because Object.to is found.
			if(mtd->typeId != selfClass->typeId) {
				KReturn(SUGAR MessageNode(kctx, selfNode, NULL, ns, ErrTag, "undefined coercion: %s to %s", KClass_text(selfClass), KClass_text(targetClass)));
			}
		}
		KReturn(SUGAR TypeCheckMethodParam(kctx, mtd, expr, ns, targetClass));
	}
}
Beispiel #6
0
static KMETHOD TypeCheck_as(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck2(stmt, expr, ns, reqc);
	kNode *targetNode = SUGAR TypeCheckNodeAt(kctx, expr, 2, ns, KClass_INFER, 0);
	kNode *selfNode   = SUGAR TypeCheckNodeAt(kctx, expr, 1, ns, KClass_(targetNode->attrTypeId), TypeCheckPolicy_NoCheck);
	if(selfNode != K_NULLNODE && targetNode != K_NULLNODE) {
		KClass *selfClass = KClass_(selfNode->attrTypeId), *targetClass = KClass_(targetNode->attrTypeId);
		if(selfClass->typeId == targetClass->typeId || selfClass->isSubType(kctx, selfClass, targetClass)) {
			KReturn(selfNode);
		}
		if(selfClass->isSubType(kctx, targetClass, selfClass)) {
			kNameSpace *ns = kNode_ns(stmt);
			kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, KClass_Object, KMethodName_("as"), 0, KMethodMatch_CamelStyle);
			DBG_ASSERT(mtd != NULL);
			KReturn(SUGAR TypeCheckMethodParam(kctx, mtd, expr, ns, targetClass));
		}
		KReturn(SUGAR MessageNode(kctx, selfNode, NULL, ns, ErrTag, "unable to downcast: %s as %s", KType_text(selfNode->attrTypeId), KType_text(targetNode->attrTypeId)));
	}
}
static void DeclVariable(KonohaContext *kctx, kNode *stmt, kNameSpace *ns, ktypeattr_t ty, kNode *termNode)
{
	DBG_ASSERT(kNode_isSymbolTerm(termNode));
	kToken *termToken = termNode->TermToken;
	if(kNameSpace_IsTopLevel(ns)) {
		if(ns->globalObjectNULL == NULL) {
			kNodeToken_Message(kctx, stmt, termToken, ErrTag, "unavailable global variable");
			return;
		}
		kNodeToken_Message(kctx, stmt, termToken, InfoTag, "global variable %s%s has type %s", KSymbol_Fmt2(termToken->symbol), KType_text(ty));
		KLIB KClass_AddField(kctx, kObject_class(ns->globalObjectNULL), ty, termToken->symbol);
	}
	else {
		kNodeToken_Message(kctx, stmt, termToken, InfoTag, "%s%s has type %s", KSymbol_Fmt2(termToken->symbol), KType_text(ty));
		KLIB AddLocalVariable(kctx, ns, ty, termToken->symbol);
	}
}