Minimal programming language prototype, created with goal to have very small compiler, so that anyone can write his own compiler for it.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

230 строки
9.6KB

  1. #include <xolatile/xtandard.c>
  2. #include <xolatile/xyntax.c>
  3. static int coin_code = 0;
  4. static int type_code = 0;
  5. static int variable_code = 0;
  6. static int constant_code = 0;
  7. static int function_code = 0;
  8. static int coin_data [240] = { 0 };
  9. static int coin_size [240] = { 0 };
  10. static char coin_text [240] [40] = { "" };
  11. static char type_name [27] [40] = { "" };
  12. static int type_size [27] = { 0 };
  13. static char variable_name [27] [40] = { "" };
  14. static int variable_type [27] = { 0 };
  15. static int variable_data [27] = { 0 };
  16. static char constant_name [30] [40] = { "" };
  17. static int constant_type [30] = { 0 };
  18. static int constant_data [30] = { 0 };
  19. static char function_name [9] [40] = { "" };
  20. static int function_type [9] = { 0 };
  21. static char function_argument_name [9] [6] [40] = { { "" } };
  22. static int function_argument_type [9] [6] = { { 0 } };
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. /*
  26. static char * register_list [] = {
  27. "rax","rdi","rsi","rdx","r10","r8","r9"
  28. };
  29. */
  30. static void add_coin (int data, int size, char * text) {
  31. coin_data [coin_code] = data;
  32. coin_size [coin_code] = size;
  33. string_copy_limit (coin_text [coin_code], text, size);
  34. ++coin_code;
  35. }
  36. static void kill (char * text, int offset) {
  37. int i;
  38. terminal_colour (colour_red, effect_bold);
  39. echo (text);
  40. terminal_cancel ();
  41. echo (coin_text [offset]);
  42. echo ("\n");
  43. for (i = 0; i < offset + 3; ++i) {
  44. if (i == offset) {
  45. terminal_colour (colour_red, effect_bold);
  46. echo (coin_text [i]);
  47. echo (" ");
  48. terminal_cancel ();
  49. } else {
  50. echo (coin_text [i]);
  51. echo (" ");
  52. }
  53. }
  54. echo ("\n");
  55. }
  56. int main (void) {
  57. char * buffer = null;
  58. int offset = 0;
  59. int length = 0;
  60. int select = 0;
  61. /**/int i;
  62. int coin_string = syntax_define (false, false, "\"", "\"", '\\', colour_red, effect_normal);
  63. int coin_type = syntax_define (false, true, "одреди", " \t\n", '\0', colour_yellow, effect_normal);
  64. int coin_loop = syntax_define (false, true, "понови", " \t\n(:", '\0', colour_yellow, effect_normal);
  65. int coin_if = syntax_define (false, true, "ако", " \t\n(", '\0', colour_yellow, effect_normal);
  66. int coin_else = syntax_define (false, true, "иначе", " \t\n:", '\0', colour_yellow, effect_normal);
  67. int coin_case = syntax_define (false, true, "погоди", " \t\n(", '\0', colour_yellow, effect_normal);
  68. int coin_return = syntax_define (false, true, "врати", " \t\n(;", '\0', colour_yellow, effect_normal);
  69. int coin_import = syntax_define (false, true, "учитај", " \t\n", '\0', colour_yellow, effect_normal);
  70. int coin_system = syntax_define (false, true, "изврши", " \t\n(", '\0', colour_yellow, effect_normal);
  71. int coin_number = syntax_define (true, true, "0123456789", " \t\n,.;:()[]#", '\0', colour_blue, effect_normal);
  72. int coin_marker = syntax_define (true, true, "абвгдђежзијклљмнљопрстћуфхцчџш_", " \t\n,.;:()[]#", '\0', colour_white, effect_normal);
  73. int coin_symbol = syntax_define (true, false, ",.;:=#[]()+-*/%&|!", "", '\0', colour_cyan, effect_normal);
  74. buffer = record ();
  75. for (offset = 0; buffer [offset] != '\0'; offset += length) {
  76. select = syntax_select (& buffer [offset], & length);
  77. if (select < syntax_count) {
  78. terminal_colour (syntax_colour [select], syntax_effect [select]);
  79. add_coin (select, length, & buffer [offset]);
  80. } else {
  81. terminal_colour (colour_red, effect_bold);
  82. if (character_compare_array (buffer [offset], " \t\n") == false) {
  83. kill ("Illegal character: ", offset);
  84. }
  85. }
  86. out (& buffer [offset], length);
  87. terminal_cancel ();
  88. }
  89. for (offset = 0; offset < coin_code; ++offset) {
  90. if (coin_data [offset] == coin_type) {
  91. ++offset;
  92. if (coin_data [offset] == coin_marker) {
  93. string_copy (type_name [type_code], coin_text [offset]);
  94. ++offset;
  95. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == '=')) {
  96. ++offset;
  97. if (coin_data [offset] == coin_number) {
  98. type_size [type_code] = atoi (coin_text [offset]);
  99. ++offset;
  100. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ';')) {
  101. ++type_code;
  102. } else kill ("Expected semicolon symbol: ", offset);
  103. } else kill ("Expected number: ", offset);
  104. } else if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == '(')) {
  105. int counter = 0;
  106. type_size [type_code] = 4;
  107. for (++offset; offset < coin_code; ++offset) {
  108. if (coin_data [offset] == coin_marker) {
  109. string_copy (constant_name [constant_code], coin_text [offset]);
  110. constant_type [constant_code] = type_code;
  111. ++offset;
  112. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ')')) {
  113. constant_data [constant_code] = counter;
  114. ++counter;
  115. ++constant_code;
  116. break;
  117. } else if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ',')) {
  118. constant_data [constant_code] = counter;
  119. ++counter;
  120. ++constant_code;
  121. } else if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == '=')) {
  122. ++offset;
  123. if (coin_data [offset] == coin_number) {
  124. int number = atoi (coin_text [offset]);
  125. constant_data [constant_code] = number;
  126. counter = number + 1;
  127. ++constant_code;
  128. ++offset;
  129. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ')')) {
  130. break;
  131. } else if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ',')) {
  132. ++counter; /* Should I replace this? */
  133. } else kill ("Expected , or ) ", offset);
  134. } else kill ("Expected constant data number:", offset);
  135. } else kill ("Expected = or , or ) ", offset);
  136. } else kill ("Expected constant name marker: ", offset);
  137. }
  138. ++type_code;
  139. } else kill ("Expected equal or open bracket symbol: ", offset);
  140. } else kill ("Expected marker: ", offset);
  141. } else if (coin_data [offset] == coin_marker) {
  142. ++offset;
  143. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ':')) {
  144. string_copy (variable_name [variable_code], coin_text [offset - 1]);
  145. ++offset;
  146. if (coin_data [offset] == coin_marker) {
  147. int j;
  148. for (j = 0; j < type_code; ++j) {
  149. if (string_compare (coin_text [offset], type_name [j]) == true) {
  150. variable_type [variable_code] = j;
  151. break;
  152. }
  153. }
  154. if (j == type_code) {
  155. kill ("Unknown type: ", offset);
  156. }
  157. ++offset;
  158. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == '=')) {
  159. ++offset;
  160. if (coin_data [offset] == coin_number) {
  161. variable_data [variable_code] = atoi (coin_text [offset]);
  162. ++offset;
  163. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ';')) {
  164. printf ("\033[1;32m%s: %s %i\033[0m\n",
  165. variable_name [variable_code],
  166. (type_size [variable_type [variable_code]] == 1) ? "db" : "dd",
  167. variable_data [variable_code]);
  168. ++variable_code;
  169. } else kill ("Expected semicolon symbol: ", offset);
  170. } else if (coin_data [offset] == coin_string) {
  171. variable_data [variable_code] = 33;
  172. ++offset;
  173. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ';')) {
  174. printf ("\033[1;32m%s: %s %s, 0\033[0m\n",
  175. variable_name [variable_code],
  176. (type_size [variable_type [variable_code]] == 1) ? "db" : "dd",
  177. coin_text [offset - 1]);
  178. ++variable_code;
  179. } else kill ("Expected semicolon symbol: ", offset);
  180. } else if (coin_data [offset] == coin_marker) {
  181. variable_data [variable_code] = 66;
  182. ++offset;
  183. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ';')) {
  184. printf ("\033[1;32m%s: %s %i\033[0m\n",
  185. variable_name [variable_code],
  186. (type_size [variable_type [variable_code]] == 1) ? "db" : "dd",
  187. variable_data [variable_code]);
  188. ++variable_code;
  189. } else kill ("Expected semicolon symbol: ", offset);
  190. } else kill ("Expected marker, number or string: ", offset);
  191. } else kill ("Expected equal symbol: ", offset);
  192. } else kill ("Expected type: ", offset);
  193. } else if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == '(')) {
  194. string_copy (function_name [function_code], coin_text [offset - 1]);
  195. ++offset;
  196. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ')')) {
  197. ++offset;
  198. if ((coin_data [offset] == coin_symbol) && (* coin_text [offset] == ':')) {
  199. echo ("PROCESSING FUNCTION...\n");
  200. ++function_code;
  201. } else kill ("Expected void function, symbol :: ", offset);
  202. } else kill ("Expected void function, symbol (): ", offset);
  203. } else kill ("Expected colon, open bracket or equal symbol: ", offset);
  204. }
  205. }
  206. /**/for (i = 0; i < type_code; ++i) printf ("-type- %s = %i;\n", type_name [i], type_size [i]);
  207. /**/for (i = 0; i < variable_code; ++i) printf ("-variable- %s : %s = %i;\n", variable_name [i], type_name [variable_type [i]], variable_data [i]);
  208. /**/for (i = 0; i < constant_code; ++i) printf ("-constant- %s : %s = %i;\n", constant_name [i], type_name [constant_type [i]], constant_data [i]);
  209. /**/for (i = 0; i < function_code; ++i) printf ("-function- %s;\n", function_name [i]);
  210. buffer = deallocate (buffer);
  211. return (log_success);
  212. }