Reputation: 1506
I saw functions like number?
and string?
.
Is there a function to test if a form is a literal?
I mean all literals in Clojure.
This is what I am trying to do.
;; Abstract Syntax Representation
(defrecord VarExp [id])
(defrecord LiteralExp [datum])
(defrecord LambdaExp [ids body])
(defrecord IfExp [pred true-exp false-exp])
(defrecord AppExp [rator rands])
(defn parse-expression [datum]
(cond
(symbol? datum) (VarExp. datum)
(literal? datum) (LiteralExp. datum)
(list? datum) (cond
(= (first datum) 'fn) (LambdaExp. (map parse-expression (second datum))
(parse-expression (nth datum 2)))
(= (first datum) 'if) (IfExp.
(parse-expression (second datum))
(parse-expression (nth datum 2))
(parse-expression (last datum)))
:else (AppExp.
(parse-expression (first datum))
(map parse-expression (rest datum))))
:else (throw
(Exception. (str 'parse-expression
": Invalid concrete syntax " datum)))))
I'd like to parse S-exp to AST without using any standalone parser because s-exp is very much like a parse tree.
My current solution is:
(defn literal? [datum]
(or
(true? datum)
(false? datum)
(string? datum)
(nil? datum)
(symbol? datum)
(number? datum)))
Is this already the most practical one?
BTW, this is the grammar of Clojure literal : STRING | NUMBER | CHARACTER | NIL | BOOLEAN | KEYWORD | SYMBOL | PARAM_NAME ;
STRING : '"' ( ~'"' | '\' '"' )* '"' ;
NUMBER : '-'? [0-9]+ ('.' [0-9]+)? ([eE] '-'? [0-9]+)? ;
CHARACTER : '\' . ;
NIL : 'nil';
BOOLEAN : 'true' | 'false' ;
KEYWORD : ':' SYMBOL ;
SYMBOL: '.' | '/' | NAME ('/' NAME)? ;
PARAM_NAME: '%' (('1'..'9')('0'..'9')*)? ;
Upvotes: 2
Views: 424
Reputation: 33637
A literal is a compile time
concept (i.e the parsing of literals to corresponding value/object is done by compiler), where as functions are runtime concept
(i.e they work on values that are available at runtime) , so, no there is no such function possible as the function won't have any way to check if a value/object was a result of literal compilation.
Only a macro can say if something is literal or not.
Upvotes: 3
Reputation: 70211
No, there is no such function in Clojure.
There are many kinds of literals, including compound collections like maps, sets, vectors, lists, etc so I'm not sure that "literal?" would actually be a meaningful question.
Upvotes: 1