added support for keywords
This commit is contained in:
parent
19a9ef2d20
commit
52dc4618c7
68
src/lexer.c
68
src/lexer.c
@ -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 == '^')
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
# Evaluate a simple expression
|
-- Evaluate a simple expression
|
||||||
2 + 3
|
2 + 3
|
@ -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
|
||||||
:
|
:
|
@ -1,4 +1,4 @@
|
|||||||
# initialise variables
|
-- initialise variables
|
||||||
pi := 3.141592
|
pi := 3.141592
|
||||||
|
|
||||||
x := 8.23
|
x := 8.23
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
# this file is just to test single character tokens
|
-- this file is just to test single character tokens
|
||||||
{ } [ ] ( ) . , +
|
{ } [ ] ( ) . , +
|
||||||
- * ^ / ; ? %
|
- * ^ / ; ? %
|
Loading…
x
Reference in New Issue
Block a user