@@ -15,10 +15,13 @@ import {
1515 type KeyPath ,
1616 type KeywordElaborationResult ,
1717 type KeywordModule ,
18- type ObjectNode ,
1918 type SemanticGraph ,
2019} from '../../semantics.js'
21- import { elaborateWithContext } from '../../semantics/expression-elaboration.js'
20+ import {
21+ elaborateWithContext ,
22+ isExpression ,
23+ type Expression ,
24+ } from '../../semantics/expression-elaboration.js'
2225import { stringifyKeyPathForEndUser } from '../../semantics/key-path.js'
2326import {
2427 lookupPropertyOfObjectNode ,
@@ -237,8 +240,11 @@ export const handlers = {
237240 * Calls the given `FunctionNode` with a given argument.
238241 */
239242 '@apply' : ( expression , _context ) : KeywordElaborationResult => {
240- const functionToApply = lookupWithinArgument ( [ 'function' , '1' ] , expression )
241- const argument = lookupWithinArgument ( [ 'argument' , '2' ] , expression )
243+ const functionToApply = lookupWithinExpression (
244+ [ 'function' , '1' ] ,
245+ expression ,
246+ )
247+ const argument = lookupWithinExpression ( [ 'argument' , '2' ] , expression )
242248
243249 if ( option . isNone ( functionToApply ) ) {
244250 return either . makeLeft ( {
@@ -300,8 +306,8 @@ export const handlers = {
300306 * Checks whether a given value is assignable to a given type.
301307 */
302308 '@check' : ( expression , context ) : KeywordElaborationResult => {
303- const value = lookupWithinArgument ( [ 'value' , '1' ] , expression )
304- const type = lookupWithinArgument ( [ 'type' , '2' ] , expression )
309+ const value = lookupWithinExpression ( [ 'value' , '1' ] , expression )
310+ const type = lookupWithinExpression ( [ 'type' , '2' ] , expression )
305311 if ( option . isNone ( value ) ) {
306312 return either . makeLeft ( {
307313 kind : 'invalidExpression' ,
@@ -331,7 +337,7 @@ export const handlers = {
331337 * Given a query, resolves the value of a property within the program.
332338 */
333339 '@lookup' : ( expression , context ) : KeywordElaborationResult => {
334- const query = lookupWithinArgument ( [ 'query' , '1' ] , expression )
340+ const query = lookupWithinExpression ( [ 'query' , '1' ] , expression )
335341 if ( option . isNone ( query ) ) {
336342 return either . makeLeft ( {
337343 kind : 'invalidExpression' ,
@@ -405,7 +411,10 @@ export const handlers = {
405411 * Preserves a raw function node for emission into the runtime code.
406412 */
407413 '@runtime' : ( expression , context ) : KeywordElaborationResult => {
408- const runtimeFunction = lookupWithinArgument ( [ 'function' , '1' ] , expression )
414+ const runtimeFunction = lookupWithinExpression (
415+ [ 'function' , '1' ] ,
416+ expression ,
417+ )
409418 if (
410419 option . isNone ( runtimeFunction ) ||
411420 ! (
@@ -498,7 +507,7 @@ export const applyLambda = (
498507 }
499508}
500509
501- type Lambda = ObjectNode & {
510+ type Lambda = Expression & {
502511 readonly 0 : '@function'
503512 readonly parameter : Atom
504513 readonly body : SemanticGraph | Molecule
@@ -507,14 +516,14 @@ type Lambda = ObjectNode & {
507516const validateLambda = (
508517 possibleLambda : SemanticGraph ,
509518) : Either < ElaborationError , Lambda > => {
510- if ( typeof possibleLambda !== 'object' ) {
519+ if ( ! isExpression ( possibleLambda ) ) {
511520 return either . makeLeft ( {
512521 kind : 'invalidExpression' ,
513- message : 'functions must be encoded as objects ' ,
522+ message : 'functions must be expressions ' ,
514523 } )
515524 } else {
516- const parameter = lookupWithinArgument ( [ 'parameter' , '1' ] , possibleLambda )
517- const body = lookupWithinArgument ( [ 'body' , '2' ] , possibleLambda )
525+ const parameter = lookupWithinExpression ( [ 'parameter' , '1' ] , possibleLambda )
526+ const body = lookupWithinExpression ( [ 'body' , '2' ] , possibleLambda )
518527
519528 if ( option . isNone ( parameter ) ) {
520529 return either . makeLeft ( {
@@ -546,7 +555,7 @@ const validateLambda = (
546555}
547556
548557const compileLambda = (
549- possibleLambda : SemanticGraph ,
558+ possibleLambda : Expression ,
550559 context : ExpressionContext ,
551560) : Either < ElaborationError , FunctionNode > => {
552561 if ( typeof possibleLambda !== 'object' ) {
@@ -555,8 +564,8 @@ const compileLambda = (
555564 message : 'functions must be encoded as objects' ,
556565 } )
557566 } else {
558- const parameter = lookupWithinArgument ( [ 'parameter' , '1' ] , possibleLambda )
559- const body = lookupWithinArgument ( [ 'body' , '2' ] , possibleLambda )
567+ const parameter = lookupWithinExpression ( [ 'parameter' , '1' ] , possibleLambda )
568+ const body = lookupWithinExpression ( [ 'body' , '2' ] , possibleLambda )
560569
561570 if ( option . isNone ( parameter ) ) {
562571 return either . makeLeft ( {
@@ -617,12 +626,12 @@ const locateSelf = (context: ExpressionContext) =>
617626 some : either . makeRight ,
618627 } )
619628
620- const lookupWithinArgument = (
629+ export const lookupWithinExpression = (
621630 keyAliases : [ Atom , ...( readonly Atom [ ] ) ] ,
622- argument : ObjectNode ,
631+ expression : Expression ,
623632) : Option < SemanticGraph > => {
624633 for ( const key of keyAliases ) {
625- const result = lookupPropertyOfObjectNode ( key , argument )
634+ const result = lookupPropertyOfObjectNode ( key , expression )
626635 if ( ! option . isNone ( result ) ) {
627636 return result
628637 }
0 commit comments