Skip to content

Commit 892305e

Browse files
cursoragentomiq
andcommitted
Runtime hints for TEXTAT, LOCATE, SORT, SPLIT, JOIN
- TEXTAT/LOCATE: comma-separated x,y[,text] forms - SORT: 1-D DIMmed array; multi-dim rejection - SPLIT/JOIN: INTO syntax, string array vs result, delimiter, commas - CHANGELOG: extend runtime-hints bullet Co-authored-by: Chris Garrett <chris@chrisg.com>
1 parent 70b55ab commit 892305e

2 files changed

Lines changed: 24 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
### Unreleased
44

5-
- **Runtime hints**: **`goto` / `gosub` / `on` / `if … then`**, **`DIM` / `FOR` / `NEXT`**, **array subscripts**, **`LET`/`=`**, **`INPUT`**, **`READ`/`DATA`**, **`RESTORE`**, **`GET`**, **`LOAD`/`MEMSET`/`MEMCPY`**, **`OPEN`/`CLOSE`** and **`PRINT#`/`INPUT#`/`GET#`**, **`WHILE`/`WEND`**, **`DO`/`LOOP`/`EXIT`** — short **`Hint:`** lines for common mistakes. **Native** `runtime_error_hint` prints **`Hint:`** on stderr (parity with WASM). **`tutorial-embed.js`**: **Ctrl+Enter** / **Cmd+Enter** runs; **`scrollToError`** (default **on**). **`web/tutorial.html`** playground mentions keyboard run.
5+
- **Runtime hints**: **`goto` / `gosub` / `on` / `if … then`**, **`DIM` / `FOR` / `NEXT`**, **array subscripts**, **`LET`/`=`**, **`INPUT`**, **`READ`/`DATA`**, **`RESTORE`**, **`GET`**, **`LOAD`/`MEMSET`/`MEMCPY`**, **`OPEN`/`CLOSE`** and **`PRINT#`/`INPUT#`/`GET#`**, **`TEXTAT`/`LOCATE`**, **`SORT`**, **`SPLIT`/`JOIN`**, **`WHILE`/`WEND`**, **`DO`/`LOOP`/`EXIT`** — short **`Hint:`** lines for common mistakes. **Native** `runtime_error_hint` prints **`Hint:`** on stderr (parity with WASM). **`tutorial-embed.js`**: **Ctrl+Enter** / **Cmd+Enter** runs; **`scrollToError`** (default **on**). **`web/tutorial.html`** playground mentions keyboard run.
66

77
- **Sprites**: **`SPRITECOLLIDE(a, b)`** — returns **1** if two loaded, visible sprites’ axis-aligned bounding boxes overlap (basic-gfx + canvas WASM; **0** otherwise). Terminal **`./basic`** errors if used (requires **basic-gfx** or canvas WASM). **Runtime errors**: optional **`Hint:`** line for **unknown function** (shows name) and **`ensure_num` / `ensure_str`** type mismatches. **`tutorial-embed.js`**: optional **`runOnEdit`** / **`runOnEditMs`** for debounced auto-run after editing; **`web/tutorial.html`** enables this on the final playground embed only (**550** ms).
88

basic.c

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6301,7 +6301,7 @@ static void statement_textat(char **p)
63016301
ensure_num(&vx);
63026302
skip_spaces(p);
63036303
if (**p != ',') {
6304-
runtime_error("TEXTAT: expected ',' after X");
6304+
runtime_error_hint("TEXTAT: expected ',' after X", "Use TEXTAT x, y, \"text\" (commas between x, y, and string).");
63056305
return;
63066306
}
63076307
(*p)++;
@@ -6310,7 +6310,7 @@ static void statement_textat(char **p)
63106310
ensure_num(&vy);
63116311
skip_spaces(p);
63126312
if (**p != ',') {
6313-
runtime_error("TEXTAT: expected ',' after Y");
6313+
runtime_error_hint("TEXTAT: expected ',' after Y", "Use TEXTAT x, y, \"text\" — comma before the string.");
63146314
return;
63156315
}
63166316
(*p)++;
@@ -6355,7 +6355,10 @@ static void statement_locate(char **p)
63556355
// Validation
63566356
vx = eval_expr(p); ensure_num(&vx);
63576357
skip_spaces(p);
6358-
if (**p != ',') { runtime_error("LOCATE: expected ',' after X"); return; }
6358+
if (**p != ',') {
6359+
runtime_error_hint("LOCATE: expected ',' after X", "Use LOCATE x, y (column then row, 0-based in gfx).");
6360+
return;
6361+
}
63596362
(*p)++;
63606363
vy = eval_expr(p); ensure_num(&vy);
63616364
skip_spaces(p);
@@ -6958,7 +6961,7 @@ static void statement_sort(char **p)
69586961

69596962
skip_spaces(p);
69606963
if (!isalpha((unsigned char)**p)) {
6961-
runtime_error("SORT requires array variable");
6964+
runtime_error_hint("SORT requires array variable", "Use SORT A or SORT T$ with a DIMmed 1-D array name.");
69626965
return;
69636966
}
69646967
read_identifier(p, namebuf, sizeof(namebuf));
@@ -6970,11 +6973,11 @@ static void statement_sort(char **p)
69706973
}
69716974
}
69726975
if (!v || !v->is_array || !v->array || v->size <= 0) {
6973-
runtime_error("SORT requires 1-D array");
6976+
runtime_error_hint("SORT requires 1-D array", "DIM the array first: DIM A(10) then SORT A.");
69746977
return;
69756978
}
69766979
if (v->dims != 1) {
6977-
runtime_error("SORT requires 1-D array");
6980+
runtime_error_hint("SORT requires 1-D array", "Multi-dimensional arrays cannot be SORTed; use 1-D only.");
69786981
return;
69796982
}
69806983
skip_spaces(p);
@@ -7016,7 +7019,7 @@ static void statement_split(char **p)
70167019
ensure_str(&v_str);
70177020
skip_spaces(p);
70187021
if (**p != ',') {
7019-
runtime_error("SPLIT: expected ,");
7022+
runtime_error_hint("SPLIT: expected ,", "Use SPLIT s$, \",\" INTO arr$ — comma after the string and delimiter.");
70207023
return;
70217024
}
70227025
(*p)++;
@@ -7025,13 +7028,13 @@ static void statement_split(char **p)
70257028
ensure_str(&v_delim);
70267029
skip_spaces(p);
70277030
if (!starts_with_kw(*p, "INTO")) {
7028-
runtime_error("SPLIT: expected INTO");
7031+
runtime_error_hint("SPLIT: expected INTO", "Syntax: SPLIT text$, delim$ INTO string_array.");
70297032
return;
70307033
}
70317034
*p += 4;
70327035
skip_spaces(p);
70337036
if (!isalpha((unsigned char)**p)) {
7034-
runtime_error("SPLIT: expected array variable");
7037+
runtime_error_hint("SPLIT: expected array variable", "After INTO, give the string array name (e.g. P$).");
70357038
return;
70367039
}
70377040
{
@@ -7040,7 +7043,7 @@ static void statement_split(char **p)
70407043
read_identifier(p, namebuf, sizeof(namebuf));
70417044
uppercase_name(namebuf, namebuf, sizeof(namebuf), &is_string);
70427045
if (!is_string) {
7043-
runtime_error("SPLIT: expected string array");
7046+
runtime_error_hint("SPLIT: expected string array", "SPLIT fills a string array (name ends with $).");
70447047
return;
70457048
}
70467049
for (i = 0; i < var_count; i++) {
@@ -7051,14 +7054,15 @@ static void statement_split(char **p)
70517054
}
70527055
}
70537056
if (!arr_var || !arr_var->is_array || !arr_var->array || arr_var->dims != 1) {
7054-
runtime_error("SPLIT: requires 1-D string array (DIM first)");
7057+
runtime_error_hint("SPLIT: requires 1-D string array (DIM first)",
7058+
"DIM P$(20) before SPLIT … INTO P$.");
70557059
return;
70567060
}
70577061
s = v_str.str;
70587062
delim = v_delim.str;
70597063
dlen = strlen(delim);
70607064
if (dlen == 0) {
7061-
runtime_error("SPLIT: empty delimiter");
7065+
runtime_error_hint("SPLIT: empty delimiter", "Delimiter must be non-empty (e.g. \",\" or \"|\").");
70627066
return;
70637067
}
70647068
arr_size = arr_var->size;
@@ -7098,13 +7102,13 @@ static void statement_join(char **p)
70987102

70997103
skip_spaces(p);
71007104
if (!isalpha((unsigned char)**p)) {
7101-
runtime_error("JOIN: expected array variable");
7105+
runtime_error_hint("JOIN: expected array variable", "Start with the string array: JOIN P$, …");
71027106
return;
71037107
}
71047108
read_identifier(p, namebuf, sizeof(namebuf));
71057109
uppercase_name(namebuf, namebuf, sizeof(namebuf), &is_string);
71067110
if (!is_string) {
7107-
runtime_error("JOIN: expected string array");
7111+
runtime_error_hint("JOIN: expected string array", "JOIN combines a string array (name ends with $).");
71087112
return;
71097113
}
71107114
for (i = 0; i < var_count; i++) {
@@ -7114,12 +7118,12 @@ static void statement_join(char **p)
71147118
}
71157119
}
71167120
if (!arr_var || !arr_var->is_array || !arr_var->array || arr_var->dims != 1) {
7117-
runtime_error("JOIN: requires 1-D string array");
7121+
runtime_error_hint("JOIN: requires 1-D string array", "DIM a string array first, same as for SPLIT.");
71187122
return;
71197123
}
71207124
skip_spaces(p);
71217125
if (**p != ',') {
7122-
runtime_error("JOIN: expected ,");
7126+
runtime_error_hint("JOIN: expected ,", "Use JOIN arr$, \",\" INTO result$ — comma after array name.");
71237127
return;
71247128
}
71257129
(*p)++;
@@ -7128,15 +7132,16 @@ static void statement_join(char **p)
71287132
ensure_str(&v_delim);
71297133
skip_spaces(p);
71307134
if (!starts_with_kw(*p, "INTO")) {
7131-
runtime_error("JOIN: expected INTO");
7135+
runtime_error_hint("JOIN: expected INTO", "Syntax: JOIN arr$, delim$ INTO out$ [, count].");
71327136
return;
71337137
}
71347138
*p += 4;
71357139
skip_spaces(p);
71367140
{
71377141
struct value *out = get_var_reference(p, &i, &is_string, NULL);
71387142
if (!out || !is_string) {
7139-
runtime_error("JOIN: expected string variable for result");
7143+
runtime_error_hint("JOIN: expected string variable for result",
7144+
"After INTO, use a scalar string variable (e.g. Q$) for the joined text.");
71407145
return;
71417146
}
71427147
skip_spaces(p);

0 commit comments

Comments
 (0)