Skip to content

Commit 0133684

Browse files
committed
Added $:map (+>), plus some useful math functions
1 parent 4631ad0 commit 0133684

File tree

9 files changed

+249
-4
lines changed

9 files changed

+249
-4
lines changed

src/main/scala/cmdreader/Global.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ object Global {
3737
val TWO = new BigInteger("2")
3838
val vM = 0
3939
val vm = 5
40-
val vr = 8
40+
val vr = 9
4141
val version = vM + "." + vm + "." + vr
4242
val r: Random = new Random
4343
}

src/main/scala/cmdreader/PStandard.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ object PStandard {
1717
val DISJUNCTION = 50
1818
val DOUBLE_OP = 1600
1919
val SHIFT = 175
20+
val MAP = 2000
2021
}

src/main/scala/cmdreader/std/Loader.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,12 @@ class Loader {
4242
Global.liblist("std").loadCmd("FPart")
4343
Global.liblist("std").loadCmd("OShl")
4444
Global.liblist("std").loadCmd("OShr")
45+
Global.liblist("std").loadCmd("OMap")
46+
Global.liblist("std").loadCmd("Exp")
47+
Global.liblist("std").loadCmd("Ln")
48+
Global.liblist("std").loadCmd("Pi")
49+
List("Sin", "Cos", "Tan").map({
50+
s => List(s, s + "h", "A" + s, "A" + s + "h").map(Global.liblist("std").loadCmd(_))
51+
})
4552
}
4653
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package cmdreader.std
2+
3+
import cmdreader._
4+
import types._
5+
import util._
6+
import java.math.BigInteger
7+
8+
class OMap extends CommandOperator {
9+
override def getName(): String = "map"
10+
override def getOpAlias() = "+>"
11+
override def isValidArg0(n: Int) = n >= 2
12+
override def apply(args: Array[Type]): Type = {
13+
val argc = args.length
14+
val lists = args.dropRight(1)
15+
val f0 = args(argc - 1)
16+
val f = f0 match {
17+
case f: TFunction => f
18+
case _ => return new TError(1, f0 + "is not a function")
19+
}
20+
val trueLists = lists.map(CollectionOps.decodeToList(_))
21+
val flipped = TurnOnSide(trueLists)
22+
val newList = flipped.map(f(_))
23+
CollectionOps.encodeFromList(newList, lists(0).getType)
24+
}
25+
def getPrecedence() = PStandard.MAP
26+
def isReversed() = false
27+
def hasAssignmentEquiv() = true
28+
def getDoubleBase() = None
29+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package cmdreader.std
2+
3+
import cmdreader._
4+
import types._
5+
import util._
6+
7+
class Exp extends Command {
8+
override def getName(): String = "exp"
9+
override def isValidArg0(n: Int): Boolean = n == 1
10+
override def apply(args: Array[Type]): Type = MathUtil.exp(args(0))
11+
}
12+
class Ln extends Command {
13+
override def getName(): String = "ln"
14+
override def isValidArg0(n: Int): Boolean = n == 1
15+
override def apply(args: Array[Type]): Type = MathUtil.ln(args(0))
16+
}
17+
class Pi extends Command {
18+
override def getName(): String = "pi"
19+
override def isValidArg0(n: Int): Boolean = n == 0
20+
override def apply(args: Array[Type]): Type = TFish(Math.PI)
21+
}
22+
class Sin extends Command {
23+
override def getName(): String = "sin"
24+
override def isValidArg0(n: Int): Boolean = n == 1
25+
override def apply(args: Array[Type]): Type = MathUtil.sin(args(0))
26+
}
27+
class Cos extends Command {
28+
override def getName(): String = "cos"
29+
override def isValidArg0(n: Int): Boolean = n == 1
30+
override def apply(args: Array[Type]): Type = MathUtil.cos(args(0))
31+
}
32+
class Tan extends Command {
33+
override def getName(): String = "tan"
34+
override def isValidArg0(n: Int): Boolean = n == 1
35+
override def apply(args: Array[Type]): Type = MathUtil.tan(args(0))
36+
}
37+
class ASin extends Command {
38+
override def getName(): String = "asin"
39+
override def isValidArg0(n: Int): Boolean = n == 1
40+
override def apply(args: Array[Type]): Type = MathUtil.asin(args(0))
41+
}
42+
class ACos extends Command {
43+
override def getName(): String = "acos"
44+
override def isValidArg0(n: Int): Boolean = n == 1
45+
override def apply(args: Array[Type]): Type = MathUtil.acos(args(0))
46+
}
47+
class ATan extends Command {
48+
override def getName(): String = "atan"
49+
override def isValidArg0(n: Int): Boolean = n == 1 || n == 2
50+
override def apply(args: Array[Type]): Type = {
51+
if (args.length == 1) MathUtil.atan(args(0))
52+
else MathUtil.atan(args(1), args(0))
53+
}
54+
}
55+
class Sinh extends Command {
56+
override def getName(): String = "sinh"
57+
override def isValidArg0(n: Int): Boolean = n == 1
58+
override def apply(args: Array[Type]): Type = MathUtil.sinh(args(0))
59+
}
60+
class Cosh extends Command {
61+
override def getName(): String = "cosh"
62+
override def isValidArg0(n: Int): Boolean = n == 1
63+
override def apply(args: Array[Type]): Type = MathUtil.cosh(args(0))
64+
}
65+
class Tanh extends Command {
66+
override def getName(): String = "tanh"
67+
override def isValidArg0(n: Int): Boolean = n == 1
68+
override def apply(args: Array[Type]): Type = MathUtil.tanh(args(0))
69+
}
70+
class ASinh extends Command {
71+
override def getName(): String = "asinh"
72+
override def isValidArg0(n: Int): Boolean = n == 1
73+
override def apply(args: Array[Type]): Type = MathUtil.asinh(args(0))
74+
}
75+
class ACosh extends Command {
76+
override def getName(): String = "acosh"
77+
override def isValidArg0(n: Int): Boolean = n == 1
78+
override def apply(args: Array[Type]): Type = MathUtil.acosh(args(0))
79+
}
80+
class ATanh extends Command {
81+
override def getName(): String = "atanh"
82+
override def isValidArg0(n: Int): Boolean = n == 1
83+
override def apply(args: Array[Type]): Type = MathUtil.atanh(args(0))
84+
}

src/main/scala/util/BTI.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package util
22

3-
import types.TMountain
3+
import types._
44
import java.math.BigInteger
55

66
object BTI {
77
def bti(b: Boolean): TMountain = {
88
new TMountain(if (b) BigInteger.ONE else BigInteger.ZERO)
99
}
10+
def btl(b: Boolean): THill = {
11+
new THill(if (b) 1L else 0L)
12+
}
1013
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package util
2+
import types._
3+
import java.math.BigInteger
4+
import scala.collection.mutable._
5+
6+
object CollectionOps {
7+
def decodeToList(t: Type): List[Type] = {
8+
t match {
9+
case t: TMountain => {
10+
val n = t.getVal
11+
List.range(0, n.bitCount).map(b => BTI.btl(n.testBit(b)))
12+
}
13+
case t: THill => {
14+
val n = t.getVal
15+
List.range(0, 64).map(b => BTI.btl((n & (1L << b)) != 0L))
16+
}
17+
case t: TString => {
18+
t.getVal.toCharArray.toList.map(i => new THill(i))
19+
}
20+
case t: LList => {
21+
t.l.toList
22+
}
23+
}
24+
}
25+
def encodeFromList(l: List[Type], mode: Int): Type = {
26+
mode match {
27+
case 1 => {
28+
var n = BigInteger.ZERO
29+
for (e <- l) {
30+
e match {
31+
case e: TNumerical => {
32+
n = n.shiftLeft(1).add(BigInteger.valueOf(e.intValue))
33+
}
34+
case _ => return new TError(1)
35+
}
36+
}
37+
TMountain(n)
38+
}
39+
case 2 => {
40+
new THill(l.map(_ match {
41+
case e: TNumerical => {
42+
e.intValue
43+
}
44+
case _ => return new TError(1)
45+
}).foldLeft(0L)((a, b) => (a << 1) + b))
46+
}
47+
case 3 => {
48+
new TString(new String(l.map(_ match {
49+
case e: TNumerical => {
50+
e.intValue.toChar
51+
}
52+
case _ => return new TError(1)
53+
}).toArray))
54+
}
55+
case 5 =>
56+
new LArray(l.to[ArrayBuffer])
57+
case 6 =>
58+
new LLinked(l.to[ListBuffer])
59+
}
60+
}
61+
def ctv[T](f: (List[Type]) => T): (Type) => T = {
62+
(t: Type) =>
63+
f(decodeToList(t))
64+
}
65+
def ctc(f: (List[Type]) => List[Type]): (Type) => Type = {
66+
(t: Type) =>
67+
encodeFromList(ctv(f)(t), t.getType)
68+
}
69+
}

src/main/scala/util/MathUtil.scala

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,44 @@ object MathUtil {
183183
else if (xt == 5 || xt == 6) mool(applyUnaryMath(f, _), x.asInstanceOf[LList])
184184
else new TError(1)
185185
}
186+
def exp(x: Type): Type = applyUnaryMath(Math.exp(_), x)
187+
def ln(x: Type): Type = applyUnaryMath(Math.log(_), x)
188+
def sin(x: Type): Type = applyUnaryMath(Math.sin(_), x)
189+
def cos(x: Type): Type = applyUnaryMath(Math.cos(_), x)
190+
def tan(x: Type): Type = applyUnaryMath(Math.tan(_), x)
191+
def csc(x: Type): Type = applyUnaryMath(1.0 / Math.sin(_), x)
192+
def sec(x: Type): Type = applyUnaryMath(1.0 / Math.cos(_), x)
193+
def cot(x: Type): Type = applyUnaryMath(1.0 / Math.tan(_), x)
194+
def asin(x: Type): Type = applyUnaryMath(Math.asin(_), x)
195+
def acos(x: Type): Type = applyUnaryMath(Math.acos(_), x)
196+
def atan(x: Type): Type = applyUnaryMath(Math.atan(_), x)
197+
def acsc(x: Type): Type = applyUnaryMath(y => Math.asin(1.0 / y), x)
198+
def asec(x: Type): Type = applyUnaryMath(y => Math.acos(1.0 / y), x)
199+
def acot(x: Type): Type = applyUnaryMath(Math.PI / 2 - Math.atan(_), x)
200+
def sinh(x: Type): Type = applyUnaryMath(Math.sinh(_), x)
201+
def cosh(x: Type): Type = applyUnaryMath(Math.cosh(_), x)
202+
def tanh(x: Type): Type = applyUnaryMath(Math.tanh(_), x)
203+
def csch(x: Type): Type = applyUnaryMath(1.0 / Math.sinh(_), x)
204+
def sech(x: Type): Type = applyUnaryMath(1.0 / Math.cosh(_), x)
205+
def coth(x: Type): Type = applyUnaryMath(1.0 / Math.tanh(_), x)
206+
def asinh(x: Double) = Math.log(Math.hypot(1.0, x) + x)
207+
def acosh(x: Double) = Math.log(Math.sqrt(Math.pow(x, 2) - 1.0) + x)
208+
def atanh(x: Double) = 0.5 * (Math.log(x + 1) - Math.log(1 - x))
209+
def asinh(x: Type): Type = applyUnaryMath(asinh(_), x)
210+
def acosh(x: Type): Type = applyUnaryMath(acosh(_), x)
211+
def atanh(x: Type): Type = applyUnaryMath(atanh(_), x)
212+
def acsch(x: Type): Type = applyUnaryMath(y => asinh(1.0 / y), x)
213+
def asech(x: Type): Type = applyUnaryMath(y => acosh(1.0 / y), x)
214+
def acoth(x: Type): Type = applyUnaryMath(y => 0.5 * Math.log((y + 1)/(y - 1)), x)
215+
def atan(x: Type, y: Type): Type = {
216+
(x, y) match {
217+
case (xl: LList, yl: LList) => motl(atan(_, _), xl, yl)
218+
case (xl: LList, _) => mool(atan(_, _), xl, y)
219+
case (_, yl: LList) => mool((a, b) => atan(b, a), yl, x)
220+
case (x: TNumerical, y: TNumerical) => TFish(Math.atan2(y.doubleValue, x.doubleValue))
221+
case _ => new TError(1)
222+
}
223+
}
186224
def idivide(x: Type, y: Type): Type = {
187225
val xt = x.getType; val yt = y.getType
188226
if ((xt == 5 || xt == 6) && (yt == 5 || yt == 6)) motl(idivide, x.asInstanceOf[LList], y.asInstanceOf[LList])
@@ -289,7 +327,7 @@ object MathUtil {
289327
(x, y) match {
290328
case (xl: LList, yl: LList) => motl(shl(_, _), xl, yl)
291329
case (xl: LList, _) => mool(shl(_, _), xl, y)
292-
case (_, yl: LList) => shl(y, x)
330+
case (_, yl: LList) => mool((a, b) => shl(b, a), yl, x)
293331
case (xm: TMountain, ym: TNumerical) => {
294332
new TMountain(xm.getVal.shiftLeft(ym.intValue))
295333
}
@@ -306,7 +344,7 @@ object MathUtil {
306344
(x, y) match {
307345
case (xl: LList, yl: LList) => motl(shr(_, _), xl, yl)
308346
case (xl: LList, _) => mool(shr(_, _), xl, y)
309-
case (_, yl: LList) => shr(y, x)
347+
case (_, yl: LList) => mool((a, b) => shr(b, a), yl, x)
310348
case (xm: TMountain, ym: TNumerical) => {
311349
new TMountain(xm.getVal.shiftRight(ym.intValue))
312350
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package util
2+
import types._
3+
4+
object TurnOnSide {
5+
// Trying to write a generalized function drove me crazy.
6+
def apply(mat: Array[List[Type]]): List[Array[Type]] = {
7+
mat(0) match {
8+
case Nil => Nil
9+
case _ => {
10+
mat.map(_.head) :: apply(mat.map(_.tail))
11+
}
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)