Four roadmap items: - codegen: fix parenthesized string comparison. emit_atom didn't consume the body of a string-literal token (`"`), so for PRINT (A$+B$ < "ZZZ") it emitted a 0 placeholder, advanced one byte, and left "ZZZ" to be reparsed as a variable + extra trailing tokens -- the binary then failed to link with `var_ZZ_sng` undeclared. emit_atom now skips to the closing quote. Separately, the left_type tracking in emit_num_prec dropped VT_STR after a string + string concat (becoming VT_SNG), so the string-comparison codepath skipped when the relational operator arrived. Preserve VT_STR through TOK_PLUS when both operands are strings. Verified: paren string-cmp now compiles and produces the same -1 / 0 result as the interpreter. - compiler: --no-gc-check and --fast-math optimization flags. --no-gc-check skips the per-line gwrt_check_line() (no string-pool GC, no Ctrl+Break trap). --fast-math drops the divide-by-zero guard on `/`; the divisor still goes through (double) so 10/0 produces inf rather than SIGFPE. Both threaded through codegen_opts_t and exposed in --help. --inline-arrays from the roadmap deferred -- larger refactor. - interp: raise static caps on 32-bit / Linux builds. vars 256 -> 1024, arrays 64 -> 256, MAX_FOR_DEPTH 16 -> 64, MAX_GOSUB_DEPTH 24 -> 128, MAX_WHILE_DEPTH 16 -> 64. Codegen FOR_STACK_MAX 16 -> 64. Analysis-pass caps: MAX_LINES 4096 -> 8192, MAX_VARS 256 -> 1024, MAX_GOTOS 256 -> 1024, MAX_DATA 1024 -> 4096, MAX_GOSUB_RET 256 -> 1024. 16-bit DOS keeps the original modest caps via #ifdef _M_I86 -- the MEDIUM model has a single 64KB DGROUP for all static data and the bumped sizes broke runtime startup under DOSBox-X. 16-bit binary grew from 128KB to 132KB from the offset_secs field plus DATE$/TIME$ shift code, well within the FreeDOS budget. - interp + codegen: DATE$ / TIME$ assignment via process-local clock offset. Was a no-op accept-and-ignore. Now sets gw.time_offset_secs (long), and DATE$ / TIME$ / TIMER readers apply it to time(NULL) before formatting. The OS clock is unaffected (would need root). Compiled-binary readers also reference gw.time_offset_secs since libgwrt shares the gw struct. Verified: PRINT DATE$; DATE$="12-31-1999"; PRINT DATE$ shows the expected before/after in both interpreter and AOT paths. After these changes: 72/72 interpreter tests, 68/68 compat, 63/63 compiler tests, DOS smoke under DOSBox-X all pass. Build clean on both Linux (cmake) and 16-bit DOS (build_dos.sh 16).
63 lines
1.6 KiB
C
63 lines
1.6 KiB
C
#ifndef ANALYSIS_H
|
|
#define ANALYSIS_H
|
|
|
|
#include "types.h"
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#define MAX_LINES 8192
|
|
#define MAX_VARS 1024
|
|
#define MAX_GOTOS 1024
|
|
#define MAX_DATA 4096
|
|
#define MAX_GOSUB_RET 1024
|
|
|
|
typedef struct {
|
|
uint16_t line_num;
|
|
bool is_target; /* referenced by GOTO/GOSUB/etc. */
|
|
bool has_data; /* contains DATA statement */
|
|
int data_start; /* index into data pool */
|
|
} line_info_t;
|
|
|
|
typedef struct {
|
|
char name[2];
|
|
gw_valtype_t type;
|
|
uint16_t first_assign_line; /* 0 = never assigned */
|
|
uint16_t first_use_line; /* 0 = never used */
|
|
} var_info_t;
|
|
|
|
typedef struct {
|
|
line_info_t lines[MAX_LINES];
|
|
int line_count;
|
|
|
|
var_info_t vars[MAX_VARS];
|
|
int var_count;
|
|
|
|
uint16_t goto_targets[MAX_GOTOS];
|
|
int goto_count;
|
|
|
|
char *data_pool[MAX_DATA]; /* collected DATA literals */
|
|
int data_count;
|
|
|
|
int data_line_map[MAX_LINES][2]; /* [line_num, data_start_index] */
|
|
int data_line_count;
|
|
|
|
gw_valtype_t def_type[26]; /* from DEFINT/DEFSNG/DEFDBL/DEFSTR */
|
|
} analysis_t;
|
|
|
|
/* Run analysis pass over the loaded program */
|
|
void analysis_run(analysis_t *a);
|
|
|
|
/* Find a variable in the census, return index or -1 */
|
|
int analysis_find_var(analysis_t *a, const char name[2], gw_valtype_t type);
|
|
|
|
/* Add a variable to the census if not already present */
|
|
int analysis_add_var(analysis_t *a, const char name[2], gw_valtype_t type);
|
|
|
|
/* Check if a line number is a jump target */
|
|
bool analysis_is_target(analysis_t *a, uint16_t line_num);
|
|
|
|
/* Emit static analysis warnings to stderr */
|
|
void analysis_warnings(analysis_t *a);
|
|
|
|
#endif
|