morph/src/parser/parser.c
2025-07-04 18:05:15 +03:00

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;
}