@ -19,11 +19,22 @@ const PREC = {
SPECIAL : 2 ,
}
const SYMBOL _HEAD =
/[^\f\n\r\t ()\[\]{}"@~^;`\\,:#'0-9\u000B\u001C\u001D\u001E\u001F\u2028\u2029\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2008\u2009\u200a\u205f\u3000]/ ;
const SYMBOL _BODY =
choice ( SYMBOL _HEAD ,
/[#':0-9]/ ) ;
const SYMBOL =
token ( seq ( SYMBOL _HEAD ,
repeat ( SYMBOL _BODY ) ) ) ;
module . exports = grammar ( clojure , {
name : 'commonlisp' ,
extras : ( $ , original ) => [ ... original , $ . block _comment ] ,
conflicts : ( $ , original ) => [ ... original , [ $ . for _clause ] , [ $ . accumulation _clause ] ] ,
conflicts : ( $ , original ) => [ ... original , [ $ . for _clause ] , [ $ . accumulation _clause ] , [ $ . do _clause ] ],
rules : {
block _comment : _ => token ( seq ( '#|' , repeat ( choice ( /[^|]/ , /\|[^#]/ ) ) , '|#' ) ) ,
@ -56,16 +67,18 @@ module.exports = grammar(clojure, {
repeat ( choice ( field ( 'value' , $ . _form ) , $ . _gap ) ) ,
field ( 'close' , ")" ) ) ,
_for _part : $ => seq ( optional ( $ . _gap ) , choice ( 'in' , 'across' , 'being' , 'using' , /being the (hash-key[s]?|hash-value[s]?) in/ , 'below' , 'from' , 'to' , 'upto' , 'downto' , 'downfrom' , 'on' , 'by' , 'then' ),
_for _part : $ => seq ( optional ( $ . _gap ) , choice ( 'in' , 'across' , 'being' , 'using' , /being the (hash-key[s]?|hash-value[s]?) in/ , 'below' , 'from' , 'to' , 'upto' , 'downto' , 'downfrom' , 'on' , 'by' , 'then' , '=' ),
optional ( $ . _gap ) , $ . _form ) ,
accumulation _verb : _ => / ( collect | append | nconc | count | sum | maximize | minimize ) ( ing ) ? / ,
accumulation _verb : _ => / ( ( collect | append | nconc | count | maximize | minimize ) ( ing ) ? | sum ( ming ) ? ) / ,
for _clause : $ => seq ( choice ( 'for' , 'and' ), optional ( $ . _gap ) , field ( 'variable' , $ . _form ) ,
$. _for _part , optional ( $ . _for _part ) ) ,
for _clause : $ => seq ( choice ( 'for' , 'and' , 'as' ), optional ( $ . _gap ) , field ( 'variable' , $ . _form ) ,
repeat1 ( $ . _for _part ) ) ,
with _clause : $ => prec . left ( seq ( 'with' , optional ( $ . _gap ) , $ . _form , optional ( $ . _gap ) , "=" , optional ( $ . _gap ) , $ . _form ) ) ,
do _clause : $ => prec . left ( seq ( 'do' , optional ( $ . _gap ) , $ . _form ) ) ,
do _clause : $ => prec . left ( seq ( 'do' , repeat ( seq ( optional ( $ . _gap ) , $ . _form ) ) ) ) ,
while _clause : $ => prec . left ( seq ( 'while' , optional ( $ . _gap ) , $ . _form ) ) ,
repeat _clause : $ => prec . left ( seq ( 'repeat' , optional ( $ . _gap ) , $ . _form ) ) ,
condition _clause : $ => prec . left ( seq ( choice ( 'when' , 'if' , 'unless' , 'always' , 'thereis' , 'never' ) , optional ( $ . _gap ) , $ . _form ) ) ,
accumulation _clause : $ => seq ( $ . accumulation _verb , optional ( $ . _gap ) , $ . _form , optional ( seq ( optional ( $ . _gap ) , 'into' , optional ( $ . _gap ) , $ . _form ) ) ) ,
termination _clause : $ => prec . left ( seq ( choice ( 'finally' , 'return' , 'initially' ) , optional ( $ . _gap ) , $ . _form ) ) ,
@ -75,27 +88,35 @@ module.exports = grammar(clojure, {
seq ( choice (
$ . for _clause ,
$ . do _clause ,
$ . while _clause ,
$ . accumulation _clause ,
$ . condition _clause ,
$ . with _clause ,
$ . termination _clause ,
$ . while _clause ,
) ) ,
loop _macro : $ =>
seq ( field ( 'open' , "(" ) ,
optional ( $ . _gap ) ,
optional ( 'cl:' ) ,
'loop' ,
repeat ( choice ( $ . loop _clause , $ . _gap ) ) ,
field ( 'close' , ")" ) ) ,
defun _keyword : _ => choice ( 'defun' , 'defmacro' ),
defun _keyword : _ => choice ( 'defun' , 'defmacro' , 'defgeneric' , 'defmethod' ),
defun _header : $ =>
seq ( field ( 'keyword' , $ . defun _keyword ) ,
repeat ( $ . _gap ) ,
field ( 'function_name' , $ . _form ) ,
repeat ( $ . _gap ) ,
field ( 'lambda_list' , $ . list _lit ) ) ,
choice (
seq ( field ( 'keyword' , $ . defun _keyword ) ,
repeat ( $ . _gap ) ,
field ( 'function_name' , $ . _form ) ,
repeat ( $ . _gap ) ,
field ( 'lambda_list' , $ . list _lit ) ) ,
seq ( field ( 'keyword' , alias ( 'lambda' , $ . defun _keyword ) ) ,
repeat ( $ . _gap ) ,
field ( 'lambda_list' , $ . list _lit ) )
) ,
array _dimension : $ => seq ( $ . num _lit , 'A' ) ,
@ -142,5 +163,10 @@ module.exports = grammar(clojure, {
$ . syn _quoting _lit ,
$ . unquote _splicing _lit ,
$ . unquoting _lit ) ,
sym _lit : $ =>
seq ( repeat ( $ . _metadata _lit ) ,
SYMBOL ) ,
}
} ) ;