Every language nowadays requires rich syntax for literals.
Here's a table for RLisp. The lists may seems a bit redundant, but it's basically nicely formatted test set data.
I don't think there's sufficient support for String
and Regexp
literal syntax.
Class | RLisp | Ruby | AST Representation | Notes |
---|---|---|---|---|
TrueClass | true | true | Global identifier true | |
#t | true | Global identifier true (translated inside parser) | Scheme compatibility only. | |
FalseClass | false | false | Global identifier false | |
#f | false | Global identifier false (translated inside parser) | Scheme compatibility only. | |
NilClass | nil | nil | Global identifier nil | |
Integer (Fixnum and Bignum ) | 0 | 0 | Integer object | |
-0 | -0 | |||
5 | 5 | |||
-5 | -5 | |||
12345678901234567890 | 12345678901234567890 | Bignum | ||
-12345678901234567890 | -12345678901234567890 | |||
0x1234 | 0x1234 | Hex | ||
-0x1234 | -0x1234 | |||
0755 | 0755 | Octal | ||
-0755 | -0755 | |||
0b10011 | 0b10011 | Binary | ||
-0b10011 | -0b10011 | |||
Float | 0.0 | 0.0 | Float objects | |
-0.0 | -0.0 | |||
5.0 | 5.0 | |||
-5.0 | -5.0 | |||
3.14 | 3.14 | |||
-3.14 | -3.14 | |||
1e6 | 1e6 | |||
-1e6 | -1e6 | |||
1.234e6 | 1.234e6 | |||
-1.234e6 | -1.234e6 | |||
1.234e+6 | 1.234e+6 | |||
-1.234e+6 | -1.234e+6 | |||
1.234e-6 | 1.234e-6 | |||
-1.234e-6 | -1.234e-6 | |||
Array (like "lists" in other Lisps) | () | [] | [] | Bare non-empty lists are considered function applications. |
(list 1 2 3) | [1, 2, 3] | [:list, 1, 2, 3] | ||
'(1 2 3) | [1, 2, 3] | [:quote, [1, 2, 3]] | ||
`(1 2 3) | [1, 2, 3] | [:quasiquote, [1, 2, 3]] | ||
`(1 ,(+ 2 3) 6) | [1, 2+3, 6] | [:quasiquote, [1, [:unquote, [:+, 2, 3]], 6]] | ||
`(1 2 ,@(list 3 4 5)) | [1, 2, *[3, 4, 5]] | [:quasiquote, [1, [:"unquote-splicing", [:list, 3, 4, 5]], 6]] | ||
(list 1 2 . (list 3 4 5)) | [1, 2, *[3, 4, 5]] | [:list, 1, 2, :".", [:list, 3, 4, 5]] | . and & have special meaning in function applications, a bit like Scheme ". "/Ruby "* ", and Ruby "& ". | |
Range | [Range new 1 25] | 1..25 | Plain method call | |
[Range new 2 25 false] | 2..25 | |||
[Range new 3 25 true] | 3...25 | |||
(.. 4 25) | 4..25 | Global function .. | ||
(... 5 25) | 5...25 | Global function ... | ||
[6 .. 25] | 6..25 | Method Object#.. in rlisp_support.rb | ||
[7 ... 25] | 7...25 | Method Object#... in rlisp_support.rb | ||
Symbol | 'foo | :foo | [:quote :foo] | When symbols are evaluated, . , & and self are magical, lowercase are RLisp variables, and uppercase (possibly with :: s inside) are Ruby global constants (but RLisp Array means Ruby ::Array really). In data mode (when quoted, or passed to macros) all symbols are equal. To create unique symbol use (gensym) . |
foo-bar | :"foo-bar" | [:quote :"foo-bar"] | Symbols can contain some characters that require special escaping in Ruby, like - . | |
'@foo | :@foo | [:quote :@foo] | ||
'foo?!?! | :"foo?!?!" | [:quote :"foo?!?!"] | ||
Hash | (hash) | {} | (hash ...) is a macro which expands to [Hash new] and some Hash#[]= calls. | |
(hash 1 => 2 3 => 4) | {1 => 2, 3 => 4} | |||
(hash 'foo => 42 'bar => 96) | {:foo => 42, :bar => 96} | |||
(hash foo: 42 bar: 96) | {:foo => 42, :bar => 96} | Hashes indexed by constant Symbol s are so common that they have special syntax (generic syntax still works). | ||
Time | [Time now] | Time.now | Plain method call. | |
[Time at 1178573823] | Time.at(1178573823) | Seconds since Unix epoch | ||
String | "Hello" | "Hello" | String object | |
"Hello, world!\n" | "Hello, world!\n" | Backslash escapes work, #{...} does not. | ||
(str "2 + 2 = " (+ 2 2)) | "2 + 2 = #{2 + 2}" | (str ...) global function which calls #to_s and joins results. | ||
Regexp | (rx "foo") | /foo/ | Calls to global function (rx ...) which calls Regexp.new . | |
(rx "(?i:foo)") | /foo/i or /(?i:foo)/ | |||
(rx "\\d+") | /\d+/ | Double-escaping is necessary. |
2 comments:
Two small comments.
1. In the table
RLisp 1..25
Ruby [Range new 1 25]
shouldn't it be vice versa?
2. double escaping in Regexps is really annoying (tested years back on C++ with Boost::Regexp :)
Zverok: Thanks for spotting the mistake, I fixed it.
I think I'll make the parser convert "Hello, #{obj}!\n" to (str "Hello, " obj "!\n") and /\d+/ to (rx "\\d+") or to Regexp object. Division will have to become (div x y), as there's not enough context in RLisp to make / character do both, but that's a small price.
Post a Comment