Skip to content

Commit

Permalink
Merge pull request #60 from MoeOrganization/prakashk/intclass-builtins
Browse files Browse the repository at this point in the history
arithmetic and relational operators on Ints
  • Loading branch information
Stevan Little committed Feb 25, 2013
2 parents 191dff1 + 0e950b6 commit 394cff8
Show file tree
Hide file tree
Showing 5 changed files with 523 additions and 11 deletions.
8 changes: 8 additions & 0 deletions src/main/scala/org/moe/interpreter/InterpreterUtils.scala
Expand Up @@ -218,5 +218,13 @@ object InterpreterUtils {
}
}

// perl modulo operator
def perlModuloOp(a: Int, b: Int): Int = {
val res = a % b
if (a < 0)
if (b > 0 && res < 0) res + b else res
else
if (b < 0) res + b else res
}
}

12 changes: 10 additions & 2 deletions src/main/scala/org/moe/parser/Expressions.scala
Expand Up @@ -14,7 +14,7 @@ trait Expressions extends Literals with JavaTokenParsers with PackratParsers {
(namespacedIdentifier <~ "{") ~
(expression <~ "}")

lazy val expression: PackratParser[AST] = addOp
lazy val expression: PackratParser[AST] = relOp | addOp

// This is what I want
// def binOpResult = { case left ~ op ~ right => MethodCallNode(left, op, List(right)) }
Expand All @@ -25,14 +25,22 @@ trait Expressions extends Literals with JavaTokenParsers with PackratParsers {
case left ~ op ~ right => MethodCallNode(left, "infix:<" + op + ">", List(right))
}| mulOp

lazy val mulOp: PackratParser[AST] = mulOp ~ "[*/]".r ~ simpleExpression ^^ {
lazy val mulOp: PackratParser[AST] = mulOp ~ "[*/%]".r ~ expOp ^^ {
case left ~ op ~ right => MethodCallNode(left, "infix:<" + op + ">", List(right))
} | expOp

lazy val expOp: PackratParser[AST] = rep1sep(simpleExpression, "**") ^^ {
xs => xs.reduceRight((left, right) => MethodCallNode(left, "infix:<**>", List(right)))
} | applyOp

lazy val applyOp: PackratParser[AST] = (mulOp <~ "->") ~ identifier ^^ {
case invocant ~ method => MethodCallNode(invocant, method, List())
} | simpleExpression

lazy val relOp: PackratParser[AST] = simpleExpression ~ "[<>]=?|[!=]=".r ~ simpleExpression ^^ {
case left ~ op ~ right => MethodCallNode(left, "infix:<" + op + ">", List(right))
}

lazy val simpleExpression: PackratParser[AST] = (
arrayIndex
| hashIndex
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/org/moe/parser/Literals.scala
Expand Up @@ -9,17 +9,17 @@ trait Literals extends Base {

// Numeric literals
def zeroNumber: Parser[IntLiteralNode] =
"""-?0""".r ^^ { n => IntLiteralNode(0) }
"""[\-+]?0""".r ^^ { n => IntLiteralNode(0) }
def intNumber: Parser[IntLiteralNode] =
"""-?[1-9][0-9_]*""".r ^^ { n => IntLiteralNode(formatInt(n)) }
"""[\-+]?[1-9][0-9_]*""".r ^^ { n => IntLiteralNode(formatInt(n)) }
def octIntNumber: Parser[IntLiteralNode] =
"""0[0-9_]+""".r ^^ { n => IntLiteralNode(formatOctal(n)) }
def hexIntNumber: Parser[IntLiteralNode] =
"""0x[0-9A-Fa-f_]+""".r ^^ { n => IntLiteralNode(formatHex(n)) }
def binIntNumber: Parser[IntLiteralNode] =
"""0b[01_]+""".r ^^ { n => IntLiteralNode(formatBin(n)) }
def floatNumber: Parser[FloatLiteralNode] =
"""-?[0-9_]*\.[0-9_]+([eE][\-+]?[0-9_]+)?""".r ^^ { n => FloatLiteralNode(formatFloat(n)) }
"""[\-+]?[0-9_]*\.[0-9_]+([eE][\-+]?[0-9_]+)?""".r ^^ { n => FloatLiteralNode(formatFloat(n)) }

// Boolean literals
def constTrue: Parser[BooleanLiteralNode] =
Expand Down
176 changes: 172 additions & 4 deletions src/main/scala/org/moe/runtime/builtins/IntClass.scala
Expand Up @@ -2,6 +2,7 @@ package org.moe.runtime.builtins

import org.moe.runtime._
import org.moe.runtime.nativeobjects._
import org.moe.interpreter.InterpreterUtils._

/**
* setup class Int
Expand All @@ -27,9 +28,24 @@ object IntClass {
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getInt(e.getCurrentInvocant.get.unboxToInt.get + i.unboxToInt.get)
case i: MoeIntObject => getInt(e.getCurrentInvocant.get.unboxToInt.get + i.unboxToInt.get)
case f: MoeNumObject => getNum(e.getCurrentInvocant.get.unboxToDouble.get + f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<->",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getInt(e.getCurrentInvocant.get.unboxToInt.get - i.unboxToInt.get)
case f: MoeNumObject => getNum(e.getCurrentInvocant.get.unboxToDouble.get - f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
Expand All @@ -42,9 +58,161 @@ object IntClass {
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getInt(e.getCurrentInvocant.get.unboxToInt.get * i.unboxToInt.get)
case i: MoeIntObject => getInt(e.getCurrentInvocant.get.unboxToInt.get * i.unboxToInt.get)
case f: MoeNumObject => getNum(e.getCurrentInvocant.get.unboxToDouble.get * f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:</>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getNum(e.getCurrentInvocant.get.unboxToInt.get / i.unboxToInt.get.toDouble)
case f: MoeNumObject => getNum(e.getCurrentInvocant.get.unboxToDouble.get / f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<%>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getInt(perlModuloOp(e.getCurrentInvocant.get.unboxToInt.get, i.unboxToInt.get))
case f: MoeNumObject => getInt(perlModuloOp(e.getCurrentInvocant.get.unboxToDouble.get.toInt, f.unboxToDouble.get.toInt))
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<**>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getInt(Math.pow(e.getCurrentInvocant.get.unboxToInt.get, i.unboxToInt.get).toInt)
case f: MoeNumObject => getNum(Math.pow(e.getCurrentInvocant.get.unboxToInt.get, f.unboxToDouble.get))
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

// relational operators

intClass.addMethod(
new MoeMethod(
"infix:<<>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getBool(e.getCurrentInvocant.get.unboxToInt.get < i.unboxToInt.get)
case f: MoeNumObject => getBool(e.getCurrentInvocant.get.unboxToDouble.get < f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<<>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getBool(e.getCurrentInvocant.get.unboxToInt.get < i.unboxToInt.get)
case f: MoeNumObject => getBool(e.getCurrentInvocant.get.unboxToDouble.get < f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<>>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getBool(e.getCurrentInvocant.get.unboxToInt.get > i.unboxToInt.get)
case f: MoeNumObject => getBool(e.getCurrentInvocant.get.unboxToDouble.get > f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<<=>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getBool(e.getCurrentInvocant.get.unboxToInt.get <= i.unboxToInt.get)
case f: MoeNumObject => getBool(e.getCurrentInvocant.get.unboxToDouble.get <= f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<>=>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getBool(e.getCurrentInvocant.get.unboxToInt.get >= i.unboxToInt.get)
case f: MoeNumObject => getBool(e.getCurrentInvocant.get.unboxToDouble.get >= f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<==>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getBool(e.getCurrentInvocant.get.unboxToInt.get == i.unboxToInt.get)
case f: MoeNumObject => getBool(e.getCurrentInvocant.get.unboxToDouble.get == f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
)

intClass.addMethod(
new MoeMethod(
"infix:<!=>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
{ (e) =>
e.get("$other").get match {
case i: MoeIntObject => getBool(e.getCurrentInvocant.get.unboxToInt.get != i.unboxToInt.get)
case f: MoeNumObject => getBool(e.getCurrentInvocant.get.unboxToDouble.get != f.unboxToDouble.get)
case _ => throw new MoeErrors.UnexpectedType(e.get("$other").get.toString)
}
}
)
Expand Down

0 comments on commit 394cff8

Please sign in to comment.