summaryrefslogtreecommitdiff
path: root/core/parser.c
diff options
context:
space:
mode:
authorChloe M. <chloe@mirocom.org>2026-05-25 00:12:32 -0500
committerChloe M. <chloe@mirocom.org>2026-05-25 00:12:32 -0500
commitd0d8ae007bd6afcda2b72ab53d3567d660593241 (patch)
treea0c115db252c71192fb226f7d90e1792a39e1b44 /core/parser.c
parent3d74850a2fcb755350d3f6efe4195704e872a294 (diff)
parser: Add initial preprocessing macro parsingmain
Signed-off-by: Chloe M. <chloe@mirocom.org>
Diffstat (limited to 'core/parser.c')
-rw-r--r--core/parser.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/core/parser.c b/core/parser.c
index a438b74..fb8d817 100644
--- a/core/parser.c
+++ b/core/parser.c
@@ -26,6 +26,14 @@
#define tokstr(tok) \
toktab[(tok)->type]
+/* Unexpected token */
+#define utok(tok) \
+ cc_error("unexpected token %s\n", tokstr(tok));
+#define utok1(tok, exp_tt) \
+ cc_error("unexpected token %s, expected %s\n", tokstr(tok), tokstr1(exp_tt))
+
+static int parser_expect(struct cescal_state *state, struct token *res, tt_t exp);
+
/*
* Converts numeric tokens into human readable strings
*/
@@ -58,16 +66,51 @@ static const char *toktab[] = {
[TT_U64] = qtok("u64")
};
+
+/*
+ * Parse a preprocessor define directive
+ */
+static int
+parse_define(struct cescal_state *state, struct token *tok)
+{
+ struct symbol *sym;
+ int error;
+
+ if (state == NULL || tok == NULL) {
+ return -1;
+ }
+
+ if (parser_expect(state, tok, TT_IDENT) < 0) {
+ return -1;
+ }
+
+ /* XXX: Should probably be a warning */
+ if ((sym = symbol_byname(&state->symtab, tok->s)) != NULL) {
+ cc_error("redefinition of symbol %s\n", tok->s);
+ return -1;
+ }
+
+ /* Allocate the symbol */
+ error = symbol_allocate(&state->symtab, tok->s, SYMBOL_NONE, &sym);
+ if (error < 0) {
+ cc_error("[internal]: failed to allocate symbol\n");
+ return -1;
+ }
+
+ return 0;
+}
+
/*
* Push a token to the token buffer in the preprocessing stage
*
+ * @state: Compiler state
* @tokbuf: Token buffer to push to
* @tok: Token to push
*
* Returns zero on success
*/
static int
-preprocessor_push(struct tokbuf *tokbuf, struct token *tok)
+preprocessor_push(struct cescal_state *state, struct tokbuf *tokbuf, struct token *tok)
{
if (tokbuf == NULL || tok == NULL) {
return -1;
@@ -75,8 +118,14 @@ preprocessor_push(struct tokbuf *tokbuf, struct token *tok)
switch (tok->type) {
case TT_IFNDEF:
+ break;
case TT_IFDEF:
+ break;
case TT_DEFINE:
+ if (parse_define(state, tok) < 0) {
+ return -1;
+ }
+
break;
default:
if (tokbuf_push(tokbuf, tok) < 0) {
@@ -114,7 +163,35 @@ parser_nom(struct cescal_state *state, struct token *res)
break;
}
- *res = tok;
+ return 0;
+}
+
+/*
+ * Assert that the next token is of a specific type
+ *
+ * @state: Compiler state
+ * @res: Token result is written here
+ * @exp: Token expedcted
+ *
+ * Returns zero on success
+ */
+static int
+parser_expect(struct cescal_state *state, struct token *res, tt_t exp)
+{
+ if (state == NULL || res == NULL) {
+ return -1;
+ }
+
+ if (parser_nom(state, res) < 0) {
+ cc_error("unexpected end of file\n");
+ return -1;
+ }
+
+ if (res->type != exp) {
+ utok1(res, exp);
+ return -1;
+ }
+
return 0;
}
@@ -129,7 +206,9 @@ parser_parse(struct cescal_state *state)
}
while (parser_nom(state, &tok) == 0) {
- cc_trace("got token %s\n", tokstr(&tok));
+ if (state->pass > 0) {
+ cc_trace("got token %s\n", tokstr(&tok));
+ }
}
++state->pass;