Skip to content

Instantly share code, notes, and snippets.

@oskimura
Created July 19, 2011 06:24
Show Gist options
  • Select an option

  • Save oskimura/1091473 to your computer and use it in GitHub Desktop.

Select an option

Save oskimura/1091473 to your computer and use it in GitHub Desktop.
//import scala.collection.mutable.HashMap
//import scala.collection.mutable.Map
import scala.collection.mutable.Stack
import scala.util.parsing.combinator._
import scala.util.parsing.combinator.syntactical._
import scala.util.parsing.combinator.lexical._
//-------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
abstract class Instraction
case class POP[A] extends Instraction
case class PUSH extends Instraction
case class EXCH extends Instraction
case class ADD[A <: Int] extends Instraction
case class VAR extends Instraction
abstract class StackVal
case class StrVal[A <: String](v:A) extends StackVal
case class CharVal[A <: Char](v:A) extends StackVal
case class IntVal[A <: Int](v:A) extends StackVal
case class BoolVal[A <: Boolean](v:A) extends StackVal
case class RealVal[A <: Double](v:A) extends StackVal
case class Name(v:String) extends StackVal
case class Dict(m : Map[Name, StackVal]) extends StackVal
case class ArrayVal(v:List[StackVal]) extends StackVal
case class ExecArray[+Instr](v:List[Instr]) extends StackVal
case object Mark extends StackVal
case object Null extends StackVal
/*
type __0[f[_], x] = x
type __1[f[_], x] = f x
type __2[f[_], x] = f f x
*/
// type DictStack[A,B] =
//type Dict = Map[Name,StackVal]
//type Stack = List[StackVal]
//type Env = (Stack,Dict)
class C {
val m = new Stack(): Stack[Dict]
def push(d:Dict) {
m.push(d)
}
val pop = ()=>{ m.pop }
}
class DictionaryStack {
val m = new Stack(): Stack[Dict]
def push(d:Dict) {
m.push(d)
}
val pop = ()=>{ m.pop }
def lookup(n:Name){
val e = m.find( e => e.m.contains(n) )
e match {
case None => None
case Some(x) => Some(x.m.get(n))
}
}
}
class Enviroment {
val operand = new Stack(): Stack[StackVal]
val execute = new Stack(): Stack[StackVal]
val dictionary = new DictionaryStack(): DictionaryStack
//val curretnDictonary = new Stack() : Stack[Dict]
}
//-----------------------------------------------------------------------------
abstract class Instr
case object Pop extends Instr
case class Push(v:StackVal) extends Instr
case object Exch extends Instr
case object Dup extends Instr
case class If(c:BoolVal[Boolean], p:ExecArray[Instr]) extends Instr
case class IfElse(c:BoolVal[Boolean], tp:ExecArray[Instr], fp:ExecArray[Instr]) extends Instr
case class Exec(p:ExecArray[Instr]) extends Instr
case class Load(n:Name) extends Instr
case class Stor(n:Name, v:StackVal) extends Instr
case object Begin extends Instr
case object End extends Instr
case class Loop(p:ExecArray[Instr]) extends Instr
case object Exit extends Instr
case class Cvx(p:ExecArray[Instr]) extends Instr
case class Add(v1:IntVal[Int],v2:IntVal[Int]) extends Instr
case class Sub(v1:IntVal[Int],v2:IntVal[Int]) extends Instr
//-----------------------------------------------------------------------------------
object StackParser extends StandardTokenParsers {
lexical.reserved += ("true","false","if","exit","loop","pop","push","mark" )
lexical.delimiters +=(" ","/", "{","}","[","]", "<<", ">>" )
lazy val pop : Parser [Instr] = ("pop") ^^^ Pop
lazy val bool : Parser [StackVal] = ("true"|"false") ^^ { case "true" => BoolVal(true)
case "false" => BoolVal(false)
}
lazy val int : Parser[StackVal] = numericLit ^^ {case s => IntVal(s.toInt)}
lazy val value : Parser[StackVal] = (bool | int | str | mark | name | compval) //
lazy val str : Parser[StackVal] = stringLit ^^ {case s => StrVal(s.toString)}
lazy val push : Parser[Instr] = "push" ~> value ^^ { case v => Push(v)}
lazy val compval : Parser[StackVal] = (dict | array | execArray )
lazy val array : Parser[StackVal] = ("[" ~> rep(value) <~ "]") ^^ {case s => ArrayVal(s)}
lazy val execArray : Parser[ExecArray[Instr]] = "{" ~> terms <~ "}" ^^ {case s => ExecArray (s)}
lazy val if_ : Parser[Instr] = (bool ~ execArray <~ "if") ^^ {case BoolVal(b) ~ e => If(BoolVal(b),e) }
lazy val loop : Parser[Instr] = (execArray <~ "loop") ^^ {case e => Loop(e) }
lazy val exit : Parser[Instr] = ("exit") ^^^ {Exit}
lazy val mark : Parser[StackVal] = ("mark") ^^^ {Mark}
lazy val name : Parser[Name] = ("/" ~> ident) ^^ { case s => Name(s) }
lazy val pair : Parser[(Name, StackVal)] = (name ~ value) ^^ {case n ~ v => (n,v) }
lazy val dict : Parser[StackVal] = ("<<" ~> rep1(pair) <~ ">>") ^^ { case (xs) => Dict(xs.toMap) }
lazy val begin : Parser[Instr] = "begin" ^^^ {Begin}
lazy val end : Parser[Instr] = "end" ^^^ {End}
lazy val sym : Parser[StackVal] = ident ^^ { case s => Name(s) }
lazy val term : Parser[Instr] = (exit | begin | end | push | loop | if_)
lazy val compterm : Parser[Instr] = (if_)
lazy val terms : Parser[List[Instr]] = rep1(term)
def parse(text : String) : ParseResult[List[Instr]] = {
val scanner = new StackParser.lexical.Scanner(text)
val result = StackParser.terms(scanner);
result match {
case Success(result, x) => println("sucess : " ++ result.toString ++ " / "++ x.toString);
case Failure(msg, _) => println("failure : " ++ msg)
case Error(msg, _) => println("error : " ++ msg)
}
return result;
}
def parse2(text : String)(p : List[Instr]=>Unit) = {
val scanner = new StackParser.lexical.Scanner(text)
val result = StackParser.terms(scanner);
result match {
case Success(result, x) => println("sucess : " ++ result.toString ++ " / "++ x.toString);
p(result)
case Failure(msg, _) => println("failure : " ++ msg)
case Error(msg, _) => println("error : " ++ msg)
}
}
}
def parse(str:String) = {
StackParser.parse(str);
}
//-------------------------------------------------------------------------
object E {
def eval(i:Instr, e:Enviroment): Enviroment = {
println(i)
i match {
case Pop => e.operand.pop; e;
case Push(v) => ;println("push");e.operand.push(v) ; e;
case Exch => val v1 = e.operand.pop; val v2 = e.operand.pop;
e.operand.push(v1); e.operand.push(v2); e;
case Dup => val v1 = e.operand.pop; e.operand.push(v1); e;
case If(BoolVal(c),p) => if (c) e.execute.push(p); e;
case IfElse(BoolVal(c),p1,p2) => if (c) e.execute.push(p1) else e.execute.push(p2) ; e
// for dictionar stack
case Begin => e;e.operand.pop match {
case Dict(d) => e.dictionary.push(Dict(d)) ; e;
}
case End => e.dictionary.pop ;e;
// for execute stack
case Exec(p) => e.execute.push(p); e;
// loop proc
case Loop(p) => p match { case ExecArray(a) => val e_ = run(a,e) ; e_;}
case Exit => e.execute.pop;e.execute.pop; e;
//
//case Add(v1:IntVal[Int], v2:IntVal[Int]) => val v3 = v1 + v2; e.operand(IntVal(v3));e;
//case Sub(v1:IntVal[Int],v2:IntVal[Int]) => val v3 = v1 - v2; e.operand(IntVal(v3));e;
}
}
def run(is:List[Instr], e:Enviroment):Enviroment = {
if (is.isEmpty != true) {
val i = is.head
val e_ = eval(i,e);
run(is.tail,e_);
}
else e
}
def cvx(ps:List[StackVal]):ExecArray[Instr] = {
return ExecArray(ps.map((x)=> Push(x)))
}
}
def parse2(str:String) = {
val e = new Enviroment
StackParser.parse2(str)((x:List[Instr]) => {E.run(x,e);});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment