diff options
Diffstat (limited to 'js/scripting-lang/docs/baba-yaga/0.0.1/lang.js.html')
-rw-r--r-- | js/scripting-lang/docs/baba-yaga/0.0.1/lang.js.html | 501 |
1 files changed, 312 insertions, 189 deletions
diff --git a/js/scripting-lang/docs/baba-yaga/0.0.1/lang.js.html b/js/scripting-lang/docs/baba-yaga/0.0.1/lang.js.html index 08a8efb..27fe6d6 100644 --- a/js/scripting-lang/docs/baba-yaga/0.0.1/lang.js.html +++ b/js/scripting-lang/docs/baba-yaga/0.0.1/lang.js.html @@ -2,22 +2,35 @@ <html lang="en"> <head> <meta charset="utf-8"> - <title>JSDoc: Source: lang.js</title> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <title>lang.js - Documentation</title> - <script src="scripts/prettify/prettify.js"> </script> - <script src="scripts/prettify/lang-css.js"> </script> + <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> -<div id="main"> +<input type="checkbox" id="nav-trigger" class="nav-trigger" /> +<label for="nav-trigger" class="navicon-button x"> + <div class="navicon"></div> +</label> - <h1 class="page-title">Source: lang.js</h1> +<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"> + + <h1 class="page-title">lang.js</h1> + @@ -33,6 +46,91 @@ import { lexer, TokenType } from './lexer.js'; import { parser } from './parser.js'; +// Cross-platform environment detection +const isNode = typeof process !== 'undefined' && process.versions && process.versions.node; +const isBun = typeof process !== 'undefined' && process.versions && process.versions.bun; +const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; + +// Cross-platform debug flag +const DEBUG = (isNode && process.env.DEBUG) || (isBrowser && window.DEBUG) || false; + +// Cross-platform IO operations +const createReadline = () => { + if (isNode || isBun) { + const readline = require('readline'); + return readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + } else if (isBrowser) { + // Browser fallback - use prompt() for now + return { + question: (prompt, callback) => { + const result = window.prompt(prompt); + callback(result); + }, + close: () => {} + }; + } else { + // Fallback for other environments + return { + question: (prompt, callback) => { + callback("fallback input"); + }, + close: () => {} + }; + } +}; + +const createFileSystem = () => { + if (isNode || isBun) { + return require('fs'); + } else if (isBrowser) { + // Browser fallback - return a mock filesystem + return { + readFile: (path, encoding, callback) => { + callback(new Error('File system not available in browser')); + }, + writeFile: (path, data, callback) => { + callback(new Error('File system not available in browser')); + } + }; + } else { + // Fallback for other environments + return { + readFile: (path, encoding, callback) => { + callback(new Error('File system not available in this environment')); + }, + writeFile: (path, data, callback) => { + callback(new Error('File system not available in this environment')); + } + }; + } +}; + +// Cross-platform console output +const safeConsoleLog = (message) => { + if (typeof console !== 'undefined') { + console.log(message); + } +}; + +const safeConsoleError = (message) => { + if (typeof console !== 'undefined') { + console.error(message); + } +}; + +// Cross-platform process exit +const safeExit = (code) => { + if (isNode || isBun) { + process.exit(code); + } else if (isBrowser) { + // In browser, we can't exit, but we can throw an error or redirect + throw new Error(`Process would exit with code ${code}`); + } +}; + /** * Environment interface for external system integration * @@ -75,6 +173,7 @@ import { parser } from './parser.js'; * function arguments and validation of input data. */ function initializeStandardLibrary(scope) { + /** * Map: Apply a function to a value or collection * @param {Function} f - Function to apply @@ -413,10 +512,10 @@ function initializeStandardLibrary(scope) { * application. */ scope.reduce = function(f, init, x) { - if (process.env.DEBUG) { - console.log(`[DEBUG] reduce: f =`, typeof f, f); - console.log(`[DEBUG] reduce: init =`, init); - console.log(`[DEBUG] reduce: x =`, x); + if (DEBUG) { + safeConsoleLog(`[DEBUG] reduce: f =`, typeof f, f); + safeConsoleLog(`[DEBUG] reduce: init =`, init); + safeConsoleLog(`[DEBUG] reduce: x =`, x); } if (typeof f !== 'function') { @@ -426,10 +525,10 @@ function initializeStandardLibrary(scope) { if (init === undefined) { // Partial application: return a function that waits for the remaining arguments return function(init, x) { - if (process.env.DEBUG) { - console.log(`[DEBUG] reduce returned function: f =`, typeof f, f); - console.log(`[DEBUG] reduce returned function: init =`, init); - console.log(`[DEBUG] reduce returned function: x =`, x); + if (DEBUG) { + safeConsoleLog(`[DEBUG] reduce returned function: f =`, typeof f, f); + safeConsoleLog(`[DEBUG] reduce returned function: init =`, init); + safeConsoleLog(`[DEBUG] reduce returned function: x =`, x); } if (x === undefined) { // Still partial application @@ -524,6 +623,12 @@ function initializeStandardLibrary(scope) { * operations through the combinator foundation. */ scope.add = function(x, y) { + if (y === undefined) { + // Partial application: return a function that waits for the second argument + return function(y) { + return x + y; + }; + } return x + y; }; @@ -534,6 +639,12 @@ function initializeStandardLibrary(scope) { * @returns {number} Difference of x and y */ scope.subtract = function(x, y) { + if (y === undefined) { + // Partial application: return a function that waits for the second argument + return function(y) { + return x - y; + }; + } return x - y; }; @@ -556,6 +667,12 @@ function initializeStandardLibrary(scope) { * operations through the combinator foundation. */ scope.multiply = function(x, y) { + if (y === undefined) { + // Partial application: return a function that waits for the second argument + return function(y) { + return x * y; + }; + } return x * y; }; @@ -567,6 +684,15 @@ function initializeStandardLibrary(scope) { * @throws {Error} When second argument is zero */ scope.divide = function(x, y) { + if (y === undefined) { + // Partial application: return a function that waits for the second argument + return function(y) { + if (y === 0) { + throw new Error('Division by zero'); + } + return x / y; + }; + } if (y === 0) { throw new Error('Division by zero'); } @@ -580,6 +706,12 @@ function initializeStandardLibrary(scope) { * @returns {number} Remainder of x divided by y */ scope.modulo = function(x, y) { + if (y === undefined) { + // Partial application: return a function that waits for the second argument + return function(y) { + return x % y; + }; + } return x % y; }; @@ -590,6 +722,12 @@ function initializeStandardLibrary(scope) { * @returns {number} x raised to the power of y */ scope.power = function(x, y) { + if (y === undefined) { + // Partial application: return a function that waits for the second argument + return function(y) { + return Math.pow(x, y); + }; + } return Math.pow(x, y); }; @@ -826,9 +964,9 @@ function initializeStandardLibrary(scope) { * transformations. */ scope.each = function(f, x) { - if (process.env.DEBUG) { - console.log(`[DEBUG] each called with: f=${typeof f}, x=${typeof x}`); - console.log(`[DEBUG] x value:`, x); + if (DEBUG) { + safeConsoleLog(`[DEBUG] each called with: f=${typeof f}, x=${typeof x}`); + safeConsoleLog(`[DEBUG] x value:`, x); } if (typeof f !== 'function') { @@ -1278,10 +1416,10 @@ function interpreter(ast, environment = null, initialState = {}) { let ioOperationsPerformed = false; // Debug: Check if combinators are available - if (process.env.DEBUG) { - console.log('[DEBUG] Available functions in global scope:', Object.keys(globalScope)); - console.log('[DEBUG] add function exists:', typeof globalScope.add === 'function'); - console.log('[DEBUG] subtract function exists:', typeof globalScope.subtract === 'function'); + if (DEBUG) { + safeConsoleLog('[DEBUG] Available functions in global scope:', Object.keys(globalScope)); + safeConsoleLog('[DEBUG] add function exists:', typeof globalScope.add === 'function'); + safeConsoleLog('[DEBUG] subtract function exists:', typeof globalScope.subtract === 'function'); } // Reset call stack tracker at the start of interpretation @@ -1408,8 +1546,8 @@ function interpreter(ast, environment = null, initialState = {}) { key = evalNode(entry.key); } // Special handling for FunctionDeclaration nodes - if (process.env.DEBUG) { - console.log(`[DEBUG] TableLiteral: entry.value.type = ${entry.value.type}`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] TableLiteral: entry.value.type = ${entry.value.type}`); } if (entry.value.type === 'FunctionDeclaration') { // Don't evaluate the function body, just create the function @@ -1605,27 +1743,27 @@ function interpreter(ast, environment = null, initialState = {}) { if (typeof node.name === 'string') { // Regular function call with string name funcToCall = globalScope[node.name]; - if (process.env.DEBUG) { - console.log(`[DEBUG] FunctionCall: looking up function '${node.name}' in globalScope, found:`, typeof funcToCall); + if (DEBUG) { + safeConsoleLog(`[DEBUG] FunctionCall: looking up function '${node.name}' in globalScope, found:`, typeof funcToCall); } } else if (node.name.type === 'Identifier') { // Function call with identifier funcToCall = globalScope[node.name.value]; - if (process.env.DEBUG) { - console.log(`[DEBUG] FunctionCall: looking up function '${node.name.value}' in globalScope, found:`, typeof funcToCall); + if (DEBUG) { + safeConsoleLog(`[DEBUG] FunctionCall: looking up function '${node.name.value}' in globalScope, found:`, typeof funcToCall); } } else { // Function call from expression (e.g., parenthesized function, higher-order) funcToCall = evalNode(node.name); - if (process.env.DEBUG) { - console.log(`[DEBUG] FunctionCall: evaluated function expression, found:`, typeof funcToCall); + if (DEBUG) { + safeConsoleLog(`[DEBUG] FunctionCall: evaluated function expression, found:`, typeof funcToCall); } } - if (funcToCall instanceof Function) { + if (typeof funcToCall === 'function') { let args = node.args.map(evalNode); - if (process.env.DEBUG) { - console.log(`[DEBUG] FunctionCall: calling function with args:`, args); + if (DEBUG) { + safeConsoleLog(`[DEBUG] FunctionCall: calling function with args:`, args); } return funcToCall(...args); } @@ -1636,16 +1774,16 @@ function interpreter(ast, environment = null, initialState = {}) { ? node.value.map(evalNode) : [evalNode(node.value)]; - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: whenValues =`, whenValues); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: whenValues =`, whenValues); } for (const caseItem of node.cases) { // Handle both single patterns and arrays of patterns const patterns = caseItem.pattern.map(evalNode); - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: patterns =`, patterns); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: patterns =`, patterns); } // Check if patterns match the values @@ -1657,14 +1795,14 @@ function interpreter(ast, environment = null, initialState = {}) { const value = whenValues[i]; const pattern = patterns[i]; - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: comparing value ${value} with pattern ${pattern}`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: comparing value ${value} with pattern ${pattern}`); } if (pattern === true) { // Wildcard pattern // Wildcard always matches - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: wildcard matches`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: wildcard matches`); } continue; } else if (typeof pattern === 'object' && pattern.type === 'FunctionCall') { @@ -1680,20 +1818,20 @@ function interpreter(ast, environment = null, initialState = {}) { }; } const patternResult = evalNode(patternToEvaluate); - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: boolean pattern result = ${patternResult}`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: boolean pattern result = ${patternResult}`); } if (!patternResult) { matches = false; - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: boolean pattern does not match`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: boolean pattern does not match`); } break; - } else { - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: boolean pattern matches`); + } else { + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: boolean pattern matches`); + } } - } } else if (typeof pattern === 'object' && pattern !== null && typeof value === 'object' && value !== null) { // Table pattern matching - check if all pattern properties exist in value let tableMatches = true; @@ -1705,31 +1843,31 @@ function interpreter(ast, environment = null, initialState = {}) { } if (!tableMatches) { matches = false; - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: table pattern does not match`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: table pattern does not match`); } break; - } else { - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: table pattern matches`); + } else { + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: table pattern matches`); + } } - } } else if (value !== pattern) { matches = false; - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: pattern does not match`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: pattern does not match`); } break; } else { - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: pattern matches`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: pattern matches`); } } } } - if (process.env.DEBUG) { - console.log(`[DEBUG] WhenExpression: case matches = ${matches}`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] WhenExpression: case matches = ${matches}`); } if (matches) { @@ -1744,11 +1882,7 @@ function interpreter(ast, environment = null, initialState = {}) { case 'WildcardPattern': return true; case 'IOInExpression': - const readline = require('readline'); - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout - }); + const rl = createReadline(); return new Promise((resolve) => { rl.question('', (input) => { @@ -1759,7 +1893,7 @@ function interpreter(ast, environment = null, initialState = {}) { }); case 'IOOutExpression': const outputValue = evalNode(node.value); - console.log(outputValue); + safeConsoleLog(outputValue); ioOperationsPerformed = true; return outputValue; case 'IOAssertExpression': @@ -1771,13 +1905,13 @@ function interpreter(ast, environment = null, initialState = {}) { case 'IOListenExpression': // Return current state from environment if available, otherwise placeholder if (environment && typeof environment.getCurrentState === 'function') { - if (process.env.DEBUG) { - console.log('[DEBUG] ..listen called - returning state from environment'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..listen called - returning state from environment'); } return environment.getCurrentState(); } else { - if (process.env.DEBUG) { - console.log('[DEBUG] ..listen called - returning placeholder state'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..listen called - returning placeholder state'); } return { status: 'placeholder', message: 'State not available in standalone mode' }; } @@ -1785,19 +1919,19 @@ function interpreter(ast, environment = null, initialState = {}) { const emitValue = evalNode(node.value); // Send value to environment if available, otherwise log to console if (environment && typeof environment.emitValue === 'function') { - if (process.env.DEBUG) { - console.log('[DEBUG] ..emit called - sending to environment'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..emit called - sending to environment'); } environment.emitValue(emitValue); } else { - console.log('[EMIT]', emitValue); + safeConsoleLog('[EMIT]', emitValue); } ioOperationsPerformed = true; return emitValue; case 'FunctionReference': const functionValue = globalScope[node.name]; - if (process.env.DEBUG) { - console.log(`[DEBUG] FunctionReference: looking up '${node.name}' in globalScope, found:`, typeof functionValue); + if (DEBUG) { + safeConsoleLog(`[DEBUG] FunctionReference: looking up '${node.name}' in globalScope, found:`, typeof functionValue); } if (functionValue === undefined) { throw new Error(`Function ${node.name} is not defined`); @@ -2044,16 +2178,16 @@ function interpreter(ast, environment = null, initialState = {}) { ? node.value.map(val => localEvalNodeWithScope(val, scope)) : [localEvalNodeWithScope(node.value, scope)]; - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: whenValues =`, whenValues); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: whenValues =`, whenValues); } for (const caseItem of node.cases) { // Handle both single patterns and arrays of patterns const patterns = caseItem.pattern.map(pat => localEvalNodeWithScope(pat, scope)); - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: patterns =`, patterns); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: patterns =`, patterns); } // Check if patterns match the values @@ -2065,14 +2199,14 @@ function interpreter(ast, environment = null, initialState = {}) { const value = whenValues[i]; const pattern = patterns[i]; - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: comparing value ${value} with pattern ${pattern}`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: comparing value ${value} with pattern ${pattern}`); } if (pattern === true) { // Wildcard pattern // Wildcard always matches - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: wildcard matches`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: wildcard matches`); } continue; } else if (typeof pattern === 'object' && pattern !== null && typeof value === 'object' && value !== null) { @@ -2086,31 +2220,31 @@ function interpreter(ast, environment = null, initialState = {}) { } if (!tableMatches) { matches = false; - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: table pattern does not match`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: table pattern does not match`); } break; - } else { - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: table pattern matches`); + } else { + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: table pattern matches`); + } } - } } else if (value !== pattern) { matches = false; - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: pattern does not match`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: pattern does not match`); } break; } else { - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: pattern matches`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: pattern matches`); } } } } - if (process.env.DEBUG) { - console.log(`[DEBUG] localEvalNodeWithScope WhenExpression: case matches = ${matches}`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] localEvalNodeWithScope WhenExpression: case matches = ${matches}`); } if (matches) { @@ -2125,22 +2259,18 @@ function interpreter(ast, environment = null, initialState = {}) { case 'WildcardPattern': return true; case 'IOInExpression': - const readline = require('readline'); - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout - }); + const rl2 = createReadline(); return new Promise((resolve) => { - rl.question('', (input) => { - rl.close(); + rl2.question('', (input) => { + rl2.close(); const num = parseInt(input); resolve(isNaN(num) ? input : num); }); }); case 'IOOutExpression': const localOutputValue = localEvalNodeWithScope(node.value, scope); - console.log(localOutputValue); + safeConsoleLog(localOutputValue); ioOperationsPerformed = true; return localOutputValue; case 'IOAssertExpression': @@ -2152,13 +2282,13 @@ function interpreter(ast, environment = null, initialState = {}) { case 'IOListenExpression': // Return current state from environment if available, otherwise placeholder if (environment && typeof environment.getCurrentState === 'function') { - if (process.env.DEBUG) { - console.log('[DEBUG] ..listen called - returning state from environment'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..listen called - returning state from environment'); } return environment.getCurrentState(); } else { - if (process.env.DEBUG) { - console.log('[DEBUG] ..listen called - returning placeholder state'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..listen called - returning placeholder state'); } return { status: 'placeholder', message: 'State not available in standalone mode' }; } @@ -2166,12 +2296,12 @@ function interpreter(ast, environment = null, initialState = {}) { const localEmitValue = localEvalNodeWithScope(node.value, scope); // Send value to environment if available, otherwise log to console if (environment && typeof environment.emitValue === 'function') { - if (process.env.DEBUG) { - console.log('[DEBUG] ..emit called - sending to environment'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..emit called - sending to environment'); } environment.emitValue(localEmitValue); } else { - console.log('[EMIT]', localEmitValue); + safeConsoleLog('[EMIT]', localEmitValue); } ioOperationsPerformed = true; return localEmitValue; @@ -2456,22 +2586,18 @@ function interpreter(ast, environment = null, initialState = {}) { case 'WildcardPattern': return true; case 'IOInExpression': - const readline = require('readline'); - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout - }); + const rl3 = createReadline(); return new Promise((resolve) => { - rl.question('', (input) => { - rl.close(); + rl3.question('', (input) => { + rl3.close(); const num = parseInt(input); resolve(isNaN(num) ? input : num); }); }); case 'IOOutExpression': const localOutputValue = localEvalNode(node.value); - console.log(localOutputValue); + safeConsoleLog(localOutputValue); ioOperationsPerformed = true; return localOutputValue; case 'IOAssertExpression': @@ -2483,13 +2609,13 @@ function interpreter(ast, environment = null, initialState = {}) { case 'IOListenExpression': // Return current state from environment if available, otherwise placeholder if (environment && typeof environment.getCurrentState === 'function') { - if (process.env.DEBUG) { - console.log('[DEBUG] ..listen called - returning state from environment'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..listen called - returning state from environment'); } return environment.getCurrentState(); } else { - if (process.env.DEBUG) { - console.log('[DEBUG] ..listen called - returning placeholder state'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..listen called - returning placeholder state'); } return { status: 'placeholder', message: 'State not available in standalone mode' }; } @@ -2497,12 +2623,12 @@ function interpreter(ast, environment = null, initialState = {}) { const localEmitValue = localEvalNode(node.value); // Send value to environment if available, otherwise log to console if (environment && typeof environment.emitValue === 'function') { - if (process.env.DEBUG) { - console.log('[DEBUG] ..emit called - sending to environment'); + if (DEBUG) { + safeConsoleLog('[DEBUG] ..emit called - sending to environment'); } environment.emitValue(localEmitValue); } else { - console.log('[EMIT]', localEmitValue); + safeConsoleLog('[EMIT]', localEmitValue); } ioOperationsPerformed = true; return localEmitValue; @@ -2614,10 +2740,10 @@ function run(scriptContent, initialState = {}, environment = null) { * expressions and function applications. */ function debugLog(message, data = null) { - if (process.env.DEBUG) { - console.log(`[DEBUG] ${message}`); + if (DEBUG) { + safeConsoleLog(`[DEBUG] ${message}`); if (data) { - console.log(data); + safeConsoleLog(data); } } } @@ -2641,10 +2767,10 @@ function debugLog(message, data = null) { * execution pipeline. */ function debugError(message, error = null) { - if (process.env.DEBUG) { - console.error(`[DEBUG ERROR] ${message}`); + if (DEBUG) { + safeConsoleError(`[DEBUG ERROR] ${message}`); if (error) { - console.error(error); + safeConsoleError(error); } } } @@ -2705,8 +2831,8 @@ const callStackTracker = { throw new Error(`Potential infinite recursion detected. Call stack depth: ${this.stack.length}`); } - if (process.env.DEBUG && this.stack.length % 100 === 0) { - console.log(`[DEBUG] Call stack depth: ${this.stack.length}, Max: ${this.maxDepth}`); + if (DEBUG && this.stack.length % 100 === 0) { + safeConsoleLog(`[DEBUG] Call stack depth: ${this.stack.length}, Max: ${this.maxDepth}`); } }, @@ -2766,22 +2892,18 @@ const callStackTracker = { * workflow where tests and examples are stored as .txt files. */ async function readFile(filePath) { - // Check if we're in a browser environment - if (typeof window !== 'undefined') { - // Browser environment - would need to implement file input or fetch - throw new Error('File I/O not supported in browser environment'); - } + // Use cross-platform filesystem + const fs = createFileSystem(); - // Node.js or Bun environment - try { - // Try dynamic import for ES modules compatibility - const fs = await import('fs'); - return fs.readFileSync(filePath, 'utf8'); - } catch (error) { - // Fallback to require for older Node.js versions - const fs = require('fs'); - return fs.readFileSync(filePath, 'utf8'); - } + return new Promise((resolve, reject) => { + fs.readFile(filePath, 'utf8', (error, data) => { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + }); } /** @@ -2835,50 +2957,50 @@ async function executeFile(filePath) { if (result instanceof Promise) { result.then(finalResult => { // Only output result if debug mode is enabled (no automatic final result output) - if (finalResult.result !== undefined && process.env.DEBUG) { - console.log(finalResult.result); + if (finalResult.result !== undefined && DEBUG) { + safeConsoleLog(finalResult.result); } // Print call stack statistics only in debug mode - if (process.env.DEBUG) { + if (DEBUG) { const stats = callStackTracker.getStats(); - console.log('\n=== CALL STACK STATISTICS ==='); - console.log('Maximum call stack depth:', stats.maxDepth); - console.log('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); + safeConsoleLog('\n=== CALL STACK STATISTICS ==='); + safeConsoleLog('Maximum call stack depth:', stats.maxDepth); + safeConsoleLog('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); } }).catch(error => { - console.error(`Error executing file: ${error.message}`); + safeConsoleError(`Error executing file: ${error.message}`); // Print call stack statistics on error only in debug mode - if (process.env.DEBUG) { + if (DEBUG) { const stats = callStackTracker.getStats(); - console.error('\n=== CALL STACK STATISTICS ON ERROR ==='); - console.error('Maximum call stack depth:', stats.maxDepth); - console.error('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); + safeConsoleError('\n=== CALL STACK STATISTICS ON ERROR ==='); + safeConsoleError('Maximum call stack depth:', stats.maxDepth); + safeConsoleError('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); } - process.exit(1); + safeExit(1); }); } else { // Only output result if debug mode is enabled (no automatic final result output) - if (result.result !== undefined && process.env.DEBUG) { - console.log(result.result); + if (result.result !== undefined && DEBUG) { + safeConsoleLog(result.result); } // Print call stack statistics only in debug mode - if (process.env.DEBUG) { + if (DEBUG) { const stats = callStackTracker.getStats(); - console.log('\n=== CALL STACK STATISTICS ==='); - console.log('Maximum call stack depth:', stats.maxDepth); - console.log('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); + safeConsoleLog('\n=== CALL STACK STATISTICS ==='); + safeConsoleLog('Maximum call stack depth:', stats.maxDepth); + safeConsoleLog('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); } } } catch (error) { - console.error(`Error executing file: ${error.message}`); + safeConsoleError(`Error executing file: ${error.message}`); // Print call stack statistics on error only in debug mode - if (process.env.DEBUG) { + if (DEBUG) { const stats = callStackTracker.getStats(); - console.error('\n=== CALL STACK STATISTICS ON ERROR ==='); - console.error('Maximum call stack depth:', stats.maxDepth); - console.error('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); + safeConsoleError('\n=== CALL STACK STATISTICS ON ERROR ==='); + safeConsoleError('Maximum call stack depth:', stats.maxDepth); + safeConsoleError('Function call counts:', JSON.stringify(stats.callCounts, null, 2)); } - process.exit(1); + safeExit(1); } } @@ -2896,29 +3018,34 @@ async function executeFile(filePath) { * Exits with appropriate error codes for different failure scenarios. */ async function main() { + // Only run main function in Node.js/Bun environments + if (!isNode && !isBun) { + return; // Skip in browser environment + } + const args = process.argv.slice(2); if (args.length === 0) { - console.error('Usage: node lang.js <file>'); - console.error(' Provide a file path to execute'); - process.exit(1); + safeConsoleError('Usage: node lang.js <file>'); + safeConsoleError(' Provide a file path to execute'); + safeExit(1); } else if (args.length === 1) { // Execute the file const filePath = args[0]; await executeFile(filePath); } else { // Too many arguments - console.error('Usage: node lang.js <file>'); - console.error(' Provide exactly one file path to execute'); - process.exit(1); + safeConsoleError('Usage: node lang.js <file>'); + safeConsoleError(' Provide exactly one file path to execute'); + safeExit(1); } } -// Start the program only if this file is run directly -if (process.argv[1] && process.argv[1].endsWith('lang.js')) { +// Start the program only if this file is run directly in Node.js/Bun +if ((isNode || isBun) && process.argv[1] && process.argv[1].endsWith('lang.js')) { main().catch(error => { - console.error('Fatal error:', error.message); - process.exit(1); + safeConsoleError('Fatal error:', error.message); + safeExit(1); }); } @@ -2935,17 +3062,13 @@ export { run, interpreter, lexer, parser }; </div> -<nav> - <h2><a href="index.html">Home</a></h2><h3>Tutorials</h3><ul><li><a href="tutorial-00_Introduction.html">00_Introduction</a></li><li><a href="tutorial-01_Juxtaposition_Function_Application.html">01_Juxtaposition_Function_Application</a></li><li><a href="tutorial-02_Right_Associative_Via_Operator.html">02_Right_Associative_Via_Operator</a></li><li><a href="tutorial-03_Automatic_Element_Wise_Table_Operations.html">03_Automatic_Element_Wise_Table_Operations</a></li><li><a href="tutorial-04_Partial_Application_by_Default.html">04_Partial_Application_by_Default</a></li><li><a href="tutorial-05_When_Expressions_Pattern_Matching.html">05_When_Expressions_Pattern_Matching</a></li><li><a href="tutorial-06_Immutable_Tables_with_Functional_Operations.html">06_Immutable_Tables_with_Functional_Operations</a></li><li><a href="tutorial-07_Function_References_with_At_Symbol.html">07_Function_References_with_At_Symbol</a></li><li><a href="tutorial-08_Combinator_Based_Architecture.html">08_Combinator_Based_Architecture</a></li><li><a href="tutorial-09_No_Explicit_Return_Statements.html">09_No_Explicit_Return_Statements</a></li><li><a href="tutorial-10_Table_Literals_as_Primary_Data_Structure.html">10_Table_Literals_as_Primary_Data_Structure</a></li><li><a href="tutorial-11_Combinators_Deep_Dive.html">11_Combinators_Deep_Dive</a></li><li><a href="tutorial-12_Functional_Harness_Integration.html">12_Functional_Harness_Integration</a></li><li><a href="tutorial-13_Operator_Spacing_Best_Practices.html">13_Operator_Spacing_Best_Practices</a></li><li><a href="tutorial-README.html">README</a></li></ul><h3>Global</h3><ul><li><a href="global.html#callStackTracker">callStackTracker</a></li><li><a href="global.html#debugError">debugError</a></li><li><a href="global.html#debugLog">debugLog</a></li><li><a href="global.html#executeFile">executeFile</a></li><li><a href="global.html#initializeStandardLibrary">initializeStandardLibrary</a></li><li><a href="global.html#interpreter">interpreter</a></li><li><a href="global.html#lexer">lexer</a></li><li><a href="global.html#main">main</a></li><li><a href="global.html#parser">parser</a></li><li><a href="global.html#readFile">readFile</a></li><li><a href="global.html#run">run</a></li></ul> -</nav> - <br class="clear"> <footer> - Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.4</a> on Tue Jul 29 2025 14:41:59 GMT-0400 (Eastern Daylight Time) + 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> +<script>prettyPrint();</script> +<script src="scripts/linenumber.js"></script> </body> </html> |