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); }
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 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 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); }