Exemplo n.º 1
0
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));
		}
	}
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/* 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);
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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);
	}
}
Exemplo n.º 8
0
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);
}