feat: started project and lexer

This commit is contained in:
Jef Roosens 2024-03-04 12:18:48 +01:00
commit a6c17eff5f
Signed by: Jef Roosens
GPG key ID: B75D4F293C7052DB
8 changed files with 344 additions and 0 deletions

View file

@ -0,0 +1,40 @@
#ifndef MRK_LEXER_INTERNAL
#define MRK_LEXER_INTERNAL
#include "mrk/lexer.h"
struct mrk_lexer {
struct {
const char *s;
size_t len;
} buf;
struct {
size_t line;
size_t line_index;
size_t buf_index;
} pos;
struct {
size_t start;
size_t end;
} token;
};
/**
* Return the next character that would be consumed by a call to advance. At the
* end of the buffer, this value is nul.
*/
char mrk_lexer_peek(mrk_lexer *lexer);
/**
* Advance the current position by one character, adding the new character to
* the curent token's context and returning it.
*/
char mrk_lexer_advance(mrk_lexer *lexer);
/**
* Output the currently matched token to the token struct with the given type,
* and reset the lexer's tracked token.
*/
void mrk_lexer_emit(mrk_token *out, mrk_lexer *lexer, mrk_token_type type);
#endif

73
src/lexer/lexer.c Normal file
View file

@ -0,0 +1,73 @@
#include "mrk/lexer_internal.h"
mrk_err mrk_lexer_init(mrk_lexer **out) {
MRK_CALLOC(out, 1, sizeof(mrk_lexer));
return mrk_err_ok;
}
void mrk_lexer_open(mrk_lexer *lexer, const char *buf, size_t len) {
lexer->buf.s = buf;
lexer->buf.len = len;
lexer->pos.line = 0;
lexer->pos.buf_index = 0;
lexer->token.start = 0;
lexer->token.end = 0;
}
bool mrk_lexer_at_end(const mrk_lexer *lexer) {
return (lexer->buf.len > 0 && lexer->pos.buf_index == lexer->buf.len) ||
(lexer->buf.s[lexer->pos.buf_index] == '\0');
}
char mrk_lexer_advance(mrk_lexer *lexer) {
if (mrk_lexer_at_end(lexer)) {
return '\0';
}
char c = lexer->buf.s[lexer->pos.buf_index];
// A newline is still part of the previous line, so if the last character was
// a newline, we now go to the next line
if (lexer->buf.s[lexer->pos.buf_index] == '\0') {
lexer->pos.line++;
lexer->pos.line_index = 0;
} else {
lexer->pos.line_index++;
}
lexer->pos.buf_index++;
lexer->token.end++;
return c;
}
char mrk_lexer_peek(mrk_lexer *lexer) {
if (mrk_lexer_at_end(lexer)) {
return '\0';
}
return lexer->buf.s[lexer->pos.buf_index];
}
void mrk_lexer_emit(mrk_token *out, mrk_lexer *lexer, mrk_token_type type) {
out->type = type;
out->start = lexer->token.start;
out->start = lexer->token.end;
lexer->token.start = lexer->token.end;
}
mrk_lexer_err mrk_lexer_next(mrk_token *out, mrk_lexer *lexer) {
if (mrk_lexer_at_end(lexer)) {
return mrk_lexer_err_done;
}
switch (mrk_lexer_advance(lexer)) {
case '#':
mrk_lexer_emit(out, lexer, mrk_token_type_pound);
break;
}
return mrk_lexer_err_ok;
}