# JavaScript Backend User Guide

## Overview

The MBASIC-2025 JavaScript backend compiles MBASIC 5.21 programs into standalone JavaScript that runs in:
- **Web browsers** - Embed BASIC programs in web pages
- **Node.js** - Run from command line

Generated JavaScript is fully self-contained with no external dependencies.

## Quick Start

### Compile to JavaScript

```bash
# Basic compilation
python3 mbasic --compile-js output.js program.bas

# With HTML wrapper for browser
python3 mbasic --compile-js output.js --html program.bas
```

### Run in Browser

The `--html` flag generates an HTML file that loads your JavaScript:

```bash
python3 mbasic --compile-js game.js --html startrek.bas
# Creates: game.js and game.html
# Open game.html in any web browser
```

### Run with Node.js

```bash
python3 mbasic --compile-js program.js hello.bas
node program.js
```

The generated JavaScript has a shebang, so you can make it executable:

```bash
chmod +x program.js
./program.js
```

## Supported Features

### ✅ Fully Implemented (Phase 1-8)

**Control Flow:**
- GOTO, ON GOTO
- GOSUB, ON GOSUB, RETURN
- FOR/NEXT loops (with variable-indexed state tracking)
- WHILE/WEND loops
- IF/THEN/ELSE (single-line and multi-line)
- END, STOP

**Input/Output:**
- PRINT (with semicolon/comma separators)
- PRINT USING (formatted output with #, !, &, \\ specifiers)
- INPUT (browser: prompt dialogs, Node.js: readline)
- READ/DATA/RESTORE

**Variables & Arrays:**
- LET assignments
- DIM arrays (multi-dimensional)
- Array subscripts (0-based or 1-based via OPTION BASE)
- SWAP variable exchange
- ERASE array reset

**Functions:**
- DEF FN user-defined functions
- All math functions: ABS, INT, SQR, SIN, COS, TAN, ATN, LOG, EXP, RND
- Additional math: FIX, SGN, CINT, CSNG, CDBL
- All string functions: LEFT$, RIGHT$, MID$, LEN, CHR$, ASC, STR$, VAL
- String utilities: INSTR, SPACE$, STRING$, HEX$, OCT$
- Print formatting: TAB, SPC, POS

**Error Handling:**
- ON ERROR GOTO/GOSUB
- RESUME, RESUME NEXT, RESUME line
- ERROR statement
- ERL() and ERR() functions

### ⚠️ Not Implemented

**Medium Priority (rarely used):**
- MID$ assignment (modifying substrings in place)
- LINE INPUT
- WRITE statement
- LPRINT

**Low Priority (advanced/specialized):**
- File I/O (OPEN, CLOSE, PRINT #, INPUT #, etc.)
- CHAIN and COMMON
- Hardware access (POKE, PEEK, OUT, INP, CALL, USR)

**Not Applicable:**
- Interactive commands (LIST, NEW, RUN, LOAD, SAVE, RENUM)
- Debugger commands (TRON, TROFF, STEP, CONT)

## Examples

### Hello World

```basic
10 PRINT "Hello, World!"
20 END
```

Compile and run:
```bash
python3 mbasic --compile-js hello.js --html hello.bas
# Open hello.html in browser
```

### Interactive Program

```basic
10 PRINT "What is your name?"
20 INPUT N$
30 PRINT "Hello, "; N$; "!"
40 END
```

Browser: Uses `prompt()` dialogs
Node.js: Uses readline for input

### Game Example

```basic
10 REM Number guessing game
20 RANDOMIZE
30 N = INT(RND * 100) + 1
40 PRINT "I'm thinking of a number 1-100"
50 INPUT "Your guess"; G
60 IF G < N THEN PRINT "Too low!" : GOTO 50
70 IF G > N THEN PRINT "Too high!" : GOTO 50
80 PRINT "Correct! You win!"
90 END
```

### Formatted Output

```basic
10 PRINT "Price Report"
20 PRINT "==========="
30 FOR I = 1 TO 5
40   PRICE = I * 9.99
50   PRINT USING "Item ##: $###.##"; I; PRICE
60 NEXT I
70 END
```

## Generated Code Structure

The compiled JavaScript follows this structure:

```javascript
#!/usr/bin/env node
// Generated by MBASIC-2025 JavaScript Backend

(function() {
  'use strict';

  // Runtime library (math, string, I/O functions)

  // Variable declarations
  let var1 = 0, var2_str = "";
  let array1 = [...];

  // DATA values
  const _data = [10, 20, "hello"];

  // Main execution loop
  let _pc = 10;  // Program counter
  while (_pc !== null) {
    switch (_pc) {
      case 10:
        // Line 10 statements
        break;
      case 20:
        // Line 20 statements
        break;
      // ...
    }
  }
})();
```

### Key Implementation Details

**Control Flow:**
- Uses a switch statement with program counter (`_pc`)
- GOTO/GOSUB implemented as `_pc = line_number`
- FOR loops use variable-indexed state tracking
- Matches Super Star Trek's complex control flow patterns

**Runtime Detection:**
- Automatically detects browser (`window`) vs Node.js (`process`)
- Single JavaScript file works in both environments
- Browser uses `document.getElementById("output")` for PRINT
- Node.js uses `console.log()` and `process.stdout.write()`

**INPUT Handling:**
- Browser: `window.prompt()` dialogs
- Node.js: Synchronous readline with `readline-sync` fallback

## HTML Wrapper

The `--html` flag generates a retro terminal-styled HTML page:

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>MBASIC Program: program.bas</title>
  <style>
    body {
      font-family: 'Courier New', monospace;
      background: black;
      color: #00ff00;
      padding: 20px;
    }
    #output {
      white-space: pre;
      line-height: 1.4;
    }
  </style>
</head>
<body>
  <div id="output"></div>
  <script src="program.js"></script>
</body>
</html>
```

## Performance

**Compilation Speed:**
- Simple programs: < 0.1 seconds
- Super Star Trek (3500+ lines): ~0.5 seconds

**Generated Code Size:**
- Runtime library: ~10KB
- Simple hello world: ~12KB total
- Super Star Trek: ~92KB (3524 lines of JavaScript)

**Execution Speed:**
- JavaScript JIT compilation provides excellent performance
- Typically faster than interpreted BASIC
- Similar performance to native C compiled code for compute-intensive tasks

## Troubleshooting

### Compilation Errors

**"Unknown statement or command: 'CLS'"**
- CLS is NOT part of MBASIC 5.21 (it's from GW-BASIC/QuickBASIC)
- Your program is not MBASIC 5.21 compatible
- Remove or comment out CLS statements to make it compatible

**"Parse error"**
- Check for syntax errors in BASIC code
- MBASIC-2025 is strict MBASIC 5.21 compatible

### Runtime Errors

**"_gosub is not defined"**
- Internal compiler bug - please report
- Try recompiling

**INPUT not working in browser**
- Ensure browser allows `prompt()` dialogs
- Some browsers block prompts on page load

**Program doesn't start in Node.js**
- Ensure file has execute permissions: `chmod +x program.js`
- Or run explicitly: `node program.js`

## Compatibility

**Works in:**
- ✅ Chrome/Chromium
- ✅ Firefox
- ✅ Safari
- ✅ Edge
- ✅ Node.js 12+

**Browser Requirements:**
- ES6 support (2015+)
- `const`, `let`, arrow functions
- Template literals
- `Math.trunc()` for integer operations

**Node.js Requirements:**
- Node.js 12 or later
- No external packages required for basic programs
- `readline-sync` package optional for better INPUT support

## Tips & Best Practices

1. **Always test in target environment first**
   - Browser behavior differs from Node.js
   - Test INPUT handling specifically

2. **Use --html for web deployment**
   - Generates ready-to-use HTML wrapper
   - Includes retro terminal styling
   - Easy to customize the CSS

3. **Keep programs self-contained**
   - File I/O not supported
   - Use DATA statements for static data
   - Use INPUT for dynamic data

4. **Error handling is your friend**
   - Use ON ERROR GOTO for robust programs
   - Check ERL() and ERR() for debugging
   - RESUME NEXT to skip errors

5. **PRINT USING for formatted output**
   - Much better than manual formatting
   - Supports numeric and string formatting
   - Formats: # (numbers), ! (first char), & (full string), \\ (fixed width)

## Advanced Usage

### Embedding in Web Pages

You can embed the generated JavaScript in your own HTML:

```html
<!DOCTYPE html>
<html>
<head>
  <title>My BASIC Game</title>
</head>
<body>
  <h1>Play My Game</h1>
  <div id="output"></div>
  <script src="game.js"></script>
</body>
</html>
```

The JavaScript looks for an element with `id="output"` to display PRINT statements.

### Customizing Output

Modify the runtime library in generated JavaScript:

```javascript
function _print(str, newline = true) {
  // Custom implementation
  const output = document.getElementById("custom-output");
  output.innerHTML += str;
  if (newline) output.innerHTML += "<br>";
}
```

### Multiple Programs

You can run multiple BASIC programs on one page by namespacing:

```bash
python3 mbasic --compile-js game1.js game1.bas
python3 mbasic --compile-js game2.js game2.bas
```

Then load both:
```html
<div id="output-game1"></div>
<script src="game1.js"></script>

<div id="output-game2"></div>
<script src="game2.js"></script>
```

(Note: You'll need to modify the runtime to target different output divs)

## See Also

- [JavaScript Backend Spec](../design/JAVASCRIPT_BACKEND_SPEC.md) - Design documentation
- [Unimplemented Features](../dev/JS_BACKEND_UNIMPLEMENTED.md) - What's not yet implemented
- [Remaining Features](../dev/JS_BACKEND_REMAINING.md) - Prioritized feature list

## Version

This guide is for MBASIC-2025 version 1.0.908 (2025-11-13)

JavaScript backend: **Phase 1-8 Complete** (~95% MBASIC 5.21 coverage)
