import { Pos } from "./Token.ts";

type UnaryType = "not";
export type BinaryType = "+" | "*" | "==" | "-" | "/" | "!=" | "<" | ">" | "<=" | ">=" | "or" | "and";

export type Param = {
    ident: string,
    pos: Pos,
};

export type Stmt = {
    kind: StmtKind,
    pos: Pos,
    id: number,
};

export type StmtKind =
    | { type: "error" }
    | { type: "break", expr?: Expr }
    | { type: "return", expr?: Expr }
    | { type: "fn", ident: string, params: Param[], body: Expr }
    | { type: "let", param: Param, value: Expr }
    | { type: "assign", subject: Expr, value: Expr }
    | { type: "expr", expr: Expr }
    ;

export type Expr = {
    kind: ExprKind,
    pos: Pos,
    id: number,
};

export type ExprKind =
    | { type: "error" }
    | { type: "int", value: number }
    | { type: "string", value: string }
    | { type: "ident", value: string }
    | { type: "group", expr: Expr }
    | { type: "field", subject: Expr, value: string }
    | { type: "index", subject: Expr, value: Expr }
    | { type: "call", subject: Expr, args: Expr[] }
    | { type: "unary", unaryType: UnaryType, subject: Expr }
    | { type: "binary", binaryType: BinaryType, left: Expr, right: Expr }
    | { type: "if", cond: Expr, truthy: Expr, falsy?: Expr }
    | { type: "bool", value: boolean}
    | { type: "null"}
    | { type: "loop", body: Expr }
    | { type: "block", stmts: Stmt[], expr?: Expr }
    ;