MBASIC Compiler - Variable Types and Naming¶
Overview¶
In MBASIC, variables with the same base name but different type suffixes are separate variables. This document explains how the BASIC-to-C and BASIC-to-JavaScript compilers handle variable types and naming.
BASIC Type Suffixes¶
| Suffix | Type | Example | C Type | JS Coercion |
|---|---|---|---|---|
% |
INTEGER | FOO% |
int |
_toInt() |
! |
SINGLE | FOO! |
float |
none (default) |
# |
DOUBLE | FOO# |
double |
none |
$ |
STRING | FOO$ |
string pool | _str suffix |
Same Name, Different Types = Different Variables¶
In BASIC, FOO, FOO%, FOO!, FOO#, and FOO$ can ALL exist in the same program as separate variables:
10 FOO = 3.14159 ' SINGLE precision (default)
20 FOO% = 42 ' INTEGER - different variable!
30 FOO# = 2.718281828 ' DOUBLE - different variable!
40 FOO$ = "hello" ' STRING - different variable!
50 PRINT FOO; FOO%; FOO#; FOO$
Generated C Code¶
The C backend adds type suffixes to variable names to distinguish them:
float foo; // FOO (SINGLE - default, no suffix)
int foo_int; // FOO% (INTEGER)
double foo_dbl; // FOO# (DOUBLE)
// FOO$ uses string pool ID, not a C variable
Generated JavaScript Code¶
let foo = 0; // FOO (SINGLE - default)
let foo_int = 0; // FOO% (INTEGER)
let foo_dbl = 0; // FOO# (DOUBLE)
let foo_str = ""; // FOO$ (STRING)
Variables Without Explicit Type Suffix¶
When a variable has no explicit type suffix, its type is determined by:
- DEFINT/DEFSNG/DEFDBL/DEFSTR statements - Define default type by first letter
- Default - SINGLE precision (
!) if no DEF statement applies
Example with DEF Statements¶
10 DEFINT I-N ' Variables starting with I-N are INTEGER
20 DEFDBL D ' Variables starting with D are DOUBLE
30 I = 100 ' INTEGER (from DEFINT)
40 X = 3.14 ' SINGLE (default)
50 D = 2.71828 ' DOUBLE (from DEFDBL)
Generated symbol table keys:
- I → I% (INTEGER, from DEFINT)
- X → X! (SINGLE, default)
- D → D# (DOUBLE, from DEFDBL)
Internal Representation¶
The compiler's symbol table uses the full name with suffix as the key:
| BASIC Variable | Symbol Table Key | Generated Name (C) | Generated Name (JS) |
|---|---|---|---|
FOO (SINGLE) |
FOO! |
foo |
foo |
FOO% |
FOO% |
foo_int |
foo_int |
FOO# |
FOO# |
foo_dbl |
foo_dbl |
FOO$ |
FOO$ |
(string pool) | foo_str |
Type Coercion at Assignment¶
Both backends apply type coercion when assigning values to typed variables:
INTEGER Variables (%)¶
I% = 3.7 ' Truncates to 3 (toward zero)
I% = -3.7 ' Truncates to -3 (toward zero)
I% = 32768 ' Clamps to 32767 (max INTEGER)
I% = -32769 ' Clamps to -32768 (min INTEGER)
- C backend: Relies on C's implicit
intconversion - JS backend: Uses
_toInt()function (truncate toward zero, clamp to -32768..32767)
SINGLE Variables (!)¶
- C backend: Uses C
floattype (32-bit) - JS backend: Uses
Math.fround()(ES6 single precision)
DOUBLE Variables (#)¶
- C backend: Uses C
doubletype (64-bit) - JS backend: Native JS Number (already 64-bit double)
Semantic Equivalence¶
Both the C and JavaScript backends produce semantically equivalent output for the same BASIC program. The same numeric values will be printed (within floating-point precision limits).
This allows programs to be compiled to either target and produce identical results, which is useful for: - Testing (compare C output vs JS output) - Cross-platform deployment (CP/M vs browser) - Debugging (JS is easier to debug than compiled C)
Implementation Details¶
Symbol Table¶
The semantic analyzer (src/semantic_analyzer.py) stores variables with their full key:
- _get_var_key(var_node) returns the uppercase name with suffix (e.g., 'FOO%', 'FOO$')
- Variables without explicit suffix get the default suffix based on DEF statements or '!' for SINGLE
C Backend¶
src/codegen_backend.py:
- _mangle_variable_name() converts BASIC names to C identifiers
- Adds _int suffix for INTEGER, _dbl suffix for DOUBLE
- String variables use the string pool system (not C variables)
JavaScript Backend¶
src/codegen_js_backend.py:
- _mangle_var_name() converts BASIC names to JS identifiers
- Adds _int, _dbl, _str suffixes as needed
- _apply_type_coercion() wraps assignments with type conversion functions