Die Programmiersprache Ruby

Blog|

Forum|

Wiki  


Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]

Ein neues Thema erstellen Auf das Thema antworten  [ 36 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: cyphers esoterische Programmierecke
BeitragVerfasst: 10 Mai 2006, 13:57 
Offline
Interpreter
Benutzeravatar

Registriert: 05 Jun 2005, 01:54
Beiträge: 3225
Nachdem ich wieder mal auf Wikipedia ueber diverse esoterische Programmiersprachen gestolpert bin, hab ich in einem Anfall von Langeweile gepaart mit dem Wunsch etwas nicht sinnvolles zu erschaffen damit angefangen Interperter fuer ein paar dieser Sprachen zu schreiben

Den Anfang macht mal das relativ einfache HQ9+:

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
31
32
33
34
#!/usr/bin/ruby -w
# HQ9+ Interpreter written in Ruby, by cypher

$accumulator = 0

def hq9plus( source )
source.downcase.each_byte do |command|
case command
when ?h
puts "Hello World!"
when ?q
puts source
when ?9
99.downto 1 do |num|
puts <<BEER
#{num} bottle#{num>1?'s':''} of beer on the wall
#{num} bottle#{num>1?'s':''} of beer
take one down, pass it around,
#{num-1!=0?num-1:"no more"} bottle#{num!=2?'s':''} of beer on the wall

BEER

end
when ?+
$accumulator += 1
else
raise "#{command} is not a valid HQ9+-Command!"
end
end
end

if __FILE__ == $0
source = IO.read(ARGV[0]).chomp
hq9plus( source.gsub( /[^hq9\+]/i, '' ) )
end

Funktionsbeweis:

1
2
3
4
5
6
7
8
kosh:~/devel/hq9+/ cat test.hq
HHQ+HQ++
kosh:~/devel/hq9+/ ./hq9+.rb test.hq
Hello World!
Hello World!
HHQ+HQ++
Hello World!
HHQ+HQ++

Fuer Leute die es etwas kompakter und unuebersichtlicher moegen:

1
2
3
4
5
6
7
8
9
#!/usr/bin/ruby -w
s=IO.read($*[0]).chomp.gsub(/[^hq9\+]/i,'');a=0;s.downcase.each_byte{|c|
c==?h? ($><< "Hello World!\n"):();c==?q? ($><< s+10.chr):();c==?+? (a+=1):();c==?9 ?(99.downto(1){|n|$><<<<BEER}):()}
#{n} bottle#{n>1?'s':''} of beer on the wall
#{n} bottle#{n>1?'s':''} of beer
take one down, pass it around,
#{n-1!=0?n-1:"no more"} bottle#{n!=2?'s':''} of beer on the wall

BEER
Geht aber sicherlich noch etwas kompakter und unuebersichtlicher, aber das wird dem geneigten Leser als Aufgabe ueberlassen ;)

Als naechstes kommt HQ9++ dran :)

_________________


1
2
3
alias L lambda
p L{|y|L{|f|y[L{|x|f[f][x]}]}[L{|f|y[L{|x|f[f][x]}]}]}[L{|z|L{|l|l.empty?? 0:1+z[l.drop(1)]}}][%w<a b c d e f g h i j>]
#=>10


Nuclear Powered Soup | Nuclear Powered Blog


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 10 Mai 2006, 16:13 
Offline
Böser Admin
Benutzeravatar

Registriert: 29 Jul 2005, 22:41
Beiträge: 1879
Wohnort: Hannover
Hi cypher,

ich freue mich ja schon auf den Brainfuck Interpreter. Eventuell kannst du ihn ja noch um ein objektorientiertes Paradigma erweitern :D


der
Daniel

_________________
511.rb | Ruby-Mine | Homepage


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 10 Mai 2006, 16:49 
Offline
Böser Admin 2
Benutzeravatar

Registriert: 17 Mär 2004, 17:03
Beiträge: 2511
Wohnort: Berlin
im zusammenhang damit sind ein paar aktuelle redhanded-beiträge interessant: esoterische Ruby-DSLs.

The Matzster of My Domain
EigenCharges

es wäre auch toll, wenn jemand mal Echo und Extreme implementieren könnte: http://cycnus.de/die%20liste/sprachen/vergleich.htm
die habe ich vor ca. 3 jahren "entworfen" :)

_________________
Ruby-Mine | (almost) murphy.de | rubychan.de


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 10 Mai 2006, 17:00 
Offline
Geselle
Benutzeravatar

Registriert: 29 Mär 2005, 19:03
Beiträge: 198
Gekauft!
Beschwer' Dich aber nicht, wenn ich den Sprachen böse Dinge antue. Die sehen unterspezifiziert aus. :twisted:

_________________
Every OS sucks!


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 10 Mai 2006, 20:09 
Offline
Interpreter
Benutzeravatar

Registriert: 05 Jun 2005, 01:54
Beiträge: 3225
murphy hat geschrieben:
im zusammenhang damit sind ein paar aktuelle redhanded-beiträge interessant: esoterische Ruby-DSLs.
EigenCharges

Ich muss zugeben, ich versteh das Beispiel bis jetzt noch nicht. 3 Tage lang daraufstarren hat auch nicht wirklich geholfen. Mag jemand zu meiner Erleuchtung beitragen?

_________________


1
2
3
alias L lambda
p L{|y|L{|f|y[L{|x|f[f][x]}]}[L{|f|y[L{|x|f[f][x]}]}]}[L{|z|L{|l|l.empty?? 0:1+z[l.drop(1)]}}][%w<a b c d e f g h i j>]
#=>10


Nuclear Powered Soup | Nuclear Powered Blog


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 10 Mai 2006, 20:37 
Offline
Böser Admin 2
Benutzeravatar

Registriert: 17 Mär 2004, 17:03
Beiträge: 2511
Wohnort: Berlin
ich schreibe gerne eine erklärung am nächsten SyntaxSonntag :)

_________________
Ruby-Mine | (almost) murphy.de | rubychan.de


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 10 Mai 2006, 23:52 
Offline
Rubyist

Registriert: 26 Apr 2006, 21:35
Beiträge: 366
Hi,
ich bin ein neuling in sachen ruby, also vll ist sowas ne ganz
gute übung. Heraus gekommen ist ein Ook!-interpreter.


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
31
32

class Ook
@@i = 0;@@m = Array.new(30000){0};@@mp = 0
@@symbols = {'.?' => [:inc_ptr,lambda{|i,mem| i + 1}],
'?.' => [:dec_ptr,lambda{|i,mem| i - 1}],
'..' => [:inc_val,lambda{|i,mem| mem[i] +=1; i }],
'!!' => [:dec_val,lambda{|i,mem| mem[i] -=1; i }],
'!.' => [:out,lambda{|i,mem| $><< mem[i].chr;
$>.flush; i }],
'.!' => [:in,lambda{|i,mem| mem[i] = $<.getc; i}],
'!?' => [:jz,lambda{|i,mem| mem[i] == 0 }],
'?!' => [:jnz,lambda{|i,mem| mem[i] != 0}]
}.freeze
def self.[](file)
c=IO.read(file).chomp.scan(/Ook([\.\?!]) +Ook([\.\?!])/).
compact.collect{|i|@@symbols[i.join][0]}
until @@i >= c.size
if c[@@i] == :jz
if @@symbols.values.assoc(c[@@i])[1].call(@@mp,@@m)
@@i+=1;s=1
begin(s += 1 and next) if c[@@i] == :jz;
(s -= 1 and next) if c[@@i] == :jnz
@@i += 1 end until @@i > c.size || s == 0
end; @@i +=1 and next elsif c[@@i] == :jnz
if @@symbols.values.assoc(c[@@i])[1].call(@@mp,@@m)
@@i -= 1;s = 1
begin(s -= 1 and next) if c[@@i] == :jz
(s += 1 and next) if c[@@i] == :jnz
@@i -= 1 end until @@i < 0 || s == 0
end; @@i+=1 and next else
@@mp = @@symbols.values.assoc(c[@@i])[1].call(@@mp,@@m)
@@i += 1 end end end end


Benutzung dann


1
2
3

require 'Ook'
Ook['dateiname']


Ist zugegebenermaßen nicht sonderlich schön (jetzt mal vom obfuscating abgesehen), aber man lehrnt ja noch. Hat irgendwie spaß gemacht.

@OP ich hoffe es stört dich nicht dass ich das einfach hier gepostet habe.

greets

_________________



 callcc{|xx| callcc{|yy| lambda{|zz| zz}[yy]}[xx]}["Love Ruby but adore Scheme"]

Solve it once, adapt it to your needs => Schnipsel


Zuletzt geändert von closure am 11 Mai 2006, 09:25, insgesamt 1-mal geändert.

Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 00:02 
Offline
Böser Admin
Benutzeravatar

Registriert: 29 Jul 2005, 22:41
Beiträge: 1879
Wohnort: Hannover
Gerade habe ich auch eine Ruby Implementierung des Brainfuck Interpreters gefunden.



der
Daniel

_________________
511.rb | Ruby-Mine | Homepage


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 09:05 
Offline
Rubyist

Registriert: 26 Apr 2006, 21:35
Beiträge: 366
Hi,

ich hab jetzt nochmal eine kürzere version mit eval.
Eigentlich ist es ein Ook!2ruby converter aber mit dem
eval wirds eben ein interpreter.


1
2
3
4
5
6
7
8
9
10
11

s = {'.?' => 'i+=1;',
'?.' => 'i-=1;',
'..' => 'm[i]+=1;',
'!!' => 'm[i]-=1;',
'!.' => '$><<m[i].chr;',
'.!' => 'm[i]=$<.getc;',
'!?' => 'while(m[i]!=0);',
'?!' => 'end;'
}
eval 'm=[0]*30000;i=0;' << IO.read($*[0]).scan(/Ook([\.\?!]) *Ook([\.\?!])/).collect{|i| s[i.join]}.join


Und noch etwas kompacter


1
2
3
4
5
6

#!/usr/bin/env ruby
s={'.?'=>'i+=1;','?.'=>'i-=1;','..'=>'m[i]+=1;','!!'=>'m[i]-=1;',
'!.'=>'$><<m[i].chr;','.!'=>'m[i]=$<.getc;','!?'=>'while(m[i]!=0);','?!'=>'end;'}
eval'm=[0]*30000;i=0;'<<IO.read($*[0]).scan(/Ook([\.\?!]) *Ook([\.\?!])/).
map{|i|s[i.join]}.join


greets

_________________



 callcc{|xx| callcc{|yy| lambda{|zz| zz}[yy]}[xx]}["Love Ruby but adore Scheme"]

Solve it once, adapt it to your needs => Schnipsel


Zuletzt geändert von closure am 12 Mai 2006, 10:15, insgesamt 6-mal geändert.

Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 09:34 
Offline
Interpreter
Benutzeravatar

Registriert: 05 Jun 2005, 01:54
Beiträge: 3225
murphy hat geschrieben:
ich schreibe gerne eine erklärung am nächsten SyntaxSonntag :)
Jo, das waere toll.
closure hat geschrieben:
@OP ich hoffe es stört dich nicht dass ich das einfach hier gepostet habe.
Nana. "cyphers esoterische Programmierecke" heisst nicht dass ich alleine in der Ecke sitz(en will). Alles was mit esoterischen Sprachen zu tun hat kann hier rein.

_________________


1
2
3
alias L lambda
p L{|y|L{|f|y[L{|x|f[f][x]}]}[L{|f|y[L{|x|f[f][x]}]}]}[L{|z|L{|l|l.empty?? 0:1+z[l.drop(1)]}}][%w<a b c d e f g h i j>]
#=>10


Nuclear Powered Soup | Nuclear Powered Blog


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 12:51 
Offline
Böser Admin 2
Benutzeravatar

Registriert: 17 Mär 2004, 17:03
Beiträge: 2511
Wohnort: Berlin
ich glaube, du hast eine marktlücke entdeckt, cypher!

_________________
Ruby-Mine | (almost) murphy.de | rubychan.de


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 13:43 
Offline
Interpreter
Benutzeravatar

Registriert: 05 Jun 2005, 01:54
Beiträge: 3225
murphy hat geschrieben:
ich glaube, du hast eine marktlücke entdeckt, cypher!
Das muss gefeiert werden! Und zwar mit dem HQ9++-Interpreter ;) Da dies die Objekt-Orientierte erweiterung zu HQ9+ ist, hab ich das ganze etwas Objekt-orientierter geloest ;)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/ruby -w
# HQ9++ Interpreter written in Ruby, by cypher

class HelloWorld
def execute
puts "Hello World!"
end
end

class Quine
attr_reader :source

def initialize source
@source = source
end

def execute
puts source
end
end

class BeerSong
def execute
99.downto 1 do |num|
puts <<BEER
#{num} bottle#{num>1?'s':''} of beer on the wall
#{num} bottle#{num>1?'s':''} of beer
take one down, pass it around,
#{num-1!=0?num-1:"no more"} bottle#{num!=2?'s':''} of beer on the wall

BEER

puts "No more bottles of beer on the wall\nOh noes!"
end
end
end

$accumulator = 0

class IncreaseAccumulator
def execute
$accumulator += 1
end
end

class IncreaseAccumulatorAndCreateANewObject
def execute
$accumulator += 1
(@@objects ||= []) << Object.new
end
end

class HQNinePlusPlus
def initialize source
@source = source
@hello_worlds = []
@quines = []
@beer_songs = []
@increase_accumulators = []
@increase_accumulator_and_create_new_objects = []
end

def parse
accumulator_flag = false
@source.downcase.each_byte do |command|
case command
when ?h
@hello_worlds << HelloWorld.new
@hello_worlds.last.execute
when ?q
@quines << Quine.new( @source )
@quines.last.execute
when ?9
@beer_songs << BeerSong.new
@beer_songs.last.execute
when ?+
if accumulator_flag == true
@increase_accumulator_and_create_new_objects << IncreaseAccumulatorAndCreateANewObject.new
@increase_accumulator_and_create_new_objects.last.execute
else
@increase_accumulators << IncreaseAccumulator.new
@increase_accumulators.last.execute
accumulator_flag = true
next
end
else
raise "#{command} is not a valid HQ9++-Command!"
end
accumulator_flag = false
end
end
end

if __FILE__ == $0
source = IO.read(ARGV[0]).chomp
parser = HQNinePlusPlus.new( source.gsub( /[^hq9\+]/i, '' ) )
parser.parse
end


Ernsthaft: esoterische Programmiersprachen moegen vielleicht nie wirklich Bedeutung erlangen, aber sie sind ein wunderbares Mittel wenn man mit einer anderen Programmiersprache spielen & experimentieren moechte. Kann ich nur empfehlen.

Als naechstes kommen dann L00P und Brainfuck dran.

_________________


1
2
3
alias L lambda
p L{|y|L{|f|y[L{|x|f[f][x]}]}[L{|f|y[L{|x|f[f][x]}]}]}[L{|z|L{|l|l.empty?? 0:1+z[l.drop(1)]}}][%w<a b c d e f g h i j>]
#=>10


Nuclear Powered Soup | Nuclear Powered Blog


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 15:18 
Offline
Interpreter
Benutzeravatar

Registriert: 15 Mär 2005, 19:26
Beiträge: 5874
Wohnort: Karlsruhe
cypher hat geschrieben:
... esoterische Programmiersprachen moegen vielleicht nie wirklich Bedeutung erlangen ...

Hah! - TECO - Text Editor and COrector (und weitere Links wenn man unter Google nach teco editor sucht). Programme in TECO sahen ähnlich aus und machten spätestens nach einem Korrekturversuch drei Wochen nachdem man es geschrieben hatte nie wieder etwas Sinnvolles.

_________________
WoNáDo.set_state!(:active)


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 16:22 
Offline
Rubyist
Benutzeravatar

Registriert: 20 Jan 2006, 20:37
Beiträge: 309
Wohnort: @~
murphy hat geschrieben:
ies wäre auch toll, wenn jemand mal Echo und Extreme implementieren könnte: http://cycnus.de/die%20liste/sprachen/vergleich.htm
die habe ich vor ca. 3 jahren "entworfen" :)


Hübsche Übung. :) Ich hab mich mal an Extreme versucht:



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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env ruby


INPUT = 'Factor:_ ?a%
Until:_ ?u%
{a _*_ i(1..u) _=_ (a * i)}
'



$vars = {}
$out = ""

class Var
def initialize(val)
@val = val
end
def to_i
Int.new(@val.to_i)
end
def to_s
Str.new(@val.to_s)
end
attr_accessor :val
end

class Str < Var
def +(v)
@val + v.to_s
end
def *(v)
@val * v.to_i
end
end

class Int < Var
def +(v)
@val + v.to_i
end
def *(v)
@val * v.to_i
end
def /(v)
@val / v.to_i
end
def -(v)
@val - v.to_i
end
end



def out_err err
puts err
exit
end

def read_str(str)
nstr = str.gsub(/\((\w+)\s*([+\-*\/])\s*(\w+)\)/) {
if (t=$vars.fetch($1, $1.to_i)).kind_of?(Integer) or t.kind_of?(Int)
v1 = t
else
out_err "Wrong type of variable!"
end
if (t=$vars.fetch($3, $3.to_i)).kind_of?(Integer) or t.kind_of?(Int)
v2 = t
else
out_err "Wrong type of variable!"
end
case $2
when '+' then result = v1 + v2
when '-' then result = v1 - v2
when '*' then result = v1 * v2
when '/' then result = v1 / v2
end
}
nstr.split(" ").each { |p|
if p =~ /\A\?([A-Za-z])(\%?)/
$vars[$1] = STDIN.gets.chomp
$vars[$1] = $vars[$1].to_i if $2 == '%'
return
end
print $vars.fetch(p, p).to_s.gsub("_", " ")
}
puts
end



INPUT.each_line { |code|
if code =~ /\A\s(.*)/ # code
block = $1
if block =~ /\A\{(.*?([A-Za-z]+))\((\w+)(\.\.\.?)(\w+)\)(.*)\}\z/
string = $1 + $6
counter = $2
rstart = $vars.fetch($3, $3.to_i)
rend = $vars.fetch($5, $5.to_i)
rtype = $4
# analyse range
$vars[counter] = Int.new(0)
range = (rtype == ".." ? (rstart..rend) : (rstart...rend))
for i in range
$vars[counter] += 1
read_str(string)
end
end
else
read_str(code)
end
}


Das Beispiel ließ sich auf jedenfall damit machen.

Is halt weder obfuscated, noch strukturiert, aber egal.

_________________
Ubuntu 7.04 Feisty Fawn



"I like Ruby!".split("").each{|c|print c;$>.flush;sleep 0.05}


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 11 Mai 2006, 20:56 
Offline
Geselle
Benutzeravatar

Registriert: 29 Dez 2005, 21:14
Beiträge: 103
WoNáDo hat geschrieben:
cypher hat geschrieben:
... esoterische Programmiersprachen moegen vielleicht nie wirklich Bedeutung erlangen ...

Hah! - TECO - Text Editor and COrector (und weitere Links wenn man unter Google nach teco editor sucht). Programme in TECO sahen ähnlich aus und machten spätestens nach einem Korrekturversuch drei Wochen nachdem man es geschrieben hatte nie wieder etwas Sinnvolles.


Ein Freund, der am MIT studiert hat, het mir mal folgendes erzählt:

Es gab dort ein nettes Spiel mit TECO. Man gab als Kommando seinen Namen oder ein beliebiges Wort ein und schaute zu, was passierte. Manchmal fand man so einige nützliche Makros!

PS: Der "echte" Name von TECO war Tape Editor and COrrector.


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 36 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach: