diff --git a/src/lexer.c b/src/lexer.c index e7d0a66..83d6967 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -87,6 +87,20 @@ add_token (enum token_type type, struct lexer *l) free (lexeme); } +_Bool +s_eq (const char *s1, const char *s2) +{ + if (!s1 || !s2) + return 0; + + size_t len1 = strlen (s1); + size_t len2 = strlen (s2); + if (len1 != len2) + return 0; + + return strncmp (s1, s2, len1) == 0; +} + void handle_number (struct lexer *l) { @@ -144,7 +158,43 @@ handle_identifier (struct lexer *l) while (isalnum (peek (l)) || peek (l) == '_') advance (l); - add_token (TOK_IDENTIFIER, l); + char *slice = buffer_slice (l->start, l->cur, l->source); + if (s_eq (slice, "if")) + add_token (TOK_IF, l); + else if (s_eq (slice, "then")) + add_token (TOK_THEN, l); + else if (s_eq (slice, "else")) + add_token (TOK_ELSE, l); + else if (s_eq (slice, "true")) + add_token (TOK_TRUE, l); + else if (s_eq (slice, "false")) + add_token (TOK_FALSE, l); + else if (s_eq (slice, "and")) + add_token (TOK_AND, l); + else if (s_eq (slice, "or")) + add_token (TOK_OR, l); + else if (s_eq (slice, "while")) + add_token (TOK_WHILE, l); + else if (s_eq (slice, "do")) + add_token (TOK_DO, l); + else if (s_eq (slice, "for")) + add_token (TOK_FOR, l); + else if (s_eq (slice, "func")) + add_token (TOK_FUNC, l); + else if (s_eq (slice, "null")) + add_token (TOK_NULL, l); + else if (s_eq (slice, "end")) + add_token (TOK_END, l); + else if (s_eq (slice, "print")) + add_token (TOK_PRINT, l); + else if (s_eq (slice, "println")) + add_token (TOK_PRINTLN, l); + else if (s_eq (slice, "ret")) + add_token (TOK_RET, l); + else + add_token (TOK_IDENTIFIER, l); + + free (slice); } /* public functions */ @@ -182,9 +232,6 @@ lexer_lex (struct lexer *l) l->line++; else if (c == ' ' || c == '\t' || c == '\r') continue; - else if (c == '#') - while (peek (l) != '\n' && !(l->cur >= buffer_length (l->source))) - advance (l); /* single-character tokens */ else if (c == '(') add_token (TOK_LPAREN, l); @@ -205,7 +252,18 @@ lexer_lex (struct lexer *l) else if (c == '+') add_token (TOK_PLUS, l); else if (c == '-') - add_token (TOK_MINUS, l); + { + if (match ('-', l)) + { + while (peek (l) != '\n' + && !(l->cur >= buffer_length (l->source))) + advance (l); + + continue; + } + + add_token (TOK_MINUS, l); + } else if (c == '*') add_token (TOK_STAR, l); else if (c == '^') diff --git a/src/token.h b/src/token.h index bceaa74..cfb513a 100644 --- a/src/token.h +++ b/src/token.h @@ -5,6 +5,7 @@ enum token_type { + /* single character tokens */ TOK_LPAREN, TOK_RPAREN, TOK_LCURLY, @@ -26,6 +27,7 @@ enum token_type TOK_GT, TOK_LT, + /* multiple character tokens */ TOK_GE, TOK_LE, TOK_NE, @@ -34,11 +36,13 @@ enum token_type TOK_GTGT, TOK_LTLT, + /* types */ TOK_IDENTIFIER, TOK_STRING, TOK_INTEGER, TOK_FLOAT, + /* keywords */ TOK_IF, TOK_THEN, TOK_ELSE, diff --git a/src/utils/buffer.c b/src/utils/buffer.c index 5ccfdc2..1a5138a 100644 --- a/src/utils/buffer.c +++ b/src/utils/buffer.c @@ -112,6 +112,39 @@ buffer_read (const char *path, struct buffer *b) return 1; } +_Bool +buffer_eq (const char *s, struct buffer *b) +{ + if (!s || !b) + return 0; + + size_t slen = strlen (s); + if (slen != b->len) + return 0; + + return strncmp (s, b->buf, slen) == 0; +} + +char * +buffer_slice (unsigned int start, unsigned int end, struct buffer *b) +{ + if (!b) + return NULL; + + if (end > buffer_length (b)) + return NULL; + + char *str = calloc ((end - start) + 1, sizeof (char)); + if (!str) + return NULL; + + char *bstart = buffer_get (b) + start; + strncpy (str, bstart, end - start); + str[end - start] = '\0'; + + return str; +} + void buffer_free (struct buffer *b) { diff --git a/src/utils/buffer.h b/src/utils/buffer.h index a8b87e1..7df5641 100644 --- a/src/utils/buffer.h +++ b/src/utils/buffer.h @@ -15,6 +15,8 @@ void buffer_append (const char *s, struct buffer *b); void buffer_printf (struct buffer *b, const char *fmt, ...); char *buffer_get (struct buffer *b); _Bool buffer_read (const char *path, struct buffer *b); +_Bool buffer_eq (const char *s, struct buffer *b); +char *buffer_slice (unsigned int start, unsigned int end, struct buffer *b); void buffer_free (struct buffer *b); size_t buffer_length (struct buffer *b); diff --git a/tests/expr.pinky b/tests/expr.pinky index bf5b0e0..63ec10c 100644 --- a/tests/expr.pinky +++ b/tests/expr.pinky @@ -1,2 +1,2 @@ -# Evaluate a simple expression +-- Evaluate a simple expression 2 + 3 \ No newline at end of file diff --git a/tests/multichtokens.pinky b/tests/multichtokens.pinky index 2dd9d70..e1d2012 100644 --- a/tests/multichtokens.pinky +++ b/tests/multichtokens.pinky @@ -1,26 +1,26 @@ -# the equals token: +-- the equals token: == -# the not equals token: +-- the not equals token: ~= -# the logical not operator +-- the logical not operator ~ -# less or equal +-- less or equal <= -# less than +-- less than < -# greater or equal +-- greater or equal >= -# greater than +-- greater than > -# assignment +-- assignment := -# colon +-- colon : \ No newline at end of file diff --git a/tests/program.pinky b/tests/program.pinky index 9c38c73..2e4a792 100644 --- a/tests/program.pinky +++ b/tests/program.pinky @@ -1,4 +1,4 @@ -# initialise variables +-- initialise variables pi := 3.141592 x := 8.23 diff --git a/tests/singletokens.pinky b/tests/singletokens.pinky index ba48353..784c55c 100644 --- a/tests/singletokens.pinky +++ b/tests/singletokens.pinky @@ -1,3 +1,3 @@ -# this file is just to test single character tokens +-- this file is just to test single character tokens { } [ ] ( ) . , + - * ^ / ; ? % \ No newline at end of file