first.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <stdarg.h>
  4. #include <sys/wait.h>
  5. #include <sys/stat.h>
  6. /* #define STR_SIZE_LIMIT 65536 */
  7. #define STR_SIZE_LIMIT 5458264
  8. #define IMP
  9. #define WANT_BUILD
  10. #define WANT_CSTR
  11. #define WANT_STR
  12. #define WANT_MAP
  13. #define WANT_TOKENIZER
  14. #define WANT_DYN_ARR
  15. #define WANT_PATH
  16. #define WANT_ENV
  17. #define WANT_SLOP
  18. #define WANT_CMD
  19. #include "./src/lib.h"
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. /*
  23. # define DIE(f, e) \
  24. (f); \
  25. if ( (e) != ERR_OK ) {\
  26. fprintf(stderr, \
  27. "Error while running `" #f "`: %s\n", \
  28. err_to_name[(e)]); \
  29. goto exit_err; \
  30. }
  31. # define PPP(f) \
  32. printf("PRE: `" #f "`\n"); \
  33. f; \
  34. printf("POST: `" #f "`\n");
  35. */
  36. int
  37. main(int argc, char *argv[])
  38. {
  39. enum err err = ERR_OK;
  40. struct cmd cmd = {0};
  41. /*
  42. struct procs procs = {0};
  43. */
  44. GO_REBUILD_YOURSELF();
  45. cmd = cmd_create_ns("ls", &err);
  46. cmd_append_args_cstrs(&cmd, &err, "-lh", "first.c", "first");
  47. cmd_exec(&cmd, &err);
  48. cmd_destroy(&cmd, &err);
  49. /*
  50. bool was_rebuild = false;
  51. struct dyn_arr dirs = {0};
  52. size_t i = 0;
  53. was_rebuild = build_go_rebuild_yourself(__FILE__, &err);
  54. if ( was_rebuild == true ) {
  55. return 0;
  56. }
  57. dirs = dir_list_with_ext("./src", ".c", &err);
  58. free(dirs);
  59. */
  60. UNUSED(argc);
  61. UNUSED(argv);
  62. return 0;
  63. }
  64. bool skip_token(struct tokenizer *tkn, char c);
  65. enum c_token_type {
  66. _TT = TK_LAST,
  67. TK_PP_DEF,
  68. TK_PP_INC
  69. };
  70. struct pp_def {
  71. struct str name;
  72. struct str val;
  73. };
  74. # define PP_DEF_DESTROY(Var) \
  75. if ( (Var) != NULL ) { \
  76. STR_DESTROY((Var)->name); \
  77. STR_DESTROY((Var)->val); \
  78. LIB_FREE((Var)); \
  79. }
  80. struct var_decl {
  81. bool is_ptr;
  82. struct str type;
  83. struct str name;
  84. };
  85. # define VAR_DECL_DESTROY(Var) \
  86. if ( (Var) != NULL ) { \
  87. STR_DESTROY((Var)->type); \
  88. STR_DESTROY((Var)->name); \
  89. }
  90. struct func_decl {
  91. struct str ret_type;
  92. struct str name;
  93. struct {
  94. struct var_decl *data;
  95. u64 size;
  96. u64 cap;
  97. } args;
  98. };
  99. void func_decl_destroy(struct func_decl *fd);
  100. void
  101. func_decl_destroy(struct func_decl *fd)
  102. {
  103. u64 i = 0;
  104. if ( fd == NULL ) return;
  105. STR_DESTROY(fd->ret_type);
  106. STR_DESTROY(fd->name);
  107. for ( i = 0; i < fd->args.size; ++i ) {
  108. STR_DESTROY(fd->args.data[i].type);
  109. STR_DESTROY(fd->args.data[i].name);
  110. }
  111. LIB_FREE(fd->args.data);
  112. LIB_FREE(fd);
  113. }
  114. bool tkn_expect(struct tokenizer *tkn, enum token_type type,
  115. struct token *out_tk, enum err *out_err);
  116. bool tkn_expect_id(struct tokenizer *tkn, const char *cstr,
  117. struct token *out_tk, enum err *out_err);
  118. bool tkn_parse_function(struct tokenizer *tkn);
  119. bool run_function(struct str str);
  120. bool tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
  121. enum err *out_err);
  122. bool tkn_parse_var(struct tokenizer *tkn, struct token *out_tk,
  123. enum err *out_err);
  124. bool tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk,
  125. enum err *out_err);
  126. bool is_space(char c);
  127. bool
  128. is_space(char c)
  129. {
  130. return (c == ' ') || (c == '\r') || (c == '\n')
  131. || (c == '\t') || (c == '\v');
  132. }
  133. int main2(int argc, char *argv[]);
  134. int
  135. main2(int argc, char *argv[])
  136. {
  137. enum err err = ERR_OK;
  138. struct path src_path = {0};
  139. struct file f = {0};
  140. struct str code = {0};
  141. struct tokenizer tkn = {0};
  142. struct tokenizer_options tkn_opts = {0};
  143. struct token tk = {0};
  144. struct dyn_arr tk_da = {0};
  145. tk_da = dyn_arr_create(sizeof(struct token), &err);
  146. src_path = path_from_cstr_ns("./first.c", &err);
  147. f = path_file_read_all(&src_path, &err);
  148. code = str_from_cstr((char*)f.data, f.size, &err);
  149. tkn_opts.skip_token = skip_token;
  150. tkn = tokenizer_create(code, src_path, &tkn_opts, &err);
  151. tk = tokenizer_next_token(&tkn, &err);
  152. do {
  153. if ( err != ERR_OK ) {
  154. fprintf(stderr, "ERROR: Failed tokenizing `%.*s`: %s\n",
  155. (int) src_path.size, src_path.data, err_to_name[err]);
  156. goto error_exit;
  157. }
  158. switch ( tk.type ) {
  159. case TK_POUND: {
  160. if ( ! tkn_parse_pp_directive(&tkn, NULL, &err) ) goto error_exit;
  161. } break;
  162. case TK_ID: if ( ! tkn_parse_decl(&tkn, NULL, &err) ) goto error_exit;
  163. case TK_NL: break;
  164. case TK_SLASH: {
  165. if ( ! tkn_expect(&tkn, TK_ASTERISK, NULL, &err) ) goto error_exit;
  166. while ( tk.type != TK_ASTERISK )
  167. tk = tokenizer_next_token(&tkn, &err);
  168. if ( ! tkn_expect(&tkn, TK_SLASH, NULL, &err) ) goto error_exit;
  169. } break;
  170. default: fprintf(stderr, "%s ERROR: Invalid Token `%s`\n",
  171. tokenizer_token_loc_temp(&tkn, &tk, TLF_VIM, NULL),
  172. token_to_cstr(tk.type));
  173. goto error_exit;
  174. }
  175. tk = tokenizer_next_token(&tkn, &err);
  176. } while ( tk.type != TK_EOF );
  177. printf("%s\n", err_to_name[err]);
  178. error_exit:
  179. if ( f.data != NULL ) free(f.data);
  180. if ( tk_da.data != NULL ) dyn_arr_destroy(&tk_da, NULL);
  181. (void) argc; (void) argv;
  182. return 0;
  183. }
  184. bool
  185. skip_token(struct tokenizer *tkn, char c)
  186. {
  187. UNUSED(tkn);
  188. return (c == ' ') || (c == '\r') || (c == '\t');
  189. }
  190. bool
  191. tkn_expect(struct tokenizer *tkn, enum token_type type, struct token *out_tk,
  192. enum err *out_err)
  193. {
  194. enum err err = ERR_OK;
  195. enum err *perr = &err;
  196. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  197. if ( tokenizer_is_next(tkn, type, out_tk, perr) == false ) {
  198. struct token tk = {0};
  199. tk = tokenizer_next_token(tkn, perr);
  200. if ( err != ERR_OK ) {
  201. fprintf(stderr, "Failed to get next token: %s\n",
  202. err_to_name[err]);
  203. return false;
  204. }
  205. fprintf(stderr, "%s ERRRO: Got wrong token, expected: %s, got: %s\n",
  206. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  207. token_to_cstr(type), token_to_cstr(tk.type));
  208. return false;
  209. }
  210. return true;
  211. }
  212. bool
  213. tkn_expect_id(struct tokenizer *tkn, const char *cstr, struct token *out_tk,
  214. enum err *out_err)
  215. {
  216. enum err err = ERR_OK;
  217. struct str str = {0};
  218. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  219. LIB_ARG_MUST_NOT_BE_NULL(cstr, out_err, false);
  220. str = str_from_cstr_ns(cstr, &err);
  221. if ( tokenizer_is_next_id(tkn, str, out_tk, &err) == false ) {
  222. struct token tk = {0};
  223. tk = tokenizer_next_token(tkn, &err);
  224. if ( err != ERR_OK ) {
  225. fprintf(stderr, "Failed to get next token: %s\n",
  226. err_to_name[err]);
  227. return false;
  228. }
  229. if ( tk.type != TK_ID ) {
  230. fprintf(stderr,
  231. "%s ERROR: Got wrong token, expected: TK_ID, got: %s\n",
  232. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  233. token_to_cstr(tk.type));
  234. return false;
  235. }
  236. fprintf(stderr, "%s ERROR: Got wrong id, expected: %s, got: %.*s\n",
  237. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  238. cstr, (int) tk.string.size, tk.string.data);
  239. return false;
  240. }
  241. return true;
  242. }
  243. bool
  244. tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
  245. enum err *out_err)
  246. {
  247. struct token tk = {0};
  248. enum err err = ERR_OK;
  249. enum err *perr = &err;
  250. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  251. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  252. if ( out_err != NULL ) {
  253. perr = out_err;
  254. }
  255. tk = tokenizer_next_token(tkn, perr);
  256. if ( *perr != ERR_OK ) {
  257. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  258. return false;
  259. }
  260. if ( tk.type != TK_ID ) {
  261. fprintf(stderr, "%s Got wrong token, expected: TK_ID, got: %s\n",
  262. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  263. token_to_cstr(tk.type));
  264. return false;
  265. }
  266. if ( str_eq_cstr(tk.string, "define", 6) == true ) {
  267. struct token tk_def = {0};
  268. struct pp_def *def = NULL;
  269. def = malloc(sizeof(struct pp_def));
  270. if ( def == NULL ) {
  271. *perr = ERR_FAILED_ALLOC;
  272. goto def_exit_err;
  273. }
  274. memset(def, 0, sizeof(struct pp_def));
  275. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto def_exit_err;
  276. tk_def.loc_start = tk.loc_start;
  277. def->name = str_dup(tk.string);
  278. tk = tokenizer_next_token(tkn, &err);
  279. if ( err != ERR_OK ) {
  280. fprintf(stderr, "Failed to get next token: %s\n",
  281. err_to_name[err]);
  282. goto def_exit_err;
  283. }
  284. switch ( tk.type ) {
  285. case TK_ID:
  286. case TK_STR_LIT:
  287. case TK_NUM_LIT:
  288. break;
  289. case TK_NL: goto def_wout_value;
  290. default:
  291. fprintf(stderr,
  292. "%s Got wrong token, expected:"
  293. " TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
  294. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  295. token_to_cstr(tk.type));
  296. goto def_exit_err;
  297. }
  298. def->val = str_dup(tk.string);
  299. tk_def.loc_end = tk.loc_end;
  300. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) goto def_exit_err;
  301. def_wout_value:
  302. tk_def.extra = def;
  303. if ( out_tk != NULL ) {
  304. *out_tk = tk_def;
  305. } else {
  306. PP_DEF_DESTROY(def);
  307. }
  308. return true;
  309. def_exit_err:
  310. PP_DEF_DESTROY(def);
  311. return false;
  312. }
  313. if ( str_eq_cstr(tk.string, "include", 7) == true ) {
  314. struct token tk_inc = {0};
  315. tk_inc.type = (enum token_type) TK_PP_INC;
  316. tk = tokenizer_next_token(tkn, &err);
  317. if ( err != ERR_OK ) {
  318. fprintf(stderr, "Failed to get next token: %s\n",
  319. err_to_name[err]);
  320. return false;
  321. }
  322. if ( tk.type == TK_STR_LIT ) {
  323. tk_inc.loc_start = tk.loc_start;
  324. tk_inc.loc_end = tk.loc_end;
  325. tk_inc.string = str_dup(tk.string);
  326. goto inc_str_lit;
  327. } else if ( tk.type != TK_L_ANG_BRACKET) {
  328. fprintf(stderr,
  329. "%s Got wrong token, expected:"
  330. " TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
  331. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  332. token_to_cstr(tk.type));
  333. goto inc_exit_err;
  334. }
  335. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto inc_exit_err;
  336. tk_inc.loc_start = tk.loc_start;
  337. tk_inc.loc_end = tk.loc_end;
  338. tk_inc.string = str_dup(tk.string);
  339. if ( ! tkn_expect(tkn, TK_DOT, NULL, perr) ) goto inc_exit_err;
  340. if ( ! tkn_expect_id(tkn, "h", NULL, perr) ) goto inc_exit_err;
  341. if ( ! tkn_expect(tkn, TK_R_ANG_BRACKET, NULL, perr) )
  342. goto inc_exit_err;
  343. if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) goto inc_exit_err;
  344. inc_str_lit:
  345. if ( out_tk != NULL ) {
  346. *out_tk = tk_inc;
  347. } else {
  348. STR_DESTROY(tk_inc.string);
  349. }
  350. return true;
  351. inc_exit_err:
  352. STR_DESTROY(tk_inc.string);
  353. return false;
  354. }
  355. if ( str_eq_cstr(tk.string, "if", 2) == true ) {
  356. return true;
  357. }
  358. if ( str_eq_cstr(tk.string, "ifdef", 2) == true ) {
  359. return true;
  360. }
  361. if ( str_eq_cstr(tk.string, "ifndef", 2) == true ) {
  362. return true;
  363. }
  364. *perr = -1;
  365. fprintf(stderr, "%s ERROR: Invalid Pre-Compiler directive `%.*s`\n",
  366. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  367. (int) tk.string.size, tk.string.data);
  368. return false;
  369. }
  370. bool
  371. tkn_parse_var(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
  372. {
  373. enum err err = ERR_OK;
  374. enum err *perr = &err;
  375. struct token tk = {0};
  376. struct var_decl *vd = NULL;
  377. struct {
  378. char *data;
  379. u64 size;
  380. u64 cap;
  381. } type = {0};
  382. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  383. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  384. if ( out_err != NULL ) {
  385. perr = out_err;
  386. }
  387. vd = malloc(sizeof(*vd));
  388. if ( vd == NULL ) {
  389. *perr = ERR_FAILED_ALLOC;
  390. goto exit_err;
  391. }
  392. memset(vd, 0, sizeof(*vd));
  393. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto exit_err;
  394. DA_APPEND_DATA(type, tk.string.data, tk.string.size, perr);
  395. DA_APPEND(type, ' ', perr);
  396. while ( true ) {
  397. /* bool is_name = false;*/
  398. /*enum token_type ntt = tokenizer_peek_token_type(tkn, NULL);*/
  399. /*is_name = ( ntt == TK_COMMA ) || ( ntt == TK_SEMICOLON )
  400. || ( ntt == TK_ASTERISK ) || ( ntt == TK_EQUAL );*/
  401. tk = tokenizer_next_token(tkn, NULL);
  402. switch ( tk.type ) {
  403. case TK_ID: break;
  404. case TK_ASTERISK: break;
  405. case TK_COMMA: break;
  406. case TK_SEMICOLON: break;
  407. default:
  408. fprintf(stderr,
  409. "%s Got wrong token, expected:"
  410. " TK_ID/TK_ASTERISK/TK_COMMA/TK_SEMICOLON, got: %s\n",
  411. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  412. token_to_cstr(tk.type));
  413. goto exit_err;
  414. }
  415. }
  416. TODO("Rest of var decl!");
  417. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto exit_err;
  418. vd->name = str_dup(tk.string);
  419. if ( ! tkn_expect(tkn, TK_COMMA, NULL, perr) ) goto exit_err;
  420. if ( out_tk != NULL ) {
  421. *out_tk = tk;
  422. }
  423. exit_err:
  424. LIB_FREE(vd);
  425. LIB_FREE(type.data);
  426. if ( *perr == ERR_OK ) *perr = ERR_GENERAL_ERROR;
  427. return false;
  428. }
  429. bool
  430. tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
  431. {
  432. struct token tk = {0};
  433. struct token tk_type = {0};
  434. enum err err = ERR_OK;
  435. enum err *perr = &err;
  436. LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
  437. LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
  438. if ( out_err != NULL ) {
  439. perr = out_err;
  440. }
  441. tk_type = tkn->last;
  442. if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
  443. switch ( tokenizer_next_token_type(tkn, perr) ) {
  444. case TK_L_BRACES: {
  445. struct token tk_fd = {0};
  446. struct func_decl *fd = NULL;
  447. fd = malloc(sizeof(struct func_decl));
  448. if ( fd == NULL ) {
  449. *out_err = ERR_FAILED_ALLOC;
  450. goto func_decl_exit_err;
  451. }
  452. memset(fd, 0, sizeof(*fd));
  453. fd->args.cap = 32;
  454. fd->args.data = malloc(sizeof(*fd->args.data) * fd->args.cap);
  455. if ( fd->args.data == NULL ) {
  456. *out_err = ERR_FAILED_ALLOC;
  457. goto func_decl_exit_err;
  458. }
  459. memset(fd->args.data, 0, sizeof(*fd->args.data) * fd->args.cap);
  460. tk_fd.loc_start = tk_type.loc_start;
  461. fd->ret_type = str_dup(tk_type.string);
  462. fd->name = str_dup(tk.string);
  463. while ( true ) {
  464. struct token tk_vd = {0};
  465. struct var_decl *vd = NULL;
  466. tkn_parse_var(tkn, &tk_vd, perr);
  467. if ( *perr != ERR_OK ) goto func_decl_exit_err;
  468. vd = tk_vd.extra;
  469. DA_APPEND(fd->args, *vd, perr);
  470. };
  471. if ( out_tk != NULL ) {
  472. *out_tk = tk_fd;
  473. } else {
  474. func_decl_destroy(fd);
  475. }
  476. return true;
  477. func_decl_exit_err:
  478. func_decl_destroy(fd);
  479. return false;
  480. /*
  481. struct func_decl {
  482. struct str ret_type;
  483. struct str name;
  484. struct {
  485. struct str *data;
  486. u64 size;
  487. u64 cap;
  488. } args;
  489. };
  490. */
  491. } break;
  492. case TK_INVALID:
  493. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  494. return false;
  495. default:
  496. fprintf(stderr,
  497. "%s Got wrong token, expected: TK_L_BRACES, got: %s\n",
  498. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  499. token_to_cstr(tk.type));
  500. }
  501. /*
  502. tk = tokenizer_next_token(tkn, perr);
  503. if ( *perr != ERR_OK ) {
  504. fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
  505. return false;
  506. }
  507. if ( tk.type != TK_ID ) {
  508. fprintf(stderr, "%s Got wrong token, expected: TK_ID, got: %s\n",
  509. tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
  510. token_to_cstr(tk.type));
  511. return false;
  512. }
  513. */
  514. UNUSED(tk_type);
  515. UNUSED(out_tk);
  516. *perr = ERR_OK;
  517. fprintf(stderr, "%s ERROR: Invalid declaration id `%.*s`\n",
  518. tokenizer_token_loc_temp(tkn, &tkn->last, TLF_VIM, NULL),
  519. (int) tk.string.size, tk.string.data);
  520. return false;
  521. }
  522. /*
  523. int
  524. main(void)
  525. {
  526. }
  527. */