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 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); }
//## Token Stmt.getToken(symbol key, Token def); static KMETHOD Stmt_getToken(KonohaContext *kctx, KonohaStack *sfp) { kStmt *stmt = sfp[0].asStmt; ksymbol_t key = (ksymbol_t)sfp[1].intValue; kToken *def = sfp[2].asToken; KReturn(SUGAR kStmt_GetToken(kctx, stmt, key, def)); }
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 kbool_t kBlock_declClassField(KonohaContext *kctx, kBlock *bk, kGamma *gma, KonohaClassVar *ct) { size_t i; kbool_t failedOnce = false; for(i = 0; i < kArray_size(bk->StmtList); i++) { kStmt *stmt = bk->StmtList->StmtItems[i]; if(stmt->syn->keyword == KW_TypeDeclPattern) { kshortflag_t flag = kField_Getter | kField_Setter; kToken *tk = SUGAR kStmt_GetToken(kctx, stmt, KW_TypePattern, NULL); kExpr *expr = SUGAR kStmt_GetExpr(kctx, stmt, KW_ExprPattern, NULL); if(!kStmt_AddClassField(kctx, stmt, gma, ct, flag, Token_typeLiteral(tk), expr)) { failedOnce = true; } } } return !(failedOnce); }
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); }