/**
 * Expression node type constants and constructors for the Architect expression tree.
 *
 * These nodes are produced by expressionParser.js (Pratt parser) from a TokenSpan.
 * They are separate from the statement-level nodes in nodes.js.
 */

const ExprNodeType = Object.freeze({
    LITERAL:    "Literal",      // string, number, boolean literal
    DATE:       "Date",         // date literal: DD/MM/YYYY (DATE_LITERAL token)
    TIME:       "Time",         // time literal: HH:MM:SS:CC (TIME_LITERAL token)
    IDENTIFIER: "Identifier",   // variable name or builtin constant/function reference
    CALL:       "Call",         // function call: callee + args[]
    UNARY:      "Unary",        // prefix op + operand
    BINARY:     "Binary",       // op + left + right
    PAREN:      "Paren",        // (expr) — preserved for position data
});

function makeLiteral(token, inferredType) {
    return { type: ExprNodeType.LITERAL, value: token.value, inferredType, token };
}

function makeDateNode(token) {
    return { type: ExprNodeType.DATE, value: token.value, inferredType: "DATE", token };
}

function makeTimeNode(token) {
    return { type: ExprNodeType.TIME, value: token.value, inferredType: "TIME", token };
}

function makeIdentifier(token) {
    return { type: ExprNodeType.IDENTIFIER, name: token.value, token };
}

function makeCall(callee, args, startToken, endToken) {
    return { type: ExprNodeType.CALL, callee, args, startToken, endToken };
}

function makeUnary(op, operand, token) {
    return { type: ExprNodeType.UNARY, op, operand, token };
}

function makeBinary(op, left, right, token) {
    return { type: ExprNodeType.BINARY, op, left, right, token };
}

function makeParen(expr, token) {
    return { type: ExprNodeType.PAREN, expr, token };
}

export {
    ExprNodeType,
    makeLiteral,
    makeDateNode,
    makeTimeNode,
    makeIdentifier,
    makeCall,
    makeUnary,
    makeBinary,
    makeParen,
};
