Skip to content

Commit 38d29f0

Browse files
cursoragentomiq
andcommitted
fix: HTTP(url) alias for HTTP$ — avoid UDF name collision
read_identifier stops at '(', so HTTP(U$) was resolved as UDF HTTP with wrong types. Route HTTP( to intrinsic HTTP$ in eval_factor and execute_statement. Co-authored-by: Chris Garrett <chris@chrisg.com>
1 parent 693810d commit 38d29f0

3 files changed

Lines changed: 17 additions & 2 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-
- **Browser WASM HTTP (`HTTP$` / `HTTPSTATUS`)**: **`R$ = HTTP$(url$ [, method$ [, body$]])`** performs **`fetch`** (Asyncify + **`EM_ASYNC_JS`**). **`HTTPSTATUS()`** returns the last HTTP status (**0** on failure). Response body is truncated to the current max string length. **Native / non-Emscripten**: **`HTTP$`** returns **`""`** (use **`EXEC$("curl …")`**). **`Makefile`**: **`ASYNCIFY_IMPORTS`** includes **`__asyncjs__wasm_js_http_fetch_async`**. **`starts_with_kw`**: longer identifiers no longer match shorter keywords (**`HTTP`** vs **`HTTPSTATUS`**). Example: **`examples/http_time_london.bas`**.
5+
- **Browser WASM HTTP (`HTTP$` / `HTTPSTATUS`)**: **`R$ = HTTP$(url$ [, method$ [, body$]])`** performs **`fetch`** (Asyncify + **`EM_ASYNC_JS`**). **`HTTPSTATUS()`** returns the last HTTP status (**0** on failure). Response body is truncated to the current max string length. **Native / non-Emscripten**: **`HTTP$`** returns **`""`** (use **`EXEC$("curl …")`**). **`Makefile`**: **`ASYNCIFY_IMPORTS`** includes **`__asyncjs__wasm_js_http_fetch_async`**. **`starts_with_kw`**: longer identifiers no longer match shorter keywords (**`HTTP`** vs **`HTTPSTATUS`**). **`HTTP(url$)`** without **`$`** is accepted as an alias for **`HTTP$`** (avoids collision with user **`FUNCTION HTTP`**). Example: **`examples/http_time_london.bas`**.
66

77
- **`SPRITEFRAME` statement**: Dispatch lived under **`c == 'D'`** but the keyword starts with **S**, so **`SPRITEFRAME 0, 1`** fell through to **`LET`** and failed with “reserved word cannot be used as variable”. Moved handling to the **`S`** branch with **`SPRITEVISIBLE`**.
88

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ Run this once after unpacking, and macOS will stop treating the binary as “fro
151151
- `ARG$(n)` — returns the *n*th argument as a string. `ARG$(0)` is the script path; `ARG$(1)``ARG$(ARGC())` are the arguments. Out-of-range returns `""`.
152152
- `SYSTEM(cmd$)`** — runs a shell command (e.g. `SYSTEM("ls -l")`), waits for it to finish, and returns its exit status (0 = success).
153153
- `EXEC$(cmd$)` — runs a shell command and returns its standard output as a string (up to 255 characters; trailing newline trimmed). Use for scripting (e.g. `U$ = EXEC$("whoami")`).
154-
- **Browser WASM only**: `HTTP$(url$ [, method$ [, body$]])``fetch` the URL; returns response body as a string. `HTTPSTATUS()` — last HTTP status from `HTTP$` (0 if the request failed). Outside the Emscripten build, `HTTP$` returns `""` (use `EXEC$` with `curl` on native). APIs must allow **CORS** from your page origin. See `examples/http_time_london.bas`.
154+
- **Browser WASM only**: `HTTP$(url$ [, method$ [, body$]])``fetch` the URL; returns response body as a string. `HTTP(url$)` without `$` is the same call. `HTTPSTATUS()` — last HTTP status from `HTTP$` (0 if the request failed). Outside the Emscripten build, `HTTP$` returns `""` (use `EXEC$` with `curl` on native). APIs must allow **CORS** from your page origin. See `examples/http_time_london.bas`.
155155

156156
### Additional/Non-Standard BASIC Commands
157157

basic.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6337,6 +6337,12 @@ static struct value eval_factor(char **p)
63376337
read_identifier(&q, namebuf, sizeof(namebuf));
63386338
return eval_function(namebuf, p);
63396339
} else {
6340+
/* HTTP(...) without $ — same intrinsic as HTTP$(...); "HTTP" alone must not match UDF HTTP. */
6341+
if (toupper((unsigned char)(*p)[0]) == 'H' && toupper((unsigned char)(*p)[1]) == 'T' &&
6342+
toupper((unsigned char)(*p)[2]) == 'T' && toupper((unsigned char)(*p)[3]) == 'P' &&
6343+
(*p)[4] == '(') {
6344+
return eval_function("HTTP$", p);
6345+
}
63406346
/* Check for user-defined FUNCTION or DEF FN, else variable */
63416347
char namebuf[VAR_NAME_MAX];
63426348
char *q;
@@ -9414,6 +9420,15 @@ static void execute_statement(char **p)
94149420
read_identifier(&q, namebuf, sizeof(namebuf));
94159421
for (i = 0; namebuf[i]; i++) namebuf[i] = (char)toupper((unsigned char)namebuf[i]);
94169422
skip_spaces(&q);
9423+
/* HTTP(url) statement — intrinsic, not UDF "HTTP" */
9424+
if (strcmp(namebuf, "HTTP") == 0 && *q == '(') {
9425+
struct value discard;
9426+
char *ep = *p;
9427+
discard = eval_function("HTTP$", &ep);
9428+
(void)discard;
9429+
*p = ep;
9430+
return;
9431+
}
94179432
if (*q == '(') {
94189433
struct value *args = (struct value *)calloc(MAX_UDF_PARAMS, sizeof(struct value));
94199434
if (!args) {

0 commit comments

Comments
 (0)