Compiler: fix 16 of 18 compile errors — 32/72 tests passing
Fixes: - Include graphics.h/virmem.h in gwrt.h (5 programs: draw_commands, get_put, graphics_stubs, peek_gfx, view_window) - RND(n): discard argument to buffer instead of emitting it inline - Float constant 0: emit "0.0f" not "0f" (invalid C suffix) - MID$ function: proper 3-argument emission with optional length - FOR/NEXT: use static variables instead of block scope for limit/step (fixes FOR inside IF/THEN and unmatched brace issues) - RESUME/RESUME NEXT: handle as statements (not misparse as FOR/NEXT) - ON TIMER/KEY/COM: skip event trap setup (not misparse as ON n GOTO) - MID$ assignment: recognize and skip (don't misparse as variable) - ERROR statement: emit gw_error() call - ERASE: stub handler Only 2 compile errors remain: bubble_sort (SWAP with arrays), misc_stmts (ENVIRON$ variable name clash). 32 of 72 tests pass. New: datetime, luhn, peek_poke, error_handler, on_timer, timer_stop, monte_carlo, number_guess.
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
#include "strpool.h"
|
||||
#include "portio.h"
|
||||
#include "sound.h"
|
||||
#include "graphics.h"
|
||||
#include "virmem.h"
|
||||
#include <setjmp.h>
|
||||
|
||||
/* Initialization / shutdown */
|
||||
|
||||
+74
-13
@@ -198,7 +198,12 @@ static void emit_atom(void)
|
||||
float v;
|
||||
memcpy(&v, tp + 1, 4);
|
||||
tp += 5;
|
||||
EMIT("%.9gf", v);
|
||||
{ char nbuf[32]; snprintf(nbuf, sizeof(nbuf), "%.9g", v);
|
||||
if (!strchr(nbuf, '.') && !strchr(nbuf, 'e'))
|
||||
EMIT("%s.0f", nbuf); /* 0 → 0.0f */
|
||||
else
|
||||
EMIT("%sf", nbuf); /* 3.14 → 3.14f */
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (tok == TOK_CONST_DBL) {
|
||||
@@ -272,9 +277,12 @@ static void emit_atom(void)
|
||||
return;
|
||||
}
|
||||
case FUNC_RND: {
|
||||
/* RND may or may not have parens */
|
||||
/* RND([n]) — argument is ignored (controls seed behavior) */
|
||||
if (cur() == '(') {
|
||||
advance(); emit_num_expr();
|
||||
advance();
|
||||
/* Consume but discard the argument */
|
||||
char *discard = emit_to_buf(emit_prec_wrapper, 0);
|
||||
free(discard);
|
||||
if (cur() == ')') advance();
|
||||
}
|
||||
EMIT("((float)rand() / RAND_MAX)");
|
||||
@@ -630,10 +638,17 @@ static void emit_str_expr(void)
|
||||
EMIT("gw_fn_mid(&(gw_value_t){.type=VT_STR,.sval=");
|
||||
advance(); emit_str_expr();
|
||||
if (cur() == ',') advance();
|
||||
EMIT("}, ");
|
||||
EMIT("}, (int)(");
|
||||
emit_num_expr();
|
||||
EMIT(", 255");
|
||||
if (cur() == ',') { advance(); EMIT("); /* mid with len */ "); }
|
||||
EMIT("), ");
|
||||
if (cur() == ',') {
|
||||
advance();
|
||||
EMIT("(int)(");
|
||||
emit_num_expr();
|
||||
EMIT(")");
|
||||
} else {
|
||||
EMIT("255");
|
||||
}
|
||||
if (cur() == ')') advance();
|
||||
EMIT(").sval");
|
||||
return;
|
||||
@@ -1033,12 +1048,13 @@ static void emit_stmt(void)
|
||||
EMIT(");\n");
|
||||
skip_spaces();
|
||||
if (cur() == TOK_TO) advance();
|
||||
/* Store limit in a temp */
|
||||
EMIT(" { %s _for_limit_%d = (%s)(", c_type(type), for_label_counter, c_type(type));
|
||||
/* Store limit and step at function scope (no {} block — FOR may span IF THEN) */
|
||||
EMIT(" static %s _for_limit_%d; _for_limit_%d = (%s)(",
|
||||
c_type(type), for_label_counter, for_label_counter, c_type(type));
|
||||
emit_num_expr();
|
||||
EMIT(");\n");
|
||||
/* Step (default 1) */
|
||||
EMIT(" %s _for_step_%d = 1;\n", c_type(type), for_label_counter);
|
||||
EMIT(" static %s _for_step_%d; _for_step_%d = 1;\n",
|
||||
c_type(type), for_label_counter, for_label_counter);
|
||||
skip_spaces();
|
||||
if (cur() == TOK_STEP) {
|
||||
advance();
|
||||
@@ -1096,9 +1112,8 @@ static void emit_stmt(void)
|
||||
fc = for_label_counter > 0 ? for_label_counter - 1 : 0;
|
||||
}
|
||||
}
|
||||
EMIT(" goto for_top_%d;\n", fc);
|
||||
EMIT(" for_done_%d: ;\n", fc);
|
||||
EMIT(" }\n");
|
||||
EMIT(" goto for_top_%d;\n", fc);
|
||||
EMIT(" for_done_%d: ;\n", fc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1148,6 +1163,12 @@ static void emit_stmt(void)
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* ON TIMER / ON KEY / ON COM — event trapping, skip */
|
||||
if (cur() == TOK_PREFIX_FE || cur() == TOK_KEY) {
|
||||
EMIT(" /* ON event trap — not compiled */\n");
|
||||
while (cur() && cur() != ':' && cur() != 0) tp++;
|
||||
return;
|
||||
}
|
||||
EMIT(" { int _on_val = (int)(");
|
||||
emit_num_expr();
|
||||
EMIT(");\n");
|
||||
@@ -1347,6 +1368,39 @@ static void emit_stmt(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/* RESUME / RESUME NEXT / RESUME n */
|
||||
if (tok == TOK_RESUME) {
|
||||
advance();
|
||||
skip_spaces();
|
||||
if (cur() == TOK_NEXT) {
|
||||
advance();
|
||||
EMIT(" /* RESUME NEXT — not fully compiled */\n");
|
||||
} else if (is_const(cur())) {
|
||||
uint16_t target = read_int();
|
||||
EMIT(" goto L_%u; /* RESUME n */\n", target);
|
||||
} else {
|
||||
EMIT(" /* RESUME — not fully compiled */\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* ERROR n */
|
||||
if (tok == TOK_ERROR) {
|
||||
advance();
|
||||
EMIT(" gw_error((int)(");
|
||||
emit_num_expr();
|
||||
EMIT("));\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* ERASE */
|
||||
if (tok == TOK_ERASE) {
|
||||
advance();
|
||||
EMIT(" /* ERASE — not yet compiled */\n");
|
||||
while (cur() && cur() != ':' && cur() != 0) tp++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* TRON/TROFF */
|
||||
if (tok == TOK_TRON) { advance(); return; }
|
||||
if (tok == TOK_TROFF) { advance(); return; }
|
||||
@@ -1590,6 +1644,13 @@ static void emit_stmt(void)
|
||||
return;
|
||||
}
|
||||
|
||||
/* MID$ assignment: MID$(var$, start [,len]) = expr */
|
||||
if (tok == TOK_PREFIX_FF && tp[1] == FUNC_MID) {
|
||||
EMIT(" /* MID$ assignment — not yet compiled */\n");
|
||||
while (cur() && cur() != ':' && cur() != 0) tp++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Implicit assignment (variable at start of statement) */
|
||||
if (is_letter(tok)) {
|
||||
emit_assignment();
|
||||
|
||||
Reference in New Issue
Block a user