プログラミング言語「めうめう」

プログラミング言語「めうめう」

プログラミング言語「ほむほむ」のほむをめうに置換すればプログラミング言語「めうめう」ができるのではないか?という発想で
http://yuroyoro.hatenablog.com/entry/20110601/1306908421
https://gist.github.com/yuroyoro/1001863
こちらの記事の「ほむ」を「めう」に置換しただけのソースコードを貼ったので誰か実行してください。
内容は全く理解してないけど、val wToken = "めう".r 辺りがめうをgrassのwに読みかえてるんだろうな。

たぶん"Hello, world!"が出力されるであろうプログラム

めう
めう めう めうめうめうめう めう めうめうめうめうめうめう めうめうめうめうめう めう めうめうめうめうめう めうめうめうめう
めうめうめうめう めうめうめう めうめう めう めうめう めうめうめうめうめうめう めうめうめうめう めう めうめう
めう めうめう めう めう めうめう
めうめう めうめう めう
めう めうめうめう めうめう めうめうめうめうめう めうめうめう めう めうめう めうめうめうめうめうめう めう めうめうめうめうめうめうめう めう めうめうめうめう めう めうめうめうめうめう めう めうめうめうめうめうめう めう めうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめうめうめうめうめう めう めう めう めう めうめうめう めうめう めうめうめうめう めうめうめうめうめうめうめう めうめうめうめうめう めうめうめうめうめうめうめう めうめうめうめうめうめう めうめうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めう めうめうめうめうめうめうめうめうめうめうめうめうめう めう めうめうめうめうめうめう めうめう めうめうめうめうめうめう めうめうめう めうめうめうめうめうめう めうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めう めうめうめうめうめうめうめうめうめうめう めうめう めうめうめうめう めうめうめう めうめうめうめう めうめうめうめう めう めうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめう めう めう めうめうめう めうめう めう めうめうめう めう めうめうめうめう めう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めう めうめうめうめうめうめうめうめうめうめうめう めうめう めうめうめうめうめうめうめうめうめうめうめう めうめうめう めうめうめうめうめうめうめう めうめうめうめう めう めうめうめうめうめう めうめうめうめうめうめうめうめう めうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめうめうめうめうめうめう めうめうめうめうめうめうめうめう めう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめう めうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめう めうめうめうめうめうめうめうめう めうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう めうめうめうめうめうめう めうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめうめう

ソースコード


import java.io.File
import scala.io.Source
import scala.util.matching.Regex
import scala.util.parsing.combinator._
import scala.util.parsing.input.{Position, NoPosition}

sealed abstract class Insn extends ( CED => CED ){
val pos:Position
}
case class App( m:Int, n:Int, pos:Position ) extends Insn{
override def apply( ced:CED ) = ced.e( m - 1 )( ced.e( n - 1 ), ced )
override def toString = "App(%s,%s)".format(m, n)
}

case class Abs( m:Int, body:List[App] ,pos:Position ) extends Insn{
override def apply( ced:CED ) =
if( m == 1) CED( ced.c, Fn( body, ced.e ) :: ced.e, ced.d )
else CED( ced.c, Fn( Abs( m - 1, body, pos ) :: Nil, ced.e ) :: ced.e, ced.d )

override def toString = "Abs(%s)".format(m)
}

case class CED( c:List[Insn], e:List[Value], d:List[CE] )
case class CE( c:List[Insn], e:List[Value] )

class GrassRuntime( val insn:List[Insn], val source:String){

val e0 = Out :: Succ :: CharFn('w') :: In :: Nil
val d0 = CE(Nil, Nil) :: CE( App(1, 1, NoPosition) :: Nil, Nil) :: Nil

def run:Unit = {
var c = eval( CED( insn, e0, d0 ) )
while( c != None ){
val Some(m) = c
c = eval( m )
}
}

def eval( ced:CED ) = ced.c match {
case Nil => ced.d match {
case Nil => None
case x::xs => Some( CED( x.c, ced.e.head:: x.e , xs ))
}
case code :: remains => Some( code( CED( remains, ced.e, ced.d )) )
}
}

abstract class Value extends ( (Value, CED) => CED )

case class Fn(code : List[Insn], env : List[Value]) extends Value {
override def apply( v:Value, ced:CED ) = CED( code , v :: env, CE( ced.c, ced.e ) :: ced.d )
override def toString = "Fn"
}

case class CharFn(char : Char) extends Value {
val ChurchTrue = Fn( Abs( 1, App( 3, 2, NoPosition ) :: Nil, NoPosition ) :: Nil, Fn( Nil, Nil ) :: Nil )
val ChurchFalse = Fn( Abs( 1, Nil, NoPosition) :: Nil, Nil)

override def apply( v:Value, ced:CED ) = v match {
case CharFn( c ) => CED( ced.c, ced.e ::: ( if( char == c ) ChurchTrue else ChurchFalse ) :: Nil, ced.d )
case _ => throw new Exception("eval error value is not CharFn")
}
override def toString = "CharFn(%s, %s)".format( char , char.toInt)
}

object Succ extends Value {
override def apply( v:Value, ced:CED ) = v match {
case CharFn( c ) =>
val char = ( (c + 1) % 256 ).toChar
CED( ced.c, CharFn( char ) :: ced.e, ced.d )
case _ => throw new Exception("eval error value is not CharFn")
}
override def toString = "Succ"
}

object Out extends Value {
override def apply( v:Value, ced:CED ) = v match {
case CharFn( c ) =>
print(c)
CED( ced.c, v :: ced.e, ced.d )
case _ => throw new Exception("eval error value is not CharFn")
}
override def toString = "Out"
}
object In extends Value {
override def apply( v:Value, ced:CED ) ={
val c = readChar
CED( ced.c, CharFn( c ) :: ced.e, ced.d )
}
override def toString = "In"
}

object Home2LangParser extends RegexParsers{
import scala.util.parsing.input.CharSequenceReader._
override def skipWhitespace = false

val wToken = "めう".r
val sep = """[ \t]""".r
val fToken = rep1( sep ) ~> rep1(wToken) <~ rep1( sep ) ^^ { x => "W" * x.length }
val vToken = """\n""".r

def p(s:String):Parser[String] = s

def wrap[A](p: Parser[A]) = Parser{r => Success(r.pos, r)} ~ p

def w :Parser[String] = rep( comment ) ~> wToken <~ rep( comment )
def f :Parser[String] = rep( comment ) ~> fToken <~ rep( comment )
def v :Parser[String] = rep( comment ) ~> vToken <~ rep( comment )
val any :Parser[String] = elem("", _ != EofCh) ^^ { _.toString }

def token :Parser[String] = wToken ||| fToken ||| vToken
def comment :Parser[String] = not( token ) <~ any ^^ ( (Unit) => "" )

def app :Parser[App] = wrap( f ~ rep1( w ) ) ^^
{ case ~( p, x ~ y ) => App( x.size, y.size, p ) }

def abs :Parser[Abs] = wrap( rep1( w ) ~ rep( app ) ~ rep(v) ) ^^
{ case ~( p, ws ~ body ~ vs ) => Abs( ws.size, body, p ) }

def prog :Parser[List[Insn]] = rep( abs ) ~ rep( app ) ~ rep( v ) ^^
{ case a ~ p ~ v => a ::: p }

def parse( s:String ):Option[GrassRuntime] = parseAll( prog , s ) match {
case Success( insn, _ ) => Some( new GrassRuntime( insn, s ) )
case Failure( msg, _ ) => { println( msg ); None }
case Error( msg, _ ) => { println( msg ); None }
}
def run( s:String ) = parse( s ) foreach{ _.run }

def test( s:String ) = parse( s ) foreach{ r => dump( r.insn, 0 ) }

def dump( x:List[Insn] , n:Int ):Unit = {
val sp = (for( i <- 0 to n ) yield{ " " } ).mkString
x.foreach{ o => o match {
case Abs( i,b,_ ) => {
println( sp + "Abs( " + i + ")")
dump( b , n + 1 )
}
case App( i,j,_) => println( sp + "App( " + i + ", " + j + " )")
}}
}
}

class GrassParser(
wTokens:List[String],
fTokens:List[String],
vTokens:List[String]
)extends RegexParsers{
import scala.util.parsing.input.CharSequenceReader._
override def skipWhitespace = false

def p(s:String):Parser[String] = s
def make( tk:List[String] ) = ( p( tk.head ) /: tk.tail ){ _ ||| p( _ ) }

def wrap[A](p: Parser[A]) = Parser{r => Success(r.pos, r)} ~ p

def w :Parser[String] = rep( comment ) ~> ( make( wTokens ) ) <~ rep( comment )
def f :Parser[String] = rep( comment ) ~> ( make( fTokens ) ) <~ rep( comment )
def v :Parser[String] = rep( comment ) ~> ( make( vTokens ) ) <~ rep( comment )
val any :Parser[String] = elem("", _ != EofCh) ^^ { _.toString }

def token :Parser[String] = make( wTokens ) ||| make( fTokens ) ||| make( vTokens )
def comment :Parser[String] = not( token ) <~ any ^^ ( (Unit) => "" )

def app :Parser[App] = wrap( rep1( f ) ~ rep1( w ) ) ^^
{ case ~( p, x ~ y ) => App( x.size, y.size, p ) }

def abs :Parser[Abs] = wrap( rep1( w ) ~ rep( app ) ~ rep(v) ) ^^
{ case ~( p, ws ~ body ~ vs ) => Abs( ws.size, body, p ) }

def prog :Parser[List[Insn]] = rep( abs ) ~ rep( app ) ~ rep( v ) ^^
{ case a ~ p ~ v => a ::: p }

def parse( s:String ):Option[GrassRuntime] = parseAll( prog , s ) match {
case Success( insn, _ ) => Some( new GrassRuntime( insn, s ) )
case Failure( msg, _ ) => { println( msg ); None }
case Error( msg, _ ) => { println( msg ); None }
}
def run( s:String ) = parse( s ) foreach{ _.run }

def test( s:String ) = parse( s ) foreach{ r => dump( r.insn, 0 ) }

def dump( x:List[Insn] , n:Int ):Unit = {
val sp = (for( i <- 0 to n ) yield{ " " } ).mkString
x.foreach{ o => o match {
case Abs( i,b,_ ) => {
println( sp + "Abs( " + i + ")")
dump( b , n + 1 )
}
case App( i,j,_) => println( sp + "App( " + i + ", " + j + " )")
}}
}
}

object Main{
def main(args:Array[String]) = {

println()
println( "プログラミング言語 めうめう" )

println("-" * 80)
println( "print w" )
val printW = "めう めうめう めうめうめうめう"

println( "source code:")
println( " %s" format printW)
println()
println( "AST:")
Home2LangParser.test( printW )
println()
println( "Result:")
Home2LangParser.run( printW )
println()

println("-" * 80)
println( "print x" )
val printX ="めう めうめうめう めうめうめうめう めうめうめう めう"

println( "source code:")
println( " %s" format printX)
println()
println( "AST:")
Home2LangParser.test( printX )
println()
println( "Result:")
Home2LangParser.run( printX )
println()

println("-" * 80)
println( "Hello World" )
val hw = Source.fromFile(new File( "./home2lang.grass" )).mkString

println( "source code:")
println( " %s" format hw)
// println()
// println( "AST:")
// Home2LangParser.test( printX )
println()
println( "Result:")
Home2LangParser.run( hw)
println()
println("-" * 80)
}
}