예제 #1
0
static KMETHOD TypeCheck_Getter(KonohaContext *kctx, KonohaStack *sfp)
{
	VAR_TypeCheck2(stmt, expr, ns, reqc);
	kToken *fieldToken = expr->NodeList->TokenItems[0];
	ksymbol_t fn = fieldToken->symbol;
	kNode *self = KLIB TypeCheckNodeAt(kctx, expr, 1, ns, KClass_INFER, 0);
	if(self != K_NULLNODE) {
		kMethod *mtd = KLIB kNameSpace_GetGetterMethodNULL(kctx, ns, KClass_(self->typeAttr), fn);
		if(mtd != NULL) {
			KFieldSet(expr->NodeList, expr->NodeList->MethodItems[0], mtd);
			KReturn(KLIB TypeCheckMethodParam(kctx, mtd, expr, ns, reqc));
		}
		else {  // dynamic field    o.name => o.get(name)
			kparamtype_t p[1] = {{KType_Symbol}};
			kparamId_t paramdom = KLIB Kparamdom(kctx, 1, p);
			mtd = KLIB kNameSpace_GetMethodBySignatureNULL(kctx, ns, KClass_(self->typeAttr), KMethodNameAttr_Getter, paramdom, 1, p);
			if(mtd != NULL) {
				KFieldSet(expr->NodeList, expr->NodeList->MethodItems[0], mtd);
				KLIB kArray_Add(kctx, expr->NodeList, new_UnboxConstNode(kctx, ns, KType_Symbol, KSymbol_Unmask(fn)));
				KReturn(KLIB TypeCheckMethodParam(kctx, mtd, expr, ns, reqc));
			}
		}
		KLIB MessageNode(kctx, stmt, fieldToken, ns, ErrTag, "undefined field: %s", kString_text(fieldToken->text));
	}
}
예제 #2
0
static kBlock* kStmt_ParseClassBlockNULL(KonohaContext *kctx, kStmt *stmt, kToken *tokenClassName)
{
	kBlock *bk = NULL;
	kToken *blockToken = (kToken *)kStmt_GetObject(kctx, stmt, KW_BlockPattern, NULL);
	if(blockToken != NULL && blockToken->resolvedSyntaxInfo->keyword == KW_BlockPattern) {
		const char *cname = S_text(tokenClassName->text);
		TokenSeq range = {Stmt_ns(stmt), GetSugarContext(kctx)->preparedTokenList};
		TokenSeq_Push(kctx, range);
		SUGAR TokenSeq_Tokenize(kctx, &range,  S_text(blockToken->text), blockToken->uline);
		{
			TokenSeq sourceRange = {range.ns, range.tokenList, range.endIdx};
			kToken *prevToken = blockToken;
			int i;
			for(i = range.beginIdx; i < range.endIdx; i++) {
				kToken *tk = range.tokenList->TokenItems[i];
				if(tk->hintChar == '(' && prevToken->unresolvedTokenType == TokenType_SYMBOL && strcmp(cname, S_text(prevToken->text)) == 0) {
					kTokenVar *newToken = new_(TokenVar, TokenType_SYMBOL, sourceRange.tokenList);
					KFieldSet(newToken, newToken->text, SYM_s(MN_new));
				}
				KLIB kArray_Add(kctx, sourceRange.tokenList, tk);
				prevToken = tk;
			}
			TokenSeq_end(kctx, (&sourceRange));
			bk = SUGAR new_kBlock(kctx, stmt/*parent*/, NULL, &sourceRange);
			KLIB kObject_setObject(kctx, stmt, KW_BlockPattern, TY_Block, bk);
		}
		TokenSeq_Pop(kctx, range);
	}
	return bk;
}
예제 #3
0
// Copied from namespace.h.
static void kNameSpace_AppendArrayRef(KonohaContext *kctx, kNameSpace *ns, const kArray **arrayRef, kObject *o)
{
	if(arrayRef[0] == NULL) {
		((kArray**)arrayRef)[0] = new_(Array, 0, ns->NameSpaceConstList);
	}
	DBG_ASSERT(IS_Array(arrayRef[0]));
	KLIB kArray_Add(kctx, arrayRef[0], o);
}
예제 #4
0
static void copyMethodList(KonohaContext *kctx, ktype_t cid, kArray *s, kArray *d)
{
    size_t i;
    for(i = 0; i < kArray_size(s); i++) {
        kMethod *mtd = s->MethodItems[i];
        if(mtd->typeId != cid) continue;
        KLIB kArray_Add(kctx, d, mtd);
    }
}
예제 #5
0
static KMETHOD Array_Add1(KonohaContext *kctx, KonohaStack *sfp)
{
	kArray *a = sfp[0].asArray;
	if(kArray_isUnboxData(a)) {
		UnboxArray_Add(kctx, a, sfp[1].unboxValue);
	} else {
		KLIB kArray_Add(kctx, a, sfp[1].asObject);
	}
}
예제 #6
0
static void kStmt_appendBlock(KonohaContext *kctx, kStmt *stmt, kBlock *bk)
{
	if(bk != NULL) {
		kBlock *block = SUGAR kStmt_GetBlock(kctx, stmt, Stmt_ns(stmt), KW_BlockPattern, NULL);
		size_t i;
		for(i = 0; i < kArray_size(bk->StmtList); i++) {
			KLIB kArray_Add(kctx, block->StmtList, bk->StmtList->StmtItems[i]);
		}
	}
}
예제 #7
0
static kbool_t KClass_AddField(KonohaContext *kctx, KClass *ct, ktypeattr_t typeattr, ksymbol_t sym)
{
	kuhalfword_t pos = ct->fieldsize;
	if(unlikely(ct->classMethodList == K_EMPTYARRAY)) {
		((KClassVar *)ct)->classMethodList = new_(MethodArray, 8, OnGlobalConstList);
		/*FIXME WriteBarrier */
	}
	INIT_GCSTACK();
	if(pos < ct->fieldAllocSize) {
		KClassVar *definedClass = (KClassVar *)ct;
		definedClass->fieldsize += 1;
		definedClass->fieldItems[pos].name = sym;
		if(KType_Is(UnboxType, typeattr)) {
			definedClass->defaultNullValueVar->fieldUnboxItems[pos] = 0;
			definedClass->fieldItems[pos].typeAttr = typeattr;
		}
		else {
			kObjectVar *o = definedClass->defaultNullValueVar;
			KFieldSet(o, o->fieldObjectItems[pos], KLIB Knull(kctx, KClass_(typeattr)));
			definedClass->fieldItems[pos].typeAttr = typeattr | KTypeAttr_Boxed;
		}
		if(1/*KHalfFlag_Is(flag, kField_Getter)*/) {
			kMethod *mtd = new_FieldGetter(kctx, _GcStack, definedClass->typeId, sym, KTypeAttr_Unmask(typeattr), pos);
			KLIB kArray_Add(kctx, ct->classMethodList, mtd);
		}
		if(!KTypeAttr_Is(ReadOnly, typeattr)/*KHalfFlag_Is(flag, kField_Setter)*/) {
			kMethod *mtd = new_FieldSetter(kctx, _GcStack, definedClass->typeId, sym, KTypeAttr_Unmask(typeattr), pos);
			KLIB kArray_Add(kctx, ct->classMethodList, mtd);
		}
	}
	else {
		if(1/*KHalfFlag_Is(flag, kField_Getter)*/) {
			kMethod *mtd = new_PrototypeGetter(kctx, _GcStack, ct->typeId, sym, KTypeAttr_Unmask(typeattr));
			KLIB kArray_Add(kctx, ct->classMethodList, mtd);
		}
		if(!KTypeAttr_Is(ReadOnly, typeattr)/*KHalfFlag_Is(flag, kField_Setter)*/) {
			kMethod *mtd = new_PrototypeSetter(kctx, _GcStack, ct->typeId, sym, KTypeAttr_Unmask(typeattr));
			KLIB kArray_Add(kctx, ct->classMethodList, mtd);
		}
	}
	RESET_GCSTACK();
	return true;
}
예제 #8
0
//## Expr Expr.addExpr(Expr expr, Expr o);
static KMETHOD kExpr_AddExpr(KonohaContext *kctx, KonohaStack *sfp)
{
	kExpr *expr  = sfp[0].asExpr;
	kExpr *o     = sfp[1].asExpr;
	if(IS_NULL(o) && IS_Array(expr->cons)) {
		kObject_set(NullObject, expr, 1);
	}
	if(IS_NOTNULL(expr)) {
		KLIB kArray_Add(kctx, expr->cons, o);
	}
	KReturn(expr);
}
예제 #9
0
static KClass *CreateEnvClass(KonohaContext *kctx, kNameSpace *ns, kToken *typeTk, KClass **EnvObjectClass)
{
	INIT_GCSTACK();
	size_t i = 0, esize = ns->genv->localScope.varsize;
	size_t start = 0, end = esize;
	KGammaStackDecl *oldenv = ns->genv->localScope.varItems;
	kparamtype_t *p = ALLOCA(kparamtype_t, esize);
	char buf[256] = {'_', '_', '_', 'E', 'N', 'V', 0}, *text = buf + 6;
	if(ns->genv->thisClass == KClass_NameSpace) {
		start = 1;
		end = esize - 1;
	}
	assert(end < 256);
	for(i = start; i <= end; i++) {
		p[i-1].name       = oldenv[i].name;
		p[i-1].attrTypeId = oldenv[i].attrTypeId;
		*(text++) = (KType_text(p[i-1].attrTypeId))[0];
	}

	*EnvObjectClass = KLIB kNameSpace_GetClassByFullName(kctx, ns, buf, text - buf, NULL);
	if(*EnvObjectClass == NULL) {
		*EnvObjectClass = kNameSpace_DefineClassName(kctx, ns, buf, text - buf);
	}

	KClass *ct = KLIB KClass_Generics(kctx, KClass_Func, typeTk->resolvedTypeId, end, p);
	if(end >= 1) {
		((KClassVar *)ct)->classMethodList = new_(MethodArray, end*2, OnGlobalConstList);
		for(i = start; i <= end; i++) {
			int n = i - 1;
			ksymbol_t sym    = p[n].name;
			ktypeattr_t type = KTypeAttr_Unmask(p[n].attrTypeId);
			kMethod *getter = new_FunctionGetter(kctx, _GcStack, ct->typeId, sym, type, n);
			kMethod *setter = new_FunctionSetter(kctx, _GcStack, ct->typeId, sym, type, n);
			KLIB kArray_Add(kctx, ct->classMethodList, getter);
			KLIB kArray_Add(kctx, ct->classMethodList, setter);
		}
	}
	RESET_GCSTACK();
	return ct;
}
예제 #10
0
// ## Array[AprTableEntry] AprTable.getElts()
static KMETHOD AprTable_getElts(KonohaContext *kctx, KonohaStack *sfp)
{
    kAprTable *self = (kAprTable *) sfp[0].asObject;
    kArray *arr = (kArray *)KLIB new_kObject(kctx, OnStack, KClass_Array, 0);
    const apr_array_header_t *apr_arr = apr_table_elts(self->tbl);
    const apr_table_entry_t *entries = (apr_table_entry_t *)apr_arr->elts;
    int i=0;
    for (i=0; i<apr_arr->nelts; i++) {
        KLIB kArray_Add(kctx, arr, (kAprTableEntry *)KLIB new_kObject(kctx, OnStack, KClass_AprTableEntry, (uintptr_t)entries));
        entries++;
    }
    KReturn(arr);
}
예제 #11
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);
	}
}
예제 #12
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);
}
예제 #13
0
//## Token[] Stmt.getTokenList(symbol keyword, Token[] def);
static KMETHOD Stmt_getTokenList(KonohaContext *kctx, KonohaStack *sfp)
{
	kStmt    *stmt    = sfp[0].asStmt;
	ksymbol_t keyword = (ksymbol_t)sfp[1].intValue;
	kArray   *def     = sfp[2].asArray;
	kTokenArray *tokenList = (kTokenArray *)kStmt_GetObject(kctx, stmt, keyword, def);
	kTokenArray *ret;
	if(!IS_Array(tokenList)) {
		ret = new_(TokenArray, 0, OnStack);
		KLIB kArray_Add(kctx, ret, tokenList);
	}
	else {
		ret = tokenList;
	}
	KReturn(ret);
}
예제 #14
0
//## method Array<T> Array.concat(Array<T> a1);
static KMETHOD Array_concat(KonohaContext *kctx, KonohaStack *sfp)
{
	kArray *a0 = sfp[0].asArray;
	kArray *a1 = sfp[1].asArray;
	size_t i;
	if(kArray_isUnboxData(a1)) {
		for (i = 0; i < kArray_size(a1); i++){
			UnboxArray_Add(kctx, a0, a1->unboxItems[i]);
		}
	} else {
		for (i = 0; i < kArray_size(a1); i++){
			KLIB kArray_Add(kctx, a0, a1->ObjectItems[i]);
		}
	}
	KReturn(a0);
}
예제 #15
0
static void MacroSet_setTokenAt(KonohaContext *kctx, MacroSet *macroSet, int index, kArray *tokenList, const char *symbol, ...)
{
	DBG_ASSERT(macroSet[index].tokenList == NULL);
	macroSet[index].symbol = KLIB Ksymbol(kctx, symbol, strlen(symbol), StringPolicy_TEXT|StringPolicy_ASCII, _NEWID);
	macroSet[index].tokenList = tokenList;
	macroSet[index].beginIdx = kArray_size(tokenList);
	kToken *tk;
	va_list ap;
	va_start(ap , symbol);
	while((tk = va_arg(ap, kToken *)) != NULL) {
		DBG_ASSERT(IS_Token(tk));
		KLIB kArray_Add(kctx, tokenList, tk);
	}
	va_end(ap);
	macroSet[index].endIdx = kArray_size(tokenList);
}
예제 #16
0
static KMETHOD Statement_syntax(KonohaContext *kctx, KonohaStack *sfp)
{
	kbool_t r = 0;
	VAR_Statement(stmt, gma);
	kTokenArray *tokenList = (kTokenArray *)kStmt_GetObject(kctx, stmt, KW_TokenPattern, NULL);
	if(tokenList == NULL) {
		SUGAR kStmt_Message2(kctx, stmt, NULL, ErrTag, "empty syntax");
	}
	if(tokenList != NULL) {
		if(!IS_Array(tokenList)) { // create tokenList from a Token
			kTokenArray *a = new_(TokenArray, 0, OnGcStack);
			KLIB kArray_Add(kctx, a, tokenList);
			tokenList = a;
		}
		DBG_ASSERT(IS_Array(tokenList));
		kNameSpace *ns = Stmt_ns(stmt);
		SugarSyntaxVar *syn = kNameSpace_guessSyntaxFromTokenList(kctx, ns, tokenList);
		if(syn != NULL) {
			if(syn->syntaxPatternListNULL_OnList != NULL) {
				SUGAR kStmt_Message2(kctx, stmt, NULL, InfoTag, "oveloading syntax: %s%s", PSYM_t(syn->keyword));
			}
			else {
				syn->syntaxPatternListNULL_OnList = new_(TokenArray, 0, ns->NameSpaceConstList);
			}
			TokenSeq tokens = {ns, tokenList, 0, kArray_size(tokenList)};
			// Referred to kNameSpace_ParseSyntaxPattern in ast.h.
			kArray *patternList = syn->syntaxPatternListNULL_OnList;
			size_t firstPatternIdx = kArray_size(patternList);
			SUGAR kArray_AddSyntaxRule(kctx, patternList, &tokens);
			if(firstPatternIdx < kArray_size(patternList)) {
				kToken *firstPattern = patternList->TokenItems[firstPatternIdx];
				if(kToken_isFirstPattern(firstPattern)) {
					kNameSpace_AppendArrayRef(kctx, ns, &((kNameSpaceVar *)ns)->stmtPatternListNULL_OnList, UPCAST(firstPattern));
				}
			}
			r = 1;
		}
		kStmt_done(kctx, stmt);
	}
	KReturnUnboxValue(r);
}
예제 #17
0
static kObject *MiniVM_AddConstPool(KonohaContext *kctx, KBuilder *builder, kObject *o)
{
	KLIB kArray_Add(kctx, builder->constPools, o);
	return o;
}
예제 #18
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);
}