예제 #1
0
static kbool_t MiniVM_VisitLocalNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	intptr_t src;
	ksymbol_t symbol;
	assert(IS_Token(node->TermToken));
	symbol = node->TermToken->symbol;
	if((src = MiniVMBuilder_FindLocalVar(kctx, builder, symbol, node->typeAttr, node->index)) == -1) {
		src = AddLocal(kctx, builder, node->index, symbol, node->typeAttr);
	}
	builder->Value = src;
	return true;
}
예제 #2
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);
}
예제 #3
0
static kbool_t MiniVM_VisitFieldNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	ksymbol_t symbol;
	intptr_t src;
	KClass *ty;

	khalfword_t index  = (khalfword_t)(node->index);
	khalfword_t xindex = (khalfword_t)(node->index >> (sizeof(khalfword_t)*8));
	assert(IS_Token(node->TermToken));
	symbol = node->TermToken->symbol;
	if((src = MiniVMBuilder_FindLocalVar(kctx, builder, symbol, KType_Object, index)) == -1) {
		src = AddLocal(kctx, builder, index, symbol, KType_Object);
	}
	ty = KClass_(node->typeAttr);
	ASM(NMOVx, TC_(builder->stackbase, ty), OC_(src), xindex, ty);
	builder->Value = builder->stackbase;
	return true;
}
예제 #4
0
static kbool_t MiniVM_VisitAssignNode(KonohaContext *kctx, KBuilder *builder, kUntypedNode *node, void *thunk)
{
	/*
	 * [LetExpr] := lhs = rhs
	 * expr->NodeList = [NULL, lhs, rhs]
	 **/

	intptr_t dst = -1;
	kUntypedNode *left = kUntypedNode_At(node, 1);
	kUntypedNode *right = kUntypedNode_At(node, 2);
	ktypeattr_t type = left->typeAttr;
	ksymbol_t symbol;

	assert(IS_Token(left->TermToken));
	symbol = left->TermToken->symbol;
	if(kUntypedNode_node(left) == KNode_Local) {
		if((dst = MiniVMBuilder_FindLocalVar(kctx, builder, symbol, type, left->index)) == -1) {
			dst = AddLocal(kctx, builder, left->index, symbol, type);
		}
		KLIB VisitNode(kctx, builder, right, thunk);
		CreateUpdate(kctx, builder, type, dst, MiniVM_getExpression(builder));
		builder->Value = dst;
	}
	else {
		khalfword_t index  = (khalfword_t)left->index;
		khalfword_t xindex = (khalfword_t)(left->index >> (sizeof(khalfword_t)*8));
		KClass *lhsClass = KClass_(left->typeAttr);
		KClass *rhsClass = KClass_(right->typeAttr);
		assert(kUntypedNode_node(left) == KNode_Field);
		if((dst = MiniVMBuilder_FindLocalVar(kctx, builder, symbol, KType_Object, index)) == -1) {
			dst = AddLocal(kctx, builder, index, symbol, KType_Object);
		}
		KLIB VisitNode(kctx, builder, right, thunk);
		ASM(XNMOV, OC_(index), xindex, TC_(MiniVM_getExpression(builder), rhsClass), lhsClass);
		if(node->typeAttr != KType_void) {
			builder->Value = builder->stackbase;
			ASM(NMOVx, TC_(builder->stackbase, rhsClass), OC_(index), xindex, lhsClass);
		}
	}
	return true;
}
예제 #5
0
파일: stmt.c 프로젝트: matsuu/konoha
void knh_Stmt_toERR(Ctx *ctx, Stmt *stmt, Term *tm)
{
    if(SP(stmt)->stt == STT_ERR) return;
    SP(stmt)->stt = STT_ERR;
    knh_uri_t uri = 0;
    int line = 0;
    if(IS_Token(tm)) {
        uri =  SP((Token*)tm)->uri;
        line =  SP((Token*)tm)->line;
    }
    else if(IS_Stmt(tm)) {
        uri =  SP((Stmt*)tm)->uri;
        line =  SP((Stmt*)tm)->line;
    }
    {
        char buf[256];
        knh_snprintf(buf, sizeof(buf), "Script!!: running errors at %s:%d", URIDN(SP(stmt)->uri), SP(stmt)->line);
        KNH_SETv(ctx, DP(stmt)->errMsg, new_String(ctx, B(buf), NULL));
        KNH_SETv(ctx, DP(stmt)->next, KNH_NULL);
    }
}
예제 #6
0
파일: stmt.c 프로젝트: matsuu/konoha
void knh_Stmt__s(Ctx *ctx, Stmt *o, OutputStream *w, String *m)
{
    knh_intptr_t i;
    knh_putc(ctx, w, '(');
    if(SP(o)->stt != STT_OP && SP(o)->stt != STT_NEW && SP(o)->stt != STT_CALL ) {
        knh_write_char(ctx, w, knh_stmt_tochar(SP(o)->stt));
        if(DP(o)->size > 0) {
            knh_putc(ctx, w, ' ');
        }
    }
    for(i = 0; i < DP(o)->size; i++) {
        if(i > 0) knh_putc(ctx, w, ' ');
        if(IS_Token(DP(o)->terms[i])) {
            knh_Token__s(ctx, DP(o)->tokens[i], w, m);
        } else {
            KNH_ASSERT(IS_Stmt(DP(o)->terms[i]));
            knh_Stmt__s(ctx, DP(o)->stmts[i], w, m);
            if(IS_NOTNULL(DP(DP(o)->stmts[i])->next)) {
                knh_write_dots(ctx, w);
            }
        }
    }
    knh_putc(ctx, w, ')');
}
예제 #7
0
void knh_vprintf(Ctx *ctx, knh_OutputStream_t *w, const char *fmt, va_list ap)
{
	knh_valist_t args[10];
	const char *c = fmt;
	int i, ch, bindex = 0, bindex_max = 10;
	for(i = 0; i < bindex_max; i++) args[i].atype = 0;
	while((ch = *c) != '\0') {
		c++;
		if(ch == '%') {
			int index;
			ch = *c;
			if(ch == '%') {
				c++;
				continue;
			}
			index = bindex++;
			c = knh_vprintf_parseindex(c++, &index);
			//DBG_P("bindex=%d, index=%d", bindex, index);
			switch(ch) {
				case 'd': case 'u':
				args[index].atype = VA_DIGIT; break;
				case 'l': case 'i':
					args[index].atype = VA_LONG; break;
				case 'f': case 'e':
					args[index].atype = VA_FLOAT; break;
				case 's':
					args[index].atype = VA_CHAR; break;
				case 'p':
					args[index].atype = VA_POINTER; break;
				case 'L':
				case 'K': case 'k':
				case 'O': case 'o':
					args[index].atype = VA_OBJECT; break;
				case 'N': case 'F':
					args[index].atype = VA_FIELDN; break;
				case 'M':
					args[index].atype = VA_METHODN; break;
				case 'C':
					args[index].atype = VA_CLASS; break;
				case 'T':
					args[index].atype = VA_TYPE; break;
				case 'B':
					args[index].atype = VA_BYTES; break;
				// TODO
				// we should care if "fmt" has "%%".
				// sometimes, next args is NULL.
				case '%':
					index--;
					c++;
				default:
					bindex--;
			}
			if(bindex == 10) {
				DBG_ASSERT(bindex < 10);
				break;
			}
		}
	}

	for(i = 0; i < 10; i++) {
		switch(args[i].atype) {
		case VA_DIGIT:
			args[i].dvalue = (knh_intptr_t)va_arg(ap, knh_intptr_t); break;
		case VA_LONG:
			args[i].ivalue = (knh_int_t)va_arg(ap, knh_int_t); break;
		case VA_FLOAT:
#if defined(K_USING_NOFLOAT)
			args[i].fvalue = (knh_float_t)va_arg(ap, knh_float_t);
#else
			args[i].fvalue = (knh_float_t)va_arg(ap, double);
#endif
			break;
		case VA_CHAR:
			args[i].svalue = (char*)va_arg(ap, char*); break;
		case VA_POINTER:
			args[i].pvalue = (void*)va_arg(ap, void*); break;
		case VA_OBJECT:
			args[i].ovalue = (Object*)va_arg(ap, Object*); break;
		case VA_FIELDN:
			args[i].fn = (knh_fieldn_t)va_arg(ap, int/*knh_fieldn_t*/); break;
		case VA_METHODN:
			args[i].mn = (knh_methodn_t)va_arg(ap, int/*knh_methodn_t*/); break;
		case VA_CLASS:
			args[i].cid = (knh_class_t)va_arg(ap, int/*knh_class_t*/); break;
		case VA_TYPE:
			args[i].type = (knh_type_t)va_arg(ap, int/*knh_type_t*/); break;
		case VA_BYTES:
			args[i].bvalue = (knh_bytes_t)va_arg(ap, knh_bytes_t); break;
		default:
			bindex_max = i;
			goto L_FORMAT;
		}
	}

	L_FORMAT: {
		knh_bytes_t b;
		knh_Method_t *mtd = NULL;
		knh_sfp_t *esp = ctx->esp;
		c = fmt;
		bindex = 0;
		b.text = c;
		b.len = 0;
		while((ch = *c) != '\0') {
			c++;
			if(ch == '\\') {
				if(b.len > 0) {
					knh_print(ctx, w, b);
				}
				ch = *c;
				switch(ch) {
					case '\0' : return ;
					case 'n': knh_println(ctx, w, STEXT("")); break;
					case 't': knh_write_TAB(ctx, w); break;
					default:
						knh_putc(ctx, w, '\\');
						knh_putc(ctx, w, ch);
				}
				b.text = c;
				b.len = 0;
			}
			else if(ch == '%') {
				if(b.len > 0) {
				  knh_print(ctx, w, b);
				}
				ch = *c;
				if(ch == '%') {
					knh_putc(ctx, w, '%');
					c++;
					b.text = c;
					b.len = 0;
					continue;
				}
				int index = bindex++;
				c = knh_vprintf_parseindex(++c, &index);

				switch(ch) {
					case '\0' : return ;
					case 'd':
						DBG_ASSERT(args[index].atype == VA_DIGIT);
						knh_write_dfmt(ctx, w, K_INTPTR_FMT, args[index].dvalue);
						break;
					case 'u':
						DBG_ASSERT(args[index].atype == VA_DIGIT);
						knh_write_dfmt(ctx, w, K_INTPTR_UFMT, args[index].uvalue);
						break;
					case 'l': case 'i' :
						DBG_ASSERT(args[index].atype == VA_LONG);
						knh_write_ifmt(ctx, w, K_INT_FMT, args[index].ivalue);
						break;
					case 'f':
						DBG_ASSERT(args[index].atype == VA_FLOAT);
						knh_write_ffmt(ctx, w, K_FLOAT_FMT, args[index].fvalue);
						break;
					case 'e':
						DBG_ASSERT(args[index].atype == VA_FLOAT);
						knh_write_ffmt(ctx, w, K_FLOAT_FMTE, args[index].fvalue);
						break;
					case 's':
						DBG_ASSERT(args[index].atype == VA_CHAR);
						knh_write(ctx, w, B(args[index].svalue));
						break;
					case 'p':
						DBG_ASSERT(args[index].atype == VA_POINTER);
						knh_write__p(ctx, w, args[index].pvalue);
						break;
					case 'L':
						DBG_ASSERT(args[index].atype == VA_OBJECT);
						if(IS_Token(args[index].ovalue)) {
							knh_write_token(ctx, w, (knh_Token_t*)args[index].ovalue);
							break;
						}
					case 'O': case 'o':
						DBG_ASSERT(args[index].atype == VA_OBJECT);
						mtd = knh_getSystemFormatter(ctx, knh_Object_cid(args[index].ovalue), MN__s);
						knh_write_Object(ctx, w, esp, &mtd, args[index].ovalue);
						break;
					case 'K': case 'k':
						DBG_ASSERT(args[index].atype == VA_OBJECT);
						mtd = knh_getSystemFormatter(ctx, knh_Object_cid(args[index].ovalue), MN__k);
						knh_write_Object(ctx, w, esp, &mtd, args[index].ovalue);
						break;
					case 'N': case 'F':
						DBG_ASSERT(args[index].atype == VA_FIELDN);
						knh_write_text(ctx, w, FN__(args[index].fn));
						break;
					case 'M':
						DBG_ASSERT(args[index].atype == VA_METHODN);
						knh_write_mn(ctx, w, args[index].mn);
						break;
					case 'C':
						DBG_ASSERT(args[index].atype == VA_CLASS);
						knh_write_sname(ctx, w, args[index].cid);
						break;
					case 'T':
						DBG_ASSERT(args[index].atype == VA_TYPE);
						knh_write_type(ctx, w, args[index].type);
						break;
					case 'B':
						DBG_ASSERT(args[index].atype == VA_BYTES);
						knh_write(ctx,w, args[index].bvalue);
						break;
					case '%':
						index--;
						bindex--;
					default:
						//knh_putc(ctx, w, '%');
						knh_putc(ctx, w, ch);
				}
				b.text = c;
				b.len = 0;
				if(!(bindex <= bindex_max)) {
					DBG_ASSERT(bindex <= bindex_max);
					break;
				}
			}
			else {
				b.len = b.len+1;
			}
		}
		if(b.len > 0) {
		  knh_print(ctx, w, b);
		}
	}
}
예제 #8
0
static KMETHOD Statement_import(KonohaContext *kctx, KonohaStack *sfp)
{
	int ret = false;
	VAR_Statement(stmt, gma);
	kTokenArray *tokenList = (kTokenArray *) kStmt_GetObjectNULL(kctx, stmt, KW_TokenPattern);
	if(tokenList == NULL) {
		KReturnUnboxValue(false);
	}
	kNameSpace *ns = Stmt_ns(stmt);
	SugarSyntaxVar *syn = (SugarSyntaxVar *) SYN_(ns, KW_ExprMethodCall);
	kExpr *expr;
	kTokenVar *tkImport = /*G*/new_(TokenVar, 0, OnGcStack);
	tkImport->resolvedSymbol = MN_("import");
	if(IS_Token(tokenList)) {
		kTokenArray *list = ((kToken *) tokenList)->subTokenList;
		if(IS_String(list)) {
			/* case: import cstyle; */
			kString *pkgname = (kString *) list;
			expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname);
		}
		else if(kArray_size(list) == 1) {
			/* case : import("konoha.import"); */
			kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text);
			expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 3,
					tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)), param0);
		}
		else if(kArray_size(list) == 2) {
			/* case : import("konoha.import", "import"); */
			kExpr *param0 = makeStringConstValue(kctx, list->TokenItems[0]->text);
			kExpr *param1 = makeStringConstValue(kctx, list->TokenItems[1]->text);
			expr = SUGAR new_UntypedCallStyleExpr(kctx, syn, 4,
					tkImport, new_ConstValueExpr(kctx, O_ct(ns), UPCAST(ns)),
					param0, param1);
		} else {
			KReturnUnboxValue(false);
		}
	} else {
		KGrowingBuffer wb;
		KLIB KBuffer_Init(&(kctx->stack->cwb), &wb);
		/* case : import konoha.import */
		ksymbol_t star = SYM_("*");
		size_t i = 0;
		if(i + 2 < kArray_size(tokenList)) {
			for (; i < kArray_size(tokenList)-1; i+=2) {
				/* name . */
				kToken *tk  = tokenList->TokenItems[i+0];
				if(i+2 < kArray_size(tokenList)) {
					kToken *startTk = tokenList->TokenItems[i+2];
					if(startTk->resolvedSyntaxInfo->keyword == star) {
						break;
					}
				}
				KLIB KBuffer_Write(kctx, &wb, S_text(tk->text), S_size(tk->text));
				KLIB KBuffer_Write(kctx, &wb, ".", 1);
			}
		}
		kString *name = tokenList->TokenItems[i]->text;
		KLIB KBuffer_Write(kctx, &wb, S_text(name), S_size(name));

		kString *pkgname = KLIB new_kString(kctx, OnGcStack, KLIB KBuffer_Stringfy(kctx, &wb, 1), KBuffer_bytesize(&wb), 0);
		expr = CreateImportCall(kctx, syn, tkImport, ns, pkgname);
	}
	KLIB kObjectProto_SetObject(kctx, stmt, KW_ExprPattern, TY_Expr, expr);
	ret = SUGAR kStmt_TypeCheckByName(kctx, stmt, KW_ExprPattern, gma, CT_void, TypeCheckPolicy_ALLOWVOID);
	if(ret) {
		kStmt_typed(stmt, EXPR);
	}
	KReturnUnboxValue(ret);
}