Skip to content

Commit

Permalink
Codegen: closure fix; method references
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Mar 7, 2024
1 parent a98d6fb commit d52f958
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/ast/operand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LexerToken } from '../lexer/lexer'
import { ParseNode, ParseTree, filterNonAstNodes } from '../parser'
import { nameLikeTokens } from '../parser/fns'
import { InstanceRelation } from '../scope/trait'
import { VirtualIdentifierMatch } from '../scope/vid'
import { Typed } from '../semantic'
import { Expr, buildExpr } from './expr'
import { AstNode, Param, buildParam } from './index'
Expand Down Expand Up @@ -217,6 +218,7 @@ export const buildBoolLiteral = (node: ParseNode): BoolLiteral => {
export interface Identifier extends AstNode<'identifier'>, Partial<Typed> {
names: Name[]
typeArgs: Type[]
ref?: VirtualIdentifierMatch
}

export const buildIdentifier = (node: ParseNode): Identifier => {
Expand Down
15 changes: 13 additions & 2 deletions src/codegen/js/expr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export const emitOperand = (operand: Operand, module: Module, ctx: Context): Emi
return emitMatchExpr(operand, module, ctx, resultVar)
case 'closure-expr': {
const params = operand.params.map(p => emitParam(p, module, ctx)).join(', ')
const block = emitBlock(operand.block, module, ctx)
const block = emitBlock(operand.block, module, ctx, true)
return { emit: jsVariable(resultVar, `function(${params}) ${block}`), resultVar }
}
case 'operand-expr':
Expand Down Expand Up @@ -194,8 +194,19 @@ export const emitOperand = (operand: Operand, module: Module, ctx: Context): Emi
case 'float-literal':
case 'bool-literal':
return emitLiteral(operand, module, ctx, resultVar)
case 'identifier':
case 'identifier': {
if (operand.ref?.def.kind === 'method-def') {
const arg = nextVariable(ctx)
const args = nextVariable(ctx)
const relName = relTypeName(operand.ref.def.rel)
const fnName = operand.ref.def.fn.name.value
return {
emit: '',
resultVar: `function(${arg}, ...${args}) { ${arg}.${relName}.${fnName}(${arg}, ${args}); }`
}
}
return { emit: '', resultVar: operand.names.at(-1)!.value }
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/codegen/js/statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export const emitBlockStatements = (
statements.push(`return ${last.resultVar};`)
}
}
return statements.map(emitExprToString)
return statements.map(emitExprToString).filter(s => s.length > 0)
}

export const emitBlock = (block: Block, module: Module, ctx: Context, resultVar?: boolean | string): string => {
Expand Down
1 change: 1 addition & 0 deletions src/semantic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ export const checkIdentifier = (identifier: Identifier, ctx: Context): void => {
// TODO: if absolute import, check that package is explicitly imported
const ref = resolveVid(vid, ctx)
if (ref) {
identifier.ref = ref
switch (ref.def.kind) {
case 'self':
identifier.type = instanceScope(ctx)!.selfType
Expand Down

0 comments on commit d52f958

Please sign in to comment.