"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const IMolangNode_1 = require("./IMolangNode");
const MolangNode_1 = require("./MolangNode");
// NOTE NOTE: I tried to call this MolangExpression but it was giving errors in the vscbuild process
class Molang {
    _data;
    constructor(molang) {
        const node = this.parse(molang);
        this._data = { rootNode: node.data };
    }
    parse(molangExpression) {
        const tokens = this.tokenize(molangExpression);
        const syntaxTree = this.parseTokens(tokens);
        return syntaxTree;
    }
    tokenize(expression) {
        // Simple tokenizer splitting by spaces and operators
        return expression.match(/(\d+|\w+|[()+\-/])/g) || [];
    }
    parseTokens(tokens) {
        const stack = [];
        const operators = [];
        const precedence = {
            "+": 1,
            "-": 1,
            "*": 2,
            "/": 2,
        };
        const operatorSet = new Set(["+", "-", "*", "/"]);
        const applyOperator = () => {
            const operator = operators.pop();
            const right = stack.pop();
            const left = stack.pop();
            const node = {
                type: IMolangNode_1.MolangNodeType.operator,
                value: operator,
                left: left?.data,
                right: right?.data,
            };
            stack.push(new MolangNode_1.default(node));
        };
        for (const token of tokens) {
            if (/\d+/.test(token)) {
                stack.push(new MolangNode_1.default({ type: IMolangNode_1.MolangNodeType.number, value: token }));
            }
            else if (/\w+/.test(token)) {
                stack.push(new MolangNode_1.default({ type: IMolangNode_1.MolangNodeType.variable, value: token }));
            }
            else if (token === "(") {
                operators.push(token);
            }
            else if (token === ")") {
                while (operators.length && operators[operators.length - 1] !== "(") {
                    applyOperator();
                }
                operators.pop(); // Remove '('
            }
            else if (operatorSet.has(token)) {
                while (operators.length && precedence[operators[operators.length - 1]] >= precedence[token]) {
                    applyOperator();
                }
                operators.push(token);
            }
        }
        while (operators.length) {
            applyOperator();
        }
        return stack[0];
    }
}
exports.default = Molang;

//# sourceMappingURL=../maps/minecraft/Molang.js.map
