Skip to content

Commit 3daef9e

Browse files
fully fix search and replace in editor, and the fact that int FN cant return a 0/FALSE value
1 parent ccacc3d commit 3daef9e

7 files changed

Lines changed: 39 additions & 46 deletions

File tree

os/programs/edit.rrbasic

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ DEF PROCdraw
3535
CURSOR 2, TERMHEIGHT
3636
PRINT "ESC EXIT"; CHR$(9); "^S SAVE"; CHR$(9); CHR$(9); "^W WHEREIS"; CHR$(9); "^R REPLACE";
3737
CURSOR TERMWIDTH - 15, TERMHEIGHT
38-
PRINT currentx; ","; top + currenty;
38+
PRINT currentx; ","; top + currenty; " ";
3939
CURSOR 1, 0
4040
PROCclearLineFromCursor
4141
CURSOR TERMWIDTH / 2 - 2, 0
@@ -455,6 +455,7 @@ REM interactive replace loop with Y/N/A/Q controls; wraps once
455455
DEF PROCreplaceLoop(find$, repl$)
456456
all_mode = FALSE
457457
did_wrap = FALSE
458+
exit_replace = FALSE
458459
next_line = top + currenty
459460
next_col = currentx + 1
460461
PROCdraw
@@ -466,7 +467,7 @@ DEF PROCreplaceLoop(find$, repl$)
466467
next_col = 0
467468
ELSE
468469
PROCtext
469-
ENDPROC
470+
exit_replace = TRUE
470471
ENDIF
471472
ELSE
472473
IF all_mode = TRUE THEN
@@ -498,15 +499,15 @@ DEF PROCreplaceLoop(find$, repl$)
498499
ENDIF
499500
IF uk$ = "Q" THEN
500501
PROCtext
501-
ENDPROC
502+
exit_replace = TRUE
502503
ENDIF
503504
IF uk$ <> "Q" AND uk$ <> "A" AND uk$ <> "N" AND uk$ <> "Y" THEN
504505
next_line = hit_line
505506
next_col = hit_pos
506507
ENDIF
507508
ENDIF
508509
ENDIF
509-
UNTIL FALSE
510+
UNTIL exit_replace = TRUE
510511
PROCtext
511512
ENDPROC
512513

@@ -543,3 +544,4 @@ DEF FNnextHit(line_from, col_from, needle$)
543544
ENDIF
544545
NEXT
545546
=FALSE
547+

src/basic/console.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,12 @@ void print_statement(struct basic_ctx* ctx)
156156
if (strncmp(out, "***DEBUG ON***",14) == 0) {
157157
debug = true;
158158
dprintf("BASIC DEBUG TRACE ENABLED\n");
159+
return;
159160
}
160161
if (strncmp(out, "***DEBUG OFF***",15) == 0) {
161162
debug = false;
162163
dprintf("BASIC DEBUG TRACE DISABLED\n");
164+
return;
163165
}
164166
uint64_t flags;
165167
lock_spinlock_irq(&console_spinlock, &flags);

src/basic/flow_control.c

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ void error_statement(struct basic_ctx* ctx)
8080

8181
void if_statement(struct basic_ctx* ctx)
8282
{
83-
if (debug) {
84-
dprintf("line %ld if_statement\n", ctx->current_linenum);
85-
}
83+
if (debug) dprintf("line %ld if_statement\n", ctx->current_linenum);
8684

8785
accept_or_return(IF, ctx);
8886
bool r = conditional(ctx);
@@ -93,16 +91,15 @@ void if_statement(struct basic_ctx* ctx)
9391
if (tokenizer_token(ctx) == NEWLINE) {
9492
/* Multi-statement block IF */
9593
accept_or_return(NEWLINE, ctx);
96-
ctx->if_nest_level++;
9794
return;
9895
}
9996
statement(ctx);
10097
} else {
10198
if (debug) dprintf("conditional is false\n");
10299

103100
if (tokenizer_token(ctx) == NEWLINE) {
104-
/* --- FIXED: multiline false-branch with proper nesting --- */
105-
/* Enter the block and scan forward once, respecting nested multiline IFs. */
101+
/* --- multiline false-branch with nesting --- */
102+
/* Enter the block and scan forward once, respecting nested multiline IFs */
106103
accept_or_return(NEWLINE, ctx);
107104

108105
int depth = 0;
@@ -111,21 +108,15 @@ void if_statement(struct basic_ctx* ctx)
111108

112109
/* Detect nested multiline IF: IF ... THEN NEWLINE */
113110
if (t == IF) {
114-
/* Look ahead to see if this IF starts a multiline block. */
115-
const char* save_ptr = ctx->ptr;
116-
const char* save_nextptr = ctx->nextptr;
117-
int save_tok = ctx->current_token;
118111

119-
/* Advance until THEN or end-of-line/input. */
120-
int saw_then = 0;
112+
/* Advance until THEN or end-of-line/input */
121113
for (;;) {
122114
tokenizer_next(ctx);
123115
int tt = tokenizer_token(ctx);
124116
if (tt == THEN) {
125-
saw_then = 1;
126117
tokenizer_next(ctx);
127118
tt = tokenizer_token(ctx);
128-
/* Multiline only if THEN is immediately followed by NEWLINE. */
119+
/* Multiline only if THEN is immediately followed by NEWLINE */
129120
if (tt == NEWLINE) {
130121
depth++;
131122
}
@@ -135,48 +126,45 @@ void if_statement(struct basic_ctx* ctx)
135126
break;
136127
}
137128
}
138-
/* Continue scanning from current position (no rewind). */
129+
/* Continue scanning from current position (no rewind) */
139130
continue;
140131
}
141132

142-
/* At our depth, ELSE NEWLINE starts the else-block. */
133+
/* At our depth, ELSE NEWLINE starts the else-block */
143134
if (t == ELSE) {
144135
tokenizer_next(ctx);
145136
if (depth == 0 && tokenizer_token(ctx) == NEWLINE) {
146-
ctx->if_nest_level++;
147137
accept_or_return(NEWLINE, ctx);
148138
return;
149139
}
150-
/* ELSE on the same line (single-line IF) or nested: ignore and continue. */
140+
/* ELSE on the same line (single-line IF) or nested: ignore and continue */
151141
continue;
152142
}
153143

154-
/* At our depth, ENDIF NEWLINE ends the whole IF without an else. */
144+
/* At our depth, ENDIF NEWLINE ends the whole IF without an else */
155145
if (t == ENDIF) {
156146
tokenizer_next(ctx);
157147
if (depth == 0) {
158148
accept_or_return(NEWLINE, ctx);
159149
return;
160150
}
161-
/* Close one nested multiline IF. */
151+
/* Close one nested multiline IF */
162152
depth--;
163153
continue;
164154
}
165155

166-
/* Any other token: just keep scanning. */
156+
/* Any other token: just keep scanning */
167157
tokenizer_next(ctx);
168158
}
169159

170-
/* Reached end of input without matching ENDIF: treat as end of block. */
160+
/* Reached end of input without matching ENDIF: treat as end of block */
171161
return;
172162
}
173163

174-
/* Single-line IF ... THEN <stmt> [ELSE <stmt>] (original behaviour). */
164+
/* Single-line IF ... THEN <stmt> [ELSE <stmt>] */
175165
do {
176166
tokenizer_next(ctx);
177-
} while (tokenizer_token(ctx) != ELSE &&
178-
tokenizer_token(ctx) != NEWLINE &&
179-
tokenizer_token(ctx) != ENDOFINPUT);
167+
} while (tokenizer_token(ctx) != ELSE && tokenizer_token(ctx) != NEWLINE && tokenizer_token(ctx) != ENDOFINPUT);
180168

181169
if (tokenizer_token(ctx) == ELSE) {
182170
tokenizer_next(ctx);
@@ -329,12 +317,8 @@ void until_statement(struct basic_ctx* ctx)
329317

330318
void endif_statement(struct basic_ctx* ctx)
331319
{
332-
if (ctx->if_nest_level == 0) {
333-
tokenizer_error_print(ctx, "ENDIF outside of block IF");
334-
}
335320
accept_or_return(ENDIF, ctx);
336321
accept_or_return(NEWLINE, ctx);
337-
ctx->if_nest_level--;
338322
}
339323

340324
void end_statement(struct basic_ctx* ctx)

src/basic/function.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,11 +316,7 @@ int64_t basic_eval_int_fn(const char* fn_name, struct basic_ctx* ctx)
316316
break;
317317
}
318318
}
319-
if (atomic->fn_return == NULL) {
320-
tokenizer_error_print(ctx, "End of function without returning value");
321-
} else {
322-
rv = (int64_t)atomic->fn_return;
323-
}
319+
rv = (int64_t)atomic->fn_return;
324320

325321
/* Copy list heads back (int/str/double).
326322
* Move-to-front inside atomic may change them,
@@ -602,14 +598,18 @@ void def_statement(struct basic_ctx* ctx)
602598

603599
void eq_statement(struct basic_ctx* ctx)
604600
{
601+
if (debug) dprintf("eq_statement\n");
605602
accept_or_return(EQUALS, ctx);
606603

607604
if (ctx->fn_type == RT_STRING) {
605+
if (debug) dprintf("eq_statement return string\n");
608606
ctx->fn_return = (void*)str_expr(ctx);
609607
} else if (ctx->fn_type == RT_FLOAT) {
608+
if (debug) dprintf("eq_statement return double\n");
610609
double_expr(ctx, (void*)&ctx->fn_return);
611610
} else if (ctx->fn_type == RT_INT) {
612611
ctx->fn_return = (void*)expr(ctx);
612+
if (debug) dprintf("eq_statement return int %ld\n", (int64_t)ctx->fn_return);
613613
} else if (ctx->fn_type == RT_NONE) {
614614
tokenizer_error_print(ctx, "Can't return a value from a PROC");
615615
return;
@@ -640,6 +640,8 @@ void endproc_statement(struct basic_ctx* ctx)
640640
/* Now restore the *caller*'s return type. */
641641
ctx->fn_type = ctx->fn_type_stack[ctx->call_stack_ptr];
642642

643+
ctx->if_nest_level = 0; // If we exit a proc, we clear the nest level
644+
643645
if (debug) dprintf("ENDPROC back to line %lu stack pos %lu\n", ctx->call_stack[ctx->call_stack_ptr], ctx->call_stack_ptr);
644646
jump_linenum(ctx->call_stack[ctx->call_stack_ptr], ctx);
645647
} else {

src/basic/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ void library_statement(struct basic_ctx *ctx) {
378378
struct basic_ctx *basic_clone(struct basic_ctx *old) {
379379
struct basic_ctx *ctx = buddy_malloc(old->allocator, sizeof(struct basic_ctx));
380380

381-
ctx->if_nest_level = old->if_nest_level;
381+
ctx->if_nest_level = 0;
382382
ctx->current_token = NO_TOKEN;
383383
ctx->error_handler = old->error_handler;
384384
ctx->sleep_until = old->sleep_until;

src/basic/tokenizer.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#include <kernel.h>
2323

24+
extern bool debug;
25+
2426
#define MAX_NUMLEN 32
2527

2628
/**
@@ -357,6 +359,7 @@ void tokenizer_error_print(struct basic_ctx* ctx, const char* error)
357359
basic_set_int_variable("ERRLINE", ctx->current_linenum, ctx, false, false);
358360
if (ctx->eval_linenum == 0) {
359361
if (ctx->ended == 0) {
362+
debug = false;
360363
if (ctx->error_handler) {
361364
dprintf("ERROR handled\n");
362365
struct ub_proc_fn_def* def = basic_find_fn(ctx->error_handler, ctx);

src/basic/variable.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ const char* basic_get_string_variable(const char* var, struct basic_ctx* ctx)
431431
while (cur) {
432432
if (len == cur->name_length && !strcmp(var, cur->varname)) {
433433
/* move-to-front optimisation */
434-
/*if (prev) {
434+
if (prev) {
435435
prev->next = cur->next;
436436
if (j == 0) {
437437
cur->next = ctx->str_variables;
@@ -440,7 +440,7 @@ const char* basic_get_string_variable(const char* var, struct basic_ctx* ctx)
440440
cur->next = ctx->local_string_variables[j];
441441
ctx->local_string_variables[j] = cur;
442442
}
443-
}*/
443+
}
444444
return cur->value;
445445
}
446446
prev = cur;
@@ -547,7 +547,7 @@ int64_t basic_get_int_variable(const char* var, struct basic_ctx* ctx)
547547
}
548548

549549
/* move-to-front optimisation */
550-
/*if (prev) {
550+
if (prev) {
551551
// unlink
552552
prev->next = cur->next;
553553
// relink at head
@@ -558,7 +558,7 @@ int64_t basic_get_int_variable(const char* var, struct basic_ctx* ctx)
558558
cur->next = ctx->local_int_variables[j];
559559
ctx->local_int_variables[j] = cur;
560560
}
561-
}*/
561+
}
562562
return v;
563563
}
564564
prev = cur;
@@ -600,7 +600,7 @@ bool basic_get_double_variable(const char* var, struct basic_ctx* ctx, double* r
600600
if (len == cur->name_length && !strcmp(var, cur->varname)) {
601601
*res = cur->value;
602602
/* move-to-front optimisation */
603-
/*if (prev) {
603+
if (prev) {
604604
prev->next = cur->next;
605605
if (j == 0) {
606606
cur->next = ctx->double_variables;
@@ -609,7 +609,7 @@ bool basic_get_double_variable(const char* var, struct basic_ctx* ctx, double* r
609609
cur->next = ctx->local_double_variables[j];
610610
ctx->local_double_variables[j] = cur;
611611
}
612-
}*/
612+
}
613613
return true;
614614
}
615615
prev = cur;

0 commit comments

Comments
 (0)