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

12 KiB

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
  2. Basic Syntax
  3. Data Types
  4. Variables
  5. Operators
  6. Control Flow
  7. Functions
  8. Standard Library
  9. Error Handling
  10. Examples

Getting Started

Running Bob Code

# 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

// 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

var name = "Bob";
var age = 25;
var isActive = true;

Assignment

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
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
// 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
// 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:

// 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:

// 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:

// 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

// 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:

// 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

"hello" * 3;             // → "hellohellohello"
3 * "hello";             // → "hellohellohello"

Note: String multiplication requires whole numbers.

Number Formatting

Bob automatically formats numbers to show only significant digits:

"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

// 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

// 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

// 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

// 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

func add(a, b) {
    return a + b;
}

Function Call

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:

var outerVar = "Outer";

func makeGreeter(greeting) {
    return greeting + " " + outerVar;
}

var greeter = makeGreeter("Hello");
// greeter captures outerVar from its lexical scope

Nested Functions

func outer() {
    func inner() {
        return 42;
    }
    return inner();
}

Standard Library

Print Function

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

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

// 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

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

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

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

// 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):

var x = 10;
x = 20;  // This is a statement, not an expression

Assignment Expressions (for loops only):

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.