Skip to content

Commit 91e6d6d

Browse files
committed
Add Abstraction Eliminators
1 parent 1c07cfc commit 91e6d6d

18 files changed

+178
-22
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- [On the Befunge-98 Interpreter](#on-the-befunge-98-interpreter)
3030
- [On the LazyK Interpreter](#on-the-lazyk-interpreter)
3131
- [How the Interface Code Works](#how-the-interface-code-works)
32+
- [Abstraction Eliminators](#abstraction-eliminators)
3233
- [Building](#building)
3334

3435
## Purpose of Eso
@@ -408,5 +409,11 @@ You'll also notice that the whole thing is wrapped in a `Trampoline` method. If
408409

409410
Of course, Eso wouldn't need special handling of trampolines if it had full TCE, but that's a matter for future JVM versions to address.
410411

412+
###Abstraction Eliminators
413+
For some combinator-calculus languages without support for lambda expressions, Eso provides abstraction eliminators. These are special transpilers that turn all lambda expressions into combinator expressions. For example, if you wanted to run abstraction elimination on an Unlambda program, you would type:
414+
```
415+
Eso> transpile -s example.txt -o example.unl -sl Lambda_Calculus
416+
```
417+
411418
### Building
412419
I use [SBT assembly](https://github.com/sbt/sbt-assembly). This repo should give you everything you need to build it, just put it in a folder, run SBT from that directory, let it do its thing, then run assembly.

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ThisBuild / scalaVersion := "2.13.0"
2-
ThisBuild / version := "2.3.1"
2+
ThisBuild / version := "2.4.0"
33
ThisBuild / organization := "com.github.dashlambda"
44
ThisBuild / organizationName := "dashlambda"
55

esoTestLog.txt

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ RunProgHandler
6161
DeadfishSpec:
6262
Deadfish
6363
- should run hworld.df correctly
64+
LambdaToLazyKUnlSpec:
65+
Lambda_Calculus => LazyK_Unlambda
66+
- should preserve the behavior of absSpaceLazyK.txt
6467
NULLSpec:
6568
NULL
6669
- should run hworld.nul correctly
@@ -78,8 +81,8 @@ WhiteSpace
7881
- should run hworld.ws correctly
7982
OokSpec:
8083
Ook <=> BrainFuck
81-
- should Preserve the behavior of hworld.ook when translating from BrainFuck to Ook
82-
- should Preserve the behavior of hworld.b when translating from Ook to BrainFuck
84+
- should preserve the behavior of hworld.ook when translating from BrainFuck to Ook
85+
- should preserve the behavior of hworld.b when translating from Ook to BrainFuck
8386
PreludeSpec:
8487
Prelude
8588
- should run hworld.pld correctly in parallel
@@ -120,8 +123,8 @@ GlyphoShorthand <=> Glypho
120123
- should preserve the behavior of hworld.glo
121124
FlufflePuffSpec:
122125
FlufflePuff <=> BrainFuck
123-
- should Preserve the behavior of hworld.fl when translating from BrainFuck to FlufflePuff
124-
- should Preserve the behavior of hworld.b when translating from FlufflePuff to BrainFuck
126+
- should preserve the behavior of hworld.fl when translating from BrainFuck to FlufflePuff
127+
- should preserve the behavior of hworld.b when translating from FlufflePuff to BrainFuck
125128
VolatileSpec:
126129
Volatile
127130
- should run hworld.vol correctly
@@ -200,6 +203,11 @@ PrimeNumTools
200203
- should generate a list of prime number Ints by trial division
201204
- should generate a list of prime number SafeLongs by trial division
202205
- should generate a list of prime number SafeLongs by incremental SOE
206+
- should correctly identify primes numbers
207+
- should factor a number such that it is equal to the product of its factors
208+
LambdaToUnlambdaSpace:
209+
Lambda_Calculus => Unlambda
210+
- should preserve the behavior of absCountUnlambda.txt
203211
PATHSpec:
204212
PATH
205213
- should run hworld.path correctly
@@ -222,8 +230,8 @@ MetatapeSpec:
222230
Metatape
223231
- should run hworld.mt correctly
224232
- should run bitWidth.mt correctly
225-
Run completed in 1 minute, 55 seconds.
226-
Total number of tests run: 127
227-
Suites: completed 46, aborted 0
228-
Tests: succeeded 127, failed 0, canceled 0, ignored 0, pending 0
233+
Run completed in 2 minutes, 19 seconds.
234+
Total number of tests run: 131
235+
Suites: completed 48, aborted 0
236+
Tests: succeeded 131, failed 0, canceled 0, ignored 0, pending 0
229237
All tests passed.

mycologyReport.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ y claims all of the following:
7979
That the offset of the IP was ( 0 0 )
8080
That the least point containing a non-space cell is ( -3 -2 )
8181
That the greatest point, relative to that point, is ( 183 911 )
82-
That the day of the month is 2
82+
That the day of the month is 3
8383
That the month is 3
8484
That the year is 2020
85-
That the time is 04 : 46 : 42
85+
That the time is 07 : 52 : 42
8686
That the size of the stack stack is 1
8787
That the stack sizes are [ 0 ] from top to bottom
8888
That the command-line arguments were: [ null ]
@@ -148,8 +148,8 @@ GOOD: all of A-Z reflected
148148
Testing fingerprint HRTI... loaded.
149149
UNDEF: G gives clock granularity as 1000 microseconds
150150
GOOD: T reflected when called before M
151-
UNDEF: S pushed 520000
152-
UNDEF: T after M pushed 0 and a second T, after 675 ys, pushed 12430000
151+
UNDEF: S pushed 232000
152+
UNDEF: T after M pushed 1000 and a second T, after 675 ys, pushed 12813000
153153
GOOD: ET reflected
154154

155155
Testing fingerprint MODE... not loaded.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package common
2+
3+
import parsers.EsoParser
4+
5+
import scala.util.Try
6+
7+
abstract class AbstractionEliminator extends Transpiler{
8+
val src: String = "Lambda_Calculus"
9+
10+
val parser: EsoParser[Seq[Char], Expr]
11+
12+
def apply(config: Config)(progRaw: String): Try[String] = parser(progRaw).toTry() map (_.toString)
13+
14+
abstract class Expr{
15+
def elim(c: Char): Expr
16+
def uses(c: Char): Boolean}
17+
}

src/main/scala/common/PrimeNumTools.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ object PrimeNumTools {
4141
if(n.emod(f) == 0) false
4242
else if(f*f >= n) true
4343
else pdo(f + 2)}
44-
n == 2 || (n.emod(2) == 0 && pdo(3))}
44+
n == 2 || n == 3 || (n > 1 && n.emod(2) == 1 && pdo(3))}
4545

46+
def factor(num: Int): Vector[Int] = factor(SafeLong(num))
4647
def factor(num: SafeLong): Vector[Int] = {
4748
@tailrec
4849
def fdo(init: SafeLong, f: SafeLong, c: Int = 0): (SafeLong, Int) = {

src/main/scala/common/Transpiler.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ abstract class Transpiler extends EsoObj{
2020
case _ => ac.mkString("\n")}
2121
val lines = prog.linesIterator.to(LazyList).map(_.dropWhile("\t ".contains(_)))
2222
ido(0, Vector(), lines)}
23+
24+
override def toString: String = s"$src => $dst"
2325
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package lazyk
2+
3+
import common.AbstractionEliminator
4+
import parsers.{EsoParser, PartialArbitraryScanParser}
5+
6+
object LambdaToLazyKUnl extends AbstractionEliminator{
7+
val dst: String = "LazyK_Unlambda"
8+
9+
val parser: EsoParser[Seq[Char], Expr] = {
10+
PartialArbitraryScanParser[Char, Expr](_.headOption){
11+
case (cs :+ '^' :+ c, a +: ac) => (cs, a.elim(c) +: ac)
12+
case (cs :+ '`', x +: y +: ac) => (cs, AppExpr(x, y) +: ac)
13+
case (cs :+ c, ac) =>
14+
if(" \t\r\n".contains(c)) (cs, ac)
15+
else (cs, CharExpr(c) +: ac)}
16+
.withErrors}
17+
18+
case class AppExpr(x: Expr, y: Expr) extends Expr {
19+
def elim(c: Char): Expr =
20+
if(uses(c)) AppExpr(AppExpr(CharExpr('s'), x.elim(c)), y.elim(c))
21+
else AppExpr(CharExpr('k'), this)
22+
def uses(c: Char): Boolean = x.uses(c) || y.uses(c)
23+
override def toString: String = s"`$x$y"}
24+
25+
case class CharExpr(chk: Char) extends Expr {
26+
def elim(c: Char): Expr =
27+
if(c == chk) CharExpr('i')
28+
else AppExpr(CharExpr('k'), this)
29+
def uses(c: Char): Boolean = c == chk
30+
override def toString: String = chk.toString}
31+
}

src/main/scala/lazyk/LazyKAnyToCC.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ object LazyKAnyToCC extends LazyKDialectTranslator{
1010

1111
def unapply(config: Config)(prog: String): Try[String] = {
1212
def mkStr(exp: Expr): String = exp match{
13-
case AppExpr(e1, e2) => s"(${mkStr(e1)}${mkStr(e2)})"
13+
case AppExpr(e1, e2) => e2 match{
14+
case FuncExpr(_) => s"${mkStr(e1)}${mkStr(e2)}"
15+
case _ => s"${mkStr(e1)}(${mkStr(e2)})"}
1416
case FuncExpr(fun) => fun match{
1517
case `scomb` => "S"
1618
case `kcomb` => "K"

src/main/scala/ui/EsoDefaults.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import scala_run.ScalaRun
2121
import slashes.Slashes
2222
import snusp.{BFToSNUSP, SNUSP}
2323
import thue.Thue
24-
import unlambda.Unlambda
24+
import unlambda.{LambdaToUnlambda, Unlambda}
2525
import volatile.Volatile
2626
import whitespace.{WSAssembly, WhiteSpace, WhiteSpaceToScala}
2727
import wierd.Wierd
@@ -101,7 +101,7 @@ object EsoDefaults extends EsoObj{
101101
ALPL,
102102
LazyBird)
103103
val defTransVec: Vector[Translator] = Vector[Translator](FlufflePuff, Ook, WSAssembly, GlyphoShorthand, LazyKAnyToUnl, LazyKAnyToIota, LazyKAnyToCC, LazyKAnyToJot)
104-
val defGenVec: Vector[Transpiler] = Vector[Transpiler](BFToScala, BFToCPP, WhiteSpaceToScala, BFToSNUSP, BFToMetatape, BFToPrelude, BFToLazyK)
104+
val defGenVec: Vector[Transpiler] = Vector[Transpiler](BFToScala, BFToCPP, WhiteSpaceToScala, BFToSNUSP, BFToMetatape, BFToPrelude, BFToLazyK, LambdaToLazyKUnl, LambdaToUnlambda)
105105

106106
val defBoolVec: Vector[(String, Boolean, String)] = Vector[(String, Boolean, String)](
107107
("log", false, "toggle detailed console logging"),

0 commit comments

Comments
 (0)