Compare commits
No commits in common. "ab690f4bb5ad16693a68630bf9bc8e5513b8af8f" and "2e773218be00463a27ad813d07c574f306e684d6" have entirely different histories.
ab690f4bb5
...
2e773218be
|
|
@ -16,8 +16,6 @@ typedef enum {
|
||||||
TOKEN_RBRACE,
|
TOKEN_RBRACE,
|
||||||
TOKEN_LBRACKET,
|
TOKEN_LBRACKET,
|
||||||
TOKEN_RBRACKET,
|
TOKEN_RBRACKET,
|
||||||
TOKEN_CHARACTER,
|
|
||||||
TOKEN_STRING,
|
|
||||||
} TokenType;
|
} TokenType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
52
src/lexer.c
52
src/lexer.c
|
|
@ -25,18 +25,18 @@ static char peek(Lexer *lexer) {
|
||||||
return lexer->source[lexer->pos];
|
return lexer->source[lexer->pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
static char far_peek(Lexer *lexer, size_t index) {
|
static char double_peek(Lexer *lexer) {
|
||||||
return lexer->source[lexer->pos + index];
|
return lexer->source[lexer->pos+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void advance(Lexer *lexer) {
|
static char 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++;
|
||||||
}
|
}
|
||||||
lexer->source[lexer->pos++];
|
return lexer->source[lexer->pos++];
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -56,20 +56,6 @@ 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 == '_';
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +77,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) == '/' && far_peek(lexer, 1) == '/')
|
if (peek(lexer) == '/' && double_peek(lexer) == '/')
|
||||||
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);
|
||||||
|
|
@ -122,39 +108,13 @@ TokenResult lexer_next(Lexer *lexer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (is_digit_char(peek(lexer), flags)) advance(lexer);
|
while (is_digit_char(peek(lexer), flags)) advance(lexer);
|
||||||
if (is_digit_after(peek(lexer))) {
|
if (isspace(peek(lexer)) || peek(lexer) == ';' || peek(lexer) == '\0' || peek(lexer) == ')' || peek(lexer) == '(' || 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);
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,11 @@
|
||||||
#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", "CHARACTER",
|
"RBRACE", "LBRACKET", "RBRACKET"
|
||||||
"STRING"
|
|
||||||
}[token.type],
|
}[token.type],
|
||||||
(int)token.length, token.start
|
(int)token.length, token.start
|
||||||
);
|
);
|
||||||
|
|
@ -47,9 +46,6 @@ 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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue