//## String ResultSet.getString(String n); static KMETHOD ResultSet_getString(KonohaContext *kctx, KonohaStack *sfp) { kResultSet *rs = (kResultSet *)sfp[0].asObject; kString *res = TS_EMPTY; int idx = ResultSet_FindColumn(kctx, rs, sfp[1].asString); if(idx >= 0) { ktypeattr_t type = rs->column[idx].type; krbp_t *val = &rs->column[idx].val; if(type == KType_String) { res = val[0].asString; } else if(type == KType_Int) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_printf(kctx, &wb, KFLOAT_FMT, val[0].floatValue); const char *text = KLIB KBuffer_text(kctx, &wb, 0); res = KLIB new_kString(kctx, OnStack, text, KBuffer_bytesize(&wb), 0); KLIB KBuffer_Free(&wb); } else if(KDefinedKonohaCommonModule() && type == KType_float) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_printf(kctx, &wb, KFLOAT_FMT, val[0].floatValue); KLIB KBuffer_Free(&wb); const char *text = KLIB KBuffer_text(kctx, &wb, 0); res = KLIB new_kString(kctx, OnStack, text, KBuffer_bytesize(&wb), 0); KLIB KBuffer_Free(&wb); } } KReturn(res); }
//## String DIR.readFileName() static KMETHOD DIR_readFileName(KonohaContext *kctx, KonohaStack *sfp) { kDir *dir = (kDir *)sfp[0].asObject; if(dir->dirp != NULL) { KMakeTrace(trace, sfp); struct dirent entry, *result; int ret = readdir_r(dir->dirp, &entry, &result); if(result != NULL) { char *d_name = result->d_name; if(dir->readerIconv == ICONV_NULL) { KReturn(KLIB new_kString(kctx, OnStack, d_name, strlen(d_name), StringPolicy_SystemInfo)); } else { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_iconv(kctx, &wb, dir->readerIconv, d_name, strlen(d_name), trace); KReturn(KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer)); } } if(ret == -1) { KTraceErrorPoint(trace, SystemFault, "readdir", LogErrno); } kDir_close(kctx, dir); } KReturn(KNULL(String)); }
static BasicBlock *new_BasicBlock(KonohaContext *kctx, size_t max, bblock_t oldId) { BasicBlock *bb; KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); bb = (BasicBlock *)KLIB KBuffer_Alloca(kctx, &wb, max); if(oldId != -1) { BasicBlock *oldbb = BasicBlock_FindById(kctx, oldId); if(((char *)oldbb) + oldbb->max == (char *)bb) { oldbb->max += (max - sizeof(BasicBlock)); wb.m->bytesize -= sizeof(BasicBlock); return oldbb; } memcpy(bb, oldbb, oldbb->size); oldbb->newid = BasicBlock_id(kctx, bb); oldbb->size = 0; } else { bb->size = sizeof(BasicBlock); bb->newid = -1; bb->nextid = -1; bb->branchid = -1; } bb->max = max; bb->codeoffset = -1; bb->lastoffset = -1; return bb; }
/* copied from src/sugar/sugarfunc.h */ static kString *kToken_ResolveEscapeSequence(KonohaContext *kctx, kToken *tk, size_t start) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); const char *text = kString_text(tk->text) + start; const char *end = kString_text(tk->text) + kString_size(tk->text); KLIB KBuffer_Write(kctx, &wb, kString_text(tk->text), start); while(text < end) { int ch = *text; if(ch == '\\' && *(text+1) != '\0') { switch (*(text+1)) { /* * compatible with ECMA-262 * http://ecma-international.org/ecma-262/5.1/#sec-7.8.4 */ case 'b': ch = '\b'; text++; break; case 't': ch = '\t'; text++; break; case 'n': ch = '\n'; text++; break; case 'v': ch = '\v'; text++; break; case 'f': ch = '\f'; text++; break; case 'r': ch = '\r'; text++; break; case '"': ch = '"'; text++; break; case '\'': ch = '\''; text++; break; case '\\': ch = '\\'; text++; break; default: return NULL; } } { char buf[1] = {ch}; KLIB KBuffer_Write(kctx, &wb, (const char *)buf, 1); } text++; } return KLIB KBuffer_Stringfy(kctx, &wb, OnGcStack, StringPolicy_FreeKBuffer); }
//## String DIR.readPath() static KMETHOD DIR_readPath(KonohaContext *kctx, KonohaStack *sfp) { kDir *dir = (kDir *)sfp[0].asObject; if(dir->dirp != NULL) { KMakeTrace(trace, sfp); struct dirent entry, *result; int ret = readdir_r(dir->dirp, &entry, &result); if(result != NULL) { char *d_name = result->d_name, delim[2] = {'/', 0}; KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_Write(kctx, &wb, kString_text(dir->PathInfoNULL), kString_size(dir->PathInfoNULL)); KLIB KBuffer_Write(kctx, &wb, delim, 1); if(dir->readerIconv != ICONV_NULL) { KLIB KBuffer_Write(kctx, &wb, d_name, strlen(d_name)); } else { KLIB KBuffer_iconv(kctx, &wb, dir->readerIconv, d_name, strlen(d_name), trace); } KReturn(KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer)); } if(ret == -1) { KTraceErrorPoint(trace, SystemFault, "readdir", LogErrno); } kDir_close(kctx, dir); } KReturn(KNULL(String)); }
//## String Curl.receiveString(); static KMETHOD Curl_receiveString(KonohaContext *kctx, KonohaStack *sfp) { kCurl* kcurl = (kCurl *)sfp[0].asObject; /* presets */ struct ReceiveBuffer rbuf = {0}; rbuf.kctx = kctx; KLIB KBuffer_Init(&(kctx->stack->cwb), &rbuf.wb); curl_easy_setopt(kcurl->curl, CURLOPT_WRITEFUNCTION, writeToBuffer); curl_easy_setopt(kcurl->curl, CURLOPT_WRITEDATA, &rbuf); /* perform */ KMakeTrace(trace, sfp); CURLcode res; if(kcurl->headers != NULL) { curl_easy_setopt(kcurl->curl, CURLOPT_HTTPHEADER, kcurl->headers); } KTraceResponseCheckPoint(trace, 0, "curl_easy_perform", res = curl_easy_perform(kcurl->curl) ); if(res != CURLE_OK) { int fault = diagnosisCurlFaultType(kctx, res, (kcurl->URLInfoNULL == NULL) ? 0 : kString_GuessUserFault(kcurl->URLInfoNULL)); KTraceErrorPoint(trace, fault, "curl_easy_perform", LogURL(kcurl), LogCurlStrError(res)); } KReturn(KLIB KBuffer_Stringfy(rbuf.kctx, &rbuf.wb, OnStack, StringPolicy_FreeKBuffer)); }
static void DumpVirtualCode(KonohaContext *kctx, KVirtualCode *c) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); WriteVirtualCode(kctx, &wb, c); DBG_P(">>>\n%s", KLIB KBuffer_text(kctx, &wb, EnsureZero)); KLIB KBuffer_Free(&wb); }
static void dumpMethod(KonohaContext *kctx, KonohaStack *sfp, kMethod *mtd) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); kMethod_WriteToBuffer(kctx, mtd, &wb); PLATAPI printf_i("%s\n", KLIB KBuffer_text(kctx, &wb, EnsureZero)); KLIB KBuffer_Free(&wb); return; }
//## String String.new(Bytes ba); static KMETHOD String_new_fromBytes_withDefaultDecode(KonohaContext *kctx, KonohaStack *sfp) { kBytes *ba = sfp[1].asBytes; kString *s = TS_EMPTY; if(ba->bytesize != 0) { KMakeTrace(trace, sfp); KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KBuffer_convertCharset(kctx, &wb, "UTF-8", I18NAPI systemCharset, ba->buf, ba->bytesize, trace); KLIB KBuffer_text(kctx, &wb, EnsureZero); /* String must be Null terminated */ s = KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer); } KReturn(s); }
//## String File.readLine(); static KMETHOD File_readLine(KonohaContext *kctx, KonohaStack *sfp) { kFile *file = (kFile *)sfp[0].asObject; if(file->fp != NULL) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); int ch, pos = 0, hasUTF8 = false, bufferCount = 0, policy = StringPolicy_ASCII; char buffer[K_PAGESIZE]; KMakeTrace(trace, sfp); while((ch = TRACE_fgetc(kctx, file, trace)) != EOF) { //DBG_P("ch='%c', pos=%d", ch, pos); if(ch == '\r') continue; if(ch == '\n') { if(bufferCount == 0 && (!hasUTF8 || file->readerIconv == ICONV_NULL)) { KReturn(KLIB new_kString(kctx, OnStack, buffer, pos, policy)); } break; } if(ch > 127) { hasUTF8 = true; policy = StringPolicy_UTF8; } buffer[pos] = ch; pos++; if(!(pos < K_PAGESIZE)) { if(hasUTF8 && file->readerIconv != ICONV_NULL) { KLIB KBuffer_iconv(kctx, &wb, file->readerIconv, buffer, pos, trace); } else { KLIB KBuffer_Write(kctx, &wb, buffer, pos); } bufferCount++; hasUTF8 = false; pos = 0; } } if(pos > 0) { if(hasUTF8 && file->readerIconv != ICONV_NULL) { KLIB KBuffer_iconv(kctx, &wb, file->readerIconv, buffer, pos, trace); } else { KLIB KBuffer_Write(kctx, &wb, buffer, pos); } } kFile_CheckEOF(kctx, file, trace); KReturn(KLIB KBuffer_Stringfy(kctx, &wb, OnStack, policy | StringPolicy_FreeKBuffer)); } else { KReturn(KNULL(String)); } }
//## @Public @Const @Immutable @Coercion String Symbol.toString(); static KMETHOD KSymbol_toString(KonohaContext *kctx, KonohaStack *sfp) { ksymbol_t symbol = (ksymbol_t)sfp[0].intValue; kString *s = KSymbol_GetString(kctx, KSymbol_Unmask(symbol)); if(KSymbol_Attr(symbol) != 0) { KBuffer wb; const char *prefix = KSymbol_prefixText(symbol); KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_Write(kctx, &wb, prefix, strlen(prefix)); KLIB KBuffer_Write(kctx, &wb, kString_text(s), kString_size(s)); s = KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer); } KReturn(s); }
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; }
//## String String.new(Bytes ba, String charset); static KMETHOD String_new_fromBytes_withSpecifiedDecode(KonohaContext *kctx, KonohaStack *sfp) { kBytes *ba = sfp[1].asBytes; kString *charset = sfp[2].asString; kString *s = TS_EMPTY; if(ba->bytesize != 0) { // At this point, we assuem 'ba' is null terminated. DBG_ASSERT(ba->buf[ba->bytesize] == '\0'); KMakeTrace(trace, sfp); KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KBuffer_convertCharset(kctx, &wb, kString_text(charset), "UTF-8", ba->buf, ba->bytesize, trace); s = KLIB KBuffer_Stringfy(kctx, &wb, OnStack, StringPolicy_FreeKBuffer); } KReturn(s); }
//## void File.print(String line); static KMETHOD File_print(KonohaContext *kctx, KonohaStack *sfp) { kFile *file = sfp[0].asFile; kString *line = sfp[1].asString; KMakeTrace(trace, sfp); if(file->writerIconv == ICONV_NULL || kString_Is(ASCII, line)) { TRACE_fwrite(kctx, file, kString_text(line), kString_size(line), trace); } else { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_iconv(kctx, &wb, file->writerIconv, kString_text(line), kString_size(line), trace); TRACE_fwrite(kctx, file, KLIB KBuffer_text(kctx, &wb, NonZero), KBuffer_bytesize(&wb), trace); KLIB KBuffer_Free(&wb); } }
//## Bytes String.toBytes(); static KMETHOD String_toBytes(KonohaContext *kctx, KonohaStack *sfp) { kString* thisString = sfp[0].asString; size_t size = kString_size(thisString); if(PLATAPI I18NModule.isSystemCharsetUTF8(kctx)) { KReturn(new_kBytes(kctx, OnStack, KGetReturnType(sfp), kString_text(thisString), size)); } else { KMakeTrace(trace, sfp); KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KBuffer_convertCharset(kctx, &wb, I18NAPI systemCharset, "UTF-8", kString_text(thisString), size, trace); KReturnWith( new_kBytes(kctx, OnStack, KGetReturnType(sfp), KLIB KBuffer_text(kctx, &wb, NonZero), KBuffer_bytesize(&wb)), KLIB KBuffer_Free(&wb) ); } }
static kNode *ParseSource(KonohaContext *kctx, kNameSpace *ns, const char *script, size_t len) { KBuffer wb; KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); KLIB KBuffer_Write(kctx, &wb, "(", 1); KLIB KBuffer_Write(kctx, &wb, script, len); KLIB KBuffer_Write(kctx, &wb, ")", 1); KTokenSeq tokens = {ns, KGetParserContext(kctx)->preparedTokenList}; KTokenSeq_Push(kctx, tokens); const char *buf = KLIB KBuffer_text(kctx, &wb, EnsureZero); SUGAR Tokenize(kctx, ns, buf, 0, 0, tokens.tokenList); KTokenSeq_End(kctx, tokens); KTokenSeq step2 = {ns, tokens.tokenList, kArray_size(tokens.tokenList)}; SUGAR Preprocess(kctx, ns, RangeTokenSeq(tokens), NULL, step2.tokenList); KTokenSeq_End(kctx, step2); kNode *newexpr = SUGAR ParseNewNode(kctx, ns, step2.tokenList, &step2.beginIdx, step2.endIdx, 0, NULL); KTokenSeq_Pop(kctx, tokens); KLIB KBuffer_Free(&wb); return newexpr; }
static void kException_AddStackTrace(KonohaContext *kctx, KonohaStack *sfp, kException *e) { kMethod *mtd = sfp[K_MTDIDX].calledMethod; KBuffer wb; KLIB KBuffer_Init(&kctx->stack->cwb, &wb); kfileline_t uline = sfp[K_RTNIDX].calledFileLine; if(uline > 0) { const char *file = KFileLine_textFileName(uline); KLIB KBuffer_printf(kctx, &wb, "(%s:%d) %s.%s%s" , PLATAPI shortFilePath(file), (kushort_t)uline, kMethod_Fmt3(mtd)); } // int i = 0, psize = kMethod_ParamSize(mtd); // kParam *pa = kMethod_GetParam(mtd); // KClass *thisClass = O_cid(sfp[0]); // for(i = 0; i < psize; i++) { // pa->paramtypeItems[0].attrTypeId; // if(i > 0) { // knh_putc(ctx, cwb->w, ','); // } // knh_Write_fn(ctx, cwb->w, p->fn); // knh_putc(ctx, cwb->w, '='); // knh_Write_sfp(ctx, cwb->w, type, &sfp[i+1], FMT_line); // } const char *msg = KLIB KBuffer_text(kctx, &wb, EnsureZero); KLIB new_kString(kctx, e->StackTraceList, msg, strlen(msg), 0); // if((mtd)->mn != MN_LAMBDA) { // knh_uline_t uline = knh_stack_uline(ctx, sfp); // knh_Write_uline(ctx, cwb->w, uline); // knh_Write_type(ctx, cwb->w, (mtd)->cid); // knh_putc(ctx, cwb->w, '.'); // knh_Write_mn(ctx, cwb->w, (mtd)->mn); // knh_putc(ctx, cwb->w, '('); // knh_putc(ctx, cwb->w, ')'); // if(DP(e)->tracesNULL == NULL) { // KNH_INITv(DP(e)->tracesNULL, new_Array(ctx, CLASS_String, 0)); // } // knh_Array_Add(ctx, DP(e)->tracesNULL, knh_cwb_newString(ctx, cwb)); // } }
static KMETHOD PyObject_toString(KonohaContext *kctx, KonohaStack *sfp) { kPyObject *po = (kPyObject *)sfp[0].asObject; KBuffer wb; // assert DBG_ASSERT(po->self != NULL); KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); kObject_class(sfp[0].asObject)->p(kctx, sfp, 0, &wb); kString *s = KLIB new_kString(kctx, OnStack, KLIB KBuffer_text(kctx, &wb, 1), KBuffer_bytesize(&wb), 0); KLIB KBuffer_Free(&wb); KReturn(s); //if(PyString_Check(po->self)) { // //dec // t = PyString_AsString(po->self); // KReturn(KLIB new_kString(kctx, t, strlen(t), 0)); //} //else if(PyUnicode_Check(po->self)) { // //dec // PyObject *s = PyUnicode_AsUTF8String(po->self); // // [TODO] there is no t's NULL check. Is it OK? // t = PyString_AsString(s); // KReturn(KLIB new_kString(kctx, t, strlen(t), 0)); //} //else if(PyByteArray_Check(po->self)) { // //dec // t = PyByteArray_AsString(po->self); // KReturn(KLIB new_kString(kctx, t, strlen(t), 0)); //} //else { // KBuffer wb; // KLIB KBuffer_Init(&(kctx->stack->cwb), &wb); // kObject_class(sfp[0].asObject)->p(kctx, sfp, 0, &wb, 0); // kString *s = KLIB new_kString(kctx, KLIB KBuffer_text(kctx, &wb, 1), KBuffer_bytesize(&wb), 0); // KLIB KBuffer_Free(&wb); // KReturn(s); //} }
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); }