diff --git a/Readme.org b/Readme.org index bc017d2..0687960 100644 --- a/Readme.org +++ b/Readme.org @@ -1,6 +1,6 @@ * 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. In this repository, you'll find the implementation for both an interpreter and diff --git a/src/lexer.c b/src/lexer.c index 9f7eca9..e7d0a66 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -6,6 +6,8 @@ #include #include +#include + /* helper functions */ char advance (struct lexer *l) @@ -85,6 +87,66 @@ add_token (enum token_type type, struct lexer *l) 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 */ struct lexer lexer_create () @@ -167,9 +229,12 @@ lexer_lex (struct lexer *l) add_token (match ('=', l) ? TOK_GE : TOK_GT, l); else if (c == ':') add_token (match ('=', l) ? TOK_ASSIGN : TOK_COLON, l); - /* check if it's a number, and determine if it's a float or integer */ - /* check if it's a " or ', and get the string */ - /* check if it's an alpha character or _, then handle identifiers */ + else if (isdigit (c)) + handle_number (l); + else if (c == '\'' || c == '"') + handle_string (c, l); + else if (isalpha (c) || c == '_') + handle_identifier (l); } } diff --git a/tests/program.pinky b/tests/program.pinky new file mode 100644 index 0000000..9c38c73 --- /dev/null +++ b/tests/program.pinky @@ -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 \ No newline at end of file