Skip to content

Commit 1a7c69e

Browse files
syntax highlighting
1 parent 84d86f6 commit 1a7c69e

File tree

6 files changed

+118
-3
lines changed

6 files changed

+118
-3
lines changed

include/basic/builtin_string_functions.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,4 +242,6 @@ char* basic_str(struct basic_ctx* ctx);
242242
*/
243243
char* basic_bool(struct basic_ctx* ctx);
244244

245-
char* basic_replace(struct basic_ctx* ctx);
245+
char* basic_replace(struct basic_ctx* ctx);
246+
247+
char* basic_highlight(struct basic_ctx* ctx);

include/video.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,6 @@ void set_video_dirty_area(int64_t start, int64_t end);
250250

251251
const char* ansi_colour(char *out, size_t out_len, unsigned char vga_colour, bool background);
252252

253+
unsigned char map_vga_to_ansi(unsigned char colour);
254+
255+
unsigned char map_vga_to_ansi_bg(unsigned char colour);

os/programs/edit.rrbasic

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ DEF PROCtext
8585
CURSOR 1, 2
8686
FOR l = top TO top + TERMHEIGHT - 3
8787
PROCclearLineFromCursor
88-
IF l < max THEN PRINT LEFT$(content$(l), TERMWIDTH)
88+
IF l < max THEN PRINT HIGHLIGHT$(LEFT$(content$(l), TERMWIDTH))
8989
NEXT
9090
AUTOFLIP FALSE
9191
FLIP

src/basic/function.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ struct basic_str_fn builtin_str[] =
123123
{ basic_getprocname, "GETPROCNAME$" },
124124
{ basic_getprocstate, "GETPROCSTATE$" },
125125
{ basic_getvar_string, "GETVARS$" },
126+
{ basic_highlight, "HIGHLIGHT$" },
126127
{ basic_inkey, "INKEY$" },
127128
{ basic_insocket, "INSOCKET$" },
128129
{ basic_intoasc, "INTOASC$" },

src/basic/string.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,113 @@ char* basic_lower(struct basic_ctx* ctx)
8989
return modified;
9090
}
9191

92+
extern struct basic_int_fn builtin_int[];
93+
extern struct basic_str_fn builtin_str[];
94+
extern struct basic_double_fn builtin_double[];
95+
96+
/*
97+
if (background) {
98+
code = map_vga_to_ansi_bg(vga_colour);
99+
} else {
100+
code = map_vga_to_ansi(vga_colour);
101+
}
102+
snprintf(out, out_len, "\x1b[%um", code);
103+
*/
104+
105+
char* basic_highlight(struct basic_ctx* ctx) {
106+
GENERATE_ENUM_STRING_NAMES(TOKEN, token_names)
107+
const size_t token_count = sizeof(token_names) / sizeof(*token_names);
108+
PARAMS_START;
109+
PARAMS_GET_ITEM(BIP_STRING);
110+
const char* in = strval;
111+
char out[MAX_STRINGLEN] = {};
112+
PARAMS_END("HIGHLIGHT$","");
113+
bool in_quotes = false, in_comment = false;
114+
const char* end = in + strlen(in);
115+
for (const char* pos = in; *pos; ++pos) {
116+
size_t current_len = strlen(out);
117+
bool found = false, reset_colour = false;
118+
if (in_comment) {
119+
*(out + current_len) = *pos;
120+
continue;
121+
} else if (!in_quotes && *pos == '"') {
122+
current_len += snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um", map_vga_to_ansi(COLOUR_LIGHTYELLOW));
123+
in_quotes = true;
124+
} else if (in_quotes && *pos == '"') {
125+
in_quotes = false;
126+
reset_colour = true;
127+
} else if (!in_quotes && *pos == '\'') {
128+
in_comment = true;
129+
current_len += snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um", map_vga_to_ansi(COLOUR_DARKGREEN));
130+
}
131+
if (!in_quotes && !in_comment) {
132+
for (size_t v = 0; builtin_int[v].name; ++v) {
133+
size_t fn_len = strlen(builtin_int[v].name);
134+
if (pos + fn_len <= end && !memcmp(pos, builtin_int[v].name, fn_len)) {
135+
/* Is a builtin integer function */
136+
snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um%s\x1b[%um", map_vga_to_ansi(COLOUR_LIGHTGREEN), builtin_int[v].name, map_vga_to_ansi(COLOUR_WHITE));
137+
found = true;
138+
pos += fn_len - 1;
139+
}
140+
}
141+
for (size_t v = 0; builtin_str[v].name; ++v) {
142+
size_t fn_len = strlen(builtin_str[v].name);
143+
if (pos + fn_len <= end && !memcmp(pos, builtin_str[v].name, fn_len)) {
144+
/* Is a builtin string function */
145+
snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um%s\x1b[%um", map_vga_to_ansi(COLOUR_LIGHTMAGENTA), builtin_str[v].name, map_vga_to_ansi(COLOUR_WHITE));
146+
found = true;
147+
pos += fn_len - 1;
148+
}
149+
}
150+
for (size_t v = 0; builtin_double[v].name; ++v) {
151+
size_t fn_len = strlen(builtin_double[v].name);
152+
if (pos + fn_len <= end && !memcmp(pos, builtin_double[v].name, fn_len)) {
153+
/* Is a builtin real function */
154+
snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um%s\x1b[%um", map_vga_to_ansi(COLOUR_LIGHTCYAN), builtin_double[v].name, map_vga_to_ansi(COLOUR_WHITE));
155+
found = true;
156+
pos += fn_len - 1;
157+
}
158+
}
159+
for (size_t v = 0; v < token_count; ++v) {
160+
size_t kw_len = strlen(token_names[v]);
161+
if (pos + kw_len <= end && !memcmp(pos, token_names[v], kw_len)) {
162+
const char *after = pos + kw_len;
163+
bool next_is_varlike = ((*after >= '0' && *after <= '9') || (toupper(*after) >= 'A' && toupper(*after) <= 'Z') || *after == '_');
164+
if (!next_is_varlike || v == PROC || v == FN || v == EQUALS) {
165+
/* Is a token */
166+
if (v == REM) {
167+
in_comment = true;
168+
snprintf(out, MAX_STRINGLEN, "\x1b[%um%s\x1b[%um", map_vga_to_ansi(COLOUR_DARKGREEN), in, map_vga_to_ansi(COLOUR_WHITE));
169+
return (char*)gc_strdup(ctx, out);
170+
} else {
171+
snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um%s\x1b[%um", map_vga_to_ansi(COLOUR_LIGHTBLUE), token_names[v], map_vga_to_ansi(COLOUR_WHITE));
172+
found = true;
173+
}
174+
pos += kw_len - 1;
175+
}
176+
}
177+
}
178+
}
179+
if (!found) {
180+
if (!in_quotes && !in_comment && ((*pos >= '0' && *pos <= '9') || ((*pos == '-' || *pos == '+') && (*(pos+1) >= '0' && *(pos+1) <= '9')))) {
181+
/* Numeric colour */
182+
snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um%c\x1b[%um", map_vga_to_ansi(COLOUR_ORANGE), *pos, map_vga_to_ansi(COLOUR_WHITE));
183+
} else if (!in_quotes && !in_comment && (*pos == '(' || *pos == ')' || *pos == '+' || *pos == '-' || *pos == '/' || *pos == '=' || *pos == '*' || *pos == '<' || *pos == '>' || *pos == ',' || *pos == ';')) {
184+
/* Symbolic maths colour */
185+
snprintf(out + current_len, MAX_STRINGLEN - current_len, "\x1b[%um%c\x1b[%um", map_vga_to_ansi(COLOUR_DARKRED), *pos, map_vga_to_ansi(COLOUR_WHITE));
186+
} else {
187+
*(out + current_len) = *pos;
188+
}
189+
}
190+
if (reset_colour) {
191+
snprintf(out + current_len, MAX_STRINGLEN - current_len, "\"\x1b[%um", map_vga_to_ansi(COLOUR_WHITE));
192+
}
193+
}
194+
char buf[MAX_STRINGLEN];
195+
snprintf(buf, MAX_STRINGLEN, "%s\x1b[%um", out, map_vga_to_ansi(COLOUR_WHITE));
196+
return (char*)gc_strdup(ctx, buf);
197+
}
198+
92199
char* basic_tokenize(struct basic_ctx* ctx)
93200
{
94201
char* varname, *split;

src/video.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,10 @@ bool video_flip_auto(void) {
630630
}
631631

632632
void set_video_auto_flip(bool flip) {
633+
if (video_flip_is_auto != flip) {
634+
dprintf("VIDEO AUTO FLIP: %d\n", flip);
635+
}
633636
video_flip_is_auto = flip;
634-
dprintf("VIDEO AUTO FLIP: %d\n", flip);
635637
}
636638

637639
void rr_flip(void) {

0 commit comments

Comments
 (0)