80 lines
2.5 KiB
C
80 lines
2.5 KiB
C
#include "logger.h"
|
|
#include "tokeniser.h"
|
|
#include "util.h"
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <token.h>
|
|
#include <dynarray.h>
|
|
#include <parser/parser.h>
|
|
#include <parser/precomp.h>
|
|
#include <parser/tokcmp.h>
|
|
#include <parser/ast.h>
|
|
|
|
int _parse(parser_state_t* state);
|
|
|
|
program_t parse(const token_t* tokens) {
|
|
// reverses tokens so its way easier to parse;
|
|
dynarray_reverse((void*)tokens);
|
|
parser_state_t state = {0};
|
|
state.tokens = (token_t*)tokens;
|
|
(void)tokens;
|
|
_parse(&state);
|
|
return state.prog;
|
|
}
|
|
|
|
int _parse(parser_state_t* state) {
|
|
while (dynarray_pop(state->tokens, &state->curr_tok) == 0) {
|
|
if (state->curr_tok.type != TT_KW) {
|
|
const char* dbg_s = get_tok_str_dbg(&state->curr_tok);
|
|
log_error(&state->curr_tok.loc, "Invalid word, expected Keyword, got %s.", dbg_s);
|
|
free((void*)dbg_s);
|
|
}
|
|
switch (state->curr_tok.kw_type) {
|
|
case (KW_INCLUDE): {
|
|
expect_token_type(state, TT_PUSH_STR);
|
|
const char* code = read_to_string(state->curr_tok.str_v);
|
|
if (!code) {
|
|
return 1;
|
|
}
|
|
token_t* tokens = tokenise_string((char*)state->curr_tok.str_v, (char*)code);
|
|
if (!tokens) {
|
|
return 1;
|
|
}
|
|
if (_parse(state) != 0) {
|
|
return 1;
|
|
}
|
|
}; break;
|
|
case (KW_CONST): {
|
|
// TODO: Implement compile time calculation of the value
|
|
token_t* tokens = dynarray_create(token_t);
|
|
|
|
while (test_token_type_ex(state, TT_KW, KW_END) == NULL) {
|
|
// clang-format off
|
|
if (
|
|
test_token_type(state, TT_PUSH_STR) || test_token_type(state, TT_PUSH_CSTR) ||
|
|
test_token_type(state, TT_PUSH_CHAR) || test_token_type(state, TT_PUSH_INT) ||
|
|
test_token_type(state, TT_PUSH_FLOAT) || test_token_type(state, TT_PUSH_MEM)
|
|
) { // clang-format on
|
|
dynarray_pop(state->tokens, &state->curr_tok);
|
|
dynarray_push(tokens, state->curr_tok);
|
|
}
|
|
}
|
|
if (!expect_token_type_ex(state, TT_KW, KW_END)) {
|
|
return 1;
|
|
}
|
|
|
|
}; break;
|
|
case (KW_MEMORY): {
|
|
|
|
}; break;
|
|
case (KW_FN): {
|
|
|
|
}; break;
|
|
default:
|
|
assert(true && "TODO: parse all kw's");
|
|
}
|
|
}
|
|
return 0;
|
|
}
|