Fixed some printing errors, introduced many more.

This commit is contained in:
Jacob Signorovitch 2024-10-19 10:59:05 -04:00
parent 4df9808859
commit 7a04ccfd9f
7 changed files with 164 additions and 79 deletions

View File

@ -22,9 +22,9 @@ TEST_SRC_FILES = $(wildcard $(TEST_DIR)/*.c)
TEST_OBJ_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_OBJ_DIR)/%.o, $(TEST_SRC_FILES)) TEST_OBJ_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_OBJ_DIR)/%.o, $(TEST_SRC_FILES))
# Stupid things. # Stupid things.
RESETCOLOR = \x1b[0m RESETCOLOR = \033[0m
WHITE = $(RESETCOLOR)\x1b[37m WHITE = $(RESETCOLOR)\033[37m
WHITE_BOLD = $(RESETCOLOR)\x1b[37;1m WHITE_BOLD = $(RESETCOLOR)\033[37;1m
all: $(TARGET) all: $(TARGET)
@ -33,7 +33,7 @@ release: CFLAGS = -Wall -O2
release: $(TARGET) release: $(TARGET)
run: $(TARGET) run: $(TARGET)
@ echo -e "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)" @ echo "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)"
@ ./$(TARGET) @ ./$(TARGET)
# Link to final binary. # Link to final binary.

View File

@ -15,16 +15,23 @@ typedef enum {
// state). // state).
LEXER_STATE_NUM, // Looking at a number. LEXER_STATE_NUM, // Looking at a number.
LEXER_STATE_CALL, // Looking at a call. LEXER_STATE_CALL, // Looking at a call.
LEXER_STATE_MAX = LEXER_STATE_CALL,
} LexerState; } LexerState;
static char* lexerstate_names[] = {
[LEXER_STATE_CONFUSED] = "CONFUSED",
[LEXER_STATE_NUM] = "NUM",
[LEXER_STATE_CALL] = "CALL",
};
// Lexer: converts text to tokens. // Lexer: converts text to tokens.
typedef struct { typedef struct {
char* src; // The source text.
size_t srcln; // The number of source chars.
char* cchar; // The current character.
Token** tokens; // The tokens produced.
size_t ntokens; // The number of tokens.
LexerState state; // What the lexer is looking at. LexerState state; // What the lexer is looking at.
size_t srcln; // The number of source chars.
char* src; // The source text.
char* cchar; // The current character.
size_t ntokens; // The number of tokens.
Token** tokens; // The tokens produced.
} Lexer; } Lexer;
// Create a lexer. // Create a lexer.
@ -51,10 +58,16 @@ void lexer_inc(Lexer* lexer);
// Add a token to the lexer. // Add a token to the lexer.
void lexer_add_token(Lexer* lexer, Token* token); void lexer_add_token(Lexer* lexer, Token* token);
// Returns a dynamic string representation of the Lexer. // Print a representation of a Lexer.
Dstr* lexer_to_dstr(Lexer* lexer); void lexer_print(Lexer* lexer);
// Returns a string representation of the LexerState. // Print a representation of a Lexer at specified indentation level.
char* lexer_state_to_str(LexerState s); void lexer_print_i(Lexer* lexer, int ilvl);
// Print a representation of a LexerState.
void lexerstate_print(LexerState s);
// Print a representation of a LexerState at the specified indentation level.
void lexerstate_print_i(LexerState s, int ilvl);
#endif #endif

View File

@ -3,11 +3,10 @@
#include <stdlib.h> #include <stdlib.h>
#include "dstr.h"
typedef enum { typedef enum {
TOKEN_TYPE_CALL, TOKEN_TYPE_CALL,
TOKEN_TYPE_NUMBER, TOKEN_TYPE_NUMBER,
TOKEN_TYPE_MAX = TOKEN_TYPE_NUMBER,
} TokenType; } TokenType;
// Token. // Token.
@ -24,7 +23,17 @@ void token_destroy(Token* token);
// Prints out a representation of the Token. // Prints out a representation of the Token.
void token_print(Token* token); void token_print(Token* token);
// Prints out a representation of the Token, with the specified indent level.
void token_print_i(Token* token, int ilevel);
// Prints out a representation of the TokenType. // Prints out a representation of the TokenType.
void tokentype_print(TokenType t); void tokentype_print(TokenType t);
// Prints out a representation of the TokenType, with the specified indent
// level.
void tokentype_print_i(TokenType t, int ilevel);
// Prints a token's type. That's it.
void tokentype_print_raw(TokenType t);
#endif #endif

View File

@ -5,24 +5,37 @@
// Log a message. // Log a message.
#define log_dbg(msg) \ #define log_dbg(msg) \
printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg \ printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
"\033[0m\n", \
__func__); __func__);
// Log a message with formatting. // Log a message with formatting.
#define log_dbgf(msg, ...) \ #define log_dbgf(msg, ...) \
printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg \ printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
"\033[0m\n", \
__func__, __VA_ARGS__); __func__, __VA_ARGS__);
#else // ifdef DBG #else // ifdef DBG
#define log_dbg(msg) #define log_dbg(msg)
#define log_dbgf(msg, ...)
#endif // ifdef DBG else #endif // ifdef DBG else
// Maximum size of a string containing only an int. // Start in indent block.
#define MAXSTRINTSZ ((CHAR_BIT * sizeof(int) - 1) / 3 + 2) #define INDENT_BEGIN(ILVL) \
Dstr* INDENT_spacing = dstr_init(); \
for (int INDENT_j = 0; INDENT_j < ILVL; INDENT_j++) \
dstr_appendch(INDENT_spacing, ' ');
// Maximum size of a string containing only a size_t. #define INDENT_TITLE(THING, WHERE) \
#define MAXSTRIZE_TSZ ((CHAR_BIT * sizeof(size_t) - 1) / 3 + 2) printf("%s" THING " @ %p\n", INDENT_spacing->buf, WHERE);
#define INDENT_FIELD(FIELD, VAL, ...) \
printf("%s " FIELD ": " VAL "\n", INDENT_spacing->buf, __VA_ARGS__);
#define INDENT_FIELD_NL(FIELD, VAL) \
printf("%s " FIELD ":\n%s " VAL "\n", INDENT_spacing->buf, \
INDENT_spacing->buf, __VA_ARGS__);
#define INDENT_FIELD_NONL(FIELD) printf("%s " FIELD ": ", INDENT_spacing->buf);
#define INDENT_END dstr_destroy(INDENT_spacing);
#endif #endif

View File

@ -55,20 +55,20 @@ void lexer_do_confused(Lexer* lexer) {
void lexer_do_number(Lexer* lexer) { void lexer_do_number(Lexer* lexer) {
log_dbgf("lexer @ %p entered number mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar); log_dbgf("lexer @ %p entered number mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
// Size of the number string. // Length of the number string.
size_t numsz; size_t numln;
// Where the number string starts. // Where the number string starts.
char* start = lexer->cchar; char* start = lexer->cchar;
for (numsz = 0; *lexer->cchar && isdigit(*lexer->cchar); numsz++) for (numln = 0; *lexer->cchar && isdigit(*lexer->cchar); numln++)
lexer_inc(lexer); lexer_inc(lexer);
char* num = malloc(numsz + 1); char* num = malloc(numln + 1);
memcpy(num, start, numsz); memcpy(num, start, numln);
num[numsz] = '\0'; num[numln] = '\0';
lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, num, 1)); lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, num, numln));
lexer->state = LEXER_STATE_CONFUSED; lexer->state = LEXER_STATE_CONFUSED;
} }
@ -76,19 +76,19 @@ void lexer_do_call(Lexer* lexer) {
log_dbgf("lexer @ %p entered call mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar); log_dbgf("lexer @ %p entered call mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
// Size of the call string. // Size of the call string.
size_t callsz; size_t callln;
// Where the call string starts. // Where the call string starts.
char* start = lexer->cchar; char* start = lexer->cchar;
for (callsz = 0; *lexer->cchar && (!isdigit(*lexer->cchar)); callsz++) for (callln = 0; *lexer->cchar && (!isdigit(*lexer->cchar)); callln++)
lexer_inc(lexer); lexer_inc(lexer);
char* call = malloc(callsz + 1); char* call = malloc(callln + 1);
memcpy(call, start, callsz); memcpy(call, start, callln);
call[callsz] = '\0'; call[callln] = '\0';
lexer_add_token(lexer, token_init(TOKEN_TYPE_CALL, call, 1)); lexer_add_token(lexer, token_init(TOKEN_TYPE_CALL, call, callln));
lexer->state = LEXER_STATE_CONFUSED; lexer->state = LEXER_STATE_CONFUSED;
} }
@ -103,33 +103,49 @@ void lexer_add_token(Lexer* lexer, Token* token) {
if (lexer->ntokens < TOKENS_MAX - 1) { if (lexer->ntokens < TOKENS_MAX - 1) {
lexer->tokens[lexer->ntokens] = token; lexer->tokens[lexer->ntokens] = token;
lexer->ntokens++; lexer->ntokens++;
log_dbgf("added token (total: %ld)", lexer->ntokens);
} }
} }
Dstr* lexer_to_dstr(Lexer* lexer) { void lexer_print(Lexer* lexer) { lexer_print_i(lexer, 0); }
Dstr* str = dstr_init();
size_t titlesz = sizeof("Lexer @ 0x00000000"); void lexer_print_i(Lexer* lexer, int ilvl) {
char title[titlesz]; Dstr* spacing = dstr_init();
sprintf(title, "Lexer @ %p", lexer); char* sp = spacing->buf;
dstr_append(str, title, titlesz - 1); for (int i = 0; i < ilvl; i++) dstr_appendch(spacing, ' ');
size_t ln = snprintf(NULL, 0, "srcln: %ld", lexer->srcln); printf("%sLexer @ %p\n", sp, lexer);
char src_sz[ln + 1]; printf("%s state:\n", sp);
snprintf(src_sz, ln + 1, "srcln: %ld", lexer->srcln); lexerstate_print_i(lexer->state, ilvl + 2);
dstr_append(str, src_sz, ln - 1); printf("%s srcln:\n", sp);
printf("%s %ld\n", sp, lexer->srcln);
printf("%s src:\n", sp);
printf("%s \"%s\"\n", sp, lexer->src);
printf("%s cchar: \'%c\'\n", sp, *lexer->cchar);
printf("%s ntokens: %ld\n", sp, lexer->ntokens);
printf("%s tokens: [\n", sp);
dstr_append(str, "\nsrc: ", 5); for (int i = 0; i < lexer->ntokens; i++) {
dstr_append(str, lexer->src, lexer->srcln); token_print_i(lexer->tokens[i], ilvl + 2);
printf(",\n\n");
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";
} }
} }
void lexerstate_print(LexerState s) { lexerstate_print_i(s, 0); }
void lexerstate_print_i(LexerState s, int ilvl) {
Dstr* spacing = dstr_init();
for (int j = 0; j < ilvl; j++) dstr_appendch(spacing, ' ');
if (s > LEXER_STATE_MAX) {
printf("%sUnknown (%d)\n", spacing->buf, s);
log_dbgf("%d is not a valid LexerSate (max: %d)", s, LEXER_STATE_MAX);
return;
}
printf("%s%s\n", spacing->buf, lexerstate_names[s]);
dstr_destroy(spacing);
}

View File

@ -20,7 +20,7 @@ int main(int argc, char** argv) {
if (cline->ln > 0) { if (cline->ln > 0) {
Lexer* lexer = lexer_init(cline->buf); Lexer* lexer = lexer_init(cline->buf);
lexer_lex(lexer); lexer_lex(lexer);
printf("\n%s\n", lexer_to_dstr(lexer)->buf); lexer_print(lexer);
} }
} }
} }

View File

@ -1,14 +1,20 @@
#include <stdio.h>
#include "include/token.h" #include "include/token.h"
#include "include/dstr.h" #include "include/dstr.h"
#include "include/util.h"
#include <stdio.h> static char* tokentype_names[] = {
[TOKEN_TYPE_CALL] = "CALL",
[TOKEN_TYPE_NUMBER] = "NUMBER",
};
Token* token_init(TokenType type, char* val, size_t valn) { Token* token_init(TokenType type, char* val, size_t valn) {
Token* t = malloc(sizeof(Token)); Token* t = malloc(sizeof(Token));
t->type = type; t->type = type;
t->val = val;
t->valn = valn; t->valn = valn;
t->val = val;
return t; return t;
} }
@ -18,25 +24,53 @@ void token_destroy(Token* t) {
free(t); free(t);
} }
Dstr* token_to_dstr(Token* token) { void token_print(Token* token) { token_print_i(token, 0); }
Dstr* str = dstr_init();
size_t titlesz = sizeof("Token @ 0x00000000"); #if 0
char title[titlesz]; void token_print_i(Token *token, int ilvl) {
sprintf(title, "Token @ %p", token); Dstr* spacing = dstr_init();
dstr_append(str, title, titlesz - 1); for (int j = 0; j < ilvl; j++) dstr_appendch(spacing, ' ');
dstr_append(str, "\n", 1);
size_t typesz = sizeof("type: 1"); printf("%sToken @ %p\n", spacing->buf, token);
char type[typesz]; printf("%s type:\n", spacing->buf);
// If token_to_dstr starts breaking, it might be because there're more than tokentype_print_i(token->type, ilvl+1);
// 10 types. FIXME. printf("%s valn:\n", spacing->buf);
sprintf(type, "type: %d", token->type); printf("%s %ld\n", spacing->buf, token->valn);
dstr_append(str, type, typesz - 1); printf("%s val:\n", spacing->buf);
dstr_append(str, "\n", 1); printf("%s \"%s\"\n", spacing->buf, token->val);
dstr_append(str, "val: ", 5); // <spacing> <field>:<value>
dstr_append(str, token->val, token->valn); }
#endif
return str;
void token_print_i(Token *token, int ilvl) {
INDENT_BEGIN(ilvl);
INDENT_TITLE("Token", token);
INDENT_FIELD_NONL("type");
tokentype_print_raw(token->type);
}
void tokentype_print_raw(TokenType t) {
if (t > TOKEN_TYPE_MAX) {
printf("Unknown (%d)", t);
log_dbgf("%d is not a valid TokenType (max: %d)", t, TOKEN_TYPE_MAX);
return;
}
printf("%s", tokentype_names[t]);
}
void tokentype_print(TokenType t) { tokentype_print_i(t, 0); }
void tokentype_print_i(TokenType t, int i) {
INDENT_BEGIN(i);
if (t > TOKEN_TYPE_MAX) {
INDENT_FIELD("val", "Unknown (%d)", t);
log_dbgf("%d is not a valid TokenType (max: %d)", t, TOKEN_TYPE_MAX);
return;
}
INDENT_FIELD("val", "%s", tokentype_names[t]);
} }