All Downloads are FREE. Search and download functionalities are using the official Maven repository.

samlang.parser.ModuleBuilder.kt Maven / Gradle / Ivy

There is a newer version: 0.0.7
Show newest version
package samlang.parser

import samlang.ast.raw.RawExpr
import samlang.ast.raw.RawModule
import samlang.ast.raw.RawTypeExpr
import samlang.parser.Position.Companion.position
import samlang.parser.Position.Companion.positionWithName
import samlang.parser.generated.PLBaseVisitor
import samlang.parser.generated.PLParser.*

internal object ModuleBuilder : PLBaseVisitor() {

    private val TypeParametersDeclarationContext.typeParameters: List
        get() = UpperId().map { it.symbol.positionWithName }

    private object ModuleNameBuilder : PLBaseVisitor() {

        override fun visitClassHeader(ctx: ClassHeaderContext): Position.WithName =
            ctx.UpperId().symbol.positionWithName

        override fun visitUtilHeader(ctx: UtilHeaderContext): Position.WithName =
            ctx.UpperId().symbol.positionWithName

    }

    private object ModuleTypeDefBuilder : PLBaseVisitor() {

        override fun visitClassHeader(ctx: ClassHeaderContext): RawModule.RawTypeDef {
            val rawTypeParams: TypeParametersDeclarationContext? = ctx.typeParametersDeclaration()
            val rawTypeDeclaration = ctx.typeDeclaration()
            val typeParams = rawTypeParams?.typeParameters
            val position = rawTypeParams?.position?.union(rawTypeDeclaration.position) ?: rawTypeDeclaration.position
            return rawTypeDeclaration.accept(TypeDefBuilder(position, typeParams))
        }

        override fun visitUtilHeader(ctx: UtilHeaderContext): RawModule.RawTypeDef? = null

        private class TypeDefBuilder(
            private val position: Position,
            private val typeParams: List?
        ) : PLBaseVisitor() {

            override fun visitObjType(ctx: ObjTypeContext): RawModule.RawTypeDef =
                RawModule.RawTypeDef.ObjectType(
                    position = position,
                    typeParams = typeParams,
                    mappings = ctx.objectTypeFieldDeclaration().map { c ->
                        val (pos, name) = c.LowerId().symbol.positionWithName
                        val t = c.typeAnnotation().typeExpr().accept(TypeExprBuilder)
                        name to (pos to t)
                    }
                )

            override fun visitVariantType(ctx: VariantTypeContext): RawModule.RawTypeDef =
                RawModule.RawTypeDef.VariantType(
                    position = position,
                    typeParams = typeParams,
                    mappings = ctx.variantTypeConstructorDeclaration().map { c ->
                        val (pos, name) = c.UpperId().symbol.positionWithName
                        val t = c.typeExpr().accept(TypeExprBuilder)
                        name to (pos to t)
                    }
                )

        }

    }

    private fun buildModuleMemberDefinition(ctx: ModuleMemberDefinitionContext): RawModule.RawMemberDefinition {
        val annotatedVars = ctx.annotatedVariable().map { annotatedVar ->
            val varName = annotatedVar.LowerId().symbol.positionWithName
            val typeAnnotation = annotatedVar.typeAnnotation().typeExpr().accept(TypeExprBuilder)
            varName to typeAnnotation
        }
        val firstArgPos = annotatedVars.firstOrNull()?.first?.position
        return RawModule.RawMemberDefinition(
            position = ctx.position,
            isPublic = ctx.PUBLIC() != null,
            isMethod = ctx.METHOD() != null,
            typeParameters = ctx.typeParametersDeclaration()?.typeParameters,
            name = ctx.LowerId().symbol.positionWithName,
            typeAnnotation = RawTypeExpr.FunctionType(
                position = Position(
                    lineStart = firstArgPos?.lineStart ?: ctx.typeExpr().start.line,
                    lineEnd = ctx.typeExpr().stop.line,
                    colStart = firstArgPos?.colStart ?: ctx.typeExpr().start.startIndex,
                    colEnd = ctx.typeExpr().stop.stopIndex
                ),
                argumentTypes = annotatedVars.map { it.second },
                returnType = ctx.typeExpr().accept(TypeExprBuilder)
            ),
            value = RawExpr.Lambda(
                position = Position(
                    lineStart = firstArgPos?.lineStart ?: ctx.expression().start.line,
                    lineEnd = ctx.expression().stop.line,
                    colStart = firstArgPos?.colStart ?: ctx.expression().start.startIndex,
                    colEnd = ctx.expression().stop.stopIndex
                ),
                arguments = annotatedVars,
                body = ctx.expression().accept(ExprBuilder)
            )
        )
    }

    override fun visitModule(ctx: ModuleContext): RawModule = RawModule(
        position = ctx.position,
        name = ctx.moduleHeaderDeclaration().accept(ModuleNameBuilder),
        typeDef = ctx.moduleHeaderDeclaration().accept(ModuleTypeDefBuilder),
        members = ctx.moduleMemberDefinition().map { buildModuleMemberDefinition(ctx = it) }
    )

}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy