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 Statement_for(KonohaContext *kctx, KonohaStack *sfp) { VAR_Statement(stmt, gma); DBG_P("for statement .. "); int isOkay = false; if(SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, CT_INFER, 0)) { kNameSpace *ns = Stmt_ns(stmt); kToken *TypeToken = SUGAR kStmt_GetToken(kctx, stmt, KW_TypePattern, NULL); kToken *VariableToken = SUGAR kStmt_GetToken(kctx, stmt, KW_SymbolPattern, NULL); DBG_P("typeToken=%p, varToken=%p", TypeToken, VariableToken); kExpr *IteratorExpr = SUGAR kStmt_GetExpr(kctx, stmt, KW_ExprPattern, NULL); if(!TY_isIterator(IteratorExpr->attrTypeId)) { kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, CT_(IteratorExpr->attrTypeId), MN_to(TY_Iterator), 0, MethodMatch_NoOption); if(mtd == NULL) { kStmtExpr_Message(kctx, stmt, IteratorExpr, ErrTag, "expected Iterator expression after in"); KReturnUnboxValue(false); } IteratorExpr = SUGAR new_TypedCallExpr(kctx, stmt, gma, CT_INFER, mtd, 1, IteratorExpr); kStmt_setObject(kctx, stmt, KW_ExprPattern, IteratorExpr); } kBlock *block = new_MacroBlock(kctx, stmt, new_TypeToken(kctx, ns, CT_(IteratorExpr->attrTypeId)), new_ParsedExprToken(kctx, ns, IteratorExpr), TypeToken, VariableToken); kStmt *IfStmt = block->StmtList->StmtItems[1]; // @see macro; kStmt_appendBlock(kctx, IfStmt, SUGAR kStmt_GetBlock(kctx, stmt, ns, KW_BlockPattern, NULL)); kStmt_Set(CatchBreak, IfStmt, true); kStmt_Set(CatchContinue, IfStmt, true); isOkay = SUGAR kBlock_TypeCheckAll(kctx, block, gma); if(isOkay) { kStmt_typed(IfStmt, LOOP); kStmt_setObject(kctx, stmt, KW_BlockPattern, block); kStmt_typed(stmt, BLOCK); } } KReturnUnboxValue(isOkay); }
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)); }
static kBlock* kStmt_ParseClassBlockNULL(KonohaContext *kctx, kStmt *stmt, kToken *tokenClassName) { kBlock *bk = NULL; kToken *blockToken = (kToken *)kStmt_GetObject(kctx, stmt, KW_BlockPattern, NULL); if(blockToken != NULL && blockToken->resolvedSyntaxInfo->keyword == KW_BlockPattern) { const char *cname = S_text(tokenClassName->text); TokenSeq range = {Stmt_ns(stmt), GetSugarContext(kctx)->preparedTokenList}; TokenSeq_Push(kctx, range); SUGAR TokenSeq_Tokenize(kctx, &range, S_text(blockToken->text), blockToken->uline); { TokenSeq sourceRange = {range.ns, range.tokenList, range.endIdx}; kToken *prevToken = blockToken; int i; for(i = range.beginIdx; i < range.endIdx; i++) { kToken *tk = range.tokenList->TokenItems[i]; if(tk->hintChar == '(' && prevToken->unresolvedTokenType == TokenType_SYMBOL && strcmp(cname, S_text(prevToken->text)) == 0) { kTokenVar *newToken = new_(TokenVar, TokenType_SYMBOL, sourceRange.tokenList); KFieldSet(newToken, newToken->text, SYM_s(MN_new)); } KLIB kArray_Add(kctx, sourceRange.tokenList, tk); prevToken = tk; } TokenSeq_end(kctx, (&sourceRange)); bk = SUGAR new_kBlock(kctx, stmt/*parent*/, NULL, &sourceRange); KLIB kObject_setObject(kctx, stmt, KW_BlockPattern, TY_Block, bk); } TokenSeq_Pop(kctx, range); } return bk; }
//## Expr Stmt.newUntypedCallStyleExpr(Token token, Expr expr1); static KMETHOD Stmt_newUntypedCallStyleExpr2(KonohaContext *kctx, KonohaStack *sfp) { kStmt *stmt = sfp[0].asStmt; kToken *token = sfp[1].asToken; kExpr *expr1 = sfp[2].asExpr; SugarSyntax *syn = SYN_(Stmt_ns(stmt), KW_ExprMethodCall); KReturn(SUGAR new_UntypedCallStyleExpr(kctx, syn, 2, token, expr1)); }
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]); } } }
//## Block Stmt.newBlock(String macro); static KMETHOD Stmt_newBlock(KonohaContext *kctx, KonohaStack *sfp) { kStmt *stmt = sfp[0].asStmt; kString *macro = sfp[1].asString; TokenSeq source = {Stmt_ns(stmt), GetSugarContext(kctx)->preparedTokenList/*TODO: set appropriate tokenList to TokenSeq*/}; TokenSeq_Push(kctx, source); SUGAR TokenSeq_Tokenize(kctx, &source, S_text(macro), 0); kBlock *bk = SUGAR new_kBlock(kctx, stmt, NULL, &source); TokenSeq_Pop(kctx, source); KReturn(bk); }
//## Expr Stmt.newTypedCallExpr(Gamma gma, cid typeId, symbol methodName, Expr firstExpr); static KMETHOD Stmt_newTypedCallExpr1(KonohaContext *kctx, KonohaStack *sfp) { kStmt *stmt = sfp[0].asStmt; kGamma *gma = sfp[1].asGamma; ktype_t cid = (ktype_t)sfp[2].intValue; ksymbol_t methodName = (ksymbol_t)sfp[3].intValue; kExpr *firstExpr = sfp[4].asExpr; kMethod *method = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, Stmt_ns(stmt), cid, methodName, 1); if(method == NULL) { KReturn(KNULL(Expr)); } KReturn(SUGAR new_TypedCallExpr(kctx, stmt, gma, cid, method, 1, firstExpr)); }
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*/)); } } }
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); }
static kStmt* TypeDeclAndMakeSetter(KonohaContext *kctx, kStmt *stmt, kGamma *gma, ktype_t ty, kExpr *termExpr, kExpr *valueExpr, kObject *scr) { kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = Object_newProtoSetterNULL(kctx, stmt, scr, ty, termExpr->termToken->resolvedSymbol); if(mtd != NULL) { kExpr *recvExpr = new_ConstValueExpr(kctx, O_typeId(scr), scr); kExpr *setterExpr = SUGAR new_TypedCallExpr(kctx, stmt, gma, TY_void, mtd, 2, recvExpr, valueExpr); kStmt *newstmt = new_(Stmt, stmt->uline, OnGcStack); kStmt_setsyn(newstmt, SYN_(ns, KW_ExprPattern)); KLIB kObject_setObject(kctx, newstmt, KW_ExprPattern, TY_Expr, setterExpr); return newstmt; } return NULL; }
static KMETHOD Statement_GlobalTypeDecl(KonohaContext *kctx, KonohaStack *sfp) { VAR_Statement(stmt, gma); kbool_t result = false; kNameSpace *ns = Stmt_ns(stmt); KMakeTrace(trace, sfp); trace->pline = stmt->uline; if(kNameSpace_InitGlobalObject(kctx, ns, trace)) { kToken *tk = SUGAR kStmt_GetToken(kctx, stmt, KW_TypePattern, NULL); kExpr *expr = SUGAR kStmt_GetExpr(kctx, stmt, KW_ExprPattern, NULL); kStmt *lastStmt = stmt; result = SUGAR kStmt_DeclType(kctx, stmt, gma, tk->resolvedTypeId, expr, ns->globalObjectNULL_OnList, TypeDeclAndMakeSetter, &lastStmt); } kStmt_done(kctx, stmt); KReturnUnboxValue(result); }
static KMETHOD TypeCheck_Getter(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kToken *tkN = expr->cons->TokenItems[0]; ksymbol_t fn = tkN->resolvedSymbol; kExpr *self = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 1, gma, TY_var, 0); kNameSpace *ns = Stmt_ns(stmt); if(self != K_NULLEXPR) { kMethod *mtd = KLIB kNameSpace_GetGetterMethodNULL(kctx, ns, self->ty, fn, TY_var); if(mtd != NULL) { KFieldSet(expr->cons, expr->cons->MethodItems[0], mtd); KReturn(SUGAR kStmtkExpr_TypeCheckCallParam(kctx, stmt, expr, mtd, gma, reqty)); } SUGAR kStmt_Message2(kctx, stmt, tkN, ErrTag, "undefined field: %s", S_text(tkN->text)); } }
static KMETHOD TypeCheck_as(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kExpr *targetExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 2, gma, TY_var, 0); kExpr *selfExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 1, gma, targetExpr->ty, TypeCheckPolicy_NOCHECK); if(selfExpr != K_NULLEXPR && targetExpr != K_NULLEXPR) { KonohaClass *selfClass = CT_(selfExpr->ty), *targetClass = CT_(targetExpr->ty); if(selfExpr->ty == targetExpr->ty || selfClass->isSubType(kctx, selfClass, targetClass)) { KReturn(selfExpr); } if(selfClass->isSubType(kctx, targetClass, selfClass)) { kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, TY_Object, MN_("as"), 0); DBG_ASSERT(mtd != NULL); KReturn(SUGAR kStmtkExpr_TypeCheckCallParam(kctx, stmt, expr, mtd, gma, targetClass->typeId)); } KReturn(kStmtExpr_Message(kctx, stmt, selfExpr, ErrTag, "unable to downcast: %s as %s", TY_t(selfExpr->ty), TY_t(targetExpr->ty))); } }
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 TypeCheck_InstanceOf(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kExpr *selfExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 1, gma, TY_var, 0); kExpr *targetExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 2, gma, TY_var, 0); if(selfExpr != K_NULLEXPR && targetExpr != K_NULLEXPR) { KonohaClass *selfClass = CT_(selfExpr->ty), *targetClass = CT_(targetExpr->ty); if(CT_is(Final, selfClass)) { kbool_t staticSubType = (selfClass == targetClass || selfClass->isSubType(kctx, selfClass, targetClass)); KReturn(SUGAR kExpr_SetUnboxConstValue(kctx, expr, TY_boolean, staticSubType)); } kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, TY_Object, MN_("<:"), 1); DBG_ASSERT(mtd != NULL); KFieldSet(expr->cons, expr->cons->MethodItems[0], mtd); kExpr *classValue = SUGAR kExpr_SetConstValue(kctx, expr->cons->ExprItems[2], targetExpr->ty, KLIB Knull(kctx, targetClass)); KFieldSet(expr->cons, expr->cons->ExprItems[2], classValue); KReturn(SUGAR kStmtkExpr_TypeCheckCallParam(kctx, stmt, expr, mtd, gma, TY_boolean)); } }
static kMethod *Object_newProtoSetterNULL(KonohaContext *kctx, kStmt *stmt, kObject *o, ktype_t ty, ksymbol_t symbol) { ktype_t cid = O_typeId(o); kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetSetterMethodNULL(kctx, ns, cid, symbol, TY_var); if(mtd != NULL) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "already defined name: %s", SYM_t(symbol)); return NULL; } mtd = KLIB kNameSpace_GetGetterMethodNULL(kctx, ns, cid, symbol, TY_var); if(mtd != NULL && Method_returnType(mtd) != ty) { SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "differently defined name: %s", SYM_t(symbol)); return NULL; } int flag = kField_Setter; if(mtd == NULL) { // no getter flag |= kField_Getter; } KLIB KonohaClass_AddField(kctx, O_ct(o), flag, ty, symbol); return KLIB kNameSpace_GetSetterMethodNULL(kctx, ns, cid, symbol, ty); }
static KMETHOD TypeCheck_to(KonohaContext *kctx, KonohaStack *sfp) { VAR_TypeCheck(stmt, expr, gma, reqty); kExpr *targetExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 2, gma, TY_var, 0); kExpr *selfExpr = SUGAR kStmt_TypeCheckExprAt(kctx, stmt, expr, 1, gma, targetExpr->ty, TypeCheckPolicy_NOCHECK); if(selfExpr != K_NULLEXPR && targetExpr != K_NULLEXPR) { KonohaClass *selfClass = CT_(selfExpr->ty), *targetClass = CT_(targetExpr->ty); if(selfExpr->ty == targetExpr->ty || selfClass->isSubType(kctx, selfClass, targetClass)) { kStmtExpr_Message(kctx, stmt, selfExpr, InfoTag, "no need: %s to %s", TY_t(selfExpr->ty), TY_t(targetExpr->ty)); KReturn(selfExpr); } kNameSpace *ns = Stmt_ns(stmt); kMethod *mtd = KLIB kNameSpace_GetCoercionMethodNULL(kctx, ns, selfExpr->ty, targetExpr->ty); if(mtd == NULL) { mtd = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, selfExpr->ty, MN_("to"), 0); DBG_ASSERT(mtd != NULL); // because Object.to is found. if(mtd->typeId != selfExpr->ty) { KReturn(kStmtExpr_Message(kctx, stmt, selfExpr, ErrTag, "undefined coercion: %s to %s", TY_t(selfExpr->ty), TY_t(targetExpr->ty))); } } KReturn(SUGAR kStmtkExpr_TypeCheckCallParam(kctx, stmt, expr, mtd, gma, targetClass->typeId)); } }
static kBlock *new_MacroBlock(KonohaContext *kctx, kStmt *stmt, kToken *IteratorTypeToken, kToken *IteratorExprToken, kToken *TypeToken, kToken *VariableToken) { kNameSpace *ns = Stmt_ns(stmt); TokenSeq source = {ns, GetSugarContext(kctx)->preparedTokenList}; TokenSeq_Push(kctx, source); /* FIXME(imasahiro) * we need to implement template as Block * "T _ = E; if(_.hasNext()) { N = _.next(); }" * ^^^^^^^^^^^^^^^^^ */ SUGAR TokenSeq_Tokenize(kctx, &source, "T _ = E; if(_.hasNext()) N = _.next();", 0); MacroSet macroSet[4] = {{0, NULL, 0, 0}}; MacroSet_setTokenAt(kctx, macroSet, 0, source.tokenList, "T", IteratorTypeToken, NULL); MacroSet_setTokenAt(kctx, macroSet, 1, source.tokenList, "E", IteratorExprToken, NULL); if(TypeToken == NULL) { MacroSet_setTokenAt(kctx, macroSet, 2, source.tokenList, "N", VariableToken, NULL); } else { MacroSet_setTokenAt(kctx, macroSet, 2, source.tokenList, "N", TypeToken, VariableToken, NULL); } kBlock *bk = SUGAR new_kBlock(kctx, stmt, macroSet, &source); TokenSeq_Pop(kctx, source); return bk; }
static KMETHOD Statement_ConstDecl(KonohaContext *kctx, KonohaStack *sfp) { VAR_Statement(stmt, gma); kNameSpace *ns = Stmt_ns(stmt); kToken *SymbolToken = SUGAR kStmt_GetToken(kctx, stmt, KW_SymbolPattern, NULL); ksymbol_t unboxKey = SymbolToken->resolvedSymbol; kbool_t result = SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, TY_var, TypeCheckPolicy_CONST); if(result) { kExpr *ConstExpr = SUGAR kStmt_GetExpr(kctx, stmt, KW_ExprPattern, NULL); ktype_t type = ConstExpr->ty; uintptr_t unboxValue; result = false; if(ConstExpr->build == TEXPR_NULL) { // const C = String type = VirtualType_KonohaClass; unboxValue = (uintptr_t)(CT_(ConstExpr->ty)); result = true; } else if(ConstExpr->build == TEXPR_CONST) { // const C = "1" unboxValue = (uintptr_t)ConstExpr->objectConstValue; result = true; } else if(ConstExpr->build == TEXPR_NCONST) { // const c = 1 unboxValue = ConstExpr->unboxConstValue; result = true; } if(result) { KMakeTraceUL(trace, sfp, stmt->uline); result = KLIB kNameSpace_SetConstData(kctx, ns, unboxKey, type, unboxValue, trace); } else { kStmt_Message(kctx, stmt, ErrTag, "constant value is expected: %s%s", PSYM_t(unboxKey)); } } kStmt_done(kctx, stmt); KReturnUnboxValue(result); }
static KMETHOD Statement_import(KonohaContext *kctx, KonohaStack *sfp) { int ret = false; VAR_Statement(stmt, gma); kTokenArray *tokenList = (kTokenArray *) kStmt_GetObjectNULL(kctx, stmt, KW_TokenPattern); if(tokenList == NULL) { KReturnUnboxValue(false); } kNameSpace *ns = Stmt_ns(stmt); SugarSyntaxVar *syn = (SugarSyntaxVar *) SYN_(ns, KW_ExprMethodCall); kExpr *expr; kTokenVar *tkImport = /*G*/new_(TokenVar, 0, OnGcStack); tkImport->resolvedSymbol = MN_("import"); if(IS_Token(tokenList)) { kTokenArray *list = ((kToken *) tokenList)->subTokenList; if(IS_String(list)) { /* case: import cstyle; */ kString *pkgname = (kString *) list; expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname); } else if(kArray_size(list) == 1) { /* case : import("konoha.import"); */ kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text); expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 3, tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)), param0); } else if(kArray_size(list) == 2) { /* case : import("konoha.import", "import"); */ kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text); kExpr *param1 = makeStringConstValue(kctx, list->TokenItems[1]->text); expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 4, tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)), param0, param1); } else { KReturnUnboxValue(false); } } else { KGrowingBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); /* case : import konoha.import */ ksymbol_t star = SYM_("*"); size_t i = 0; if(i + 2 < kArray_size(tokenList)) { for (; i < kArray_size(tokenList)-1; i+=2) { /* name . */ kToken *tk = tokenList->TokenItems[i+0]; if(i+2 < kArray_size(tokenList)) { kToken *startTk = tokenList->TokenItems[i+2]; if(startTk->resolvedSyntaxInfo->keyword == star) { break; } } KLIB KBuffer_Write(kctx, &wb, S_text(tk->text), S_size(tk->text)); KLIB KBuffer_Write(kctx, &wb, ".", 1); } } kString *name = tokenList->TokenItems[i]->text; KLIB KBuffer_Write(kctx, &wb, S_text(name), S_size(name)); kString *pkgname = KLIB new_kString(kctx, OnGcStack, KLIB KBuffer_Stringfy(kctx, &wb, 1), KBuffer_bytesize(&wb), 0); expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname); } KLIB kObjectProto_SetObject(kctx, stmt, KW_ExprPattern, TY_Expr, expr); ret = SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, CT_void, TypeCheckPolicy_ALLOWVOID); if(ret) { kStmt_typed(stmt, EXPR); } KReturnUnboxValue(ret); }