diff options
Diffstat (limited to 'js/baba-yaga/experimental/fmt/fmt-README.md')
-rw-r--r-- | js/baba-yaga/experimental/fmt/fmt-README.md | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/js/baba-yaga/experimental/fmt/fmt-README.md b/js/baba-yaga/experimental/fmt/fmt-README.md new file mode 100644 index 0000000..132549b --- /dev/null +++ b/js/baba-yaga/experimental/fmt/fmt-README.md @@ -0,0 +1,338 @@ +# Baba Yaga Code Formatter (`fmt.js`) + +A code formatter for the Baba Yaga programming language, similar to Go's `fmt` tool. It automatically formats Baba Yaga source code according to consistent style guidelines. + +## Features + +- **Consistent Formatting**: Applies standard formatting rules across all Baba Yaga code +- **Automatic Indentation**: Proper indentation for nested structures (functions, when expressions, with blocks) +- **Operator Spacing**: Consistent spacing around operators and punctuation +- **Line Breaking**: Smart line breaking for long expressions and data structures +- **Comment Preservation**: Maintains existing comments (work in progress) +- **Type Annotation Formatting**: Proper formatting of typed function parameters and return types + +## Installation + +The formatter uses the existing Baba Yaga lexer and parser. Ensure you have the core language files: +- `lexer.js` +- `parser.js` +- `fmt.js` + +## Usage + +### Command Line + +```bash +# Format and print to stdout +node fmt.js file.baba + +# Format and write back to file +node fmt.js --write file.baba +node fmt.js -w file.baba + +# Check if file is already formatted (exit code 0 if formatted, 1 if not) +node fmt.js --check file.baba +node fmt.js -c file.baba + +# Custom indentation size (default: 2 spaces) +node fmt.js --indent=4 file.baba +``` + +### As a Module + +```javascript +import { BabaYagaFormatter } from './fmt.js'; + +const formatter = new BabaYagaFormatter({ + indentSize: 2, + maxLineLength: 100, + preserveComments: true +}); + +const source = `x:2+3;y:x*2;`; +const formatted = formatter.format(source); +console.log(formatted); +// Output: +// x : 2 + 3; +// y : x * 2; +``` + +## Formatting Rules + +### Function Body Indentation + +All function bodies are properly indented relative to the function name: + +```baba +// Simple function body +inc : x -> + x + 1; + +// Complex function body with when expression +classify : n -> + when n is + 0 then "zero" + _ then "other"; + +// Function with with header +calculate : a b -> + with ( + sum : a + b; + product : a * b; + ) -> + {sum: sum, product: product}; +``` + +### Basic Declarations + +**Before:** +```baba +x:42;y:"hello"; +``` + +**After:** +```baba +x : 42; +y : "hello"; +``` + +### Functions + +**Before:** +```baba +add:x y->x+y; +multiply:(x:Int,y:Int)->Int->x*y; +``` + +**After:** +```baba +add : x y -> + x + y; + +multiply : (x: Int, y: Int) -> Int -> + x * y; +``` + +### When Expressions + +**Before:** +```baba +check:x->when x is 1 then"one"2 then"two"_ then"other"; +``` + +**After:** +```baba +check : x -> + when x is + 1 then "one" + 2 then "two" + _ then "other"; +``` + +### Then Keyword Alignment + +The formatter ensures all `then` keywords within a `when` expression scope are aligned for maximum readability: + +**Before:** +```baba +processRequest : method path -> + when method path is + "GET" "/" then "Home page" + "GET" "/about" then "About page" + "POST" "/api/users" then "Create user" + "DELETE" "/api/users" then "Delete user" + _ _ then "Not found"; +``` + +**After:** +```baba +processRequest : method path -> + when method path is + "GET" "/" then "Home page" + "GET" "/about" then "About page" + "POST" "/api/users" then "Create user" + "DELETE" "/api/users" then "Delete user" + _ _ then "Not found"; +``` + +This alignment is maintained within each `when` scope, making nested when expressions highly readable. + +### Lists and Tables + +**Before:** +```baba +nums:[1,2,3,4,5]; +person:{name:"Alice",age:30,active:true}; +``` + +**After:** +```baba +nums : [1, 2, 3, 4, 5]; +person : {name: "Alice", age: 30, active: true}; +``` + +For longer structures, the formatter uses multi-line format: +```baba +longList : [ + 1, + 2, + 3, + 4, + 5 +]; + +complexTable : { + name: "Alice", + details: { + age: 30, + city: "Boston" + }, + preferences: ["tea", "books", "coding"] +}; +``` + +### With Headers + +**Before:** +```baba +calc:x y->with(a:x+1;b:y*2;)->a+b; +``` + +**After:** +```baba +calc : x y -> + with ( + a : x + 1; + b : y * 2; + ) -> + a + b; +``` + +### Function Calls + +**Before:** +```baba +result:add 5 3; +complex:map(x->x*2)[1,2,3]; +``` + +**After:** +```baba +result : add 5 3; +complex : map (x -> x * 2) [1, 2, 3]; +``` + +## Supported Node Types + +The formatter handles all major Baba Yaga language constructs: + +- **Declarations**: Variables, functions, types +- **Expressions**: Binary, unary, function calls, member access +- **Literals**: Numbers, strings, booleans, lists, tables +- **Control Flow**: When expressions with pattern matching +- **Advanced Features**: With headers, curried functions, anonymous functions +- **Type Annotations**: Typed parameters and return types + +## Error Handling + +If the formatter encounters a parsing error, it will report the issue and exit with a non-zero status code: + +```bash +$ node fmt.js invalid.baba +Error formatting 'invalid.baba': Formatting failed: Expected token type COLON but got SEMICOLON at 1:5 +``` + +## Integration with Editors + +The formatter can be integrated with various editors: + +### VS Code +Add to your `settings.json`: +```json +{ + "[baba]": { + "editor.defaultFormatter": "none", + "editor.formatOnSave": false + } +} +``` + +Then create a task in `.vscode/tasks.json`: +```json +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Format Baba Yaga", + "type": "shell", + "command": "node", + "args": ["fmt.js", "--write", "${file}"], + "group": "build", + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared" + } + } + ] +} +``` + +### Command Line Integration +Add to your shell profile (`.bashrc`, `.zshrc`, etc.): +```bash +# Format all .baba files in current directory +alias babafmt='find . -name "*.baba" -exec node /path/to/fmt.js --write {} \;' + +# Check formatting of all .baba files +alias babafmtcheck='find . -name "*.baba" -exec node /path/to/fmt.js --check {} \;' +``` + +## Examples + +### Before Formatting +```baba +// Unformatted Baba Yaga code +factorial:n->when n is 0 then 1 1 then 1 _ then n*(factorial(n-1)); +numbers:[1,2,3,4,5];sum:reduce(acc x->acc+x)0 numbers; +user:{name:"Alice",age:30,calculate:x y->x+y}; +``` + +### After Formatting +```baba +// Unformatted Baba Yaga code +factorial : n -> + when n is + 0 then 1 + 1 then 1 + _ then n * (factorial (n - 1)); + +numbers : [1, 2, 3, 4, 5]; +sum : reduce (acc x -> acc + x) 0 numbers; + +user : { + name: "Alice", + age: 30, + calculate: x y -> x + y +}; +``` + +## Contributing + +The formatter is built using the existing Baba Yaga AST structure. To add support for new language features: + +1. Add the new node type to the `visitNode` method +2. Implement a corresponding `format*` method +3. Add test cases +4. Update this documentation + +## Known Limitations + +- Comment preservation is basic and may not handle all edge cases +- Very complex nested expressions might need manual formatting +- Error recovery could be improved for malformed input + +## License + +Same as the Baba Yaga language implementation. |