added integers, floats, strings, and identifiers
This commit is contained in:
parent
aa46974753
commit
19a9ef2d20
@ -1,6 +1,6 @@
|
|||||||
* Pinky
|
* Pinky
|
||||||
|
|
||||||
Pinky is a little toy programming language, designed to teach about compilers
|
[[https://pinky-lang.org/][Pinky]] is a little toy programming language, designed to teach about compilers
|
||||||
and interpreters development.
|
and interpreters development.
|
||||||
|
|
||||||
In this repository, you'll find the implementation for both an interpreter and
|
In this repository, you'll find the implementation for both an interpreter and
|
||||||
|
71
src/lexer.c
71
src/lexer.c
@ -6,6 +6,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
/* helper functions */
|
/* helper functions */
|
||||||
char
|
char
|
||||||
advance (struct lexer *l)
|
advance (struct lexer *l)
|
||||||
@ -85,6 +87,66 @@ add_token (enum token_type type, struct lexer *l)
|
|||||||
free (lexeme);
|
free (lexeme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_number (struct lexer *l)
|
||||||
|
{
|
||||||
|
if (!l)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (isdigit (peek (l)))
|
||||||
|
advance (l);
|
||||||
|
|
||||||
|
if (peek (l) == '.' && isdigit (lookahead (1, l)))
|
||||||
|
{
|
||||||
|
/* if it's a float, consume the second part of the number */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
advance (l);
|
||||||
|
}
|
||||||
|
while (isdigit (peek (l)));
|
||||||
|
|
||||||
|
add_token (TOK_FLOAT, l);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_token (TOK_INTEGER, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_string (char quote, struct lexer *l)
|
||||||
|
{
|
||||||
|
if (!l)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (peek (l) != quote && l->cur < buffer_length (l->source))
|
||||||
|
advance (l);
|
||||||
|
|
||||||
|
if (l->cur >= buffer_length (l->source))
|
||||||
|
{
|
||||||
|
/* we reached the end of the file without closing the string */
|
||||||
|
fprintf (stderr,
|
||||||
|
"lexer.c: handle_string - unterminated string on line %d\n",
|
||||||
|
l->line);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
advance (l); /* consume the closing quote */
|
||||||
|
|
||||||
|
add_token (TOK_STRING, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handle_identifier (struct lexer *l)
|
||||||
|
{
|
||||||
|
if (!l)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (isalnum (peek (l)) || peek (l) == '_')
|
||||||
|
advance (l);
|
||||||
|
|
||||||
|
add_token (TOK_IDENTIFIER, l);
|
||||||
|
}
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
struct lexer
|
struct lexer
|
||||||
lexer_create ()
|
lexer_create ()
|
||||||
@ -167,9 +229,12 @@ lexer_lex (struct lexer *l)
|
|||||||
add_token (match ('=', l) ? TOK_GE : TOK_GT, l);
|
add_token (match ('=', l) ? TOK_GE : TOK_GT, l);
|
||||||
else if (c == ':')
|
else if (c == ':')
|
||||||
add_token (match ('=', l) ? TOK_ASSIGN : TOK_COLON, l);
|
add_token (match ('=', l) ? TOK_ASSIGN : TOK_COLON, l);
|
||||||
/* check if it's a number, and determine if it's a float or integer */
|
else if (isdigit (c))
|
||||||
/* check if it's a " or ', and get the string */
|
handle_number (l);
|
||||||
/* check if it's an alpha character or _, then handle identifiers */
|
else if (c == '\'' || c == '"')
|
||||||
|
handle_string (c, l);
|
||||||
|
else if (isalpha (c) || c == '_')
|
||||||
|
handle_identifier (l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
tests/program.pinky
Normal file
10
tests/program.pinky
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# initialise variables
|
||||||
|
pi := 3.141592
|
||||||
|
|
||||||
|
x := 8.23
|
||||||
|
|
||||||
|
if x >= 0 then
|
||||||
|
println ("x is positive")
|
||||||
|
else
|
||||||
|
println ("x is negative")
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user