Hatena::Grouprubyist

たばさの RSSフィード

11/29(木) 2007

interpreter in ruby 見つからない

|  interpreter in ruby 見つからない - たばさの を含むブックマーク はてなブックマーク -  interpreter in ruby 見つからない - たばさの

where is the interpreter in ruby?

公式にperlはある *1

書き換えればいいんじゃね

...分からないとこがある。ていうか、perl書けない。

新言語習得のモチベーション維持のため始めた golf でどうにか51言語エントリー。しかし大半は付け焼刃のプリント文だけとかなのだ。それすら難しい言語もあったけど。


ということで、whitespace interpreter in perl を動かすためだけに perl を久々に入れた。

loop

|  loop - たばさの を含むブックマーク はてなブックマーク -  loop - たばさの

ん、いじっていたらミスのせいでループした

[lf][sp][lf][lf]

ラベルなしのジャンプで先頭に?。golfのほう(timeout)ではエラー,残念。

interpreterのバグか そもそも仕様がない?

loopしたり

| loopしたり - たばさの を含むブックマーク はてなブックマーク - loopしたり - たばさの

C で書いた Whitespace インタプリタ あった http://shinh.skr.jp/koneta/

borland c でコンパイルしたら「おそらく不正な代入」といわれた。おそらくって。

test1.ws.txt

適当なsample


[print "test of non-whitespace"]
[print]
[label "top"]
[push 10]
[print "times start"]
[print]

[3 times]      tend までを10回繰り返し
	[print "times"]
	[call "inc_pr"] ...//4掛けて1足して足してプリント
	[call "inc_pr"] くくらないものはすべてコメント
	[call "inc_pr"] なんかかっこわるい
	[call "inc_pr"]
[tend]

[print "tend.."]
[call "inc_pr"]
[call "inc_pr"]
[print "続き"]
[call "inc_pr"]
[くくっても解析できなければコメント扱い]
[call "inc_pr"]
[print]
[goto "end"]
[//]


[label "inc_pr"]
	[push 4]
	[/print "this is comment out"]
	[*]
	[++]
	[/dup]
	[call 111]
	[ret]


[label "test_label"]
[label 111]
	[dup]
	[outnum] スタックにある数をプリント
	[print]   改行する
	[ret]
	
	
[label "end"]
	[print 1234567890123456789]
	[print]
	[print "end of test."]
	[exit]
	

実行結果

 >-ws.bat test1.ws.txt ((debug はうしろに適当な引数を))
test of non-whitespace
times start
times41
165
661
2645
times10581
42325
169301
677205
times2708821
10835285
43341141
173364565
tend..693458261
-1521134251
続き-1789569707
1431655765

-35028715
end of test.


…というふうにするためのファイルたち。

実行にはwindows、 whitespace.plなどのインタプリタなどが必要です。

おまけで作った times..tend loop は変換前のコードをコピーしてるので遅い。


# ws-comp.rb
# ver. '071129

# no-whitespace 2 ws
# [sp][tab][lf] etc. can be used.
#
# commands...
#
# [120] integer 120
# ['a] char 'a'
# [print] kaigyo print
# ["str"] string
# [print "str"] str print
# [print 123] int print
# [putc a] one char print
# [+] 2stack_val.add
# [-] 2stack_val.sub
# [push 123]
# [outchr]
# [label 1234] label, by number
# [call 1234] call, by number
# [label "string"] label, by double-quoted string
# [call "string"] call, by double-quoted string
# [jpifzero "label"] jump if stack is zero, to label
# [jpifne "label"] jump if stack is negative, to label
#
# and right words in the array in ws-comlist.rb


$sp=" "
$tb="\t"
$lf="\x0a"

require "ws-comlist"

$debug =(ARGV[2]==nil)

def strfrom01 bits
 s=bits.gsub("1","[t]").gsub("0","[s]")+"[l]"
 s
end

def trans n, wo
  from,to = 1,0
  wo.gsub!($w[n][from],$w[n][to])
  wo
end

def delcomment wo
  from,to = 1,0
  (
    wo.gsub!("\n",'')  
    wo.sub!(/^([^\[\n]*)/,'')     # line-top is not "["
    wo.gsub!(/\]([^\[\n]*)/,']')  # outside of []
  )
  wo
end

def delnotws wo
 p wo if $debug
 wo.gsub!(/\[[^\[\n]*\]/,'') 
 p "translating end", wo if $debug
 wo
end

def chr01x8 ch
 a="00000000"+ch.to_s(2)
 a[-8,8]
end

def strby8bit str
 a=""
 str.each_byte{|i|
  a<<chr01x8(i)
 }
 strfrom01(a)
end

def zeroone2SpTb zeroone
 zeroone.gsub!("1","[t]").gsub!("0","[s]")
end

def ws_print ch
 "[S][S][S]"+"[#{ch}]"+"[T][L][S][S]"
end
def ws_printnum ch
 "[S][S][S]"+"[#{ch}]"+"[T][L][S][T]"
end

def printcalc d
 while 1
  /\[ *(print) *\]/ =~ d
  return d if $1==nil
  ahead=$` 
  alast=$'
  d = ahead +"[print\"\n\"]" +alast
 end
end

def str2SpTb str
  a=""
  str.each_byte{|ch|
  a<< chr01x8(ch)
  }
  zeroone2SpTb  a
end

def strcalc d
 while 1
  /\[ *"([^"]+)" *\]/ =~ d
  return d if $1==nil
  a =str2SpTb $1
  ahead=$` 
  alast=$'
  d = ahead +a+"[l]" +alast
 end
end

def keyAndStrCalc key, keySTL, data
 while 1
  /\[ *#{key} *("[^"]+") *\]/ =~ data
  return data if $1==nil
  a=$1
  ahead=$` 
  alast=$'
  data = ahead +keySTL +"[" +a +"]" +alast
 end
end


# [10 times](content)[tend]  =>  (content) * 10
def timescalc data
 while 1
  /\[ *([0-9]+) *times *\]/ =~ data
  return data if $1==nil
  count=$1.to_i
  ahead=$` 
  alast=$'
  /(\[ *tend *\])/ =~ alast
  return data if $1==nil
  content =$`
  alast=$'
  data = ahead + (content *count) +alast
 end
end



def printstrcalc d
 while 1
  /\[ *print *"([^"]+)" *\]/ =~ d
  #p $1
  return d if $1==nil
  a=""
  $1.each_byte{|i|
  a<< ws_print(i)
  }
  ahead=$` 
  alast=$'
  d = ahead +a +alast
 end
end

def gotocalc d
 keyAndStrCalc "goto", "[l][s][l]", d
end

def printnumcalc d
 while 1
  /\[ *print *([0-9]+) *\]/ =~ d
  #p $1
  return d if $1==nil
  ahead=$` 
  alast=$'
  d = ahead +ws_printnum($1) +alast
 end
end

def putccalc d
 while 1
  /\[ *putc *(.) *\]/ =~ d
  return d if $1==nil
  ahead=$` 
  alast=$'
  d = ahead +ws_print($1[0]) +alast
 end
end

def numcalc d
 while 1
  /\[([0-9]+)\]/ =~ d
  return d if $1==nil
  a="0"+$1.to_i.to_s(2)
  ahead=$` 
  alast=$'
  a =zeroone2SpTb a
  d = ahead +a +"[lf]" +alast
 end
end

def charcalc d
 while 1
  /\['(.)\]/ =~ d
  return d if $1==nil
  a=$1[0].to_s(2)
  ahead=$` 
  alast=$'
  a =zeroone2SpTb a
  d = ahead +a +"[lf]" +alast
 end
end

def pushcalc d
 while 1
  /\[ *push *([0-9]+) *\]/ =~ d
  return d if $1==nil
  a=$1
  ahead=$` 
  alast=$'
  d = ahead +"[s][s]["+a +"]" +alast
 end
end

def labelnumcalc d
 while 1
  /\[ *label *([0-9]+) *\]/ =~ d
  return d if $1==nil
  a=$1
  ahead=$` 
  alast=$'
  d = ahead +"[l][s][s]" +"["+a+"]"+alast
 end
end

def oldlabelchrcalc d
 while 1
  /\[ *label *"([^"]+)" *\]/ =~ d
  return d if $1==nil
  a=strby8bit($1)
  ahead=$` 
  alast=$'
  d = ahead +"[l][s][s]" +a +alast
 end
end

def callchrcalc d
 while 1
  /\[ *call *"([^"]+)" *\]/ =~ d
  return d if $1==nil
  a=strby8bit($1)
  ahead=$` 
  alast=$'
  d = ahead +"[l][s][t]" +a +alast
 end
end

def callcalc d
 while 1
  /\[ *call ([0-9]+) *\]/ =~ d
  return d if $1==nil
  a=$1
  ahead=$` 
  alast=$'
  d = ahead +"[l][s][t]"+ "["+a+"]"+alast
 end
end

def outchrcalc d
 while 1
  /\[ *(outchr) *\]/ =~ d
  return d if $1==nil
  ahead=$` 
  alast=$'
  d = ahead +"[t][l][s][s]" +alast
 end
end

def jpifzerocalc d
  keyAndStrCalc "jpifzero", "[l][t][s]" ,d
end

def jpifnecalc d
  keyAndStrCalc "jpifne", "[l][t][t]" ,d
end

def labelchrcalc d
 keyAndStrCalc "label", "[l][s][s]", d
end

def stl_pr source
 return if !$debug
 source.each_byte{|d|
 print "s" if d==" "[0]
 print "t" if d=="\t"[0]
 print "l" if d=="\n"[0]
 }
 puts
 puts "(output length: #{source.length})"
end

(puts "usage: %0 infile outfile [no-debug]";exit) if ARGV.length < 2 
# if ARGV==[]
# source =$stdin 
# else
 source =File.new(ARGV[0], "r")
# end

p ARGV if $debug

d = source.readlines.join

d = timescalc d
d = jpifzerocalc d
d = jpifnecalc d
d = labelnumcalc d
d = labelchrcalc d
d = callcalc d
d = callchrcalc d
d = gotocalc d

d = printcalc d
d = pushcalc d
d = outchrcalc d
p d if $debug

d = printstrcalc d
d = printnumcalc d
d = putccalc d
d = numcalc d
d = charcalc d
d = strcalc d
d=delcomment(d)
p d if $debug

d.downcase!
$w.length.times{|t|
  d=trans(t,d)
}
d =delnotws d
open(ARGV[1],"w+b"){|f|
 stl_pr(d)
 f.write(d)
}


# ws-comlist.rb
# ver. '071129

# when adding, 
# left str must be in [s][l][t] or alternates
# 

$w=[
       ["[t][t][s]","[store]"],
       ["[t][t][t]","[retrieve]"],
       ["[l][l][l]","[exit]"],
       ["[l][t][l]","[ret]"],
       ["[s][l][s]","[dup]"],
       ["[s][l][t]","[swap]"],
       ["[s][l][l]","[dis]"],
       ["[t][l][s][t]","[outnum]"],
       ["[t][l][s][s]","[outchr]"],
       ["[t][l][t][s]","[inchr]"],
       ["[t][l][t][t]","[innum]"],
       ["[t][s][s][l]","[*]"],
       ["[t][s][t][s]","[/]"],
       ["[t][s][t][t]","[%]"],
       ["[t][s][s][s]","[+]"],
       ["[t][s][s][t]","[-]"],
       ["[s][s][s][t][l][t][s][s][s]","[++]"],
       ["[s][s][s][t][l][t][s][s][t]","[--]"],
       [$sp,"[space]"],
       [$tb,"[tab]"],
       [$lf,"[lf]"],
       [$sp,"[sp]"],
       [$tb,"[tb]"],
       [$sp,"[s]"],
       [$tb,"[t]"],
       [$lf,"[l]"]
]


rem -ws.bat
@echo off
set prog=ws
if "%2"=="" goto nodebug
ws-comp %1 temp.ws 
%prog% temp.ws
goto en

:nodebug
ws-comp %1 temp.ws 1
%prog% temp.ws

:en

interpreterを変更するにはset prog=ws.exe のws.exeのとこを書き換えます。

真のホワイトスペイサーはやはりこんなものは使わずすらすらと50バイトくらいは手書きで書くんでしょうか。でも本家サンプルのコードにもラベルはアルファベットが使ってあるようですよ

トラックバック - http://rubyist.g.hatena.ne.jp/hatecha/20071129
カレンダー
<< 2007/11 >>
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
archive Error : RSSが取得できませんでした。