/* * Copyright (c) 2026, Chloe M. * Provided under the BSD-3 clause */ #include #include #include "cescal/log.h" #include "cescal/parser.h" #include "cescal/state.h" #include "cescal/lexer.h" /* Symbolic token */ #define symtok(tok) \ "[" tok "]" /* Quoted token */ #define qtok(tok) \ "'" tok "'" /* Convert token to string */ #define tokstr1(tt) \ toktab[(tt)] /* Convert token to string */ #define tokstr(tok) \ toktab[(tok)->type] /* * Converts numeric tokens into human readable strings */ static const char *toktab[] = { [TT_NONE] = symtok("none"), [TT_IDENT] = symtok("ident"), [TT_COMMENT] = symtok("comment"), [TT_INTLIT] = symtok("number"), [TT_LPAREN] = qtok("("), [TT_RPAREN] = qtok(")"), [TT_COMMA] = qtok(","), [TT_COLON] = qtok(":"), [TT_ARROW] = qtok("->"), [TT_PLUS] = qtok("+"), [TT_MINUS] = qtok("-"), [TT_SLASH] = qtok("/"), [TT_STAR] = qtok("*"), [TT_EQUALS] = qtok("="), [TT_DEFINE] = qtok("#define"), [TT_IFNDEF] = qtok("#ifndef"), [TT_IFDEF] = qtok("#ifdef"), [TT_RETURN] = qtok("return"), [TT_PUB] = qtok("pub"), [TT_PROC] = qtok("proc"), [TT_BEGIN] = qtok("begin"), [TT_END] = qtok("end"), [TT_U8] = qtok("u8"), [TT_U16] = qtok("u16"), [TT_U32] = qtok("u32"), [TT_U64] = qtok("u64") }; /* * Push a token to the token buffer in the preprocessing stage * * @tokbuf: Token buffer to push to * @tok: Token to push * * Returns zero on success */ static int preprocessor_push(struct tokbuf *tokbuf, struct token *tok) { if (tokbuf == NULL || tok == NULL) { return -1; } switch (tok->type) { case TT_IFNDEF: case TT_IFDEF: case TT_DEFINE: break; default: if (tokbuf_push(tokbuf, tok) < 0) { return -1; } } return 0; } static int parser_nom(struct cescal_state *state, struct token *res) { struct token tok; if (state == NULL || res == NULL) { errno = EINVAL; return -1; } switch (state->pass) { case 0: /* Pre-processor */ if (lexer_nom(state, &tok) < 0) { return -1; } printf("* %s\n", tokstr(&tok)); if (preprocessor_push(&state->tokbuf, &tok) < 0) { return -1; } break; case 1: /* Parse */ if (tokbuf_pop(&state->tokbuf, &tok) < 0) { return -1; } break; } *res = tok; return 0; } int parser_parse(struct cescal_state *state) { struct token tok; if (state == NULL) { errno = EINVAL; return -1; } while (parser_nom(state, &tok) == 0) { cc_trace("got token %s\n", tokstr(&tok)); } ++state->pass; return 0; }