東北
今回は準備不足で、何も出来ず。グフっ!っていうかんじでした。
言い訳すると、telnetをcygwinにインストールできなくて、終わったんです。
情けない。
書いてたソースは簡単に、計算するだけのインタプリタで、なんもしてなくて、
JavaとScalaと比較するとこれだけ違うよって話をしようかと思ってました。
これを、stackマシンとかにしたほうがいいのかなぁ???
っていうかんじだったのですけども、まぁいいやっと。
Case.scala
abstract class Atom case class Var(value: int) extends Atom case class Add(left:Atom, right:Atom) extends Atom case class Mul(left:Atom, right:Atom) extends Atom object Case { def main(args: Array[String]) = { val exp = Add(Var(1),Var(2)) println(exp) println(eval(exp)) } def eval(exp:Atom):int = { exp match { case Var(a) => a case Add(a,b) => eval(a) + eval(b) case Mul(a,b) => eval(a) * eval(b) } } }
Case.rb
class Var attr_accessor :value def initialize(value) @value = value end def to_s () return "Var(" + @value.to_s + ")" end end class Add attr_accessor :left attr_accessor :right def initialize(left, right) @left = left @right = right end def to_s return "Add("+@left.to_s+","+@right.to_s+")" end end class Mul attr_accessor :left attr_accessor :right def initialize(left,right) @left = left @right = right end def to_s () return "Mul("+@left.to_s+","+@right.to_s+")" end end def eval(exp) case exp when Var then exp.value when Add then eval(exp.left) + eval(exp.right) when Mul then eval(exp.left) + eval(exp.right) else raise "error" end end exp = Add.new(Var.new(1), Var.new(2)) puts(exp) puts(eval(exp))
Case.java
class Atom{} class Var extends Atom { int value; Var(int value) { this.value = value; } public String toString() { return "Var("+value+")"; } } class Add extends Atom { Atom left; Atom right; Add(Atom left, Atom right) { this.left = left; this.right = right; } public String toString() { return "Add("+left+","+right+")"; } } class Mul extends Atom { Atom left; Atom right; Mul(Atom left, Atom right) { this.left = left; this.right = right; } public String toString() { return "Mul("+left+","+right+")"; } } class Case { public static void main(String[] argv) throws Exception { Atom exp = new Add(new Var(1), new Var(2)); System.out.println(exp); System.out.println(eval(exp)); } public static int eval(Atom exp) throws Exception { if(exp instanceof Var) { Var var = (Var)exp; return var.value; } if(exp instanceof Add) { Add add = (Add)exp; return eval(add.left) + eval(add.right); } if(exp instanceof Mul) { Mul mul = (Mul)exp; return eval(mul.left) + eval(mul.right); } throw new Exception("error"); } }
簡単な、スタックマシン
SC.scala
abstract class Atom case class Var(value: int) extends Atom case class Add(left:Atom, right:Atom) extends Atom case class Mul(left:Atom, right:Atom) extends Atom object SC { var i = 0 val VAL, ADD, MUL, RET = {i += 1; i} def main(args: Array[String]) = { try { val exp = Mul(Add(Var(1),Var(2)),Var(3)) println(exp) println(compile(exp)) println(eval(compile(exp))) } catch { case e => println(e) } } def compile(exp:Atom) = { def comp(exp:Atom):List[int] = { exp match { case Var(a) => List(VAL,a) case Add(a,b) => comp(a) ::: comp(b) ::: List(ADD) case Mul(a,b) => comp(a) ::: comp(b) ::: List(MUL) } } comp(exp):::List(RET) } def eval(c:List[int]):int = { def eval1(s:List[int], c:List[int]):int = { (s,c) match { case (s, VAL::a::c) => eval1(a::s, c)// 値 case (a::b::s, ADD::c) => eval1((a+b)::s, c)// 足し算 case (a::b::s, MUL::c) => eval1((a*b)::s, c)// 掛け算 case (a::s, RET::c) => a// リターン case (_, _) => throw new Exception("runtime error") } } eval1(List():List[int], c) } }