Compare commits
No commits in common. "933418895ead487572789346841d3d0aaa77972a" and "63f5064ba95c5baa1c8cb8824694715d4251bed4" have entirely different histories.
933418895e
...
63f5064ba9
@ -2,8 +2,12 @@
|
||||
#define LEXER_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "token.h"
|
||||
|
||||
#define TOKENS_MAX 32
|
||||
@ -20,7 +24,7 @@ typedef enum {
|
||||
// Lexer: converts text to tokens.
|
||||
typedef struct {
|
||||
char* src; // The source text.
|
||||
size_t srcln; // The number of source chars.
|
||||
size_t srcl; // The number of source chars.
|
||||
char* cchar; // The current character.
|
||||
Token** tokens; // The tokens produced.
|
||||
size_t ntokens; // The number of tokens.
|
||||
@ -51,10 +55,4 @@ void lexer_inc(Lexer* lexer);
|
||||
// Add a token to the lexer.
|
||||
void lexer_add_token(Lexer* lexer, Token* token);
|
||||
|
||||
// Returns a dynamic string representation of the Lexer.
|
||||
Dstr* lexer_to_dstr(Lexer* lexer);
|
||||
|
||||
// Returns a string representation of the LexerState.
|
||||
char* lexer_state_to_str(LexerState s);
|
||||
|
||||
#endif
|
||||
|
@ -1,28 +1,20 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#ifdef DBG // Debug macros
|
||||
#ifdef DBG
|
||||
|
||||
// Log a message.
|
||||
#define log_dbg(msg) \
|
||||
printf("\033[37;1mdbg\033[0m:\033[37;5m%s\033[0m:\033[32m " msg \
|
||||
"\033[0m\n", \
|
||||
__func__);
|
||||
|
||||
// Log a message with formatting.
|
||||
#define log_dbgf(msg, ...) \
|
||||
printf("\033[37;1mdbg\033[0m:\033[37;5m%s\033[0m:\033[32m " msg \
|
||||
"\033[0m\n", \
|
||||
__func__, __VA_ARGS__);
|
||||
|
||||
#else // ifdef DBG
|
||||
#else
|
||||
#define log_dbg(msg)
|
||||
#endif // ifdef DBG else
|
||||
|
||||
// Maximum size of a string containing only an int.
|
||||
#define MAXSTRINTSZ ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
|
||||
|
||||
// Maximum size of a string containing only a size_t.
|
||||
#define MAXSTRIZE_TSZ ((CHAR_BIT * sizeof(size_t) - 1) / 3 + 2)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
51
src/lexer.c
51
src/lexer.c
@ -1,17 +1,14 @@
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "include/lexer.h"
|
||||
#include "include/dstr.h"
|
||||
#include "include/util.h"
|
||||
|
||||
Lexer* lexer_init(char* src) {
|
||||
Lexer* lexer = malloc(sizeof(Lexer));
|
||||
|
||||
lexer->src = src;
|
||||
lexer->srcln = strlen(src);
|
||||
lexer->srcl = strlen(src);
|
||||
lexer->cchar = lexer->src;
|
||||
|
||||
lexer->tokens = calloc(TOKENS_MAX, sizeof(Token*));
|
||||
@ -43,18 +40,15 @@ void lexer_lex(Lexer* lexer) {
|
||||
void lexer_do_confused(Lexer* lexer) {
|
||||
log_dbgf("lexer @ %p entered confused mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
|
||||
|
||||
if (isdigit(*lexer->cchar)) {
|
||||
lexer->state = LEXER_STATE_NUM;
|
||||
lexer_do_number(lexer);
|
||||
} else {
|
||||
lexer->state = LEXER_STATE_CALL;
|
||||
lexer_do_call(lexer);
|
||||
}
|
||||
lexer->state = LEXER_STATE_CONFUSED;
|
||||
if (isdigit(*lexer->cchar)) lexer_do_number(lexer);
|
||||
else lexer_do_call(lexer);
|
||||
}
|
||||
|
||||
void lexer_do_number(Lexer* lexer) {
|
||||
log_dbgf("lexer @ %p entered number mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
|
||||
|
||||
lexer->state = LEXER_STATE_NUM;
|
||||
// Size of the number string.
|
||||
size_t numsz;
|
||||
|
||||
@ -69,19 +63,21 @@ void lexer_do_number(Lexer* lexer) {
|
||||
num[numsz] = '\0';
|
||||
|
||||
lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, num, 1));
|
||||
lexer->state = LEXER_STATE_CONFUSED;
|
||||
}
|
||||
|
||||
void lexer_do_call(Lexer* lexer) {
|
||||
log_dbgf("lexer @ %p entered call mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
|
||||
|
||||
lexer->state = LEXER_STATE_CALL;
|
||||
// Size of the call string.
|
||||
size_t callsz;
|
||||
|
||||
// Where the call string starts.
|
||||
char* start = lexer->cchar;
|
||||
|
||||
for (callsz = 0; *lexer->cchar && (!isdigit(*lexer->cchar)); callsz++)
|
||||
for (; *lexer->cchar && (isblank(lexer->cchar) || *lexer->cchar == '\n'); lexer_inc(lexer));
|
||||
|
||||
for (callsz = 0; *lexer->cchar && isalpha(*lexer->cchar); callsz++)
|
||||
lexer_inc(lexer);
|
||||
|
||||
char* call = malloc(callsz + 1);
|
||||
@ -89,8 +85,6 @@ void lexer_do_call(Lexer* lexer) {
|
||||
call[callsz] = '\0';
|
||||
|
||||
lexer_add_token(lexer, token_init(TOKEN_TYPE_CALL, call, 1));
|
||||
|
||||
lexer->state = LEXER_STATE_CONFUSED;
|
||||
}
|
||||
|
||||
void lexer_inc(Lexer* lexer) {
|
||||
@ -106,30 +100,3 @@ void lexer_add_token(Lexer* lexer, Token* token) {
|
||||
}
|
||||
}
|
||||
|
||||
Dstr* lexer_to_dstr(Lexer* lexer) {
|
||||
Dstr* str = dstr_init();
|
||||
|
||||
size_t titlesz = sizeof("Lexer @ 0x00000000");
|
||||
char title[titlesz];
|
||||
sprintf(title, "Lexer @ %p", lexer);
|
||||
dstr_append(str, title, titlesz - 1);
|
||||
|
||||
size_t ln = snprintf(NULL, 0, "srcln: %ld", lexer->srcln);
|
||||
char src_sz[ln + 1];
|
||||
snprintf(src_sz, ln + 1, "srcln: %ld", lexer->srcln);
|
||||
dstr_append(str, src_sz, ln - 1);
|
||||
|
||||
dstr_append(str, "\nsrc: ", 5);
|
||||
dstr_append(str, lexer->src, lexer->srcln);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
char* lexer_state_to_str(LexerState s) {
|
||||
switch (s) {
|
||||
case LEXER_STATE_NUM: return "NUM";
|
||||
case LEXER_STATE_CALL: return "CALL";
|
||||
case LEXER_STATE_CONFUSED: return "CONFUSED";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
12
src/main.c
12
src/main.c
@ -10,17 +10,15 @@ int main(int argc, char** argv) {
|
||||
Dstr* cline = dstr_init(); // The current line.
|
||||
printf("> ");
|
||||
fflush(stdout);
|
||||
for (char cch; (cch = getc(stdin)) != '\n';) {
|
||||
log_dbgf("cchar: %c", cch);
|
||||
dstr_appendch(cline, cch);
|
||||
for (char cch; (cch = getchar() != EOF);) {
|
||||
dstr_appendch(cline, fgetc(stdin));
|
||||
}
|
||||
|
||||
log_dbgf("cline: %s", cline->buf);
|
||||
|
||||
if (cline->ln > 0) {
|
||||
Lexer* lexer = lexer_init(cline->buf);
|
||||
lexer_lex(lexer);
|
||||
printf("\n%s\n", lexer_to_dstr(lexer)->buf);
|
||||
}
|
||||
printf("\n=%s\n", token_to_dstr(lexer->tokens[0])->buf);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user