first.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #define STR_SIZE_LIMIT 65536
  4. #define IMP
  5. #define WANT_BUILD
  6. #define WANT_CSTR
  7. #define WANT_STR
  8. #define WANT_TOKENIZER
  9. #define WANT_DYN_ARR
  10. #define WANT_PATH
  11. #define WANT_ENV
  12. #include "./src/lib.h"
  13. #include <stdlib.h>
  14. #include <stdio.h>
  15. bool tkn_expect(struct tokenizer *tkn, enum token_type type,
  16. struct token *out_tk, enum err *out_err);
  17. bool tkn_expect_id(struct tokenizer *tkn, const char *cstr,
  18. struct token *out_tk, enum err *out_err);
  19. bool tkn_parse_function(struct tokenizer *tkn);
  20. bool run_function(struct str str);
  21. bool tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
  22. enum err *out_err);
  23. enum c_token_type {
  24. _TT = TK_LAST,
  25. TK_PP_DEF,
  26. TK_PP_INC
  27. };
  28. struct token_pp_inc {
  29. enum c_token_type type;
  30. u64 loc_start;
  31. u64 loc_end;
  32. struct str string;
  33. };
  34. struct token_pp_def {
  35. enum token_type type;
  36. u64 loc_start;
  37. u64 loc_end;
  38. struct str name;
  39. struct str val;
  40. };
  41. bool skip_token(struct tokenizer *tkn, char c);
  42. int
  43. main(int argc, char *argv[])
  44. {
  45. enum err err = ERR_OK;
  46. struct path src_path = {0};
  47. struct file f = {0};
  48. struct str code = {0};
  49. struct tokenizer tkn = {0};
  50. struct tokenizer_options tkn_opts = {0};
  51. struct token tk = {0};
  52. struct dyn_arr tk_da = {0};
  53. tk_da = dyn_arr_create(sizeof(struct token), &err);
  54. src_path = path_from_cstr_ns("./first.c", &err);
  55. f = path_file_read_all(&src_path, &err);
  56. code = str_from_cstr((char*)f.data, f.size, &err);
  57. tkn_opts.skip_token = skip_token;
  58. tkn = tokenizer_create(code, src_path, &tkn_opts, &err);
  59. tkn.edata = &tk_da;
  60. tk = tokenizer_next_token(&tkn, &err);
  61. do {
  62. if ( err != ERR_OK ) {
  63. fprintf(stderr, "ERROR: Failed tokenizing `%.*s`: %s\n",
  64. (int) src_path.size, src_path.data, err_to_name[err]);
  65. goto error_exit;
  66. }
  67. switch ( tk.type ) {
  68. case TK_POUND:
  69. if ( ! tkn_parse_pp_directive(&tkn, NULL, &err) ) goto error_exit;
  70. break;
  71. case TK_NL: break;
  72. default: fprintf(stderr, "%s ERROR: Invalid Token `%s`\n",
  73. tokenizer_token_loc_temp(&tkn, &tk, TLF_VIM, NULL),
  74. token_to_cstr(tk.type));
  75. goto error_exit;
  76. }
  77. tk = tokenizer_next_token(&tkn, &err);
  78. } while ( tk.type != TK_EOF );
  79. /*
  80. if ( ! tkn_expect(&tkn, TK_POUND) ) return 1;
  81. if ( ! tkn_expect_id(&tkn, "run") ) return 1;
  82. if ( ! tkn_expect(&tkn, TK_L_CUR_BRACES) ) return 1;
  83. if ( ! tkn_parse_function(&tkn) ) return 1;
  84. if ( ! tkn_expect(&tkn, TK_R_CUR_BRACES) ) return 1;
  85. if ( ! tkn_expect(&tkn, TK_EOF) ) return 1;
  86. */
  87. printf("%s\n", err_to_name[err]);
  88. error_exit:
  89. if ( f.data != NULL ) free(f.data);
  90. if ( tk_da.data != NULL ) dyn_arr_destroy(&tk_da, NULL);
  91. (void) argc; (void) argv;
  92. return 0;
  93. }
  94. bool
  95. skip_token(struct tokenizer *tkn, char c)
  96. {
  97. UNUSED(tkn);
  98. return (c == ' ') || (c == '\r') || (c == '\t');
  99. }
  100. bool
  101. tkn_expect(struct tokenizer *tkn, enum token_type type, struct token *out_tk,
  102. enum err *out_err)
  103. {
  104. enum err err = ERR_OK;
  105. enum err *perr = &err;
  106. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  107. if ( tokenizer_is_next(tkn, type, out_tk, perr) == false ) {
  108. struct token tk = {0};
  109. tk = tokenizer_next_token(tkn, perr);
  110. if ( err != ERR_OK ) {
  111. fprintf(stderr, "Failed to get next token: %s\n",
  112. err_to_name[err]);
  113. return false;
  114. }
  115. fprintf(stderr, "%s ERRRO: Got wrong token, expected: %s, got: %s\n",
  116. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  117. token_to_cstr(type), token_to_cstr(tk.type));
  118. return false;
  119. }
  120. return true;
  121. }
  122. bool
  123. tkn_expect_id(struct tokenizer *tkn, const char *cstr, struct token *out_tk,
  124. enum err *out_err)
  125. {
  126. enum err err = ERR_OK;
  127. struct str str = {0};
  128. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  129. LIB_ARG_MUST_NOT_BE_NULL(cstr, out_err, false);
  130. str = str_from_cstr_ns(cstr, &err);
  131. if ( tokenizer_is_next_id(tkn, str, out_tk, &err) == false ) {
  132. struct token tk = {0};
  133. struct token_wstr *tk_ws = NULL;
  134. tk = tokenizer_next_token(tkn, &err);
  135. if ( err != ERR_OK ) {
  136. fprintf(stderr, "Failed to get next token: %s\n",
  137. err_to_name[err]);
  138. return false;
  139. }
  140. if ( tk.type != TK_ID ) {
  141. fprintf(stderr,
  142. "%s ERROR: Got wrong token, expected: TK_ID, got: %s\n",
  143. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  144. token_to_cstr(tk.type));
  145. return false;
  146. }
  147. tk_ws = (struct token_wstr *)&tk;
  148. fprintf(stderr, "%s ERROR: Got wrong id, expected: %s, got: %.*s\n",
  149. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  150. cstr, (int) tk_ws->string.size, tk_ws->string.data);
  151. return false;
  152. }
  153. return true;
  154. }
  155. bool
  156. tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
  157. enum err *out_err)
  158. {
  159. static char buf[1024] = {0};
  160. static char buf2[1024] = {0};
  161. struct token tk = {0};
  162. struct token_wstr *tk_ws = NULL;
  163. enum err err = ERR_OK;
  164. enum err *perr = &err;
  165. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  166. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  167. if ( out_err != NULL ) {
  168. perr = out_err;
  169. }
  170. tk = tokenizer_next_token(tkn, perr);
  171. if ( *perr != ERR_OK ) {
  172. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  173. return false;
  174. }
  175. if ( tk.type != TK_ID ) {
  176. fprintf(stderr, "%s Got wrong token, expected: TK_ID, got: %s\n",
  177. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  178. token_to_cstr(tk.type));
  179. return false;
  180. }
  181. tk_ws = (struct token_wstr *) &tk;
  182. if ( str_eq_cstr(tk_ws->string, "define", 6) == true ) {
  183. struct token_pp_def tk_def = {0};
  184. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
  185. tk_ws = (struct token_wstr *) &tk;
  186. tk_def.loc_start = tk_ws->loc_start;
  187. memcpy(buf, tk_ws->string.data, tk_ws->string.size);
  188. tk_def.name.data = buf;
  189. tk_def.name.size = tk_ws->string.size;
  190. tk = tokenizer_next_token(tkn, &err);
  191. if ( err != ERR_OK ) {
  192. fprintf(stderr, "Failed to get next token: %s\n",
  193. err_to_name[err]);
  194. return false;
  195. }
  196. switch ( tk.type ) {
  197. case TK_ID:
  198. case TK_STR_LIT:
  199. case TK_NUM_LIT:
  200. tk_ws = (struct token_wstr *) &tk;
  201. break;
  202. default:
  203. fprintf(stderr,
  204. "%s Got wrong token, expected:"
  205. " TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
  206. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  207. token_to_cstr(tk.type));
  208. return false;
  209. }
  210. memcpy(buf2, tk_ws->string.data, tk_ws->string.size);
  211. tk_def.val.data = buf2;
  212. tk_def.val.size = tk_ws->string.size;
  213. tk_def.loc_end = tk_ws->loc_end;
  214. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) return false;
  215. LIB_SET_IF_NOT_NULL(out_tk, *(struct token *) &tk_def);
  216. return true;
  217. }
  218. if ( str_eq_cstr(tk_ws->string, "include", 7) == true ) {
  219. struct token_pp_inc tk_inc = {0};
  220. tk_inc.type = TK_PP_INC;
  221. if ( ! tkn_expect(tkn, TK_L_ANG_BRACKET, NULL, perr) ) return false;
  222. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
  223. tk_ws = (struct token_wstr *) &tk;
  224. tk_inc.loc_start = tk_ws->loc_start;
  225. tk_inc.loc_end = tk_ws->loc_end;
  226. tk_inc.string.data = buf;
  227. tk_inc.string.size = tk_ws->string.size;
  228. memcpy(buf, tk_ws->string.data, tk_ws->string.size);
  229. if ( ! tkn_expect(tkn, TK_DOT, NULL, perr) ) return false;
  230. if ( ! tkn_expect_id(tkn, "h", NULL, perr) ) return false;
  231. if ( ! tkn_expect(tkn, TK_R_ANG_BRACKET, NULL, perr) ) return false;
  232. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) return false;
  233. LIB_SET_IF_NOT_NULL(out_tk, *(struct token *) &tk_inc);
  234. return true;
  235. }
  236. if ( str_eq_cstr(tk_ws->string, "if", 2) == true ) {
  237. return true;
  238. }
  239. if ( str_eq_cstr(tk_ws->string, "ifdef", 2) == true ) {
  240. return true;
  241. }
  242. if ( str_eq_cstr(tk_ws->string, "ifndef", 2) == true ) {
  243. return true;
  244. }
  245. /* Format src.c:line:col: msg */
  246. fprintf(stderr, "%s ERROR: Invalid Pre-Compiler directive `%.*s`\n",
  247. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  248. (int) tk_ws->string.size, tk_ws->string.data);
  249. return false;
  250. }
  251. /*
  252. int
  253. main(void)
  254. {
  255. enum err err = ERR_OK;
  256. bool was_rebuild = false;
  257. struct dyn_arr dirs = {0};
  258. size_t i = 0;
  259. was_rebuild = build_go_rebuild_yourself(__FILE__, &err);
  260. if ( was_rebuild == true ) {
  261. return 0;
  262. }
  263. dirs = dir_list_with_ext("./src", ".c", &err);
  264. free(dirs);
  265. return 0;
  266. }
  267. */