mirror of
https://github.com/0x221E/ibuild.git
synced 2026-01-18 02:42:20 +00:00
DRAFT, Add: Build configuration recognizes parser
This commit is contained in:
163
ibuild.c
163
ibuild.c
@@ -35,6 +35,7 @@ void launch_compile(CompileOptions* co)
|
||||
else if (p==0)
|
||||
{
|
||||
char* args[] = {"compile", "test.c", "-o", "test", NULL};
|
||||
printf("SET COMPILER: %s\n", co->compiler_path);
|
||||
if((execvp(co->compiler_path, args)) == -1)
|
||||
die("launch_compile() execvp error");
|
||||
}
|
||||
@@ -164,10 +165,12 @@ Token tokenizer_next(Tokenizer* t)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
K_NA = -1,
|
||||
K_UNKNOWN = 0,
|
||||
K_COMPILER_PATH = 1,
|
||||
K_SRC_DIR = 2,
|
||||
K_BUILD_DIR = 3,
|
||||
K_TARGET_EXEC = 4,
|
||||
} Key;
|
||||
|
||||
typedef enum
|
||||
@@ -185,7 +188,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Tokenizer* tokenizer;
|
||||
Arena* tokens_alloc;
|
||||
size_t loc;
|
||||
size_t cap;
|
||||
Arena alloc;
|
||||
@@ -201,6 +204,7 @@ static KeyMap keyword_mappings[] = {
|
||||
{K_COMPILER_PATH, "COMPILER_PATH"},
|
||||
{K_SRC_DIR, "SRC_DIR"},
|
||||
{K_BUILD_DIR, "BUILD_DIR"},
|
||||
{K_TARGET_EXEC, "TARGET_EXEC"},
|
||||
{K_UNKNOWN, NULL},
|
||||
};
|
||||
|
||||
@@ -222,9 +226,9 @@ Token parser_peek(Parser* p, size_t o)
|
||||
{
|
||||
if (p->loc + o >= p->cap)
|
||||
{
|
||||
return ((Token*)p->tokenizer->alloc.start)[p->loc - 1];
|
||||
return ((Token*)p->tokens_alloc->start)[p->loc - 1];
|
||||
}
|
||||
return ((Token*)p->tokenizer->alloc.start)[p->loc + o];
|
||||
return ((Token*)p->tokens_alloc->start)[p->loc + o];
|
||||
}
|
||||
|
||||
Token parser_previous(Parser* p)
|
||||
@@ -234,30 +238,40 @@ Token parser_previous(Parser* p)
|
||||
die("parser logic error.");
|
||||
}
|
||||
|
||||
return ((Token*)p->tokenizer->alloc.start)[p->loc - 1];
|
||||
return ((Token*)p->tokens_alloc->start)[p->loc - 1];
|
||||
}
|
||||
|
||||
Token parser_advance(Parser* p)
|
||||
{
|
||||
if(p->loc + 1 >= p->cap)
|
||||
{
|
||||
return ((Token*)p->tokenizer->alloc.start)[p->loc];
|
||||
return ((Token*)p->tokens_alloc->start)[p->loc];
|
||||
}
|
||||
p->loc++;
|
||||
return ((Token*)p->tokenizer->alloc.start)[p->loc];
|
||||
return ((Token*)p->tokens_alloc->start)[p->loc];
|
||||
}
|
||||
|
||||
Token parser_expect(Parser* p, TokenType tt, char* s)
|
||||
{
|
||||
if(p == NULL) die("parser_expect() p must not be NULL");
|
||||
if(p == NULL) die("parser_expect() s must not be NULL");
|
||||
|
||||
if(parser_peek(p, 1).type != tt)
|
||||
die(s);
|
||||
|
||||
return parser_advance(p);
|
||||
}
|
||||
|
||||
Node* parser_expression(Parser* p)
|
||||
{
|
||||
Token t = parser_peek(p,0);
|
||||
Token t = parser_advance(p);
|
||||
if(t.type == T_STRING)
|
||||
{
|
||||
Key k = key_lookup(t.value);
|
||||
if(k == K_UNKNOWN) die("Syntax error: Unexpected expression encountered");
|
||||
Node* node = (Node*)arena_alloc(&p->alloc, sizeof(Node));
|
||||
node->key = k;
|
||||
node->key = K_NA;
|
||||
node->value = (void*)t.value;
|
||||
node->type = N_STRING;
|
||||
parser_advance(p);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -266,11 +280,12 @@ Node* parser_expression(Parser* p)
|
||||
|
||||
Node* parser_statement(Parser* p)
|
||||
{
|
||||
Token t = parser_advance(p);
|
||||
Token t = parser_peek(p, 0);
|
||||
if(t.type == T_IDENTIFIER)
|
||||
{
|
||||
Key k = key_lookup(t.value);
|
||||
if(k == K_UNKNOWN) die("Syntax error: Unexpected identifer encountered");
|
||||
parser_expect(p, T_IS, "Syntax error: Expected '=' after identifier");
|
||||
Node* expression = parser_expression(p);
|
||||
Node* node = (Node*)arena_alloc(&p->alloc, sizeof(Node));
|
||||
node->key = k;
|
||||
@@ -279,14 +294,48 @@ Node* parser_statement(Parser* p)
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%d", t.type);
|
||||
die("Syntax error: expected an identifier");
|
||||
}
|
||||
}
|
||||
|
||||
Node* parser_parse(Parser* p)
|
||||
size_t parser_parse(Parser* p, Node*** out)
|
||||
{
|
||||
return parser_statement(p);
|
||||
Arena statements_alloc = ARENA_CONST;
|
||||
|
||||
size_t size = 0;
|
||||
|
||||
while(p->loc < p->cap - 1)
|
||||
{
|
||||
Node** temp = (Node**)arena_alloc(&statements_alloc, sizeof(Node*));
|
||||
*temp = parser_statement(p);
|
||||
size++;
|
||||
}
|
||||
|
||||
*out = (Node**)statements_alloc.start;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void debug_parser(Node* n, int indent)
|
||||
{
|
||||
for(int i = 0; i < indent; i++)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
switch(n->type)
|
||||
{
|
||||
case N_PAIR:
|
||||
printf("PAIR STATEMENT");
|
||||
printf(" Key: %10d\n", n->key);
|
||||
if(n->value != NULL)
|
||||
debug_parser((Node*)n->value, 2);
|
||||
break;
|
||||
case N_STRING:
|
||||
printf("STRING EXPRESSION");
|
||||
printf(" Value: %s\n", (char*)n->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*** configuration file management ***/
|
||||
@@ -300,13 +349,20 @@ long get_file_size(FILE* fd)
|
||||
return size;
|
||||
}
|
||||
|
||||
int process_config(Arena* tokens)
|
||||
typedef struct
|
||||
{
|
||||
Arena tokens;
|
||||
} ConfigMemory;
|
||||
|
||||
int process_config(Node*** ast)
|
||||
{
|
||||
if(!detect_config_file())
|
||||
return 1;
|
||||
|
||||
printf("IBUILD Configuration file detected.\n");
|
||||
|
||||
ConfigMemory cm = {ARENA_CONST};
|
||||
|
||||
FILE* fd = fopen("IBUILD", "r");
|
||||
|
||||
if(fd == NULL) die("process_config() file exists however fd is NULL");
|
||||
@@ -315,6 +371,8 @@ int process_config(Arena* tokens)
|
||||
|
||||
printf("IBUILD file of size: %d\n", fs);
|
||||
|
||||
if(fs < 2) return 0;
|
||||
|
||||
char* config_mem = malloc(fs + 1);
|
||||
|
||||
fread(config_mem, sizeof(char), fs, fd);
|
||||
@@ -330,44 +388,64 @@ int process_config(Arena* tokens)
|
||||
Token token = tokenizer_next(&t);
|
||||
if(token.type == T_INVALID) die("illegal token!");
|
||||
|
||||
Token* tm = arena_alloc(tokens, sizeof(Token));
|
||||
Token* tm = arena_alloc(&cm.tokens, sizeof(Token));
|
||||
*tm = token;
|
||||
|
||||
t_count++;
|
||||
if(token.type == T_EOF) break;
|
||||
}
|
||||
|
||||
Parser parser = {.tokenizer = &t, .loc = 0, .cap = t_count, .alloc = ARENA_CONST};
|
||||
parser_parse(&parser);
|
||||
Parser parser = {.tokens_alloc = &cm.tokens, .loc = 0, .cap = t_count, .alloc = ARENA_CONST};
|
||||
|
||||
Node** statements = NULL;
|
||||
size_t statements_len = parser_parse(&parser, &statements);
|
||||
|
||||
if(statements == NULL) die("parser return invalid results");
|
||||
|
||||
for (size_t i = 0; i < statements_len; i++)
|
||||
debug_parser(statements[i], 0);
|
||||
|
||||
free(config_mem);
|
||||
return 0;
|
||||
arena_free(&cm.tokens);
|
||||
*ast = statements;
|
||||
return statements_len;
|
||||
}
|
||||
|
||||
/*** build configuration process ***/
|
||||
/*
|
||||
void populate_compile_options(CompileOptions* co, Token* t)
|
||||
{
|
||||
switch(t->type)
|
||||
{
|
||||
case T_KEY_COMPILER_PATH: co->compiler_path = t->value; break;
|
||||
case T_KEY_BUILD_DIR: co->build_dir = t->value; break;
|
||||
case T_KEY_TARGET_EXEC: co->target_exec = t->value; break;
|
||||
case T_KEY_SRC_DIR: co->compiler_path = t->value; break;
|
||||
case T_KEY_VERSION: co->version = t->value; break;
|
||||
}
|
||||
}*/
|
||||
|
||||
void build(Token* options)
|
||||
void set_compiler_option(CompileOptions* co, Key k, char* val)
|
||||
{
|
||||
switch(k)
|
||||
{
|
||||
case K_COMPILER_PATH: co->compiler_path = val; break;
|
||||
case K_BUILD_DIR: co->build_dir = val; break;
|
||||
case K_TARGET_EXEC: co->target_exec = val; break;
|
||||
default:
|
||||
die("Invalid compiler option was supplied!");
|
||||
}
|
||||
}
|
||||
|
||||
void populate_compile_options(CompileOptions* co, Node* n)
|
||||
{
|
||||
switch(n->type)
|
||||
{
|
||||
case N_PAIR:
|
||||
Key k = n->key;
|
||||
set_compiler_option(co, k, (char*)((Node*)n->value)->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void build(int len, Node** st)
|
||||
{
|
||||
CompileOptions co;
|
||||
co.compiler_path = "/usr/bin/gcc";
|
||||
co.build_dir = ".";
|
||||
co.src_dir = ".";
|
||||
co.target_exec = "iexec";
|
||||
|
||||
Token* temp = options;
|
||||
for(; temp->type != T_EOF; temp++)
|
||||
{
|
||||
// populate_compile_options(&co, temp);
|
||||
}
|
||||
for (size_t i = 0; i < len; i++)
|
||||
populate_compile_options(&co, st[i]);
|
||||
|
||||
launch_compile(&co);
|
||||
printf("Compilation finished.\n");
|
||||
@@ -375,15 +453,10 @@ void build(Token* options)
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Arena a = ARENA_CONST;
|
||||
Node** ast = NULL;
|
||||
int len_ast = process_config(&ast);
|
||||
|
||||
process_config(&a);
|
||||
|
||||
Token* ptr = (Token*)a.start;
|
||||
for(; ptr->type != T_EOF; ptr++)
|
||||
{
|
||||
printf("TokenType: %d, Value: %s\n", ptr->type, ptr->value);
|
||||
}
|
||||
build(len_ast, ast);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user