knh_flag_t knh_StmtMETHOD_flag(Ctx *ctx, Stmt *o) { knh_flag_t flag = 0; if(IS_DictMap(DP(o)->metaDictMap)) { Object *v = knh_DictMap_get__b(ctx, DP(o)->metaDictMap, STEXT("Virtual")); if(IS_NOTNULL(v)) { flag |= KNH_FLAG_MF_VIRTUAL; } v = knh_DictMap_get__b(ctx, DP(o)->metaDictMap, STEXT("Abstract")); if(IS_NOTNULL(v)) { flag |= KNH_FLAG_MF_VIRTUAL; } v = knh_DictMap_get__b(ctx, DP(o)->metaDictMap, STEXT("Private")); if(IS_NOTNULL(v)) { flag |= KNH_FLAG_MF_PRIVATE; } v = knh_DictMap_get__b(ctx, DP(o)->metaDictMap, STEXT("Const")); if(IS_NOTNULL(v)) { flag |= KNH_FLAG_MF_CONST; } v = knh_DictMap_get__b(ctx, DP(o)->metaDictMap, STEXT("Static")); if(IS_NOTNULL(v)) { flag |= KNH_FLAG_MF_STATIC; } } return flag; }
static METHOD knh__String_substring(Ctx *ctx, knh_sfp_t *sfp) { knh_bytes_t base = knh_String_tobytes(sfp[0].s); knh_bytes_t sub; if(knh_String_isASCII(sfp[0].s)) { size_t offset = IS_NULL(sfp[1].o) ? 0 : knh_array_index(ctx, sfp[1].ivalue, base.len); sub = knh_bytes_last(base, offset); if(IS_NOTNULL(sfp[2].o)) { size_t len = (size_t)sfp[2].ivalue; if(len < sub.len) sub = knh_bytes_first(sub, len); } } else { // multibytes size_t mlen = knh_bytes_mlen(base); size_t offset = IS_NULL(sfp[1].o) ? 0 : knh_array_index(ctx, sfp[1].ivalue, mlen); size_t length = IS_NULL(sfp[2].o) ? (mlen - offset) : (size_t)sfp[2].ivalue; sub = knh_bytes_mofflen(base, offset, length); } String *s; if(sub.len == 0) { s = TS_EMPTY; } else if(sub.len == base.len) { s = sfp[0].s; } else { s = new_String(ctx, sub, sfp[0].s); } KNH_RETURN(ctx, sfp, s); }
static void kArray_executeRegExp(KonohaContext *kctx, kArray *resultArray, kRegExp *regex, kString *s0) { int stringPolicy = kString_is(ASCII, s0) ? StringPolicy_ASCII : 0; if(IS_NOTNULL(regex) && S_size(regex->pattern) > 0) { const char *s = S_text(s0); // necessary const char *base = s; const char *eos = base + S_size(s0); size_t i, nmatch = pcre_nmatchsize(kctx, regex->reg); kregmatch_t *p, pmatch[nmatch+1]; int isGlobalOption = RegExp_isGlobal(regex); do { int res = pcre_regexec(kctx, regex->reg, s, nmatch, pmatch, regex->eflags); if(res != 0) { // FIXME //LOG_regex(kctx, sfp, res, regex, s); break; } for(p = pmatch, i = 0; i < nmatch; p++, i++) { if(p->rm_so == -1) break; KLIB new_kString(kctx, resultArray, s + (p->rm_so), ((p->rm_eo) - (p->rm_so)), stringPolicy); } if(isGlobalOption) { size_t eo = pmatch[0].rm_eo; // shift matched pattern s += (eo > 0) ? eo : 1; if(!(s < eos)) isGlobalOption = 0; // stop iteration } } while(isGlobalOption); } }
static METHOD knh__String_opSubsete(Ctx *ctx, knh_sfp_t *sfp) { if(IS_NOTNULL(sfp[2].o)) { size_t offset = IS_NULL(sfp[1].o) ? 0 : (size_t)sfp[1].ivalue; sfp[2].ivalue = sfp[2].ivalue - offset + 1; } knh__String_substring(ctx, sfp); }
//## int Token.error(String s, String s, int begin, int end); static KMETHOD Token_error(KonohaContext *kctx, KonohaStack *sfp) { kTokenVar *tk = (kTokenVar *) sfp[0].asToken; if(IS_NOTNULL(tk)) { SUGAR kToken_ToError(kctx, tk, ErrTag, "%s", S_text(sfp[1].asString)); } KReturnUnboxValue(sfp[4].intValue); }
static void knh_getToken(ksfp_t *sfp, AccessToken_t *token) { kObject *consumer = sfp[0].ox->fields[0]; kObject *rtoken = sfp[0].ox->fields[1]; if (IS_NOTNULL(consumer)) { kObject *of = (kObject *)consumer; token->key = S_totext((kString*)of->fields[0]); token->secret = S_totext((kString*)of->fields[1]); } if (IS_NOTNULL(rtoken)) { kObject *of = (kObject *)rtoken; token->rtoken = S_totext((kString *)of->fields[0]); token->rtoken_secret = S_totext((kString *)of->fields[1]); } DBG_P("consumer_key: %s, consumer_secret: %s", token->key, token->secret); DBG_P("request_token: %s, request_token_secret: %s", token->rtoken, token->rtoken_secret); }
int knh_StmtMETA_is(Ctx *ctx, Stmt *stmt, knh_bytes_t name) { if(IS_DictMap(DP(stmt)->metaDictMap)) { Object *v = knh_DictMap_get__b(ctx, DP(stmt)->metaDictMap, name); if(IS_NOTNULL(v)) return 1; } return 0; }
knh_bool_t knh_StmtMETA_isOverride(Ctx *ctx, Stmt *o) { if(IS_DictMap(DP(o)->metaDictMap)) { Object *v = knh_DictMap_get__b(ctx, DP(o)->metaDictMap, STEXT("Override")); if(IS_NOTNULL(v)) return 1; } return 0; }
Stmt *knh_Stmt_tail(Ctx *ctx, Stmt *o) { Stmt *tail = o; while(IS_NOTNULL(DP(tail)->next)) { //DBG_P("stt=%s", knh_stmt_tochar(SP(tail)->stt)); tail = DP(tail)->next; } return tail; }
knh_flag_t knh_StmtPRINT_flag(Ctx *ctx, Stmt *o) { knh_flag_t flag = 0; if(IS_bDictMap(DP(o)->metaDictMap)) { Object *v = knh_DictMap_get__b(ctx, DP(o)->metaDictMap, STEXT("time")); if(IS_NOTNULL(v)) { flag |= KNH_FLAG_PF_TIME; } } return flag; }
//## 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); }
void knh_Stmt__dump(Ctx *ctx, Stmt *o, OutputStream *w, String *m) { L_RESTART: ; if(IS_DictMap(DP(o)->metaDictMap)) { knh_StmtMETA_dump(ctx, o, w, m); } knh_printf(ctx, w, "%s\t", knh_stmt_tochar(SP(o)->stt)); knh_Stmt__s(ctx, o, w, m); if(IS_NOTNULL(DP(o)->next)) { knh_putc(ctx, w, '\n'); o = DP(o)->next; goto L_RESTART; } }
//## int Token.parse(symbol keyword, String s, int begin, int end); static KMETHOD Token_Parse(KonohaContext *kctx, KonohaStack *sfp) { kTokenVar *tk = (kTokenVar *) sfp[0].asToken; if(IS_NOTNULL(tk)) { kString *text = sfp[2].asString; size_t len = S_size(text); size_t beginIdx = (size_t)sfp[3].intValue; size_t endIdx = (size_t)sfp[4].intValue; if(beginIdx <= endIdx && endIdx < len) { ksymbol_t keyword = (ksymbol_t)sfp[1].intValue; tk->unresolvedTokenType = keyword; KFieldSet(tk, tk->text, KLIB new_kString(kctx, OnField, S_text(text) + beginIdx, endIdx - beginIdx, 0)); } } KReturnUnboxValue(sfp[4].intValue); }
METHOD knh__Script_eval(Ctx *ctx, knh_sfp_t *sfp) { if(IS_NOTNULL(sfp[1].s)) { knh_sfp_t *lsfp = KNH_LOCAL(ctx); knh_cwb_t cwbbuf, *cwb = knh_cwb_open(ctx, &cwbbuf); knh_cwb_write(ctx, cwb, knh_String_tobytes(sfp[1].s)); knh_cwb_putc(ctx, cwb, '\n'); InputStream *in = new_BytesInputStream(ctx, cwb->ba, cwb->pos, knh_Bytes_size(cwb->ba)); KNH_LPUSH(ctx, in); DP(in)->uri = URI_EVAL; DP(in)->line = 0; knh_NameSpace_load(ctx, ctx->share->mainns, in, 1/*isEval*/,0/*isThrowable*/); knh_cwb_close(cwb); KNH_LOCALBACK(ctx, lsfp); } KNH_RETURN_void(ctx, sfp); }
//## @Const method String String.replace(RegExp searchvalue, String newvalue); static KMETHOD String_replace(KonohaContext *kctx, KonohaStack *sfp) { kString *s0 = sfp[0].asString; kRegExp *re = sfp[1].asRegExp; const char* fmttext = S_text(sfp[2].asString); size_t fmtlen = S_size(sfp[2].asString); kString *s = s0; if(IS_NOTNULL(re) && S_size(re->pattern) > 0) { KGrowingBuffer wb; KLIB Kwb_Init(&(kctx->stack->cwb), &wb); const char *str = S_text(s0); // necessary const char *base = str; const char *eos = str + S_size(s0); // end of str kregmatch_t pmatch[KREGEXP_MATCHSIZE+1]; int isGlobalOption = RegExp_isGlobal(re); do { if(str >= eos) break; int res = pcre_regexec(kctx, re->reg, str, KREGEXP_MATCHSIZE, pmatch, re->eflags); if(res != 0) { // TODO //LOG_regex(kctx, sfp, res, re, str); break; } size_t len = pmatch[0].rm_eo; if(pmatch[0].rm_so > 0) { KLIB Kwb_write(kctx, &wb, str, pmatch[0].rm_so); } size_t matched = knh_regexp_Matched(pmatch, KREGEXP_MATCHSIZE); if(len > 0) { Kwb_writeRegexFormat(kctx, &wb, fmttext, fmtlen, base, pmatch, matched); str += len; } else { if(str == base) { // 0-length match at head of string Kwb_writeRegexFormat(kctx, &wb, fmttext, fmtlen, base, pmatch, matched); } break; } } while(isGlobalOption); KLIB Kwb_write(kctx, &wb, str, strlen(str)); // write out remaining string s = Kwb_newString(kctx, OnStack, &wb); // close cwb KLIB Kwb_Free(&wb); } KReturn(s); }
static void kArray_split(KonohaContext *kctx, kArray *resultArray, kString *str, kRegExp *regex, size_t limit) { int stringPolicy = kString_is(ASCII, str) ? StringPolicy_ASCII : 0; if(IS_NOTNULL(regex) && S_size(regex->pattern) > 0) { const char *s = S_text(str); // necessary const char *eos = s + S_size(str); kregmatch_t pmatch[2]; int res = 0; while(s < eos && res == 0) { res = pcre_regexec(kctx, regex->reg, s, 1, pmatch, regex->eflags); if(res != 0) break; size_t len = pmatch[0].rm_eo; if(len > 0) { KLIB new_kString(kctx, resultArray, s, pmatch[0].rm_so, stringPolicy); s += len; } if(!(kArray_size(resultArray) + 1 < limit)) { return; } } if(s < eos) { KLIB new_kString(kctx, resultArray, s, eos - s, stringPolicy); // append remaining string to array } } else { const unsigned char *s = (const unsigned char *)S_text(str); size_t i, n = S_size(str); if(kString_is(ASCII, str)) { for(i = 0; i < n; i++) { KLIB new_kString(kctx, resultArray, (const char *)s + i, 1, StringPolicy_ASCII); } } else { for(i = 0; i < n; i++) { int len = utf8len(s[i]); KLIB new_kString(kctx, resultArray, (const char *)s + i, len, len == 1 ? StringPolicy_ASCII: StringPolicy_UTF8); i += len; } } } }
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, ')'); }
static KMETHOD RegExp_test(KonohaContext *kctx, KonohaStack *sfp) { kString *s0 = sfp[1].asString; kRegExp *re = sfp[0].asRegExp; kbool_t matched = false; if(IS_NOTNULL(re) && S_size(re->pattern) > 0) { const char *str = S_text(s0); // necessary const char *base = str; const char *eos = base + S_size(s0); size_t i, nmatch = pcre_nmatchsize(kctx, re->reg); kregmatch_t *p, pmatch[nmatch+1]; int isGlobalOption = RegExp_isGlobal(re); do { int res = pcre_regexec(kctx, re->reg, str, nmatch, pmatch, re->eflags); if(res != 0) { // FIXME //LOG_regex(kctx, sfp, res, re, str); break; } for(p = pmatch, i = 0; i < nmatch; p++, i++) { if(p->rm_so == -1) break; re->lastIndex = utf8_strlen(str, p->rm_eo); matched = true; } if(isGlobalOption) { size_t eo = pmatch[0].rm_eo; // shift matched pattern str += (eo > 0) ? eo : 1; if(!(str < eos)) isGlobalOption = 0; // stop iteration } } while(isGlobalOption); } else { re->lastIndex = 0; } KReturnUnboxValue(matched); }
static KMETHOD TokenFunc_ExtendedIntLiteral(KonohaContext *kctx, KonohaStack *sfp) { kTokenVar *tk = (kTokenVar *)sfp[1].asObject; const char *source = kString_text(sfp[2].asString); const char *start = source, *end; int c = *source++; /* * DIGIT = 0-9 * DIGITS = DIGIT | DIGIT DIGITS * HEX = 0-9a-fA-F * HEXS = HEX | HEX HEXS * BIN = 0 | 1 * BINS = BIN | BIN BINS * TAG = "0x" | "0b" * HEXINT = ("0x" | "0X") HEXS * INT = DIGITS | HEXS | BINS */ int base = 10; bool isFloat = false; char (*parseDigit)(char) = parseDecimalDigit; if(c == '0') { c = *source++; switch (c) { case 'b': base = 2; parseDigit = parseBinaryDigit; break; case 'x': base = 16; parseDigit = parseHexDigit; break; case '0':case '1':case '2':case '3': case '4':case '5':case '6':case '7': base = 8; parseDigit = parseOctalDigit; break; default: source--; break; } } for (; (c = *source) != 0; ++source) { if(c == '_') continue; if(parseDigit(c) == -1) break; } /* * DIGIT = 0-9 * DIGITS = DIGIT | DIGIT DIGITS * INT = DIGIT | DIGIT1-9 DIGITS * FLOAT = INT * | INT FRAC * | INT EXP * | INT FRAC EXP * FRAC = "." digits * EXP = E digits * E = 'e' | 'e+' | 'e-' | 'E' | 'E+' | 'E-' */ if(base != 10 && c != '.' && c != 'e' && c != 'E') { goto L_emit; } if(c == '.') { isFloat = true; source++; for (; (c = *source) != 0; ++source) { if(c == '_') continue; if(parseDecimalDigit(c) == -1) break; } } if(c == 'e' || c == 'E') { isFloat = true; c = *(++source); if(!('0' <= c && c <= '9') && !(c == '+' || c == '-')) { source--; goto L_emit; } if(c == '+' || c == '-') { c = *source++; } for (; (c = *source) != 0; ++source) { if(c == '_') continue; if(parseDecimalDigit(c) == -1) break; } } L_emit:; if(IS_NOTNULL(tk)) { /* skip unit */ for (; (c = *source) != 0; ++source) { if(c == '_') continue; if(!isalpha(c)) break; } end = source; KFieldSet(tk, tk->text, KLIB new_kString(kctx, OnField, start, end - start, StringPolicy_ASCII)); tk->tokenType = isFloat ? KSymbol_("$Float") : TokenType_Number; } KReturnUnboxValue(source - start); }
/* added by Wakamori */ void loadPolicy(CTX ctx) { if (enforce_security == 0) return; // load $konoha.home.path/policy knh_setProperty(ctx, new_String(ctx, "role"), (dynamic *)new_String(ctx, role)); CWB_t cwbbuf, *cwb = CWB_open0(ctx, &cwbbuf); kString *s = knh_getPropertyNULL(ctx, STEXT("konoha.home.path")); CWB_write(ctx, cwb, S_tobytes(s)); CWB_write(ctx, cwb, STEXT("/policy")); kInputStream *is = new_InputStream(ctx, NULL, new_Path(ctx, CWB_newString0(ctx, cwb))); if (is == NULL) { DBG_P("policy file not found. All @Restricted annotated method is rescricted"); } else { /* if (enforce_security == 0) { enforce_security = 1; knh_memcpy(role, "Default", 7); role[7] = '\0'; } */ // parse policy file written in JSON // it must be refactored in the future kDictMap *dmap = ctx->share->securityDictMap; kString *line = knh_InputStream_readLine(ctx, is); while (IS_NOTNULL(line)) { //fprintf(stderr, "line=%s\n", S_totext(line)); if (S_equals(line, STEXT("[")) || S_equals(line, STEXT("]"))) { /* ignore */ } else { kString *key = NULL; kArray *a = new_Array(ctx, CLASS_String, 0); const char *idx = NULL; char *p = strstr(S_totext(line), "\"name\": \""); if (p != NULL) { p += 9; // == strlen("\"name\": \"") idx = strchr((const char *)p, '"'); if (idx != NULL) { p[idx - p] = '\0'; //fprintf(stderr, "name: %s\n", p); //knh_DictMap_set(ctx, dmap, new_String(ctx, "name"), new_String(ctx, p)); key = new_String(ctx, p); p = (char *)idx + 1; } } p = strstr((const char *)p, "\"permission\": ["); if (p != NULL) { p += 16; // == strlen("\"permission\": \[\"") idx = strchr((const char *)p, '"'); while (idx != NULL) { p[idx - p] = '\0'; if (strstr((const char *)p, ", ") == NULL) { //fprintf(stderr, "permission: %s\n", p); knh_Array_add(ctx, a, new_String(ctx, p)); } p = (char *)idx + 1; idx = strchr((const char *)p, '"'); } } if (key != NULL) { knh_DictMap_set(ctx, dmap, key, a); } } line = knh_InputStream_readLine(ctx, is); } knh_InputStream_close(ctx, is); } }
static int parseNumber(KonohaContext *kctx, kTokenVar *tk, TokenizerEnv *tenv, int tok_start) { const char *start = tenv->source + tok_start, *end, *ts = start; int c = *ts++; if (!(c == '.' || ('0' <= c && c <= '9'))) { /* It do not seem as Number */ return tok_start; } int isFloat = 0; /* * DIGIT = 0-9 * DIGITS = DIGIT | DIGIT DIGITS * INT = DIGIT | DIGIT1-9 DIGITS * FLOAT = INT * | INT FRAC * | INT EXP * | INT FRAC EXP * FRAC = "." digits * EXP = E digits * E = 'e' | 'e+' | 'e-' | 'E' | 'E+' | 'E-' */ if (c == '0') { c = *ts++; } else if ('1' <= c && c <= '9') { for (; '0' <= c && c <= '9' && c != 0; c = *ts++) { if (c == '_') continue; } } if (c != '.' && c != 'e' && c != 'E') { goto L_emit; } if (c == '.') { isFloat = 1; for (c = *ts++; '0' <= c && c <= '9' && c != 0; c = *ts++) { if (c == '_') continue; } } if (c == 'e' || c == 'E') { isFloat = 1; c = *ts++; if (!('0' <= c && c <= '9') && !(c == '+' || c == '-')) { ts--; goto L_emit; } if (c == '+' || c == '-') { c = *ts++; } for (; '0' <= c && c <= '9' && c != 0; c = *ts++) { if (c == '_') continue; } } L_emit:; end = ts; if (IS_NOTNULL(tk)) { /* skip unit */ while (isalpha(*ts) && *ts != 0) ts++; KSETv(tk, tk->text, KLIB new_kString(kctx, start, end - start - 1, SPOL_ASCII)); tk->unresolvedTokenType = (isFloat)? TokenType_FLOAT : TokenType_INT; } return tok_start + ts - start - 1; }
static kbool_t regexp_defineMethod(KonohaContext *kctx, kNameSpace *ns, KTraceInfo *trace) { kregexpshare_t *base = (kregexpshare_t *)KCalloc_UNTRACE(sizeof(kregexpshare_t), 1); base->h.name = "regexp"; base->h.setup = kregexpshare_setup; base->h.reftrace = kregexpshare_reftrace; base->h.free = kregexpshare_free; KLIB KonohaRuntime_setModule(kctx, MOD_REGEXP, &base->h, trace); KDEFINE_CLASS RegExpDef = { STRUCTNAME(RegExp), .cflag = 0, .init = RegExp_init, .free = RegExp_free, .p = RegExp_p, }; base->cRegExp = KLIB kNameSpace_defineClass(kctx, ns, NULL, &RegExpDef, trace); ktype_t TY_StringArray0 = CT_StringArray0->typeId; KDEFINE_METHOD MethodData[] = { /*JS*/_Public|_Const|_Im, _F(RegExp_getglobal), TY_boolean, TY_RegExp, MN_("getglobal"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getignoreCase), TY_boolean, TY_RegExp, MN_("getignoreCase"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getmultiline), TY_boolean, TY_RegExp, MN_("getmultiline"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getsource), TY_String, TY_RegExp, MN_("getsource"), 0, /*JS*/_Public|_Const|_Im, _F(RegExp_getlastIndex), TY_int, TY_RegExp, MN_("getlastIndex"), 0, /*JS*/_Public|_Im, _F(String_match), TY_StringArray0, TY_String, MN_("match"), 1, TY_RegExp, FN_("regexp"), /*JS*/_Public|_Const|_Im, _F(String_replace), TY_String, TY_String, MN_("replace"), 2, TY_RegExp, FN_("searchvalue"), TY_String, FN_("newvalue"), /*JS*/_Public|_Const|_Im, _F(String_search), TY_int, TY_String, MN_("search"), 1, TY_RegExp, FN_("searchvalue"), /*JS*/_Public|_Im, _F(String_split), TY_StringArray0, TY_String, MN_("split"), 1, TY_RegExp, FN_("separator"), /*JS*/_Public|_Im, _F(String_splitWithLimit), TY_StringArray0, TY_String, MN_("split"), 2, TY_RegExp, FN_("separator"), TY_int, FN_("limit"), /*JS*/_Public|_Const, _F(RegExp_new), TY_RegExp, TY_RegExp, MN_("new"), 1, TY_String, FN_("pattern"), /*JS*/_Public|_Const, _F(RegExp_new2), TY_RegExp, TY_RegExp, MN_("new"), 2, TY_String, FN_("pattern"), TY_String, FN_("option"), /*JS*/_Public|_Const, _F(RegExp_exec), TY_StringArray0, TY_RegExp, MN_("exec"), 1, TY_String, FN_("str"), /*JS*/_Public|_Const|_Im, _F(RegExp_test), TY_boolean, TY_RegExp, MN_("test"), 1, TY_String, FN_("str"), DEND, }; KLIB kNameSpace_loadMethodData(kctx, ns, MethodData); return true; } static KMETHOD TokenFunc_JavaScriptRegExp(KonohaContext *kctx, KonohaStack *sfp) { kTokenVar *tk = (kTokenVar *)sfp[1].asObject; int ch, prev = '/', pos = 1; const char *source = S_text(sfp[2].asString); if(source[pos] == '*' || source[pos] == '/') { KReturnUnboxValue(0); } /*FIXME: we need to care about context sensitive case*/ //int tokenListize = kArray_size(tenv->tokenList); //if(tokenListize > 0) { // kToken *tkPrev = tenv->tokenList->TokenItems[tokenListize - 1]; // if(tkPrev->unresolvedTokenType == TokenType_INT || // (tkPrev->topCharHint != '(' && tkPrev->unresolvedTokenType == TokenType_SYMBOL)) { // KReturnUnboxValue(0); // } //} while((ch = source[pos++]) != 0) { if(ch == '\n') { break; } if(ch == '/' && prev != '\\') { int pos0 = pos; while(isalpha(source[pos])) pos++; if(IS_NOTNULL(tk)) { kArray *a = (kArray *)KLIB new_kObject(kctx, OnField, CT_StringArray0, 2); // FIXME KFieldSet(tk, tk->subTokenList, a); KLIB new_kString(kctx, a, source + 1, (pos0-2), 0); KLIB new_kString(kctx, a, source + pos0, pos-pos0, 0); tk->unresolvedTokenType = SYM_("$RegExp"); } KReturnUnboxValue(pos); } prev = ch; } if(IS_NOTNULL(tk)) { SUGAR kToken_printMessage(kctx, tk, ErrTag, "must close with %s", "/"); } KReturnUnboxValue(pos-1); }
static METHOD Object_isNotNull(Ctx *ctx, knh_sfp_t *sfp, long rix) { RETURNb_(IS_NOTNULL(sfp[0].o)); }