示例#1
0
static kMethod *CompileClosure(KonohaContext *kctx, kNameSpace *ns, kNode *expr, KClass *envCt, kToken *typeTk, kNode **texprRef)
{
	INIT_GCSTACK();
	kParam *pa = kNode_GetParamNULL(kctx, expr, typeTk, ns);
	kMethodVar *mtd = (kMethodVar *) KLIB new_kMethod(kctx, _GcStack, 0, envCt->typeId, 0/*mn*/, NULL);
	KLIB kMethod_SetParam(kctx, mtd, pa->rtype, pa->psize, (kparamtype_t *)pa->paramtypeItems);

	int errorCount = KGetParserContext(kctx)->errorMessageCount;
	KGammaStackDecl lvarItems[32] = {};
	struct KGammaLocalData newgma = {};
	newgma.flag = 0;
	newgma.currentWorkingMethod = mtd;
	newgma.thisClass            = envCt;
	newgma.localScope.varItems  = lvarItems;
	newgma.localScope.capacity  = 32;
	newgma.localScope.varsize   = 0;
	newgma.localScope.allocsize = 0;
	kNameSpace_InitParam(kctx, ns, &newgma, pa, envCt);

	KPushGammaStack(ns, &newgma);
	*texprRef = SUGAR TypeCheckNodeByName(kctx, expr, KSymbol_BlockPattern, ns, KClass_var, TypeCheckPolicy_AllowVoid);

	kNode *block = SUGAR kNode_GetNode(kctx, expr, KSymbol_BlockPattern, NULL);
	KLIB kMethod_GenCode(kctx, mtd, block, HatedLazyCompile);

	KPopGammaStack(ns, &newgma);
	kMethod_Set(StaticError, mtd, KGetParserContext(kctx)->errorMessageCount > errorCount);
	RESET_GCSTACK();
	return mtd;
}
示例#2
0
static kbool_t FuelVM_VisitJumpNode(KonohaContext *kctx, KBuilder *builder, kNode *stmt, void *thunk, ksymbol_t label)
{
	kNode *jump = kNode_GetNode(kctx, stmt, label);
	DBG_ASSERT(jump != NULL && IS_Node(jump));
	Block *target = kNode_GetTargetBlock(kctx, jump, label);
	IRBuilder_JumpTo(BLD(builder), target);
	return true;
}
示例#3
0
static kbool_t FuelVM_VisitReturnNode(KonohaContext *kctx, KBuilder *builder, kNode *stmt, void *thunk)
{
	kNode *expr = SUGAR kNode_GetNode(kctx, stmt, KSymbol_ExprPattern, NULL);
	if(expr != NULL && IS_Node(expr) && expr->attrTypeId != KType_void) {
		SUGAR VisitNode(kctx, builder, expr, thunk);
		INode *Ret  = FuelVM_getExpression(builder);
		INode *Inst = CreateReturn(BLD(builder), Ret);
		INode_setType(Inst, ConvertToTypeId(kctx, expr->attrTypeId));
	} else {
		CreateReturn(BLD(builder), 0);
	}
	return true;
}
示例#4
0
static kbool_t SetParamType(KonohaContext *kctx, kNode *stmt, int n, kparamtype_t *p)
{
	kToken *typeToken  = SUGAR kNode_GetToken(kctx, stmt, KSymbol_TypePattern, NULL);
	kNode  *expr = SUGAR kNode_GetNode(kctx, stmt, KSymbol_ExprPattern, NULL);
	DBG_ASSERT(typeToken != NULL);
	DBG_ASSERT(expr != NULL);
	if(kNode_isSymbolTerm(expr)) {
		kToken *tkN = expr->TermToken;
		p[n].name = tkN->symbol;
		p[n].attrTypeId = Token_typeLiteral(typeToken);
		return true;
	}
	return false;
}
示例#5
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);
}
示例#6
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;
}
示例#7
0
static kNode *kNode_GetNode(KonohaContext *kctx, kNode *stmt, ksymbol_t kw)
{
	return SUGAR kNode_GetNode(kctx, stmt, kw, NULL);
}
示例#8
0
static kNode* kNode_getFirstNode(KonohaContext *kctx, kNode *stmt)
{
	return SUGAR kNode_GetNode(kctx, stmt, KSymbol_ExprPattern, NULL);
}
示例#9
0
static kNode* kNode_getElseBlock(KonohaContext *kctx, kNode *stmt)
{
	return SUGAR kNode_GetNode(kctx, stmt, KSymbol_else, K_NULLBLOCK);
}
示例#10
0
static kbool_t FuelVM_VisitLoopNode(KonohaContext *kctx, KBuilder *builder, kNode *stmt, void *thunk, enum LoopType Loop)
{
	Block *HeadBB  = CreateBlock(BLD(builder));
	Block *BodyBB  = CreateBlock(BLD(builder));
	Block *ItrBB   = CreateBlock(BLD(builder));
	Block *MergeBB = CreateBlock(BLD(builder));

	kNode_SetLabelBlock(kctx, stmt, KSymbol_("continue"), ItrBB);
	kNode_SetLabelBlock(kctx, stmt, KSymbol_("break"),    MergeBB);

	kNode *itrBlock = SUGAR kNode_GetNode(kctx, stmt, KSymbol_("Iterator"), NULL);
	if(itrBlock != NULL) {
		assert(Loop == ForLoop);
		IRBuilder_JumpTo(BLD(builder), HeadBB);
	}
	else if(Loop == WhileLoop) {
		/* [WhileStmt]
		 * "Head" is Join Node
		 * Head  : if(COND) { goto Body } else {goto Merge }
		 * Body  : Body
		 *         ...
		 *         goto Itr
		 * Itr   : Body3
		 *         goto Head
		 * Merge : ...
		 */
		IRBuilder_JumpTo(BLD(builder), HeadBB);
	} else {
		/* [LoopStmt] (e.g. do-while loop)
		 * "Body" is Join Node
		 * Body  : Body
		 *         ...
		 *         goto Itr
		 * Itr   : Body3
		 *         goto Head
		 * Head  : if(COND) { goto Body } else {goto Merge }
		 * Merge : ...
		 */
		IRBuilder_JumpTo(BLD(builder), BodyBB);
	}

	{ /* Head */
		IRBuilder_setBlock(BLD(builder), HeadBB);
		SUGAR VisitNode(kctx, builder, kNode_getFirstNode(kctx, stmt), thunk);
		CreateBranch(BLD(builder), FuelVM_getExpression(builder), BodyBB, MergeBB);
	}

	{ /* Body */
		IRBuilder_setBlock(BLD(builder), BodyBB);
		SUGAR VisitNode(kctx, builder, kNode_getFirstBlock(kctx, stmt), thunk);
		IRBuilder_JumpTo(BLD(builder), ItrBB);

		/* Itr */
		IRBuilder_setBlock(BLD(builder), ItrBB);
		if(itrBlock != NULL) {
			SUGAR VisitNode(kctx, builder, itrBlock, thunk);
		}
		IRBuilder_JumpTo(BLD(builder), HeadBB);
	}

	IRBuilder_setBlock(BLD(builder), MergeBB);
	return true;
}
示例#11
0
/* Konoha AST API */
static kNode* kNode_getFirstBlock(KonohaContext *kctx, kNode *stmt)
{
	return SUGAR kNode_GetNode(kctx, stmt, KSymbol_BlockPattern, K_NULLBLOCK);
}