Beispiel #1
0
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));
	}
}
Beispiel #2
0
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*/));
		}
	}
}
Beispiel #3
0
static KMETHOD Expression_Defined(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_Expression(expr, tokenList, beginIdx, currentIdx, endIdx);
	kNameSpace *ns = kNode_ns(expr);
	if(beginIdx == currentIdx && beginIdx + 1 < endIdx) {
		kTokenVar *definedToken = tokenList->TokenVarItems[beginIdx];   // defined
		kTokenVar *pToken = tokenList->TokenVarItems[beginIdx+1];
		if(IS_Array(pToken->GroupTokenList)) {
			SUGAR kNode_Op(kctx, expr, definedToken, 0);
			FilterDefinedParam(kctx, ns, RangeGroup(pToken->GroupTokenList));
			KReturn(SUGAR AppendParsedNode(kctx, expr, RangeGroup(pToken->GroupTokenList), NULL, ParseExpressionOption, "("));
		}
	}
}
Beispiel #4
0
static KMETHOD Expression_isNotNull(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_Expression(stmt, tokenList, beginIdx, opIdx, endIdx);
	if(opIdx + 2 == endIdx) {
		DBG_P("checking .. x != null");
		kTokenVar *tk = tokenList->TokenVarItems[opIdx+1];
		if(tk->symbol == KSymbol_("null") || tk->symbol == KSymbol_("NULL")) {
			kNameSpace *ns = kNode_ns(stmt);
			tk->symbol = KSymbol_("IsNotNull");
			tk->resolvedSyntaxInfo = tokenList->TokenVarItems[opIdx]->resolvedSyntaxInfo;
			SUGAR kNode_Op(kctx, stmt, tk, 1, SUGAR ParseNewNode(kctx, ns, tokenList, &beginIdx, opIdx, ParseExpressionOption, NULL));
			KReturnUnboxValue(opIdx + 2);
		}
	}
	DBG_P("checking parent .. != ..");
	KReturnUnboxValue(-1);
}
Beispiel #5
0
static KMETHOD Expression_BinarySugar(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_Expression(stmt, tokenList, beginIdx, operatorIdx, endIdx);
	kToken *opToken = tokenList->TokenItems[operatorIdx];
	SugarSyntax *opSyntax = opToken->resolvedSyntaxInfo;
	if(opSyntax->macroParamSize == 2) {
		TokenSequence macro = {Stmt_nameSpace(stmt), tokenList};
		TokenSequence_push(kctx, macro);
		MacroSet macroParam[] = {
			{SYM_("X"), tokenList, beginIdx, operatorIdx},
			{SYM_("Y"), tokenList, operatorIdx+1, endIdx},
			{0, NULL, 0, 0},
		};
		macro.TargetPolicy.RemovingIndent = true;
		SUGAR TokenSequence_applyMacro(kctx, &macro, opSyntax->macroDataNULL_OnList, 0, kArray_size(opSyntax->macroDataNULL_OnList), opSyntax->macroParamSize, macroParam);
		kExpr *expr = SUGAR kStmt_parseExpr(kctx, stmt, macro.tokenList, macro.beginIdx, macro.endIdx, NULL);
		TokenSequence_pop(kctx, macro);
		KReturn(expr);
	}
}
Beispiel #6
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);
	}
}
Beispiel #7
0
static KMETHOD Expression_dollar(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_Expression(stmt, tokenList, beginIdx, currentIdx, endIdx);
	DBG_ASSERT(beginIdx == currentIdx);
	if(currentIdx + 1 < endIdx) {
		kToken *nextToken = tokenList->TokenItems[currentIdx+1];
		DBG_P("nextToken='%s'", kString_text(nextToken->text));
//		if(nextToken->resolvedSyntaxInfo->keyword == KSymbol_SymbolPattern) {
//			KReturn(Expression_DollarSymbol(kctx, stmt, nextToken));
//		}

	}
//	KClass *foundClass = NULL;
//	int nextIdx = SUGAR ParseTypePattern(kctx, stmt, kNode_ns(stmt), tokenList, beginIdx + 1, endIdx, &foundClass);
//	if(nextIdx != -1 && nextIdx < kArray_size(tokenList)) {
//		kToken *nextTokenAfterClassName = tokenList->TokenItems[nextIdx];
////		if(ct->typeId == KType_void) {
////			KReturn(SUGAR MessageNode(kctx, stmt, tk1, ErrTag, "undefined class: %s", kString_text(tk1->text)));
////		} else if(KClass_Is(Virtual, ct)) {
////			SUGAR MessageNode(kctx, stmt, NULL, ErrTag, "invalid application of 'dollar' to incomplete class %s", KClass_text(ct));
////		}
//		if(nextTokenAfterClassName->resolvedSyntaxInfo->keyword == KSymbol_ParenthesisGroup) {  // dollar C (...)
//			kSyntax *syn = kSyntax_(kNode_ns(stmt), KSymbol_ParamPattern/*MethodCall*/);
//			kNode *expr = SUGAR dollar_UntypedCallStyleNode(kctx, syn, 2, dollarToken, NewNode(kctx, syn, tokenList->TokenVarItems[beginIdx+1], foundClass->typeId));
//			dollarToken->symbol = MN_dollar;
//			KReturn(expr);
//		}
//		if(nextTokenAfterClassName->resolvedSyntaxInfo->keyword == KSymbol_BracketGroup) {     // dollar int [100]
//			kSyntax *syn = kSyntax_(kNode_ns(stmt), KSymbol_("dollar"));
//			KClass *arrayClass = KClass_p0(kctx, KClass_Array, foundClass->typeId);
//			dollarToken->symbol = KMethodName_("dollarArray");
//			kNode *expr = SUGAR dollar_UntypedCallStyleNode(kctx, syn, 2, dollarToken, NewNode(kctx, syn, tokenList->TokenVarItems[beginIdx+1], arrayClass->typeId));
//			KReturn(expr);
//		}
//	}
}
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);
}