mes_record.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* -*-comment-start: "//";comment-end:""-*-
  2. * GNU Mes --- Maxwell Equations of Software
  3. * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  4. * Copyright © 2019 Jeremiah Orians
  5. *
  6. * This file is part of GNU Mes.
  7. *
  8. * GNU Mes is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * GNU Mes is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include "mes.h"
  22. /* Imported functions */
  23. struct cell* make_record(struct cell* type, struct cell* vector);
  24. struct cell* make_record_type(char* name, struct cell* list);
  25. struct cell* make_string(char* a);
  26. struct cell* make_vector(int count, struct cell* init);
  27. int record_field_index(struct cell* record, char* name)
  28. {
  29. require(RECORD_TYPE == record->type, "mes_record.c: record_field_index did not receive a record-type\n");
  30. struct cell* i = record->cdr->cdr;
  31. int count = 0;
  32. while(nil != i)
  33. {
  34. if(match(i->car->string, name)) return count;
  35. count = count + 1;
  36. i = i->cdr;
  37. }
  38. require(FALSE, "mes_record.c: record_field_index did not find field with matching name\n");
  39. exit(EXIT_FAILURE);
  40. }
  41. struct cell* record_ref(struct cell* type, char* name, struct cell* record)
  42. {
  43. int i = record_field_index(type, name);
  44. struct cell* e = record->cdr->cdr;
  45. while(0 < i)
  46. {
  47. e = e->cdr;
  48. i = i - 1;
  49. }
  50. return e->car;
  51. }
  52. struct cell* record_set(struct cell* type, char* name, struct cell* record, struct cell* value)
  53. {
  54. int i = record_field_index(type, name);
  55. struct cell* e = record->cdr->cdr;
  56. while(0 < i)
  57. {
  58. e = e->cdr;
  59. i = i - 1;
  60. }
  61. e->car = value;
  62. return value;
  63. }
  64. struct cell* record_construct(struct cell* type, struct cell* list_args, struct cell* list_vals)
  65. {
  66. struct cell* e = make_record(type, make_vector(type->cdr->value, cell_f));
  67. while(nil != list_args)
  68. {
  69. require(SYM == list_args->car->type, "mes_record.c: record_construct was not passed symbols\n");
  70. require(nil != list_vals, "mes_record.c: record_construct received insufficient values\n");
  71. record_set(type, list_args->car->string, e, list_vals->car);
  72. list_args = list_args->cdr;
  73. list_vals = list_vals->cdr;
  74. }
  75. return e;
  76. }
  77. /* Exposed primitives */
  78. struct cell* builtin_make_record_type(struct cell* args)
  79. {
  80. require(nil != args, "make-record-type requires arguments\n");
  81. require(nil != args->cdr, "make-record-type received insufficient arguments\n");
  82. require(STRING == args->car->type, "make-record-type did not receive a string\n");
  83. require(CONS == args->cdr->car->type, "make-record-type did not receive a list\n");
  84. return make_record_type(args->car->string, args->cdr->car);
  85. }
  86. struct cell* builtin_make_record(struct cell* args)
  87. {
  88. require(nil != args, "make-record requires arguments\n");
  89. require(nil != args->cdr, "make-record received insufficient arguments\n");
  90. require(RECORD_TYPE == args->car->type, "make-record did not receive a string\n");
  91. require(VECTOR == args->cdr->car->type, "make-record did not receive a vector\n");
  92. return make_record(args->car, args->cdr->car);
  93. }
  94. struct cell* builtin_record_type_name(struct cell* args)
  95. {
  96. require(nil != args, "record-type-name requires an argument\n");
  97. require(nil == args->cdr, "record-type-name received too many arguments\n");
  98. require(RECORD_TYPE == args->car->type, "record-type-name did not receive a record-type\n");
  99. return make_string(args->car->string);
  100. }
  101. struct cell* builtin_record_type_fields(struct cell* args)
  102. {
  103. require(nil != args, "record-type-fields requires an argument\n");
  104. require(nil == args->cdr, "record-type-fields received too many arguments\n");
  105. require(RECORD_TYPE == args->car->type, "record-type-fields did not receive a record-type\n");
  106. return args->car->cdr->cdr;
  107. }
  108. struct cell* builtin_record_typep(struct cell* args)
  109. {
  110. require(nil != args, "record-type? requires an argument\n");
  111. require(nil == args->cdr, "record-type? received too many arguments\n");
  112. if(RECORD_TYPE == args->car->type) return cell_t;
  113. return cell_f;
  114. }
  115. struct cell* builtin_recordp(struct cell* args)
  116. {
  117. require(nil != args, "record? requires an argument\n");
  118. require(nil == args->cdr, "record? received too many arguments\n");
  119. if(RECORD == args->car->type) return cell_t;
  120. return cell_f;
  121. }
  122. struct cell* builtin_record_type_descriptor(struct cell* args)
  123. {
  124. require(nil != args, "record-type-descriptor requires an argument\n");
  125. require(nil == args->cdr, "record-type-descriptor received too many arguments\n");
  126. require(RECORD == args->car->type, "record-type-descriptor did not receive a record\n");
  127. return args->car->car;
  128. }
  129. struct cell* builtin_record_predicate(struct cell* args)
  130. {
  131. require(nil != args, "core:record-predicate requires an argument\n");
  132. require(nil != args->cdr, "core:record-predicate received insufficient arguments\n");
  133. if(RECORD_TYPE == args->car->type)
  134. {
  135. if(RECORD == args->cdr->car->type)
  136. {
  137. if(args->cdr->car->car == args->car) return cell_t;
  138. }
  139. }
  140. return cell_f;
  141. }
  142. struct cell* builtin_record_accessor(struct cell* args)
  143. {
  144. require(nil != args, "core:record-accessor requires arguments\n");
  145. require(nil != args->cdr, "core:record-accessor requires more arguments\n");
  146. require(nil != args->cdr->cdr, "core:record-accessor requires more arguments\n");
  147. require(RECORD_TYPE == args->car->type, "core:record-accessor did not receive RECORD-TYPE\n");
  148. require(SYM == args->cdr->car->type, "core:record-accessor did not receive SYMBOL\n");
  149. require(RECORD == args->cdr->cdr->car->type, "core:record-accessor did not receive RECORD\n");
  150. require(args->cdr->cdr->car->car == args->car, "core:record-accessor got a record of a type different than record-type\n");
  151. return record_ref(args->car, args->cdr->car->string, args->cdr->cdr->car);
  152. }
  153. struct cell* builtin_record_modifier(struct cell* args)
  154. {
  155. require(nil != args, "core:record-modifier requires arguments\n");
  156. require(nil != args->cdr, "core:record-modifier requires more arguments\n");
  157. require(nil != args->cdr->cdr, "core:record-modifier requires more arguments\n");
  158. require(nil != args->cdr->cdr->cdr, "core:record-modifier requires more arguments\n");
  159. require(RECORD_TYPE == args->car->type, "core:record-modifier did not receive RECORD-TYPE\n");
  160. require(SYM == args->cdr->car->type, "core:record-modifier did not receive SYMBOL\n");
  161. require(RECORD == args->cdr->cdr->car->type, "core:record-modifier did not receive RECORD\n");
  162. require(args->cdr->cdr->car->car == args->car, "core:record-modifier got a record of a type different than record-type\n");
  163. return record_set(args->car, args->cdr->car->string, args->cdr->cdr->car, args->cdr->cdr->cdr->car);
  164. }
  165. struct cell* builtin_record_constructor(struct cell* args)
  166. {
  167. require(nil != args, "core:record-constructor requires arguments\n");
  168. require(nil != args->cdr, "core:record-constructor requires more arguments\n");
  169. require(nil != args->cdr->cdr, "core:record-constructor requires more arguments\n");
  170. require(RECORD_TYPE == args->car->type, "core:record-constructor did not receive RECORD-TYPE\n");
  171. require(CONS == args->cdr->car->type, "core:record-constructor did not receive argument list\n");
  172. require(CONS == args->cdr->cdr->car->type, "core:record-constructor did not receive argument list\n");
  173. return record_construct(args->car, args->cdr->car, args->cdr->cdr->car);
  174. }