diff options
| author | Chloe M. <chloe@aptel.org> | 2026-08-23 09:12:47 +0000 |
|---|---|---|
| committer | Chloe M. <chloe@aptel.org> | 2026-08-23 09:12:47 +0000 |
| commit | f3df011c18821ee6b09f9c2ee8fd48163ed92096 (patch) | |
| tree | 733c63e7689d6a81a3bf029509b009e1d7a7bedc | |
| parent | be90a06efa50496ce4a7fd3f79970efda30498cf (diff) | |
core: lexer+parser: Handle integer literals
Signed-off-by: Chloe M. <chloe@aptel.org>
| -rw-r--r-- | conf/defconf-00.conf | 1 | ||||
| -rw-r--r-- | core/lexer.c | 57 | ||||
| -rw-r--r-- | core/parser.c | 4 | ||||
| -rw-r--r-- | head/defconf/token.h | 2 |
4 files changed, 64 insertions, 0 deletions
diff --git a/conf/defconf-00.conf b/conf/defconf-00.conf index f2b152f..028c8c5 100644 --- a/conf/defconf-00.conf +++ b/conf/defconf-00.conf @@ -1,2 +1,3 @@ define MEOW_YES true define MEOW_NO false +define MEOW_COUNT 3 diff --git a/core/lexer.c b/core/lexer.c index ac5194f..59aaa13 100644 --- a/core/lexer.c +++ b/core/lexer.c @@ -13,6 +13,7 @@ /* Constants */ #define MAX_KW_LEN 32 +#define MAX_NUM_LEN 20 /* * Returns true if the given character is a whitespace character @@ -126,6 +127,51 @@ lexer_scan_ident(struct defconf_state *state, int lc) } /* + * Scan a number + * + * @state: Defconf state + * @lc: Last character provided + * @result: Result is written here + */ +static int +lexer_scan_num(struct defconf_state *state, int lc, struct token *result) +{ + char c, buf[MAX_NUM_LEN + 1]; + size_t bufind = 0; + + if (state == NULL || result == NULL) { + return -1; + } + + if (!isdigit(lc)) { + return -1; + } + + buf[bufind++] = lc; + for (;;) { + if (bufind >= sizeof(buf) - 1) { + trace_fatal(state, "digits exceed maximum length\n"); + return -1; + } + + c = lexer_nom(state, false); + if (!isdigit(c)) { + lexer_putback(state, c); + buf[bufind] = '\0'; + + /* Set the token */ + result->type = TT_INTLIT; + result->v = atoi(buf); + return 0; + } + + buf[bufind++] = c; + } + + return -1; +} + +/* * Check if a keyword matches against known keywords * * @kw: Keyword to check @@ -172,6 +218,7 @@ lexer_scan(struct defconf_state *state, struct token *result) { int c; char *ident; + int error; if (state == NULL || result == NULL) { return -1; @@ -192,6 +239,16 @@ lexer_scan(struct defconf_state *state, struct token *result) return 0; } + /* Is this a digit? */ + if (isdigit(c)) { + error = lexer_scan_num(state, c, result); + if (error < 0) { + return -1; + } + + return 0; + } + trace_fatal(state, "unexpected token '%c'\n", c); return -1; } diff --git a/core/parser.c b/core/parser.c index 698691e..79fda93 100644 --- a/core/parser.c +++ b/core/parser.c @@ -50,6 +50,10 @@ token_to_data(struct token *tok, struct data_value *result) result->v = 0; result->type = DATA_TYPE_INT; return 0; + case TT_INTLIT: + result->v = tok->v; + result->type = DATA_TYPE_INT; + return 0; default: return -1; } diff --git a/head/defconf/token.h b/head/defconf/token.h index 4a69311..9db1a7e 100644 --- a/head/defconf/token.h +++ b/head/defconf/token.h @@ -25,12 +25,14 @@ typedef enum { * @type: Token type * @c: Associated character * @s: Associated string + * @v: Associated integer */ struct token { tt_t type; union { char c; char *s; + size_t v; }; }; |
