tl-rpc.lisp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. (defpackage tl-rpc
  2. (:use :cl :parser-combinators :alexandria))
  3. (in-package :tl-rpc)
  4. (defun not-equal (a b)
  5. (not (equal a b)))
  6. (defun <ml-not-end> ()
  7. (named-seq? (<- char
  8. (choice (sat (curry #'not-equal #\*))
  9. (except? #\* "*/")))
  10. (string char)))
  11. (defun <ml-content> (ml-comment)
  12. (named-seq? (<- content
  13. (many? (choice (named-seq? (<- inner ml-comment)
  14. (concatenate 'string "/*" inner "*/"))
  15. (<ml-not-end>))))
  16. (apply #'concatenate 'string content)))
  17. (defun <ml-comment> ()
  18. (named? ml-comment
  19. (bracket? "/*" (<ml-content> ml-comment) "*/")))
  20. (defun <sl-comment> ()
  21. (bracket? "//"
  22. (named-seq? (<- comment (many? (sat (curry #'not-equal #\Newline))))
  23. (coerce comment 'string))
  24. #\Newline))
  25. (defun <punctuation> ()
  26. (sat (rcurry #'member '(#\; #\( #\) #\{ #\} #\. #\# #\: #\[ #\] #\= #\? #\% #\+ #\< #\> #\, #\* #\!))))
  27. (defun <token> ()
  28. (choice
  29. (between? (sat #'(lambda (i) (or (alphanumericp i)
  30. (member i '(#\_))))) 1 nil 'string)
  31. (quoted? :quote-char #\`)))
  32. (defun tokenize (input)
  33. (remove :whitespace
  34. (parse-string*
  35. (many? (choices (<token>)
  36. (<punctuation>)
  37. (chook? :whitespace
  38. (choices (whitespace?) "---" (<sl-comment>) (<ml-comment>)))))
  39. input)))
  40. ;; Actual parsers
  41. (defun <hex-digit> ()
  42. (choice (digit?) (sat (rcurry #'member '(#\a #\b #\c #\d #\e #\f)))))
  43. (defun <letter> ()
  44. (choice (lower?) (upper?)))
  45. (defun <ident-char> ()
  46. (choices (<letter>) (digit?) #\_))
  47. (defmacro def-string-parser (name arguments &body body)
  48. (with-unique-names (inp)
  49. (multiple-value-bind (forms declarations docstring) (parse-body body :documentation t)
  50. `(defun ,name ,arguments
  51. ,docstring
  52. ,@declarations
  53. (sat (lambda (,inp)
  54. (and (stringp ,inp)
  55. (parse-string* ,@forms ,inp :complete t))))))))
  56. (defun concat (&rest args)
  57. (apply #'concatenate 'string args))
  58. (defun string-concat (args)
  59. (apply #'concatenate 'string (mapcar 'string args)))
  60. (def-string-parser <lc-ident> ()
  61. (named-seq? (<- hd (lower?))
  62. (<- tl (many? (<ident-char>)))
  63. (coerce (cons hd tl) 'string)))
  64. (def-string-parser <uc-ident> ()
  65. (named-seq? (<- hd (upper?))
  66. (<- tl (many? (<ident-char>)))
  67. (coerce (cons hd tl) 'string)))
  68. (def-string-parser <hex-string> (&optional len)
  69. (between? (<hex-digit>) len len))
  70. (defun <namespace-ident> () (<lc-ident>))
  71. (defstruct ident ns id name)
  72. (defun <lc-ident-ns> ()
  73. (named-seq? (<- ns (opt? (seq-list? (<namespace-ident>) #\.)))
  74. (<- id (<lc-ident>))
  75. (make-ident :ns (car ns) :id id)))
  76. (defun <uc-ident-ns> ()
  77. (named-seq? (<- ns (opt? (seq-list? (<namespace-ident>) #\.)))
  78. (<- id (<uc-ident>))
  79. (make-ident :ns (car ns) :id id)))
  80. (defun <lc-ident-full> ()
  81. (named-seq? (<- id (<lc-ident-ns>))
  82. (<- name (opt? (seq-list? #\# (<hex-string> 8))))
  83. (progn (when name (setf (ident-name id) (second name)))
  84. id)))
  85. (defun <nat-const> ()
  86. (many1? (digit?)))
  87. (defun <boxed-type-ident> () (<uc-ident-ns>))
  88. (defun sep? (&optional accept-empty) (whitespace? :accept-empty accept-empty))
  89. (defun <full-combinator-id> ()
  90. (choice (<lc-ident-full>) "_"))
  91. (defun <combinator-id> ()
  92. (choice (<lc-ident-ns>) "_"))
  93. (defun <type-ident> ()
  94. (choices
  95. (<boxed-type-ident>)
  96. (<lc-ident-ns>)
  97. "#"))
  98. (defun <var-ident> ()
  99. (choice (<lc-ident>) (<uc-ident>)))
  100. (defun <term> (expr)
  101. (named? term
  102. (choices
  103. (seq-list? "(" expr ")")
  104. (<type-ident>)
  105. (<var-ident>)
  106. (<nat-const>)
  107. (seq-list? "%" term)
  108. (seq-list? (<type-ident>) "<" (sepby1? expr ",") ">")
  109. )))
  110. (defun <subexpr> (expr)
  111. (named? subexpr
  112. (choices
  113. (<term> expr)
  114. (seq-list? (<nat-const>) "+" subexpr)
  115. (seq-list? subexpr "+" (<nat-const>)))))
  116. (defun <expr> ()
  117. (named? expr
  118. (many? (<subexpr> expr))))
  119. (defun <type-expr> () (<expr>))
  120. (defun <nat-expr> () (<expr>))
  121. (defun <type-term> () (<term> (<expr>)))
  122. (defun <nat-term> () (<term> (<expr>)))
  123. (defun <opt-args> ()
  124. (named-seq?
  125. "{" (sep? t)
  126. (<- vars (sepby1? (<var-ident>) (sep?))) (sep? t)
  127. ":"
  128. (opt? "!")
  129. (<- type-expr (<type-expr>)) (sep? t)
  130. "}" (sep? t)
  131. (list :opt-args vars type-expr)))
  132. (defun <multiplicity> () (<nat-term>))
  133. (defun <var-ident-opt> () (choices (<var-ident>) "_"))
  134. (defun <conditional-def> ()
  135. (seq-list? (<var-ident>) (opt? (seq-list? "." (<nat-const>))) "?"))
  136. (defun <args> ()
  137. (named? args
  138. (choices
  139. (seq-list? (<var-ident-opt>) ":" (opt? (<conditional-def>)) (opt? "!") (<type-term>))
  140. (seq-list? (opt? (seq-list? (<var-ident-opt>) ":"))
  141. (opt? (seq-list? (<multiplicity>) "*"))
  142. "[" (many? args) "]")
  143. (seq-list? "(" (many1? (<var-ident-opt>)) ":" (opt? "!") (<type-term>) ")")
  144. (seq-list? (opt? "!") (<type-term>)))))
  145. (defun <result-type> ()
  146. (choices
  147. (seq-list? (<boxed-type-ident>) (many? (<subexpr> (<expr>))))
  148. (seq-list? (<boxed-type-ident>) "<" (sepby1? (<subexpr> (<expr>)) ",") ">")))
  149. (defun <combinator-decl> ()
  150. (named-seq?
  151. (<- comb (<full-combinator-id>)) (sep?)
  152. (<- opt-args (many? (<opt-args>))) (sep? t)
  153. (<- args (many? (<args>))) (sep? t)
  154. "=" (sep?)
  155. (<- result-type (<result-type>)) (sep? t)
  156. ";"
  157. (list :comb-decl comb opt-args args result-type)))
  158. (defun <partial-type-app-decl> ()
  159. (choices
  160. (named-seq?
  161. (<- type (<boxed-type-ident>)) (sep?)
  162. (<- ex (many1? (<subexpr> (<expr>)))) (sep?)
  163. ";"
  164. (list :part-type type ex))
  165. (named-seq?
  166. (<- type (<boxed-type-ident>)) (sep?)
  167. "<" (<- ex (sepby1? (<expr>) ",")) ">"
  168. (list :part-type type ex))))
  169. (defun <partial-comb-app-decl> ()
  170. (seq-list? (<combinator-id>) (many1? (<subexpr> (<expr>)))))
  171. (defun <partial-app-decl> ()
  172. (choices
  173. (<partial-type-app-decl>)
  174. (<partial-comb-app-decl>)))
  175. (defun <builtin-combinator-decl> ()
  176. (named-seq?
  177. (<- comb (<full-combinator-id>)) (sep?)
  178. "?" (sep?)
  179. "=" (sep?)
  180. (<- type (<boxed-type-ident>)) (sep? t)
  181. ";"
  182. (list :builtin-decl comb type)))
  183. (defun <final-decl> ()
  184. (named-seq?
  185. (<- type (choices "New" "Final" "Empty"))
  186. (<- ind (<boxed-type-ident>)) #\;
  187. (list :final-decl type ind)))
  188. (defun <declaration> ()
  189. (choices (<builtin-combinator-decl>)
  190. (<combinator-decl>)
  191. (<partial-app-decl>)
  192. (<final-decl>)))
  193. (defun <constr-declarations> ()
  194. (many? (named-seq? (<- dec (<declaration>)) #\; dec)))
  195. (defun <fun-declarations> ()
  196. (many? (named-seq? (<- dec (<declaration>)) #\; dec)))
  197. (defstruct tl-program constructors functions)
  198. (defun <tl-program> ()
  199. (named-seq? (<- hd (<constr-declarations>))
  200. (<- tl (many?
  201. (choice
  202. (named-seq? "---" "functions" "---"
  203. (<- decs (<fun-declarations>))
  204. (cons :funcs decs))
  205. (named-seq? "---" "types" "---"
  206. (<- decs (<constr-declarations>))
  207. (cons :constrs decs)))))
  208. (make-tl-program
  209. :constructors (append hd (mapcar #'cdr (remove :funcs tl :key #'car)))
  210. :functions (mapcar #'cdr (remove :constrs tl :key #'car)))))