Skip to content

Commit f12c67f

Browse files
committed
Merge remote-tracking branch 'origin/Temp_Work'
# Conflicts: # mycologyReport.txt
2 parents e7156a9 + ddf09ad commit f12c67f

File tree

15 files changed

+202
-21
lines changed

15 files changed

+202
-21
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Current native language support (mostly in chronological order):
8282
* [Platts](https://esolangs.org/wiki/Platts)
8383
* [WordLang](https://github.com/WilliamRagstad/WordLang)
8484
* [LazyK](https://esolangs.org/wiki/Lazy_K)
85+
* [alpl](https://esolangs.org/wiki/ALPL)
8586
* Scala
8687

8788
### Current features:
@@ -271,7 +272,7 @@ The environment maintained by Eso has collected quite a few parameters, detailed
271272
* fileEOF: The ASCII code of the character Eso sticks at the end of file input. Most languages expect 0, but sometimes it needs to be something else. For instance, cgbfi.b expects a program terminated by `!`, and anything following is considered input.
272273
* init: Initial length of memory tape, where applicable.
273274
* methSize: The maximum number of blocks allowed in a method when breaking up generated code to fit in the JVM's nonsensical limits.
274-
* mtCharWidth: Bit-width of characters used by Metatape.
275+
* charWidth: Bit-width of characters used by Metatape.
275276
* olen: Maximum number of characters to print. This is primarily useful for non-terminating programs. Some transpilers ignore this.
276277

277278
Boolean values can be set to true with an argument matching the regex `(true|yes|t|y|[1-9])` and false matching `(false|no|f|n|0)`, both case-insensitive.

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.0.0"
2+
ThisBuild / version := "2.1.0"
33
ThisBuild / organization := "com.github.dashlambda"
44
ThisBuild / organizationName := "dashlambda"
55

mycologyReport.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ y claims all of the following:
8282
That the day of the month is 19
8383
That the month is 2
8484
That the year is 2020
85-
That the time is 00 : 14 : 09
85+
That the time is 11 : 40 : 29
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 978000
152-
UNDEF: T after M pushed 1000 and a second T, after 675 ys, pushed 10080000
151+
UNDEF: S pushed 33000
152+
UNDEF: T after M pushed 0 and a second T, after 675 ys, pushed 10241000
153153
GOOD: ET reflected
154154

155155
Testing fingerprint MODE... not loaded.

src/main/scala/alpl/ALPL.scala

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package alpl
2+
3+
import common.{Config, Interpreter}
4+
import parsers.{DepthRecurParser, EsoParser, RegexParser}
5+
6+
import scala.annotation.tailrec
7+
import scala.collection.immutable
8+
import scala.util.Try
9+
import scala.util.control.TailCalls._
10+
11+
object ALPL extends Interpreter{
12+
val name: String = "ALPL"
13+
14+
val allParser: EsoParser[String, Vector[Expr]] = {
15+
val asnParser = RegexParser[Expr](raw"""=(.)"""){m => FuncExpr(Assign(m.group(1).head))}
16+
val prmParser = RegexParser[Expr](raw"""([^\[\]\.\`\=])"""){m =>
17+
m.group(1) match{
18+
case "?" => FuncExpr(Inp)
19+
case "0" => FuncExpr(Print(false))
20+
case "1" => FuncExpr(Print(true))
21+
case str => RefExpr(str.head)}}
22+
val lamParser = RegexParser[Expr](raw"""\[([^\.]*)\.([^\]]*)\]"""){m =>
23+
val binds = m.group(1).toVector
24+
val ops = m.group(2).toVector.map{
25+
case '`' => None
26+
case c =>
27+
val expr = c match{
28+
case '?' => FuncExpr(Inp)
29+
case '0' => FuncExpr(Print(false))
30+
case '1' => FuncExpr(Print(true))
31+
case _ => binds.indexOf(c) match{
32+
case -1 => RefExpr(c)
33+
case i => BoundExpr(i)}}
34+
Some(expr)}
35+
FuncExpr(Lambda(ops, Vector(), binds.size))}
36+
37+
def recur(str: String): Option[(String, Int, Int)] = if(str.startsWith("`")) Some((str.tail, 0, 1)) else None
38+
def collect(xs: Seq[Expr]): Expr = xs.reduceLeft(AppExpr)
39+
DepthRecurParser(asnParser.withErrors <+> prmParser.withErrors <+> lamParser.withErrors)(2)(recur)(collect)
40+
.withConditioning(_.replaceAll("""\s+""", ""))
41+
.withErrors.*}
42+
43+
def apply(config: Config)(progRaw: String): Try[Seq[Char] => LazyList[Char]] = allParser(progRaw).toTry() map{
44+
case prog +: es =>
45+
inputs => {
46+
val width = config.num("charWidth")
47+
val initEnv = Env(immutable.HashMap(), binInp(inputs, width), 0, width - 1)
48+
val initRet: TailRec[Ret] = prog(PassCont(es), initEnv)
49+
LazyList.unfold(initRet)(nxt => nxt.result.resolve)}}
50+
51+
def binInp(inp: Seq[Char], wid: Int = 8): Seq[Boolean] = {
52+
@tailrec
53+
def toBin(src: Int, ac: Vector[Boolean] = Vector()): Vector[Boolean] = {
54+
if(ac.sizeIs == wid) ac
55+
else toBin(src/2, (src%2 == 1) +: ac)}
56+
inp flatMap (c => toBin(c.toInt))}
57+
58+
case class Env(funcs: immutable.HashMap[Char, Expr], inp: Seq[Boolean], oac: Int, onum: Int){
59+
def apply(c: Char): Expr = funcs(c)
60+
def add(c: Char, exp: Expr): Env = Env(funcs + ((c, exp)), inp, oac, onum)
61+
def read: (Boolean, Env) = (inp.head, Env(funcs, inp.tail, oac, onum))
62+
def write(bit: Int): (Option[Char], Env) = {
63+
val nac = (oac*2) + bit
64+
if(onum == 0) (Some(nac.toChar), Env(funcs, inp, 0, 7))
65+
else (None, Env(funcs, inp, nac, onum - 1))}}
66+
67+
trait Ret{
68+
def resolve: Option[(Char, TailRec[Ret])]}
69+
70+
trait Expr{
71+
def apply(cc: Cont, env: Env): TailRec[Ret]}
72+
73+
trait Cont{
74+
def apply(f: Func, env: Env): TailRec[Ret]}
75+
76+
trait Func{
77+
def apply(f: Expr, cc: Cont, env: Env): TailRec[Ret]}
78+
79+
//Returns
80+
object HaltRet extends Ret{
81+
def resolve: Option[(Char, TailRec[Ret])] = None}
82+
83+
case class PrintRet(c: Char, nxt: TailRec[Ret]) extends Ret {
84+
def resolve: Option[(Char, TailRec[Ret])] = Some((c, nxt))}
85+
86+
//Expressions
87+
case class FuncExpr(f: Func) extends Expr{
88+
def apply(cc: Cont, env: Env): TailRec[Ret] = tailcall(cc(f, env))}
89+
90+
case class RefExpr(c: Char) extends Expr{
91+
def apply(cc: Cont, env: Env): TailRec[Ret] = tailcall(env(c)(cc, env))}
92+
93+
case class BoundExpr(n: Int) extends Expr{
94+
def apply(cc: Cont, env: Env): TailRec[Ret] = done(HaltRet)}
95+
96+
case class AppExpr(x: Expr, y: Expr) extends Expr{
97+
def apply(cc: Cont, env: Env): TailRec[Ret] = tailcall(x(ExprCont(y, cc), env))}
98+
99+
//Continuations
100+
object EndCont extends Cont{
101+
def apply(f: Func, env: Env): TailRec[Ret] = done(HaltRet)}
102+
103+
case class PassCont(exps: Seq[Expr]) extends Cont{
104+
def apply(f: Func, env: Env): TailRec[Ret] = exps match{
105+
case e +: es => tailcall(e(PassCont(es), env))
106+
case _ => done(HaltRet)}}
107+
108+
case class ExprCont(y: Expr, cc: Cont) extends Cont{
109+
def apply(f: Func, env: Env): TailRec[Ret] = tailcall(f(y, cc, env))}
110+
111+
//Functions
112+
case class Inp1(x: Expr) extends Func{
113+
def apply(f: Expr, cc: Cont, env: Env): TailRec[Ret] = env.read match{
114+
case (bit, nenv) =>
115+
if(bit) tailcall(x(cc, nenv))
116+
else tailcall(f(cc, nenv))}}
117+
object Inp extends Func{
118+
def apply(f: Expr, cc: Cont, env: Env): TailRec[Ret] = tailcall(cc(Inp1(f), env))}
119+
120+
case class Print(bit: Boolean) extends Func{
121+
def apply(f: Expr, cc: Cont, env: Env): TailRec[Ret] = env.write(if(bit) 1 else 0) match{
122+
case (res, nenv) => res match{
123+
case Some(c) => done(PrintRet(c, tailcall(f(cc, nenv))))
124+
case None => tailcall(f(cc, nenv))}}}
125+
126+
case class Assign(c: Char) extends Func{
127+
def apply(f: Expr, cc: Cont, env: Env): TailRec[Ret] = tailcall(f(cc, env.add(c, f)))}
128+
129+
case class Lambda(ops: Vector[Option[Expr]], bound: Vector[Expr], rem: Int) extends Func{
130+
def apply(f: Expr, cc: Cont, env: Env): TailRec[Ret] = {
131+
if(rem == 1) tailcall(collapse(bound :+ f)(cc, env))
132+
else tailcall(cc(Lambda(ops, bound :+ f, rem - 1), env))}
133+
134+
def collapse(binds: Vector[Expr]): Expr = {
135+
trait PC{
136+
def apply(ex: Expr): PC}
137+
object EPC extends PC{
138+
def apply(ex: Expr): PC = RPC(ex)}
139+
case class RPC(res: Expr) extends PC{
140+
def apply(ex: Expr): PC = RPC(ex)}
141+
case class APC(cc: PC) extends PC{
142+
def apply(ex: Expr): PC = APC1(ex, cc)}
143+
case class APC1(x: Expr, cc: PC) extends PC{
144+
def apply(ex: Expr): PC = cc(AppExpr(x, ex))}
145+
146+
@tailrec
147+
def cdo(src: Vector[Option[Expr]], cc: PC): Expr = src match{
148+
case e +: es => e match{
149+
case Some(BoundExpr(n)) => cdo(es, cc(binds(n)))
150+
case Some(ex) => cdo(es, cc(ex))
151+
case None => cdo(es, APC(cc))}
152+
case _ => cc match{
153+
case RPC(res) => res}}
154+
cdo(ops, EPC)}}
155+
}

src/main/scala/lazyk/LazyKParsers.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object LazyKParsers extends EsoObj{
2323
case _ => None}
2424
def collect(xs: Seq[Expr]): Expr = xs match{
2525
case x +: y +: _ => AppExpr(x, y)}
26-
DepthRecurParser(2)(recur)(collect)(funcParser)}
26+
DepthRecurParser(funcParser)(2)(recur)(collect)}
2727

2828
val combParser: EsoParser[Seq[Char], Expr] = {
2929
def collect(src: Seq[Expr]): Expr = src.foldLeft(iexp)(AppExpr)
@@ -36,7 +36,7 @@ object LazyKParsers extends EsoObj{
3636
case 'I' => ARPNext(iexp, cs, 0, 1)
3737
case _ => ARPFail}
3838
case _ => ARPUp(src, 0, 0)}
39-
ArbitraryRecurParser(recur _, collect)}
39+
ArbitraryRecurParser(recur _)(collect)}
4040

4141
val iotaParser: EsoParser[Seq[Char], Expr] = {
4242
val funcParser = {
@@ -47,7 +47,7 @@ object LazyKParsers extends EsoObj{
4747
case _ => None}
4848
def collect(xs: Seq[Expr]): Expr = xs match{
4949
case x +: y +: _ => AppExpr(x, y)}
50-
DepthRecurParser(2)(recur)(collect)(funcParser)}
50+
DepthRecurParser(funcParser)(2)(recur)(collect)}
5151

5252
val jotParser: EsoParser[Seq[Char], Expr] = (inp: Seq[Char]) => {
5353
def collect(exps: Vector[Expr]): Expr = exps.foldLeft(iexp){case (x, y) => AppExpr(x, y)}

src/main/scala/metatape/BFToMetatape.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object BFToMetatape extends Transpiler{
2222
'_' -> "n")
2323

2424
def apply(config: Config)(progRaw: String): Try[String] = {
25-
val wid: Int = config.num("mtCharWidth")
25+
val wid: Int = config.num("charWidth")
2626
val prog = filterChars(progRaw, "[]<>+-,.")
2727
.replaceAll("""\[[+\-]\]""", "_")
2828
.toVector

src/main/scala/metatape/Metatape.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object Metatape extends Interpreter{
1515
val namReg: Regex = raw"""^ ?((?:\S|\S.*\S)) ?\z""".r
1616

1717
def apply(config: Config)(progRaw: String): Try[Seq[Char] => LazyList[Char]] = Try{parse(progRaw)} map{
18-
case (prog, subs) => runProg(prog, subs, config.rands, config.num("mtCharWidth"))}
18+
case (prog, subs) => runProg(prog, subs, config.rands, config.num("charWidth"))}
1919

2020
def runProg(prog: Vector[MTOP], subVec: Vector[MSub], rands: LazyList[Int], padLen: Int): Seq[Char] => LazyList[Char] = {
2121
val subs = mkMap(subVec.map{case MSub(nam, sub) => (nam, sub)})

src/main/scala/parsers/ArbitraryRecurParser.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ case class ARPDown[+A, +B](rem: A, start: Int, end: Int) extends ARPRet[A, B]
99
case class ARPUp[+A, +B](rem: A, start: Int, end: Int) extends ARPRet[A, B]
1010
object ARPFail extends ARPRet[Nothing, Nothing]
1111

12-
case class ArbitraryRecurParser[A, B](func: PartialFunction[A, ARPRet[A, B]], collect: Seq[B] => B) extends EsoParser[A, B]{
12+
case class ArbitraryRecurParser[A, B](func: PartialFunction[A, ARPRet[A, B]])(collect: Seq[B] => B) extends EsoParser[A, B]{
1313
def apply(inp: A): EsoParseRes[A, B] = {
1414
@tailrec
1515
def pdo(src: A, end: Int, tmp: Vector[B], stk: Vector[Vector[B]]): ARPRet[A, B] = func.lift(src) match{
@@ -38,6 +38,6 @@ case class ArbitraryRecurParser[A, B](func: PartialFunction[A, ARPRet[A, B]], co
3838
}
3939

4040
object ArbitraryRecurParser{
41-
def apply[A, B](func: A => ARPRet[A, B], collect: Seq[B] => B): ArbitraryRecurParser[A, B] = {
42-
ArbitraryRecurParser(PartialFunction.fromFunction(func), collect)}
41+
def apply[A, B](func: A => ARPRet[A, B])(collect: Seq[B] => B): ArbitraryRecurParser[A, B] = {
42+
ArbitraryRecurParser(PartialFunction.fromFunction(func))(collect)}
4343
}

src/main/scala/parsers/DepthRecurParser.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package parsers
22

33
import scala.annotation.tailrec
44

5-
case class DepthRecurParser[A, B](depth: Int, priority: Int = 0)(recur: A => Option[(A, Int, Int)])(collect: Seq[B] => B)(endParser: EsoParser[A, B]) extends EsoParser[A, B]{
5+
case class DepthRecurParser[A, B](endParser: EsoParser[A, B])(depth: Int)(recur: A => Option[(A, Int, Int)])(collect: Seq[B] => B) extends EsoParser[A, B]{
66
def apply(inp: A): EsoParseRes[A, B] = {
77
trait Cont{
88
def apply(x: B): Cont}
@@ -16,13 +16,14 @@ case class DepthRecurParser[A, B](depth: Int, priority: Int = 0)(recur: A => Opt
1616
else cc(collect(ac :+ x))}}
1717

1818
@tailrec
19-
def pdo(src: A, len: Int, cc: Cont): EsoParseRes[A, B] = {
20-
recur(src) match{
19+
def pdo(src: A, len: Int, cc: Cont): EsoParseRes[A, B] = cc match{
20+
case ResCont(res) => EsoParsed(res, src, 0, len)
21+
case _ => recur(src) match{
2122
case Some((nxt, _, ne)) => pdo(nxt, len + ne, RecCont(depth, Vector(), cc))
2223
case None => endParser(src) match{
2324
case EsoParsed(res, rem, _, ne) => pdo(rem, len + ne, cc(res))
2425
case EsoParseFail => cc match{
25-
case ResCont(res) => EsoParsed(res, src, priority, len)
26+
case ResCont(res) => EsoParsed(res, src, 0, len)
2627
case _ => EsoParseFail}}}}
2728
recur(inp) match{
2829
case Some((nxt, start, end)) => pdo(nxt, end, RecCont(depth, Vector(), FinCont)) match{

src/main/scala/parsers/EsoParser.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ abstract class EsoParser[A, +B] extends (A => EsoParseRes[A, B]) with EsoObj{
6464
def apply(inp: A): EsoParseRes[A, B]
6565
def parseOne(inp: A): B = apply(inp) match{
6666
case EsoParsed(res, _, _, _) => res
67+
case EsoParseErr(e) => throw e
6768
case _ => throw EsoExcep("Parse Failed")}
6869

6970
def parseAllValues(inp: A): Vector[B] = parseValuesIterator(inp).toVector

0 commit comments

Comments
 (0)