// === Identifiers === type VariableName = string type FunctionName = string type CellName = string type Tag = string type FieldName = string type Program = { function_definitions: { name: FunctionName, definition: FunctionDefinition }[], // TODO: Perhaps include the story and the environment? // story should be a list of currently viewed bindings // environment should be like the store... maybe call it store! It should map names to values and perhaps expressions that generated the value... // like a reactive cell. This is the analogue of the tiddler. store: Map }; type Cell = { name: CellName, expression: Expr, cached_value?: Value, status: "clean" | "dirty" | "error", // TODO: Dependencies? Not sure about this yet... // dependencies?: Set, } type CellStatus = | "clean" | "dirty" | "error" type FunctionDefinition = | { tag: "user", def: UserFunctionDefinition } | { tag: "primitive", def: PrimitiveFunctionDefinition } type UserFunctionDefinition = { name: FunctionName, parameters: ProductPattern[], body: Expr, } type PrimitiveFunctionDefinition = { name: FunctionName, number_of_parameters: number, implementation: (args: Value[]) => Value, } // === Expressions === type Expr = | { tag: "literal", literal: Literal } | { tag: "var_use", name: VariableName } | { tag: "cell_ref", name: CellName } | { tag: "call", name: FunctionName, args: Expr[] } | { tag: "let", bindings: ExprBinding[], body: Expr } | { tag: "tag", tag_name: Tag } | { tag: "tagged", tag_name: Tag, expr: Expr } | { tag: "tuple", exprs: Expr[] } | { tag: "record", fields: { name: FieldName, expr: Expr }[] } | { tag: "match", arg: Expr, branches: { pattern: Pattern, body: Expr }[] } | { tag: "lambda", parameters: ProductPattern[], body: Expr } | { tag: "apply", callee: Expr, args: Expr[] } type Literal = | { tag: "number", value: number } | { tag: "string", value: string } type ExprBinding = { var: ProductPattern, expr: Expr, } type Pattern = | { tag: "any", name: VariableName } | { tag: "tuple", patterns: ProductPattern[] } | { tag: "tag", tag_name: Tag } | { tag: "tagged", tag_name: Tag, pattern: Pattern } type ProductPattern = | { tag: "any", name: VariableName } | { tag: "tuple", patterns: ProductPattern[] } | { tag: "record", fields: { name: FieldName, pattern: ProductPattern }[] } // === Values === type Value = | { tag: "string", value: string } | { tag: "number", value: number } | { tag: "tag", tag_name: Tag } | { tag: "tagged", tag_name: Tag, value: Value } | { tag: "tuple", values: Value[] } | { tag: "record", fields: { name: FieldName, value: Value }[] } | { tag: "closure", closure: Closure } type EnvBinding = { var: VariableName, value: Value, } type Env = EnvBinding[]; type Closure = { env: Env, parameters: ProductPattern[], body: Expr, }