diff options
Diffstat (limited to 'js/scripting-lang/docs/baba-yaga/0.0.1/index.html')
-rw-r--r-- | js/scripting-lang/docs/baba-yaga/0.0.1/index.html | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/js/scripting-lang/docs/baba-yaga/0.0.1/index.html b/js/scripting-lang/docs/baba-yaga/0.0.1/index.html new file mode 100644 index 0000000..365268c --- /dev/null +++ b/js/scripting-lang/docs/baba-yaga/0.0.1/index.html @@ -0,0 +1,224 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <title>Home - Documentation</title> + + <script src="scripts/prettify/prettify.js"></script> + <script src="scripts/prettify/lang-css.js"></script> + <!--[if lt IE 9]> + <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> + <![endif]--> + <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> + <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> + <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> +</head> +<body> + +<input type="checkbox" id="nav-trigger" class="nav-trigger" /> +<label for="nav-trigger" class="navicon-button x"> + <div class="navicon"></div> +</label> + +<label for="nav-trigger" class="overlay"></label> + +<nav> + <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Tutorials</li><li class="nav-item"><a href="tutorial-00_Introduction.html">00_Introduction</a></li><li class="nav-item"><a href="tutorial-01_Function_Calls.html">01_Function_Calls</a></li><li class="nav-item"><a href="tutorial-02_Function_Composition.html">02_Function_Composition</a></li><li class="nav-item"><a href="tutorial-03_Table_Operations.html">03_Table_Operations</a></li><li class="nav-item"><a href="tutorial-04_Currying.html">04_Currying</a></li><li class="nav-item"><a href="tutorial-05_Pattern_Matching.html">05_Pattern_Matching</a></li><li class="nav-item"><a href="tutorial-06_Immutable_Tables.html">06_Immutable_Tables</a></li><li class="nav-item"><a href="tutorial-07_Function_References.html">07_Function_References</a></li><li class="nav-item"><a href="tutorial-08_Combinators.html">08_Combinators</a></li><li class="nav-item"><a href="tutorial-09_Expression_Based.html">09_Expression_Based</a></li><li class="nav-item"><a href="tutorial-10_Tables_Deep_Dive.html">10_Tables_Deep_Dive</a></li><li class="nav-item"><a href="tutorial-11_Standard_Library.html">11_Standard_Library</a></li><li class="nav-item"><a href="tutorial-12_IO_Operations.html">12_IO_Operations</a></li><li class="nav-item"><a href="tutorial-13_Error_Handling.html">13_Error_Handling</a></li><li class="nav-item"><a href="tutorial-14_Advanced_Combinators.html">14_Advanced_Combinators</a></li><li class="nav-item"><a href="tutorial-15_Integration_Patterns.html">15_Integration_Patterns</a></li><li class="nav-item"><a href="tutorial-16_Best_Practices.html">16_Best_Practices</a></li><li class="nav-item"><a href="tutorial-README.html">README</a></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#callStackTracker">callStackTracker</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#debugError">debugError</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#debugLog">debugLog</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#executeFile">executeFile</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#initializeStandardLibrary">initializeStandardLibrary</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#interpreter">interpreter</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#lexer">lexer</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#main">main</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#parser">parser</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#readFile">readFile</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="global.html#run">run</a></span></li> +</nav> + +<div id="main"> + + + + + + + + + + + + + + + + + + + + <section class="readme"> + <article><h1>Baba Yaga</h1> +<h2>A Scripting Language</h2> +<p>Baba Yaga is a combinator-based scripting language that aims to be dangerously functional-brained, has minimal syntax, an intuitive approach to pattern matching, and hopefully enough of a standard library to be useful...but not too much of a standard library to be difficult to recall.</p> +<p>This whole thing started as an aesthetic curiosity, and continued on from there. I wanted to be able to do pattern matching like this:</p> +<pre class="prettyprint source lang-plaintext"><code>factorial : n -> + when n is + 0 then 1 + _ then n * (factorial (n - 1)); +</code></pre> +<p>I've implemented a whole bunch of <a href="https://git.sr.ht/~eli_oat/chupacabra">forths</a>, and a couple schemes, but never have I ever implemented something like a "regular" programming language. And, while, an <a href="https://en.wikipedia.org/wiki/Standard_ML">ML-flavored</a> programming language isn't exactly regular, this has grown from an aesthetic curiosity to a full-blown aesthetic indulgence.</p> +<p>Baba Yaga supports...</p> +<ul> +<li><strong>Function definitions</strong> using arrow syntax with lexical scoping</li> +<li><strong>Pattern matching</strong> with a single <code>when ... is ... then</code> expression that handles wildcards and arbitrarily nested features</li> +<li><strong>Tables</strong> inspired by Lua's tables, with array-like and key-value entries, including boolean keys</li> +<li><strong>Function references</strong> using an <code>@</code> operator for higher-order programming</li> +<li><strong>IO Operations</strong> including input, output, and assertions, plus an <code>..emit</code> and <code>..listen</code> pattern for interfacing a functional core with the outside world. This contains side effects to a very limited surface area</li> +<li><strong>Standard Library</strong> with a complete set of arithmetic, comparison, logical, and higher-order combinators...I think (let me know if I'm missing anything)</li> +<li><strong>APL-style operations</strong> with element-wise and immutable table operations so that you can use broadcasting instead of looping</li> +<li><strong>Function composition</strong> with <code>compose</code>, <code>pipe</code>, and <code>via</code> operators, supporting a bunch of different ways to chain functions together</li> +<li><strong>Currying by default</strong> - all functions are automatically curried</li> +<li><strong>Combinator-based architecture</strong> everything is "just" a function call or reference under the hood...because this supposedly made parsing easier...but I'm not yet totally sold on that reasoning</li> +</ul> +<h2>Example Script</h2> +<pre class="prettyprint source lang-plaintext"><code>/* Basic arithmetic */ +result : 5 + 3 * 2; +..out result; + +/* Function definition */ +factorial : n -> + when n is + 0 then 1 + _ then n * (factorial (n - 1)); + +/* Function composition */ +double : x -> x * 2; +increment : x -> x + 1; +composed : compose @double @increment 5; +..out composed; + +/* Pattern matching */ +classify : x y -> + when x y is + 0 0 then "both zero" + 0 _ then "x is zero" + _ 0 then "y is zero" + _ _ then "neither zero"; + +/* Tables */ +person : {name: "Baba Yaga", age: 99, active: true}; +..out person.name; +..out person["age"]; + +numbers : {1, 2, 3, 4, 5}; +doubled : map @double numbers; +..out doubled[1]; + +/* APL-style element-wise operations over tables */ +table1 : {a: 1, b: 2, c: 3}; +table2 : {a: 10, b: 20, c: 30}; +sum : each @add table1 table2; +..out sum.a; +</code></pre> +<p>Baba Yaga files should use either the <code>.txt</code> file extension, or the <code>.baba</code> extension.</p> +<h2>Key Features</h2> +<h3>Function Application</h3> +<p>Functions are applied using juxtaposition (space-separated), and you can use parentheses to help disambiguate precedence:</p> +<pre class="prettyprint source lang-plaintext"><code>f x /* Apply function f to argument x */ +f x y /* Apply f to x, then apply result to y */ +f (g x) /* Apply g to x, then apply f to result */ +</code></pre> +<h3>Pattern Matching</h3> +<p>Use <code>when</code> expressions for pattern matching:</p> +<pre class="prettyprint source lang-plaintext"><code>result : when value is + 0 then "zero" + 1 then "one" + _ then "other"; +</code></pre> +<h3>Tables</h3> +<p>Create and access data structures:</p> +<pre class="prettyprint source lang-plaintext"><code>/* Array-like */ +numbers : {1, 2, 3, 4, 5}; + +/* Key-value pairs */ +person : {name: "Beatrice", age: 26}; + +/* Boolean keys */ +flags : {true: "enabled", false: "disabled"}; +</code></pre> +<h3>Function References</h3> +<p>Use the <code>@</code> to make reference to functions as arguments for other functions:</p> +<pre class="prettyprint source lang-plaintext"><code>numbers : {1, 2, 3, 4, 5}; +doubled : map @double numbers; +</code></pre> +<h2>Combinators and Higher-Order Functions</h2> +<p>Baba Yaga tries to provide a comprehensive set of combinators for functional programming:</p> +<h3>Core Combinators</h3> +<ul> +<li><code>map f x</code> - Transform elements in collections</li> +<li><code>filter p x</code> - Select elements based on predicates</li> +<li><code>reduce f init x</code> - Accumulate values into a single result</li> +<li><code>each f x</code> - Multi-argument element-wise operations</li> +</ul> +<h3>Function Composition</h3> +<ul> +<li><code>compose f g</code> - Right-to-left composition (mathematical style)</li> +<li><code>pipe f g</code> - Left-to-right composition (pipeline style)</li> +<li><code>via</code> - Kinda like <code>.</code> composition syntax: <code>f via g via h</code></li> +</ul> +<h3>Table Operations</h3> +<p>All table operations are immutable so they return new tables.</p> +<ul> +<li><code>t.map</code>, <code>t.filter</code>, <code>t.set</code>, <code>t.delete</code>, <code>t.merge</code>, <code>t.get</code>, <code>t.has</code>, <code>t.length</code></li> +</ul> +<h3>When to Use Which Combinator</h3> +<ul> +<li>Use <code>map</code> for general collections, <code>t.map</code> to emphasize table operations</li> +<li>Use <code>map</code> for single-table transformations, <code>each</code> for combining multiple collections.</li> +</ul> +<h3>Standard Library</h3> +<p>The language includes a comprehensive standard library:</p> +<p><strong>Arithmetic</strong>: <code>add</code>, <code>subtract</code>, <code>multiply</code>, <code>divide</code>, <code>modulo</code>, <code>power</code>, <code>negate</code><br> +<strong>Comparison</strong>: <code>equals</code>, <code>notEquals</code>, <code>lessThan</code>, <code>greaterThan</code>, <code>lessEqual</code>, <code>greaterEqual</code><br> +<strong>Logical</strong>: <code>logicalAnd</code>, <code>logicalOr</code>, <code>logicalXor</code>, <code>logicalNot</code><br> +<strong>Higher-Order</strong>: <code>map</code>, <code>compose</code>, <code>pipe</code>, <code>apply</code>, <code>filter</code>, <code>reduce</code>, <code>fold</code>, <code>curry</code>, <code>each</code><br> +<strong>Enhanced</strong>: <code>identity</code>, <code>constant</code>, <code>flip</code>, <code>on</code>, <code>both</code>, <code>either</code><br> +<strong>Table Operations</strong>: <code>t.map</code>, <code>t.filter</code>, <code>t.set</code>, <code>t.delete</code>, <code>t.merge</code>, <code>t.get</code>, <code>t.has</code>, <code>t.length</code></p> +<h2>Architecture</h2> +<p>Baba Yaga uses a combinator-based architecture where all operations are translated to function calls:</p> +<ol> +<li><strong>Lexer</strong>: Converts source code into tokens</li> +<li><strong>Parser</strong>: Translates tokens into AST, converting operators to combinator calls</li> +<li><strong>Interpreter</strong>: Executes combinator functions from the standard library</li> +</ol> +<p>The idea behind this approach is that it should eliminate parsing ambiguity while preserving syntax and enabling functional programming patterns like currying and composition, but the implementation is likely a little bit janky.</p> +<h2>Testing</h2> +<p>Run the complete test suite!</p> +<pre class="prettyprint source lang-bash"><code>./run_tests.sh +</code></pre> +<p>This assumes you are using bun, but I've also tested extensively with both node and the browser, too. I haven't validated it, yet, but I think Baba Yaga should work with quickjs, too.</p> +<h3>Debug Mode</h3> +<p>Enable debug output for development using the flag <code>DEBUG=1</code> or <code>DEBUG=2</code>:</p> +<pre class="prettyprint source lang-bash"><code>DEBUG=1 node lang.js your-script.txt +</code></pre> +<p>This'll output a lot of debug info, including the AST (as JSON).</p> +<h3>Adding Features</h3> +<p>If you wanna add language features, the easiest way to do it is to see if you can implement them in Baba Yaga script, if you need to get into the guts of the thing, though, you wanna follow this pattern,</p> +<ol> +<li>Add tests in <code>tests/</code></li> +<li>Add tokens in <code>lexer.js</code></li> +<li>Add parsing logic in <code>parser.js</code></li> +<li>Add evaluation logic in <code>lang.js</code></li> +<li>Validate against the tests you added earlier</li> +<li>Update documentation</li> +</ol></article> + </section> + + + + + + +</div> + +<br class="clear"> + +<footer> + Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.4</a> on Tue Jul 29 2025 23:15:00 GMT-0400 (Eastern Daylight Time) using the Minami theme. +</footer> + +<script>prettyPrint();</script> +<script src="scripts/linenumber.js"></script> +</body> +</html> \ No newline at end of file |