aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2021-04-21 00:05:04 +0200
committerMarvin Borner2021-04-21 00:05:04 +0200
commitc219c38e854fe15bc47519d2df0d6cbd7bab2ab7 (patch)
tree239b84c05371b4e853b40ebb52b1ad744fe0fc53
parentf31fc8b66eee149bd78603996f34264be8fad411 (diff)
Started syntax highlighting
doesn't work but don't want to fix lel.
-rw-r--r--Makefile3
-rw-r--r--src/gui.c38
-rw-r--r--src/inc/gui.h3
-rw-r--r--src/inc/lexer.h6
-rw-r--r--src/inc/syntax.h8
-rw-r--r--src/lexer.c6
-rw-r--r--src/parser.c9
-rw-r--r--src/syntax.c60
8 files changed, 128 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 4cf9d6c..75008a5 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/src/gui.c b/src/gui.c
index ea86191..d7c7123 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -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;
+ }
+ }
+}