Exemple #1
0
static KMETHOD Statement_ConstDecl(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck(stmt, ns, reqc);
	kToken *symbolToken = SUGAR kNode_GetToken(kctx, stmt, KSymbol_SymbolPattern, NULL);
	ksymbol_t unboxKey = symbolToken->symbol;
	kNode *constNode = SUGAR TypeCheckNodeByName(kctx, stmt, KSymbol_ExprPattern, ns, KClass_INFER, TypeCheckPolicy_CONST);
	if(!kNode_IsError(constNode)) {
		KClass *constClass = KClass_(constNode->attrTypeId);
		ktypeattr_t type = constClass->typeId;
		uintptr_t unboxValue;
		kbool_t result = false;
		if(kNode_node(constNode) == KNode_Null) {   // const C = String
			type = VirtualType_KClass;
			unboxValue = (uintptr_t)constClass;
			result = true;
		}
		else if(kNode_node(constNode) == KNode_Const) {   // const C = "1"
			unboxValue = (uintptr_t)constNode->ObjectConstValue;
			result = true;
		}
		else if(kNode_node(constNode) == KNode_UnboxConst) {  // const c = 1
			unboxValue = constNode->unboxConstValue;
			result = true;
		}
		if(result) {
			KMakeTraceUL(trace, sfp, kNode_uline(stmt));
			result = KLIB kNameSpace_SetConstData(kctx, ns, unboxKey, type, unboxValue, trace);
		}
		else {
			kNode_Message(kctx, stmt, ErrTag, "constant value is expected: %s%s", KSymbol_Fmt2(unboxKey));
		}
		constNode = kNode_Type(kctx, stmt, KNode_Done, KType_void);
	}
	KReturn(constNode);
}
Exemple #2
0
//## Token Node.getToken(Symbol key, Token def);
static KMETHOD Node_getToken(KonohaContext *kctx, KonohaStack *sfp)
{
	kNode *stmt   = sfp[0].asNode;
	ksymbol_t key = (ksymbol_t)sfp[1].intValue;
	kToken *def   = sfp[2].asToken;
	KReturn(SUGAR kNode_GetToken(kctx, stmt, key, def));
}
static KMETHOD Statement_class(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck(stmt, ns, reqc);
	kToken *tokenClassName = SUGAR kNode_GetToken(kctx, stmt, KSymbol_("$ClassName"), NULL);
	int isNewlyDefinedClass = false;
	KClassVar *definedClass = (KClassVar *)KLIB kNameSpace_GetClassByFullName(kctx, ns, kString_text(tokenClassName->text), kString_size(tokenClassName->text), NULL);
	if(definedClass == NULL) {   // Already defined
		kshortflag_t cflag = kNode_ParseClassFlag(kctx, stmt, KClassFlag_Virtual);
		KMakeTraceUL(trace, sfp, kNode_uline(stmt));
		definedClass = kNameSpace_DefineClassName(kctx, ns, cflag, tokenClassName->text, trace);
		isNewlyDefinedClass = true;
	}
	kNode *block = kNode_ParseClassNodeNULL(kctx, stmt, tokenClassName);
	size_t declsize = kNode_countFieldSize(kctx, block);
	if(isNewlyDefinedClass) {   // Already defined
		KClass *superClass = KClass_Object;
		kToken *tokenSuperClass= SUGAR kNode_GetToken(kctx, stmt, KSymbol_("extends"), NULL);
		if(tokenSuperClass != NULL) {
			DBG_ASSERT(Token_isVirtualTypeLiteral(tokenSuperClass));
			superClass = KClass_(Token_typeLiteral(tokenSuperClass));
			if(KClass_Is(Final, superClass)) {
				KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s is final", KClass_text(superClass)));
			}
			if(KClass_Is(Virtual, superClass)) {
				KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s is still virtual", KClass_text(superClass)));
			}
		}
		size_t initsize = (block != NULL) ? declsize : initFieldSizeOfVirtualClass(superClass);
		KClass_InitField(kctx, definedClass, superClass, initsize);
	}
	else {
		if(declsize > 0 && !KClass_Is(Virtual, definedClass)) {
			KReturn(SUGAR MessageNode(kctx, stmt, NULL, ns, ErrTag, "%s has already defined", KClass_text(definedClass)));
		}
	}
	if(block != NULL) {
		if(!kNode_declClassField(kctx, block, ns, definedClass)) {
			KReturnUnboxValue(false);
		}
		KClass_Set(Virtual, definedClass, false);
	}
	kToken_SetTypeId(kctx, tokenClassName, ns, definedClass->typeId);
	kNode_AddMethodDeclNode(kctx, block, tokenClassName, stmt);
	KReturn(kNode_Type(kctx, stmt, KNode_Done, KType_void));
}
Exemple #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;
}
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);
}
Exemple #6
0
static KMETHOD Statement_namespace(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck(stmt, ns, reqc);
	kstatus_t result = K_CONTINUE;
	kToken *tk = SUGAR kNode_GetToken(kctx, stmt, KSymbol_BlockPattern, NULL);
	if(tk != NULL && tk->resolvedSyntaxInfo->keyword == TokenType_LazyBlock) {
		INIT_GCSTACK();
		kNameSpace *ns = new_(NameSpace, kNode_ns(stmt), _GcStack);
		KTokenSeq range = {ns, KGetParserContext(kctx)->preparedTokenList};
		KTokenSeq_Push(kctx, range);
		SUGAR Tokenize(kctx, ns, kString_text(tk->text), tk->uline, tk->indent, range.tokenList);
		KTokenSeq_End(kctx, range);
		result = SUGAR EvalTokenList(kctx, &range, NULL/*trace*/);
		KTokenSeq_Pop(kctx, range);
		RESET_GCSTACK();
		kNode_Type(kctx, stmt, KNode_Done, KType_void);
	}
	KReturnUnboxValue(result == K_CONTINUE);
}
Exemple #7
0
/* ------------------------------------------------------------------------ */
static KMETHOD TypeCheck_Closure(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck(expr, ns, reqc);
	kNode *texpr = K_NULLNODE;
	INIT_GCSTACK();
	kToken *typeTk   = SUGAR kNode_GetToken(kctx, expr, KSymbol_TypePattern, NULL);
	KClass *EnvObjectClass = NULL;
	KClass *envCt = CreateEnvClass(kctx, ns, typeTk, &EnvObjectClass);

	kMethod *mtd = CompileClosure(kctx, ns, expr, envCt, typeTk, &texpr);
	/* type check is OK */
	if(texpr != K_NULLNODE) {
		/*
		 * FunctionExpression
		 * 0: Method
		 * 1: EnvObject's Default Object
		 * 2: Current LocalScope Variable
		 * 3: ditto
		 * 4: ...
		 */
		kNode_Type(texpr, KNode_Function, envCt->typeId);
		KFieldSet(expr, texpr->NodeList, new_(Array, 0, OnField));
		KLIB kArray_Add(kctx, texpr->NodeList, mtd);
		KLIB kArray_Add(kctx, texpr->NodeList, KLIB Knull(kctx, EnvObjectClass));
		size_t i = 0;
		struct KGammaLocalData *genv = ns->genv;
		if(genv->thisClass == KClass_NameSpace) {
			i = 1;
		}
		for(; i < genv->localScope.varsize; i++) {
			kNode *node = new_VariableNode(kctx, ns, KNode_Local, genv->localScope.varItems[i].attrTypeId, i);
			KLIB kArray_Add(kctx, texpr->NodeList, node);
		}
	}
	RESET_GCSTACK();
	KReturn(texpr);
}