JNIEXPORT jlong JNICALL Java_org_grammaticalframework_pgf_Expr_initApp(JNIEnv* env, jclass clazz, jstring jfun, jobjectArray args, jlong jpool) { GuPool* pool = l2p(jpool); PgfExpr expr; GuString fun = (*env)->GetStringUTFChars(env, jfun, 0); PgfExprFun* e = gu_new_flex_variant(PGF_EXPR_FUN, PgfExprFun, fun, strlen(fun)+1, &expr, pool); strcpy(e->fun, fun); (*env)->ReleaseStringUTFChars(env, jfun, fun); size_t n_args = (*env)->GetArrayLength(env, args); for (size_t i = 0; i < n_args; i++) { PgfExpr fun = expr; PgfExpr arg = gu_variant_from_ptr(get_ref(env, (*env)->GetObjectArrayElement(env, args, i))); PgfExprApp* e = gu_new_variant(PGF_EXPR_APP, PgfExprApp, &expr, pool); e->fun = fun; e->arg = arg; } return expr; }
PgfExpr pgf_expr_string(GuString str, GuPool* pool) { PgfLiteral lit; PgfLiteralStr* plit = gu_new_flex_variant(PGF_LITERAL_STR, PgfLiteralStr, val, strlen(str)+1, &lit, pool); strcpy(plit->val, str); return gu_new_variant_i(pool, PGF_EXPR_LIT, PgfExprLit, lit); }
static PgfLiteral pgf_read_literal(PgfReader* rdr) { PgfLiteral lit = gu_null_variant; uint8_t tag = pgf_read_tag(rdr); switch (tag) { case PGF_LITERAL_STR: { size_t len = pgf_read_len(rdr); uint8_t* buf = alloca(len*6+1); uint8_t* p = buf; for (size_t i = 0; i < len; i++) { gu_in_utf8_buf(&p, rdr->in, rdr->err); gu_return_on_exn(rdr->err, gu_null_variant); } *p++ = 0; PgfLiteralStr *lit_str = gu_new_flex_variant(PGF_LITERAL_STR, PgfLiteralStr, val, p-buf, &lit, rdr->opool); strcpy((char*) lit_str->val, (char*) buf); break; } case PGF_LITERAL_INT: { PgfLiteralInt *lit_int = gu_new_variant(PGF_LITERAL_INT, PgfLiteralInt, &lit, rdr->opool); lit_int->val = pgf_read_int(rdr); break; } case PGF_LITERAL_FLT: { PgfLiteralFlt *lit_flt = gu_new_variant(PGF_LITERAL_FLT, PgfLiteralFlt, &lit, rdr->opool); lit_flt->val = pgf_read_double(rdr); break; } default: pgf_read_tag_error(rdr); } return lit; }
JNIEXPORT jlong JNICALL Java_org_grammaticalframework_pgf_Expr_initStringLit(JNIEnv* env, jclass clazz, jstring jstr, jlong jpool) { GuPool* pool = l2p(jpool); PgfExpr expr; PgfExprLit* e = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, &expr, pool); GuString str = (*env)->GetStringUTFChars(env, jstr, 0); PgfLiteralStr* slit = gu_new_flex_variant(PGF_LITERAL_STR, PgfLiteralStr, val, strlen(str)+1, &e->lit, pool); strcpy(slit->val, str); (*env)->ReleaseStringUTFChars(env, jstr, str); return expr; }
PgfExpr pgf_expr_apply(PgfApplication* app, GuPool* pool) { PgfExpr expr; size_t len = strlen(app->fun); PgfExprFun *efun = gu_new_flex_variant(PGF_EXPR_FUN, PgfExprFun, fun, len+1, &expr, pool); strcpy(efun->fun, app->fun); for (int i = 0; i < app->n_args; i++) { expr = gu_new_variant_i(pool, PGF_EXPR_APP, PgfExprApp, .fun = expr, .arg = app->args[i]); } return expr; }
static PgfExpr pgf_value2expr(PgfReasoner* rs, int level, PgfClosure* clos) { clos = rs->eval_gates->enter(rs, clos); if (clos == NULL) return gu_null_variant; PgfExpr expr = gu_null_variant; size_t n_args = 0; PgfClosure** args; if (clos->code == rs->eval_gates->evaluate_value) { PgfValue* val = (PgfValue*) clos; PgfAbsFun* absfun = gu_container(val->con, PgfAbsFun, closure); expr = absfun->ep.expr; n_args = absfun->arity; args = val->args; } else if (clos->code == rs->eval_gates->evaluate_value_lit) { PgfValueLit* val = (PgfValueLit*) clos; PgfExprLit *elit = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, &expr, rs->out_pool); GuVariantInfo i = gu_variant_open(val->lit); switch (i.tag) { case PGF_LITERAL_STR: { PgfLiteralStr* lstr = i.data; PgfLiteralStr* new_lstr = gu_new_flex_variant(PGF_LITERAL_STR, PgfLiteralStr, val, strlen(lstr->val)+1, &elit->lit, rs->out_pool); strcpy(new_lstr->val, lstr->val); break; } case PGF_LITERAL_INT: { PgfLiteralInt* lint = i.data; PgfLiteralInt* new_lint = gu_new_variant(PGF_LITERAL_INT, PgfLiteralInt, &elit->lit, rs->out_pool); new_lint->val = lint->val; break; } case PGF_LITERAL_FLT: { PgfLiteralFlt* lflt = i.data; PgfLiteralFlt* new_lflt = gu_new_variant(PGF_LITERAL_FLT, PgfLiteralFlt, &elit->lit, rs->out_pool); new_lflt->val = lflt->val; break; } default: gu_impossible(); } } else if (clos->code == rs->eval_gates->evaluate_value_pap) { PgfValuePAP *pap = (PgfValuePAP*) clos; PgfValueGen* gen = gu_new(PgfValueGen, rs->pool); gen->header.code = rs->eval_gates->evaluate_gen; gen->level = level; size_t n_args = pap->n_args/sizeof(PgfClosure*); PgfValuePAP* new_pap = gu_new_flex(rs->pool, PgfValuePAP, args, n_args+1); new_pap->header.code = rs->eval_gates->evaluate_value_pap; new_pap->fun = pap->fun; new_pap->n_args = pap->n_args+sizeof(PgfClosure*); new_pap->args[0] = &gen->header; for (size_t i = 0; i < n_args; i++) { new_pap->args[i+1] = pap->args[i]; } PgfExprAbs *eabs = gu_new_variant(PGF_EXPR_ABS, PgfExprAbs, &expr, rs->out_pool); eabs->bind_type = PGF_BIND_TYPE_EXPLICIT; eabs->id = gu_format_string(rs->out_pool, "v%d", level); eabs->body = pgf_value2expr(rs, level+1, &new_pap->header); } else if (clos->code == rs->eval_gates->evaluate_value_const) { PgfValuePAP* val = (PgfValuePAP*) clos; if (val->fun->code == rs->eval_gates->evaluate_meta) { PgfValueMeta* fun = (PgfValueMeta*) val->fun; PgfExprMeta *emeta = gu_new_variant(PGF_EXPR_META, PgfExprMeta, &expr, rs->out_pool); emeta->id = fun->id; } else if (val->fun->code == rs->eval_gates->evaluate_gen) { PgfValueGen* fun = (PgfValueGen*) val->fun; PgfExprVar *evar = gu_new_variant(PGF_EXPR_VAR, PgfExprVar, &expr, rs->out_pool); evar->var = level - fun->level - 1; } else if (val->fun->code == rs->eval_gates->evaluate_sum) { PgfValueSum* sum = (PgfValueSum*) val->fun; PgfExpr e1,e2; PgfExprFun *efun = gu_new_flex_variant(PGF_EXPR_FUN, PgfExprFun, fun, 2, &e1, rs->out_pool); strcpy(efun->fun, "+"); PgfExprLit *elit = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, &e2, rs->out_pool); elit->lit = sum->lit; PgfExprApp* eapp = gu_new_variant(PGF_EXPR_APP, PgfExprApp, &expr, rs->out_pool); eapp->fun = e1; eapp->arg = e2; size_t n_consts = gu_buf_length(sum->consts); for (size_t i = 0; i < n_consts; i++) { PgfClosure* con = gu_buf_get(sum->consts, PgfClosure*, i); PgfExpr fun = expr; PgfExpr arg = pgf_value2expr(rs, level, con); if (gu_variant_is_null(arg)) return gu_null_variant; PgfExprApp* e = gu_new_variant(PGF_EXPR_APP, PgfExprApp, &expr, rs->out_pool); e->fun = fun; e->arg = arg; } } else {
static PgfSymbol pgf_read_symbol(PgfReader* rdr) { PgfSymbol sym = gu_null_variant; uint8_t tag = pgf_read_tag(rdr); switch (tag) { case PGF_SYMBOL_CAT: { PgfSymbolCat *sym_cat = gu_new_variant(PGF_SYMBOL_CAT, PgfSymbolCat, &sym, rdr->opool); sym_cat->d = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); sym_cat->r = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_LIT: { PgfSymbolLit *sym_lit = gu_new_variant(PGF_SYMBOL_LIT, PgfSymbolLit, &sym, rdr->opool); sym_lit->d = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); sym_lit->r = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_VAR: { PgfSymbolVar *sym_var = gu_new_variant(PGF_SYMBOL_VAR, PgfSymbolVar, &sym, rdr->opool); sym_var->d = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); sym_var->r = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_KS: { size_t len = pgf_read_len(rdr); uint8_t* buf = alloca(len*6+1); uint8_t* p = buf; for (size_t i = 0; i < len; i++) { gu_in_utf8_buf(&p, rdr->in, rdr->err); gu_return_on_exn(rdr->err, gu_null_variant); } *p++ = 0; PgfSymbolKS *sym_ks = gu_new_flex_variant(PGF_SYMBOL_KS, PgfSymbolKS, token, p-buf, &sym, rdr->opool); strcpy((char*) sym_ks->token, (char*) buf); break; } case PGF_SYMBOL_KP: { PgfSymbols* default_form = pgf_read_symbols(rdr); gu_return_on_exn(rdr->err, gu_null_variant); size_t n_forms = pgf_read_len(rdr); gu_return_on_exn(rdr->err, gu_null_variant); PgfSymbolKP *sym_kp = gu_new_flex_variant(PGF_SYMBOL_KP, PgfSymbolKP, forms, n_forms, &sym, rdr->opool); sym_kp->default_form = default_form; sym_kp->n_forms = n_forms; for (size_t i = 0; i < sym_kp->n_forms; i++) { pgf_read_alternative(rdr, &sym_kp->forms[i]); gu_return_on_exn(rdr->err, gu_null_variant); } break; } case PGF_SYMBOL_NE: { gu_new_variant(PGF_SYMBOL_NE, PgfSymbolNE, &sym, rdr->opool); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_BIND: { gu_new_variant(PGF_SYMBOL_BIND, PgfSymbolBIND, &sym, rdr->opool); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_SOFT_BIND: { gu_new_variant(PGF_SYMBOL_SOFT_BIND, PgfSymbolBIND, &sym, rdr->opool); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_SOFT_SPACE: { gu_new_variant(PGF_SYMBOL_SOFT_SPACE, PgfSymbolBIND, &sym, rdr->opool); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_CAPIT: { gu_new_variant(PGF_SYMBOL_CAPIT, PgfSymbolCAPIT, &sym, rdr->opool); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_SYMBOL_ALL_CAPIT: { gu_new_variant(PGF_SYMBOL_ALL_CAPIT, PgfSymbolCAPIT, &sym, rdr->opool); gu_return_on_exn(rdr->err, gu_null_variant); break; } default: pgf_read_tag_error(rdr); } return sym; }
static PgfAbsFun* pgf_read_absfun(PgfReader* rdr, PgfAbstr* abstr, PgfAbsFun* absfun) { size_t len = pgf_read_len(rdr); PgfExprFun *efun = gu_new_flex_variant(PGF_EXPR_FUN, PgfExprFun, fun, len+1, &absfun->ep.expr, rdr->opool); gu_in_bytes(rdr->in, (uint8_t*)efun->fun, len, rdr->err); efun->fun[len] = 0; absfun->name = efun->fun; gu_return_on_exn(rdr->err, NULL); absfun->type = pgf_read_type_(rdr); gu_return_on_exn(rdr->err, NULL); absfun->arity = pgf_read_int(rdr); uint8_t tag = pgf_read_tag(rdr); gu_return_on_exn(rdr->err, NULL); switch (tag) { case 0: absfun->defns = NULL; if (absfun->arity == 0) { absfun->closure.code = abstr->eval_gates->evaluate_value; absfun->closure.con = &absfun->closure.code; } else { absfun->closure.code = NULL; } break; case 1: { size_t length = pgf_read_len(rdr); gu_return_on_exn(rdr->err, NULL); absfun->defns = gu_new_seq(PgfEquation*, length, rdr->opool); PgfEquation** data = gu_seq_data(absfun->defns); for (size_t i = 0; i < length; i++) { size_t n_patts = pgf_read_len(rdr); gu_return_on_exn(rdr->err, NULL); PgfEquation *equ = gu_malloc(rdr->opool, sizeof(PgfEquation)+sizeof(PgfPatt)*n_patts); equ->n_patts = n_patts; for (size_t j = 0; j < n_patts; j++) { equ->patts[j] = pgf_read_patt(rdr); gu_return_on_exn(rdr->err, NULL); } equ->body = pgf_read_expr_(rdr); gu_return_on_exn(rdr->err, NULL); data[i] = equ; } // pgf_jit_function(rdr, abstr, absfun); break; } default: pgf_read_tag_error(rdr); break; } absfun->ep.prob = - log(pgf_read_double(rdr)); return absfun; }
static PgfExpr pgf_read_expr_(PgfReader* rdr) { PgfExpr expr = gu_null_variant; uint8_t tag = pgf_read_tag(rdr); switch (tag) { case PGF_EXPR_ABS:{ PgfExprAbs *eabs = gu_new_variant(PGF_EXPR_ABS, PgfExprAbs, &expr, rdr->opool); eabs->bind_type = pgf_read_tag(rdr); gu_return_on_exn(rdr->err, gu_null_variant); eabs->id = pgf_read_cid(rdr, rdr->opool); gu_return_on_exn(rdr->err, gu_null_variant); eabs->body = pgf_read_expr_(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_EXPR_APP: { PgfExprApp *eapp = gu_new_variant(PGF_EXPR_APP, PgfExprApp, &expr, rdr->opool); eapp->fun = pgf_read_expr_(rdr); gu_return_on_exn(rdr->err, gu_null_variant); eapp->arg = pgf_read_expr_(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_EXPR_LIT: { PgfExprLit *elit = gu_new_variant(PGF_EXPR_LIT, PgfExprLit, &expr, rdr->opool); elit->lit = pgf_read_literal(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_EXPR_META: { PgfExprMeta *emeta = gu_new_variant(PGF_EXPR_META, PgfExprMeta, &expr, rdr->opool); emeta->id = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_EXPR_FUN: { size_t len = pgf_read_len(rdr); PgfExprFun *efun = gu_new_flex_variant(PGF_EXPR_FUN, PgfExprFun, fun, len+1, &expr, rdr->opool); gu_in_bytes(rdr->in, (uint8_t*)efun->fun, len, rdr->err); efun->fun[len] = 0; gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_EXPR_VAR: { PgfExprVar *evar = gu_new_variant(PGF_EXPR_VAR, PgfExprVar, &expr, rdr->opool); evar->var = pgf_read_int(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_EXPR_TYPED: { PgfExprTyped *etyped = gu_new_variant(PGF_EXPR_TYPED, PgfExprTyped, &expr, rdr->opool); etyped->expr = pgf_read_expr_(rdr); gu_return_on_exn(rdr->err, gu_null_variant); etyped->type = pgf_read_type_(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } case PGF_EXPR_IMPL_ARG: { PgfExprImplArg *eimpl = gu_new_variant(PGF_EXPR_IMPL_ARG, PgfExprImplArg, &expr, rdr->opool); eimpl->expr = pgf_read_expr_(rdr); gu_return_on_exn(rdr->err, gu_null_variant); break; } default: pgf_read_tag_error(rdr); } return expr; }