123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- /* This file is part of ilk.
- *
- * Ilk is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Ilk is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with ilk. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <dirent.h>
- #include <inttypes.h>
- #include <rid.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <ctype.h>
- #define STYLE_9
- #include <fn85.h>
- #include <rid_fn85.h>
- #include <unfy/unfy.h>
- #include <unfy/unfp.h>
- #include <rls/rls.h>
- #include <rls/rlsp.h>
- #include <rls/rlsr.h>
- #define NIT_SHORT_NAMES
- #include <nit/list.h>
- #include <nit/set.h>
- #include <nit/map.h>
- #include <nit/err.h>
- #include <nit/file.h>
- #include <nit/buf.h>
- #include <nit/gap.h>
- #include <nit/crs.h>
- #include "../utilize.h"
- #include "../front.h"
- #include "acts.h"
- #define pass(str) (sizeof(str) - 1)
- typedef enum {
- ILK_NO_CMD,
- ILK_VIEW,
- ILK_SAVE,
- ILK_COUNT,
- ILK_RECALL,
- ILK_TEST,
- ILK_PROD,
- ILK_MODE,
- ILK_ACT,
- ILK_DEPS,
- } Ilk_cmd;
- void
- more_print(void *extra)
- {
- Ilk_more *more = extra;
- printf(".%" PRIu64, more->srch_cnt);
- }
- #define WORD_PARSE(LIT, ENUM_VAL) \
- if (!strncmp(str, LIT, pass(LIT))) { \
- *pos += pass(LIT); \
- return ENUM_VAL; \
- }
- Ilk_cmd
- ilk_cmd_parse(const char *str, size_t *pos)
- {
- switch (*str) {
- case 'a':
- WORD_PARSE("act", ILK_ACT);
- break;
- case 'v':
- WORD_PARSE("view", ILK_VIEW);
- break;
- case 's':
- WORD_PARSE("save", ILK_SAVE);
- break;
- case 'c':
- WORD_PARSE("count", ILK_COUNT);
- break;
- case 'r':
- WORD_PARSE("recall", ILK_RECALL);
- break;
- case 't':
- WORD_PARSE("test", ILK_TEST);
- break;
- case 'p':
- WORD_PARSE("prod", ILK_PROD);
- break;
- case 'm':
- WORD_PARSE("mode", ILK_MODE);
- break;
- case 'd':
- WORD_PARSE("deps", ILK_DEPS);
- break;
- }
- return ILK_NO_CMD;
- }
- void
- print_view(Ilk_sys *sys)
- {
- Nit_iter iter;
- if (!sys->grps.entry_num) {
- printf("Nothing here\n");
- return;
- }
- iter_init(&iter, &sys->grps);
- do {
- Ilk_grp *grp = iter_val(&iter);
- rlsp_rule_print(grp->rules, more_print);
- } while (iter_next(&iter));
- }
- static Unfy_stat
- ilk_recall(Ilk_sys *sys, char *str, size_t pos)
- {
- const char *error;
- uint64_t srch_cnt;
- Rls_srch *srch = NULL;
- if (unfp_space(str + pos, &pos, &error) < 0) {
- err_cust(&sys->lib->err, error);
- goto err_repl;
- }
- errno = 0;
- if (sscanf(str + pos, "%" PRIu64, &srch_cnt) < 1) {
- if (errno)
- err_std(&sys->lib->err);
- else if (str[pos] == '\0')
- err_cust(&sys->lib->err, "Missing digit");
- else
- err_cust(&sys->lib->err, "Invalid digit");
- goto err_repl;
- }
- if (ilk_srch_get(&srch, srch_cnt, sys) < 0)
- goto err_get;
- rlsp_srch_print(srch, 1);
- /* rls_recycle_srch(&sys->lib->rec, srch); */
- return UNFY_YES;
- err_repl:
- err_where(&sys->lib->err, "repl");
- err_pos(&sys->lib->err, pos);
- err_get:
- err_under(&sys->lib->err, pos + sizeof("* ") - 1);
- return UNFY_ERR;
- }
- static Ilk_act_num
- ilk_act_name(Ilk_sys *sys, char *str, size_t *pos)
- {
- const char *error;
- if (unfp_space(str + *pos, pos, &error) < 0) {
- err_cust(&sys->lib->err, error);
- goto err;
- }
- str += *pos;
- switch (*str) {
- case 'a':
- WORD_PARSE("add", ILK_ACT_ADD);
- break;
- case 'g':
- WORD_PARSE("gensym", ILK_ACT_GENSYM);
- break;
- }
- err_cust(&sys->lib->err, "Unknown act name");
- err:
- err_pos(&sys->lib->err, *pos);
- err_under(&sys->lib->err, *pos + sizeof("* ") - 1);
- err_where(&sys->lib->err, "repl");
- return ILK_ACT_NO;
- }
- static Unfy_stat
- repl_act(Ilk_sys *sys, char *str, size_t pos)
- {
- Ilk_act_num act = ilk_act_name(sys, str, &pos);
- Ilk_grp *grp;
- if (act == ILK_ACT_NO || !(grp = ilk_act_add2(sys, act)))
- return UNFY_ERR;
- return UNFY_YES;
- }
- static void
- deps_print(Nit_gap *deps)
- {
- Nit_crs crs;
- uint64_t srch_cnt;
- crs_init(&crs, deps, 0);
- while (crs_movef(&crs, sizeof(srch_cnt)) >= 0) {
- crs_read(&crs, &srch_cnt, sizeof(srch_cnt));
- srch_cnt = le64toh(srch_cnt);
- printf("%" PRIu64 " ", srch_cnt);
- }
- printf("\n");
- }
- static Unfy_stat
- repl_deps(Ilk_sys *sys, char *str, size_t pos)
- {
- size_t tmp;
- Rid id;
- const char *error;
- Ilk_meta meta;
- str += pos;
- tmp = pos;
- if (unfp_space(str, &pos, &error) < 0) {
- err_cust(&sys->lib->err, error);
- goto err_space;
- }
- str += pos - tmp;
- tmp = pos;
- if (rid_fn85_parse(id, str, &pos, &error) != FN85_OKAY)
- goto id_err;
- if (ilk_meta_load(&meta, id, sys) < 0)
- return UNFY_ERR;
- deps_print(&meta.deps);
- ilk_meta_dispose(&meta);
- return UNFY_YES;
- id_err:
- err_cust(&sys->lib->err, error);
- err_space:
- err_under(&sys->lib->err, pos + sizeof("* ") - 1);
- err_where(&sys->lib->err, "repl");
- err_pos(&sys->lib->err, pos);
- return UNFY_ERR;
- }
- static Unfy_stat
- ilk_lsn(Rlsr_lsnr *lsnr, Rls_rule **rules, Rls_srch **srch, char **str,
- size_t *size, Rls_info *info, void *extra, Rls_recycle *rec)
- {
- Ilk_sys *sys = extra;
- switch (ilk_cmd_parse(*str, &lsnr->pos)) {
- case ILK_SAVE:
- if (ilk_sys_save(sys) < 0)
- return UNFY_ERR;
- else
- printf("saved\n");
- return UNFY_YES;
- case ILK_VIEW:
- print_view(sys);
- return UNFY_YES;
- case ILK_COUNT:
- printf("%" PRIu64 "\n", sys->srch_cnt + 1);
- return UNFY_YES;
- case ILK_RECALL:
- return ilk_recall(sys, *str, lsnr->pos);
- case ILK_TEST:
- if (sys->lib->testing)
- printf("Already in testing mode\n");
- else
- printf("Changed to testing mode\n");
- sys->lib->testing = 1;
- return UNFY_YES;
- case ILK_PROD:
- if (!sys->lib->testing)
- printf("Already in production mode\n");
- else
- printf("Changed to production mode\n");
- sys->lib->testing = 0;
- return UNFY_YES;
- case ILK_MODE:
- if (sys->lib->testing)
- printf("In testing mode\n");
- else
- printf("In production mode\n");
- return UNFY_YES;
- case ILK_ACT:
- return repl_act(sys, *str, lsnr->pos);
- case ILK_DEPS:
- return repl_deps(sys, *str, lsnr->pos);
- case ILK_NO_CMD:
- break;
- }
- if (rlsr_default_lsn(lsnr, rules, srch, str,
- size, info, extra, rec) == UNFY_ERR) {
- if (!sys->lib->err.occured) {
- err_cust(&sys->lib->err, lsnr->error_str);
- err_pos(&sys->lib->err, lsnr->pos);
- err_under(&sys->lib->err, lsnr->pos + sizeof("* ") - 1);
- err_where(&sys->lib->err, "repl");
- }
- return UNFY_ERR;
- }
- return UNFY_YES;
- }
- static void
- handle_invalid_rule(Nit_err *err, Rlsr_stmnt *stmnt)
- {
- if (!ilk_rule_valid(stmnt->term, stmnt->list))
- return;
- err_where(err, "repl");
- err_pos(err, stmnt->term_pos);
- err_under(err, stmnt->term_pos + sizeof("* ") - 1);
- }
- int
- ilk_assert(Rlsr_lsnr *lsnr, Rlsr_stmnt *stmnt,
- Rls_rule **rules, void *extra, Rls_recycle *rec)
- {
- Ilk_sys *sys = extra;
- Ilk_grp *grp = ilk_rule_add(sys, stmnt->id, stmnt->term,
- stmnt->list, 0);
- if (!grp) {
- handle_invalid_rule(&sys->lib->err, stmnt);
- return -1;
- }
- *rules = grp->rules;
- return 0;
- }
- Unfy_stat
- ilk_search(Rlsr_lsnr *lsnr, Rlsr_stmnt *stmnt, Rls_srch **srch_ref,
- Rls_rule **rules, Rls_info *info, void *extra,
- Rls_recycle *rec)
- {
- Ilk_sys *sys = extra;
- Ilk_grp *grp = NULL;
- Unfy_stat stat;
- if (sys->lib->testing)
- stat = ilk_srch(sys, srch_ref, stmnt->term,
- &stmnt->limit, info);
- else
- stat = ilk_srch_n_save(sys, srch_ref, stmnt->term,
- &stmnt->limit, info);
- switch (stat) {
- case UNFY_NO:
- break;
- case UNFY_YES:
- /* This should never fail b/c search */
- grp = ilk_grp_get_term(sys, stmnt->term, &stat);
- break;
- case UNFY_ERR:
- handle_invalid_rule(&sys->lib->err, stmnt);
- break;
- }
- *rules = grp ? grp->rules : NULL;
- return stat;
- }
- void
- ilk_err(Rlsr_lsnr *lsnr, void *extra)
- {
- Ilk_sys *sys = extra;
- err_print(&sys->lib->err);
- sys->lib->err.occured = 0;
- }
- void
- ilk_repl(Ilk_sys *sys)
- {
- Rls_rule *rules = NULL;
- Rlsr_lsnr lsnr;
- rlsr_lsnr_init(&lsnr, ilk_lsn, ilk_assert, ilk_search,
- ilk_err, sys->lib->bend, NULL, 0);
- rlsr_repl(&rules, &lsnr, sys, &sys->lib->rec);
- if (!sys->lib->testing)
- ilk_sys_save(sys);
- }
- int
- main(int argc, char *argv[])
- {
- Ilk_lib lib;
- Ilk_sys *sys;
- ilk_lib_init(&lib, ILK_ACT_MAX, ilk_acts);
- if (!(sys = ilk_sys(&lib, "./"))) {
- err_print(&lib.err);
- return 0;
- }
- ilk_repl(sys);
- ilk_sys_rec(sys);
- ilk_lib_dispose(&lib);
- return 0;
- }
|