Skip to content

Commit

Permalink
Codegen: upcast fn include generic fields
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Mar 23, 2024
1 parent 50b3d7f commit 4e5fdec
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/codegen/js/statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Context } from '../../scope'
import { trace } from '../../scope/std'
import { typeDefToVirtualType } from '../../scope/trait'
import { vidEq, vidToString } from '../../scope/util'
import { virtualTypeToString } from '../../typecheck'
import { EmitExpr, emitExpr, emitParam, emitPattern } from './expr'
import { emitTraceImpl } from './native'
import { EmitNode, emitIntersperse, emitToken, emitTree, jsVariable } from './node'
Expand Down Expand Up @@ -159,5 +160,12 @@ export const emitVariant = (v: Variant, typeDef: TypeDef, module: Module, ctx: C
export const emitUpcastFn = (v: Variant, typeDef: TypeDef, module: Module, ctx: Context): EmitNode => {
const params = ['value', 'Self', ...typeDef.generics.map(g => g.name.value)]
const selfG = 'for(const [trait,impl] of Self){value[trait]=impl;}'
return emitTree([emitToken(`function(${params.join(',')}) {`), emitToken(selfG), emitToken('}')])
const gs = typeDef.generics.flatMap(g => {
const fields = v.fieldDefs.filter(f => virtualTypeToString(f.type!) === g.name.value).map(f => f.name.value)
if (fields.length === 0) return []
return [
`for(const [trait,impl] of ${g.name.value}){${fields.map(f => `value.value.${f}[trait]=impl;`).join('')}}`
]
})
return emitToken(`function(${params.join(',')}) {${selfG}${gs.join('')}}`)
}

0 comments on commit 4e5fdec

Please sign in to comment.