Skip to content

Instantly share code, notes, and snippets.

@oskimura
Created July 22, 2011 10:13
Show Gist options
  • Select an option

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

Select an option

Save oskimura/1099203 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
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))
}
}
override def toString():String = {
return m.toString()
}
}
//-----------------------------------------------------------------------------
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
//---------------------------------------------------------------------------
class Enviroment {
val operand = new Stack(): Stack[StackVal]
val execute = new Stack(): Stack[Instr]
val dictionary = new DictionaryStack(): DictionaryStack
def pushExec(a: ExecArray[Instr]) = {
a match {
case ExecArray(is:List[Instr]) => for (i <- is) {execute.push(i)}
case _ => println("abort")
}
}
def print() = {
println("op " ++ operand.toString())
println("exe " ++ execute.toString())
println("dict " ++ dictionary.toString())
}
}
//-----------------------------------------------------------------------------------
object StackParser extends StandardTokenParsers {
lexical.reserved += ("true","false","if","exit","loop","pop","push","mark" , "add", "sub")
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 add : Parser[Instr] =
(int ~ int <~ "add") ^^
{case n1 ~ n2 => (n1,n2) match {case (n1:IntVal[Int],n2:IntVal[Int]) => Add(n1,n2) } }
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 | pop | add | 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);
}
def exit_(e: Enviroment):Enviroment = {
e.execute.pop match {
case Loop(p) => return e;
case _ => return exit_(e)
}
}
//-------------------------------------------------------------------------
object E {
def eval(i:Instr, e:Enviroment): Enviroment = {
// def exe(a:List[Instr]) : {}
println(i)
i match {
case Pop =>
e.operand.pop; e.print;
case Push(v) =>
println("push");e.operand.push(v) ; e.print;
case Exch =>
val v1 = e.operand.pop; val v2 = e.operand.pop;
e.operand.push(v1); e.operand.push(v2);
case Dup =>
val v1 = e.operand.pop; e.operand.push(v1);
case If(BoolVal(c),p) =>
if (c) e.pushExec(p)
e.print;
case IfElse(BoolVal(c),p1,p2) =>
if (c) {e.pushExec(p1)}
else {e.pushExec(p2)}
// for dictionar stack
case Begin =>
e;e.operand.pop match {
case Dict(d) => e.dictionary.push(Dict(d)) ;
}
case End =>
e.dictionary.pop ;
// for execute stack
case Exec(p:ExecArray[Instr]) =>
e.pushExec(p);
// loop proc
case Loop(p) =>
e.execute.push(Loop(p));e.pushExec(p) ; e.print;
case Exit =>
exit_(e); e.print;
/*
case Add(v1:IntVal[Int], v2:IntVal[Int]) =>
(v1,v2) match { case (IntVal (n1),IntVal(n2)) => e.operand(IntVal[Int](n2+n1)); }
e;
*/
//case Sub(v1:IntVal[Int],v2:IntVal[Int]) => val v3 = v1 - v2; e.operand(IntVal(v3));e;
case _ => println("this instruction not implements " ++ i.toString ++ " .");
}
return e;
}
def run(e:Enviroment):Enviroment = {
println("run")
if (!e.execute.isEmpty) {
val i = e.execute.pop;
println(i)
val e2 = eval(i,e)
return run(e2);
}
return e
}
def parse2(str:String) = {
val e = new Enviroment
StackParser.parse2(str)((x:List[Instr]) => { e.pushExec(ExecArray(x)); run(e);});
}
def cvx(ps:List[StackVal]):ExecArray[Instr] = {
return ExecArray(ps.map((x)=> Push(x)))
}
}
def parse2(str:String) = {
E.parse2(str);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment