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); } }
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(); }
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*/ }
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; }
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)); } }
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); } }