aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-09-12 11:47:57 +0200
committerHimbeer <himbeer@disroot.org>2024-09-12 12:34:26 +0200
commitfba23922428dae65c16f958f356b12427454f4d5 (patch)
tree29d822abab201b4a52ad7bf59150e92f776f2371 /src
parent8712349ebc414cc4312cf44553f9363cae7b06e0 (diff)
Implement lexical analysis of number literals
Diffstat (limited to 'src')
-rw-r--r--src/lex.c40
-rw-r--r--src/main.c5
2 files changed, 43 insertions, 2 deletions
diff --git a/src/lex.c b/src/lex.c
index a5e1a6a..0c8ccf6 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -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) {
diff --git a/src/main.c b/src/main.c
index 020fa62..5e72619 100644
--- a/src/main.c
+++ b/src/main.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]);
}