From 9bf5da82de7c19360c291d990814128a7b86c92e Mon Sep 17 00:00:00 2001 From: "Chloe M." Date: Sun, 23 Aug 2026 06:37:47 +0000 Subject: core: parser: Parse and emit define directives Signed-off-by: Chloe M. --- core/parser.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) (limited to 'core/parser.c') diff --git a/core/parser.c b/core/parser.c index 727d5e1..e568504 100644 --- a/core/parser.c +++ b/core/parser.c @@ -6,6 +6,8 @@ #include "defconf/parser.h" #include "defconf/lexer.h" #include "defconf/token.h" +#include "defconf/data.h" +#include "defconf/emit.h" /* Symbolic token */ #define SYMTOK(TOKSTR) \ @@ -31,17 +33,129 @@ static const char *toktab[_TT_MAX] = { [TT_IDENT] = SYMTOK("ident") }; +static int +token_to_data(struct token *tok, struct data_value *result) +{ + if (tok == NULL || result == NULL) { + return -1; + } + + switch (tok->type) { + case TT_TRUE: + result->v = 1; + result->type = DATA_TYPE_INT; + return 0; + case TT_FALSE: + result->v = 0; + result->type = DATA_TYPE_INT; + return 0; + default: + return -1; + } + + return -1; +} + +/* + * Assert that the next token is of a specific type + * + * @state: Defconf state + * @tok: Last token + * @exp: Expected token + */ +static int +parse_expect(struct defconf_state *state, struct token *tok, tt_t exp) +{ + int error; + + if (state == NULL || tok == NULL) { + return -1; + } + + /* Try to grab the next token */ + if ((error = lexer_scan(state, tok)) < 0) { + printf("fatal: expected '%s', got eof\n", TOKSTR(exp)); + return error; + } + + if (tok->type != exp) { + printf("fatal: expected '%s', got %s instead\n", + TOKSTR(exp), TOKSTR(tok->type)); + return -1; + } + + return 0; +} + +/* + * Parse a define directive + * + * @state: Defconf state + * @tok: Last token + * + * Returns zero on success + */ +static int +parse_define(struct defconf_state *state, struct token *tok) +{ + struct data_value value; + char *ident; + int error; + + if (state == NULL || tok == NULL) { + return -1; + } + + /* Expect an identifier */ + if ((error = parse_expect(state, tok, TT_IDENT)) < 0) { + return error; + } + + /* Save the identifier */ + ident = tok->s; + + /* Scan the value */ + if ((error = lexer_scan(state, tok)) < 0) { + printf("fatal: expected value, got eof\n"); + return error; + } + + /* Convert token to data */ + if ((error = token_to_data(tok, &value)) < 0) { + printf("fatal: got bad data [%s]\n", TOKSTR(tok->type)); + return error; + } + + /* Emit the define */ + if ((error = emit_data(ident, &value)) < 0) { + return error; + } + + return 0; +} + int parse_begin(struct defconf_state *state) { struct token tok; + int error; if (state == NULL) { return -1; } while (lexer_scan(state, &tok) == 0) { - printf("got %s\n", TOKSTR(tok.type)); + switch (tok.type) { + case TT_DEFINE: + if ((error = parse_define(state, &tok)) < 0) { + return error; + } + + break; + default: + printf("fatal: got unexpected token: %s\n", TOKSTR(tok.type)); + return -1; + } } return 0; -- cgit v1.2.3