Compare commits

...

3 Commits

3 changed files with 54 additions and 8 deletions

View File

@ -16,6 +16,8 @@ typedef enum {
TOKEN_RBRACE,
TOKEN_LBRACKET,
TOKEN_RBRACKET,
TOKEN_CHARACTER,
TOKEN_STRING,
} TokenType;
typedef struct {

View File

@ -25,18 +25,18 @@ static char peek(Lexer *lexer) {
return lexer->source[lexer->pos];
}
static char double_peek(Lexer *lexer) {
return lexer->source[lexer->pos+1];
static char far_peek(Lexer *lexer, size_t index) {
return lexer->source[lexer->pos + index];
}
static char advance(Lexer *lexer) {
static void advance(Lexer *lexer) {
if (lexer->source[lexer->pos] == '\n') {
lexer->line++;
lexer->column = 1;
} else {
lexer->column++;
}
return lexer->source[lexer->pos++];
lexer->source[lexer->pos++];
}
typedef enum {
@ -56,6 +56,20 @@ static char is_digit_char(char c, DigitFlags flags) {
return isdigit(c) || c == '_';
}
static char is_digit_after(char c) {
return
isspace(c) ||
c == '\0' ||
c == ',' ||
c == ')' ||
c == '(' ||
c == '}' ||
c == '{' ||
c == ']' ||
c == '[' ||
c == ';';
}
static char is_identifier_start(char c) {
return isalpha(c) || c == '_';
}
@ -77,7 +91,7 @@ TokenResult lexer_next(Lexer *lexer) {
while (isspace(peek(lexer)) || peek(lexer) == '/') {
// Skip Comments
if (peek(lexer) == '/' && double_peek(lexer) == '/')
if (peek(lexer) == '/' && far_peek(lexer, 1) == '/')
while (peek(lexer) != '\n') advance(lexer);
// Skip whitespace
while (isspace(peek(lexer))) advance(lexer);
@ -108,13 +122,39 @@ TokenResult lexer_next(Lexer *lexer) {
}
}
while (is_digit_char(peek(lexer), flags)) advance(lexer);
if (isspace(peek(lexer)) || peek(lexer) == ';' || peek(lexer) == '\0' || peek(lexer) == ')' || peek(lexer) == '(' || peek(lexer) == ',') {
if (is_digit_after(peek(lexer))) {
return lexer_result(lexer, TOKEN_NUMBER, start, start_line);
} else {
return lexer_error(lexer, "Invalid number format", start, start_line);
}
}
// Characters
if (c == '\'') {
advance(lexer); // Opening `'`
if (peek(lexer) == '\\') advance(lexer); // Slash
advance(lexer); // Char
if (peek(lexer) == '\'') {
advance(lexer); // Closing `'`
return lexer_result(lexer, TOKEN_CHARACTER, start, start_line);
} else return lexer_error(lexer, "Invalid character format", start, start_line);
}
// Strings
if (c == '"') {
advance(lexer);
while (peek(lexer) != '"') {
if (peek(lexer) == '\\') {
advance(lexer);
} else if (peek(lexer) == '\n') {
return lexer_error(lexer, "Invalid string format", start, start_line);
}
advance(lexer);
}
advance(lexer);
return lexer_result(lexer, TOKEN_STRING, start, start_line);
}
// Identifiers
if (is_identifier_start(c)) {
while (is_identifier_char(peek(lexer))) advance(lexer);

View File

@ -4,11 +4,12 @@
#include "sync/lexer.h"
static void print_token(Token token) {
printf("Token: %-15s | Text: '%.*s'\n",
printf("Token: %-15s | Text: %.*s\n",
(const char *[]){
"EOF", "IDENTIFIER", "NUMBER", "OPERATOR",
"LPAREN", "RPAREN", "SEMICOLON", "LBRACE",
"RBRACE", "LBRACKET", "RBRACKET"
"RBRACE", "LBRACKET", "RBRACKET", "CHARACTER",
"STRING"
}[token.type],
(int)token.length, token.start
);
@ -46,6 +47,9 @@ int main(void) {
fprintf(stderr, "Error: %s\n", result.error.message);
fprintf(stderr, "\tFilename: %s\n", result.error.file_info.filename);
fprintf(stderr, "\tLine: %zi\n", result.error.file_info.line);
fprintf(stderr, "\tColumn: %zi\n", result.error.file_info.column);
free(source);
return 1;
}
} while (result.type != SYNC_ERROR && result.result.type != TOKEN_EOF);