Blogged by Ujihisa. Standard methods of programming and thoughts including Clojure, Vim, LLVM, Haskell, Ruby and Mathematics written by a Japanese programmer. github/ujihisa

Wednesday, May 13, 2009

Lisp like symbol in Ruby

Lisp like symbol in Ruby

I succeeded in adding a lisp like symbol literal to ruby by fixing parse.y.

diff --git a/parse.y b/parse.y
index e2e92ce..c9fbb03 100644
--- a/parse.y
+++ b/parse.y
@@ -6319,6 +6319,9 @@ static int
 parser_yylex(struct parser_params *parser)
 {
     register int c;
+    int cs[1024];
+    int i;
+    char flag; // 't': sTring, 'y': sYmbol
     int space_seen = 0;
     int cmd_state;
     enum lex_state_e last_state;
@@ -6631,8 +6634,26 @@ parser_yylex(struct parser_params *parser)
         return tXSTRING_BEG;

       case '\'':
-        lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
-        return tSTRING_BEG;
+        flag = 'y'; // sYmbol by default
+        for (i=0; i<sizeof(cs); i++) {
+            cs[i] = nextc();
+            if (cs[i] == '\'') {
+                flag = 't'; // sTring
+                break;
+            }
+            if (cs[i] == '\n' || cs[i] == -1) {
+                break; // sYmbol
+            }
+        }
+        while (i >= 0)
+            pushback(cs[i--]);
+        if (flag == 't') {
+            lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
+            return tSTRING_BEG;
+        } else {
+            lex_state = EXPR_FNAME;
+            return tSYMBEG;
+        }

       case '?':
         if (lex_state == EXPR_END || lex_state == EXPR_ENDARG) {

After applying this patch, we can write such like:

p 'aaa'      #=> "aaa"
p 'bbb       #=> :bbb
p 'ccc, true #=> :ccc
             #   true
p :ddd       #=> :ddd

The followings are the methodology how it works:

  1. If the ruby parser finds single quote, the parser peeks the next characters from the next character
  2. The parser stocks each characters into a stack which maximum size is 1024
  3. If the parser finds another single quote, the parser does back tracking with the stack and then considers the following characters as a string.
  4. Otherwise if the parser does not find another single quote within the line, the parser does back tracking with the stack and then considers the following characters as a symbol.

Obviously, there are some known bugs:

  • It cannot handle a line which has 1024+ characters after a quote
  • It confuses in p 'aaa, 'bbb
  • It cannot handle a multi line string

e.g.

p 'aaa
   bbb'

To tell the truth, I wrote this patch just for my curiousity. I don't believe this syntax will harmonize well with Ruby.

No comments:

Post a Comment

Followers