#include "lua_lsup.h" #define check_term(L) \ *(LSUP_Term **)luaL_checkudata(L, 1, "LSUP.Term") static 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 l_iriref_new (lua_State *L) { const char *data = luaL_checkstring (L, 1); // TODO handle nsm. LSUP_NSMap *nsm = lua_touserdata (L, 2); LSUP_Term **tp = allocate_term (L); *tp = LSUP_iriref_new (data, nsm); if (!*tp) luaL_error (L, "Error while creating a term!"); return 1; } static int l_iriref_new_abs (lua_State *L) { LSUP_Term *root = check_term (L), *iri = *(LSUP_Term **)luaL_checkudata (L, 2, "LSUP.Term"); LSUP_Term **tp = allocate_term (L); *tp = LSUP_iriref_absolute (root, iri); if (!*tp) luaL_error (L, "Error while creating a term!"); return 1; } static int l_iriref_new_rel (lua_State *L) { LSUP_Term *root = check_term (L), *iri = *(LSUP_Term **)luaL_checkudata (L, 2, "LSUP.Term"); LSUP_Term **tp = allocate_term (L); *tp = LSUP_iriref_relative (root, iri); if (!*tp) luaL_error (L, "Error while creating a term!"); return 1; } static int l_lit_new (lua_State *L) { const char *data = luaL_checkstring (L, 1), *dtype_str = luaL_checkstring (L, 2); const char *lang = luaL_checkstring (L, 3); LSUP_Term **tp = allocate_term (L); if (lang) *tp = LSUP_lt_literal_new (data, (char *)lang); else { LSUP_Term *dtype = (dtype) ? LSUP_iriref_new (dtype_str, NULL) : NULL; *tp = LSUP_literal_new (data, dtype); } if (!*tp) luaL_error (L, "Error while creating a term!"); return 1; } static int l_bnode_new (lua_State *L) { const char *data = luaL_checkstring (L, 1); LSUP_Term **tp = allocate_term (L); *tp = LSUP_bnode_new (data); if (!*tp) luaL_error (L, "Error while creating a term!"); return 1; } static int new_copy (lua_State *L) { LSUP_Term *src = check_term (L); LSUP_Term **tp = allocate_term (L); *tp = LSUP_term_copy (src); if (!*tp) luaL_error (L, "Error while creating a term!"); return 1; } static int new_from_buffer (lua_State *L) { const LSUP_Buffer *sterm = *(LSUP_Buffer **)luaL_checkudata ( L, 1, "LSUP.Buffer"); LSUP_Term **tp = allocate_term (L); *tp = LSUP_term_new_from_buffer (sterm); if (!*tp) luaL_error (L, "Error while creating a term!"); return 1; } /* * Class methods. */ static int equals (lua_State *L) { LSUP_Term *t1 = check_term (L), *t2 = *(LSUP_Term **)luaL_checkudata (L, 2, "LSUP.Term"); lua_pushboolean (L, LSUP_term_equals (t1, t2)); return 1; } static int gc (lua_State *L) { LSUP_Term *t = check_term (L); if (t) LSUP_term_free (t); return 0; } static int get_hash (lua_State *L) { LSUP_Term *t = check_term (L); lua_pushinteger (L, LSUP_term_hash (t)); return 1; } static int serialize (lua_State *L) { LSUP_Term *t = check_term (L); LSUP_Buffer *buf = LSUP_term_serialize (t); if (!buf) luaL_error (L, "Error while serializing a term!"); lua_pushfstring (L, buf->addr, buf->size); LSUP_buffer_free (buf); return 1; } /* * Getters. */ // Forward declaration. static const struct luaL_Reg term_getters []; static int get_attr (lua_State *L) { const char *attr = luaL_checkstring (L, 2); for (int i = 0; term_getters[i].name != NULL; i++) { if (strcmp(term_getters[i].name, attr) == 0) return term_getters[i].func (L); } // If the attribute doesn't exist, return nil. return 0; } static int get_data (lua_State *L) { LSUP_Term *t = check_term (L); lua_pushstring (L, t->data); return 1; } static int get_type (lua_State *L) { LSUP_Term *t = check_term (L); lua_pushinteger (L, t->type); return 1; } static int get_iriref_nsm (lua_State *L) { LSUP_Term *t = check_term (L); // TODO lua_pushlightuserdata (L, LSUP_iriref_nsm (t)); return 1; } static int get_iriref_prefix (lua_State *L) { LSUP_Term *t = check_term (L); lua_pushstring (L, LSUP_iriref_prefix (t)); return 1; } static int get_iriref_path (lua_State *L) { LSUP_Term *t = check_term (L); lua_pushstring (L, LSUP_iriref_path (t)); return 1; } static int get_iriref_frag (lua_State *L) { LSUP_Term *t = check_term (L); lua_pushstring (L, LSUP_iriref_frag (t)); return 1; } static int get_lit_datatype (lua_State *L) { LSUP_Term *t = check_term (L); if (!LSUP_IS_LITERAL (t)) luaL_error (L, "Term is not a literal."); lua_pushstring (L, t->datatype->data); return 1; } static int get_lit_lang (lua_State *L) { LSUP_Term *t = check_term (L); if (!LSUP_IS_LITERAL (t)) luaL_error (L, "Term is not a literal."); lua_pushstring (L, t->lang); return 1; } /* * Setters. */ // Very simple for now. static int set_attr (lua_State *L) { luaL_error (L, "Direct attribute setting is not allowed for this type."); } /* * Library setup. */ static const luaL_Reg term_lib_fn [] = { {"iriref_new", l_iriref_new}, {"iriref_new_abs", l_iriref_new_abs}, {"iriref_new_rel", l_iriref_new_rel}, {"lit_new", l_lit_new}, {"bnode_new", l_bnode_new}, {"term_new_copy", new_copy}, {NULL} }; static const luaL_Reg term_getters [] = { // General getters. {"data", get_data}, {"type", get_type}, // IRIRef getters. {"nsm", get_iriref_nsm}, {"prefix", get_iriref_prefix}, {"path", get_iriref_path}, {"frag", get_iriref_frag}, // Literal getters. {"datatype", get_lit_datatype}, {"lang", get_lit_lang}, {NULL} }; static const luaL_Reg term_setters [] = { {NULL} }; static const luaL_Reg term_lib_meth [] = { {"__eq", equals}, {"__gc", gc}, {"__index", get_attr}, {"__newindex", set_attr}, {"hash", get_hash}, {"serialize", serialize}, {NULL} }; int luaopen_term (lua_State *L) { luaL_newmetatable (L, "LSUP.Term"); lua_pushvalue (L, -1); lua_setfield (L, -2, "__index"); luaL_setfuncs (L, term_lib_meth, 0); luaL_newlib (L, term_lib_fn); return 1; }