mes_record.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. int string_size(char* a);
  24. struct cell* make_record(struct cell* type, struct cell* vector);
  25. struct cell* make_record_type(char* name, struct cell* list);
  26. struct cell* make_string(char* a, int length);
  27. struct cell* make_vector(int count, struct cell* init);
  28. int record_field_index(struct cell* record, char* name)
  29. {
  30. require(RECORD_TYPE == record->type, "mes_record.c: record_field_index did not receive a record-type\n");
  31. struct cell* i = record->cdr->cdr;
  32. int count = 0;
  33. while(nil != i)
  34. {
  35. if(match(i->car->string, name)) return count;
  36. count = count + 1;
  37. i = i->cdr;
  38. }
  39. require(FALSE, "mes_record.c: record_field_index did not find field with matching name\n");
  40. exit(EXIT_FAILURE);
  41. }
  42. struct cell* record_ref(struct cell* type, char* name, struct cell* record)
  43. {
  44. int i = record_field_index(type, name);
  45. struct cell* e = record->cdr->cdr;
  46. while(0 < i)
  47. {
  48. e = e->cdr;
  49. i = i - 1;
  50. }
  51. return e->car;
  52. }
  53. struct cell* record_set(struct cell* type, char* name, struct cell* record, struct cell* value)
  54. {
  55. int i = record_field_index(type, name);
  56. struct cell* e = record->cdr->cdr;
  57. while(0 < i)
  58. {
  59. e = e->cdr;
  60. i = i - 1;
  61. }
  62. e->car = value;
  63. return value;
  64. }
  65. struct cell* record_construct(struct cell* type, struct cell* list_args, struct cell* list_vals)
  66. {
  67. struct cell* e = make_record(type, make_vector(type->cdr->value, cell_f));
  68. while(nil != list_args)
  69. {
  70. require(SYM == list_args->car->type, "mes_record.c: record_construct was not passed symbols\n");
  71. require(nil != list_vals, "mes_record.c: record_construct received insufficient values\n");
  72. record_set(type, list_args->car->string, e, list_vals->car);
  73. list_args = list_args->cdr;
  74. list_vals = list_vals->cdr;
  75. }
  76. return e;
  77. }
  78. /* Exposed primitives */
  79. struct cell* builtin_make_record_type(struct cell* args)
  80. {
  81. require(nil != args, "make-record-type requires arguments\n");
  82. require(nil != args->cdr, "make-record-type received insufficient arguments\n");
  83. require(STRING == args->car->type, "make-record-type did not receive a string\n");
  84. require(CONS == args->cdr->car->type, "make-record-type did not receive a list\n");
  85. return make_record_type(args->car->string, args->cdr->car);
  86. }
  87. struct cell* builtin_make_record(struct cell* args)
  88. {
  89. require(nil != args, "make-record requires arguments\n");
  90. require(nil != args->cdr, "make-record received insufficient arguments\n");
  91. require(RECORD_TYPE == args->car->type, "make-record did not receive a string\n");
  92. require(VECTOR == args->cdr->car->type, "make-record did not receive a vector\n");
  93. return make_record(args->car, args->cdr->car);
  94. }
  95. struct cell* builtin_record_type_name(struct cell* args)
  96. {
  97. require(nil != args, "record-type-name requires an argument\n");
  98. require(nil == args->cdr, "record-type-name received too many arguments\n");
  99. require(RECORD_TYPE == args->car->type, "record-type-name did not receive a record-type\n");
  100. return make_string(args->car->string, string_size(args->car->string));
  101. }
  102. struct cell* builtin_record_type_fields(struct cell* args)
  103. {
  104. require(nil != args, "record-type-fields requires an argument\n");
  105. require(nil == args->cdr, "record-type-fields received too many arguments\n");
  106. require(RECORD_TYPE == args->car->type, "record-type-fields did not receive a record-type\n");
  107. return args->car->cdr->cdr;
  108. }
  109. struct cell* builtin_record_typep(struct cell* args)
  110. {
  111. require(nil != args, "record-type? requires an argument\n");
  112. require(nil == args->cdr, "record-type? received too many arguments\n");
  113. if(RECORD_TYPE == args->car->type) return cell_t;
  114. return cell_f;
  115. }
  116. struct cell* builtin_recordp(struct cell* args)
  117. {
  118. require(nil != args, "record? requires an argument\n");
  119. require(nil == args->cdr, "record? received too many arguments\n");
  120. if(RECORD == args->car->type) return cell_t;
  121. return cell_f;
  122. }
  123. struct cell* builtin_record_type_descriptor(struct cell* args)
  124. {
  125. require(nil != args, "record-type-descriptor requires an argument\n");
  126. require(nil == args->cdr, "record-type-descriptor received too many arguments\n");
  127. require(RECORD == args->car->type, "record-type-descriptor did not receive a record\n");
  128. return args->car->car;
  129. }
  130. struct cell* builtin_record_predicate(struct cell* args)
  131. {
  132. require(nil != args, "core:record-predicate requires an argument\n");
  133. require(nil != args->cdr, "core:record-predicate received insufficient arguments\n");
  134. if(RECORD_TYPE == args->car->type)
  135. {
  136. if(RECORD == args->cdr->car->type)
  137. {
  138. if(args->cdr->car->car == args->car) return cell_t;
  139. }
  140. }
  141. return cell_f;
  142. }
  143. struct cell* builtin_record_accessor(struct cell* args)
  144. {
  145. require(nil != args, "core:record-accessor requires arguments\n");
  146. require(nil != args->cdr, "core:record-accessor requires more arguments\n");
  147. require(nil != args->cdr->cdr, "core:record-accessor requires more arguments\n");
  148. require(RECORD_TYPE == args->car->type, "core:record-accessor did not receive RECORD-TYPE\n");
  149. require(SYM == args->cdr->car->type, "core:record-accessor did not receive SYMBOL\n");
  150. require(RECORD == args->cdr->cdr->car->type, "core:record-accessor did not receive RECORD\n");
  151. require(args->cdr->cdr->car->car == args->car, "core:record-accessor got a record of a type different than record-type\n");
  152. return record_ref(args->car, args->cdr->car->string, args->cdr->cdr->car);
  153. }
  154. struct cell* builtin_record_modifier(struct cell* args)
  155. {
  156. require(nil != args, "core:record-modifier requires arguments\n");
  157. require(nil != args->cdr, "core:record-modifier requires more arguments\n");
  158. require(nil != args->cdr->cdr, "core:record-modifier requires more arguments\n");
  159. require(nil != args->cdr->cdr->cdr, "core:record-modifier requires more arguments\n");
  160. require(RECORD_TYPE == args->car->type, "core:record-modifier did not receive RECORD-TYPE\n");
  161. require(SYM == args->cdr->car->type, "core:record-modifier did not receive SYMBOL\n");
  162. require(RECORD == args->cdr->cdr->car->type, "core:record-modifier did not receive RECORD\n");
  163. require(args->cdr->cdr->car->car == args->car, "core:record-modifier got a record of a type different than record-type\n");
  164. return record_set(args->car, args->cdr->car->string, args->cdr->cdr->car, args->cdr->cdr->cdr->car);
  165. }
  166. struct cell* builtin_record_constructor(struct cell* args)
  167. {
  168. require(nil != args, "core:record-constructor requires arguments\n");
  169. require(nil != args->cdr, "core:record-constructor requires more arguments\n");
  170. require(nil != args->cdr->cdr, "core:record-constructor requires more arguments\n");
  171. require(RECORD_TYPE == args->car->type, "core:record-constructor did not receive RECORD-TYPE\n");
  172. require(CONS == args->cdr->car->type, "core:record-constructor did not receive argument list\n");
  173. require(CONS == args->cdr->cdr->car->type, "core:record-constructor did not receive argument list\n");
  174. return record_construct(args->car, args->cdr->car, args->cdr->cdr->car);
  175. }