Skip to content

Commit

Permalink
Added $:map (+>), plus some useful math functions
Browse files Browse the repository at this point in the history
  • Loading branch information
bluebear94 committed Jan 26, 2014
1 parent 4631ad0 commit 0133684
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/cmdreader/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ object Global {
val TWO = new BigInteger("2")
val vM = 0
val vm = 5
val vr = 8
val vr = 9
val version = vM + "." + vm + "." + vr
val r: Random = new Random
}
1 change: 1 addition & 0 deletions src/main/scala/cmdreader/PStandard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ object PStandard {
val DISJUNCTION = 50
val DOUBLE_OP = 1600
val SHIFT = 175
val MAP = 2000
}
7 changes: 7 additions & 0 deletions src/main/scala/cmdreader/std/Loader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,12 @@ class Loader {
Global.liblist("std").loadCmd("FPart")
Global.liblist("std").loadCmd("OShl")
Global.liblist("std").loadCmd("OShr")
Global.liblist("std").loadCmd("OMap")
Global.liblist("std").loadCmd("Exp")
Global.liblist("std").loadCmd("Ln")
Global.liblist("std").loadCmd("Pi")
List("Sin", "Cos", "Tan").map({
s => List(s, s + "h", "A" + s, "A" + s + "h").map(Global.liblist("std").loadCmd(_))
})
}
}
29 changes: 29 additions & 0 deletions src/main/scala/cmdreader/std/OMap.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cmdreader.std

import cmdreader._
import types._
import util._
import java.math.BigInteger

class OMap extends CommandOperator {
override def getName(): String = "map"
override def getOpAlias() = "+>"
override def isValidArg0(n: Int) = n >= 2
override def apply(args: Array[Type]): Type = {
val argc = args.length
val lists = args.dropRight(1)
val f0 = args(argc - 1)
val f = f0 match {
case f: TFunction => f
case _ => return new TError(1, f0 + "is not a function")
}
val trueLists = lists.map(CollectionOps.decodeToList(_))
val flipped = TurnOnSide(trueLists)
val newList = flipped.map(f(_))
CollectionOps.encodeFromList(newList, lists(0).getType)
}
def getPrecedence() = PStandard.MAP
def isReversed() = false
def hasAssignmentEquiv() = true
def getDoubleBase() = None
}
84 changes: 84 additions & 0 deletions src/main/scala/cmdreader/std/mathf.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package cmdreader.std

import cmdreader._
import types._
import util._

class Exp extends Command {
override def getName(): String = "exp"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.exp(args(0))
}
class Ln extends Command {
override def getName(): String = "ln"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.ln(args(0))
}
class Pi extends Command {
override def getName(): String = "pi"
override def isValidArg0(n: Int): Boolean = n == 0
override def apply(args: Array[Type]): Type = TFish(Math.PI)
}
class Sin extends Command {
override def getName(): String = "sin"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.sin(args(0))
}
class Cos extends Command {
override def getName(): String = "cos"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.cos(args(0))
}
class Tan extends Command {
override def getName(): String = "tan"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.tan(args(0))
}
class ASin extends Command {
override def getName(): String = "asin"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.asin(args(0))
}
class ACos extends Command {
override def getName(): String = "acos"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.acos(args(0))
}
class ATan extends Command {
override def getName(): String = "atan"
override def isValidArg0(n: Int): Boolean = n == 1 || n == 2
override def apply(args: Array[Type]): Type = {
if (args.length == 1) MathUtil.atan(args(0))
else MathUtil.atan(args(1), args(0))
}
}
class Sinh extends Command {
override def getName(): String = "sinh"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.sinh(args(0))
}
class Cosh extends Command {
override def getName(): String = "cosh"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.cosh(args(0))
}
class Tanh extends Command {
override def getName(): String = "tanh"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.tanh(args(0))
}
class ASinh extends Command {
override def getName(): String = "asinh"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.asinh(args(0))
}
class ACosh extends Command {
override def getName(): String = "acosh"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.acosh(args(0))
}
class ATanh extends Command {
override def getName(): String = "atanh"
override def isValidArg0(n: Int): Boolean = n == 1
override def apply(args: Array[Type]): Type = MathUtil.atanh(args(0))
}
5 changes: 4 additions & 1 deletion src/main/scala/util/BTI.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package util

import types.TMountain
import types._
import java.math.BigInteger

object BTI {
def bti(b: Boolean): TMountain = {
new TMountain(if (b) BigInteger.ONE else BigInteger.ZERO)
}
def btl(b: Boolean): THill = {
new THill(if (b) 1L else 0L)
}
}
69 changes: 69 additions & 0 deletions src/main/scala/util/CollectionOps.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package util
import types._
import java.math.BigInteger
import scala.collection.mutable._

object CollectionOps {
def decodeToList(t: Type): List[Type] = {
t match {
case t: TMountain => {
val n = t.getVal
List.range(0, n.bitCount).map(b => BTI.btl(n.testBit(b)))
}
case t: THill => {
val n = t.getVal
List.range(0, 64).map(b => BTI.btl((n & (1L << b)) != 0L))
}
case t: TString => {
t.getVal.toCharArray.toList.map(i => new THill(i))
}
case t: LList => {
t.l.toList
}
}
}
def encodeFromList(l: List[Type], mode: Int): Type = {
mode match {
case 1 => {
var n = BigInteger.ZERO
for (e <- l) {
e match {
case e: TNumerical => {
n = n.shiftLeft(1).add(BigInteger.valueOf(e.intValue))
}
case _ => return new TError(1)
}
}
TMountain(n)
}
case 2 => {
new THill(l.map(_ match {
case e: TNumerical => {
e.intValue
}
case _ => return new TError(1)
}).foldLeft(0L)((a, b) => (a << 1) + b))
}
case 3 => {
new TString(new String(l.map(_ match {
case e: TNumerical => {
e.intValue.toChar
}
case _ => return new TError(1)
}).toArray))
}
case 5 =>
new LArray(l.to[ArrayBuffer])
case 6 =>
new LLinked(l.to[ListBuffer])
}
}
def ctv[T](f: (List[Type]) => T): (Type) => T = {
(t: Type) =>
f(decodeToList(t))
}
def ctc(f: (List[Type]) => List[Type]): (Type) => Type = {
(t: Type) =>
encodeFromList(ctv(f)(t), t.getType)
}
}
42 changes: 40 additions & 2 deletions src/main/scala/util/MathUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,44 @@ object MathUtil {
else if (xt == 5 || xt == 6) mool(applyUnaryMath(f, _), x.asInstanceOf[LList])
else new TError(1)
}
def exp(x: Type): Type = applyUnaryMath(Math.exp(_), x)
def ln(x: Type): Type = applyUnaryMath(Math.log(_), x)
def sin(x: Type): Type = applyUnaryMath(Math.sin(_), x)
def cos(x: Type): Type = applyUnaryMath(Math.cos(_), x)
def tan(x: Type): Type = applyUnaryMath(Math.tan(_), x)
def csc(x: Type): Type = applyUnaryMath(1.0 / Math.sin(_), x)
def sec(x: Type): Type = applyUnaryMath(1.0 / Math.cos(_), x)
def cot(x: Type): Type = applyUnaryMath(1.0 / Math.tan(_), x)
def asin(x: Type): Type = applyUnaryMath(Math.asin(_), x)
def acos(x: Type): Type = applyUnaryMath(Math.acos(_), x)
def atan(x: Type): Type = applyUnaryMath(Math.atan(_), x)
def acsc(x: Type): Type = applyUnaryMath(y => Math.asin(1.0 / y), x)
def asec(x: Type): Type = applyUnaryMath(y => Math.acos(1.0 / y), x)
def acot(x: Type): Type = applyUnaryMath(Math.PI / 2 - Math.atan(_), x)
def sinh(x: Type): Type = applyUnaryMath(Math.sinh(_), x)
def cosh(x: Type): Type = applyUnaryMath(Math.cosh(_), x)
def tanh(x: Type): Type = applyUnaryMath(Math.tanh(_), x)
def csch(x: Type): Type = applyUnaryMath(1.0 / Math.sinh(_), x)
def sech(x: Type): Type = applyUnaryMath(1.0 / Math.cosh(_), x)
def coth(x: Type): Type = applyUnaryMath(1.0 / Math.tanh(_), x)
def asinh(x: Double) = Math.log(Math.hypot(1.0, x) + x)
def acosh(x: Double) = Math.log(Math.sqrt(Math.pow(x, 2) - 1.0) + x)
def atanh(x: Double) = 0.5 * (Math.log(x + 1) - Math.log(1 - x))
def asinh(x: Type): Type = applyUnaryMath(asinh(_), x)
def acosh(x: Type): Type = applyUnaryMath(acosh(_), x)
def atanh(x: Type): Type = applyUnaryMath(atanh(_), x)
def acsch(x: Type): Type = applyUnaryMath(y => asinh(1.0 / y), x)
def asech(x: Type): Type = applyUnaryMath(y => acosh(1.0 / y), x)
def acoth(x: Type): Type = applyUnaryMath(y => 0.5 * Math.log((y + 1)/(y - 1)), x)
def atan(x: Type, y: Type): Type = {
(x, y) match {
case (xl: LList, yl: LList) => motl(atan(_, _), xl, yl)
case (xl: LList, _) => mool(atan(_, _), xl, y)
case (_, yl: LList) => mool((a, b) => atan(b, a), yl, x)
case (x: TNumerical, y: TNumerical) => TFish(Math.atan2(y.doubleValue, x.doubleValue))
case _ => new TError(1)
}
}
def idivide(x: Type, y: Type): Type = {
val xt = x.getType; val yt = y.getType
if ((xt == 5 || xt == 6) && (yt == 5 || yt == 6)) motl(idivide, x.asInstanceOf[LList], y.asInstanceOf[LList])
Expand Down Expand Up @@ -289,7 +327,7 @@ object MathUtil {
(x, y) match {
case (xl: LList, yl: LList) => motl(shl(_, _), xl, yl)
case (xl: LList, _) => mool(shl(_, _), xl, y)
case (_, yl: LList) => shl(y, x)
case (_, yl: LList) => mool((a, b) => shl(b, a), yl, x)
case (xm: TMountain, ym: TNumerical) => {
new TMountain(xm.getVal.shiftLeft(ym.intValue))
}
Expand All @@ -306,7 +344,7 @@ object MathUtil {
(x, y) match {
case (xl: LList, yl: LList) => motl(shr(_, _), xl, yl)
case (xl: LList, _) => mool(shr(_, _), xl, y)
case (_, yl: LList) => shr(y, x)
case (_, yl: LList) => mool((a, b) => shr(b, a), yl, x)
case (xm: TMountain, ym: TNumerical) => {
new TMountain(xm.getVal.shiftRight(ym.intValue))
}
Expand Down
14 changes: 14 additions & 0 deletions src/main/scala/util/TurnOnSide.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package util
import types._

object TurnOnSide {
// Trying to write a generalized function drove me crazy.
def apply(mat: Array[List[Type]]): List[Array[Type]] = {
mat(0) match {
case Nil => Nil
case _ => {
mat.map(_.head) :: apply(mat.map(_.tail))
}
}
}
}

0 comments on commit 0133684

Please sign in to comment.