Bob/BOB_LANGUAGE_REFERENCE.md
Bobby Lucero 72a1b82b43 More things
- Add while, for, and do-while loops with break/continue
- Implement assignment statements (prevents if(x=10) bugs)
- Keep assignment expressions only for for-loop clauses
- Fix critical memory management bug (dangling pointers in cleanup)
- Add automatic memory cleanup with conservative reference counting
- Consolidate documentation into single reference file
- Add comprehensive test coverage for all loop types and edge cases
- VSCode extension for bob highlighting and snippets
2025-08-06 00:57:36 -04:00

570 lines
12 KiB
Markdown

# Bob Language Reference
## Overview
Bob is a dynamically typed programming language focused on safety and clarity. It features automatic type conversion, closures, and a clean syntax inspired by modern programming languages.
## Table of Contents
1. [Getting Started](#getting-started)
2. [Basic Syntax](#basic-syntax)
3. [Data Types](#data-types)
4. [Variables](#variables)
5. [Operators](#operators)
6. [Control Flow](#control-flow)
7. [Functions](#functions)
8. [Standard Library](#standard-library)
9. [Error Handling](#error-handling)
10. [Examples](#examples)
## Getting Started
### Running Bob Code
```bash
# Compile the interpreter
make
# Run a Bob file
./build/bob your_file.bob
# Run the comprehensive test suite
./build/bob test_bob_language.bob
```
### File Extension
- **`.bob`**: Standard file extension for Bob source code
### Interactive Mode
- **Not implemented**: No REPL (Read-Eval-Print Loop) yet
- **File-based**: All code must be in `.bob` files
## Basic Syntax
### Statements
- **Semicolons**: Required at end of statements
- **Parentheses**: Required for function calls
- **Curly braces**: Required for function bodies
- **Case sensitive**: `var` and `Var` are different
### Comments
```go
// Single line comment
/* Multi-line comment */
```
## Data Types
### Numbers
- **Integers**: `42`, `-10`, `0`
- **Floats**: `3.14`, `2.718`, `-1.5`
- **Automatic conversion**: Numbers are stored as doubles internally
### Strings
- **Literal strings**: `"Hello, World!"`
- **Empty strings**: `""`
- **Escape sequences**: Not currently supported
### Booleans
- **True**: `true`
- **False**: `false`
### None
- **Null value**: `none` (represents absence of value)
## Variables
### Declaration
```go
var name = "Bob";
var age = 25;
var isActive = true;
```
### Assignment
```go
var x = 10;
x = 20; // Reassignment
```
### Scoping
- **Global scope**: Variables declared at top level
- **Local scope**: Variables declared inside functions
- **Shadowing**: Local variables can shadow global variables
- **No `global` keyword**: Unlike Python, Bob doesn't require explicit global declaration
```go
var globalVar = 100;
func testScope() {
var localVar = 50; // Local variable
return localVar + globalVar; // Can access global
}
```
### Assignment System
Bob uses two assignment systems for safety and practicality:
#### Assignment Statements
- **Purpose**: Main way to assign values
- **Syntax**: `variable = value;` (with semicolon)
- **Context**: Standalone statements
```go
// Assignment statements (most common)
var x = 5;
x = 10; // Regular assignment
y += 5; // Compound assignment
z *= 2; // Compound assignment
```
#### Assignment Expressions (For Loops Only)
- **Purpose**: For loop clauses only
- **Syntax**: `variable = value` (without semicolon)
- **Context**: For loop initializers and increment clauses
```go
// Assignment expressions (for loops only)
for (var i = 0; i < 5; i = i + 1) { } // Assignment in increment
for (j = 0; j < 5; j += 1) { } // Assignment in initializer and increment
```
#### Why This Design?
**Prevents Common Bugs:**
```go
// This would be a bug in many languages:
if (x = 10) { } // Parse error - assignment in conditional
// Bob forces you to write:
x = 10;
if (x == 10) { } // Clear comparison
```
**Keeps Expressions Pure:**
```go
// Prevents side effects in expressions:
var result = (x = 10) + (y = 20); // Parse error
// Forces clean code:
x = 10;
y = 20;
var result = x + y; // Pure expression
```
**What's Blocked:**
```go
// These all cause parse errors:
var result = x = 10; // AssignExpr not allowed in expressions
var result = true ? (x = 10) : 0; // AssignExpr not allowed in ternary
var result = func(x = 10); // AssignExpr not allowed in function calls
var result = (x = 10) + 5; // AssignExpr not allowed in arithmetic
```
## Operators
### Arithmetic Operators
- **Addition**: `+`
- **Subtraction**: `-`
- **Multiplication**: `*`
- **Division**: `/`
- **Modulo**: `%`
### Comparison Operators
- **Equal**: `==`
- **Not equal**: `!=`
- **Greater than**: `>`
- **Less than**: `<`
- **Greater than or equal**: `>=`
- **Less than or equal**: `<=`
### Logical Operators
- **And**: `&&`
- **Or**: `||`
- **Not**: `!`
### Conditional (Ternary) Operator
```go
// Basic ternary operator
var result = condition ? valueIfTrue : valueIfFalse;
// Examples
var max = x > y ? x : y;
var status = age >= 18 ? "adult" : "minor";
var message = x > 0 ? "positive" : "non-positive";
// Ternary with expressions
var result = x + y > 10 ? x * y : x + y;
// Ternary with function calls
var value = condition ? getValue() : getOtherValue();
// Nested ternary expressions
var result = x == 5 ? (y == 10 ? "both true" : "x true") : "x false";
```
**Precedence**: The ternary operator has lower precedence than logical operators (`&&`, `||`) but higher than assignment operators.
### String Operators
#### Concatenation
Bob supports bidirectional string + number concatenation with automatic type conversion:
```go
// String + Number
"Hello " + 42; // → "Hello 42"
"Pi: " + 3.14; // → "Pi: 3.14"
// Number + String
42 + " items"; // → "42 items"
3.14 + " is pi"; // → "3.14 is pi"
```
#### String Multiplication
```go
"hello" * 3; // → "hellohellohello"
3 * "hello"; // → "hellohellohello"
```
**Note**: String multiplication requires whole numbers.
### Number Formatting
Bob automatically formats numbers to show only significant digits:
```go
"Count: " + 2.0; // → "Count: 2" (no trailing zeros)
"Pi: " + 3.14; // → "Pi: 3.14" (exact precision)
"Integer: " + 42; // → "Integer: 42" (no decimal)
```
## Control Flow
### If Statements
```go
// Basic if statement
if (x > 10) {
print("x is greater than 10");
}
// If-else statement
if (x > 10) {
print("x is greater than 10");
} else {
print("x is 10 or less");
}
// If-else if-else chain
if (x > 10) {
print("x is greater than 10");
} else if (x > 5) {
print("x is greater than 5");
} else {
print("x is 5 or less");
}
```
### While Loops
```go
// Basic while loop
var i = 0;
while (i < 5) {
print(i);
i = i + 1;
}
// While loop with break (using return)
func countToThree() {
var i = 0;
while (true) {
i = i + 1;
if (i > 3) {
return i;
}
}
}
```
### For Loops
```go
// Basic for loop
for (var i = 0; i < 5; i = i + 1) {
print(i);
}
// For loop with no initializer
var j = 0;
for (; j < 3; j = j + 1) {
// Empty body
}
// For loop with no condition (infinite loop with break)
for (var k = 0; ; k = k + 1) {
if (k >= 2) {
break; // or return
}
}
// For loop with no increment
for (var n = 0; n < 3; ) {
n = n + 1;
}
```
### Do-While Loops
```go
// Basic do-while loop
var i = 0;
do {
print(i);
i = i + 1;
} while (i < 5);
// Do-while with break
var j = 0;
do {
j = j + 1;
if (j == 3) {
break;
}
} while (j < 10);
// Do-while with continue
var k = 0;
var sum = 0;
do {
k = k + 1;
if (k == 2) {
continue;
}
sum = sum + k;
} while (k < 5);
```
### Loop Features
- **Nested loops**: While, for, and do-while loops can be nested
- **Complex conditions**: Loops support any boolean expression
- **Function calls**: Loop conditions and bodies can contain function calls
- **Return statements**: Loops can be exited using return statements
- **Break and continue**: All loop types support break and continue statements
- **Variable scoping**: Variables declared in for loop initializers are scoped to the loop
- **Do-while behavior**: Do-while loops always execute the body at least once before checking the condition
## Functions
### Function Declaration
```go
func add(a, b) {
return a + b;
}
```
### Function Call
```go
var result = add(2, 3); // result = 5
```
### Parameters
- **Any number of parameters** supported
- **No default parameters** (not implemented)
- **No keyword arguments** (not implemented)
### Return Values
- **Explicit return**: `return value;`
- **Implicit return**: Functions return `none` if no return statement
- **Early return**: Functions can return from anywhere
### Closures
Bob supports lexical closures with variable capture:
```go
var outerVar = "Outer";
func makeGreeter(greeting) {
return greeting + " " + outerVar;
}
var greeter = makeGreeter("Hello");
// greeter captures outerVar from its lexical scope
```
### Nested Functions
```go
func outer() {
func inner() {
return 42;
}
return inner();
}
```
## Standard Library
### Print Function
```go
print("Hello, World!");
print(42);
print(true);
```
**Usage**: `print(expression)`
- Prints the result of any expression
- Automatically converts values to strings
- Adds newline after output
### Assert Function
```go
assert(condition, "optional message");
```
**Usage**:
- `assert(true)` - passes silently
- `assert(false)` - throws error and stops execution
- `assert(condition, "message")` - includes custom error message
**Behavior**:
- Terminates program execution on failure
- No exception handling mechanism (yet)
- Useful for testing and validation
## Error Handling
### Current Error Types
- **Division by zero**: `DivisionByZeroError`
- **Type errors**: `Operands must be of same type`
- **String multiplication**: `String multiplier must be whole number`
- **Assertion failures**: `Assertion failed: condition is false`
### Error Behavior
- **No try-catch**: Exception handling not implemented
- **Program termination**: Errors stop execution immediately
- **Error messages**: Descriptive error messages printed to console
### Common Error Scenarios
```go
// Division by zero
10 / 0; // Error: DivisionByZeroError
// Type mismatch
"hello" - "world"; // Error: Cannot use '-' on two strings
// Invalid string multiplication
"hello" * 3.5; // Error: String multiplier must be whole number
// Undefined variable
undefinedVar; // Error: Undefined variable
```
## Examples
### Basic Calculator
```go
func add(a, b) {
return a + b;
}
func multiply(a, b) {
return a * b;
}
var result = add(5, multiply(3, 4));
print("Result: " + result); // Result: 17
```
### String Processing
```go
func greet(name) {
return "Hello, " + name + "!";
}
func repeat(str, count) {
return str * count;
}
var greeting = greet("Bob");
var repeated = repeat("Ha", 3);
print(greeting + " " + repeated); // Hello, Bob! HaHaHa
```
### Variable Scoping Example
```go
var globalCounter = 0;
func increment() {
var localCounter = 1;
globalCounter = globalCounter + localCounter;
return globalCounter;
}
print("Before: " + globalCounter); // Before: 0
increment();
print("After: " + globalCounter); // After: 1
```
### Loop Examples
```go
// Count from 1 to 5
for (var i = 1; i <= 5; i = i + 1) {
print("Count: " + i);
}
// Sum numbers from 1 to 10
var sum = 0;
for (var j = 1; j <= 10; j = j + 1) {
sum = sum + j;
}
print("Sum: " + sum);
// Find first even number
var k = 1;
while (k % 2 != 0) {
k = k + 1;
}
print("First even: " + k);
```
## Implementation Details
### Assignment System: Statements vs Expressions
Bob uses a dual assignment system to prevent common programming errors:
**Assignment Statements** (general use):
```go
var x = 10;
x = 20; // This is a statement, not an expression
```
**Assignment Expressions** (for loops only):
```go
for (var i = 0; i < 10; i = i + 1) { // Assignment in increment clause
print(i);
}
```
**Why This Design?**
- **Prevents `if (x = 10)` bugs**: Assignment statements can't be used in conditions
- **Maintains loop functionality**: For loops still work with assignment expressions
- **Clear intent**: Distinguishes between intentional assignments and accidental ones
### Memory Management
Bob uses automatic memory management with conservative cleanup:
**Reference Counting**:
- All objects use `std::shared_ptr` for automatic cleanup
- Functions and thunks are tracked by reference count
- Objects are freed when no longer referenced
**Automatic Cleanup**:
- Functions created in loops are automatically cleaned up when unused
- Cleanup occurs every 1000 function/thunk creations
- Only removes objects with `use_count() == 1` (conservative approach)
**Safety Guarantees**:
- Functions referenced anywhere are never cleaned up
- Only truly unused functions are removed
- No dangling pointers or memory corruption
---
*This documentation covers the current Bob language implementation. For development plans, see ROADMAP.md.*