diff options
author | Marvin Borner | 2021-04-21 00:05:04 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-21 00:05:04 +0200 |
commit | c219c38e854fe15bc47519d2df0d6cbd7bab2ab7 (patch) | |
tree | 239b84c05371b4e853b40ebb52b1ad744fe0fc53 | |
parent | f31fc8b66eee149bd78603996f34264be8fad411 (diff) |
Started syntax highlighting
doesn't work but don't want to fix lel.
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | src/gui.c | 38 | ||||
-rw-r--r-- | src/inc/gui.h | 3 | ||||
-rw-r--r-- | src/inc/lexer.h | 6 | ||||
-rw-r--r-- | src/inc/syntax.h | 8 | ||||
-rw-r--r-- | src/lexer.c | 6 | ||||
-rw-r--r-- | src/parser.c | 9 | ||||
-rw-r--r-- | src/syntax.c | 60 |
8 files changed, 128 insertions, 5 deletions
@@ -5,7 +5,8 @@ OBJS = $(patsubst $(SOURCEDIR)/%.c, $(BUILDDIR)/%.o, $(SOURCES)) CC = gcc WARNINGS = -Wall -Wextra -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wformat=2 -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wswitch-default -Wswitch-enum -Wlogical-op -Wunreachable-code -Wundef -Wold-style-definition -Wvla -pedantic -CFLAGS = -O3 $(WARNINGS) -I$(SOURCEDIR)/inc/ $(shell pkg-config --cflags --libs gtk+-3.0 gtksourceview-4) -fsanitize=undefined #-fsanitize=address +DEBUG = -fsanitize=undefined -fsanitize=address -ggdb3 -g3 -g -s -Og +CFLAGS = -Ofast $(WARNINGS) -I$(SOURCEDIR)/inc/ $(shell pkg-config --cflags --libs gtk+-3.0 gtksourceview-4) $(DEBUG) all: $(OBJS) @$(CC) -o ./$(BUILDDIR)/out $^ $(CFLAGS) @@ -5,6 +5,9 @@ #include <parser.h> #include <stdio.h> #include <string.h> +#include <syntax.h> + +#define BUFFER_SIZE 1024 // Main window static GtkWidget *window; @@ -23,7 +26,7 @@ static char *gui_text_buffer(void) static void gui_fill_text_view(const char *path) { - char buf[1024] = { 0 }; + char buf[BUFFER_SIZE] = { 0 }; FILE *test = fopen(path, "r"); if (!test) { @@ -43,13 +46,39 @@ static void gui_call_parser(void) { char *buf = gui_text_buffer(); - // TODO: Get actual buffer size - if (parse(buf, 1024)) + if (parse(buf, BUFFER_SIZE)) gui_show_info("Compiled successfully!"); g_free(buf); } +static void gui_call_syntax_highlighter(void) +{ + char *buf = gui_text_buffer(); + + syntax_highlight(buf, BUFFER_SIZE); + + g_free(buf); +} + +static void gui_init_highlighter(void) +{ + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); + gtk_text_buffer_create_tag(buffer, "instr", "foreground", "#ff0000", NULL); + gtk_text_buffer_create_tag(buffer, "regs", "foreground", "#00ff00", NULL); +} + +void gui_highlight(u32 column, u32 line, u32 length, const char *tag_name) +{ + GtkTextIter start, end; + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); + + gtk_text_buffer_get_iter_at_line_offset(buffer, &start, line, column); + gtk_text_buffer_get_iter_at_line_offset(buffer, &end, line, column + length); + + gtk_text_buffer_apply_tag_by_name(buffer, tag_name, &start, &end); +} + void gui_show_warning(const char *text) { if (!text) @@ -125,12 +154,15 @@ static void gui_activate(GtkApplication *app, gpointer data) // Strange text view text_view = gtk_source_view_new(); gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(text_view), TRUE); + gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(text_view), TRUE); gtk_box_pack_end(GTK_BOX(box), text_view, TRUE, TRUE, 0); gtk_widget_show_all(window); // Only for testing purposes gui_fill_text_view("test.asm"); + + gui_init_highlighter(); } int gui_init(int argc, char *argv[]) diff --git a/src/inc/gui.h b/src/inc/gui.h index 1c7fc01..aa059e5 100644 --- a/src/inc/gui.h +++ b/src/inc/gui.h @@ -1,8 +1,11 @@ #ifndef GUI_H #define GUI_H +#include <def.h> + int gui_init(int argc, char *argv[]); void gui_show_warning(const char *text); void gui_show_info(const char *text); +void gui_highlight(u32 column, u32 line, u32 length, const char *color); #endif diff --git a/src/inc/lexer.h b/src/inc/lexer.h index c3999e7..f323f58 100644 --- a/src/inc/lexer.h +++ b/src/inc/lexer.h @@ -8,6 +8,7 @@ enum token_type { NEWLINE, SPACE, + INSTR_START, NOP, JBC, JB, @@ -61,6 +62,7 @@ enum token_type { DATA, BIT, INCLUDE, + INSTR_END, HASH, DOLLAR, @@ -71,13 +73,16 @@ enum token_type { COLON, SEMICOLON, + NUM_START, DEC_NUM, HEX_NUM, BIN_NUM, + NUM_END, STRING, // Registers + REGS_START, ACCU, ATR0, ATR1, @@ -89,6 +94,7 @@ enum token_type { R5, R6, R7, + REGS_END, }; struct token { diff --git a/src/inc/syntax.h b/src/inc/syntax.h new file mode 100644 index 0000000..7857d75 --- /dev/null +++ b/src/inc/syntax.h @@ -0,0 +1,8 @@ +#ifndef SYNTAX_H +#define SYNTAX_H + +#include <def.h> + +void syntax_highlight(char *buf, u32 size); + +#endif diff --git a/src/lexer.c b/src/lexer.c index d4a6d6a..5b43cb5 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -37,8 +37,10 @@ struct token token_resolve(char *str, u32 size) if (str[length] == 'h' || str[length] == 'H') { type = HEX_NUM; + length++; } else if (str[length] == 'b' || str[length] == 'B') { type = BIN_NUM; + length++; } else { type = DEC_NUM; } @@ -263,8 +265,10 @@ struct token token_resolve(char *str, u32 size) while (ALPHA_NUMERIC(str[length])) length++; - if (length) + if (length) { type = STRING; + length++; + } } } diff --git a/src/parser.c b/src/parser.c index 2e8894b..2f16323 100644 --- a/src/parser.c +++ b/src/parser.c @@ -383,6 +383,7 @@ static u32 parse_line(struct context *ctx, char *str, u32 size) struct token tok = token_resolve(str + str_ind, size - str_ind); if (tok.type == NEWLINE) { ctx->line++; + ctx->column = 0; break; } @@ -602,6 +603,14 @@ static u32 parse_line(struct context *ctx, char *str, u32 size) case BIT: warnings_add(ctx, "Random non-instruction found"); break; + case INSTR_START: + case INSTR_END: + case NUM_START: + case NUM_END: + case REGS_START: + case REGS_END: + warnings_add(ctx, "Got enum boundary"); + break; default: warnings_add(ctx, "Super-unknown instruction"); break; diff --git a/src/syntax.c b/src/syntax.c new file mode 100644 index 0000000..d01496e --- /dev/null +++ b/src/syntax.c @@ -0,0 +1,60 @@ +#include <def.h> +#include <gui.h> +#include <lexer.h> +#include <stdio.h> +#include <syntax.h> + +struct pos { + u32 x; + u32 y; +}; + +static void syntax_highlight_line(struct pos *pos, char *str, u32 size) +{ + while (1) { + /* printf("%d:%d\n", pos->y, pos->x); */ + struct token tok = token_resolve(str + pos->x, size - pos->x); + + if (tok.type == NEWLINE) { + pos->x = 0; + pos->y++; + return; + } + + if (tok.type == UNKNOWN) + return; + + if (tok.type == SPACE) { + pos->x += tok.length; + continue; + } + + token_print(&tok); + + /* if (tok.type > INSTR_START && tok.type < INSTR_END) */ + /* gui_highlight(pos->x, pos->y, tok.length, "instr"); */ + /* else if (tok.type > REGS_START && tok.type < REGS_END) { */ + /* gui_highlight(pos->x, pos->y, tok.length, "regs"); */ + /* } */ + + pos->x += tok.length; + } +} + +void syntax_highlight(char *buf, u32 size) +{ + return; // TODO: Fix some stuff + struct pos pos = { 0 }; + + char *start = buf; + for (u32 i = 0; i < size; i++) { + if (buf[i] == '\0') + break; + + if (buf[i] == '\n') { + pos.x = 0; + syntax_highlight_line(&pos, start, i); + start += i; + } + } +} |