예제 #1
0
bool PruningVisitor::VisitImpNode(ASTNode **nodePtr)
{
	ASTNode *node = *nodePtr;

	ASTNode **leftNodePtr, **rightNodePtr;
	leftNodePtr = &(node->Nodes[0]);
	rightNodePtr = &(node->Nodes[1]);

	bool leftNodeKnown = VisitNode(leftNodePtr),
		rightNodeKnown = VisitNode(rightNodePtr);

	ASTNode *leftNode = *leftNodePtr,
		*rightNode = *rightNodePtr;

	//P->Q === !P||Q
	ASTNode *newNode = new ASTNode(Token(TOKENTYPE_OPOR, "||"));

	ASTNode *newSubNode = new ASTNode(Token(TOKENTYPE_OPNOT, "!"));
	newSubNode->Nodes.push_back(leftNode);

	newNode->Nodes.push_back(newSubNode);
	newNode->Nodes.push_back(rightNode);

	bool newKnown = VisitNode(&newNode);

	CopyTo(newNode, nodePtr);

	return newKnown;
}
예제 #2
0
bool PruningVisitor::VisitBitorNode(ASTNode **nodePtr)
{
	ASTNode *node = *nodePtr;

	ASTNode **leftNodePtr, **rightNodePtr;
	leftNodePtr = &(node->Nodes[0]);
	rightNodePtr = &(node->Nodes[1]);
	bool leftNodeKnown = VisitNode(leftNodePtr),
		rightNodeKnown = VisitNode(rightNodePtr);

	ASTNode *leftNode = *leftNodePtr,
		*rightNode = *rightNodePtr;

	if ((leftNodeKnown && leftNode->Value == 0xFFFFFFFF) || (rightNodeKnown && rightNode->Value == 0xFFFFFFFF))
	{
		delete leftNode;
		delete rightNode;
		node->Nodes.clear();
		SetKnown(node, 0xFFFFFFFF);
		return true;
	}
	else if (leftNodeKnown && leftNode->Value == 0)
	{
		delete leftNode;
		CopyTo(rightNode, nodePtr);
		return false;
	}
	else if (rightNodeKnown && rightNode->Value == 0)
	{
		delete rightNode;
		CopyTo(leftNode, nodePtr);
		return false;
	}
	return false;
}
예제 #3
0
파일: Compiler.c 프로젝트: myoan/minikonoha
static kbool_t FuelVM_VisitIfNode(KonohaContext *kctx, KBuilder *builder, kNode *stmt, void *thunk)
{
	kNode *expr    = kNode_getFirstNode(kctx, stmt);
	Block *ThenBB  = CreateBlock(BLD(builder));
	Block *ElseBB  = CreateBlock(BLD(builder));
	Block *MergeBB = CreateBlock(BLD(builder));
	/* if */
	SUGAR VisitNode(kctx, builder, expr, thunk);
	CreateBranch(BLD(builder), FuelVM_getExpression(builder), ThenBB, ElseBB);
	{ /* then */
		IRBuilder_setBlock(BLD(builder), ThenBB);
		SUGAR VisitNode(kctx, builder, kNode_getFirstBlock(kctx, stmt), thunk);
		if(!Block_HasTerminatorInst(BLD(builder)->Current)) {
			IRBuilder_JumpTo(BLD(builder), MergeBB);
		}
	}
	{ /* else */
		IRBuilder_setBlock(BLD(builder), ElseBB);
		SUGAR VisitNode(kctx, builder, kNode_getElseBlock(kctx, stmt), thunk);
		if(!Block_HasTerminatorInst(BLD(builder)->Current)) {
			IRBuilder_JumpTo(BLD(builder), MergeBB);
		}
	}
	/* endif */
	IRBuilder_setBlock(BLD(builder), MergeBB);
	return true;
}
예제 #4
0
bool PruningVisitor::VisitModNode(ASTNode **nodePtr)
{
	ASTNode *node = *nodePtr;

	ASTNode **leftNodePtr, **rightNodePtr;
	leftNodePtr = &(node->Nodes[0]);
	rightNodePtr = &(node->Nodes[1]);
	bool leftNodeKnown = VisitNode(leftNodePtr),
		rightNodeKnown = VisitNode(rightNodePtr);

	ASTNode *leftNode = *leftNodePtr,
		*rightNode = *rightNodePtr;

	if (leftNodeKnown && rightNodeKnown)
	{
		int value = leftNode->Value % rightNode->Value;

		delete leftNode;
		*leftNodePtr = leftNode = NULL;
		delete rightNode;
		*rightNodePtr = rightNode = NULL;

		node->Nodes.clear();
		SetKnown(node, value);
		return true;
	}
	return false;
}
예제 #5
0
static kbool_t CollectLocalVar_VisitIfNode(KVISITOR_PARAM)
{
	KLIB VisitNode(kctx, builder, kUntypedNode_getFirstNode(kctx, node), thunk);
	KLIB VisitNode(kctx, builder, kUntypedNode_getFirstBlock(kctx, node), thunk);
	KLIB VisitNode(kctx, builder, kUntypedNode_getElseBlock(kctx, node), thunk);
	return true;
}
예제 #6
0
static kbool_t MiniVM_VisitDoWhileNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	bblock_t HeadBB  = new_BasicBlockLABEL(kctx);
	bblock_t BodyBB  = new_BasicBlockLABEL(kctx);
	bblock_t MergeBB = new_BasicBlockLABEL(kctx);

	kUntypedNode_SetLabelBlock(kctx, node, KSymbol_("continue"), HeadBB);
	kUntypedNode_SetLabelBlock(kctx, node, KSymbol_("break"),    MergeBB);

	MiniVMBuilder_JumpTo(kctx, builder, BodyBB);
	{ /* Head */
		MiniVMBuilder_setBlock(kctx, builder, HeadBB);
		KLIB VisitNode(kctx, builder, kUntypedNode_getFirstNode(kctx, node), thunk);
		CreateBranch(kctx, builder, MiniVM_getExpression(builder), MergeBB, BodyBB, true);
	}

	{ /* Body */
		MiniVMBuilder_setBlock(kctx, builder, BodyBB);
		KLIB VisitNode(kctx, builder, kUntypedNode_getFirstBlock(kctx, node), thunk);
		MiniVMBuilder_JumpTo(kctx, builder, HeadBB);
	}

	MiniVMBuilder_setBlock(kctx, builder, MergeBB);
	return true;
}
예제 #7
0
bool PruningVisitor::VisitDivNode(ASTNode **nodePtr)
{
	ASTNode *node = *nodePtr;

	ASTNode **leftNodePtr, **rightNodePtr;
	leftNodePtr = &(node->Nodes[0]);
	rightNodePtr = &(node->Nodes[1]);
	bool leftNodeKnown = VisitNode(leftNodePtr),
		rightNodeKnown = VisitNode(rightNodePtr);

	ASTNode *leftNode = *leftNodePtr,
		*rightNode = *rightNodePtr;

	if (leftNodeKnown && rightNodeKnown)
	{
		if (rightNode->Value == 0)
		{
			throw RuntimeError("Divided by zero.");
		}
		int value = leftNode->Value / rightNode->Value;

		delete leftNode;
		*leftNodePtr = leftNode = NULL;
		delete rightNode;
		*rightNodePtr = rightNode = NULL;

		node->Nodes.clear();
		SetKnown(node, value);
		return true;
	}
	return false;
}
예제 #8
0
bool PruningVisitor::VisitBitxorNode(ASTNode **nodePtr)
{
	ASTNode *node = *nodePtr;

	ASTNode **leftNodePtr, **rightNodePtr;
	leftNodePtr = &(node->Nodes[0]);
	rightNodePtr = &(node->Nodes[1]);
	bool leftNodeKnown = VisitNode(leftNodePtr),
		rightNodeKnown = VisitNode(rightNodePtr);

	ASTNode *leftNode = *leftNodePtr,
		*rightNode = *rightNodePtr;

	if ((leftNodeKnown && leftNode->Value == 0xFFFFFFFF)) //1^x === ~x
	{
		delete leftNode;
		*leftNodePtr = leftNode = NULL;

		ASTNode *newNode = new ASTNode(Token(TOKENTYPE_OPBITNOT, "~"));
		newNode->Nodes.push_back(rightNode);
		
		bool newKnown = VisitNode(&newNode);
		CopyTo(newNode, nodePtr);

		return newKnown;
	}
	else if (leftNodeKnown && leftNode->Value == 0) //0^x === x
	{
		delete leftNode;
		*leftNodePtr = leftNode = NULL;

		CopyTo(rightNode, nodePtr);

		return rightNodeKnown;
	}
	else if (rightNodeKnown && rightNode->Value == 0xFFFFFFFF) //x^1 === ~x
	{
		delete rightNode;
		*rightNodePtr = rightNode = NULL;

		ASTNode *newNode = new ASTNode(Token(TOKENTYPE_OPBITNOT, "~"));
		newNode->Nodes.push_back(leftNode);

		bool newKnown = VisitNode(&newNode);
		CopyTo(newNode, nodePtr);

		return newKnown;
	}
	else if (rightNodeKnown && rightNode->Value == 0) //x^0 === x
	{
		delete rightNode;
		*rightNodePtr = rightNode = NULL;

		CopyTo(leftNode, nodePtr);

		return leftNodeKnown;
	}
	return false;
}
예제 #9
0
파일: Compiler.c 프로젝트: myoan/minikonoha
static kbool_t FuelVM_VisitAssignNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	/*
	 * [LetExpr] := lhs = rhs
	 * expr->NodeList = [NULL, lhs, rhs]
	 **/

	kNode *left = kNode_At(expr, 1);
	kNode *right = kNode_At(expr, 2);
	INode *Node;
	FuelIRBuilder *flbuilder = BLD(builder);
	if(left->node == KNode_Local) {
		enum TypeId type = ConvertToTypeId(kctx, left->attrTypeId);
		if((Node = IRBuilder_FindLocalVarByHash(flbuilder, type, left->index)) == 0) {
			Node = CreateLocal(flbuilder, type);
			IField_setHash((IField *) Node, left->index);
		}
		SUGAR VisitNode(kctx, builder, right, thunk);
		INode *RHS = FuelVM_getExpression(builder);
		//if(RHS->Type != Node->Type) {
		//	INode_setType(Node, RHS->Type);
		//}
		CreateUpdate(flbuilder, Node, RHS);
	}
	//else if(left->node == TEXPR_STACKTOP) {
	//	enum TypeId type = ConvertToTypeId(kctx, left->attrTypeId);
	//	uintptr_t Hash = (uintptr_t) left;
	//	if((Node = IRBuilder_FindLocalVarByHash(flbuilder, type, Hash)) == 0) {
	//		Node = CreateLocal(flbuilder, type);
	//		IField_setHash((IField *) Node, Hash);
	//		ARRAY_add(INodePtr, &BLD(builder)->Stack, Node);
	//	}
	//	SUGAR VisitNode(kctx, builder, right, thunk);
	//	INode *RHS = FuelVM_getExpression(builder);
	//	if(RHS->Type != Node->Type)
	//		INode_setType(Node, RHS->Type);
	//	CreateUpdate(BLD(builder), Node, RHS);
	//}
	else{
		assert(left->node == KNode_Field);
		SUGAR VisitNode(kctx, builder, right, thunk);
		kshort_t index  = (kshort_t)left->index;
		kshort_t xindex = (kshort_t)(left->index >> (sizeof(kshort_t)*8));

		INode *Left;
		if((Left = IRBuilder_FindLocalVarByHash(BLD(builder), TYPE_Object, index)) == 0) {
			Left = CreateLocal(BLD(builder), TYPE_Object);
			IField_setHash((IField *) Left, index);
		}
		enum TypeId type = ConvertToTypeId(kctx, left->attrTypeId);
		Node = CreateField(BLD(builder), FieldScope, type, Left, xindex);
		SUGAR VisitNode(kctx, builder, right, thunk);
		CreateUpdate(BLD(builder), Node, FuelVM_getExpression(builder));
	}
	builder->Value = Node;
	return true;
}
예제 #10
0
static kbool_t CollectLocalVar_VisitWhileNode(KVISITOR_PARAM)
{
	kUntypedNode *ItrBlock;
	KLIB VisitNode(kctx, builder, kUntypedNode_getFirstNode(kctx, node), thunk);
	KLIB VisitNode(kctx, builder, kUntypedNode_getFirstBlock(kctx, node), thunk);
	ItrBlock = KLIB kUntypedNode_GetNode(kctx, node, KSymbol_("Iterator"), NULL);
	if(ItrBlock != NULL) {
		KLIB VisitNode(kctx, builder, ItrBlock, thunk);
	}
	return true;
}
예제 #11
0
static kbool_t CollectLocalVar_VisitAssignNode(KVISITOR_PARAM)
{
	kUntypedNode *left = kUntypedNode_At(node, 1);
	kUntypedNode *right = kUntypedNode_At(node, 2);
	if(kUntypedNode_node(left) == KNode_Local) {
		LOCAL(left->typeAttr, left->index);
		KLIB VisitNode(kctx, builder, right, thunk);
	} else{
		LOCAL(KType_Object, (khalfword_t)left->index);
		KLIB VisitNode(kctx, builder, right, thunk);
	}
	return true;
}
예제 #12
0
static struct KVirtualCode *MiniVM_GenerateVirtualCode(KonohaContext *kctx, kMethod *mtd, kUntypedNode *block, int option)
{
	KVirtualCode *vcode;
	KBuffer wb;
	KBuilder builderbuf = {{0}}, *builder = &builderbuf;
	kNameSpace *ns = kUntypedNode_ns(block);

	INIT_GCSTACK();
	KLIB KBuffer_Init(&(kctx->stack->cwb), &wb);
	builder->common.api = ns->builderApi;
	builder->constPools = ns->NameSpaceConstList;
	builder->bbBeginId  = new_BasicBlockLABEL(kctx);
	builder->bbReturnId = new_BasicBlockLABEL(kctx);
	builder->bbMainId   = builder->bbBeginId;
	builder->currentMtd = mtd;
	builder->Value      = 0;
	builder->stackbase  = 0;
	builder->InstructionSize = 0;

	builder->common.api = &CollectLocalVar_BuilderAPI;
	KLIB VisitNode(kctx, builder, block, NULL);
	builder->stackbase += builder->localVarSize + 1/* == this object */;
	builder->common.api = ns->builderApi;

	KLIB KArray_Init(kctx, &builder->localVar, sizeof(LocalVarInfo) * builder->stackbase);

	ASM(THCODE, 0, _THCODE);
	ASM(CHKSTACK, 0);

	KLIB VisitNode(kctx, builder, block, NULL);

	if(!Block_HasTerminatorInst(kctx, builder->bbMainId)) {
		MiniVMBuilder_JumpTo(kctx, builder, builder->bbReturnId);
	}

	MiniVMBuilder_setBlock(kctx, builder, builder->bbReturnId);
	if(mtd->mn == MN_new) {
		// FIXME: Type 'This' must be resolved
		ASM(NMOV, OC_(K_RTNIDX), OC_(0), KClass_(mtd->typeId));
	}
	ASM(RET);
	vcode = CompileVirtualCode(kctx, builder, builder->bbBeginId, builder->bbReturnId);

	KLIB KArray_Free(kctx, &builder->localVar);
	RESET_GCSTACK();
	KLIB KBuffer_Free(&wb);
	return vcode;

}
예제 #13
0
bool AStar::Step(sf::RectangleShape board[])
{
	Node* pCurrentNode;
	if (!qOpenList.empty())
	{
		pCurrentNode = VisitNode();
	}
	else
	{ 
		std::cout << "Can't find a path" << std::endl;
		return true;
	}

	UpdateBoardGraphic(board);

	if (pCurrentNode == tRoot[iEndNode])
	{
		PrintPath(pCurrentNode, board);
		return true;
	}

	board[pCurrentNode->X()*yMax + pCurrentNode->Y()].setFillColor(sf::Color::Red);

	return false;
}
예제 #14
0
	void Visit(SyntaxApi::IOperations::IUnaryOp* operation_node)
	{
		std::vector<TSOperation*> param_expressions;
		TSOperation *left;
		left = VisitNode(operation_node->GetLeft());

		param_expressions.push_back(left);

		std::vector<TExpressionResult> param;

		param.resize(1);
		param[0] = left->GetFormalParameter();

		SemanticApi::ISMethod *unary_operator = nullptr;

		if (param[0].GetClass() == nullptr)
			syntax_node->Error("К данному операнду нельзя применить унарный оператор (нужен тип отличающийся от void)!");

		std::vector<SemanticApi::ISMethod*> operators;
		param[0].GetClass()->GetOperators(operators, operation_node->GetOp());

		unary_operator = FindMethod(syntax_node, operators, param);

		if (unary_operator != nullptr)
		{
			ValidateAccess(syntax_node, owner, unary_operator);

			TSExpression_TMethodCall* method_call = new TSExpression_TMethodCall(SemanticApi::TMethodCallType::Operator);
			method_call->Build(param_expressions, dynamic_cast<TSMethod*>(unary_operator));
			Return(method_call);
		}
		else
			syntax_node->Error("Унарного оператора для данного типа не существует!");
	}
예제 #15
0
DWORD CQHState::OnVisitHierarchy( DWORD size, void *params )
{
	VISITHIERARCHYDATA *vhd = static_cast<VISITHIERARCHYDATA *>( params );
	VERIFY_MESSAGE_SIZE( size, sizeof( *vhd ) );
	VisitNode( vhd->visitor );
	return MSG_HANDLED_STOP;
}
예제 #16
0
bool PruningVisitor::VisitNotNode(ASTNode **nodePtr)
{
	auto node = *nodePtr;

	ASTNode **subnodePtr = &(node->Nodes[0]);
	bool subKnown = VisitNode(subnodePtr);
	ASTNode *subNode = *subnodePtr;
	
	if (subKnown)
	{
		int value = !subNode->Value;
		delete subNode;
		node->Nodes.clear();
		SetKnown(node, value);
		return true;
	}
	else if (subNode->token.Type == TOKENTYPE_OPNOT) //!!x === x
	{
		ASTNode *subSubNode = subNode->Nodes[0];
		subNode->Nodes.clear();
		delete subNode;
		*subnodePtr = subNode = NULL;

		CopyTo(subSubNode, nodePtr);
		return subSubNode->Known;
	}
	return false;
}
예제 #17
0
파일: MiniVM.c 프로젝트: imasahiro/konoha3
static kbool_t KBuilder_VisitMethodCallNode(KonohaContext *kctx, KBuilder *builder, kNode *expr, void *thunk)
{
	kshort_t a = AssignStack(thunk), espidx = expr->stackbase, thisidx = espidx + K_CALLDELTA;
	DBG_ASSERT(a <= espidx);
	kMethod *mtd = CallNode_getMethod(expr);
	DBG_ASSERT(IS_Method(mtd));
	int i, s = kMethod_Is(Static, mtd) ? 2 : 1;
	int argc = CallNode_getArgCount(expr);
	for (i = s; i < argc + 2; i++) {
		intptr_t a = thisidx + i - 1;
		kNode *paramNode = kNode_At(expr, i);
		if(!kNode_IsValue(paramNode) && paramNode->stackbase != a) {
			DBG_P("a=%d, stackbase=%d", a, paramNode->stackbase);
			DBG_ASSERT(paramNode->stackbase == a);
		}
		SUGAR VisitNode(kctx, builder, paramNode, &a);
	}
	if(kMethod_Is(Final, mtd) || !kMethod_Is(Virtual, mtd)) {
		ASM(NSET, NC_(thisidx-1), (intptr_t)mtd, KClass_Method);
		if(kMethod_Is(Virtual, mtd)) {
			// set namespace to enable method lookups
			ASM(NSET, OC_(thisidx-2), (intptr_t)kNode_ns(expr), KClass_NameSpace);
		}
	}
	else {
		ASM(NSET, OC_(thisidx-2), (intptr_t)kNode_ns(expr), KClass_NameSpace);
		ASM(LOOKUP, SFP_(thisidx), kNode_ns(expr), mtd);
	}
	int esp_ = SFP_(espidx + argc + K_CALLDELTA + 1);
	ASM(CALL, builder->common.uline, SFP_(thisidx), esp_, KLIB Knull(kctx, KClass_(expr->attrTypeId)));
	ReAssignNonValueNode(kctx, builder, a, expr);
	return true;
}
예제 #18
0
파일: Compiler.c 프로젝트: myoan/minikonoha
static struct KVirtualCode *FuelVM_GenerateVirtualCode(KonohaContext *kctx, kMethod *mtd, kNode *block, int option)
{
	if(unlikely(AbstractMethodPtr == 0)) {
		AbstractMethodPtr = mtd->invokeKMethodFunc;
	}

	kNameSpace *ns = kNode_ns(block);
	KBuilder builderbuf = {}, *builder = &builderbuf;
	FuelIRBuilder Builder = {};
	INIT_GCSTACK();
	IRBuilder_Init(&Builder, kctx, ns);
	builder->builder = &Builder;
	builder->common.api = ns->builderApi;
	Block *EntryBlock = CreateBlock(BLD(builder));
	IRBuilder_setBlock(BLD(builder), EntryBlock);
	INode *Self = SetUpArguments(kctx, &Builder, mtd);

	SUGAR VisitNode(kctx, builder, block, NULL);

	if(!Block_HasTerminatorInst(BLD(builder)->Current)) {
		if(mtd->mn == MN_new) {
			INode *Ret = CreateReturn(BLD(builder), Self);
			INode_setType(Ret, ConvertToTypeId(kctx, mtd->typeId));
		} else {
			ktypeattr_t retTy = kMethod_GetReturnType(mtd)->typeId;
			if(retTy == KType_void) {
				CreateReturn(BLD(builder), 0);
			} else {
				enum TypeId Type = ConvertToTypeId(kctx, retTy);
				INode *Ret;
				if(KType_Is(UnboxType, retTy)) {
					SValue V; V.bits = 0;
					Ret = CreateConstant(BLD(builder), Type, V);
				} else {
					kObject *obj = KLIB Knull(kctx, KClass_(retTy));
					Ret = CreateObject(BLD(builder), Type, (void *)obj);
				}
				Ret = CreateReturn(BLD(builder), Ret);
				INode_setType(Ret, Type);
				CreateReturn(BLD(builder), 0);
			}
		}
	}
	RESET_GCSTACK();
	IMethod Mtd = {kctx, mtd, EntryBlock, ns};
	BLD(builder)->Method = &Mtd;
	bool JITCompiled = false;
	union ByteCode *code = IRBuilder_Compile(BLD(builder), &Mtd, option, &JITCompiled);
	if(mtd->invokeKMethodFunc == FuelVM_RunVirtualMachine) {
		mtd->virtualCodeApi_plus1[-1]->FreeVirtualCode(kctx, mtd->vcode_start);
	}
	KLIB kMethod_SetFunc(kctx, mtd, 0);
	if(JITCompiled) {
		KLIB kMethod_SetFunc(kctx, mtd, (KMethodFunc) code);
	}
	KFieldSet(mtd, ((kMethodVar *)mtd)->CompiledNode, block);
	IRBuilder_Exit(&Builder);
	return (struct KVirtualCode *) code;
}
예제 #19
0
static kbool_t CollectLocalVar_VisitReturnNode(KVISITOR_PARAM)
{
	kUntypedNode *expr = KLIB kUntypedNode_GetNode(kctx, node, KSymbol_ExprPattern, NULL);
	if(expr != NULL && IS_Node(expr) && expr->typeAttr != KType_void) {
		KLIB VisitNode(kctx, builder, expr, thunk);
	}
	return false;
}
예제 #20
0
int Dijkstra(NodeStruct *Map,int MapSize,int Start,int Finish)
{
    //Start Dijkstra algorithm
    VisitNode(Map, MapSize, Start, Finish);

    //Trace found route of Dijkstra algorithm
    return TraceRoute(Map, Finish);
}
예제 #21
0
파일: Compiler.c 프로젝트: myoan/minikonoha
static INode *FetchINode(KonohaContext *kctx, KBuilder *builder, kNode *expr, unsigned idx, ktypeattr_t reqTy, void *thunk)
{
	kNode *exprN = kNode_At(expr, idx);
	SUGAR VisitNode(kctx, builder, exprN, thunk);
	INode *Node = FuelVM_getExpression(builder);
	assert(Node->Type != TYPE_void);
	return Node;
}
예제 #22
0
static kbool_t MiniVM_VisitForNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	kUntypedNode *initNode = kUntypedNode_GetNode(kctx, node, KSymbol_("init"));
	if(initNode != NULL) {
		KLIB VisitNode(kctx, builder, initNode, thunk);
	}
	return MiniVM_VisitLoopNode(kctx, builder, node, thunk, ForLoop);
}
예제 #23
0
파일: Compiler.c 프로젝트: myoan/minikonoha
static void CreateCond(KonohaContext *kctx, KBuilder *builder, kNode *expr, enum ConditionalOp Op, void *thunk)
{
	kNode *LHS = kNode_At(expr, 1);
	kNode *RHS = kNode_At(expr, 2);

	Block *HeadBB  = CreateBlock(BLD(builder));
	Block *ThenBB  = CreateBlock(BLD(builder));
	Block *MergeBB = CreateBlock(BLD(builder));

	/* [CondExpr]
	 * LogicalAnd case
	 *       | goto Head
	 * Head  | let bval = LHS
	 *       | if(bval) { goto Then } else { goto Merge }
	 * Then  | bval = RHS
	 *       | goto Merge
	 * Merge | ...
	 */

	INode *Node;
	IRBuilder_JumpTo(BLD(builder), HeadBB);
	{ /* Head */
		IRBuilder_setBlock(BLD(builder), HeadBB);
		Node = CreateLocal(BLD(builder), TYPE_boolean);
		SUGAR VisitNode(kctx, builder, LHS, thunk);
		INode *Left = FuelVM_getExpression(builder);
		CreateUpdate(BLD(builder), Node, Left);

		if(Op == LogicalAnd) {
			CreateBranch(BLD(builder), Left, ThenBB, MergeBB);
		} else {
			CreateBranch(BLD(builder), Left, MergeBB, ThenBB);
		}
	}
	{ /* Then */
		IRBuilder_setBlock(BLD(builder), ThenBB);
		SUGAR VisitNode(kctx, builder, RHS, thunk);
		INode *Right = FuelVM_getExpression(builder);
		CreateUpdate(BLD(builder), Node, Right);
		IRBuilder_JumpTo(BLD(builder), MergeBB);
	}

	IRBuilder_setBlock(BLD(builder), MergeBB);
	builder->Value = Node;
}
예제 #24
0
static kbool_t CollectLocalVar_VisitFunctionNode(KVISITOR_PARAM)
{
	size_t i, ParamSize = kArray_size(node->NodeList)-2;
	for(i = 0; i < ParamSize; i++) {
		kUntypedNode *expr = kUntypedNode_At(node, i+2);
		KLIB VisitNode(kctx, builder, expr, thunk);
	}
	return true;
}
예제 #25
0
static kbool_t CollectLocalVar_VisitForNode(KVISITOR_PARAM)
{
	kUntypedNode *initNode = kUntypedNode_GetNode(kctx, node, KSymbol_("init"));
	if(initNode != NULL) {
		KLIB VisitNode(kctx, builder, initNode, thunk);
	}
	CollectLocalVar_VisitWhileNode(kctx, builder, node, thunk);
	return true;
}
예제 #26
0
static void CreateCond(KonohaContext *kctx, KBuilder *builder, kUntypedNode *expr, enum ConditionalOp Op, void *thunk)
{
	intptr_t cond;
	kUntypedNode *LHS = kUntypedNode_At(expr, 1);
	kUntypedNode *RHS = kUntypedNode_At(expr, 2);

	bblock_t HeadBB  = new_BasicBlockLABEL(kctx);
	bblock_t ThenBB  = new_BasicBlockLABEL(kctx);
	bblock_t MergeBB = new_BasicBlockLABEL(kctx);

	/* [CondExpr]
	 * LogicalAnd case
	 *       | goto Head
	 * Head  | let bval = LHS
	 *       | if(bval) { goto Then } else { goto Merge }
	 * Then  | bval = RHS
	 *       | goto Merge
	 * Merge | ...
	 */

	MiniVMBuilder_JumpTo(kctx, builder, HeadBB);
	cond = builder->stackbase;
	builder->stackbase += 1;
	{ /* Head */
		MiniVMBuilder_setBlock(kctx, builder, HeadBB);
		KLIB VisitNode(kctx, builder, LHS, thunk);
		CreateUpdate(kctx, builder, KType_Boolean, cond, MiniVM_getExpression(builder));
		if(Op == LogicalAnd)
			CreateBranch(kctx, builder, cond, ThenBB, MergeBB, false);
		else {
			CreateBranch(kctx, builder, cond, ThenBB, MergeBB, true);
		}
	}
	{ /* Then */
		MiniVMBuilder_setBlock(kctx, builder, ThenBB);
		KLIB VisitNode(kctx, builder, RHS, thunk);
		CreateUpdate(kctx, builder, KType_Boolean, cond, MiniVM_getExpression(builder));
		MiniVMBuilder_JumpTo(kctx, builder, MergeBB);
	}

	MiniVMBuilder_setBlock(kctx, builder, MergeBB);
	builder->stackbase -= 1;
	builder->Value = builder->stackbase;
}
예제 #27
0
static kbool_t MiniVM_VisitLoopNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk, enum LoopType Loop)
{
	kUntypedNode *ItrBlock;
	bblock_t HeadBB  = new_BasicBlockLABEL(kctx);
	bblock_t BodyBB  = new_BasicBlockLABEL(kctx);
	bblock_t ItrBB   = new_BasicBlockLABEL(kctx);
	bblock_t MergeBB = new_BasicBlockLABEL(kctx);

	kUntypedNode_SetLabelBlock(kctx, node, KSymbol_("continue"), ItrBB);
	kUntypedNode_SetLabelBlock(kctx, node, KSymbol_("break"),    MergeBB);

	ItrBlock = KLIB kUntypedNode_GetNode(kctx, node, KSymbol_("Iterator"), NULL);
	if(ItrBlock != NULL) {
		assert(Loop == ForLoop);
		MiniVMBuilder_JumpTo(kctx, builder, HeadBB);
	}
	else if(Loop == WhileLoop) {
		MiniVMBuilder_JumpTo(kctx, builder, HeadBB);
	} else {
		MiniVMBuilder_JumpTo(kctx, builder, BodyBB);
	}

	{ /* Head */
		MiniVMBuilder_setBlock(kctx, builder, HeadBB);
		KLIB VisitNode(kctx, builder, kUntypedNode_getFirstNode(kctx, node), thunk);
		CreateBranch(kctx, builder, MiniVM_getExpression(builder), BodyBB, MergeBB, false);
	}

	{ /* Body */
		MiniVMBuilder_setBlock(kctx, builder, BodyBB);
		KLIB VisitNode(kctx, builder, kUntypedNode_getFirstBlock(kctx, node), thunk);
		MiniVMBuilder_JumpTo(kctx, builder, ItrBB);

		/* Itr */
		MiniVMBuilder_setBlock(kctx, builder, ItrBB);
		if(ItrBlock != NULL) {
			KLIB VisitNode(kctx, builder, ItrBlock, thunk);
		}
		MiniVMBuilder_JumpTo(kctx, builder, HeadBB);
	}

	MiniVMBuilder_setBlock(kctx, builder, MergeBB);
	return true;
}
예제 #28
0
static kbool_t MiniVM_VisitReturnNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	kUntypedNode *expr = KLIB kUntypedNode_GetNode(kctx, node, KSymbol_ExprPattern, NULL);
	if(expr != NULL && IS_Node(expr) && expr->typeAttr != KType_void) {
		KLIB VisitNode(kctx, builder, expr, thunk);
		ASM_NMOV(kctx, builder, KClass_(expr->typeAttr), K_RTNIDX, MiniVM_getExpression(builder));
	}
	MiniVMBuilder_JumpTo(kctx, builder, builder->bbReturnId);
	return false;
}
예제 #29
0
static kbool_t MiniVM_VisitBoxNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	/*
	 * [box] := box(this)
	 **/
	KLIB VisitNode(kctx, builder, node->NodeToPush, thunk);
	ASM(BOX, OC_(builder->stackbase), NC_(MiniVM_getExpression(builder)), KClass_(node->typeAttr));
	builder->Value = builder->stackbase;
	return true;
}
예제 #30
0
static kbool_t CollectLocalVar_VisitBlockNode(KVISITOR_PARAM)
{
	unsigned i;
	for(i = 0; i < kUntypedNode_GetNodeListSize(kctx, node); i++) {
		kUntypedNode *stmt = node->NodeList->NodeItems[i];
		if(!KLIB VisitNode(kctx, builder, stmt, thunk))
			break;
	}
	return true;
}