diff --git a/Makefile b/Makefile index 2878383..32b73f4 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,10 @@ release: clean release: CFLAGS = -Wall -O2 release: $(TARGET) +run: $(TARGET) + @ echo -e "$(WHITE_BOLD)Running... $(RESETCOLOR)./$(TARGET)" + @ ./$(TARGET) + # Link to final binary. $(TARGET): $(OBJ_FILES) @ echo -e "$(WHITE_BOLD)Linking $(WHITE)$(TARGET)$(WHITE_BOLD)...$(RESETCOLOR) $(CC) -o $(TARGET) $(OBJ_FILES) $(LDFLAGS)" @@ -60,8 +64,5 @@ clean: @ echo -e "$(WHITE_BOLD)Cleaning up...$(WHITE) $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET)$(RESETCOLOR)" @ rm -rf $(OBJ_DIR)/*.o $(TEST_OBJ_DIR)/*.o $(TEST_BUILD_DIR)/test.out $(TARGET) -run: - ./$(TARGET) - -.PHONY: all clean test nocolor release +.PHONY: all clean test nocolor release run diff --git a/src/dstr.c b/src/dstr.c index 32c69be..b98b81d 100644 --- a/src/dstr.c +++ b/src/dstr.c @@ -1,11 +1,15 @@ #include "include/dstr.h" +#include "include/util.h" + #include +#include Dstr* dstr_init(void) { Dstr* dstr = malloc(sizeof(Dstr)); dstr->bufsz = DSTR_INITSZ; dstr->buf = malloc(DSTR_INITSZ); + *dstr->buf = '\0'; dstr->ln = 0; return dstr; @@ -16,12 +20,30 @@ void dstr_destroy(Dstr* dstr) { free(dstr); } -void dstr_append(Dstr* dest, size_t ln, char* src) { - if (dest->ln + ln > dest->bufsz) { +void dstr_append(Dstr* dest, char* src, size_t ln) { + while (dest->ln + ln + 1 > dest->bufsz) { // Double the buffer size when overflown. - dest->bufsz *= dest->bufsz; + dest->bufsz *= 2; dest->buf = realloc(dest->buf, dest->bufsz); + log_dbgf("dstr @ %p doubled from %ld to %ld", dest, dest->bufsz/2, dest->bufsz); } - strcat(dest->buf + ln, src); + // Overwrites the \0 at the end of the string, keeps the null from the given + // string. + memcpy(dest->buf + dest->ln, src, ln + 1); + dest->ln += ln; +} + +void dstr_appendch(Dstr *dest, char ch) { + if (dest->ln + 1 + 1 > dest->bufsz) { + // Double the buffer size when overflown. + dest->bufsz *= 2; + dest->buf = realloc(dest->buf, dest->bufsz); + log_dbgf("dstr @ %p doubled from %ld to %ld", dest, dest->bufsz/2, dest->bufsz); + } + + // Overwrites the preexisting null terminator, and adds one of its own. + dest->buf[dest->ln] = ch; + dest->buf[dest->ln+1] = '\0'; + dest->ln += 1; } diff --git a/src/include/dstr.h b/src/include/dstr.h index cd64c93..2dfdb97 100644 --- a/src/include/dstr.h +++ b/src/include/dstr.h @@ -2,7 +2,6 @@ #define DSTR_H #include -#include #define DSTR_INITSZ 128 @@ -16,6 +15,9 @@ Dstr* dstr_init(void); void dstr_destroy(Dstr* dstr); // Append ln characters of src to dest. -void dstr_append(Dstr* dest, size_t ln, char* src); +void dstr_append(Dstr* dest, char* src, size_t ln); + +// Append ch to dest. +void dstr_appendch(Dstr* dest, char ch); #endif diff --git a/src/include/token.h b/src/include/token.h index 3108b14..52c26c0 100644 --- a/src/include/token.h +++ b/src/include/token.h @@ -3,6 +3,9 @@ #include #include +#include + +#include "dstr.h" typedef enum { TOKEN_TYPE_CALL, @@ -12,15 +15,16 @@ typedef enum { // Token. typedef struct { TokenType type; // The type of the Token. + size_t valn; // The length of val. char* val; // The text of the Token. size_t len; // Length of the text of the Token. } Token; -Token* token_init(TokenType type, char* val); +Token* token_init(TokenType type, char* val, size_t valn); void token_destroy(Token* token); // Returns a string representation of the Token. -char* token_to_str(Token* token, unsigned int indent); +Dstr* token_to_dstr(Token* token); // Returns a string representation of the TokenType. char* token_type_to_str(TokenType t); diff --git a/src/include/util.h b/src/include/util.h index 051b6ce..38932df 100644 --- a/src/include/util.h +++ b/src/include/util.h @@ -2,9 +2,17 @@ #define UTIL_H #ifdef DBG -#define log_dbg(msg) \ - printf("[dbg:%s:%s:%d] %s\n", __FILE__, __func__, __LINE__, msg); \ - fflush(stdout); + +#define log_dbg(msg) \ + printf("\033[37;1mdbg\033[0m:\033[37;5m%s\033[0m:\033[32m " msg \ + "\033[0m\n", \ + __func__); + +#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 #define log_dbg(msg) #endif diff --git a/src/lexer.c b/src/lexer.c index d466364..3ae4d35 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -1,3 +1,6 @@ +#include +#include + #include "include/lexer.h" #include "include/util.h" @@ -12,6 +15,8 @@ Lexer* lexer_init(char* src) { lexer->ntokens = 0; lexer->state = LEXER_STATE_CONFUSED; + log_dbgf("created new lexer @ %p", lexer); + return lexer; } @@ -33,13 +38,17 @@ void lexer_lex(Lexer* lexer) { } void lexer_do_confused(Lexer* lexer) { - log_dbg("entered confused mode"); + log_dbgf("lexer @ %p entered confused mode @ char '%c' (%d)", lexer, *lexer->cchar, (int)*lexer->cchar); + + 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_dbg("entered number mode"); + 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; @@ -53,25 +62,29 @@ void lexer_do_number(Lexer* lexer) { memcpy(num, start, numsz); num[numsz] = '\0'; - lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, num)); + lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, num, 1)); } void lexer_do_call(Lexer* lexer) { - log_dbg("entered call mode"); + 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 && isalpha(*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); memcpy(call, start, callsz); call[callsz] = '\0'; - lexer_add_token(lexer, token_init(TOKEN_TYPE_CALL, call)); + lexer_add_token(lexer, token_init(TOKEN_TYPE_CALL, call, 1)); } void lexer_inc(Lexer* lexer) { diff --git a/src/main.c b/src/main.c index fda8dd7..f863774 100644 --- a/src/main.c +++ b/src/main.c @@ -1,17 +1,24 @@ #include +#include "include/dstr.h" #include "include/token.h" #include "include/util.h" #include "include/lexer.h" int main(int argc, char** argv) { - char* text = malloc(5); - text = "aa11"; + while(1) { + Dstr* cline = dstr_init(); // The current line. + printf("> "); + fflush(stdout); + for (char cch; (cch = getchar() != EOF);) { + dstr_appendch(cline, fgetc(stdin)); + } - Lexer* lexer = lexer_init(text); - lexer_lex(lexer); + if (cline->ln > 0) { + Lexer* lexer = lexer_init(cline->buf); + lexer_lex(lexer); + printf("\n=%s\n", token_to_dstr(lexer->tokens[0])->buf); + } - printf("%s\n", token_to_str(lexer->tokens[0], 0)); - - lexer_destroy(lexer); + } } diff --git a/src/token.c b/src/token.c index 07251bb..b5aab09 100644 --- a/src/token.c +++ b/src/token.c @@ -1,11 +1,13 @@ #include "include/token.h" -#include +#include "include/dstr.h" +#include -Token* token_init(TokenType type, char* val) { +Token* token_init(TokenType type, char* val, size_t valn) { Token* t = malloc(sizeof(Token)); t->type = type; t->val = val; + t->valn = valn; return t; } @@ -15,8 +17,25 @@ void token_destroy(Token* t) { free(t); } -char* token_to_str(Token* token, unsigned int indent) { - char* title = malloc(sizeof("Token @ 0x000000000000\n")); - sprintf(title, "Token @%p\n", token); - return title; +Dstr* token_to_dstr(Token* token) { + Dstr* str = dstr_init(); + + 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); + + 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); + + dstr_append(str, "val: ", 5); + dstr_append(str, token->val, token->valn); + + return str; } diff --git a/test/dstr.c b/test/dstr.c index 1630415..1b479b7 100644 --- a/test/dstr.c +++ b/test/dstr.c @@ -12,14 +12,16 @@ void test_dstr_init() { void test_dstr_append() { char* str1 = malloc(2); - str1 = "h"; + str1[0] = 'h'; + str1[1] = '\0'; char* str2 = malloc(DSTR_INITSZ); - str2 = "h"; + str2[0] = 'h'; + str2[1] = '\0'; Dstr* dstr = dstr_init(); - dstr_append(dstr, 1, str1); + dstr_append(dstr, str1, 1); TEST_ASSERT_EQUAL_STRING(str2, dstr->buf); }