"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.simplifyFunctions = void 0;
const Literal_1 = __importDefault(require("../ast/Literal"));
const binaryOps = {
    "||": (a, b) => a || b,
    "&&": (a, b) => a && b,
    "+": (a, b) => a + b,
    "-": (a, b) => a - b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
    "**": (a, b) => a ** b,
    "^": (a, b) => a ^ b,
};
const unaryOps = {
    "!": (a) => !a,
    "+": (a) => +a,
    "-": (a) => -a,
    "~": (a) => ~a,
};
exports.simplifyFunctions = {
    BinaryExpression(node, resolved) {
        let left = resolved.get(node.left);
        let right = resolved.get(node.right);
        if (Literal_1.default.is(left) && Literal_1.default.is(right)) {
            let value = binaryOps[node.operator](left.value, right.value);
            return new Literal_1.default({ location: node.location, value });
        }
    },
    UnaryExpression(node, resolved) {
        if (Literal_1.default.is(node.argument)) {
            let arg = resolved.get(node.argument);
            let value = unaryOps[node.operator](arg.value);
            return new Literal_1.default({ location: node.location, value });
        }
    },
    Literal(node) {
    },
    ClassDeclaration(node) {
    },
    Parameter(node) {
    },
    VariableDeclaration(node) {
    },
    FunctionExpression(node) {
    },
    Reference(node) {
    },
    MemberExpression(node) {
    },
    ArrayExpression(node) {
    },
    CallExpression(node) {
    },
};
function evaluate(node, resolved, scopes) {
    var _a;
    let func = exports.simplifyFunctions[node.constructor.name];
    return (_a = func === null || func === void 0 ? void 0 : func(node, resolved, scopes)) !== null && _a !== void 0 ? _a : node;
}
exports.default = evaluate;
