( func: NodePath<t.Function>, env: Environment, // Bindings captured from the outer function, in case lower() is called recursively (for lambdas) bindings: Bindings | null = null, capturedRefs: Map<t.Identifier, SourceLocation> = new Map(), )
| 70 | * the runtime, ie by invalidating memoization. |
| 71 | */ |
| 72 | export function lower( |
| 73 | func: NodePath<t.Function>, |
| 74 | env: Environment, |
| 75 | // Bindings captured from the outer function, in case lower() is called recursively (for lambdas) |
| 76 | bindings: Bindings | null = null, |
| 77 | capturedRefs: Map<t.Identifier, SourceLocation> = new Map(), |
| 78 | ): Result<HIRFunction, CompilerError> { |
| 79 | const builder = new HIRBuilder(env, { |
| 80 | bindings, |
| 81 | context: capturedRefs, |
| 82 | }); |
| 83 | const context: HIRFunction['context'] = []; |
| 84 | |
| 85 | for (const [ref, loc] of capturedRefs ?? []) { |
| 86 | context.push({ |
| 87 | kind: 'Identifier', |
| 88 | identifier: builder.resolveBinding(ref), |
| 89 | effect: Effect.Unknown, |
| 90 | reactive: false, |
| 91 | loc, |
| 92 | }); |
| 93 | } |
| 94 | |
| 95 | let id: string | null = null; |
| 96 | if (func.isFunctionDeclaration() || func.isFunctionExpression()) { |
| 97 | const idNode = ( |
| 98 | func as NodePath<t.FunctionDeclaration | t.FunctionExpression> |
| 99 | ).get('id'); |
| 100 | if (hasNode(idNode)) { |
| 101 | id = idNode.node.name; |
| 102 | } |
| 103 | } |
| 104 | const params: Array<Place | SpreadPattern> = []; |
| 105 | func.get('params').forEach(param => { |
| 106 | if (param.isIdentifier()) { |
| 107 | const binding = builder.resolveIdentifier(param); |
| 108 | if (binding.kind !== 'Identifier') { |
| 109 | builder.errors.pushDiagnostic( |
| 110 | CompilerDiagnostic.create({ |
| 111 | category: ErrorCategory.Invariant, |
| 112 | reason: 'Could not find binding', |
| 113 | description: `[BuildHIR] Could not find binding for param \`${param.node.name}\``, |
| 114 | }).withDetails({ |
| 115 | kind: 'error', |
| 116 | loc: param.node.loc ?? null, |
| 117 | message: 'Could not find binding', |
| 118 | }), |
| 119 | ); |
| 120 | return; |
| 121 | } |
| 122 | const place: Place = { |
| 123 | kind: 'Identifier', |
| 124 | identifier: binding.identifier, |
| 125 | effect: Effect.Unknown, |
| 126 | reactive: false, |
| 127 | loc: param.node.loc ?? GeneratedSource, |
| 128 | }; |
| 129 | params.push(place); |
no test coverage detected