東北

http://groups.google.co.jp/group/scala-tohoku/web/%E3%81%BF%E3%82%93%E3%81%AA%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89?hl=ja


今回は準備不足で、何も出来ず。グフっ!っていうかんじでした。
言い訳すると、telnetcygwinにインストールできなくて、終わったんです。
情けない。


書いてたソースは簡単に、計算するだけのインタプリタで、なんもしてなくて、
JavaScalaと比較するとこれだけ違うよって話をしようかと思ってました。


これを、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)
    }
}