うはwww Scala で Grass を実装してみたwwwwwwww
Scalaの勉強がてら ちょっと草植えときますね型言語 Grass を実装してみましたwwwwwww
今更感が今更だけど大自然の意志には逆らえないwwwwwww
_, ._
( ・ω・) んも〜
○={=}〇,
|:::::::::\, ', ´
、、、、し 、、、(((.@)wvwwWWwvwwWwwvwwwwWWWwwWw
事前目標
コード
class Grass { class CED(c :List[Insn], e :List[Value], d :List[CE]) { val code = c val env = e val dump = d } class CE(c :List[Insn], e :List[Value]) { val code = c val env = e } val ENV = List[Value](In, CharFn('w'), Succ, Out) val DUMP : List[CE] = List(new CE(Nil, Nil), new CE(List(App(1, 1)), Nil)) def run(str : String) : Unit = evalGrass(new CED(parse(str), ENV, DUMP)) def evalGrass(ced :CED) : Unit = { def loop(ced :CED) : CED = ced.code match { case head::tail => loop(eval(head, new CED(tail, ced.env, ced.dump))) case Nil => if (!ced.dump.isEmpty) { loop(new CED(ced.dump.last.code, ced.dump.last.env:::List(ced.env.last), ced.dump.slice(0, ced.dump.length-1))) } else { null } } loop(ced) } val PATTERN_ABS = "^(w+)(.*)".r val PATTERN_APP = "^(W+)(w+)(.*)".r def parse(src : String) : List[Insn] = { normalize(src).split("v").toList.flatMap(_ match { case PATTERN_ABS(x, y) => List(Abs(x.length, parseBody(y))) case PATTERN_APP(m, n, body) => App(m.length, n.length)::parseBody(body) case _ => throw new Exception("parse error") }) } def normalize(s : String) = { "[^wWv]".r.replaceAllIn( "\\A[^w]*".r.replaceFirstIn( s.replaceAll("w", "w"). replaceAll("W", "W"). replaceAll("v", "v"), ""), "") } def parseBody(src : String) : List[Insn] = { def _parseBody(src : String, code : List[Insn]) : List[Insn] = src match { case PATTERN_APP(m, n, body) => _parseBody(body, code:::List(App(m.length, n.length))) case _ => code } _parseBody(src, Nil) } abstract class Insn case class App(m :Int, n :Int) extends Insn case class Abs(n :Int, code :List[Insn]) extends Insn def eval(insn :Insn, ced :CED) : CED = insn match { case App(m, n) => app(ced.env(ced.env.length - m), ced.env(ced.env.length - n), ced) case Abs(1, c) => new CED(ced.code, ced.env:::List(Fn(c, ced.env)), ced.dump) case Abs(n, c) => new CED(ced.code, ced.env:::List(Fn(List(Abs(n - 1, c)), ced.env)), ced.dump) } abstract class Value case class Fn(code : List[Insn], env : List[Value]) extends Value { override def toString() :String = "Fn" } case class CharFn(char : Char) extends Value case object Succ extends Value case object Out extends Value case object In extends Value val ChurchTrue = Fn(List(Abs(1, List(App(3, 2)))), List(Fn(Nil, Nil))) val ChurchFalse = Fn(List(Abs(1, Nil)), Nil) def app(v :Value, arg :Value, ced :CED) : CED = v match { case Fn(c, e) => new CED(c, e:::List(arg), ced.dump:::List(new CE(ced.code, ced.env))) case CharFn(char) => new CED(ced.code, ced.env:::List(if (char == getChar(arg)) ChurchTrue else ChurchFalse), ced.dump) case Succ => new CED(ced.code, ced.env:::List(CharFn(((getChar(arg) + 1) % 256).asInstanceOf[Char])), ced.dump) case Out => System.out.print(getChar(arg)) System.out.flush() new CED(ced.code, ced.env:::List(arg), ced.dump) case In => new CED(ced.code, ced.env:::List(CharFn(System.in.read().asInstanceOf[Char])), ced.dump) } def getChar(v :Value) : Char = v match { case CharFn(char) => char case _ => throw new Exception("eval error at getChar") } }
100行ぐらいに収まりました。
実行例
object Main { def main(args : Array[String]) = { var grass = new Grass() // w grass.run("wWWwwww") println() // x grass.run("wWWWwwwwWWWw") println() // ww grass.run("wwWWwvwwwwWWWwwWwwWWWWWWwwwwWwwvwWWwwwWwwwwWwwwwwwWwwwwwwwww") println() // Hello, world! grass.run("wvwWwwwwWwwwwwwWWWWWwWWWWWwwwwvwwwwWWWwwWwwWWWWWWwwwwWwwvwWW" + "wWwwvwwWWwvwWWWwwWWWWWwwwWwwWWWWWWwWWWWWWWwWWWWwWWWWWwWWWWWW" + "wWWWWWWWWWWWWWWwwwwwwwwWwWwWWWwwWWWWwwwwwwwWWWWWwwwwwwwWWWWW" + "WwwwwwwwWWWWWWWWWWWWWWWWWWWWWwwwwwwwwwwwwwwwwwwwwwWwwwwwwwww" + "wwwwwwwwwwwWwwwwwwwwwwwwwWwwwwwwWWwwwwwwWWWwwwwwwWWWWWWwwwww" + "wwwwwwwwwwwwwwwWwwwwwwwwwwWWwwwwWWWwwwwWWWWwWWWWWwwwwwwwwwww" + "wwwwwwwWWWWWWWWWWWwWwwwWWwWWWwWWWWwWWWWWWWWWWWWWWWWWwwwwwwww" + "wwwwwwwwwWwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwWwwwwwwwwwww" + "WWwwwwwwwwwwwWWWwwwwwwwWWWWwWWWWWwwwwwwwwWWWWWWwwwwwwwwwwwww" + "wwwwwwwwWWWWWWWwwwwwwwwwwwwwwwwwwwwwwwwwwwwWWWWWWWWWwwwwwwww" + "WwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwWWwwwwwwwwwwwwwWWWwwwwwwwww" + "wwwwWWWWwwwwwwwwWWWWWwwwwwwwwwwwwwwwwwwwwwwwwwwWWWWWWwwwwwww" + "wwwwwwwwwwwwwwwwww") } }
芝が広がりんぐwwwwwww