Skip to content

Instantly share code, notes, and snippets.

@beala
Created April 4, 2012 23:24
Show Gist options
  • Save beala/2306531 to your computer and use it in GitHub Desktop.
Save beala/2306531 to your computer and use it in GitHub Desktop.
Interpreter in Smalla
/* 8*7 */
val input1: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:8, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](Times:()), r:-7}
in
/* 0>10 */
val input2: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:0, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](Gt:()), r:10}
in
/* 10+10 */
val input3: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:10, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](Plus:()), r:10}
in
/* 10==10 */
val input4: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:10, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](Eq:()), r:10}
in
/* 1<10 */
val input5: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:1, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](Lt:()), r:10}
in
/* !1 */
val input6: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:0, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](Not:()), r:1}
in
/* 0 && 1 */
val input7: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:0, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](And:()), r:1}
in
/* 0 || 1 */
val input8: {l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int} =
{l:0, op:inj[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit](Or:()), r:1}
in
/* Converts an Int to Boolean */
def itob(i:Int):Boolean = if (i==0) false else true
in
/* Recrusively multiplies two positive numbers */
def mult(l:Int):Int=>Int=>Int =
(r:Int)=>(a:Int)=>
if (r<1)
a
else
mult(l)(r-1)(l+a)
in
/* Wrapper for mult. Accepts negative or positive */
def multiply(l:Int):Int=>Int =
(r:Int)=>
if ((l<0) && (r<0)){
mult(-l)(-r)(0)
}else{
if (l<0){
-mult(-l)(r)(0)
}else{
if (r<0){
-mult(l)(-r)(0)
}else{
mult(l)(r)(0)
}
}
}
in
def eval(e:{l:Int, op:[Plus:Unit, Minus:Unit, Times:Unit, Eq:Unit, Lt:Unit, Gt:Unit, Not:Unit, And:Unit, Or:Unit], r:Int}):[I:Int, B:Boolean, U:Unit] = e.op match[[I:Int, B:Boolean, U:Unit]] {
case Plus:nil => inj[I:Int, B:Boolean, U:Unit](I: (e.l+e.r))
case Minus:nil => inj[I:Int, B:Boolean, U:Unit](I: (e.l-e.r))
case Times:nil => inj[I:Int, B:Boolean, U:Unit](I: multiply(e.l)(e.r))
case Eq:nil => inj[I:Int, B:Boolean, U:Unit](B: (e.l==e.r))
case Lt:nil => inj[I:Int, B:Boolean, U:Unit](B: (e.l<e.r))
case Gt:nil => inj[I:Int, B:Boolean, U:Unit](B: (e.r<e.l))
case Not:nil => inj[I:Int, B:Boolean, U:Unit](B: (!itob(e.r)))
case And:nil => inj[I:Int, B:Boolean, U:Unit](B: (itob(e.l) && itob(e.r)))
case Or:nil => inj[I:Int, B:Boolean, U:Unit](B: (itob(e.r) || itob(e.l)))
}
in
/* Print the union type returned by eval */
def printVal(v:[I:Int, B:Boolean, U:Unit]):Unit = v match[Unit] {
case I:i => print(i)
case B:b => print(b)
case U:u => print(u)
}
in
/* Run tests */
{
printVal(eval(input1));
printVal(eval(input2));
printVal(eval(input3));
printVal(eval(input4));
printVal(eval(input5));
printVal(eval(input6));
printVal(eval(input7));
printVal(eval(input8))
}
/**************
Expected output:
-56
false
20
true
true
false
false
true
Value:
()
***************/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment