static void kNode_AddMethodDeclNode(KonohaContext *kctx, kNode *bk, kToken *tokenClassName, kNode *classNode) { if(bk == NULL) { return; } size_t i; kNameSpace *ns = kNode_ns(classNode); kMethod *AddMethod = KLIB kNameSpace_GetMethodByParamSizeNULL(kctx, ns, KClass_NameSpace, KMethodName_("AddMethodDecl"), 1, KMethodMatch_NoOption); for(i = 0; i < kNode_GetNodeListSize(kctx, bk); i++) { kNode *stmt = bk->NodeList->NodeItems[i]; if(stmt->syn->keyword == KSymbol_TypeDeclPattern) continue; if(stmt->syn->keyword == KSymbol_MethodDeclPattern) { KLIB kObjectProto_SetObject(kctx, stmt, KSymbol_("ClassName"), KType_Token, tokenClassName); kNodeVar *classParentBlock = kNode_GetParentNULL(classNode); if(classParentBlock == NULL) { classParentBlock = KNewNode(ns); SUGAR kNode_AddNode(kctx, classParentBlock, classNode); kNode_Type(kctx, classParentBlock, KNode_Block, KType_void); } /* Create 'NameSpace.AddMethodDecl(stmt)' */ kNode *arg0 = new_ConstNode(kctx, ns, NULL, UPCAST(ns)); kNode *arg1 = new_ConstNode(kctx, ns, NULL, UPCAST(stmt)); kNode *callNode = SUGAR new_MethodNode(kctx, ns, KClass_NameSpace, AddMethod, 2, arg0, arg1); SUGAR kNode_AddNode(kctx, classParentBlock, callNode); } else { SUGAR MessageNode(kctx, stmt, NULL, NULL, WarnTag, "%s is not available within the class clause", KSymbol_Fmt2(stmt->syn->keyword)); } } }
static size_t kNode_countFieldSize(KonohaContext *kctx, kNode *bk) { size_t i, c = 0; if(bk != NULL) { for(i = 0; i < kNode_GetNodeListSize(kctx, bk); i++) { kNode *stmt = bk->NodeList->NodeItems[i]; DBG_P("stmt->keyword=%s%s", KSymbol_Fmt2(stmt->syn->keyword)); if(stmt->syn->keyword == KSymbol_TypeDeclPattern) { kNode *expr = SUGAR kNode_GetNode(kctx, stmt, KSymbol_ExprPattern, NULL); if(expr->syn->keyword == KSymbol_COMMA) { c += (kNode_GetNodeListSize(kctx, expr) - 1); } else if(expr->syn->keyword == KSymbol_LET || kNode_IsTerm(expr)) { c++; } } } } return c; }
/* copied from src/parser/import/syntax.h */ static kParam *kNode_GetParamNULL(KonohaContext *kctx, kNode *stmt, kToken *typeTk, kNameSpace* ns) { kNode *params = (kNode *) kNode_GetObjectNULL(kctx, stmt, KSymbol_ParamPattern); /* parsing parameter of closure function */ size_t i, psize = kNode_GetNodeListSize(kctx, params); kparamtype_t *p = ALLOCA(kparamtype_t, psize); for(i = 0; i < psize; i++) { kNode *node = params->NodeList->NodeItems[i]; if(node->syn->keyword != KSymbol_TypeDeclPattern || !SetParamType(kctx, node, i, p)) { /*"invalid parameter"*/ break; } } return new_kParam(kctx, typeTk->resolvedTypeId, psize, p); }
static kbool_t kNode_declClassField(KonohaContext *kctx, kNode *bk, kNameSpace *ns, KClassVar *ct) { size_t i; kbool_t failedOnce = false; for(i = 0; i < kNode_GetNodeListSize(kctx, bk); i++) { kNode *stmt = bk->NodeList->NodeItems[i]; if(stmt->syn->keyword == KSymbol_TypeDeclPattern) { kToken *tk = SUGAR kNode_GetToken(kctx, stmt, KSymbol_TypePattern, NULL); kNode *expr = SUGAR kNode_GetNode(kctx, stmt, KSymbol_ExprPattern, NULL); if(!kNode_AddClassField(kctx, stmt, ns, ct, Token_typeLiteral(tk), expr)) { failedOnce = true; } } } return !(failedOnce); }
static kbool_t kNode_AddClassField(KonohaContext *kctx, kNode *stmt, kNameSpace *ns, KClassVar *definedClass, ktypeattr_t ty, kNode *expr) { if(expr->syn->keyword == KSymbol_LET) { // String name = "naruto"; kNode *lexpr = kNode_At(expr, 1); if(kNode_IsTerm(lexpr)) { kString *name = lexpr->TermToken->text; ksymbol_t symbol = KAsciiSymbol(kString_text(name), kString_size(name), KSymbol_NewId); kNode *vexpr = SUGAR TypeCheckNodeAt(kctx, expr, 2, ns, KClass_(ty), 0); if(vexpr == K_NULLNODE) return false; if(vexpr->node == KNode_Const) { KLIB KClass_AddField(kctx, definedClass, ty, symbol); KClass_SetClassFieldObjectValue(kctx, definedClass, symbol, vexpr->ObjectConstValue); } else if(vexpr->node == KNode_UnboxConst) { KLIB KClass_AddField(kctx, definedClass, ty, symbol); KClass_SetClassFieldUnboxValue(kctx, definedClass, symbol, vexpr->unboxConstValue); } else if(vexpr->node == KNode_Null) { KLIB KClass_AddField(kctx, definedClass, ty, symbol); } else { SUGAR MessageNode(kctx, stmt, lexpr->TermToken, ns, ErrTag, "field initial value must be const: %s", kString_text(name)); return false; } return true; } } else if(expr->syn->keyword == KSymbol_COMMA) { // String (firstName = naruto, lastName) size_t i; for(i = 1; i < kNode_GetNodeListSize(kctx, expr); i++) { if(!kNode_AddClassField(kctx, stmt, ns, definedClass, ty, kNode_At(expr, i))) return false; } return true; } else if(kNode_IsTerm(expr)) { // String name kString *name = expr->TermToken->text; ksymbol_t symbol = KAsciiSymbol(kString_text(name), kString_size(name), KSymbol_NewId); KLIB KClass_AddField(kctx, definedClass, ty, symbol); return true; } SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "field name is expected"); return false; }
static kbool_t FuelVM_VisitBlockNode(KonohaContext *kctx, KBuilder *builder, kNode *block, void *thunk) { unsigned size = ARRAY_size(BLD(builder)->Stack); Block *NewBlock = CreateBlock(BLD(builder)); IRBuilder_JumpTo(BLD(builder), NewBlock); IRBuilder_setBlock(BLD(builder), NewBlock); size_t i; for(i = 0; i < kNode_GetNodeListSize(kctx, block); i++) { kNode *stmt = block->NodeList->NodeItems[i]; builder->common.uline = kNode_uline(stmt); if(!SUGAR VisitNode(kctx, builder, stmt, thunk)) break; } ARRAY_size(BLD(builder)->Stack) = size; if(builder->Value) { INode *Node = FuelVM_getExpression(builder); builder->Value = Node; } return true; }
static KMETHOD Expression_LispOperator(KonohaContext *kctx, KonohaStack *sfp) { VAR_Expression(expr, tokenList, beginIdx, currentIdx, endIdx); kNameSpace *ns = kNode_ns(expr); if(beginIdx == currentIdx && beginIdx + 1 < endIdx) { kTokenVar *opToken = tokenList->TokenVarItems[beginIdx]; kNode_Type(kctx, expr, KNode_Block, KType_var); int i = beginIdx + 1; SUGAR kNode_Op(kctx, expr, opToken, 0); while(i < endIdx) { int orig = i; kNode *node = SUGAR ParseNewNode(kctx, ns, tokenList, &i, i+1, ParseExpressionOption, "("); SUGAR kNode_AddNode(kctx, expr, node); assert(i != orig); } int size = kNode_GetNodeListSize(kctx, expr); if(size == 1) { /* case (+) */ assert(0 && "(+) is not supported"); } else if(size == 2) { /* case (+ 1) */ KReturnUnboxValue(endIdx); } /* (+ 1 2 3 4) => (+ (+ (+ 1 2) 3 ) 4) */ kNode *leftNode = kNode_At(expr, 1), *rightNode; for(i = 2; i < size-1; i++) { kNode *node = KNewNode(ns); rightNode = kNode_At(expr, i); SUGAR kNode_Op(kctx, node, opToken, 2, leftNode, rightNode); leftNode = node; } rightNode = kNode_At(expr, i); KLIB kArray_Clear(kctx, expr->NodeList, 1); KLIB kArray_Add(kctx, expr->NodeList, leftNode); KLIB kArray_Add(kctx, expr->NodeList, rightNode); KDump(expr); KReturnUnboxValue(endIdx); } }
static KMETHOD Expression_ExtendedTextLiteral(KonohaContext *kctx, KonohaStack *sfp) { VAR_Expression(expr, tokenList, beginIdx, opIdx, endIdx); kNameSpace *ns = kNode_ns(expr); kToken *tk = tokenList->TokenItems[opIdx]; INIT_GCSTACK(); kString *text = remove_escapes(kctx, tk); if(beginIdx != opIdx) { /* FIXME */ assert(0 && "FIXME"); KReturnUnboxValue(-1); } if(text == NULL) { /* text contain unsupported escape sequences */ RESET_GCSTACK(); KReturnUnboxValue(-1); } const char *str = kString_text(text); const char *end = NULL; const char *start = strstr(str, "${"); if(start == NULL) { /* text does not contain Interpolation expressions */ RESET_GCSTACK(); KReturnUnboxValue(beginIdx+1); } kSyntax *addSyntax = kSyntax_(ns, KSymbol_("+")); kTokenVar *opToken = tokenList->TokenVarItems[beginIdx]; opToken->symbol = KSymbol_("+"); opToken->text = KLIB new_kString(kctx, OnGcStack, "+", 1, 0); KFieldSet(opToken, opToken->resolvedSyntaxInfo, addSyntax); SUGAR kNode_Op(kctx, expr, opToken, 0); /* [before] "aaa${bbb}ccc" * [after] "" + "aaa" + bbb + "ccc" */ SUGAR kNode_AddNode(kctx, expr, new_ConstNode(kctx, ns, NULL, UPCAST(TS_EMPTY))); while(true) { start = strstr(str, "${"); if(start == NULL) break; if(start == strstr(str, "${}")) { str += 3; continue; } end = strchr(start, '}'); if(end == NULL) break; kNode *newexpr = ParseSource(kctx, ns, start+2, end-(start+2)); if(start - str > 0) { kNode *first = new_ConstNode(kctx, ns, NULL, UPCAST(KLIB new_kString(kctx, OnGcStack, str, (start - str), 0))); SUGAR kNode_AddNode(kctx, expr, first); } SUGAR kNode_AddNode(kctx, expr, newexpr); str = end + 1; } if((start == NULL) || (start != NULL && end == NULL)) { kNode *rest = new_ConstNode(kctx, ns, KClass_String, UPCAST(KLIB new_kString(kctx, OnGcStack, str, strlen(str), 0))); SUGAR kNode_AddNode(kctx, expr, rest); } /* (+ 1 2 3 4) => (+ (+ (+ 1 2) 3 ) 4) */ int i, size = kNode_GetNodeListSize(kctx, expr); assert(size > 2); kNode *leftNode = kNode_At(expr, 1), *rightNode; for(i = 2; i < size-1; i++) { kNode *node = KNewNode(ns); rightNode = kNode_At(expr, i); SUGAR kNode_Op(kctx, node, opToken, 2, leftNode, rightNode); leftNode = node; } rightNode = kNode_At(expr, i); KLIB kArray_Clear(kctx, expr->NodeList, 1); KLIB kArray_Add(kctx, expr->NodeList, leftNode); KLIB kArray_Add(kctx, expr->NodeList, rightNode); RESET_GCSTACK(); KReturnUnboxValue(beginIdx+1); }