diff options
Diffstat (limited to 'js/scripting-lang/README.md')
-rw-r--r-- | js/scripting-lang/README.md | 845 |
1 files changed, 169 insertions, 676 deletions
diff --git a/js/scripting-lang/README.md b/js/scripting-lang/README.md index 6ea5104..73ccbf1 100644 --- a/js/scripting-lang/README.md +++ b/js/scripting-lang/README.md @@ -1,727 +1,220 @@ # Simple Scripting Language -A minimal, interpreted scripting language designed for learning language implementation concepts. This language demonstrates the core components needed for an interpreter: lexer, parser, and interpreter. +A functional programming language with immutable variables, first-class functions, and pattern matching. ## Features -- **Arithmetic operations**: `+`, `-`, `*`, `/`, `%` (modulo), `^` (power) -- **Comparison operators**: `=`, `<`, `>`, `<=`, `>=`, `!=` -- **Logical operators**: `and`, `or`, `xor`, `not` -- **Variable assignment**: Immutable variables with `:` syntax -- **Function definitions**: Arrow function syntax with pattern matching -- **Pattern matching**: Case expressions with wildcard support -- **Function calls**: Direct function application -- **First-class functions**: Functions can be passed as arguments using `@` syntax -- **Function composition**: Higher-order functions for combining functions -- **Lexical scoping**: Functions create their own scope -- **Input/Output**: Built-in IO operations with `..in`, `..out`, and `..assert` -- **Standard Library**: Built-in functional programming utilities -- **Comments**: C-style block comments with `/* ... */` syntax -- **Tables**: Lua-style immutable tables with array and object capabilities +- **Immutable Variables**: Variables cannot be reassigned +- **First-Class Functions**: Functions can be passed as arguments and stored in data structures +- **Lexical Scoping**: Functions create their own scope +- **Pattern Matching**: Case expressions with wildcard support +- **Table Literals**: Lua-style tables with both array-like and key-value entries +- **Standard Library**: Built-in higher-order functions (`map`, `compose`, `pipe`, `apply`, `filter`, `reduce`, `fold`, `curry`) +- **IO Operations**: Built-in input/output operations (`..in`, `..out`, `..assert`) +- **Floating Point Arithmetic**: Full support for decimal numbers +- **Unary Minus**: Support for negative numbers (e.g., `-1`, `-3.14`) ## Syntax -### Variables - -Variables are immutable and assigned using the `:` operator: - -``` -x : 5; -y : 10; -``` - -### Arithmetic Operations - -Arithmetic operations are supported with parentheses grouping: - -``` -sum : x + y; -diff : x - y; -product : x * y; -quotient : x / y; -modulo : 17 % 5; /* Returns 2 */ -power : 2 ^ 3; /* Returns 8 */ -grouped : (5 + 3) * 2; /* Returns 16 */ -nested : ((5 + 3) * 2) + 1; /* Returns 17 */ -``` - -### Function Definitions - -Functions are defined using arrow syntax (`->`): - +### Basic Operations ``` -add : x y -> x + y; -double : x -> x * 2; -``` - -### Function Calls +/* Arithmetic */ +x : 5 + 3; +y : 10 - 2; +z : 4 * 3; +w : 15 / 3; +neg : -5; /* Unary minus */ -Functions are called by providing arguments directly after the function name: +/* Comparisons */ +result : x > y; +equal : a = b; +not_equal : a != b; +/* Logical */ +and_result : true and false; +or_result : true or false; ``` -result : add 3 4; -doubled : double 5; -``` - -#### Function Calls with Parentheses - -Function calls support parenthesized arguments for complex expressions: +### Variables and Functions ``` -/* Simple function call */ -result1 : add 3 4; +/* Immutable variables */ +x : 42; +y : "hello"; -/* Function call with parenthesized arithmetic */ -result2 : add (3 + 2) (4 + 1); +/* Function definition */ +f : x -> x * 2; -/* Function call with function calls in parentheses */ -result3 : add (double 3) (square 2); - -/* Complex nested function calls with parentheses */ -result4 : add (add 1 2) (add 3 4); +/* Function call */ +result : f 5; ``` -**Note:** Parentheses provide explicit grouping and are the recommended way to handle complex nested function calls. - ### Tables - -The language supports Lua-style immutable tables that can serve as both arrays and objects: - -#### Table Creation - -Tables are created using curly braces `{}`: - -``` -/* Empty table */ -empty : {}; - -/* Array-like table (1-indexed) */ -numbers : {1, 2, 3, 4, 5}; - -/* Key-value table */ -person : {name: "Alice", age: 30, active: true}; - -/* Mixed table (array-like and key-value) */ -mixed : {1, name: "Bob", 2, active: false}; ``` +/* Table literal */ +table : {1, 2, 3, key: "value"}; -#### Table Access - -Tables support both bracket notation and dot notation for accessing values: - +/* Table access */ +first : table[1]; +value : table.key; +nested : table.key.subkey; ``` -/* Array access with bracket notation */ -first : numbers[1]; /* Returns 1 */ -second : numbers[2]; /* Returns 2 */ - -/* Object access with dot notation */ -name : person.name; /* Returns "Alice" */ -age : person.age; /* Returns 30 */ - -/* Object access with bracket notation */ -name_bracket : person["name"]; /* Returns "Alice" */ -age_bracket : person["age"]; /* Returns 30 */ - -/* Mixed table access */ -first_mixed : mixed[1]; /* Returns 1 */ -name_mixed : mixed.name; /* Returns "Bob" */ -second_mixed : mixed[2]; /* Returns 2 */ -``` - -#### Table Features - -- **Immutable**: Tables cannot be modified after creation -- **1-indexed arrays**: Array-like tables start indexing at 1 -- **Mixed types**: Tables can contain numbers, strings, booleans, and functions -- **Nested access**: Tables can contain other tables for complex data structures -- **Unified syntax**: Same syntax for arrays and objects - -#### Tables with Case Expressions - -Tables work well with case expressions for pattern matching: - -``` -/* Case expressions with table values */ -person : {name: "Alice", age: 30, active: true}; -result : case person.age of - 0 : 30 : "Person is 30" - 1 : _ : "Person is different age" -; - -/* Case expressions with boolean values */ -status : case person.active of - 0 : true : "Person is active" - 1 : false : "Person is inactive" -; - -/* Case expressions with array-like access */ -numbers : {1: 10, 2: 20, 3: 30}; -element : case numbers[2] of - 0 : 20 : "Second element is 20" - 1 : _ : "Unexpected second element" -; -``` - -**Current Limitations:** -- Function calls from tables (e.g., `table.func args`) are not supported -- Function definitions inside table literals are not supported -- Tables can store function references, but they cannot be called directly - -### First-Class Functions - -Functions can be passed as arguments to other functions using the `@` prefix: - -``` -double : x -> x * 2; -square : x -> x * x; -compose : f g x -> f g x; - -composed : compose @double @square 3; /* double(square(3)) = 18 */ -``` - -**Function Reference Syntax:** -- `@functionName` - Creates a function reference (doesn't execute the function) -- `functionName args` - Calls the function with arguments ### Pattern Matching - -The language supports pattern matching with case expressions in function bodies: - -``` -compare : x y -> - case x y of - 0 0 : "both zero" - 0 _ : "x is zero" - _ 0 : "y is zero" - _ _ : "neither zero"; -``` - -#### Pattern Matching Syntax - -- **Exact matches**: `0 0` matches when both values are 0 -- **Wildcards**: `_` matches any value -- **Mixed patterns**: `0 _` matches when first value is 0 and second can be anything - -### Comparison and Logical Operations - -The language supports comparison and logical operations: - -``` -/* Comparison operators */ -less : 3 < 5; /* true */ -greater : 10 > 5; /* true */ -equal : 5 = 5; /* true */ -not_equal : 3 != 5; /* true */ -less_equal : 5 <= 5; /* true */ -greater_equal : 5 >= 3; /* true */ - -/* Logical operators */ -and_result : 1 and 1; /* true */ -or_result : 0 or 1; /* true */ -xor_result : 1 xor 0; /* true */ -not_result : not 0; /* true */ -``` - -### Comments - -The language supports C-style block comments: - -``` -/* This is a single line comment */ - -/* This is a multi-line comment - that spans multiple lines */ - -x : 5; /* Comment on same line as code */ - -/* Nested comments are supported */ -/* Outer comment /* Inner comment */ More outer comment */ -``` - -**Comment Features:** -- Block comments start with `/*` and end with `*/` -- Comments can span multiple lines -- Comments can appear on the same line as code -- Nested comments are supported -- Comments are completely ignored by the lexer and parser - -### Input/Output Operations - -The language provides built-in IO operations for reading from stdin and writing to stdout: - -``` -name : ..in; /* Read input from stdin */ -..out name; /* Output to stdout */ -..out "Hello"; /* Output string literal */ -..out 42; /* Output number */ -..assert x = 5; /* Assert that x equals 5 */ -..assert y > 3; /* Assert that y is greater than 3 */ -..assert z != 0; /* Assert that z is not equal to 0 */ -``` - -**IO Functions:** -- `..in` - Reads a line from stdin, returns a number if possible, otherwise a string -- `..out` - Outputs a value to stdout and returns the value -- `..assert` - Asserts that a comparison is true, throws an error if it's false. Supports all comparison operators: `=`, `<`, `>`, `<=`, `>=`, `!=` - -**Note:** The `..` prefix indicates these are impure operations that have side effects. - -## Standard Library - -The language includes a built-in standard library with functional programming utilities: - -### Higher-Order Functions - -- **map**: Apply a function to a value (`map f x = f x`) -- **compose**: Compose two functions (`compose f g x = f(g(x))`) -- **curry**: Explicit currying (`curry f x y = f x y`) -- **apply**: Apply a function to an argument (`apply f x = f x`) -- **pipe**: Compose functions left-to-right (`pipe f g x = g(f(x))`) -- **filter**: Filter based on a predicate (`filter p x = p(x) ? x : 0`) -- **reduce**: Reduce to a single value (`reduce f init x = f(init, x)`) -- **fold**: Same as reduce (`fold f init x = f(init, x)`) - -### Usage Examples - ``` -double : x -> x * 2; -square : x -> x * x; - -/* Using map */ -result1 : map @double 5; /* Returns 10 */ -result2 : map @square 3; /* Returns 9 */ - -/* Using compose */ -composed : compose @double @square 3; /* double(square(3)) = 18 */ - -/* Using pipe */ -piped : pipe @double @square 2; /* square(double(2)) = 16 */ - -/* Using filter */ -isPositive : x -> x > 0; -filtered : filter @isPositive 5; /* Returns 5 (since 5 > 0) */ +/* Case expression */ +result : case x of + 1 : "one" + 2 : "two" + _ : "other"; ``` - - -## Language Components - -### Lexer - -The lexer tokenizes input into meaningful units: -- Numbers: `123` -- Identifiers: `variable_name` -- Operators: `+`, `-`, `*`, `/` -- Keywords: `case`, `of`, `function` -- Symbols: `:`, `->`, `_` - -### Parser - -The parser builds an Abstract Syntax Tree (AST) from tokens, supporting: -- Number literals -- Arithmetic expressions -- Variable assignments -- Function declarations -- Function calls -- Case expressions -- Pattern matching - -### Interpreter - -The interpreter executes the AST with: -- Global scope management -- Function evaluation -- Pattern matching execution -- Arithmetic computation -- Immutable variable semantics - -## Example Programs - -### Basic Arithmetic and Variables - -``` -/* Simple arithmetic with variables */ -x : 5; -y : 10; -sum : x + y; -diff : x - y; -product : x * y; -quotient : y / x; -modulo : 17 % 5; /* Returns 2 */ -power : 2 ^ 3; /* Returns 8 */ - -..out sum; /* 15 */ -..out diff; /* -5 */ -..out product; /* 50 */ -..out quotient; /* 2 */ -..out modulo; /* 2 */ -..out power; /* 8 */ - -/* Grouped expressions with parentheses */ -grouped : (5 + 3) * 2; /* 16 */ -nested : ((5 + 3) * 2) + 1; /* 17 */ -complex : (2 ^ 3) % 3 and 5 > 3; /* true */ -``` - -### Function Definitions and Calls - -``` -/* Basic function definition */ -add : x y -> x + y; -multiply : x y -> x * y; -double : x -> x * 2; -square : x -> x * x; - -/* Function calls */ -result1 : add 3 4; /* 7 */ -result2 : multiply 5 6; /* 30 */ -result3 : double 8; /* 16 */ -result4 : square 4; /* 16 */ - -/* Function calls with parenthesized arguments */ -result5 : add (3 + 2) (4 + 1); /* 15 */ -result6 : add (double 3) (square 2); /* 10 */ -result7 : add (add 1 2) (add 3 4); /* 10 */ -``` - -### Tables and Data Structures - -``` -/* Create various table types */ -empty : {}; -numbers : {1, 2, 3, 4, 5}; -person : {name: "Alice", age: 30, active: true}; -mixed : {1, name: "Bob", 2, active: false}; - -/* Access array elements */ -first : numbers[1]; -second : numbers[2]; -last : numbers[5]; - -/* Access object properties */ -name : person.name; -age : person.age; -active : person.active; - -/* Access mixed table */ -first_mixed : mixed[1]; -name_mixed : mixed.name; -second_mixed : mixed[2]; - -/* Output results */ -..out "First number: "; -..out first; -..out "Person name: "; -..out name; -..out "Mixed first: "; -..out first_mixed; -..out "Mixed name: "; -..out name_mixed; +### IO Operations ``` +/* Output */ +..out "Hello, World!"; -### Pattern Matching with Case Expressions +/* Input */ +name : ..in; +/* Assertion */ +..assert x = 5; ``` -/* Pattern matching in function bodies */ -compare : x y -> - case x y of - 0 0 : "both zero" - 0 _ : "x is zero" - _ 0 : "y is zero" - _ _ : "neither zero"; - -/* Testing pattern matching */ -test1 : compare 0 0; /* "both zero" */ -test2 : compare 0 5; /* "x is zero" */ -test3 : compare 5 0; /* "y is zero" */ -test4 : compare 5 5; /* "neither zero" */ - -/* Single-parameter case expressions */ -factorial : n -> - case n of - 0 : 1 - _ : n * (factorial (n - 1)); - -/* Single-parameter grade function */ -grade : score -> - case score of - 90 : "A" - 80 : "B" - 70 : "C" - _ : "F"; - -fact5 : factorial 5; /* 120 */ -grade1 : grade 95; /* "A" */ -grade2 : grade 85; /* "B" */ -grade3 : grade 65; /* "F" */ -``` - -### First-Class Functions and Composition +### Standard Library ``` -/* Function references and composition */ +/* Map */ double : x -> x * 2; -square : x -> x * x; -add1 : x -> x + 1; - -/* Using standard library functions */ -composed : compose @double @square 3; /* double(square(3)) = 18 */ -piped : pipe @double @square 2; /* square(double(2)) = 16 */ -applied : apply @double 5; /* double(5) = 10 */ - -/* Higher-order functions */ -mapped1 : map @double 5; /* 10 */ -mapped2 : map @square 3; /* 9 */ - -/* Function references in case expressions */ -getFunction : type -> - case type of - "double" : @double - "square" : @square - _ : @add1; - -func1 : getFunction "double"; /* Function reference */ -func2 : getFunction "square"; /* Function reference */ -``` - -### Recursion and Complex Functions - -``` -/* Recursive factorial function (using single-parameter case) */ -factorial : n -> - case n of - 0 : 1 - _ : n * (factorial (n - 1)); - -/* Recursive countdown function */ -countdown : n -> - case n of - 0 : "done" - _ : countdown (n - 1); - -/* Testing recursive functions */ -fact5 : factorial 5; /* 120 */ -count : countdown 3; /* "done" */ -``` - -### Comparison and Logical Operators +squared : map @double 5; -``` -/* Comparison operators */ -a : 5; -b : 10; - -less : a < b; /* true */ -greater : b > a; /* true */ -equal : a = a; /* true */ -notEqual : a != b; /* true */ -lessEqual : a <= 5; /* true */ -greaterEqual : b >= 10; /* true */ - -/* Logical operators */ -logicalAnd : 1 and 1; /* true */ -logicalOr : 0 or 1; /* true */ -logicalXor : 1 xor 0; /* true */ -logicalNot : not 0; /* true */ - -/* Complex logical expressions */ -complex1 : a < b and b > 5; /* true */ -complex2 : a = 5 or b = 15; /* true */ -complex3 : not (a = b); /* true */ -``` - -### Input/Output and Assertions - -``` -/* Interactive input/output */ -..out "Enter your name: "; -name : ..in; -..out "Hello, "; -..out name; -..out "!"; - -/* Assertions for testing */ -x : 5; -y : 3; -sum : x + y; - -..assert x = 5; /* Passes */ -..assert y = 3; /* Passes */ -..assert sum = 8; /* Passes */ -..assert x > 3; /* Passes */ -..assert y < 10; /* Passes */ -..assert sum != 0; /* Passes */ -..assert (add 3 4) = 7; /* Passes (with parentheses) */ - -/* String comparisons */ -..assert "hello" = "hello"; /* Passes */ -..assert "world" != "hello"; /* Passes */ -``` - -### Standard Library Functions - -``` -/* Using all standard library functions */ -double : x -> x * 2; -square : x -> x * x; -add : x y -> x + y; +/* Filter */ isPositive : x -> x > 0; +filtered : filter @isPositive 5; -/* Map function */ -mapped1 : map @double 5; /* 10 */ -mapped2 : map @square 3; /* 9 */ - -/* Compose function */ -composed : compose @double @square 3; /* 18 */ - -/* Pipe function */ -piped : pipe @double @square 2; /* 16 */ - -/* Apply function */ -applied : apply @double 7; /* 14 */ - -/* Filter function */ -filtered : filter @isPositive 5; /* 5 (since 5 > 0) */ -filtered2 : filter @isPositive -3; /* 0 (since -3 <= 0) */ - -/* Reduce and Fold functions */ -reduced : reduce @add 0 5; /* 5 */ -folded : fold @add 0 5; /* 5 */ - -/* Curry function (explicit currying) */ -curried : curry @add 3 4; /* 7 */ -``` - -### Complete Program Example - -``` -/* A complete program demonstrating multiple features */ -..out "Welcome to the Calculator!"; - -/* Define arithmetic functions */ -add : x y -> x + y; -subtract : x y -> x - y; -multiply : x y -> x * y; -divide : x y -> x / y; - -/* Define utility functions */ -double : x -> x * 2; -square : x -> x * x; -isEven : x -> x % 2 = 0; - -/* Get user input */ -..out "Enter first number: "; -num1 : ..in; -..out "Enter second number: "; -num2 : ..in; - -/* Perform calculations */ -sum : add num1 num2; -diff : subtract num1 num2; -prod : multiply num1 num2; -quot : divide num1 num2; - -/* Display results */ -..out "Sum: "; -..out sum; -..out "Difference: "; -..out diff; -..out "Product: "; -..out prod; -..out "Quotient: "; -..out quot; - -/* Use higher-order functions */ -doubledSum : double sum; -squaredDiff : square diff; - -..out "Doubled sum: "; -..out doubledSum; -..out "Squared difference: "; -..out squaredDiff; - -/* Pattern matching for number classification */ -classify : num -> - case num of - 0 : "zero" - _ : case isEven num of - true : "even" - _ : "odd"; - -classification : classify num1; -..out "First number is: "; -..out classification; - -/* Assertions to verify calculations */ -..assert sum = add num1 num2; -..assert diff = subtract num1 num2; -..assert prod = multiply num1 num2; - -..out "All calculations verified!"; +/* Compose */ +f : x -> x + 1; +g : x -> x * 2; +h : compose @f @g; +result : h 5; /* (5 * 2) + 1 = 11 */ ``` -## Running Programs - -The language supports two modes of execution: - -### File Execution Mode -Run a script file by providing the file path as an argument: +## Usage +### Running Scripts ```bash node lang.js script.txt ``` -### REPL Mode -Start an interactive REPL by running without arguments: - +### Testing +The project uses a structured testing approach with unit and integration tests: + +#### Unit Tests +Located in `tests/` directory, each focusing on a specific language feature: +- `01_lexer_basic.txt` - Basic lexer functionality +- `02_arithmetic_operations.txt` - Arithmetic operations +- `03_comparison_operators.txt` - Comparison operators +- `04_logical_operators.txt` - Logical operators +- `05_io_operations.txt` - IO operations +- `06_function_definitions.txt` - Function definitions +- `07_case_expressions.txt` - Case expressions and pattern matching +- `08_first_class_functions.txt` - First-class function features +- `09_tables.txt` - Table literals and access +- `10_standard_library.txt` - Standard library functions + +#### Integration Tests +Test combinations of multiple features: +- `integration_01_basic_features.txt` - Basic feature combinations +- `integration_02_pattern_matching.txt` - Pattern matching with other features +- `integration_03_functional_programming.txt` - Functional programming patterns + +#### Running Tests ```bash -node lang.js -``` - -In REPL mode: -- Type expressions and end them with a semicolon (`;`) to execute -- Multi-line expressions are supported -- Type `exit` or `quit` to exit -- Variables and functions persist between expressions +# Run all tests +./run_tests.sh - -## Language Design Principles - -- **Simplicity**: Minimal syntax for maximum clarity -- **Immutability**: Variables cannot be reassigned -- **Functional**: Functions are first-class values with composition support -- **Pattern-oriented**: Pattern matching as a core feature -- **Recursive**: Support for recursive function calls in function bodies -- **Grouped**: Parentheses support for complex arithmetic expressions -- **Expressive**: Rich set of arithmetic, comparison, and logical operators -- **IO-aware**: Built-in input/output operations with clear impurity markers -- **Educational**: Designed to teach language implementation concepts - -## Limitations - -This is a learning language with intentional limitations: -- Complex nested function calls (e.g., `add double 3 square 2`) are ambiguous without explicit grouping -- There's one known issue with function calls inside assertions (e.g., ..assert add 3 4 = 7), which is a parsing edge case. Workaround: use parentheses around function calls in assertions (e.g., ..assert (add 3 4) = 7) -- Limited to immutable data structures (no mutation operations) -- No error handling beyond basic validation -- No modules or imports -- IO operations are synchronous and block execution - -## Future Enhancements - -Planned features for future versions: -- Ambiguous function call detection and error reporting -- Lists and data structures -- Error handling -- Modules and imports -- Performance optimizations +# Run individual tests +node lang.js tests/01_lexer_basic.txt +node lang.js tests/integration_01_basic_features.txt +``` ## Implementation Details -The language is implemented in JavaScript with three main components: +### Architecture +- **Lexer**: Tokenizes input into tokens (numbers, identifiers, operators, etc.) +- **Parser**: Builds Abstract Syntax Tree (AST) from tokens +- **Interpreter**: Executes AST with scope management + +### Key Components +- **Token Types**: Supports all basic operators, literals, and special tokens +- **AST Nodes**: Expression, statement, and declaration nodes +- **Scope Management**: Lexical scoping with proper variable resolution +- **Error Handling**: Comprehensive error reporting for parsing and execution + +## Recent Fixes + +### ✅ Parser Ambiguity with Unary Minus Arguments (Latest Fix) +- **Issue**: `filter @isPositive -3` was incorrectly parsed as binary operation instead of function call with unary minus argument +- **Root Cause**: Parser treating `FunctionReference MINUS` as binary minus operation +- **Solution**: Added special case in `parseExpression()` to handle `FunctionReference MINUS` pattern +- **Status**: ✅ Resolved - Standard library functions now work with negative arguments + +### ✅ Unary Minus Operator +- **Issue**: Stack overflow when parsing negative numbers (e.g., `-1`) +- **Root Cause**: Parser lacked specific handling for unary minus operator +- **Solution**: Added `UnaryMinusExpression` parsing and evaluation +- **Status**: ✅ Resolved - All tests passing + +### ✅ IO Operation Parsing +- **Issue**: IO operations not parsed correctly at top level +- **Solution**: Moved IO parsing to proper precedence level +- **Status**: ✅ Resolved + +### ✅ Decimal Number Support +- **Issue**: Decimal numbers not handled correctly +- **Solution**: Updated lexer and interpreter to use `parseFloat()` +- **Status**: ✅ Resolved + +## Known Issues + +### 🔄 Logical Operator Precedence +- **Issue**: Logical operators (`and`, `or`, `xor`) have incorrect precedence relative to function calls +- **Example**: `isEven 10 and isPositive 5` is parsed as `isEven(10 and isPositive(5))` instead of `(isEven 10) and (isPositive 5)` +- **Impact**: Complex expressions with logical operators may not evaluate correctly +- **Status**: 🔄 In Progress - Working on proper operator precedence hierarchy +- **Workaround**: Use parentheses to explicitly group expressions: `(isEven 10) and (isPositive 5)` + +### 🔄 Parentheses Parsing with Logical Operators +- **Issue**: Some expressions with logical operators inside parentheses fail to parse +- **Example**: `add (multiply 3 4) (isEven 10 and isPositive 5)` may fail with parsing errors +- **Status**: 🔄 In Progress - Related to logical operator precedence issue + +## Development + +### File Structure +``` +. +├── lang.js # Main implementation +├── test.txt # Comprehensive test file +├── tests/ # Unit and integration tests +│ ├── 01_lexer_basic.txt +│ ├── 02_arithmetic_operations.txt +│ ├── ... +│ ├── integration_01_basic_features.txt +│ ├── integration_02_pattern_matching.txt +│ └── integration_03_functional_programming.txt +├── run_tests.sh # Test runner script +├── FIXME.md # Issues and fixes documentation +└── README.md # This file +``` + +### Debugging +Enable debug mode by setting `DEBUG=true`: +```bash +DEBUG=true node lang.js script.txt +``` -1. **Lexer** (`lexer()`): Converts source code to tokens -2. **Parser** (`parser()`): Builds AST from tokens -3. **Interpreter** (`interpreter()`): Executes AST +## Contributing -Each component is designed to be modular and extensible for adding new language features. \ No newline at end of file +1. Create focused unit tests for new features +2. Add integration tests for feature combinations +3. Update documentation +4. Run the full test suite before submitting changes \ No newline at end of file |