123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #include "lua_lsup.h"
- #define check_triple(L) \
- *(LSUP_Triple **)luaL_checkudata(L, 1, "LSUP.Triple")
- // TODO this is duplicate. Find a way to access a common fn.
- LSUP_Term **allocate_term (lua_State *L)
- {
- LSUP_Term **tp = lua_newuserdatauv (L, sizeof (*tp), 1);
- luaL_getmetatable (L, "LSUP.Term");
- lua_setmetatable (L, -2);
- return tp;
- }
- /*
- * Factory methods.
- */
- static int new (lua_State *L)
- {
- LSUP_Triple **trp_p = lua_newuserdatauv (L, sizeof (*trp_p), 1);
- luaL_getmetatable (L, "LSUP.Triple");
- lua_setmetatable (L, -2);
- LSUP_Term
- *s = *(LSUP_Term **)luaL_checkudata(L, 1, "LSUP.Term"),
- *p = *(LSUP_Term **)luaL_checkudata(L, 2, "LSUP.Term"),
- *o = *(LSUP_Term **)luaL_checkudata(L, 3, "LSUP.Term");
- *trp_p = LSUP_triple_new (
- LSUP_term_copy (s),
- LSUP_term_copy (p),
- LSUP_term_copy (o));
- if (!*trp_p) return luaL_error (L, "Error while creating a triple!");
- return 1;
- }
- /*
- * Class methods.
- */
- static int gc (lua_State *L)
- {
- LSUP_Triple *trp = check_triple (L);
- if (trp) LSUP_triple_free (trp);
- return 0;
- }
- /** @brief Get information about a triple's term.
- *
- * Note that this is only a visual representation, as terms cannot be modified
- * outside of their containing triple (unlike in the C library).
- *
- * @FIXME this doesn't allow chaining access methods, e.g. trp.s.data
- *
- * To get an independent copy of a triple term, use triple.copy_term().
- */
- static int get_term (lua_State *L)
- {
- const LSUP_Triple *trp = check_triple (L);
- const char pos = luaL_checkstring (L, 2)[0];
- LSUP_TriplePos pn;
- if (pos == 's') pn = TRP_POS_S;
- else if (pos == 'p') pn = TRP_POS_P;
- else if (pos == 'o') pn = TRP_POS_O;
- else return luaL_error(L, "Out of range position: %c.", pos);
- LSUP_Term *t = LSUP_triple_pos (trp, pn);
- char *nt_term = NULL;
- CHECK (nt_codec.encode_term (t, NULL, &nt_term), fail);
- lua_pushfstring (L, "LSUP.Term @ %p %s", t, nt_term);
- return 1;
- fail:
- if (nt_term) free (nt_term);
- return luaL_error (L, "Error encoding triple term for display!");
- }
- static int set_term (lua_State *L)
- {
- LSUP_Triple *trp = check_triple (L);
- const char pos = luaL_checkstring (L, 2)[0];
- const LSUP_Term *t = *(LSUP_Term **)luaL_checkudata(L, 3, "LSUP.Term");
- LSUP_Term *new_t = LSUP_term_copy (t);
- if (pos == 's') {
- LSUP_term_free (trp->s);
- trp->s = new_t;
- } else if (pos == 'p') {
- LSUP_term_free (trp->p);
- trp->p = new_t;
- } else if (pos == 'o') {
- LSUP_term_free (trp->o);
- trp->o = new_t;
- } else return luaL_error(L, "Out of range position: %c.", pos);
- return 1;
- }
- static int copy_term (lua_State *L)
- {
- const LSUP_Triple *trp = check_triple (L);
- const char pos = luaL_checkstring (L, 2)[0];
- LSUP_TriplePos pn;
- if (pos == 's') pn = TRP_POS_S;
- else if (pos == 'p') pn = TRP_POS_P;
- else if (pos == 'o') pn = TRP_POS_O;
- else return luaL_error(L, "Copy: Out of range position: %c.", pos);
- LSUP_Term **tp = allocate_term (L);
- *tp = LSUP_term_copy (LSUP_triple_pos (trp, pn));
- if (!*tp) return luaL_error (L, "Error while copying a triple term!");
- return 1;
- }
- /*
- * Library setup.
- */
- static const struct luaL_Reg triple_lib_fn [] = {
- {"new", new},
- {NULL}
- };
- static const struct luaL_Reg triple_lib_meth [] = {
- {"__gc", gc},
- {"__index", get_term},
- {"__newindex", set_term},
- {"copy_term", copy_term},
- {NULL}
- };
- int luaopen_triple (lua_State *L)
- {
- LSUP_init(); // This is idempotent: no problem calling it multiple times.
- luaL_newmetatable (L, "LSUP.Triple");
- lua_pushvalue (L, -1);
- // MT
- lua_setfield (L, -1, "__index");
- luaL_setfuncs (L, triple_lib_meth, 0);
- luaL_newlib (L, triple_lib_fn);
- // Module-level constants.
- lua_pushinteger (L, TRP_POS_S);
- lua_setfield (L, -2, "TRP_POS_S");
- lua_pushinteger (L, TRP_POS_P);
- lua_setfield (L, -2, "TRP_POS_P");
- lua_pushinteger (L, TRP_POS_O);
- lua_setfield (L, -2, "TRP_POS_O");
- return 1;
- }
|