Skip to content

Commit 95665f8

Browse files
authored
Merge pull request #35 from mkantor/runtime-indexing
Allow `@index` operations to be deferred until runtime
2 parents 912f9f4 + 5c633de commit 95665f8

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

src/end-to-end.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,17 @@ testCases(endToEnd, code => code)('end-to-end tests', [
234234
assert.deepEqual(typeof output.value['value'], 'string')
235235
},
236236
],
237+
[
238+
`{@runtime context =>
239+
:identity(:context).program.start_time
240+
}`,
241+
output => {
242+
if (either.isLeft(output)) {
243+
assert.fail(output.value.message)
244+
}
245+
assert(typeof output.value === 'string')
246+
},
247+
],
237248
[
238249
`{@runtime context =>
239250
:context.environment.lookup(PATH)

src/language/compiling/semantics/keyword-handlers/index-handler.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ElaborationError } from '../../../errors.js'
44
import {
55
applyKeyPathToSemanticGraph,
66
asSemanticGraph,
7+
containsAnyUnelaboratedNodes,
78
keyPathFromObjectNodeOrMolecule,
89
readIndexExpression,
910
stringifyKeyPathForEndUser,
@@ -17,20 +18,31 @@ export const indexKeywordHandler: KeywordHandler = (
1718
expression: Expression,
1819
_context: ExpressionContext,
1920
): Either<ElaborationError, SemanticGraph> =>
20-
either.flatMap(readIndexExpression(expression), ({ object, query }) =>
21-
either.flatMap(keyPathFromObjectNodeOrMolecule(query), keyPath =>
22-
option.match(
23-
applyKeyPathToSemanticGraph(asSemanticGraph(object), keyPath),
24-
{
25-
none: () =>
26-
either.makeLeft({
27-
kind: 'invalidExpression',
28-
message: `property \`${stringifyKeyPathForEndUser(
29-
keyPath,
30-
)}\` not found`,
31-
}),
32-
some: either.makeRight,
33-
},
34-
),
21+
either.flatMap(readIndexExpression(expression), indexExpression =>
22+
either.flatMap(
23+
keyPathFromObjectNodeOrMolecule(indexExpression.query),
24+
keyPath => {
25+
if (containsAnyUnelaboratedNodes(indexExpression.object)) {
26+
// The object isn't ready, so keep the @index unelaborated.
27+
return either.makeRight(indexExpression)
28+
} else {
29+
return option.match(
30+
applyKeyPathToSemanticGraph(
31+
asSemanticGraph(indexExpression.object),
32+
keyPath,
33+
),
34+
{
35+
none: () =>
36+
either.makeLeft({
37+
kind: 'invalidExpression',
38+
message: `property \`${stringifyKeyPathForEndUser(
39+
keyPath,
40+
)}\` not found`,
41+
}),
42+
some: either.makeRight,
43+
},
44+
)
45+
}
46+
},
3547
),
3648
)

0 commit comments

Comments
 (0)