# Simple Scripting Language A functional programming language with immutable variables, first-class functions, and pattern matching. ## Features - **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 ### Basic Operations ``` /* Arithmetic */ x : 5 + 3; y : 10 - 2; z : 4 * 3; w : 15 / 3; neg : -5; /* Unary minus */ /* Comparisons */ result : x > y; equal : a = b; not_equal : a != b; /* Logical */ and_result : true and false; or_result : true or false; ``` ### Variables and Functions ``` /* Immutable variables */ x : 42; y : "hello"; /* Function definition */ f : x -> x * 2; /* Function call */ result : f 5; ``` ### Tables ``` /* Table literal */ table : {1, 2, 3, key: "value"}; /* Table access */ first : table[1]; value : table.key; nested : table.key.subkey; ``` ### Pattern Matching ``` /* Case expression */ result : case x of 1 : "one" 2 : "two" _ : "other"; ``` ### IO Operations ``` /* Output */ ..out "Hello, World!"; /* Input */ name : ..in; /* Assertion */ ..assert x = 5; ``` ### Standard Library ``` /* Map */ double : x -> x * 2; squared : map @double 5; /* Filter */ isPositive : x -> x > 0; filtered : filter @isPositive 5; /* Compose */ f : x -> x + 1; g : x -> x * 2; h : compose @f @g; result : h 5; /* (5 * 2) + 1 = 11 */ ``` ## Usage ### Running Scripts ```bash node lang.js script.txt ``` ### 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 # Run all tests ./run_tests.sh # Run individual tests node lang.js tests/01_lexer_basic.txt node lang.js tests/integration_01_basic_features.txt ``` ## Implementation Details ### 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 ``` ## Contributing 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