Fixed some printing errors, introduced many more.
This commit is contained in:
parent
4df9808859
commit
7a04ccfd9f
8
Makefile
8
Makefile
@ -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))
|
||||
|
||||
# Stupid things.
|
||||
RESETCOLOR = \x1b[0m
|
||||
WHITE = $(RESETCOLOR)\x1b[37m
|
||||
WHITE_BOLD = $(RESETCOLOR)\x1b[37;1m
|
||||
RESETCOLOR = \033[0m
|
||||
WHITE = $(RESETCOLOR)\033[37m
|
||||
WHITE_BOLD = $(RESETCOLOR)\033[37;1m
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
@ -33,7 +33,7 @@ release: CFLAGS = -Wall -O2
|
||||
release: $(TARGET)
|
||||
|
||||
run: $(TARGET)
|
||||
@ echo -e "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)"
|
||||
@ echo "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)"
|
||||
@ ./$(TARGET)
|
||||
|
||||
# Link to final binary.
|
||||
|
@ -15,16 +15,23 @@ typedef enum {
|
||||
// state).
|
||||
LEXER_STATE_NUM, // Looking at a number.
|
||||
LEXER_STATE_CALL, // Looking at a call.
|
||||
LEXER_STATE_MAX = LEXER_STATE_CALL,
|
||||
} LexerState;
|
||||
|
||||
static char* lexerstate_names[] = {
|
||||
[LEXER_STATE_CONFUSED] = "CONFUSED",
|
||||
[LEXER_STATE_NUM] = "NUM",
|
||||
[LEXER_STATE_CALL] = "CALL",
|
||||
};
|
||||
|
||||
// Lexer: converts text to tokens.
|
||||
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.
|
||||
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;
|
||||
|
||||
// Create a lexer.
|
||||
@ -51,10 +58,16 @@ 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);
|
||||
// Print a representation of a Lexer.
|
||||
void lexer_print(Lexer* lexer);
|
||||
|
||||
// Returns a string representation of the LexerState.
|
||||
char* lexer_state_to_str(LexerState s);
|
||||
// Print a representation of a Lexer at specified indentation level.
|
||||
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
|
||||
|
@ -3,11 +3,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dstr.h"
|
||||
|
||||
typedef enum {
|
||||
TOKEN_TYPE_CALL,
|
||||
TOKEN_TYPE_NUMBER,
|
||||
TOKEN_TYPE_MAX = TOKEN_TYPE_NUMBER,
|
||||
} TokenType;
|
||||
|
||||
// Token.
|
||||
@ -24,7 +23,17 @@ void token_destroy(Token* token);
|
||||
// Prints out a representation of the 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.
|
||||
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
|
||||
|
@ -5,24 +5,37 @@
|
||||
|
||||
// Log a message.
|
||||
#define log_dbg(msg) \
|
||||
printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg \
|
||||
"\033[0m\n", \
|
||||
printf("\033[37;1mdbg\033[0m:\033[37m%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[37m%s\033[0m:\033[32m " msg \
|
||||
"\033[0m\n", \
|
||||
printf("\033[37;1mdbg\033[0m:\033[37m%s\033[0m:\033[32m " msg "\033[0m\n", \
|
||||
__func__, __VA_ARGS__);
|
||||
|
||||
#else // ifdef DBG
|
||||
#define log_dbg(msg)
|
||||
#define log_dbgf(msg, ...)
|
||||
#endif // ifdef DBG else
|
||||
|
||||
// Maximum size of a string containing only an int.
|
||||
#define MAXSTRINTSZ ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
|
||||
// Start in indent block.
|
||||
#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 MAXSTRIZE_TSZ ((CHAR_BIT * sizeof(size_t) - 1) / 3 + 2)
|
||||
#define INDENT_TITLE(THING, WHERE) \
|
||||
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
|
||||
|
86
src/lexer.c
86
src/lexer.c
@ -55,20 +55,20 @@ void lexer_do_confused(Lexer* lexer) {
|
||||
void lexer_do_number(Lexer* lexer) {
|
||||
log_dbgf("lexer @ %p entered number mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar);
|
||||
|
||||
// Size of the number string.
|
||||
size_t numsz;
|
||||
// Length of the number string.
|
||||
size_t numln;
|
||||
|
||||
// Where the number string starts.
|
||||
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);
|
||||
|
||||
char* num = malloc(numsz + 1);
|
||||
memcpy(num, start, numsz);
|
||||
num[numsz] = '\0';
|
||||
char* num = malloc(numln + 1);
|
||||
memcpy(num, start, numln);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
// Size of the call string.
|
||||
size_t callsz;
|
||||
size_t callln;
|
||||
|
||||
// Where the call string starts.
|
||||
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);
|
||||
|
||||
char* call = malloc(callsz + 1);
|
||||
memcpy(call, start, callsz);
|
||||
call[callsz] = '\0';
|
||||
char* call = malloc(callln + 1);
|
||||
memcpy(call, start, callln);
|
||||
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;
|
||||
}
|
||||
@ -103,33 +103,49 @@ void lexer_add_token(Lexer* lexer, Token* token) {
|
||||
if (lexer->ntokens < TOKENS_MAX - 1) {
|
||||
lexer->tokens[lexer->ntokens] = token;
|
||||
lexer->ntokens++;
|
||||
|
||||
log_dbgf("added token (total: %ld)", lexer->ntokens);
|
||||
}
|
||||
}
|
||||
|
||||
Dstr* lexer_to_dstr(Lexer* lexer) {
|
||||
Dstr* str = dstr_init();
|
||||
void lexer_print(Lexer* lexer) { lexer_print_i(lexer, 0); }
|
||||
|
||||
size_t titlesz = sizeof("Lexer @ 0x00000000");
|
||||
char title[titlesz];
|
||||
sprintf(title, "Lexer @ %p", lexer);
|
||||
dstr_append(str, title, titlesz - 1);
|
||||
void lexer_print_i(Lexer* lexer, int ilvl) {
|
||||
Dstr* spacing = dstr_init();
|
||||
char* sp = spacing->buf;
|
||||
for (int i = 0; i < ilvl; i++) dstr_appendch(spacing, ' ');
|
||||
|
||||
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);
|
||||
printf("%sLexer @ %p\n", sp, lexer);
|
||||
printf("%s state:\n", sp);
|
||||
lexerstate_print_i(lexer->state, ilvl + 2);
|
||||
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);
|
||||
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";
|
||||
for (int i = 0; i < lexer->ntokens; i++) {
|
||||
token_print_i(lexer->tokens[i], ilvl + 2);
|
||||
printf(",\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ int main(int argc, char** argv) {
|
||||
if (cline->ln > 0) {
|
||||
Lexer* lexer = lexer_init(cline->buf);
|
||||
lexer_lex(lexer);
|
||||
printf("\n%s\n", lexer_to_dstr(lexer)->buf);
|
||||
lexer_print(lexer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
74
src/token.c
74
src/token.c
@ -1,14 +1,20 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "include/token.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* t = malloc(sizeof(Token));
|
||||
|
||||
t->type = type;
|
||||
t->val = val;
|
||||
t->valn = valn;
|
||||
t->val = val;
|
||||
|
||||
return t;
|
||||
}
|
||||
@ -18,25 +24,53 @@ void token_destroy(Token* t) {
|
||||
free(t);
|
||||
}
|
||||
|
||||
Dstr* token_to_dstr(Token* token) {
|
||||
Dstr* str = dstr_init();
|
||||
void token_print(Token* token) { token_print_i(token, 0); }
|
||||
|
||||
size_t titlesz = sizeof("Token @ 0x00000000");
|
||||
char title[titlesz];
|
||||
sprintf(title, "Token @ %p", token);
|
||||
dstr_append(str, title, titlesz - 1);
|
||||
dstr_append(str, "\n", 1);
|
||||
#if 0
|
||||
void token_print_i(Token *token, int ilvl) {
|
||||
Dstr* spacing = dstr_init();
|
||||
for (int j = 0; j < ilvl; j++) dstr_appendch(spacing, ' ');
|
||||
|
||||
size_t typesz = sizeof("type: 1");
|
||||
char type[typesz];
|
||||
// If token_to_dstr starts breaking, it might be because there're more than
|
||||
// 10 types. FIXME.
|
||||
sprintf(type, "type: %d", token->type);
|
||||
dstr_append(str, type, typesz - 1);
|
||||
dstr_append(str, "\n", 1);
|
||||
printf("%sToken @ %p\n", spacing->buf, token);
|
||||
printf("%s type:\n", spacing->buf);
|
||||
tokentype_print_i(token->type, ilvl+1);
|
||||
printf("%s valn:\n", spacing->buf);
|
||||
printf("%s %ld\n", spacing->buf, token->valn);
|
||||
printf("%s val:\n", spacing->buf);
|
||||
printf("%s \"%s\"\n", spacing->buf, token->val);
|
||||
|
||||
dstr_append(str, "val: ", 5);
|
||||
dstr_append(str, token->val, token->valn);
|
||||
|
||||
return str;
|
||||
// <spacing> <field>:<value>
|
||||
}
|
||||
#endif
|
||||
|
||||
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]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user