added support for keywords

This commit is contained in:
ghostie 2025-07-04 16:14:05 -05:00
parent 19a9ef2d20
commit 52dc4618c7
8 changed files with 114 additions and 17 deletions

View File

@ -87,6 +87,20 @@ add_token (enum token_type type, struct lexer *l)
free (lexeme); 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 void
handle_number (struct lexer *l) handle_number (struct lexer *l)
{ {
@ -144,7 +158,43 @@ handle_identifier (struct lexer *l)
while (isalnum (peek (l)) || peek (l) == '_') while (isalnum (peek (l)) || peek (l) == '_')
advance (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 */ /* public functions */
@ -182,9 +232,6 @@ lexer_lex (struct lexer *l)
l->line++; l->line++;
else if (c == ' ' || c == '\t' || c == '\r') else if (c == ' ' || c == '\t' || c == '\r')
continue; continue;
else if (c == '#')
while (peek (l) != '\n' && !(l->cur >= buffer_length (l->source)))
advance (l);
/* single-character tokens */ /* single-character tokens */
else if (c == '(') else if (c == '(')
add_token (TOK_LPAREN, l); add_token (TOK_LPAREN, l);
@ -205,7 +252,18 @@ lexer_lex (struct lexer *l)
else if (c == '+') else if (c == '+')
add_token (TOK_PLUS, l); add_token (TOK_PLUS, l);
else if (c == '-') 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 == '*') else if (c == '*')
add_token (TOK_STAR, l); add_token (TOK_STAR, l);
else if (c == '^') else if (c == '^')

View File

@ -5,6 +5,7 @@
enum token_type enum token_type
{ {
/* single character tokens */
TOK_LPAREN, TOK_LPAREN,
TOK_RPAREN, TOK_RPAREN,
TOK_LCURLY, TOK_LCURLY,
@ -26,6 +27,7 @@ enum token_type
TOK_GT, TOK_GT,
TOK_LT, TOK_LT,
/* multiple character tokens */
TOK_GE, TOK_GE,
TOK_LE, TOK_LE,
TOK_NE, TOK_NE,
@ -34,11 +36,13 @@ enum token_type
TOK_GTGT, TOK_GTGT,
TOK_LTLT, TOK_LTLT,
/* types */
TOK_IDENTIFIER, TOK_IDENTIFIER,
TOK_STRING, TOK_STRING,
TOK_INTEGER, TOK_INTEGER,
TOK_FLOAT, TOK_FLOAT,
/* keywords */
TOK_IF, TOK_IF,
TOK_THEN, TOK_THEN,
TOK_ELSE, TOK_ELSE,

View File

@ -112,6 +112,39 @@ buffer_read (const char *path, struct buffer *b)
return 1; 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 void
buffer_free (struct buffer *b) buffer_free (struct buffer *b)
{ {

View File

@ -15,6 +15,8 @@ void buffer_append (const char *s, struct buffer *b);
void buffer_printf (struct buffer *b, const char *fmt, ...); void buffer_printf (struct buffer *b, const char *fmt, ...);
char *buffer_get (struct buffer *b); char *buffer_get (struct buffer *b);
_Bool buffer_read (const char *path, 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); void buffer_free (struct buffer *b);
size_t buffer_length (struct buffer *b); size_t buffer_length (struct buffer *b);

View File

@ -1,2 +1,2 @@
# Evaluate a simple expression -- Evaluate a simple expression
2 + 3 2 + 3

View File

@ -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
: :

View File

@ -1,4 +1,4 @@
# initialise variables -- initialise variables
pi := 3.141592 pi := 3.141592
x := 8.23 x := 8.23

View File

@ -1,3 +1,3 @@
# this file is just to test single character tokens -- this file is just to test single character tokens
{ } [ ] ( ) . , + { } [ ] ( ) . , +
- * ^ / ; ? % - * ^ / ; ? %