Compare commits

...

3 Commits

3 changed files with 54 additions and 8 deletions

View File

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

View File

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

View File

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