Skip to content

Commit

Permalink
Added support for big ints and big decimals in pattern matching
Browse files Browse the repository at this point in the history
  • Loading branch information
stackoverflow committed Jun 18, 2022
1 parent 12e4ac1 commit 7b1340f
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 5 deletions.
3 changes: 2 additions & 1 deletion releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

## Features

- Added new syntax for literal big ints and big decimals: `100000N`, `100000.30M`
- Added new syntax for literal big ints and big decimals: `100000N`, `100000.30M`
- Added support for big ints and big decimals in pattern matching

# 0.2.0

Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/novah/ast/Desugar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ class Desugar(private val smod: SModule, private val typeChecker: Typechecker) {
is SLiteralPattern.Int64Literal -> LiteralPattern.Int64Literal(e.desugar(locals) as Expr.Int64)
is SLiteralPattern.Float32Literal -> LiteralPattern.Float32Literal(e.desugar(locals) as Expr.Float32)
is SLiteralPattern.Float64Literal -> LiteralPattern.Float64Literal(e.desugar(locals) as Expr.Float64)
is SLiteralPattern.BigintLiteral -> LiteralPattern.BigintLiteral(e.desugar(locals) as Expr.Bigint)
is SLiteralPattern.BigdecPattern -> LiteralPattern.BigdecLiteral(e.desugar(locals) as Expr.Bigdec)
}

private fun SLetDef.DefBind.desugar(locals: List<String>, tvars: Map<String, Type>): LetDef {
Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/novah/ast/canonical/CanonicalAST.kt
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ sealed class LiteralPattern(open val e: Expr) {
data class Int64Literal(override val e: Expr.Int64) : LiteralPattern(e)
data class Float32Literal(override val e: Expr.Float32) : LiteralPattern(e)
data class Float64Literal(override val e: Expr.Float64) : LiteralPattern(e)
data class BigintLiteral(override val e: Expr.Bigint) : LiteralPattern(e)
data class BigdecLiteral(override val e: Expr.Bigdec) : LiteralPattern(e)
}

fun Pattern.show(): String = when (this) {
Expand All @@ -285,6 +287,8 @@ fun LiteralPattern.show(): String = when (this) {
is LiteralPattern.Int64Literal -> e.v.toString()
is LiteralPattern.Float32Literal -> e.v.toString()
is LiteralPattern.Float64Literal -> e.v.toString()
is LiteralPattern.BigintLiteral -> e.v.toString()
is LiteralPattern.BigdecLiteral -> e.v.toString()
}

data class Metadata(val data: Expr.RecordExtend) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/novah/ast/source/SourceAST.kt
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ sealed class LiteralPattern {
data class Int64Literal(val e: Expr.Int64) : LiteralPattern()
data class Float32Literal(val e: Expr.Float32) : LiteralPattern()
data class Float64Literal(val e: Expr.Float64) : LiteralPattern()
data class BigintLiteral(val e: Expr.Bigint) : LiteralPattern()
data class BigdecPattern(val e: Expr.Bigdec) : LiteralPattern()
}

typealias Row = Type
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/novah/formatter/Formatter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,8 @@ class Formatter {
is LiteralPattern.Int64Literal -> show(p.e)
is LiteralPattern.Float32Literal -> show(p.e)
is LiteralPattern.Float64Literal -> show(p.e)
is LiteralPattern.BigintLiteral -> show(p.e)
is LiteralPattern.BigdecPattern -> show(p.e)
}

private fun show(l: LetDef, isFor: Boolean = false): String {
Expand Down
8 changes: 8 additions & 0 deletions src/main/kotlin/novah/frontend/Parser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,14 @@ class Parser(
iter.next()
Pattern.LiteralP(LiteralPattern.Float64Literal(Expr.Float64(tk.value.v, tk.value.text)), tk.span)
}
is BigintT -> {
iter.next()
Pattern.LiteralP(LiteralPattern.BigintLiteral(Expr.Bigint(tk.value.v, tk.value.text)), tk.span)
}
is BigdecT -> {
iter.next()
Pattern.LiteralP(LiteralPattern.BigdecPattern(Expr.Bigdec(tk.value.v, tk.value.text)), tk.span)
}
is CharT -> {
iter.next()
Pattern.LiteralP(LiteralPattern.CharLiteral(Expr.CharE(tk.value.c, tk.value.raw)), tk.span)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ class PatternMatchingCompiler<R>(private val ctorCache: MutableMap<String, Ctor>
is LiteralPattern.Int64Literal -> mkPrimCtor(l.e.v.toString())
is LiteralPattern.Float32Literal -> mkPrimCtor(l.e.v.toString())
is LiteralPattern.Float64Literal -> mkPrimCtor(l.e.v.toString())
is LiteralPattern.BigintLiteral -> mkPrimCtor(l.e.v.toString())
is LiteralPattern.BigdecLiteral -> mkPrimCtor(l.e.v.toString())
}
Pat.PCon(con)
}
Expand Down
19 changes: 15 additions & 4 deletions src/main/kotlin/novah/optimize/Optimizer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,19 @@ class Optimizer(private val ast: CModule, private val ctorCache: MutableMap<Stri
is Pattern.Unit -> PatternResult(tru)
is Pattern.LiteralP -> {
val lit = p.lit.e.convert(locals)
if (p.lit is LiteralPattern.StringLiteral) {
PatternResult(Expr.NativeMethod(eqString, lit, listOf(exp), boolType, exp.span))
} else {
PatternResult(Expr.OperatorApp("==", listOf(lit, exp), boolType, exp.span))
when (p.lit) {
is LiteralPattern.StringLiteral -> {
PatternResult(Expr.NativeMethod(eqString, lit, listOf(exp), boolType, exp.span))
}
is LiteralPattern.BigintLiteral -> {
PatternResult(Expr.NativeMethod(bigIntEquals, lit, listOf(exp), boolType, exp.span))
}
is LiteralPattern.BigdecLiteral -> {
PatternResult(Expr.NativeMethod(bigDecEquals, lit, listOf(exp), boolType, exp.span))
}
else -> {
PatternResult(Expr.OperatorApp("==", listOf(lit, exp), boolType, exp.span))
}
}
}
is Pattern.Regex -> {
Expand Down Expand Up @@ -817,6 +826,8 @@ class Optimizer(private val ast: CModule, private val ctorCache: MutableMap<Stri
val recFunField = RecFunction::class.java.fields.find { it.name == "fun" }!!
val patternMatches = java.util.regex.Pattern::class.java.methods.find { it.name == "matches" }!!
val registerMetas = novah.Metadata::class.java.methods.find { it.name == "registerMetas" }!!
val bigIntEquals = BigInteger::class.java.methods.find { it.name == "equals" }!!
val bigDecEquals = BigDecimal::class.java.methods.find { it.name == "equals" }!!
val bigIntCtor = BigInteger::class.java.constructors.find {
it.parameterCount == 1 && it.parameters[0].type.simpleName == "String"
}!!
Expand Down

0 comments on commit 7b1340f

Please sign in to comment.