diff options
author | Himbeer <himbeer@disroot.org> | 2024-09-12 11:47:57 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-09-12 12:34:26 +0200 |
commit | fba23922428dae65c16f958f356b12427454f4d5 (patch) | |
tree | 29d822abab201b4a52ad7bf59150e92f776f2371 /src | |
parent | 8712349ebc414cc4312cf44553f9363cae7b06e0 (diff) |
Implement lexical analysis of number literals
Diffstat (limited to 'src')
-rw-r--r-- | src/lex.c | 40 | ||||
-rw-r--r-- | src/main.c | 5 |
2 files changed, 43 insertions, 2 deletions
@@ -2,7 +2,6 @@ #include <assert.h> #include <ctype.h> -#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -147,7 +146,7 @@ search(const char *buf, int bound) static enum lexical_token lex_ident(struct lexer *lexer, struct token *out) { - bool isident; + bool isident = false; uint32_t c; while ((c = next(lexer)) != C_EOF) { @@ -175,6 +174,38 @@ lex_ident(struct lexer *lexer, struct token *out) return out->token; } +static enum lexical_token +lex_number(struct lexer *lexer, struct token *out) +{ + bool isfloat = false; + + uint32_t c; + while ((c = next(lexer)) != C_EOF) { + if (c >= 0x7F || (!isdigit(c) && c != '_' && c != '.' + && c != 'x')) { + unget(lexer); + break; + } + if (c == '.') { + isfloat = true; + } + if (c != '_') { + push(lexer, c); + } + } + + out->info.num.isfloat = isfloat; + if (isfloat) { + out->info.num.value.floatingpt = atof(lexer->buf); + } else { + out->info.num.value.integer = strtol(lexer->buf, NULL, 0); + } + + clear(lexer); + out->token = T_NUMBER; + return out->token; +} + enum lexical_token lex(struct lexer *lexer, struct token *out) { @@ -195,6 +226,11 @@ lex(struct lexer *lexer, struct token *out) return lex_ident(lexer, out); } + if (c <= 0x7F && isdigit(c)) { + push(lexer, c); + return lex_number(lexer, out); + } + uint32_t ch; switch (c) { @@ -45,6 +45,11 @@ main(int argc, char *argv[]) printf("%d", token.token); if (token.token == T_IDENT || token.token == T_NAME) { printf(" %s", token.info.str); + } else if (token.token == T_NUMBER + && token.info.num.isfloat) { + printf(" %f", token.info.num.value.floatingpt); + } else if (token.token == T_NUMBER) { + printf(" %d", token.info.num.value.integer); } else { printf(" %s", tokens[token.token]); } |