From 166526e54bd9d2ca4ab20fff138d85561a0e738b Mon Sep 17 00:00:00 2001 From: Yura Dupyn <2153100+omedusyo@users.noreply.github.com> Date: Tue, 3 Feb 2026 23:56:05 +0100 Subject: [PATCH] Outline a programming language's abstract-expressions/values --- src/value.ts | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/value.ts diff --git a/src/value.ts b/src/value.ts new file mode 100644 index 0000000..58fc8f3 --- /dev/null +++ b/src/value.ts @@ -0,0 +1,107 @@ + +// === 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, +} +