first.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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. bool tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk,
  24. enum err *out_err);
  25. enum c_token_type {
  26. _TT = TK_LAST,
  27. TK_PP_DEF,
  28. TK_PP_INC
  29. };
  30. struct token_pp_inc {
  31. enum c_token_type type;
  32. u64 loc_start;
  33. u64 loc_end;
  34. struct str string;
  35. };
  36. struct token_pp_def {
  37. enum token_type type;
  38. u64 loc_start;
  39. u64 loc_end;
  40. struct str name;
  41. struct str val;
  42. };
  43. bool skip_token(struct tokenizer *tkn, char c);
  44. int
  45. main(int argc, char *argv[])
  46. {
  47. enum err err = ERR_OK;
  48. struct path src_path = {0};
  49. struct file f = {0};
  50. struct str code = {0};
  51. struct tokenizer tkn = {0};
  52. struct tokenizer_options tkn_opts = {0};
  53. struct token tk = {0};
  54. struct dyn_arr tk_da = {0};
  55. tk_da = dyn_arr_create(sizeof(struct token), &err);
  56. src_path = path_from_cstr_ns("./first.c", &err);
  57. f = path_file_read_all(&src_path, &err);
  58. code = str_from_cstr((char*)f.data, f.size, &err);
  59. tkn_opts.skip_token = skip_token;
  60. tkn = tokenizer_create(code, src_path, &tkn_opts, &err);
  61. tkn.edata = &tk_da;
  62. tk = tokenizer_next_token(&tkn, &err);
  63. do {
  64. if ( err != ERR_OK ) {
  65. fprintf(stderr, "ERROR: Failed tokenizing `%.*s`: %s\n",
  66. (int) src_path.size, src_path.data, err_to_name[err]);
  67. goto error_exit;
  68. }
  69. switch ( tk.type ) {
  70. case TK_POUND: {
  71. struct token pp_tk = {0};
  72. if ( ! tkn_parse_pp_directive(&tkn, &pp_tk, &err) ) goto error_exit;
  73. } break;
  74. case TK_ID: if ( ! tkn_parse_decl(&tkn, NULL, &err) ) goto error_exit;
  75. case TK_NL: break;
  76. default: fprintf(stderr, "%s ERROR: Invalid Token `%s`\n",
  77. tokenizer_token_loc_temp(&tkn, &tk, TLF_VIM, NULL),
  78. token_to_cstr(tk.type));
  79. goto error_exit;
  80. }
  81. tk = tokenizer_next_token(&tkn, &err);
  82. } while ( tk.type != TK_EOF );
  83. printf("%s\n", err_to_name[err]);
  84. error_exit:
  85. if ( f.data != NULL ) free(f.data);
  86. if ( tk_da.data != NULL ) dyn_arr_destroy(&tk_da, NULL);
  87. (void) argc; (void) argv;
  88. return 0;
  89. }
  90. bool
  91. skip_token(struct tokenizer *tkn, char c)
  92. {
  93. UNUSED(tkn);
  94. return (c == ' ') || (c == '\r') || (c == '\t');
  95. }
  96. bool
  97. tkn_expect(struct tokenizer *tkn, enum token_type type, struct token *out_tk,
  98. enum err *out_err)
  99. {
  100. enum err err = ERR_OK;
  101. enum err *perr = &err;
  102. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  103. if ( tokenizer_is_next(tkn, type, out_tk, perr) == false ) {
  104. struct token tk = {0};
  105. tk = tokenizer_next_token(tkn, perr);
  106. if ( err != ERR_OK ) {
  107. fprintf(stderr, "Failed to get next token: %s\n",
  108. err_to_name[err]);
  109. return false;
  110. }
  111. fprintf(stderr, "%s ERRRO: Got wrong token, expected: %s, got: %s\n",
  112. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  113. token_to_cstr(type), token_to_cstr(tk.type));
  114. return false;
  115. }
  116. return true;
  117. }
  118. bool
  119. tkn_expect_id(struct tokenizer *tkn, const char *cstr, struct token *out_tk,
  120. enum err *out_err)
  121. {
  122. enum err err = ERR_OK;
  123. struct str str = {0};
  124. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  125. LIB_ARG_MUST_NOT_BE_NULL(cstr, out_err, false);
  126. str = str_from_cstr_ns(cstr, &err);
  127. if ( tokenizer_is_next_id(tkn, str, out_tk, &err) == false ) {
  128. struct token tk = {0};
  129. struct token_wstr *tk_ws = NULL;
  130. tk = tokenizer_next_token(tkn, &err);
  131. if ( err != ERR_OK ) {
  132. fprintf(stderr, "Failed to get next token: %s\n",
  133. err_to_name[err]);
  134. return false;
  135. }
  136. if ( tk.type != TK_ID ) {
  137. fprintf(stderr,
  138. "%s ERROR: Got wrong token, expected: TK_ID, got: %s\n",
  139. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  140. token_to_cstr(tk.type));
  141. return false;
  142. }
  143. tk_ws = (struct token_wstr *)&tk;
  144. fprintf(stderr, "%s ERROR: Got wrong id, expected: %s, got: %.*s\n",
  145. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  146. cstr, (int) tk_ws->string.size, tk_ws->string.data);
  147. return false;
  148. }
  149. return true;
  150. }
  151. bool
  152. tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
  153. enum err *out_err)
  154. {
  155. static char buf[1024] = {0};
  156. static char buf2[1024] = {0};
  157. struct token tk = {0};
  158. struct token_wstr *tk_ws = NULL;
  159. enum err err = ERR_OK;
  160. enum err *perr = &err;
  161. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  162. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  163. if ( out_err != NULL ) {
  164. perr = out_err;
  165. }
  166. tk = tokenizer_next_token(tkn, perr);
  167. if ( *perr != ERR_OK ) {
  168. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  169. return false;
  170. }
  171. if ( tk.type != TK_ID ) {
  172. fprintf(stderr, "%s Got wrong token, expected: TK_ID, got: %s\n",
  173. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  174. token_to_cstr(tk.type));
  175. return false;
  176. }
  177. tk_ws = (struct token_wstr *) &tk;
  178. if ( str_eq_cstr(tk_ws->string, "define", 6) == true ) {
  179. struct token_pp_def tk_def = {0};
  180. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
  181. tk_ws = (struct token_wstr *) &tk;
  182. tk_def.loc_start = tk_ws->loc_start;
  183. memcpy(buf, tk_ws->string.data, tk_ws->string.size);
  184. tk_def.name.data = buf;
  185. tk_def.name.size = tk_ws->string.size;
  186. tk = tokenizer_next_token(tkn, &err);
  187. if ( err != ERR_OK ) {
  188. fprintf(stderr, "Failed to get next token: %s\n",
  189. err_to_name[err]);
  190. return false;
  191. }
  192. switch ( tk.type ) {
  193. case TK_ID:
  194. case TK_STR_LIT:
  195. case TK_NUM_LIT:
  196. tk_ws = (struct token_wstr *) &tk;
  197. break;
  198. case TK_NL: goto define_wout_value;
  199. default:
  200. fprintf(stderr,
  201. "%s Got wrong token, expected:"
  202. " TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
  203. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  204. token_to_cstr(tk.type));
  205. return false;
  206. }
  207. memcpy(buf2, tk_ws->string.data, tk_ws->string.size);
  208. tk_def.val.data = buf2;
  209. tk_def.val.size = tk_ws->string.size;
  210. tk_def.loc_end = tk_ws->loc_end;
  211. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) return false;
  212. define_wout_value:
  213. LIB_SET_IF_NOT_NULL(out_tk, *(struct token *) &tk_def);
  214. return true;
  215. }
  216. if ( str_eq_cstr(tk_ws->string, "include", 7) == true ) {
  217. struct token_pp_inc tk_inc = {0};
  218. tk_inc.type = TK_PP_INC;
  219. tk = tokenizer_next_token(tkn, &err);
  220. if ( err != ERR_OK ) {
  221. fprintf(stderr, "Failed to get next token: %s\n",
  222. err_to_name[err]);
  223. return false;
  224. }
  225. if ( tk.type == TK_STR_LIT ) {
  226. tk_ws = (struct token_wstr *) &tk;
  227. tk_inc.loc_start = tk_ws->loc_start;
  228. tk_inc.loc_end = tk_ws->loc_end;
  229. memcpy(buf, tk_ws->string.data, tk_ws->string.size);
  230. tk_inc.string.data = buf;
  231. tk_inc.string.size = tk_ws->string.size;
  232. goto include_str_lit;
  233. } else if ( tk.type != TK_L_ANG_BRACKET) {
  234. fprintf(stderr,
  235. "%s Got wrong token, expected:"
  236. " TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
  237. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  238. token_to_cstr(tk.type));
  239. return false;
  240. }
  241. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
  242. tk_ws = (struct token_wstr *) &tk;
  243. tk_inc.loc_start = tk_ws->loc_start;
  244. tk_inc.loc_end = tk_ws->loc_end;
  245. memcpy(buf, tk_ws->string.data, tk_ws->string.size);
  246. tk_inc.string.data = buf;
  247. tk_inc.string.size = tk_ws->string.size;
  248. if ( ! tkn_expect(tkn, TK_DOT, NULL, perr) ) return false;
  249. if ( ! tkn_expect_id(tkn, "h", NULL, perr) ) return false;
  250. if ( ! tkn_expect(tkn, TK_R_ANG_BRACKET, NULL, perr) ) return false;
  251. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) return false;
  252. include_str_lit:
  253. LIB_SET_IF_NOT_NULL(out_tk, *(struct token *) &tk_inc);
  254. return true;
  255. }
  256. if ( str_eq_cstr(tk_ws->string, "if", 2) == true ) {
  257. return true;
  258. }
  259. if ( str_eq_cstr(tk_ws->string, "ifdef", 2) == true ) {
  260. return true;
  261. }
  262. if ( str_eq_cstr(tk_ws->string, "ifndef", 2) == true ) {
  263. return true;
  264. }
  265. *perr = -1;
  266. fprintf(stderr, "%s ERROR: Invalid Pre-Compiler directive `%.*s`\n",
  267. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  268. (int) tk_ws->string.size, tk_ws->string.data);
  269. return false;
  270. }
  271. bool
  272. tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
  273. {
  274. /* static char buf[1024] = {0}; */
  275. /* static char buf2[1024] = {0}; */
  276. struct token tk = {0};
  277. struct token_wstr *tk_ws = NULL;
  278. struct token_wstr tk_type = {0};
  279. enum err err = ERR_OK;
  280. enum err *perr = &err;
  281. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  282. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  283. if ( out_err != NULL ) {
  284. perr = out_err;
  285. }
  286. tk_type = *(struct token_wstr *) &tkn->last;
  287. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
  288. switch ( tokenizer_next_token_type(tkn, perr) ) {
  289. case TK_L_BRACES: {
  290. TODO("Implement function declaration");
  291. } break;
  292. case TK_INVALID:
  293. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  294. return false;
  295. default:
  296. fprintf(stderr,
  297. "%s Got wrong token, expected: TK_L_BRACES, got: %s\n",
  298. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  299. token_to_cstr(tk.type));
  300. }
  301. /*
  302. tk = tokenizer_next_token(tkn, perr);
  303. if ( *perr != ERR_OK ) {
  304. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  305. return false;
  306. }
  307. if ( tk.type != TK_ID ) {
  308. fprintf(stderr, "%s Got wrong token, expected: TK_ID, got: %s\n",
  309. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  310. token_to_cstr(tk.type));
  311. return false;
  312. }
  313. */
  314. UNUSED(tk_type);
  315. UNUSED(out_tk);
  316. *perr = ERR_OK;
  317. tk_ws = (struct token_wstr *) &tkn->last;
  318. fprintf(stderr, "%s ERROR: Invalid declaration id `%.*s`\n",
  319. tokenizer_token_loc_temp(tkn, &tkn->last, TLF_VIM, NULL),
  320. (int) tk_ws->string.size, tk_ws->string.data);
  321. return false;
  322. }
  323. /*
  324. int
  325. main(void)
  326. {
  327. enum err err = ERR_OK;
  328. bool was_rebuild = false;
  329. struct dyn_arr dirs = {0};
  330. size_t i = 0;
  331. was_rebuild = build_go_rebuild_yourself(__FILE__, &err);
  332. if ( was_rebuild == true ) {
  333. return 0;
  334. }
  335. dirs = dir_list_with_ext("./src", ".c", &err);
  336. free(dirs);
  337. return 0;
  338. }
  339. */