您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

builtins.c 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "vm/builtins.h"
  2. #include <stdio.h>
  3. static void print_val(struct l2_vm *vm, struct l2_io_writer *out, struct l2_vm_value *val) {
  4. switch (l2_vm_value_type(val)) {
  5. case L2_VAL_TYPE_NONE:
  6. l2_io_printf(out, "(none)");
  7. break;
  8. case L2_VAL_TYPE_ATOM:
  9. if (val->atom == vm->values[vm->ktrue].atom) {
  10. l2_io_printf(out, "(true)");
  11. } else if (val->atom == vm->values[vm->kfalse].atom) {
  12. l2_io_printf(out, "(false)");
  13. } else {
  14. l2_io_printf(out, "(atom %u)", val->atom);
  15. }
  16. break;
  17. case L2_VAL_TYPE_REAL:
  18. l2_io_printf(out, "%g", val->real);
  19. break;
  20. case L2_VAL_TYPE_BUFFER:
  21. if (val->buffer != NULL) {
  22. out->write(out, val->buffer->data, val->buffer->len);
  23. }
  24. break;
  25. case L2_VAL_TYPE_ARRAY:
  26. if (val->array == NULL) {
  27. out->write(out, "[]", 2);
  28. break;
  29. }
  30. out->write(out, "[", 1);
  31. for (size_t i = 0; i < val->array->len; ++i) {
  32. if (i != 0) {
  33. out->write(out, " ", 1);
  34. }
  35. print_val(vm, out, &vm->values[val->array->data[i]]);
  36. }
  37. out->write(out, "]", 1);
  38. break;
  39. case L2_VAL_TYPE_NAMESPACE:
  40. l2_io_printf(out, "(namespace)");
  41. break;
  42. case L2_VAL_TYPE_FUNCTION:
  43. case L2_VAL_TYPE_CFUNCTION:
  44. l2_io_printf(out, "(function)");
  45. break;
  46. case L2_VAL_TYPE_ERROR:
  47. l2_io_printf(out, "(error: %s)", val->error);
  48. break;
  49. case L2_VAL_TYPE_CONTINUATION:
  50. l2_io_printf(out, "(continuation)");
  51. break;
  52. }
  53. }
  54. l2_word l2_builtin_add(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  55. if (argc < 1) {
  56. return 0;
  57. }
  58. struct l2_vm_value *val = &vm->values[argv[0]];
  59. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  60. return l2_vm_type_error(vm, val);
  61. }
  62. double sum = val->real;
  63. for (l2_word i = 1; i < argc; ++i) {
  64. val = &vm->values[argv[i]];
  65. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  66. return l2_vm_type_error(vm, val);
  67. }
  68. sum += val->real;
  69. }
  70. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  71. vm->values[id].real = sum;
  72. return id;
  73. }
  74. l2_word l2_builtin_sub(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  75. if (argc < 1) {
  76. return 0;
  77. }
  78. struct l2_vm_value *val = &vm->values[argv[0]];
  79. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  80. return l2_vm_type_error(vm, val);
  81. }
  82. double sum = val->real;
  83. for (l2_word i = 1; i < argc; ++i) {
  84. val = &vm->values[argv[i]];
  85. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  86. return l2_vm_type_error(vm, val);
  87. }
  88. sum -= val->real;
  89. }
  90. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  91. vm->values[id].real = sum;
  92. return id;
  93. }
  94. l2_word l2_builtin_mul(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  95. if (argc < 1) {
  96. return 0;
  97. }
  98. struct l2_vm_value *val = &vm->values[argv[0]];
  99. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  100. return l2_vm_type_error(vm, val);
  101. }
  102. double sum = val->real;
  103. for (l2_word i = 1; i < argc; ++i) {
  104. val = &vm->values[argv[i]];
  105. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  106. return l2_vm_type_error(vm, val);
  107. }
  108. sum *= val->real;
  109. }
  110. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  111. vm->values[id].real = sum;
  112. return id;
  113. }
  114. l2_word l2_builtin_div(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  115. if (argc < 1) {
  116. return 0;
  117. }
  118. struct l2_vm_value *val = &vm->values[argv[0]];
  119. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  120. return l2_vm_type_error(vm, val);
  121. }
  122. double sum = val->real;
  123. for (l2_word i = 1; i < argc; ++i) {
  124. val = &vm->values[argv[i]];
  125. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  126. return l2_vm_type_error(vm, val);
  127. }
  128. sum /= val->real;
  129. }
  130. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  131. vm->values[id].real = sum;
  132. return id;
  133. }
  134. l2_word l2_builtin_print(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  135. for (size_t i = 0; i < argc; ++i) {
  136. if (i != 0) {
  137. vm->std_output->write(vm->std_output, " ", 1);
  138. }
  139. struct l2_vm_value *val = &vm->values[argv[i]];
  140. print_val(vm, vm->std_output, val);
  141. }
  142. vm->std_output->write(vm->std_output, "\n", 1);
  143. return 0;
  144. }
  145. l2_word l2_builtin_len(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  146. if (argc != 1) {
  147. return l2_vm_error(vm, "Expected 1 argument");
  148. }
  149. l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  150. struct l2_vm_value *ret = &vm->values[ret_id];
  151. ret->real = 0;
  152. struct l2_vm_value *val = &vm->values[argv[0]];
  153. switch (l2_vm_value_type(val)) {
  154. case L2_VAL_TYPE_NONE:
  155. case L2_VAL_TYPE_ATOM:
  156. case L2_VAL_TYPE_REAL:
  157. case L2_VAL_TYPE_FUNCTION:
  158. case L2_VAL_TYPE_CFUNCTION:
  159. case L2_VAL_TYPE_ERROR:
  160. case L2_VAL_TYPE_CONTINUATION:
  161. break;
  162. case L2_VAL_TYPE_BUFFER:
  163. if (val->buffer) {
  164. ret->real = val->buffer->len;
  165. }
  166. break;
  167. case L2_VAL_TYPE_ARRAY:
  168. if (val->array) {
  169. ret->real = val->array->len;
  170. }
  171. break;
  172. case L2_VAL_TYPE_NAMESPACE:
  173. if (val->ns) {
  174. ret->real = val->ns->len;
  175. }
  176. }
  177. return ret_id;
  178. }
  179. l2_word l2_builtin_if(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  180. if (argc != 2 && argc != 3) {
  181. return l2_vm_error(vm, "Expected 2 or 3 arguments");
  182. }
  183. struct l2_vm_value *cond = &vm->values[argv[0]];
  184. if (
  185. l2_vm_value_type(cond) == L2_VAL_TYPE_ATOM &&
  186. cond->atom == vm->values[vm->ktrue].atom) {
  187. l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_CONTINUATION, 0);
  188. struct l2_vm_value *ret = &vm->values[ret_id];
  189. ret->cont.call = argv[1];
  190. ret->cont.arg = 0;
  191. return ret_id;
  192. } else if (argc == 3) {
  193. l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_CONTINUATION, 0);
  194. struct l2_vm_value *ret = &vm->values[ret_id];
  195. ret->cont.call = argv[2];
  196. ret->cont.arg = 0;
  197. return ret_id;
  198. } else {
  199. return 0;
  200. }
  201. }