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.

examples.t.c 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #ifdef __unix__
  2. #include "vm/vm.h"
  3. #include "parse/parse.h"
  4. #include <sys/types.h>
  5. #include <libgen.h>
  6. #include <dirent.h>
  7. #include <string.h>
  8. #include <errno.h>
  9. #include <stdio.h>
  10. #include <snow/snow.h>
  11. static char example_path[512];
  12. static char example_expected_path[512];
  13. static char example_actual_path[512];
  14. static char *error_message = NULL;
  15. static void check_diff(const char *expected, const char *actual) {
  16. FILE *e = fopen(expected, "r");
  17. if (e == NULL) {
  18. snow_fail("%s: %s\n Actual result stored in %s", expected, strerror(errno), actual);
  19. }
  20. FILE *a = fopen(actual, "r");
  21. if (a == NULL) {
  22. fclose(e);
  23. snow_fail("%s: %s", actual, strerror(errno));
  24. }
  25. int line = 1;
  26. int ch = 1;
  27. while (1) {
  28. int ech = fgetc(e);
  29. int ach = fgetc(a);
  30. if (ech != ach) {
  31. fclose(e);
  32. fclose(a);
  33. snow_fail("%s differs at location %i:%i:\n Expected %c(%i), got %c(%i)",
  34. actual, line, ch, ech, ech, ach, ach);
  35. }
  36. if (ech == EOF) {
  37. break;
  38. }
  39. if (ech == '\n') {
  40. line += 1;
  41. ch = 1;
  42. } else {
  43. ch += 1;
  44. }
  45. }
  46. fclose(e);
  47. fclose(a);
  48. }
  49. static void check_impl(const char *name) {
  50. char fname[] = __FILE__;
  51. char *dname = dirname(fname);
  52. snprintf(example_path, sizeof(example_path), "%s/../examples/%s", dname, name);
  53. snprintf(example_expected_path, sizeof(example_path), "%s/../examples/%s.expected", dname, name);
  54. snprintf(example_actual_path, sizeof(example_path), "%s/../examples/%s.actual", dname, name);
  55. FILE *inf = fopen(example_path, "r");
  56. if (inf == NULL) {
  57. snow_fail("%s: %s", example_path, strerror(errno));
  58. }
  59. struct l2_io_file_reader input ={
  60. .r.read = l2_io_file_read,
  61. .f = inf,
  62. };
  63. struct l2_io_mem_writer bytecode = {
  64. .w.write = l2_io_mem_write,
  65. .len = 0,
  66. .mem = NULL,
  67. };
  68. struct l2_lexer lexer;
  69. l2_lexer_init(&lexer, &input.r);
  70. struct l2_generator gen;
  71. l2_gen_init(&gen, &bytecode.w);
  72. struct l2_parse_error err;
  73. if (l2_parse_program(&lexer, &gen, &err) < 0) {
  74. free(bytecode.mem);
  75. fclose(input.f);
  76. error_message = err.message;
  77. snow_fail("%s: %s", example_path, err.message);
  78. }
  79. fclose(inf);
  80. FILE *outf = fopen(example_actual_path, "w");
  81. if (outf == NULL) {
  82. snow_fail("%s: %s", example_actual_path, strerror(errno));
  83. }
  84. struct l2_io_file_writer output = {
  85. .w.write = l2_io_file_write,
  86. .f = outf,
  87. };
  88. struct l2_vm vm;
  89. l2_vm_init(&vm, (l2_word *)bytecode.mem, bytecode.len / sizeof(l2_word));
  90. vm.std_output = &output.w;
  91. l2_vm_run(&vm);
  92. l2_vm_free(&vm);
  93. free(bytecode.mem);
  94. fclose(output.f);
  95. check_diff(example_expected_path, example_actual_path);
  96. }
  97. #define check(name) do { \
  98. snow_fail_update(); \
  99. check_impl(name); \
  100. } while (0)
  101. describe(exaples) {
  102. test("examples") {
  103. check("namespaces.l2");
  104. check("arrays.l2");
  105. check("functions.l2");
  106. }
  107. if (error_message != NULL) {
  108. free(error_message);
  109. }
  110. }
  111. #endif