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.

eval.t.c 2.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "parse/parse.h"
  2. #include "vm/vm.h"
  3. #include "vm/print.h"
  4. #include <stdio.h>
  5. #include <snow/snow.h>
  6. static struct l2_lexer lex;
  7. static struct l2_io_mem_reader r;
  8. static struct l2_generator gen;
  9. static struct l2_io_mem_writer w;
  10. static struct l2_vm vm;
  11. static struct l2_vm_value *var_lookup(const char *name) {
  12. l2_word atom_id = l2_strset_get(&gen.atomset, name);
  13. l2_word id = l2_vm_namespace_get(&vm, &vm.values[vm.nstack[1]], atom_id);
  14. return &vm.values[id];
  15. }
  16. static int eval_impl(const char *str, struct l2_parse_error *err) {
  17. r.r.read = l2_io_mem_read;
  18. r.idx = 0;
  19. r.len = strlen(str);
  20. r.mem = str;
  21. l2_lexer_init(&lex, &r.r);
  22. w.w.write = l2_io_mem_write;
  23. w.len = 0;
  24. w.mem = NULL;
  25. l2_gen_init(&gen, (struct l2_io_writer *)&w);
  26. if (l2_parse_program(&lex, &gen, err) < 0) {
  27. free(w.mem);
  28. return -1;
  29. }
  30. l2_vm_init(&vm, (l2_word *)w.mem, w.len / sizeof(l2_word));
  31. l2_vm_run(&vm);
  32. free(w.mem);
  33. return 0;
  34. }
  35. #define eval(str) do { \
  36. snow_fail_update(); \
  37. struct l2_parse_error err; \
  38. if (eval_impl(str, &err) < 0) { \
  39. snow_fail("Parsing failed: %i:%i: %s", err.line, err.ch, err.message); \
  40. } \
  41. } while (0)
  42. describe(eval) {
  43. test("assignment") {
  44. eval("foo := 10");
  45. defer(l2_vm_free(&vm));
  46. defer(l2_gen_free(&gen));
  47. asserteq(l2_vm_value_type(var_lookup("foo")), L2_VAL_TYPE_REAL);
  48. asserteq(var_lookup("foo")->real, 10);
  49. }
  50. test("var deref assignment") {
  51. eval("foo := 10\nbar := foo");
  52. defer(l2_vm_free(&vm));
  53. defer(l2_gen_free(&gen));
  54. asserteq(l2_vm_value_type(var_lookup("foo")), L2_VAL_TYPE_REAL);
  55. asserteq(var_lookup("foo")->real, 10);
  56. asserteq(l2_vm_value_type(var_lookup("bar")), L2_VAL_TYPE_REAL);
  57. asserteq(var_lookup("bar")->real, 10);
  58. }
  59. test("string assignment") {
  60. eval("foo := \"hello world\"");
  61. defer(l2_vm_free(&vm));
  62. defer(l2_gen_free(&gen));
  63. asserteq(l2_vm_value_type(var_lookup("foo")), L2_VAL_TYPE_BUFFER);
  64. struct l2_vm_buffer *buf = var_lookup("foo")->buffer;
  65. asserteq(buf->len, 11);
  66. assert(strncmp(buf->data, "hello world", 11) == 0);
  67. }
  68. }