@@ -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+
92199char * basic_tokenize (struct basic_ctx * ctx )
93200{
94201 char * varname , * split ;
0 commit comments