Minimal programming language prototype, created with goal to have very small compiler, so that anyone can write his own compiler for it.
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.

213 lines
7.6KB

  1. #include <xolatile/xtandard.c>
  2. enum {
  3. coin_none,
  4. coin_type, coin_loop, coin_if, coin_else, coin_case, coin_return, coin_import, coin_system,
  5. coin_function, coin_variable, coin_constant, coin_data_type, coin_string, coin_number, coin_marker, coin_label,
  6. coin_add, coin_subtract, coin_multiply, coin_divide, coin_modulus, coin_equal, coin_above, coin_below,
  7. coin_open, coin_close, coin_next, coin_stop, coin_branch, coin_and, coin_or, coin_not,
  8. coin_range, coin_enrange, coin_derange, coin_machine
  9. };
  10. static int coin_code = 0;
  11. static int type_code = 0;
  12. static int function_code = 0;
  13. static int variable_code = 0;
  14. static int constant_code = 0;
  15. static int coin_type [240] = { 0 };
  16. static int coin_data [240] = { 0 };
  17. static char type_name [27] [40] = { "" };
  18. static int type_size [27] = { 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. static char variable_name [27] [40] = { "" };
  24. static int variable_type [27] = { 0 };
  25. static int variable_data [27] = { 0 };
  26. static char constant_name [30] [40] = { "" };
  27. static int constant_type [30] = { 0 };
  28. static int constant_data [30] = { 0 };
  29. #include <stdio.h>
  30. static char * word_list [] = {
  31. "type", "loop", "if", "else", "case", "return", "import", "system"
  32. };
  33. static void add_coin (int type, int data) {
  34. coin_type [coin_code] = type;
  35. coin_data [coin_code] = data;
  36. ++coin_code;
  37. }
  38. static void add_type (char * name, int size) {
  39. string_copy (type_name [type_code], name);
  40. type_size [type_code] = size;
  41. ++type_code;
  42. }
  43. static void add_function (char * name, int type, char * * agrument_name, int * argument_type) {
  44. string_copy (type_name [type_code], name);
  45. type_size [type_code] = size;
  46. ++type_code;
  47. }
  48. static void kill (char * data) {
  49. echo (data);
  50. exit (log_failure);
  51. }
  52. int main (void) {
  53. char * buffer = null;
  54. int offset = 0;
  55. int length = 0;
  56. buffer = file_import ("./test.x");
  57. for (offset = 0; buffer [offset] != '\0'; ++offset) {
  58. if (buffer [offset] == '"') {
  59. int size = 0;
  60. char data [STRING_LIMIT] = "";
  61. for (++offset; (buffer [offset] != '"') && (buffer [offset] != '\0'); ++offset) {
  62. data [size++] = buffer [offset];
  63. }
  64. data [size] = '\0';
  65. add_coin (core_string, string_code);
  66. add_string (data, size);
  67. } else if (character_is_digit (buffer [offset]) == true) {
  68. int data = buffer [offset] - '0';
  69. for (++offset; (character_is_digit (buffer [offset]) == true) && (buffer [offset] != '\0'); ++offset) {
  70. data *= 10;
  71. data += (buffer [offset] - '0');
  72. }
  73. add_coin (core_number, number_code);
  74. add_number (data);
  75. --offset;
  76. } else if (character_is_alpha (buffer [offset]) == true) {
  77. int size = 0;
  78. char name [NAME_LIMIT] = "";
  79. for (; ((character_is_alpha (buffer [offset]) == true) ||
  80. (character_is_digit (buffer [offset]) == true) ||
  81. (character_is_underscore (buffer [offset]) == true)) && (buffer [offset] != '\0'); ++offset) {
  82. name [size++] = buffer [offset];
  83. }
  84. name [size] = '\0';
  85. for (length = 0; length < (int) (sizeof (word_list) / sizeof (word_list [0])); ++length) {
  86. if (string_compare_limit (name, word_list [length], string_length (word_list [length]) + 1) == true) {
  87. add_coin (core_word, length);
  88. goto here;
  89. }
  90. }
  91. add_coin (core_marker, marker_code);
  92. add_marker (name, token_type [token_count - 1]);
  93. if ((token_type [token_count - 2] == core_word) && (token_data [token_count - 2] == word_type)) {
  94. token_type [token_count - 1] = core_type;
  95. add_type (name);
  96. }
  97. for (length = 0; length < type_code; ++length) {
  98. if (string_compare_limit (name, type_name [length], string_length (type_name [length]) + 1) == true) {
  99. token_type [token_count - 1] = core_type;
  100. }
  101. }
  102. here:
  103. --offset;
  104. } else if (character_compare_array (buffer [offset], ",.;:=<>&|!+-*/%()[]") == true) {
  105. add_coin (core_symbol, symbol_code);
  106. add_symbol (buffer [offset]);
  107. } else {
  108. if (character_is_blank (buffer [offset]) == false) {
  109. echo ("\033[1;31mCharacter set exception point: Segmentation\033[0m\n");
  110. printf ("%c -- %i\n", buffer [offset], (int) buffer [offset]);
  111. exit (log_failure);
  112. }
  113. }
  114. }
  115. end:
  116. for (length = 0; length < token_count; ++length) {
  117. switch (token_type [length]) {
  118. case core_symbol: printf ("\033[1;34m%c\033[0m ", symbol_data [token_data [length]]); break;
  119. case core_string: printf ("\033[1;31m%s\033[0m ", string_data [token_data [length]]); break;
  120. case core_number: printf ("\033[1;32m%i\033[0m ", number_data [token_data [length]]); break;
  121. case core_type: printf ("\033[1;36m%s\033[0m ", marker_name [token_data [length]]); break;
  122. case core_marker: printf ("\033[1;33m%s\033[0m ", marker_name [token_data [length]]); break;
  123. case core_word: printf ("\033[1;35m%s\033[0m ", word_list [token_data [length]]); break;
  124. default: break;
  125. }
  126. }
  127. printf ("\n");
  128. for (length = 0; length < token_count; ++length) {
  129. if ((token_type [length] == core_word) && (token_data [length] == word_return)) {
  130. ++length;
  131. if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == '(')) {
  132. echo ("return (\n");
  133. ++length;
  134. } else if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == ';')) {
  135. echo ("; return;\nxor rax, rax\nret\n");
  136. ++length;
  137. } else if (token_type [length] == core_number && (token_type [length + 1] == core_symbol) && (symbol_data [token_data [length + 1]] == ';')) {
  138. printf ("; return {number};\nmov rax, %i\nret\n", number_data [token_data [length]]);
  139. ++length;
  140. } else {
  141. kill ("return ?\n");
  142. }
  143. } else if ((token_type [length] == core_word) && (token_data [length] == word_if)) {
  144. ++length;
  145. if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == '(')) {
  146. echo ("if (\n");
  147. ++length;
  148. } else {
  149. kill ("if ?\n");
  150. }
  151. } else if ((token_type [length] == core_word) && (token_data [length] == word_else)) {
  152. ++length;
  153. if ((token_type [length] == core_symbol) && (symbol_data [token_data [length]] == ':')) {
  154. echo ("else :\n");
  155. ++length;
  156. } else if ((token_type [length] == core_word) && (token_data [length] == word_if)) {
  157. echo ("else if\n");
  158. ++length;
  159. } else {
  160. echo ("else expression\n");
  161. }
  162. } else if ((token_type [length] == core_word) && (token_data [length] == word_type)) {
  163. ++length;
  164. if (token_type [length] == core_type) {
  165. echo ("type <name> -- ");
  166. echo (marker_name [token_data [length]]);
  167. echo ("\n");
  168. ++length;
  169. } else {
  170. kill ("type ?\n");
  171. }
  172. }
  173. }
  174. for (length = 0; length < string_code; ++length) { string_data [length] = deallocate (string_data [length]); }
  175. for (length = 0; length < marker_code; ++length) { marker_name [length] = deallocate (marker_name [length]); }
  176. for (length = 0; length < type_code; ++length) { type_name [length] = deallocate (type_name [length]); }
  177. string_data = deallocate (string_data);
  178. string_size = deallocate (string_size);
  179. marker_name = deallocate (marker_name);
  180. marker_type = deallocate (marker_type);
  181. type_name = deallocate (type_name);
  182. symbol_data = deallocate (symbol_data);
  183. number_data = deallocate (number_data);
  184. token_data = deallocate (token_data);
  185. token_type = deallocate (token_type);
  186. buffer = deallocate (buffer);
  187. return (log_success);
  188. }