Created
July 19, 2011 06:24
-
-
Save oskimura/1091473 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //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