- //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);});
- }