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.

vm.c 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "vm/vm.h"
  2. void l2_vm_init(struct l2_vm *vm, struct l2_op *ops, size_t opcount) {
  3. vm->ops = ops;
  4. vm->opcount = opcount;
  5. vm->iptr = 0;
  6. vm->sptr = 0;
  7. vm->values = NULL;
  8. vm->valuessize = 0;
  9. l2_bitset_init(&vm->valueset);
  10. }
  11. static l2_word alloc_val(struct l2_vm *vm) {
  12. size_t id = l2_bitset_set_next(&vm->valueset);
  13. if (id > vm->valuessize) {
  14. if (vm->valuessize == 0) {
  15. vm->valuessize = 16;
  16. }
  17. while (id > vm->valuessize) {
  18. vm->valuessize *= 2;
  19. }
  20. vm->values = realloc(vm->values, sizeof(*vm->values) * vm->valuessize);
  21. }
  22. return (l2_word)id;
  23. }
  24. void l2_vm_step(struct l2_vm *vm) {
  25. struct l2_op op = vm->ops[vm->iptr++];
  26. l2_word word;
  27. switch (op.code) {
  28. case L2_OP_PUSH:
  29. vm->stack[vm->sptr++] = op.val;
  30. break;
  31. case L2_OP_ADD:
  32. vm->sptr -= 1;
  33. vm->stack[vm->sptr - 1] += vm->stack[vm->sptr];
  34. break;
  35. case L2_OP_JUMP:
  36. vm->iptr = vm->stack[--vm->sptr];
  37. break;
  38. case L2_OP_CALL:
  39. word = vm->stack[--vm->sptr];
  40. vm->stack[vm->sptr++] = vm->iptr + 1;
  41. vm->iptr = word;
  42. break;
  43. case L2_OP_RET:
  44. vm->iptr = vm->stack[--vm->sptr];
  45. break;
  46. case L2_OP_ALLOC_INTEGER:
  47. word = alloc_val(vm);
  48. vm->values[word].flags = L2_VAL_TYPE_INTEGER;
  49. vm->values[word].integer = 0;
  50. vm->stack[vm->sptr++] = word;
  51. break;
  52. case L2_OP_ALLOC_REAL:
  53. word = alloc_val(vm);
  54. vm->values[word].flags = L2_VAL_TYPE_REAL;
  55. vm->values[word].real = 0;
  56. vm->stack[vm->sptr++] = word;
  57. break;
  58. case L2_OP_ALLOC_STRING:
  59. word = alloc_val(vm);
  60. vm->values[word].flags = L2_VAL_TYPE_STRING;
  61. vm->values[word].data = calloc(1, sizeof(struct l2_vm_string));
  62. vm->stack[vm->sptr++] = word;
  63. break;
  64. case L2_OP_ALLOC_ARRAY:
  65. word = alloc_val(vm);
  66. vm->values[word].flags = L2_VAL_TYPE_ARRAY;
  67. vm->values[word].data = calloc(1, sizeof(struct l2_vm_array));
  68. vm->stack[vm->sptr++] = word;
  69. break;
  70. case L2_OP_HALT:
  71. break;
  72. }
  73. }