@ -3,7 +3,7 @@
* Copyright ( C ) 2021 Stephan Seitz < stephan . seitz @ fau . de >
* Adapted from tree - sitter - clojure
*
* Distributed under terms of the GPLv3 license .
* Distributed under terms of the MIT license .
* /
const clojure = require ( "tree-sitter-clojure/grammar" ) ;
@ -114,12 +114,28 @@ function clSymbol(symbol) {
return seq ( optional ( seq ( 'cl' , ':' ) ) , symbol )
}
function loopSymbol ( symbol ) {
return seq ( optional ( seq ( optional ( 'cl' ) , ':' ) ) , symbol )
}
function optSeq ( ... args ) {
return optional ( seq ( ... args ) )
}
module . exports = grammar ( clojure , {
name : 'commonlisp' ,
extras : ( $ , original ) => [ ... original , $ . block _comment ] ,
conflicts : ( $ , original ) => [ ... original , [ $ . for _clause ] , [ $ . accumulation _clause ] , [ $ . loop _macro , $ . defun _keyword , $ . package _lit ] ] ,
conflicts : ( $ ,
original ) => [ ... original ,
[ $ . for _clause _word , $ . package _lit ] ,
[ $ . with _clause , $ . package _lit ] ,
[ $ . with _clause ] ,
[ $ . for _clause ] ,
[ $ . accumulation _clause ] ,
[ $ . loop _macro , $ . defun _keyword , $ . package _lit ] ] ,
rules : {
block _comment : _ => token ( seq ( '#|' , repeat ( choice ( /[^|]/ , /\|[^#]/ ) ) , '|#' ) ) ,
@ -193,14 +209,14 @@ module.exports = grammar(clojure, {
'"' ,
repeat ( choice (
token . immediate ( prec ( 1 , /[^\\~"]+/ ) ) ,
token . immediate ( seq ( "\\\"" ) ) ,
token . immediate ( seq ( /\\./ ) ) ,
$ . format _specifier ,
) ) ,
optional ( '~' ) ,
'"' ,
) ,
for _clause _word : _ => c lSymbol( choice (
for _clause _word : _ => loop Symbol( choice (
'in' ,
'across' ,
'being' ,
@ -211,6 +227,7 @@ module.exports = grammar(clojure, {
'from' ,
'to' ,
'upto' ,
'upfrom' ,
'downto' ,
'downfrom' ,
'on' ,
@ -221,18 +238,16 @@ module.exports = grammar(clojure, {
_for _part : $ => seq ( repeat ( $ . _gap ) , $ . for _clause _word , repeat ( $ . _gap ) , $ . _form ) ,
accumulation _verb : _ => clSymbol ( /((collect|append|nconc|count|maximize|minimize)(ing)?|sum(ming)?)/ ) ,
for _clause : $ => choice ( seq ( choice ( clSymbol ( 'for' ) , clSymbol ( 'and' ) , clSymbol ( 'as' ) ) , repeat ( $ . _gap ) , field ( 'variable' , $ . _form ) , optional ( field ( 'type' , seq ( repeat ( $ . _gap ) , $ . _form ) ) ) ,
repeat1 ( $ . _for _part ) ) , clSymbol ( 'and' ) ) ,
with _clause : $ => prec . left ( seq ( clSymbol ( 'with' ) , repeat ( $ . _gap ) , $ . _form , optional ( field ( 'type' , seq ( repeat ( $ . _gap ) , $ . _form ) ) ) , repeat ( $ . _gap ) , clSymbol ( "=" ) , repeat ( $ . _gap ) , $ . _form ) ) ,
do _clause : $ => prec . left ( seq ( clSymbol ( 'do' ) , repeat1 ( prec . left ( seq ( repeat ( $ . _gap ) , $ . _form , repeat ( $ . _gap ) ) ) ) ) ) ,
while _clause : $ => prec . left ( seq ( choice ( clSymbol ( 'while' ) , clSymbol ( 'until' ) ) , repeat ( $ . _gap ) , $ . _form ) ) ,
repeat _clause : $ => prec . left ( seq ( clSymbol ( 'repeat' ) , repeat ( $ . _gap ) , $ . _form ) ) ,
condition _clause : $ => prec . left ( choice ( seq ( choice ( clSymbol ( 'when' ) , clSymbol ( 'if' ) , clSymbol ( 'unless' ) , clSymbol ( 'always' ) , clSymbol ( 'thereis' ) , clSymbol ( 'never' ) ) , repeat ( $ . _gap ) , $ . _form ) , clSymbol ( "else" ) ) ) ,
accumulation _clause : $ => seq ( $ . accumulation _verb , repeat ( $ . _gap ) , $ . _form , optional ( seq ( repeat ( $ . _gap ) , clSymbol ( 'into' ) , repeat ( $ . _gap ) , $ . _form ) ) ) ,
termination _clause : $ => prec . left ( seq ( choice ( clSymbol ( 'finally' ) , clSymbol ( 'return' ) , clSymbol ( 'initially' ) ) , repeat ( $ . _gap ) , $ . _form ) ) ,
accumulation _verb : _ => loopSymbol ( /((collect|append|nconc|count|maximize|minimize)(ing)?|sum(ming)?)/ ) ,
for _clause : $ => choice ( seq ( choice ( loopSymbol ( 'for' ) , loopSymbol ( 'and' ) , loopSymbol ( 'as' ) ) , repeat ( $ . _gap ) , field ( 'variable' , $ . _form ) , optional ( field ( 'type' , seq ( repeat ( $ . _gap ) , $ . _form ) ) ) ,
repeat1 ( $ . _for _part ) ) , loopSymbol ( 'and' ) ) ,
with _clause : $ => seq ( loopSymbol ( 'with' ) , repeat ( $ . _gap ) , choice ( $ . _form , seq ( $ . _form , repeat ( $ . _gap ) , field ( 'type' , $ . _form ) ) ) , repeat ( $ . _gap ) , optSeq ( loopSymbol ( "=" ) , repeat ( $ . _gap ) ) , optSeq ( $ . _form , repeat ( $ . _gap ) ) ) ,
do _clause : $ => prec . left ( seq ( loopSymbol ( 'do' ) , repeat1 ( prec . left ( seq ( repeat ( $ . _gap ) , $ . _form , repeat ( $ . _gap ) ) ) ) ) ) ,
while _clause : $ => prec . left ( seq ( choice ( loopSymbol ( 'while' ) , loopSymbol ( 'until' ) ) , repeat ( $ . _gap ) , $ . _form ) ) ,
repeat _clause : $ => prec . left ( seq ( loopSymbol ( 'repeat' ) , repeat ( $ . _gap ) , $ . _form ) ) ,
condition _clause : $ => prec . left ( choice ( seq ( choice ( loopSymbol ( 'when' ) , loopSymbol ( 'if' ) , loopSymbol ( 'unless' ) , loopSymbol ( 'always' ) , loopSymbol ( 'thereis' ) , loopSymbol ( 'never' ) ) , repeat ( $ . _gap ) , $ . _form ) , loopSymbol ( "else" ) ) ) ,
accumulation _clause : $ => seq ( $ . accumulation _verb , repeat ( $ . _gap ) , $ . _form , optional ( seq ( repeat ( $ . _gap ) , loopSymbol ( 'into' ) , repeat ( $ . _gap ) , $ . _form ) ) ) ,
termination _clause : $ => prec . left ( seq ( choice ( loopSymbol ( 'finally' ) , loopSymbol ( 'return' ) , loopSymbol ( 'initially' ) ) , repeat ( $ . _gap ) , $ . _form ) ) ,
loop _clause : $ =>
@ -260,7 +275,11 @@ module.exports = grammar(clojure, {
defun _keyword : _ => prec ( 10 , clSymbol ( choice ( 'defun' , 'defmacro' , 'defgeneric' , 'defmethod' ) ) ) ,
defun _header : $ =>
choice (
prec ( PREC . SPECIAL , choice (
seq ( field ( 'keyword' , $ . defun _keyword ) ,
repeat ( $ . _gap ) ,
choice ( $ . unquoting _lit , $ . unquote _splicing _lit )
) ,
seq ( field ( 'keyword' , $ . defun _keyword ) ,
repeat ( $ . _gap ) ,
field ( 'function_name' , $ . _form ) ,
@ -270,12 +289,12 @@ module.exports = grammar(clojure, {
seq ( field ( 'keyword' , alias ( 'lambda' , $ . defun _keyword ) ) ,
repeat ( $ . _gap ) ,
field ( 'lambda_list' , choice ( $ . list _lit , $ . unquoting _lit ) ) )
) ,
) ) ,
array _dimension : _ => prec ( 100 , /\d+[aA]/ ) ,
char _lit : ( _ , original ) =>
seq ( '#' , choice ( original , /\\[nN]ewline/ , /\\[lL]inefeed/ , /\\[Ss]pace/ , /\\[nN]ull/ , /\\[rR]ull/ ) ) ,
char _lit : _ =>
seq ( '#' , /\\([^\f\n\r\t ()]+|[()])/ ) ,
vec _lit : $ =>
prec ( PREC . SPECIAL ,