Skip to content

Instantly share code, notes, and snippets.

@VienosNotes
Created November 23, 2012 10:30
Show Gist options
  • Select an option

  • Save VienosNotes/4134968 to your computer and use it in GitHub Desktop.

Select an option

Save VienosNotes/4134968 to your computer and use it in GitHub Desktop.
Perl6で単純な命令列を実行するインタプリタ
use v6;
role Value[::Type] {
has Type $.value;
has @.exp;
multi method new (Type $v, @exp) {
self.bless(*, value => $v, exp => @exp);
}
}
role BinOp {
method f ($p1, $p2) { ... }
method apply ($v1, $v2) {
return Value[Any].new(self.f($v1.value, $v2.value), [self, [$v1.exp], [$v2.exp]]);
}
}
role Literal[::Type] { }
constant Plus = (anon class Plus { method f (Int $p1, Int $p2) { $p1 + $p2 }}) but BinOp;
constant Minus = (anon class Minus { method f (Int $p1, Int $p2) { $p1 - $p2 }}) but BinOp;
constant Mult = (anon class Mult { method f (Int $p1, Int $p2) { $p1 * $p2 }}) but BinOp;
constant Div = (anon class Div { method f (Int $p1, Int $p2) { $p1 / $p2 }}) but BinOp;
constant And = (anon class And { method f (Bool $p1, Bool $p2) { $p1 && $p2 }}) but BinOp;
constant Or = (anon class Or { method f (Bool $p1, Bool $p2) { $p1 || $p2 }}) but BinOp;
constant IntLit = (anon class IntLit {}) but Literal[Int];
constant BoolLit = (anon class BoolLit {}) but Literal[Bool];
proto sub evaluate () {*}
multi sub evaluate ([BinOp $op, $e1, $e2]) {
my ($v1, $v2) = ((evaluate $e1), (evaluate $e2));
return $op.apply($v1, $v2);
}
multi sub evaluate ([Literal $t, $l]) {
return Value[$l].new($l, [$t, $l]);
}
multi sub evaluate (*@_) {
fail "Unknown instruction \"@_[0]\"";
}
say evaluate [Plus, [IntLit, 1], [IntLit, 2]];
say evaluate [And, [BoolLit, True], [Or, [BoolLit, False], [BoolLit, True]]];
# output:
# % perl6 evaluate.pl
# Value.new(value => 3, exp => Array.new(Plus+{BinOp}, [IntLit+{Literal}, 1], [IntLit+{Literal}, 2]))
# Value.new(value => Bool::True, exp => Array.new(And+{BinOp}, [BoolLit+{Literal}, Bool::True], [Or+{BinOp}, [BoolLit+{Literal}, Bool::False], [BoolLit+{Literal}, Bool::True]]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment