You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

builtins.c 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. }
  50. }
  51. l2_word l2_builtin_add(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  52. if (argc < 1) {
  53. return 0;
  54. }
  55. struct l2_vm_value *val = &vm->values[argv[0]];
  56. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  57. return l2_vm_type_error(vm, val);
  58. }
  59. double sum = val->real;
  60. for (l2_word i = 1; i < argc; ++i) {
  61. val = &vm->values[argv[i]];
  62. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  63. return l2_vm_type_error(vm, val);
  64. }
  65. sum += val->real;
  66. }
  67. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  68. vm->values[id].real = sum;
  69. return id;
  70. }
  71. l2_word l2_builtin_sub(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  72. if (argc < 1) {
  73. return 0;
  74. }
  75. struct l2_vm_value *val = &vm->values[argv[0]];
  76. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  77. return l2_vm_type_error(vm, val);
  78. }
  79. double sum = val->real;
  80. for (l2_word i = 1; i < argc; ++i) {
  81. val = &vm->values[argv[i]];
  82. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  83. return l2_vm_type_error(vm, val);
  84. }
  85. sum -= val->real;
  86. }
  87. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  88. vm->values[id].real = sum;
  89. return id;
  90. }
  91. l2_word l2_builtin_mul(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  92. if (argc < 1) {
  93. return 0;
  94. }
  95. struct l2_vm_value *val = &vm->values[argv[0]];
  96. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  97. return l2_vm_type_error(vm, val);
  98. }
  99. double sum = val->real;
  100. for (l2_word i = 1; i < argc; ++i) {
  101. val = &vm->values[argv[i]];
  102. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  103. return l2_vm_type_error(vm, val);
  104. }
  105. sum *= val->real;
  106. }
  107. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  108. vm->values[id].real = sum;
  109. return id;
  110. }
  111. l2_word l2_builtin_div(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  112. if (argc < 1) {
  113. return 0;
  114. }
  115. struct l2_vm_value *val = &vm->values[argv[0]];
  116. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  117. return l2_vm_type_error(vm, val);
  118. }
  119. double sum = val->real;
  120. for (l2_word i = 1; i < argc; ++i) {
  121. val = &vm->values[argv[i]];
  122. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  123. return l2_vm_type_error(vm, val);
  124. }
  125. sum /= val->real;
  126. }
  127. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  128. vm->values[id].real = sum;
  129. return id;
  130. }
  131. l2_word l2_builtin_print(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  132. for (size_t i = 0; i < argc; ++i) {
  133. if (i != 0) {
  134. vm->std_output->write(vm->std_output, " ", 1);
  135. }
  136. struct l2_vm_value *val = &vm->values[argv[i]];
  137. print_val(vm, vm->std_output, val);
  138. }
  139. vm->std_output->write(vm->std_output, "\n", 1);
  140. return 0;
  141. }
  142. l2_word l2_builtin_len(struct l2_vm *vm, l2_word argc, l2_word *argv) {
  143. if (argc < 1) {
  144. return l2_vm_error(vm, "Expected at least 1 argument");
  145. }
  146. l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  147. struct l2_vm_value *ret = &vm->values[ret_id];
  148. ret->real = 0;
  149. struct l2_vm_value *val = &vm->values[argv[0]];
  150. switch (l2_vm_value_type(val)) {
  151. case L2_VAL_TYPE_NONE:
  152. case L2_VAL_TYPE_ATOM:
  153. case L2_VAL_TYPE_REAL:
  154. case L2_VAL_TYPE_FUNCTION:
  155. case L2_VAL_TYPE_CFUNCTION:
  156. case L2_VAL_TYPE_ERROR:
  157. break;
  158. case L2_VAL_TYPE_BUFFER:
  159. if (val->buffer) {
  160. ret->real = val->buffer->len;
  161. }
  162. break;
  163. case L2_VAL_TYPE_ARRAY:
  164. if (val->array) {
  165. ret->real = val->array->len;
  166. }
  167. break;
  168. case L2_VAL_TYPE_NAMESPACE:
  169. if (val->ns) {
  170. ret->real = val->ns->len;
  171. }
  172. }
  173. return ret_id;
  174. }