Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/language/runtime/keywords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import {
type KeywordHandlers,
type SemanticGraph,
} from '../semantics.js'
import {
lookupPropertyOfObjectNode,
makeUnelaboratedObjectNode,
} from '../semantics/object-node.js'
import { lookupPropertyOfObjectNode } from '../semantics/object-node.js'
import { prettyJson } from '../unparsing.js'

const unserializableFunction = () =>
Expand Down Expand Up @@ -169,10 +166,7 @@ const lookupWithinExpression = (
expression: Expression,
): Option<SemanticGraph> => {
for (const key of keyAliases) {
const result = lookupPropertyOfObjectNode(
key,
makeUnelaboratedObjectNode(expression),
)
const result = lookupPropertyOfObjectNode(key, makeObjectNode(expression))
if (!option.isNone(result)) {
return result
}
Expand Down
2 changes: 0 additions & 2 deletions src/language/semantics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,13 @@ export {
isObjectNode,
lookupPropertyOfObjectNode,
makeObjectNode,
makeUnelaboratedObjectNode,
type ObjectNode,
} from './semantics/object-node.js'
export { prelude } from './semantics/prelude.js'
export {
applyKeyPathToSemanticGraph,
containsAnyUnelaboratedNodes,
isSemanticGraph,
isUnelaborated,
matchSemanticGraph,
serialize,
stringifySemanticGraphForEndUser,
Expand Down
13 changes: 3 additions & 10 deletions src/language/semantics/expression-elaboration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import type { Atom, Molecule, SyntaxTree } from '../parsing.js'
import type { Expression } from './expression.js'
import type { KeyPath } from './key-path.js'
import { isKeyword, type Keyword } from './keyword.js'
import {
makeObjectNode,
makeUnelaboratedObjectNode,
type ObjectNode,
} from './object-node.js'
import { makeObjectNode, type ObjectNode } from './object-node.js'
import {
extractStringValueIfPossible,
updateValueAtKeyPathInSemanticGraph,
Expand Down Expand Up @@ -44,10 +40,7 @@ export const elaborate = (
elaborateWithContext(program, {
keywordHandlers,
location: [],
program:
typeof program === 'string'
? program
: makeUnelaboratedObjectNode(program),
program: typeof program === 'string' ? program : makeObjectNode(program),
})

export const elaborateWithContext = (
Expand Down Expand Up @@ -161,7 +154,7 @@ const handleObjectNodeWhichMayBeAExpression = (
const { 0: possibleKeyword, ...possibleArguments } = node
return isKeyword(possibleKeyword)
? context.keywordHandlers[possibleKeyword](
makeUnelaboratedObjectNode({
makeObjectNode({
...possibleArguments,
0: possibleKeyword,
}),
Expand Down
8 changes: 4 additions & 4 deletions src/language/semantics/expressions/apply-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import either, { type Either } from '@matt.kantor/either'
import type { ElaborationError } from '../../errors.js'
import type { Molecule } from '../../parsing.js'
import { isSpecificExpression } from '../expression.js'
import { makeUnelaboratedObjectNode, type ObjectNode } from '../object-node.js'
import { type SemanticGraph, type unelaboratedKey } from '../semantic-graph.js'
import { makeObjectNode, type ObjectNode } from '../object-node.js'
import { type SemanticGraph } from '../semantic-graph.js'
import { readArgumentsFromExpression } from './expression-utilities.js'

export type ApplyExpression = ObjectNode & {
Expand Down Expand Up @@ -34,8 +34,8 @@ export const makeApplyExpression = ({
}: {
readonly function: SemanticGraph | Molecule
readonly argument: SemanticGraph | Molecule
}): ApplyExpression & { readonly [unelaboratedKey]: true } =>
makeUnelaboratedObjectNode({
}): ApplyExpression =>
makeObjectNode({
0: '@apply',
function: f,
argument,
Expand Down
8 changes: 4 additions & 4 deletions src/language/semantics/expressions/check-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import either, { type Either } from '@matt.kantor/either'
import type { ElaborationError } from '../../errors.js'
import type { Molecule } from '../../parsing.js'
import { isSpecificExpression } from '../expression.js'
import { makeUnelaboratedObjectNode, type ObjectNode } from '../object-node.js'
import { type SemanticGraph, type unelaboratedKey } from '../semantic-graph.js'
import { makeObjectNode, type ObjectNode } from '../object-node.js'
import { type SemanticGraph } from '../semantic-graph.js'
import { readArgumentsFromExpression } from './expression-utilities.js'

export type CheckExpression = ObjectNode & {
Expand Down Expand Up @@ -34,8 +34,8 @@ export const makeCheckExpression = ({
}: {
value: SemanticGraph | Molecule
type: SemanticGraph | Molecule
}): CheckExpression & { readonly [unelaboratedKey]: true } =>
makeUnelaboratedObjectNode({
}): CheckExpression =>
makeObjectNode({
0: '@check',
value,
type,
Expand Down
10 changes: 3 additions & 7 deletions src/language/semantics/expressions/expression-utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Expression } from '../expression.js'
import { stringifyKeyPathForEndUser } from '../key-path.js'
import {
lookupPropertyOfObjectNode,
makeUnelaboratedObjectNode,
makeObjectNode,
type ObjectNode,
} from '../object-node.js'
import {
Expand All @@ -18,8 +18,7 @@ import {

export const asSemanticGraph = (
value: SemanticGraph | Molecule,
): SemanticGraph =>
isSemanticGraph(value) ? value : makeUnelaboratedObjectNode(value)
): SemanticGraph => (isSemanticGraph(value) ? value : makeObjectNode(value))

export const locateSelf = (context: ExpressionContext) =>
option.match(applyKeyPathToSemanticGraph(context.program, context.location), {
Expand Down Expand Up @@ -73,10 +72,7 @@ const lookupWithinExpression = (
expression: Expression,
): Option<SemanticGraph> => {
for (const key of keyAliases) {
const result = lookupPropertyOfObjectNode(
key,
makeUnelaboratedObjectNode(expression),
)
const result = lookupPropertyOfObjectNode(key, makeObjectNode(expression))
if (!option.isNone(result)) {
return result
}
Expand Down
12 changes: 4 additions & 8 deletions src/language/semantics/expressions/function-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@ import either, { type Either } from '@matt.kantor/either'
import type { ElaborationError } from '../../errors.js'
import type { Atom, Molecule } from '../../parsing.js'
import { isSpecificExpression } from '../expression.js'
import { makeUnelaboratedObjectNode, type ObjectNode } from '../object-node.js'
import {
serialize,
type SemanticGraph,
type unelaboratedKey,
} from '../semantic-graph.js'
import { makeObjectNode, type ObjectNode } from '../object-node.js'
import { serialize, type SemanticGraph } from '../semantic-graph.js'
import {
asSemanticGraph,
readArgumentsFromExpression,
Expand Down Expand Up @@ -46,8 +42,8 @@ export const readFunctionExpression = (
export const makeFunctionExpression = (
parameter: Atom,
body: SemanticGraph | Molecule,
): FunctionExpression & { readonly [unelaboratedKey]: true } =>
makeUnelaboratedObjectNode({
): FunctionExpression =>
makeObjectNode({
0: '@function',
parameter,
body,
Expand Down
8 changes: 4 additions & 4 deletions src/language/semantics/expressions/index-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { isSpecificExpression } from '../expression.js'
import { keyPathFromObjectNodeOrMolecule } from '../key-path.js'
import {
isObjectNode,
makeUnelaboratedObjectNode,
makeObjectNode,
type ObjectNode,
} from '../object-node.js'
import { type SemanticGraph, type unelaboratedKey } from '../semantic-graph.js'
import { type SemanticGraph } from '../semantic-graph.js'
import {
asSemanticGraph,
readArgumentsFromExpression,
Expand Down Expand Up @@ -61,8 +61,8 @@ export const makeIndexExpression = ({
}: {
readonly query: ObjectNode | Molecule
readonly object: ObjectNode | Molecule
}): IndexExpression & { readonly [unelaboratedKey]: true } =>
makeUnelaboratedObjectNode({
}): IndexExpression =>
makeObjectNode({
0: '@index',
object,
query,
Expand Down
12 changes: 4 additions & 8 deletions src/language/semantics/expressions/lookup-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@ import {
keyPathFromObjectNodeOrMolecule,
keyPathToMolecule,
} from '../key-path.js'
import {
makeObjectNode,
makeUnelaboratedObjectNode,
type ObjectNode,
} from '../object-node.js'
import { type SemanticGraph, type unelaboratedKey } from '../semantic-graph.js'
import { makeObjectNode, type ObjectNode } from '../object-node.js'
import { type SemanticGraph } from '../semantic-graph.js'
import {
asSemanticGraph,
readArgumentsFromExpression,
Expand Down Expand Up @@ -56,8 +52,8 @@ export const readLookupExpression = (

export const makeLookupExpression = (
query: ObjectNode | Molecule,
): LookupExpression & { readonly [unelaboratedKey]: true } =>
makeUnelaboratedObjectNode({
): LookupExpression =>
makeObjectNode({
0: '@lookup',
query,
})
9 changes: 3 additions & 6 deletions src/language/semantics/expressions/runtime-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import type { ElaborationError } from '../../errors.js'
import type { Molecule } from '../../parsing.js'
import { isSpecificExpression } from '../expression.js'
import { isFunctionNode } from '../function-node.js'
import { makeUnelaboratedObjectNode, type ObjectNode } from '../object-node.js'
import { makeObjectNode, type ObjectNode } from '../object-node.js'
import {
containsAnyUnelaboratedNodes,
type SemanticGraph,
type unelaboratedKey,
} from '../semantic-graph.js'
import {
asSemanticGraph,
Expand Down Expand Up @@ -46,10 +45,8 @@ export const readRuntimeExpression = (
message: 'not an expression',
})

export const makeRuntimeExpression = (
f: SemanticGraph,
): RuntimeExpression & { readonly [unelaboratedKey]: true } =>
makeUnelaboratedObjectNode({
export const makeRuntimeExpression = (f: SemanticGraph): RuntimeExpression =>
makeObjectNode({
0: '@runtime',
function: f,
})
18 changes: 1 addition & 17 deletions src/language/semantics/object-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@ import option, { type Option } from '@matt.kantor/option'
import type { Writable } from '../../utility-types.js'
import type { UnserializableValueError } from '../errors.js'
import type { Atom, Molecule } from '../parsing.js'
import {
nodeTag,
serialize,
unelaboratedKey,
type SemanticGraph,
} from './semantic-graph.js'
import { nodeTag, serialize, type SemanticGraph } from './semantic-graph.js'

export type ObjectNode = {
readonly [nodeTag]: 'object'
readonly [key: Atom]: SemanticGraph | Molecule
readonly [unelaboratedKey]?: true
}

export const isObjectNode = (node: SemanticGraph) =>
Expand All @@ -38,16 +32,6 @@ export const makeObjectNode = <
[nodeTag]: 'object',
})

export const makeUnelaboratedObjectNode = <
const Properties extends Readonly<Record<Atom, SemanticGraph | Molecule>>,
>(
properties: Properties,
): ObjectNode & Properties & { readonly [unelaboratedKey]: true } => ({
...properties,
[nodeTag]: 'object',
[unelaboratedKey]: true,
})

export const serializeObjectNode = (
node: ObjectNode,
): Either<UnserializableValueError, Molecule> => {
Expand Down
19 changes: 4 additions & 15 deletions src/language/semantics/semantic-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@ import type {
import type { Atom, Molecule } from '../parsing.js'
import type { Canonicalized } from '../parsing/syntax-tree.js'
import { inlinePlz, unparse } from '../unparsing.js'
import { isExpression } from './expression.js'
import { serializeFunctionNode, type FunctionNode } from './function-node.js'
import { stringifyKeyPathForEndUser, type KeyPath } from './key-path.js'
import {
makeObjectNode,
makeUnelaboratedObjectNode,
serializeObjectNode,
type ObjectNode,
} from './object-node.js'

export const nodeTag = Symbol('nodeTag')

export const unelaboratedKey = Symbol('unelaborated')

export type SemanticGraph = Atom | FunctionNode | ObjectNode

export const applyKeyPathToSemanticGraph = (
Expand Down Expand Up @@ -49,15 +47,10 @@ export const applyKeyPathToSemanticGraph = (
}
}

export const isUnelaborated = (node: SemanticGraph | Molecule): boolean =>
typeof node !== 'string' &&
unelaboratedKey in node &&
node[unelaboratedKey] === true

export const containsAnyUnelaboratedNodes = (
node: SemanticGraph | Molecule,
): boolean => {
if (isUnelaborated(node)) {
if (isExpression(node)) {
return true
} else if (typeof node === 'object') {
for (const propertyValue of Object.values(node)) {
Expand Down Expand Up @@ -113,9 +106,7 @@ export const updateValueAtKeyPathInSemanticGraph = (
operation,
),
updatedNode =>
(isUnelaborated(node)
? makeUnelaboratedObjectNode
: makeObjectNode)({
(isExpression(node) ? makeObjectNode : makeObjectNode)({
...node,
[firstKey]: updatedNode,
}),
Expand Down Expand Up @@ -193,6 +184,4 @@ export const isSemanticGraph = (
const syntaxTreeToSemanticGraph = (
syntaxTree: Atom | Molecule,
): ObjectNode | Atom =>
typeof syntaxTree === 'string'
? syntaxTree
: makeUnelaboratedObjectNode(syntaxTree)
typeof syntaxTree === 'string' ? syntaxTree : makeObjectNode(syntaxTree)