Skip to content

Commit

Permalink
Merge pull request #54 from melvic-ybanez/scala-prefs
Browse files Browse the repository at this point in the history
Scala prefs
  • Loading branch information
melvic-ybanez authored Apr 9, 2022
2 parents de5eea3 + e3847fd commit 42a7438
Show file tree
Hide file tree
Showing 28 changed files with 449 additions and 111 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ org.scala-ide.sdt.update-site/site.xml
*.ppm
*.png

*.sc
*.sc

user-prefs.json
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ chi> def apply[A, B]: (A => B) => A => B
Detected language: Scala
Generated code:
def apply[A, B]: ((A => B) => (A => B)) =
Predef.identity
identity

chi> def fst[A, B]: (A, B) => A
Detected language: Scala
Expand All @@ -61,19 +61,19 @@ chi> def compose[A, B, C]: (B => C) => (A => B) => A => C
Detected language: Scala
Generated code:
def compose[A, B, C]: ((B => C) => ((A => B) => (A => C))) =
f => g => a => f(g(a))
f => g => f.compose(g)

chi> def andThen[A, B, C]: (A => B) => (B => C) => A => C
Detected language: Scala
Generated code:
def andThen[A, B, C]: ((A => B) => ((B => C) => (A => C))) =
f => g => a => g(f(a))
f => g => g.compose(f)

chi> def foo[A, B, C]: (A => C) => (B => C) => Either[A, B] => C
Detected language: Scala
Generated code:
def foo[A, B, C]: ((A => C) => ((B => C) => (Either[A, B] => C))) =
f => g => e => e match {
f => g => {
case Left(a) => f(a)
case Right(b) => g(b)
}
Expand All @@ -82,7 +82,7 @@ chi> def foo[A]: Either[A, A] => A
Detected language: Scala
Generated code:
def foo[A]: (Either[A, A] => A) =
e => e match {
{
case Left(a) => a
case Right(a) => a
}
Expand All @@ -91,7 +91,7 @@ chi> def foo[A, B, C]: (A => C) => (B => C) => B => C
Detected language: Scala
Generated code:
def foo[A, B, C]: ((A => C) => ((B => C) => (B => C))) =
f => Predef.identity
f => identity

chi> exit
Bye!
Expand All @@ -106,7 +106,7 @@ def identity(a: A): A =

chi> def andThen[A, B, C](f: (A => B), g: (B => C)): A => C
def andThen[A, B, C](f: (A => B), g: (B => C)): (A => C) =
a => g(f(a))
g.compose(f)

```

Expand All @@ -123,7 +123,7 @@ def disjunctionElimination[A, B, C](
f: (A => C),
g: (B => C)
): (Either[A, B] => C) =
e => e match {
{
case Left(a) => f(a)
case Right(b) => g(b)
}
Expand Down Expand Up @@ -166,7 +166,7 @@ chi> def foo(f: String => Int, g: Float => Int): Either[String, Float] => Int
Detected language: Scala
Generated code:
def foo(f: (String => Int), g: (Float => Int)): (Either[String, Float] => Int) =
e => e match {
{
case Left(s) => f(s)
case Right(h) => g(h)
}
Expand Down
8 changes: 7 additions & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ object Dependencies {
"com.fifesoft" % "rsyntaxtextarea" % "3.2.0"
)

lazy val jsonDependencies = Seq(
"com.lihaoyi" %% "upickle" % "1.5.0"
)

lazy val dependencies = Seq(
"org.scala-lang.modules" % "scala-parser-combinators_2.13" % "2.1.1",
) ++ testDependencies ++ uiDependencies
"com.lihaoyi" %% "os-lib" % "0.8.1",
"com.miglayout" % "miglayout-swing" % "11.0"
) ++ testDependencies ++ uiDependencies ++ jsonDependencies
}
7 changes: 7 additions & 0 deletions src/main/resources/preferences.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"scala": {
"pointFree": true,
"simplifyMatch": true,
"usePredef": true
}
}
5 changes: 5 additions & 0 deletions src/main/scala/com/melvic/chi/Config.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.melvic.chi

// TODO: Store this on a properties file
object Config {
val MaxColumnWidth: Int = 80
val DialogFontSize: Int = 14
val DialogHeaderFontSize: Int = 15
val CustomSettingsPath = "user-prefs.json"
val DefaultSettingsPath = "preferences.json"
}
9 changes: 6 additions & 3 deletions src/main/scala/com/melvic/chi/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ package com.melvic.chi

import com.github.weisj.darklaf.LafManager
import com.github.weisj.darklaf.theme.DarculaTheme
import com.melvic.chi.views.menus.MainView
import com.melvic.chi.config.{Preferences, SettingsContent}
import com.melvic.chi.views.MainComponent

import javax.swing.SwingUtilities

//noinspection SpellCheckingInspection
object Main {
implicit val preferences: Preferences = Preferences.load

def main(args: Array[String]): Unit =
args match {
case Array("repl", _ @_*) => Repl()
case Array("repl", _ @_*) => Repl
case _ => runUI()
}

Expand All @@ -19,7 +22,7 @@ object Main {
LafManager.install(new DarculaTheme)

override def run(): Unit = {
new MainView(generateAndShow).setVisible(true)
new MainComponent(generateAndShow).setVisible(true)
}
})
}
18 changes: 11 additions & 7 deletions src/main/scala/com/melvic/chi/Repl.scala
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
package com.melvic.chi

import com.melvic.chi.config.Preferences

import scala.annotation.tailrec
import scala.io.StdIn.readLine

//noinspection SpellCheckingInspection
object Repl {
def apply(): Unit = {
println("Welcome to the Chi Repl. Write your propositions or function signatures below " +
"and press enter to see the results")
loop()
def apply(implicit prefs: Preferences): Unit = {
println(
"Welcome to the Chi Repl. Write your propositions or function signatures below " +
"and press enter to see the results"
)
loop
}

@tailrec
def loop(): Unit =
def loop(implicit prefs: Preferences): Unit =
readLine("chi> ") match {
case "exit" => println("Bye!")
case "" => loop()
case "" => loop
case input =>
println(generateAndShow(input))
println()
loop()
loop
}
}
14 changes: 13 additions & 1 deletion src/main/scala/com/melvic/chi/ast/Proof.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.melvic.chi.ast

import com.melvic.chi.ast.Proposition.PUnit

sealed trait Proof

//noinspection SpellCheckingInspection
Expand All @@ -15,7 +17,9 @@ object Proof {
* A disjunction that utilizes both components, unlike what [[PRight]] and [[PLeft]] are for.
* Each component is a pair: the components name and the component itself.
*/
final case class Disjunction(name: String, left: (String, Proof), right: (String, Proof)) extends Proof
final case class EitherCases(left: (String, Proof), right: (String, Proof)) extends Proof

final case class EitherMatch(name: String, disjunction: EitherCases) extends Proof

final case class Abstraction(domain: Proof, codomain: Proof) extends Proof

Expand All @@ -24,4 +28,12 @@ object Proof {
* name as a string, in order to support invokations of curried functions (e.g `f(a)(b)`)
*/
final case class Application(function: Proof, params: List[Proof]) extends Proof

final case class Infix(left: Proof, right: Proof) extends Proof

def atomicVariable(name: String): Variable =
Variable(name, PUnit)

def applyOne(function: Proof, arg: Proof): Application =
Application(function, arg :: Nil)
}
26 changes: 26 additions & 0 deletions src/main/scala/com/melvic/chi/config/Preferences.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.melvic.chi.config

import com.melvic.chi.config.SettingsContent.save
import os.Path

class Preferences {
var content: SettingsContent = SettingsContent.dummy

def reload(): Unit =
content = SettingsContent.load

def save(settingsContent: SettingsContent): Unit = {
SettingsContent.save(settingsContent)
reload()
}
}

object Preferences {
def load: Preferences = new Preferences {
content = SettingsContent.load
}

def loadDefaults: Preferences = new Preferences {
content = SettingsContent.loadDefaults
}
}
50 changes: 50 additions & 0 deletions src/main/scala/com/melvic/chi/config/SettingsContent.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.melvic.chi.config

import com.melvic.chi.Config
import com.melvic.chi.config.SettingsContent.ScalaSettings
import os.{Path, ReadablePath, ResourcePath}
import upickle.default._

import java.io.{BufferedWriter, FileWriter}

final case class SettingsContent(scala: ScalaSettings)

object SettingsContent {
final case class ScalaSettings(pointFree: Boolean, simplifyMatch: Boolean, usePredef: Boolean)

implicit def scalaPrefs(implicit prefs: Preferences): ScalaSettings =
prefs.content.scala

implicit val scalaConfigRW: ReadWriter[ScalaSettings] = macroRW[ScalaSettings]
implicit val prefRW: ReadWriter[SettingsContent] = macroRW[SettingsContent]

val dummy = SettingsContent(
ScalaSettings(pointFree = false, simplifyMatch = false, usePredef = false)
)

val customSettingsPath = os.pwd / Config.CustomSettingsPath
val defaultSettingsPath = os.resource / Config.DefaultSettingsPath

def load: SettingsContent = {
val prefPath =
if (os.exists(customSettingsPath)) os.read(customSettingsPath)
else os.read(defaultSettingsPath)
loadFromPathString(prefPath)
}

def loadFromPathString(path: String) =
read[SettingsContent](ujson.read(path))

def loadDefaults: SettingsContent =
loadFromPathString(os.read(defaultSettingsPath))

def save(settingsContent: SettingsContent): Unit = {
if (!os.exists(customSettingsPath))
customSettingsPath.toIO.getParentFile.mkdirs()

val settingsJson = write(settingsContent)
val writer = new BufferedWriter(new FileWriter(customSettingsPath.toIO))
writer.write(settingsJson)
writer.close()
}
}
11 changes: 8 additions & 3 deletions src/main/scala/com/melvic/chi/eval/Generate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,21 @@ package com.melvic.chi.eval

import com.melvic.chi.ast.Proposition.{Atom, Identifier, PUnit}
import com.melvic.chi.ast.{Definition, Proposition, Signature}
import com.melvic.chi.config.Preferences
import com.melvic.chi.env.Env
import com.melvic.chi.out.Fault.UnknownPropositions
import com.melvic.chi.out.Result
import com.melvic.chi.out.Result.Result
import com.melvic.chi.parsers.{JavaParser, Language, ScalaParser}

object Generate {
def fromSignature(signature: Signature, language: Language): Result[Definition] = {
def fromSignature(signature: Signature, language: Language)(
implicit prefs: Preferences
): Result[Definition] = {
val Signature(name, typeParams, params, proposition) = signature

implicit val localFnName: String = name

val unknownTypes = Proposition.filter(proposition) {
case PUnit => false
case atom @ Atom(value) =>
Expand All @@ -22,11 +27,11 @@ object Generate {
else
Prover
.proveProposition(proposition)(Env.fromListWithDefault(params))
.map(Simplifier.simplyProof(_, language))
.map(Transform.from(_, language))
.map(Definition(signature, _, language))
}

def fromSignatureString(functionCode: String): Result[Definition] =
def fromSignatureString(functionCode: String)(implicit prefs: Preferences): Result[Definition] =
ScalaParser
.parseSignature(functionCode)
.orElse(JavaParser.parseSignature(functionCode))
Expand Down
14 changes: 12 additions & 2 deletions src/main/scala/com/melvic/chi/eval/Prover.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
package com.melvic.chi.eval

import com.melvic.chi.ast.Proof.{Abstraction, Application, PLeft, PRight, TUnit, Variable, Conjunction => PConjunction, Disjunction => PDisjunction}
import com.melvic.chi.ast.Proof.{
Abstraction,
Application,
EitherCases,
EitherMatch,
PLeft,
PRight,
TUnit,
Variable,
Conjunction => PConjunction
}
import com.melvic.chi.ast.Proposition._
import com.melvic.chi.ast.{Proof, Proposition}
import com.melvic.chi.env.Env
Expand Down Expand Up @@ -125,7 +135,7 @@ object Prover {
case (Variable(leftName, _), leftProof) =>
proveWithComponent(right).flatMap {
case (Variable(rightName, _), rightProof) =>
Result.success(PDisjunction(name, (leftName, leftProof), (rightName, rightProof)))
Result.success(EitherMatch(name, EitherCases((leftName, leftProof), (rightName, rightProof))))
}
}
}
Expand Down
23 changes: 0 additions & 23 deletions src/main/scala/com/melvic/chi/eval/Simplifier.scala

This file was deleted.

Loading

0 comments on commit 42a7438

Please sign in to comment.