Skip to content

Commit

Permalink
Merge pull request #44 from frwang96/feature/is-expression
Browse files Browse the repository at this point in the history
Is expression
  • Loading branch information
frwang96 authored Nov 4, 2021
2 parents 947feae + 9066b85 commit c591e3b
Show file tree
Hide file tree
Showing 30 changed files with 434 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ abstract class EDeclaration : ETypedElement(), Declaration {
fun isSpecializable(): Boolean {
return when (val parent = this.parent) {
is EFile -> true
is EKtBasicClass -> this in parent.declarations
is EKtBasicClass -> this in parent.declarations || this == parent.primaryConstructor
else -> false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class EPropertyStatement(

override fun replaceChild(oldDeclaration: EDeclaration, newDeclaration: EDeclaration): Boolean {
newDeclaration.parent = this
return if (property == oldDeclaration && newDeclaration is EAbstractInitializedProperty) {
property = newDeclaration
return if (property == oldDeclaration) {
newDeclaration.cast<EAbstractInitializedProperty>()?.let { property = it }
true
} else false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@
package io.verik.compiler.ast.element.common

import io.verik.compiler.ast.property.Type
import io.verik.compiler.common.NullDeclaration
import io.verik.compiler.common.Visitor
import io.verik.compiler.message.SourceLocation

class ETemporaryProperty(
override val location: SourceLocation,
override var type: Type,
override var initializer: EExpression?
override val location: SourceLocation
) : EAbstractInitializedProperty() {

override var name = "<tmp>"
override var type: Type = NullDeclaration.toType()
override var initializer: EExpression? = null

init {
fun init(type: Type, initializer: EExpression?) {
initializer?.parent = this
this.type = type
this.initializer = initializer
}

override fun accept(visitor: Visitor) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2021 Francis Wang
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.verik.compiler.ast.element.kt

import io.verik.compiler.ast.element.common.EAbstractContainerExpression
import io.verik.compiler.ast.element.common.EAbstractInitializedProperty
import io.verik.compiler.ast.element.common.EDeclaration
import io.verik.compiler.ast.element.common.EExpression
import io.verik.compiler.ast.interfaces.DeclarationContainer
import io.verik.compiler.ast.property.SerializationType
import io.verik.compiler.ast.property.Type
import io.verik.compiler.common.TreeVisitor
import io.verik.compiler.common.Visitor
import io.verik.compiler.core.common.Core
import io.verik.compiler.message.SourceLocation

class EIsExpression(
override val location: SourceLocation,
override var expression: EExpression,
var property: EAbstractInitializedProperty,
val isNegated: Boolean,
var castType: Type
) : EAbstractContainerExpression(), DeclarationContainer {

override var type = Core.Kt.C_Boolean.toType()

override val serializationType = SerializationType.INTERNAL

init {
expression.parent = this
property.parent = this
}

override fun accept(visitor: Visitor) {
visitor.visitIsExpression(this)
}

override fun acceptChildren(visitor: TreeVisitor) {
super.acceptChildren(visitor)
property.accept(visitor)
}

override fun replaceChild(oldDeclaration: EDeclaration, newDeclaration: EDeclaration): Boolean {
newDeclaration.parent = this
return if (property == oldDeclaration) {
newDeclaration.cast<EAbstractInitializedProperty>()?.let { property = it }
true
} else false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtIsExpression
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameter
Expand Down Expand Up @@ -236,6 +237,10 @@ class CasterVisitor(private val castContext: CastContext) : KtVisitor<EElement,
return ExpressionCaster.castKtArrayAccessExpression(expression, castContext)
}

override fun visitIsExpression(expression: KtIsExpression, data: Unit?): EElement {
return ExpressionCaster.castIsExpression(expression, castContext)
}

override fun visitIfExpression(expression: KtIfExpression, data: Unit?): EIfExpression {
return ExpressionCaster.castIfExpression(expression, castContext)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import io.verik.compiler.ast.element.common.EIfExpression
import io.verik.compiler.ast.element.common.EReferenceExpression
import io.verik.compiler.ast.element.common.EReturnStatement
import io.verik.compiler.ast.element.common.ESuperExpression
import io.verik.compiler.ast.element.common.ETemporaryProperty
import io.verik.compiler.ast.element.common.EThisExpression
import io.verik.compiler.ast.element.common.EWhileExpression
import io.verik.compiler.ast.element.kt.EForExpression
import io.verik.compiler.ast.element.kt.EFunctionLiteralExpression
import io.verik.compiler.ast.element.kt.EIsExpression
import io.verik.compiler.ast.element.kt.EKtArrayAccessExpression
import io.verik.compiler.ast.element.kt.EKtBinaryExpression
import io.verik.compiler.ast.element.kt.EKtBlockExpression
Expand All @@ -49,6 +51,7 @@ import org.jetbrains.kotlin.psi.KtDoWhileExpression
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtIsExpression
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtPostfixExpression
import org.jetbrains.kotlin.psi.KtPrefixExpression
Expand Down Expand Up @@ -255,6 +258,21 @@ object ExpressionCaster {
return EKtArrayAccessExpression(location, type, array, ArrayList(indices))
}

fun castIsExpression(expression: KtIsExpression, castContext: CastContext): EIsExpression {
val location = expression.location()
val childExpression = castContext.casterVisitor.getExpression(expression.leftHandSide)
val castType = castContext.castType(expression.typeReference!!)
val temporaryProperty = ETemporaryProperty(location)
temporaryProperty.init(castType, null)
return EIsExpression(
location,
childExpression,
temporaryProperty,
expression.isNegated,
castType
)
}

fun castIfExpression(expression: KtIfExpression, castContext: CastContext): EIfExpression {
val location = expression.location()
val type = castContext.castType(expression)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.verik.compiler.check.post

import io.verik.compiler.ast.element.common.EAbstractContainerClass
import io.verik.compiler.ast.element.common.EAbstractPackage
import io.verik.compiler.ast.element.common.EDeclaration
import io.verik.compiler.common.ProjectStage
Expand Down Expand Up @@ -64,5 +65,12 @@ object NameRedeclarationCheckerStage : ProjectStage() {
}
declarationSet.checkDuplicates()
}

override fun visitAbstractContainerClass(abstractContainerClass: EAbstractContainerClass) {
super.visitAbstractContainerClass(abstractContainerClass)
val declarationSet = DeclarationSet()
abstractContainerClass.declarations.forEach { declarationSet.add(it) }
declarationSet.checkDuplicates()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.verik.compiler.ast.element.common.ENullElement
import io.verik.compiler.ast.element.common.ETemporaryProperty
import io.verik.compiler.ast.element.common.ETemporaryValueParameter
import io.verik.compiler.ast.element.kt.EForExpression
import io.verik.compiler.ast.element.kt.EIsExpression
import io.verik.compiler.ast.element.kt.EKtArrayAccessExpression
import io.verik.compiler.ast.element.kt.EKtBasicClass
import io.verik.compiler.ast.element.kt.EKtBinaryExpression
Expand Down Expand Up @@ -122,6 +123,11 @@ object UntransformedElementCheckerStage : ProjectStage() {
Messages.INTERNAL_ERROR.on(arrayAccessExpression, "Array access expression $message")
}

override fun visitIsExpression(isExpression: EIsExpression) {
super.visitIsExpression(isExpression)
Messages.INTERNAL_ERROR.on(isExpression, "Is expression $message")
}

override fun visitWhenExpression(whenExpression: EWhenExpression) {
super.visitWhenExpression(whenExpression)
Messages.INTERNAL_ERROR.on(whenExpression, "When expression $message")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import io.verik.compiler.ast.element.common.EWhileExpression
import io.verik.compiler.ast.element.kt.EAnnotation
import io.verik.compiler.ast.element.kt.EForExpression
import io.verik.compiler.ast.element.kt.EFunctionLiteralExpression
import io.verik.compiler.ast.element.kt.EIsExpression
import io.verik.compiler.ast.element.kt.EKtArrayAccessExpression
import io.verik.compiler.ast.element.kt.EKtBasicClass
import io.verik.compiler.ast.element.kt.EKtBinaryExpression
Expand Down Expand Up @@ -616,6 +617,16 @@ class ElementPrinter : Visitor() {
}
}

override fun visitIsExpression(isExpression: EIsExpression) {
build("IsExpression") {
build(isExpression.type.toString())
build(isExpression.expression)
build(isExpression.property)
build(isExpression.isNegated)
build(isExpression.castType.toString())
}
}

override fun visitWidthCastExpression(widthCastExpression: EWidthCastExpression) {
build("WidthCastExpression") {
build(widthCastExpression.type.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import io.verik.compiler.ast.element.common.EWhileExpression
import io.verik.compiler.ast.element.kt.EAnnotation
import io.verik.compiler.ast.element.kt.EForExpression
import io.verik.compiler.ast.element.kt.EFunctionLiteralExpression
import io.verik.compiler.ast.element.kt.EIsExpression
import io.verik.compiler.ast.element.kt.EKtAbstractFunction
import io.verik.compiler.ast.element.kt.EKtArrayAccessExpression
import io.verik.compiler.ast.element.kt.EKtBasicClass
Expand Down Expand Up @@ -489,6 +490,10 @@ abstract class Visitor {
visitAbstractContainerExpression(streamingExpression)
}

open fun visitIsExpression(isExpression: EIsExpression) {
visitAbstractContainerExpression(isExpression)
}

open fun visitWidthCastExpression(widthCastExpression: EWidthCastExpression) {
visitAbstractContainerExpression(widthCastExpression)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ object Core {
val F_time = CoreVk.F_time
val F_finish = CoreVk.F_finish
val F_fatal = CoreVk.F_fatal
val F_fatal_String = CoreVk.F_fatal_String
val F_error_String = CoreVk.F_error_String
val F_sv_String = CoreVk.F_sv_String

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,23 @@ object CoreVk : CoreScope(CorePackage.VK) {

val F_fatal = BasicCoreFunctionDeclaration(parent, "fatal", "fun fatal()", Target.F_fatal)

val F_fatal_String = object : TransformableCoreFunctionDeclaration(parent, "fatal", "fun fatal(String)") {

override fun transform(callExpression: EKtCallExpression): EExpression {
return EKtCallExpression(
callExpression.location,
callExpression.type,
Target.F_fatal,
null,
arrayListOf(
EConstantExpression(callExpression.location, Core.Kt.C_Int.toType(), "1"),
callExpression.valueArguments[0]
),
ArrayList()
)
}
}

val F_error_String = BasicCoreFunctionDeclaration(parent, "error", "fun error(String)", Target.F_error)

val F_sv_String = BasicCoreFunctionDeclaration(parent, "sv", "fun sv(String)", null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ object BasicClassInterpreterStage : ProjectStage() {
): ESvFunction? {
if (basicClass.isAbstract)
return null
val temporaryProperty = ETemporaryProperty(
constructor.location,
val temporaryProperty = ETemporaryProperty(constructor.location)
temporaryProperty.init(
constructor.type.copy(),
ESvCallExpression(
constructor.location,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import io.verik.compiler.serialize.target.TargetSerializerStage
import io.verik.compiler.specialize.DeclarationSpecializerStage
import io.verik.compiler.transform.mid.AssignmentTransformerStage
import io.verik.compiler.transform.mid.CaseStatementTransformerStage
import io.verik.compiler.transform.mid.CastTransformerStage
import io.verik.compiler.transform.mid.ConstantExpressionEvaluatorStage
import io.verik.compiler.transform.mid.EnumNameTransformerStage
import io.verik.compiler.transform.mid.ForStatementTransformerStage
Expand Down Expand Up @@ -138,6 +139,7 @@ object StageSequencer {
stageSequence.add(EnumNameTransformerStage)
stageSequence.add(InjectedExpressionReducerStage)
stageSequence.add(StringTemplateExpressionReducerStage)
stageSequence.add(CastTransformerStage)
stageSequence.add(UninitializedPropertyTransformerStage)
stageSequence.add(ForStatementTransformerStage)
stageSequence.add(FunctionTransformerStage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ object Messages {
)

val NO_TOP_DECLARATIONS = MessageTemplate0(
Severity.ERROR,
Severity.WARNING,
"No top level declarations found"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.verik.compiler.ast.element.common.EDeclaration
import io.verik.compiler.ast.element.common.EElement
import io.verik.compiler.ast.element.common.EReceiverExpression
import io.verik.compiler.ast.element.common.EReferenceExpression
import io.verik.compiler.ast.element.common.ETemporaryProperty
import io.verik.compiler.ast.element.common.ETypedElement
import io.verik.compiler.ast.element.kt.EKtAbstractFunction
import io.verik.compiler.ast.element.kt.EKtBasicClass
Expand Down Expand Up @@ -161,6 +162,12 @@ class DeclarationSpecializeIndexerVisitor(
specializerContext[property] = specializedProperty
}

override fun visitTemporaryProperty(temporaryProperty: ETemporaryProperty) {
super.visitTemporaryProperty(temporaryProperty)
val specializedTemporaryProperty = ETemporaryProperty(temporaryProperty.location)
specializerContext[temporaryProperty] = specializedTemporaryProperty
}

override fun visitKtEnumEntry(enumEntry: EKtEnumEntry) {
super.visitKtEnumEntry(enumEntry)
val specializedEnumEntry = EKtEnumEntry(enumEntry.location, enumEntry.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.verik.compiler.specialize

import io.verik.compiler.ast.element.common.EDeclaration
import io.verik.compiler.ast.element.common.ETemporaryProperty
import io.verik.compiler.ast.element.kt.EKtBasicClass
import io.verik.compiler.ast.element.kt.EKtEnumEntry
import io.verik.compiler.ast.element.kt.EKtFunction
Expand All @@ -37,6 +38,7 @@ object DeclarationSpecializer {
is EKtFunction -> specializeKtFunction(declaration, specializerContext)
is EPrimaryConstructor -> specializePrimaryConstructor(declaration, specializerContext)
is EKtProperty -> specializeKtProperty(declaration, specializerContext)
is ETemporaryProperty -> specializeTemporaryProperty(declaration, specializerContext)
is EKtEnumEntry -> specializeKtEnumEntry(declaration, specializerContext)
is EKtValueParameter -> specializeKtValueParameter(declaration, specializerContext)
else -> {
Expand Down Expand Up @@ -144,6 +146,21 @@ object DeclarationSpecializer {
return specializedProperty
}

private fun specializeTemporaryProperty(
temporaryProperty: ETemporaryProperty,
specializerContext: SpecializerContext
): ETemporaryProperty {
val specializedTemporaryProperty = specializerContext[temporaryProperty, temporaryProperty]
.cast<ETemporaryProperty>(temporaryProperty)
?: return temporaryProperty

val type = specializerContext.specializeType(temporaryProperty)
val initializer = temporaryProperty.initializer?.let { specializerContext.specialize(it) }

specializedTemporaryProperty.init(type, initializer)
return specializedTemporaryProperty
}

private fun specializeKtEnumEntry(enumEntry: EKtEnumEntry, specializerContext: SpecializerContext): EKtEnumEntry {
val specializedEnumEntry = specializerContext[enumEntry, enumEntry]
.cast<EKtEnumEntry>(enumEntry)
Expand Down
Loading

0 comments on commit c591e3b

Please sign in to comment.