//## method int Array.lastIndexOf(T0 a1); static KMETHOD Array_lastIndexOf(KonohaContext *kctx, KonohaStack *sfp) { kArray *a = sfp[0].asArray; kint_t res = -1; size_t i = 0; if(kArray_isUnboxData(a)) { uintptr_t nv = sfp[1].unboxValue; for(i = kArray_size(a)- 1; i != 0; i--) { if(a->unboxItems[i] == nv) { break; } } } else { //TODO: Need to implement Object compareTo; kObject *o = sfp[1].asObject; for(i = kArray_size(a)- 1; i != 0; i--) { // KMakeTrace(trace, sfp); // KLIB KonohaRuntime_raise(kctx, EXPT_("NotImplemented"), NULL, trace); if(O_ct(o)->compareObject(a->ObjectItems[i], o) == 0) { break; } } } res = i; KReturnUnboxValue(res); }
// for select :: fd_set* => kArray* static void fromFd(KonohaContext *kctx, fd_set* s, kArray *a ) { if(s != NULL && kArray_size(a) > 0 ) { size_t indx; for(indx = 0; indx < kArray_size(a); indx++ ) { if(!FD_ISSET(WORD2INT(a->kintItems[indx]), s) ) { // kArray_remove(a, indx); } } } }
static KMETHOD Expression_Bracket(KonohaContext *kctx, KonohaStack *sfp) { VAR_Expression(stmt, tokenList, beginIdx, operatorIdx, endIdx); KonohaClass *genericsClass = NULL; kNameSpace *ns = Stmt_ns(stmt); int nextIdx = SUGAR TokenUtils_ParseTypePattern(kctx, ns, tokenList, beginIdx, endIdx, &genericsClass); if(nextIdx != -1) { // to avoid Func[T] KReturn(SUGAR kStmt_ParseOperatorExpr(kctx, stmt, tokenList->TokenItems[beginIdx]->resolvedSyntaxInfo, tokenList, beginIdx, beginIdx, endIdx)); } kToken *currentToken = tokenList->TokenItems[operatorIdx]; if(beginIdx == operatorIdx) { /* transform '[ Value1, Value2, ... ]' to '(Call Untyped new (Value1, Value2, ...))' */ DBG_ASSERT(currentToken->resolvedSyntaxInfo->keyword == KW_BracketGroup); kExpr *arrayExpr = SUGAR new_UntypedCallStyleExpr(kctx, currentToken->resolvedSyntaxInfo, 2, currentToken, K_NULL); KReturn(SUGAR kStmt_AddExprParam(kctx, stmt, arrayExpr, currentToken->subTokenList, 0, kArray_size(currentToken->subTokenList), NULL)); } else { kExpr *leftExpr = SUGAR kStmt_ParseExpr(kctx, stmt, tokenList, beginIdx, operatorIdx, NULL); if(leftExpr == K_NULLEXPR) { KReturn(leftExpr); } if(leftExpr->syn->keyword == SYM_("new")) { // new int[100], new int[](); DBG_P("cur:%d, beg:%d, endIdx:%d", operatorIdx, beginIdx, endIdx); size_t subTokenSize = kArray_size(currentToken->subTokenList); if(subTokenSize == 0) { /* transform 'new Type0 [ ]' => (Call Type0 new) */ kExpr_Setsyn(leftExpr, SYN_(ns, KW_ExprMethodCall)); } else { /* transform 'new Type0 [ Type1 ] (...) => new 'Type0<Type1>' (...) */ KonohaClass *classT0 = NULL; kArray *subTokenList = currentToken->subTokenList; int beginIdx = -1; if(kArray_size(subTokenList) > 0) { beginIdx = SUGAR TokenUtils_ParseTypePattern(kctx, ns, subTokenList, 0, kArray_size(subTokenList), &classT0); } beginIdx = (beginIdx == -1) ? 0 : beginIdx; kExpr_Setsyn(leftExpr, SYN_(ns, KW_ExprMethodCall)); DBG_P("currentToken->subtoken:%d", kArray_size(subTokenList)); leftExpr = SUGAR kStmt_AddExprParam(kctx, stmt, leftExpr, subTokenList, beginIdx, kArray_size(subTokenList), "["); } } else { /* transform 'Value0 [ Value1 ]=> (Call Value0 get (Value1)) */ kTokenVar *tkN = /*G*/new_(TokenVar, 0, OnGcStack); tkN->resolvedSymbol= MN_toGETTER(0); tkN->uline = currentToken->uline; SugarSyntax *syn = SYN_(Stmt_ns(stmt), KW_ExprMethodCall); leftExpr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 2, tkN, leftExpr); leftExpr = SUGAR kStmt_AddExprParam(kctx, stmt, leftExpr, currentToken->subTokenList, 0, kArray_size(currentToken->subTokenList), "["); } KReturn(SUGAR kStmt_RightJoinExpr(kctx, stmt, leftExpr, tokenList, operatorIdx + 1, endIdx)); } }
static KMETHOD Expression_Defined(KonohaContext *kctx, KonohaStack *sfp) { VAR_Expression(stmt, tokenList, beginIdx, currentIdx, endIdx); if(beginIdx == currentIdx && beginIdx + 1 < endIdx) { kTokenVar *definedToken = tokenList->TokenVarItems[beginIdx]; // defined kTokenVar *pToken = tokenList->TokenVarItems[beginIdx+1]; if(IS_Array(pToken->subTokenList)) { kExpr *expr = SUGAR new_UntypedCallStyleExpr(kctx, definedToken->resolvedSyntaxInfo, 1, definedToken); filterArrayList(kctx, Stmt_ns(stmt), pToken->subTokenList, 0, kArray_size(pToken->subTokenList)); KReturn(SUGAR kStmt_AddExprParam(kctx, stmt, expr, pToken->subTokenList, 0, kArray_size(pToken->subTokenList), 0/*isAllowEmpty*/)); } } }
// for select static int getArrayMax(kArray *a) { int ret = -1; if(kArray_size(a) > 0) { size_t cnt; int fd; for(cnt = 0; cnt < kArray_size(a); cnt++) { if((fd = WORD2INT(a->kintItems[cnt])) > ret) { ret = fd; } } } return ret; }
static void kMethod_genCode(KonohaContext *kctx, kMethod *mtd, kBlock *bk) { DBG_P("START CODE GENERATION.."); INIT_GCSTACK(); if(ctxcode == NULL) { kmodcode->h.setup(kctx, NULL, 0); } KLIB kMethod_setFunc(kctx, mtd, MethodFunc_runVirtualMachine); DBG_ASSERT(kArray_size(ctxcode->codeList) == 0); kBasicBlock* lbINIT = new_BasicBlockLABEL(kctx); kBasicBlock* lbBEGIN = new_BasicBlockLABEL(kctx); ctxcode->lbEND = new_BasicBlockLABEL(kctx); PUSH_GCSTACK(lbINIT); PUSH_GCSTACK(lbBEGIN); PUSH_GCSTACK(ctxcode->lbEND); ctxcode->currentWorkingBlock = lbINIT; // BUILD_pushLABEL(kctx, NULL, lbBEGIN, lbEND); ASM(THCODE, _THCODE); ASM(CHKSTACK, 0); ASM_LABEL(kctx, lbBEGIN); BLOCK_asm(kctx, bk, 0); ASM_LABEL(kctx, ctxcode->lbEND); if (mtd->mn == MN_new) { ASM(NMOV, OC_(K_RTNIDX), OC_(0), CT_(mtd->typeId)); // FIXME: Type 'This' must be resolved } ASM(RET); assert(ctxcode->lbEND);/* scan-build: remove warning */ // BUILD_popLABEL(kctx); BUILD_compile(kctx, mtd, lbINIT, ctxcode->lbEND); ctxcode->lbEND = NULL; RESET_GCSTACK(); }
static void MacroSet_setTokenAt(KonohaContext *kctx, MacroSet *macroSet, int index, kArray *tokenList, const char *symbol, ...) { DBG_ASSERT(macroSet[index].tokenList == NULL); macroSet[index].symbol = KLIB Ksymbol(kctx, symbol, strlen(symbol), StringPolicy_TEXT|StringPolicy_ASCII, _NEWID); macroSet[index].tokenList = tokenList; macroSet[index].beginIdx = kArray_size(tokenList); kToken *tk; va_list ap; va_start(ap , symbol); while((tk = va_arg(ap, kToken *)) != NULL) { DBG_ASSERT(IS_Token(tk)); KLIB kArray_Add(kctx, tokenList, tk); } va_end(ap); macroSet[index].endIdx = kArray_size(tokenList); }
static kBasicBlock* new_BasicBlockLABEL(KonohaContext *kctx) { kBasicBlock *bb = new_(BasicBlock, 0); bb->id = kArray_size(ctxcode->codeList); KLIB kArray_add(kctx, ctxcode->codeList, bb); return bb; }
static void dumpMethodList(KonohaContext *kctx, KonohaStack *sfp, size_t start, kArray *list) { size_t i; for(i = start; i < kArray_size(list); i++) { dumpMethod(kctx, sfp, list->MethodItems[i]); } }
static KMETHOD TypeCheck_Bracket(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); // [0] currentToken, [1] NULL, [2] .... size_t i; KonohaClass *requestClass = CT_(reqty); KonohaClass *paramType = (requestClass->baseTypeId == TY_Array) ? CT_(requestClass->p0) : CT_INFER; for(i = 2; i < kArray_size(expr->cons); i++) { kExpr *typedExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, i, gma, paramType, 0); if(typedExpr == K_NULLEXPR) { KReturn(typedExpr); } if(paramType->typeId == TY_var) { paramType = CT_(typedExpr->attrTypeId); } } if(requestClass->baseTypeId != TY_Array) { requestClass = (paramType->typeId == TY_var) ? CT_Array : CT_p0(kctx, CT_Array, paramType->typeId); } kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, Stmt_ns(stmt), CT_Array, MN_("[]"), -1, MethodMatch_NoOption); DBG_ASSERT(mtd != NULL); KFieldSet(expr, expr->cons->MethodItems[0], mtd); KFieldSet(expr, expr->cons->ExprItems[1], SUGAR kExpr_SetVariable(kctx, NULL, gma, TEXPR_NEW, requestClass->typeId, kArray_size(expr->cons) - 2)); KReturn(Expr_typed(expr, TEXPR_CALL, requestClass->typeId)); }
//## method Array<T> Array.concat(Array<T> a1); static KMETHOD Array_concat(KonohaContext *kctx, KonohaStack *sfp) { kArray *a0 = sfp[0].asArray; kArray *a1 = sfp[1].asArray; size_t i; if(kArray_isUnboxData(a1)) { for (i = 0; i < kArray_size(a1); i++){ UnboxArray_Add(kctx, a0, a1->unboxItems[i]); } } else { for (i = 0; i < kArray_size(a1); i++){ KLIB kArray_Add(kctx, a0, a1->ObjectItems[i]); } } KReturn(a0); }
static SugarSyntaxVar *kNameSpace_guessSyntaxFromTokenList(KonohaContext *kctx, kNameSpace *ns, kArray *tokenList) { int beginIdx = 0, endIdx = kArray_size(tokenList); if(beginIdx < endIdx) { ksymbol_t keyword = tokenList->TokenItems[beginIdx]->resolvedSyntaxInfo->keyword; if(keyword == KW_TextPattern) { ksymbol_t kw; if(isSubKeyword(kctx, tokenList, beginIdx, endIdx)) { char buf[256]; PLATAPI snprintf_i(buf, sizeof(buf), "%s_%s", S_text(tokenList->TokenItems[beginIdx]->text), S_text(tokenList->TokenItems[beginIdx+1]->text)); kw = ksymbolA((const char *)buf, strlen(buf), SYM_NEWID); } else { kw = ksymbolA(S_text(tokenList->TokenItems[beginIdx]->text), S_size(tokenList->TokenItems[beginIdx]->text), SYM_NEWID); } return (SugarSyntaxVar *)NEWSYN_(ns, kw); } else if(keyword == KW_DOLLAR) { // $TokenPattern char buf[256]; PLATAPI snprintf_i(buf, sizeof(buf), "$%s", S_text(tokenList->TokenItems[beginIdx+1]->text)); ksymbol_t kw = ksymbolA((const char *)buf, strlen(buf), SYM_NEWID); return (SugarSyntaxVar *)NEWSYN_(ns, kw); } } return NULL; }
static void dumpMethodList(CTX, ksfp_t *sfp, size_t start, kArray *list) { size_t i; for(i = start; i < kArray_size(list); i++) { dumpMethod(_ctx, sfp, list->methods[i]); } }
// for select :: kArray* => fd_set* static fd_set* toFd(fd_set* s, kArray *a ) { if(s == NULL || kArray_size(a) <= 0) { return NULL; } FD_ZERO(s); size_t indx; int fd; for(indx = 0; indx < kArray_size(a); indx++ ) { fd = WORD2INT(a->kintItems[indx]); if((fd >= 0) && (fd < FD_SETSIZE)) { FD_SET(fd, s); } } return s; }
static void Array_setNextResultUnbox(KonohaContext *kctx, KonohaStack* sfp) { kIterator *itr = (kIterator *)sfp[0].asObject; size_t n = itr->current_pos; itr->current_pos += 1; DBG_ASSERT(n < kArray_size(itr->arrayList)); KReturnUnboxValue(itr->arrayList->kintItems[n]); }
static KMETHOD TypeCheck_RegExp(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kToken *tk = expr->termToken; kRegExp *r = new_(RegExp, NULL, OnGcStack); DBG_ASSERT(kArray_size(tk->subTokenList) == 2); RegExp_set(kctx, r, tk->subTokenList->stringItems[0], tk->subTokenList->stringItems[1]); KReturn(SUGAR kExpr_setConstValue(kctx, expr, TY_RegExp, UPCAST(r))); }
static void copyMethodList(CTX, kcid_t cid, kArray *s, kArray *d) { size_t i; for(i = 0; i < kArray_size(s); i++) { kMethod *mtd = s->methods[i]; if(mtd->cid != cid) continue; kArray_add(d, mtd); } }
static void copyMethodList(KonohaContext *kctx, ktype_t cid, kArray *s, kArray *d) { size_t i; for(i = 0; i < kArray_size(s); i++) { kMethod *mtd = s->MethodItems[i]; if(mtd->typeId != cid) continue; KLIB kArray_Add(kctx, d, mtd); } }
static void UnboxArray_Add(KonohaContext *kctx, kArray *o, uintptr_t value) { size_t asize = kArray_size(o); struct _kAbstractArray *a = (struct _kAbstractArray *)o; UnboxArray_ensureMinimumSize(kctx, a, asize+1); DBG_ASSERT(a->a.ObjectItems[asize] == NULL); o->unboxItems[asize] = value; kArray_SetSize(o, (asize+1)); }
static kbool_t CollectLocalVar_VisitFunctionNode(KVISITOR_PARAM) { size_t i, ParamSize = kArray_size(node->NodeList)-2; for(i = 0; i < ParamSize; i++) { kUntypedNode *expr = kUntypedNode_At(node, i+2); KLIB VisitNode(kctx, builder, expr, thunk); } return true; }
static void kStmt_appendBlock(KonohaContext *kctx, kStmt *stmt, kBlock *bk) { if(bk != NULL) { kBlock *block = SUGAR kStmt_GetBlock(kctx, stmt, Stmt_ns(stmt), KW_BlockPattern, NULL); size_t i; for(i = 0; i < kArray_size(bk->StmtList); i++) { KLIB kArray_Add(kctx, block->StmtList, bk->StmtList->StmtItems[i]); } } }
static KMETHOD Array_unshift(KonohaContext *kctx, KonohaStack *sfp) { kArray *a = sfp[0].asArray; if(kArray_isUnboxData(a)) { UnboxArray_insert(kctx, a, 0, sfp[1].unboxValue); } else { KLIB kArray_Insert(kctx, a, 0, sfp[1].asObject); } KReturnUnboxValue(kArray_size(a)); }
static void DumpVisitor_visitOrExpr(KonohaContext *kctx, IRBuilder *self, kExpr *expr) { unsigned i; emit_string("OR", "", "", DUMPER(self)->indent); DUMPER(self)->indent++; for (i = 1; i < kArray_size(expr->cons); ++i) { handleExpr(kctx, self, kExpr_at(expr, i)); } DUMPER(self)->indent--; }
static size_t kBlock_countFieldSize(KonohaContext *kctx, kBlock *bk) { size_t i, c = 0; if(bk != NULL) { for(i = 0; i < kArray_size(bk->StmtList); i++) { kStmt *stmt = bk->StmtList->StmtItems[i]; DBG_P("stmt->keyword=%s%s", PSYM_t(stmt->syn->keyword)); if(stmt->syn->keyword == KW_TypeDeclPattern) { kExpr *expr = SUGAR kStmt_GetExpr(kctx, stmt, KW_ExprPattern, NULL); if(expr->syn->keyword == KW_COMMA) { c += (kArray_size(expr->cons) - 1); } else if(expr->syn->keyword == KW_LET || Expr_isTerm(expr)) { c++; } } } } return c; }
static void kNameSpace_SetStaticFunction(KonohaContext *kctx, kNameSpace *ns, kArray *list, ktype_t cid, KTraceInfo *trace) { size_t i; for(i = 0; i < kArray_size(list); i++) { kMethod *mtd = list->MethodItems[i]; if(kMethod_is(Static, mtd) && mtd->typeId == cid) { uintptr_t mtdinfo = ((uintptr_t)cid | (((uintptr_t)mtd->mn) << (sizeof(ktype_t) * 8))); KLIB kNameSpace_SetConstData(kctx, ns, mtd->mn, VirtualType_StaticMethod, mtdinfo, trace); } } }
static KMETHOD Statement_syntax(KonohaContext *kctx, KonohaStack *sfp) { kbool_t r = 0; VAR_Statement(stmt, gma); kTokenArray *tokenList = (kTokenArray *)kStmt_GetObject(kctx, stmt, KW_TokenPattern, NULL); if(tokenList == NULL) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "empty syntax"); } if(tokenList != NULL) { if(!IS_Array(tokenList)) { // create tokenList from a Token kTokenArray *a = new_(TokenArray, 0, OnGcStack); KLIB kArray_Add(kctx, a, tokenList); tokenList = a; } DBG_ASSERT(IS_Array(tokenList)); kNameSpace *ns = Stmt_ns(stmt); SugarSyntaxVar *syn = kNameSpace_guessSyntaxFromTokenList(kctx, ns, tokenList); if(syn != NULL) { if(syn->syntaxPatternListNULL_OnList != NULL) { SUGAR kStmt_Message2(kctx, stmt, NULL, InfoTag, "oveloading syntax: %s%s", PSYM_t(syn->keyword)); } else { syn->syntaxPatternListNULL_OnList = new_(TokenArray, 0, ns->NameSpaceConstList); } TokenSeq tokens = {ns, tokenList, 0, kArray_size(tokenList)}; // Referred to kNameSpace_ParseSyntaxPattern in ast.h. kArray *patternList = syn->syntaxPatternListNULL_OnList; size_t firstPatternIdx = kArray_size(patternList); SUGAR kArray_AddSyntaxRule(kctx, patternList, &tokens); if(firstPatternIdx < kArray_size(patternList)) { kToken *firstPattern = patternList->TokenItems[firstPatternIdx]; if(kToken_isFirstPattern(firstPattern)) { kNameSpace_AppendArrayRef(kctx, ns, &((kNameSpaceVar *)ns)->stmtPatternListNULL_OnList, UPCAST(firstPattern)); } } r = 1; } kStmt_done(kctx, stmt); } KReturnUnboxValue(r); }
static KMETHOD Array_Pop(KonohaContext *kctx, KonohaStack *sfp) { kArray *a = sfp[0].asArray; if(kArray_size(a) == 0) KReturnDefaultValue(); size_t n = kArray_size(a) - 1; if(kArray_isUnboxData(a)) { uintptr_t v = a->unboxItems[n]; a->unboxItems[n] = 0; kArray_SetSize(a, n); KReturnUnboxValue(v); } else { struct _kAbstractArray *a2 = (struct _kAbstractArray *)a; kObject *value = a2->a.ObjectItems[n]; kObject** null = NULL; KFieldInit(a2, a2->a.ObjectItems[n], null); a2->a.bytesize = n * sizeof(uintptr_t); KReturn(value); } }
//## @Immutable method T0 Array.get(Int n); static KMETHOD Array_get(KonohaContext *kctx, KonohaStack *sfp) { kArray *a = sfp[0].asArray; size_t n = (size_t)sfp[1].intValue; KCheckIndex(n, kArray_size(a)); if(kArray_isUnboxData(a)) { KReturnUnboxValue(a->unboxItems[n]); } else { KReturn(a->ObjectItems[n]); } }
//## method void Array.set(Int n, T0 v); static KMETHOD Array_set(KonohaContext *kctx, KonohaStack *sfp) { kArray *a = sfp[0].asArray; size_t n = (size_t)sfp[1].intValue; KCheckIndex(n, kArray_size(a)); if(kArray_isUnboxData(a)) { a->unboxItems[n] = sfp[2].unboxValue; } else { KFieldSet(a, a->ObjectItems[n], sfp[2].asObject); } }
kString *knh_getURN(CTX, kfileid_t fileid) { size_t n = URI_UNMASK(fileid); kArray *a = ctx->share->urns; if(n < kArray_size(a)) { return (kString*)(a)->list[n]; } else { DBG_ASSERT(fileid == URI_unknown); return TS_EMPTY; } }