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.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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. l2_io_printf(out, "(atom %u)", val->atom);
  10. break;
  11. case L2_VAL_TYPE_REAL:
  12. l2_io_printf(out, "%g", val->real);
  13. break;
  14. case L2_VAL_TYPE_BUFFER:
  15. if (val->buffer != NULL) {
  16. out->write(out, val->buffer->data, val->buffer->len);
  17. }
  18. break;
  19. case L2_VAL_TYPE_ARRAY:
  20. if (val->array == NULL) {
  21. out->write(out, "[]", 2);
  22. break;
  23. }
  24. out->write(out, "[", 1);
  25. for (size_t i = 0; i < val->array->len; ++i) {
  26. if (i != 0) {
  27. out->write(out, " ", 1);
  28. }
  29. print_val(vm, out, &vm->values[val->array->data[i]]);
  30. }
  31. out->write(out, "]", 1);
  32. break;
  33. case L2_VAL_TYPE_NAMESPACE:
  34. l2_io_printf(out, "(namespace)");
  35. break;
  36. case L2_VAL_TYPE_FUNCTION:
  37. case L2_VAL_TYPE_CFUNCTION:
  38. l2_io_printf(out, "(function)");
  39. break;
  40. case L2_VAL_TYPE_ERROR:
  41. l2_io_printf(out, "(error: %s)", val->error);
  42. break;
  43. }
  44. }
  45. l2_word l2_builtin_add(struct l2_vm *vm, struct l2_vm_array *args) {
  46. if (args->len < 1) {
  47. return 0;
  48. }
  49. struct l2_vm_value *val = &vm->values[args->data[0]];
  50. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  51. return l2_vm_type_error(vm, val);
  52. }
  53. double sum = val->real;
  54. for (size_t i = 1; i < args->len; ++i) {
  55. val = &vm->values[args->data[i]];
  56. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  57. return l2_vm_type_error(vm, val);
  58. }
  59. sum += val->real;
  60. }
  61. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  62. vm->values[id].real = sum;
  63. return id;
  64. }
  65. l2_word l2_builtin_sub(struct l2_vm *vm, struct l2_vm_array *args) {
  66. if (args->len < 1) {
  67. return 0;
  68. }
  69. struct l2_vm_value *val = &vm->values[args->data[0]];
  70. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  71. return l2_vm_type_error(vm, val);
  72. }
  73. double sum = val->real;
  74. for (size_t i = 1; i < args->len; ++i) {
  75. val = &vm->values[args->data[i]];
  76. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  77. return l2_vm_type_error(vm, val);
  78. }
  79. sum -= val->real;
  80. }
  81. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  82. vm->values[id].real = sum;
  83. return id;
  84. }
  85. l2_word l2_builtin_mul(struct l2_vm *vm, struct l2_vm_array *args) {
  86. if (args->len < 1) {
  87. return 0;
  88. }
  89. struct l2_vm_value *val = &vm->values[args->data[0]];
  90. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  91. return l2_vm_type_error(vm, val);
  92. }
  93. double sum = val->real;
  94. for (size_t i = 1; i < args->len; ++i) {
  95. val = &vm->values[args->data[i]];
  96. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  97. return l2_vm_type_error(vm, val);
  98. }
  99. sum *= val->real;
  100. }
  101. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  102. vm->values[id].real = sum;
  103. return id;
  104. }
  105. l2_word l2_builtin_div(struct l2_vm *vm, struct l2_vm_array *args) {
  106. if (args->len < 1) {
  107. return 0;
  108. }
  109. struct l2_vm_value *val = &vm->values[args->data[0]];
  110. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  111. return l2_vm_type_error(vm, val);
  112. }
  113. double sum = val->real;
  114. for (size_t i = 1; i < args->len; ++i) {
  115. val = &vm->values[args->data[i]];
  116. if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
  117. return l2_vm_type_error(vm, val);
  118. }
  119. sum /= val->real;
  120. }
  121. l2_word id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  122. vm->values[id].real = sum;
  123. return id;
  124. }
  125. l2_word l2_builtin_print(struct l2_vm *vm, struct l2_vm_array *args) {
  126. for (size_t i = 0; i < args->len; ++i) {
  127. if (i != 0) {
  128. vm->std_output->write(vm->std_output, " ", 1);
  129. }
  130. struct l2_vm_value *val = &vm->values[args->data[i]];
  131. print_val(vm, vm->std_output, val);
  132. }
  133. vm->std_output->write(vm->std_output, "\n", 1);
  134. return 0;
  135. }
  136. l2_word l2_builtin_len(struct l2_vm *vm, struct l2_vm_array *args) {
  137. // TODO: error if wrong argc
  138. l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
  139. struct l2_vm_value *ret = &vm->values[ret_id];
  140. ret->real = 0;
  141. struct l2_vm_value *val = &vm->values[args->data[0]];
  142. switch (l2_vm_value_type(val)) {
  143. case L2_VAL_TYPE_NONE:
  144. case L2_VAL_TYPE_ATOM:
  145. case L2_VAL_TYPE_REAL:
  146. case L2_VAL_TYPE_FUNCTION:
  147. case L2_VAL_TYPE_CFUNCTION:
  148. case L2_VAL_TYPE_ERROR:
  149. break;
  150. case L2_VAL_TYPE_BUFFER:
  151. if (val->buffer) {
  152. ret->real = val->buffer->len;
  153. }
  154. break;
  155. case L2_VAL_TYPE_ARRAY:
  156. if (val->array) {
  157. ret->real = val->array->len;
  158. }
  159. break;
  160. case L2_VAL_TYPE_NAMESPACE:
  161. if (val->ns) {
  162. ret->real = val->ns->len;
  163. }
  164. }
  165. return ret_id;
  166. }