From 1dcc39f45b33c0d96d4ec8101ac404b29f567276 Mon Sep 17 00:00:00 2001 From: Eremey Valetov Date: Sun, 29 Mar 2026 14:53:02 -0400 Subject: [PATCH] =?UTF-8?q?Compiler:=20READ=20arrays,=20PRINT=20USING=20co?= =?UTF-8?q?lon=20fix,=20array=20assign=20fix=20=E2=80=94=2041/72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit READ into array elements: parse subscripts after variable name in READ handler, call gwrt_array_elem + gwrt_data_read. Unlocks matrix_mult, roman_numerals (partial). PRINT USING colon-in-string: scan past quoted strings when finding statement-end colon for token embedding. Fixes truncated format strings like "Pi estimate: #.####". Array element assignment: don't zero element before RHS evaluation. Previous code did `*_elem = {.type=4}` which zeroed fval before reading C(I,J) in `C(I,J) = C(I,J) + A(I,K)*B(K,J)`, making self-referencing assignments always read 0. DEF FN call fix: skip past TOK_FN byte before calling gw_eval_fn_call. DEFINT pre-scan: analysis pass processes DEFINT/DEFSNG/DEFDBL/DEFSTR before variable type resolution. Integer assignment rounding: use gw_cint() (rint) instead of (int16_t) C truncation. 41/72 tests pass. 0 compile errors. New: hundred_doors, matrix_mult, pascal_triangle, stats_calc. --- src/codegen.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index b5a7ed3..94859da 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1019,9 +1019,9 @@ static void emit_assignment(void) emit_str_expr(); EMIT(";\n _elem->type = VT_STR;\n"); } else { - EMIT(" *_elem = (gw_value_t){.type=%d};\n", type); + EMIT(" _elem->type = %d;\n", type); switch (type) { - case VT_INT: EMIT(" _elem->ival = (int16_t)("); break; + case VT_INT: EMIT(" _elem->ival = gw_cint((double)("); break; case VT_SNG: EMIT(" _elem->fval = (float)("); break; case VT_DBL: EMIT(" _elem->dval = (double)("); break; default: EMIT(" _elem->fval = (float)("); break; @@ -1086,7 +1086,12 @@ static void emit_stmt(void) /* Skip past USING token, then embed remaining bytes */ advance(); /* skip TOK_USING */ uint8_t *start = tp; - while (*tp && *tp != ':') tp++; + /* Scan to end of statement, skipping string literals */ + while (*tp) { + if (*tp == '"') { tp++; while (*tp && *tp != '"') tp++; if (*tp) tp++; continue; } + if (*tp == ':') break; + tp++; + } int len = (int)(tp - start); /* Sync compiled variables to interpreter table so gw_eval works */ EMIT(" {\n"); @@ -1760,7 +1765,38 @@ static void emit_stmt(void) if (is_letter(cur())) { char name[2]; gw_valtype_t type = parse_var(name); - if (type == VT_STR) { + skip_spaces(); + if (cur() == '(') { + /* READ into array element */ + advance(); + char *sbufs[8]; int nd = 0; + do { + if (nd > 0 && cur() == ',') advance(); + sbufs[nd++] = emit_to_buf(emit_prec_wrapper, 0); + } while (cur() == ',' && nd < 8); + if (cur() == ')') advance(); + EMIT(" { gw_value_t *_re = gwrt_array_elem("); + emit_name_str(name); + EMIT(", %d, %d, (int[]){", type, nd); + for (int d = 0; d < nd; d++) { + if (d > 0) EMIT(","); + EMIT("(int)(%s)", sbufs[d]); + free(sbufs[d]); + } + EMIT("});\n"); + if (type == VT_STR) { + EMIT(" gw_str_free(&_re->sval);\n"); + EMIT(" _re->sval = gw_str_from_cstr(gwrt_data_read());\n"); + EMIT(" _re->type = VT_STR; }\n"); + } else { + EMIT(" _re->type = %d;\n", type); + switch (type) { + case VT_INT: EMIT(" _re->ival = (int16_t)atof(gwrt_data_read()); }\n"); break; + case VT_DBL: EMIT(" _re->dval = atof(gwrt_data_read()); }\n"); break; + default: EMIT(" _re->fval = (float)atof(gwrt_data_read()); }\n"); break; + } + } + } else if (type == VT_STR) { EMIT(" gw_str_free(&"); emit_varname(name, type); EMIT(");\n"); @@ -1770,7 +1806,10 @@ static void emit_stmt(void) } else { EMIT(" "); emit_varname(name, type); - EMIT(" = (%s)atof(gwrt_data_read());\n", c_type(type)); + if (type == VT_INT) + EMIT(" = (int16_t)atof(gwrt_data_read());\n"); + else + EMIT(" = (%s)atof(gwrt_data_read());\n", c_type(type)); } } skip_spaces();