triple.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "lua_lsup.h"
  2. #define check_triple(L) \
  3. *(LSUP_Triple **)luaL_checkudata(L, 1, "LSUP.Triple")
  4. // TODO this is duplicate. Find a way to access a common fn.
  5. LSUP_Term **allocate_term (lua_State *L)
  6. {
  7. LSUP_Term **tp = lua_newuserdatauv (L, sizeof (*tp), 1);
  8. luaL_getmetatable (L, "LSUP.Term");
  9. lua_setmetatable (L, -2);
  10. return tp;
  11. }
  12. /*
  13. * Factory methods.
  14. */
  15. static int new (lua_State *L)
  16. {
  17. LSUP_Triple **trp_p = lua_newuserdatauv (L, sizeof (*trp_p), 1);
  18. luaL_getmetatable (L, "LSUP.Triple");
  19. lua_setmetatable (L, -2);
  20. LSUP_Term
  21. *s = *(LSUP_Term **)luaL_checkudata(L, 1, "LSUP.Term"),
  22. *p = *(LSUP_Term **)luaL_checkudata(L, 2, "LSUP.Term"),
  23. *o = *(LSUP_Term **)luaL_checkudata(L, 3, "LSUP.Term");
  24. *trp_p = LSUP_triple_new (
  25. LSUP_term_copy (s),
  26. LSUP_term_copy (p),
  27. LSUP_term_copy (o));
  28. if (!*trp_p) return luaL_error (L, "Error while creating a triple!");
  29. return 1;
  30. }
  31. /*
  32. * Class methods.
  33. */
  34. static int gc (lua_State *L)
  35. {
  36. LSUP_Triple *trp = check_triple (L);
  37. if (trp) LSUP_triple_free (trp);
  38. return 0;
  39. }
  40. /** @brief Get information about a triple's term.
  41. *
  42. * Note that this is only a visual representation, as terms cannot be modified
  43. * outside of their containing triple (unlike in the C library).
  44. *
  45. * @FIXME this doesn't allow chaining access methods, e.g. trp.s.data
  46. *
  47. * To get an independent copy of a triple term, use triple.copy_term().
  48. */
  49. static int get_term (lua_State *L)
  50. {
  51. const LSUP_Triple *trp = check_triple (L);
  52. const char pos = luaL_checkstring (L, 2)[0];
  53. LSUP_TriplePos pn;
  54. if (pos == 's') pn = TRP_POS_S;
  55. else if (pos == 'p') pn = TRP_POS_P;
  56. else if (pos == 'o') pn = TRP_POS_O;
  57. else return luaL_error(L, "Out of range position: %c.", pos);
  58. LSUP_Term *t = LSUP_triple_pos (trp, pn);
  59. char *nt_term = NULL;
  60. CHECK (nt_codec.encode_term (t, NULL, &nt_term), fail);
  61. lua_pushfstring (L, "LSUP.Term @ %p %s", t, nt_term);
  62. return 1;
  63. fail:
  64. if (nt_term) free (nt_term);
  65. return luaL_error (L, "Error encoding triple term for display!");
  66. }
  67. static int set_term (lua_State *L)
  68. {
  69. LSUP_Triple *trp = check_triple (L);
  70. const char pos = luaL_checkstring (L, 2)[0];
  71. const LSUP_Term *t = *(LSUP_Term **)luaL_checkudata(L, 3, "LSUP.Term");
  72. LSUP_Term *new_t = LSUP_term_copy (t);
  73. if (pos == 's') {
  74. LSUP_term_free (trp->s);
  75. trp->s = new_t;
  76. } else if (pos == 'p') {
  77. LSUP_term_free (trp->p);
  78. trp->p = new_t;
  79. } else if (pos == 'o') {
  80. LSUP_term_free (trp->o);
  81. trp->o = new_t;
  82. } else return luaL_error(L, "Out of range position: %c.", pos);
  83. return 1;
  84. }
  85. static int copy_term (lua_State *L)
  86. {
  87. const LSUP_Triple *trp = check_triple (L);
  88. const char pos = luaL_checkstring (L, 2)[0];
  89. LSUP_TriplePos pn;
  90. if (pos == 's') pn = TRP_POS_S;
  91. else if (pos == 'p') pn = TRP_POS_P;
  92. else if (pos == 'o') pn = TRP_POS_O;
  93. else return luaL_error(L, "Copy: Out of range position: %c.", pos);
  94. LSUP_Term **tp = allocate_term (L);
  95. *tp = LSUP_term_copy (LSUP_triple_pos (trp, pn));
  96. if (!*tp) return luaL_error (L, "Error while copying a triple term!");
  97. return 1;
  98. }
  99. /*
  100. * Library setup.
  101. */
  102. static const struct luaL_Reg triple_lib_fn [] = {
  103. {"new", new},
  104. {NULL}
  105. };
  106. static const struct luaL_Reg triple_lib_meth [] = {
  107. {"__gc", gc},
  108. {"__index", get_term},
  109. {"__newindex", set_term},
  110. {"copy_term", copy_term},
  111. {NULL}
  112. };
  113. int luaopen_triple (lua_State *L)
  114. {
  115. LSUP_init(); // This is idempotent: no problem calling it multiple times.
  116. luaL_newmetatable (L, "LSUP.Triple");
  117. lua_pushvalue (L, -1);
  118. // MT
  119. lua_setfield (L, -1, "__index");
  120. luaL_setfuncs (L, triple_lib_meth, 0);
  121. luaL_newlib (L, triple_lib_fn);
  122. // Module-level constants.
  123. lua_pushinteger (L, TRP_POS_S);
  124. lua_setfield (L, -2, "TRP_POS_S");
  125. lua_pushinteger (L, TRP_POS_P);
  126. lua_setfield (L, -2, "TRP_POS_P");
  127. lua_pushinteger (L, TRP_POS_O);
  128. lua_setfield (L, -2, "TRP_POS_O");
  129. return 1;
  130. }