From: Wyss Clemens Date: 2001-12-11T18:10:31+09:00 Subject: [ruby-talk:28191] RE: c++2rb 2.) sub!(/(\S+)(\s)*}/, '\1\2; end') 3.) eval("gsub!(/(#{token_re})::\\1(.*)/, 'def initialize\\2')") 'using namespace foo;' -> include foo ? 'using foo::foomember;' -> ? Clemens > -----Original Message----- > From: Issac Trotts [mailto:ITrotts@IdolMinds.com] > Sent: Dienstag, 11. Dezember 2001 04:25 > To: ruby-talk@ruby-lang.org > Subject: [ruby-talk:28170] c++2rb > > > Here's a little program to partially automate conversion from > C++ to Ruby. > If you make any improvements, please let me know. > > A few things surprised me about the script: > > 1. When I tried to move the body of the while loop into a > separate function > taking > no args, the script suddenly stopped working. The > expressions only use > $_ so I don't > see what the trouble is. Here's the error message: > > c2rb:19:in `gsub!': $_ value need to be String (nil given) > (TypeError) > > Isn't $_ supposed to be global? > > 2. See the line that says "WHY DOESN'T THIS WORK?" > > 3. The failed attempt at making a regular expression for > constructors (see > below). > I want to match a pattern that looks like FOO::FOO() > > One more question before I go: > What are the Ruby equivalents of 'using namespace foo;' > and 'using foo::foomember;'? > > > > ======= %< ======== > > #!/usr/bin/env ruby > # > # c++2rb : partial conversion from C and C++ to Ruby > # > # Copyright (c) 2001 Issac Trotts > # > # Under the Ruby license > # > # TODO > # - template functions > # - template classes > > type_re = '(void|char|short|int|long|float|double)' > map_re = '\bmap\s*<.*>' > list_re = '\blist\s*<.*>' > vector_re = '\bvector\s*<.*>' > token_re = '[a-zA-Z_][a-zA-Z0-9_]*' > > while gets > gsub!(/;/, '') > gsub!(/#include\s+\<([^>.]+)(.h)?>/, 'require \'\1\'') > gsub!(/const\s*/, '') > gsub!(/unsigned\s*/, '') > eval('gsub!(/#{list_re}\s*(#{token_re})/, \'\1 = []\')') > eval('gsub!(/#{vector_re}\s*(#{token_re})/, \'\1 = []\')') > eval('gsub!(/#{map_re}\s*(#{token_re})/, \'\1 = {}\')') > gsub!(/push_back/, 'push') > gsub!(/std::/, '') > gsub!(/cout\s*\<\ gsub!(/\<\ gsub!(/this/, 'self') > gsub!(/endl/, '"\n"') > gsub!(/(public|protected|private)\:/, '\1') > # comments > gsub!(/\/\//, '#') > gsub!(/\{/, '') > gsub!(/(\s*)}/, '\1end') > sub!(/(\S)+(\s)*}/, '\1\2; end') # WHY DOESN'T THIS WORK? > gsub!(/case/, 'when') > gsub!(/switch/, 'case') > gsub!(/default/, 'else') > gsub!(/struct/, 'class') > gsub!(/virtual\s*/, '') > gsub!(/if\s*\(([^)]+)\)/, 'if \1') > #gsub!(/if\(([^)]+)\)\s*(\S*)$/, 'if \1; \2') > # inheritance > gsub!(/:\s+(public|private|protected)/, '<') > gsub!(/\-\>/, '.') > # global functions with no args > eval("sub!(/#{type_re}\\s+(#{token_re})\\s*\\(\\s*\\)/, "+ > '\'def \2\')') > # global functions with args > eval("sub!(/#{type_re}\\s+(#{token_re})\\s*(\\(.*\\))\s*{?/, "+ > '\'def \2\3\')') > # constructors > #eval("gsub!(/#{(token_re)::\$1(.*)/, 'def initialize\2')") > # member functions with no args > > eval("sub!(/#{type_re}\\s+(#{token_re})::(#{token_re})\\s*\\(\\s*\\)/, > "+ > '\'class \2; def \3 # FIXME: put another end at the end\')') > # member functions with args > > eval("sub!(/#{type_re}\\s+(#{token_re})::(#{token_re})\\s*\\((.*)\\)/, > "+ > '\'class \2; def \3 (\4) # FIXME: put another end at > the end\')') > # member function invocations with no args > > # member function invocations with args > > # for-loops... > > # using std::cout etc > > # using namespace X > > # namespaces > gsub!(/namespace/, 'module') > > print > end >