lel = {
function parseExpression(tokens, index) {
let exprStack = [];
let previousToken = null;
while (index < tokens.length) {
let token = tokens[index];
index++;
if (token === "(") {
const result = parseExpression(tokens, index);
exprStack.push(result.expression);
index = result.newIndex;
} else if (token === ")") {
break;
} else if (infixOperators.includes(token)) {
exprStack.push(token);
} else if (
prefixOperators.includes(token) &&
(!previousToken || infixOperators.includes(previousToken))
) {
const operand = tokens[index];
index++;
exprStack.push([token, operand]);
} else {
// console.log(`Detected operand or unknown token: ${token}`);
exprStack.push(token);
}
// console.log(
// `Expression stack after processing ${token}: ${JSON.stringify(
// exprStack
// )}`
// );
previousToken = token;
}
// console.log(`--- Exiting parseExpression ---`);
let currentExpr = exprStack.pop();
while (exprStack.length > 0) {
const operator = exprStack.pop();
let leftOperand;
if (exprStack.length > 0) {
leftOperand = exprStack.pop();
currentExpr = [operator, leftOperand, currentExpr];
} else {
currentExpr = [operator, currentExpr];
}
}
return { expression: currentExpr, newIndex: index };
}
/**
* Parses a string expression and returns it in S-expression format.
*
* @func
* @sig String -> Array
* @param {TemplateStringsArray} strings - The string literals.
* @param {...*} values - The string values.
* @return {Array} The parsed expression in S-expression format.
* @throws {Error} Throws an error if the expression cannot be parsed.
* @example
*
* sExp`(a + b)^2`; //=> ["^", ["+", "a", "b"], "2"]
* sExp`a + b`; //=> ["+", "a", "b"]
* sExp`!a`; //=> ["!", "a"]
*/
function sExp(strings, ...values) {
const input = String.raw(strings, ...values);
//console.log(`Starting to process input: ${input}`);
let tokens = input
.split(/\s+/)
.join("")
.split(/(>>>?|&&|\|\||>=?|<=?|[+\-*/()^><=|&!])/)
.filter((t) => t.length > 0);
//console.log(`Initial tokens: ${JSON.stringify(tokens)}`);
let index = 0;
try {
const result = parseExpression(tokens, index);
return result.expression;
} catch (error) {
throw new Error(`Error parsing expression: ${error.message}`);
}
}
var infixOperators = [
"+",
"-",
"*",
"/",
"^",
"=>",
"=<",
">>",
">>>",
":>",
"<",
"|",
"&",
"||",
"&&",
">="
];
var prefixOperators = ["!", "-"];
return { sExp };
}