|
|
@@ -1,6 +1,8 @@
|
|
|
#include <stdio.h>
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
+#include <sys/wait.h>
|
|
|
+
|
|
|
/* #define STR_SIZE_LIMIT 65536 */
|
|
|
#define STR_SIZE_LIMIT 5458264
|
|
|
|
|
|
@@ -14,81 +16,13 @@
|
|
|
#define WANT_PATH
|
|
|
#define WANT_ENV
|
|
|
#define WANT_SLOP
|
|
|
+#define WANT_CMD
|
|
|
#include "./src/lib.h"
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
#include <stdio.h>
|
|
|
|
|
|
-bool tkn_expect(struct tokenizer *tkn, enum token_type type,
|
|
|
- struct token *out_tk, enum err *out_err);
|
|
|
-bool tkn_expect_id(struct tokenizer *tkn, const char *cstr,
|
|
|
- struct token *out_tk, enum err *out_err);
|
|
|
-bool tkn_parse_function(struct tokenizer *tkn);
|
|
|
-
|
|
|
-bool run_function(struct str str);
|
|
|
-
|
|
|
-bool tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
|
|
|
- enum err *out_err);
|
|
|
-
|
|
|
-bool tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk,
|
|
|
- enum err *out_err);
|
|
|
-
|
|
|
-bool is_space(char c);
|
|
|
-bool
|
|
|
-is_space(char c)
|
|
|
-{
|
|
|
- return (c == ' ') || (c == '\r') || (c == '\n')
|
|
|
- || (c == '\t') || (c == '\v');
|
|
|
-}
|
|
|
-
|
|
|
-enum c_token_type {
|
|
|
- _TT = TK_LAST,
|
|
|
- TK_PP_DEF,
|
|
|
- TK_PP_INC
|
|
|
-};
|
|
|
-
|
|
|
-struct token_pp_inc {
|
|
|
- enum c_token_type type;
|
|
|
- u64 loc_start;
|
|
|
- u64 loc_end;
|
|
|
-
|
|
|
- struct str string;
|
|
|
-};
|
|
|
-
|
|
|
-struct token_pp_def {
|
|
|
- enum token_type type;
|
|
|
- u64 loc_start;
|
|
|
- u64 loc_end;
|
|
|
-
|
|
|
- struct str name;
|
|
|
- struct str val;
|
|
|
-};
|
|
|
-
|
|
|
-struct token_var_decl {
|
|
|
- enum token_type type;
|
|
|
- u64 loc_start;
|
|
|
- u64 loc_end;
|
|
|
-
|
|
|
- struct str _type;
|
|
|
- struct str name;
|
|
|
- struct str init;
|
|
|
-};
|
|
|
-
|
|
|
-struct token_func_decl {
|
|
|
- enum token_type type;
|
|
|
- u64 loc_start;
|
|
|
- u64 loc_end;
|
|
|
-
|
|
|
- struct str _type;
|
|
|
- struct str name;
|
|
|
-};
|
|
|
-
|
|
|
-struct ctx {
|
|
|
- void *t;
|
|
|
-};
|
|
|
-
|
|
|
-bool skip_token(struct tokenizer *tkn, char c);
|
|
|
-
|
|
|
+/*
|
|
|
# define DIE(f, e) \
|
|
|
(f); \
|
|
|
if ( (e) != ERR_OK ) {\
|
|
|
@@ -102,95 +36,133 @@ bool skip_token(struct tokenizer *tkn, char c);
|
|
|
printf("PRE: `" #f "`\n"); \
|
|
|
f; \
|
|
|
printf("POST: `" #f "`\n");
|
|
|
+*/
|
|
|
|
|
|
int
|
|
|
main(int argc, char *argv[])
|
|
|
{
|
|
|
enum err err = ERR_OK;
|
|
|
|
|
|
- u8 *file = NULL;
|
|
|
- u64 file_size = 0;
|
|
|
- struct str s = {0};
|
|
|
- struct str ss = {0};
|
|
|
- struct str_tokenizer stkn = {0};
|
|
|
+ struct cmd cmd = {0};
|
|
|
|
|
|
- u64 *index = NULL;
|
|
|
- u64 i = 0;
|
|
|
- u64 counter = 0;
|
|
|
|
|
|
- void *tmp = NULL;
|
|
|
- struct key_bytes *kb = NULL;
|
|
|
+ cmd = cmd_create_ns("/bin/echo", &err);
|
|
|
+
|
|
|
+ cmd_append_arg_ns(&cmd, "This is a test of execve", &err);
|
|
|
|
|
|
- struct map m = {0};
|
|
|
+ cmd_exec(&cmd, &err);
|
|
|
|
|
|
- m = DIE(map_create(sizeof(u64), 64, &err), err);
|
|
|
+ cmd_destroy(&cmd, &err);
|
|
|
|
|
|
- file = DIE(slop_file_slurp("./t8.shakespeare.txt", &file_size, &err), err);
|
|
|
+ if ( err != ERR_OK ) {
|
|
|
+ cmd_destroy(&cmd, NULL);
|
|
|
+ fprintf(stderr, "Failed cmd: %s\n", err_to_name[err]);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
|
|
|
- s = DIE(str_from_cstr((char*)file, file_size, &err), err);
|
|
|
+ /*
|
|
|
+ bool was_rebuild = false;
|
|
|
+ struct dyn_arr dirs = {0};
|
|
|
+ size_t i = 0;
|
|
|
|
|
|
- stkn = str_tokenize_func(s, is_space);
|
|
|
+ was_rebuild = build_go_rebuild_yourself(__FILE__, &err);
|
|
|
+ if ( was_rebuild == true ) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
- ss = str_tokenizer_next(&stkn);
|
|
|
- for ( ; ss.size != ((u64) -1); (ss = str_tokenizer_next(&stkn), ++i)) {
|
|
|
- /*
|
|
|
- if ( i > 10 ) {
|
|
|
- break;
|
|
|
- }
|
|
|
- */
|
|
|
-
|
|
|
- /* printf("i -> %ld\n", i); */
|
|
|
- tmp = map_get(&m, (void*)ss.data, ss.size, &err);
|
|
|
- if ( err == ERR_NOT_FOUND ) {
|
|
|
- err = ERR_OK;
|
|
|
- counter = 1;
|
|
|
- /* printf("-> `%.*s` | `%ld`\n", (int)ss.size, ss.data, counter); */
|
|
|
- DIE(map_add(&m, (void*)ss.data, ss.size, &counter, &err), err);
|
|
|
- continue;
|
|
|
- }
|
|
|
- counter = *(u64*) tmp;
|
|
|
+ dirs = dir_list_with_ext("./src", ".c", &err);
|
|
|
|
|
|
- ++counter;
|
|
|
- DIE(map_set(&m, (void*)ss.data, ss.size, &counter, &err), err);
|
|
|
+ free(dirs);
|
|
|
+ */
|
|
|
|
|
|
- /* printf("-> `%.*s` | `%ld`\n", (int)ss.size, ss.data, counter); */
|
|
|
- }
|
|
|
+ UNUSED(argc);
|
|
|
+ UNUSED(argv);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- i = 0;
|
|
|
- MAP_FOR_EACH(&m, index, kb) {
|
|
|
- struct map_item *mi = MAP_GET_INDEX(&m, *index);
|
|
|
+bool skip_token(struct tokenizer *tkn, char c);
|
|
|
|
|
|
- if ( i > 10 ) break;
|
|
|
+enum c_token_type {
|
|
|
+ _TT = TK_LAST,
|
|
|
+ TK_PP_DEF,
|
|
|
+ TK_PP_INC
|
|
|
+};
|
|
|
|
|
|
- printf("%.*s -> %ld\n", (int) kb->size, kb->key , *(u64*)mi->item);
|
|
|
+struct pp_def {
|
|
|
+ struct str name;
|
|
|
+ struct str val;
|
|
|
+};
|
|
|
|
|
|
- ++i;
|
|
|
+# define PP_DEF_DESTROY(Var) \
|
|
|
+ if ( (Var) != NULL ) { \
|
|
|
+ STR_DESTROY((Var)->name); \
|
|
|
+ STR_DESTROY((Var)->val); \
|
|
|
+ LIB_FREE((Var)); \
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- MAP_FOR_EACH_INDEXS(&m, index) {
|
|
|
- struct map_item *mi = MAP_GET_INDEX(&m, *index);
|
|
|
- printf("%ld -> Value: %ld\n", *index, *(u64*)mi->item);
|
|
|
+struct var_decl {
|
|
|
+ bool is_ptr;
|
|
|
+ struct str type;
|
|
|
+ struct str name;
|
|
|
+};
|
|
|
+
|
|
|
+# define VAR_DECL_DESTROY(Var) \
|
|
|
+ if ( (Var) != NULL ) { \
|
|
|
+ STR_DESTROY((Var)->type); \
|
|
|
+ STR_DESTROY((Var)->name); \
|
|
|
}
|
|
|
|
|
|
- kb = m.keys.data;
|
|
|
- while ( kb->size > 0 ) {
|
|
|
- printf("-->> %.*s\n", (int) kb->size, kb->key);
|
|
|
- kb = CAST(struct key_bytes *, CAST(u8*, kb->key) + kb->size);
|
|
|
+struct func_decl {
|
|
|
+ struct str ret_type;
|
|
|
+ struct str name;
|
|
|
+ struct {
|
|
|
+ struct var_decl *data;
|
|
|
+ u64 size;
|
|
|
+ u64 cap;
|
|
|
+ } args;
|
|
|
+};
|
|
|
+
|
|
|
+void func_decl_destroy(struct func_decl *fd);
|
|
|
+void
|
|
|
+func_decl_destroy(struct func_decl *fd)
|
|
|
+{
|
|
|
+ u64 i = 0;
|
|
|
+ if ( fd == NULL ) return;
|
|
|
+ STR_DESTROY(fd->ret_type);
|
|
|
+ STR_DESTROY(fd->name);
|
|
|
+
|
|
|
+ for ( i = 0; i < fd->args.size; ++i ) {
|
|
|
+ STR_DESTROY(fd->args.data[i].type);
|
|
|
+ STR_DESTROY(fd->args.data[i].name);
|
|
|
}
|
|
|
- */
|
|
|
+ LIB_FREE(fd->args.data);
|
|
|
|
|
|
- DIE(map_destroy(&m, &err), err);
|
|
|
+ LIB_FREE(fd);
|
|
|
+}
|
|
|
|
|
|
- free(file);
|
|
|
+bool tkn_expect(struct tokenizer *tkn, enum token_type type,
|
|
|
+ struct token *out_tk, enum err *out_err);
|
|
|
+bool tkn_expect_id(struct tokenizer *tkn, const char *cstr,
|
|
|
+ struct token *out_tk, enum err *out_err);
|
|
|
+bool tkn_parse_function(struct tokenizer *tkn);
|
|
|
|
|
|
- UNUSED(argc);
|
|
|
- UNUSED(argv);
|
|
|
- return 0;
|
|
|
-exit_err:
|
|
|
- if ( file != NULL ) free(file);
|
|
|
- map_destroy(&m, NULL);
|
|
|
- return 1;
|
|
|
+bool run_function(struct str str);
|
|
|
+
|
|
|
+bool tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
|
|
|
+ enum err *out_err);
|
|
|
+
|
|
|
+bool tkn_parse_var(struct tokenizer *tkn, struct token *out_tk,
|
|
|
+ enum err *out_err);
|
|
|
+
|
|
|
+bool tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk,
|
|
|
+ enum err *out_err);
|
|
|
+
|
|
|
+bool is_space(char c);
|
|
|
+bool
|
|
|
+is_space(char c)
|
|
|
+{
|
|
|
+ return (c == ' ') || (c == '\r') || (c == '\n')
|
|
|
+ || (c == '\t') || (c == '\v');
|
|
|
}
|
|
|
|
|
|
int main2(int argc, char *argv[]);
|
|
|
@@ -217,8 +189,6 @@ main2(int argc, char *argv[])
|
|
|
tkn_opts.skip_token = skip_token;
|
|
|
tkn = tokenizer_create(code, src_path, &tkn_opts, &err);
|
|
|
|
|
|
- tkn.edata = &tk_da;
|
|
|
-
|
|
|
tk = tokenizer_next_token(&tkn, &err);
|
|
|
do {
|
|
|
if ( err != ERR_OK ) {
|
|
|
@@ -228,11 +198,18 @@ main2(int argc, char *argv[])
|
|
|
}
|
|
|
switch ( tk.type ) {
|
|
|
case TK_POUND: {
|
|
|
- struct token pp_tk = {0};
|
|
|
- if ( ! tkn_parse_pp_directive(&tkn, &pp_tk, &err) ) goto error_exit;
|
|
|
+ if ( ! tkn_parse_pp_directive(&tkn, NULL, &err) ) goto error_exit;
|
|
|
} break;
|
|
|
case TK_ID: if ( ! tkn_parse_decl(&tkn, NULL, &err) ) goto error_exit;
|
|
|
case TK_NL: break;
|
|
|
+ case TK_SLASH: {
|
|
|
+ if ( ! tkn_expect(&tkn, TK_ASTERISK, NULL, &err) ) goto error_exit;
|
|
|
+
|
|
|
+ while ( tk.type != TK_ASTERISK )
|
|
|
+ tk = tokenizer_next_token(&tkn, &err);
|
|
|
+
|
|
|
+ if ( ! tkn_expect(&tkn, TK_SLASH, NULL, &err) ) goto error_exit;
|
|
|
+ } break;
|
|
|
default: fprintf(stderr, "%s ERROR: Invalid Token `%s`\n",
|
|
|
tokenizer_token_loc_temp(&tkn, &tk, TLF_VIM, NULL),
|
|
|
token_to_cstr(tk.type));
|
|
|
@@ -298,7 +275,6 @@ tkn_expect_id(struct tokenizer *tkn, const char *cstr, struct token *out_tk,
|
|
|
|
|
|
if ( tokenizer_is_next_id(tkn, str, out_tk, &err) == false ) {
|
|
|
struct token tk = {0};
|
|
|
- struct token_wstr *tk_ws = NULL;
|
|
|
tk = tokenizer_next_token(tkn, &err);
|
|
|
if ( err != ERR_OK ) {
|
|
|
fprintf(stderr, "Failed to get next token: %s\n",
|
|
|
@@ -312,10 +288,9 @@ tkn_expect_id(struct tokenizer *tkn, const char *cstr, struct token *out_tk,
|
|
|
token_to_cstr(tk.type));
|
|
|
return false;
|
|
|
}
|
|
|
- tk_ws = (struct token_wstr *)&tk;
|
|
|
fprintf(stderr, "%s ERROR: Got wrong id, expected: %s, got: %.*s\n",
|
|
|
tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
|
|
|
- cstr, (int) tk_ws->string.size, tk_ws->string.data);
|
|
|
+ cstr, (int) tk.string.size, tk.string.data);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
@@ -326,10 +301,7 @@ bool
|
|
|
tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
|
|
|
enum err *out_err)
|
|
|
{
|
|
|
- static char buf[1024] = {0};
|
|
|
- static char buf2[1024] = {0};
|
|
|
struct token tk = {0};
|
|
|
- struct token_wstr *tk_ws = NULL;
|
|
|
enum err err = ERR_OK;
|
|
|
enum err *perr = &err;
|
|
|
|
|
|
@@ -353,61 +325,68 @@ tkn_parse_pp_directive(struct tokenizer *tkn, struct token *out_tk,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- tk_ws = (struct token_wstr *) &tk;
|
|
|
-
|
|
|
- if ( str_eq_cstr(tk_ws->string, "define", 6) == true ) {
|
|
|
- struct token_pp_def tk_def = {0};
|
|
|
+ if ( str_eq_cstr(tk.string, "define", 6) == true ) {
|
|
|
+ struct token tk_def = {0};
|
|
|
+ struct pp_def *def = NULL;
|
|
|
|
|
|
- if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
|
|
|
- tk_ws = (struct token_wstr *) &tk;
|
|
|
-
|
|
|
- tk_def.loc_start = tk_ws->loc_start;
|
|
|
+ def = malloc(sizeof(struct pp_def));
|
|
|
+ if ( def == NULL ) {
|
|
|
+ *perr = ERR_FAILED_ALLOC;
|
|
|
+ goto def_exit_err;
|
|
|
+ }
|
|
|
+ memset(def, 0, sizeof(struct pp_def));
|
|
|
|
|
|
- memcpy(buf, tk_ws->string.data, tk_ws->string.size);
|
|
|
+ if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto def_exit_err;
|
|
|
+ tk_def.loc_start = tk.loc_start;
|
|
|
|
|
|
- tk_def.name.data = buf;
|
|
|
- tk_def.name.size = tk_ws->string.size;
|
|
|
+ def->name = str_dup(tk.string);
|
|
|
|
|
|
tk = tokenizer_next_token(tkn, &err);
|
|
|
if ( err != ERR_OK ) {
|
|
|
fprintf(stderr, "Failed to get next token: %s\n",
|
|
|
err_to_name[err]);
|
|
|
- return false;
|
|
|
+ goto def_exit_err;
|
|
|
}
|
|
|
|
|
|
switch ( tk.type ) {
|
|
|
case TK_ID:
|
|
|
case TK_STR_LIT:
|
|
|
case TK_NUM_LIT:
|
|
|
- tk_ws = (struct token_wstr *) &tk;
|
|
|
break;
|
|
|
- case TK_NL: goto define_wout_value;
|
|
|
+ case TK_NL: goto def_wout_value;
|
|
|
default:
|
|
|
fprintf(stderr,
|
|
|
"%s Got wrong token, expected:"
|
|
|
" TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
|
|
|
tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
|
|
|
token_to_cstr(tk.type));
|
|
|
- return false;
|
|
|
+ goto def_exit_err;
|
|
|
}
|
|
|
|
|
|
- memcpy(buf2, tk_ws->string.data, tk_ws->string.size);
|
|
|
+ def->val = str_dup(tk.string);
|
|
|
+
|
|
|
+ tk_def.loc_end = tk.loc_end;
|
|
|
|
|
|
- tk_def.val.data = buf2;
|
|
|
- tk_def.val.size = tk_ws->string.size;
|
|
|
+ if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) goto def_exit_err;
|
|
|
+def_wout_value:
|
|
|
|
|
|
- tk_def.loc_end = tk_ws->loc_end;
|
|
|
+ tk_def.extra = def;
|
|
|
|
|
|
- if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) return false;
|
|
|
-define_wout_value:
|
|
|
+ if ( out_tk != NULL ) {
|
|
|
+ *out_tk = tk_def;
|
|
|
+ } else {
|
|
|
+ PP_DEF_DESTROY(def);
|
|
|
+ }
|
|
|
|
|
|
- LIB_SET_IF_NOT_NULL(out_tk, *(struct token *) &tk_def);
|
|
|
return true;
|
|
|
+def_exit_err:
|
|
|
+ PP_DEF_DESTROY(def);
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- if ( str_eq_cstr(tk_ws->string, "include", 7) == true ) {
|
|
|
- struct token_pp_inc tk_inc = {0};
|
|
|
- tk_inc.type = TK_PP_INC;
|
|
|
+ if ( str_eq_cstr(tk.string, "include", 7) == true ) {
|
|
|
+ struct token tk_inc = {0};
|
|
|
+ tk_inc.type = (enum token_type) TK_PP_INC;
|
|
|
|
|
|
tk = tokenizer_next_token(tkn, &err);
|
|
|
if ( err != ERR_OK ) {
|
|
|
@@ -417,72 +396,143 @@ define_wout_value:
|
|
|
}
|
|
|
|
|
|
if ( tk.type == TK_STR_LIT ) {
|
|
|
- tk_ws = (struct token_wstr *) &tk;
|
|
|
- tk_inc.loc_start = tk_ws->loc_start;
|
|
|
- tk_inc.loc_end = tk_ws->loc_end;
|
|
|
-
|
|
|
- memcpy(buf, tk_ws->string.data, tk_ws->string.size);
|
|
|
- tk_inc.string.data = buf;
|
|
|
- tk_inc.string.size = tk_ws->string.size;
|
|
|
- goto include_str_lit;
|
|
|
+ tk_inc.loc_start = tk.loc_start;
|
|
|
+ tk_inc.loc_end = tk.loc_end;
|
|
|
+
|
|
|
+ tk_inc.string = str_dup(tk.string);
|
|
|
+ goto inc_str_lit;
|
|
|
} else if ( tk.type != TK_L_ANG_BRACKET) {
|
|
|
fprintf(stderr,
|
|
|
"%s Got wrong token, expected:"
|
|
|
" TK_ID/TK_STR_LIT/TK_NUM_LIT, got: %s\n",
|
|
|
tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
|
|
|
token_to_cstr(tk.type));
|
|
|
- return false;
|
|
|
+ goto inc_exit_err;
|
|
|
}
|
|
|
|
|
|
- if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
|
|
|
- tk_ws = (struct token_wstr *) &tk;
|
|
|
+ if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto inc_exit_err;
|
|
|
+ tk_inc.loc_start = tk.loc_start;
|
|
|
+ tk_inc.loc_end = tk.loc_end;
|
|
|
|
|
|
- tk_inc.loc_start = tk_ws->loc_start;
|
|
|
- tk_inc.loc_end = tk_ws->loc_end;
|
|
|
+ tk_inc.string = str_dup(tk.string);
|
|
|
|
|
|
- memcpy(buf, tk_ws->string.data, tk_ws->string.size);
|
|
|
+ if ( ! tkn_expect(tkn, TK_DOT, NULL, perr) ) goto inc_exit_err;
|
|
|
+ if ( ! tkn_expect_id(tkn, "h", NULL, perr) ) goto inc_exit_err;
|
|
|
|
|
|
- tk_inc.string.data = buf;
|
|
|
- tk_inc.string.size = tk_ws->string.size;
|
|
|
+ if ( ! tkn_expect(tkn, TK_R_ANG_BRACKET, NULL, perr) )
|
|
|
+ goto inc_exit_err;
|
|
|
+ if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) goto inc_exit_err;
|
|
|
|
|
|
- if ( ! tkn_expect(tkn, TK_DOT, NULL, perr) ) return false;
|
|
|
- if ( ! tkn_expect_id(tkn, "h", NULL, perr) ) return false;
|
|
|
-
|
|
|
- if ( ! tkn_expect(tkn, TK_R_ANG_BRACKET, NULL, perr) ) return false;
|
|
|
- if ( ! tkn_expect(tkn, TK_NL, NULL, perr) ) return false;
|
|
|
-
|
|
|
-include_str_lit:
|
|
|
- LIB_SET_IF_NOT_NULL(out_tk, *(struct token *) &tk_inc);
|
|
|
+inc_str_lit:
|
|
|
+ if ( out_tk != NULL ) {
|
|
|
+ *out_tk = tk_inc;
|
|
|
+ } else {
|
|
|
+ STR_DESTROY(tk_inc.string);
|
|
|
+ }
|
|
|
return true;
|
|
|
+inc_exit_err:
|
|
|
+ STR_DESTROY(tk_inc.string);
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- if ( str_eq_cstr(tk_ws->string, "if", 2) == true ) {
|
|
|
+ if ( str_eq_cstr(tk.string, "if", 2) == true ) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- if ( str_eq_cstr(tk_ws->string, "ifdef", 2) == true ) {
|
|
|
+ if ( str_eq_cstr(tk.string, "ifdef", 2) == true ) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- if ( str_eq_cstr(tk_ws->string, "ifndef", 2) == true ) {
|
|
|
+ if ( str_eq_cstr(tk.string, "ifndef", 2) == true ) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
*perr = -1;
|
|
|
fprintf(stderr, "%s ERROR: Invalid Pre-Compiler directive `%.*s`\n",
|
|
|
tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
|
|
|
- (int) tk_ws->string.size, tk_ws->string.data);
|
|
|
+ (int) tk.string.size, tk.string.data);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+bool
|
|
|
+tkn_parse_var(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
|
|
|
+{
|
|
|
+ enum err err = ERR_OK;
|
|
|
+ enum err *perr = &err;
|
|
|
+
|
|
|
+ struct token tk = {0};
|
|
|
+
|
|
|
+ struct var_decl *vd = NULL;
|
|
|
+
|
|
|
+ struct {
|
|
|
+ char *data;
|
|
|
+ u64 size;
|
|
|
+ u64 cap;
|
|
|
+ } type = {0};
|
|
|
+
|
|
|
+ LIB_ARG_IF_NOT_NULL_MUST_BE(out_err, ERR_OK, false);
|
|
|
+ LIB_ARG_MUST_NOT_BE_NULL(tkn, out_err, false);
|
|
|
+
|
|
|
+ if ( out_err != NULL ) {
|
|
|
+ perr = out_err;
|
|
|
+ }
|
|
|
+
|
|
|
+ vd = malloc(sizeof(*vd));
|
|
|
+ if ( vd == NULL ) {
|
|
|
+ *perr = ERR_FAILED_ALLOC;
|
|
|
+ goto exit_err;
|
|
|
+ }
|
|
|
+ memset(vd, 0, sizeof(*vd));
|
|
|
+
|
|
|
+ if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto exit_err;
|
|
|
+ DA_APPEND_DATA(type, tk.string.data, tk.string.size, perr);
|
|
|
+ DA_APPEND(type, ' ', perr);
|
|
|
+
|
|
|
+ while ( true ) {
|
|
|
+ /* bool is_name = false;*/
|
|
|
+ /*enum token_type ntt = tokenizer_peek_token_type(tkn, NULL);*/
|
|
|
+
|
|
|
+ /*is_name = ( ntt == TK_COMMA ) || ( ntt == TK_SEMICOLON )
|
|
|
+ || ( ntt == TK_ASTERISK ) || ( ntt == TK_EQUAL );*/
|
|
|
+
|
|
|
+ tk = tokenizer_next_token(tkn, NULL);
|
|
|
+ switch ( tk.type ) {
|
|
|
+ case TK_ID: break;
|
|
|
+ case TK_ASTERISK: break;
|
|
|
+ case TK_COMMA: break;
|
|
|
+ case TK_SEMICOLON: break;
|
|
|
+ default:
|
|
|
+ fprintf(stderr,
|
|
|
+ "%s Got wrong token, expected:"
|
|
|
+ " TK_ID/TK_ASTERISK/TK_COMMA/TK_SEMICOLON, got: %s\n",
|
|
|
+ tokenizer_token_loc_temp(tkn, &tk, TLF_VIM, NULL),
|
|
|
+ token_to_cstr(tk.type));
|
|
|
+ goto exit_err;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ TODO("Rest of var decl!");
|
|
|
+
|
|
|
+ if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) goto exit_err;
|
|
|
+ vd->name = str_dup(tk.string);
|
|
|
+ if ( ! tkn_expect(tkn, TK_COMMA, NULL, perr) ) goto exit_err;
|
|
|
+
|
|
|
+ if ( out_tk != NULL ) {
|
|
|
+ *out_tk = tk;
|
|
|
+ }
|
|
|
+
|
|
|
+exit_err:
|
|
|
+ LIB_FREE(vd);
|
|
|
+ LIB_FREE(type.data);
|
|
|
+ if ( *perr == ERR_OK ) *perr = ERR_GENERAL_ERROR;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
bool
|
|
|
tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
|
|
|
{
|
|
|
- /* static char buf[1024] = {0}; */
|
|
|
- /* static char buf2[1024] = {0}; */
|
|
|
struct token tk = {0};
|
|
|
- struct token_wstr *tk_ws = NULL;
|
|
|
- struct token_wstr tk_type = {0};
|
|
|
+ struct token tk_type = {0};
|
|
|
enum err err = ERR_OK;
|
|
|
enum err *perr = &err;
|
|
|
|
|
|
@@ -493,13 +543,70 @@ tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
|
|
|
perr = out_err;
|
|
|
}
|
|
|
|
|
|
- tk_type = *(struct token_wstr *) &tkn->last;
|
|
|
+ tk_type = tkn->last;
|
|
|
|
|
|
if ( ! tkn_expect(tkn, TK_ID, &tk, perr) ) return false;
|
|
|
|
|
|
switch ( tokenizer_next_token_type(tkn, perr) ) {
|
|
|
case TK_L_BRACES: {
|
|
|
- TODO("Implement function declaration");
|
|
|
+ struct token tk_fd = {0};
|
|
|
+ struct func_decl *fd = NULL;
|
|
|
+
|
|
|
+ fd = malloc(sizeof(struct func_decl));
|
|
|
+ if ( fd == NULL ) {
|
|
|
+ *out_err = ERR_FAILED_ALLOC;
|
|
|
+ goto func_decl_exit_err;
|
|
|
+ }
|
|
|
+ memset(fd, 0, sizeof(*fd));
|
|
|
+
|
|
|
+ fd->args.cap = 32;
|
|
|
+ fd->args.data = malloc(sizeof(*fd->args.data) * fd->args.cap);
|
|
|
+ if ( fd->args.data == NULL ) {
|
|
|
+ *out_err = ERR_FAILED_ALLOC;
|
|
|
+ goto func_decl_exit_err;
|
|
|
+ }
|
|
|
+ memset(fd->args.data, 0, sizeof(*fd->args.data) * fd->args.cap);
|
|
|
+
|
|
|
+ tk_fd.loc_start = tk_type.loc_start;
|
|
|
+
|
|
|
+ fd->ret_type = str_dup(tk_type.string);
|
|
|
+ fd->name = str_dup(tk.string);
|
|
|
+
|
|
|
+ while ( true ) {
|
|
|
+ struct token tk_vd = {0};
|
|
|
+ struct var_decl *vd = NULL;
|
|
|
+
|
|
|
+ tkn_parse_var(tkn, &tk_vd, perr);
|
|
|
+ if ( *perr != ERR_OK ) goto func_decl_exit_err;
|
|
|
+
|
|
|
+ vd = tk_vd.extra;
|
|
|
+
|
|
|
+ DA_APPEND(fd->args, *vd, perr);
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ if ( out_tk != NULL ) {
|
|
|
+ *out_tk = tk_fd;
|
|
|
+ } else {
|
|
|
+ func_decl_destroy(fd);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+func_decl_exit_err:
|
|
|
+ func_decl_destroy(fd);
|
|
|
+ return false;
|
|
|
+ /*
|
|
|
+struct func_decl {
|
|
|
+ struct str ret_type;
|
|
|
+ struct str name;
|
|
|
+ struct {
|
|
|
+ struct str *data;
|
|
|
+ u64 size;
|
|
|
+ u64 cap;
|
|
|
+ } args;
|
|
|
+};
|
|
|
+*/
|
|
|
+
|
|
|
} break;
|
|
|
case TK_INVALID:
|
|
|
fprintf(stderr, "Failed to get next token: %s\n", err_to_name[*perr]);
|
|
|
@@ -533,10 +640,9 @@ tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
|
|
|
UNUSED(out_tk);
|
|
|
|
|
|
*perr = ERR_OK;
|
|
|
- tk_ws = (struct token_wstr *) &tkn->last;
|
|
|
fprintf(stderr, "%s ERROR: Invalid declaration id `%.*s`\n",
|
|
|
tokenizer_token_loc_temp(tkn, &tkn->last, TLF_VIM, NULL),
|
|
|
- (int) tk_ws->string.size, tk_ws->string.data);
|
|
|
+ (int) tk.string.size, tk.string.data);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
@@ -544,20 +650,5 @@ tkn_parse_decl(struct tokenizer *tkn, struct token *out_tk, enum err *out_err)
|
|
|
int
|
|
|
main(void)
|
|
|
{
|
|
|
- enum err err = ERR_OK;
|
|
|
- bool was_rebuild = false;
|
|
|
- struct dyn_arr dirs = {0};
|
|
|
- size_t i = 0;
|
|
|
-
|
|
|
- was_rebuild = build_go_rebuild_yourself(__FILE__, &err);
|
|
|
- if ( was_rebuild == true ) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- dirs = dir_list_with_ext("./src", ".c", &err);
|
|
|
-
|
|
|
- free(dirs);
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
*/
|