(defpackage tl-rpc (:use :cl :parser-combinators :alexandria)) (in-package :tl-rpc) (defun not-equal (a b) (not (equal a b))) (defun () (named-seq? (<- char (choice (sat (curry #'not-equal #\*)) (except? #\* "*/"))) (string char))) (defun (ml-comment) (named-seq? (<- content (many? (choice (named-seq? (<- inner ml-comment) (concatenate 'string "/*" inner "*/")) ()))) (apply #'concatenate 'string content))) (defun () (named? ml-comment (bracket? "/*" ( ml-comment) "*/"))) (defun () (bracket? "//" (named-seq? (<- comment (many? (sat (curry #'not-equal #\Newline)))) (coerce comment 'string)) #\Newline)) (defun () (sat (rcurry #'member '(#\; #\( #\) #\{ #\} #\. #\# #\: #\[ #\] #\= #\? #\% #\+ #\< #\> #\, #\* #\!)))) (defun () (choice (between? (sat #'(lambda (i) (or (alphanumericp i) (member i '(#\_))))) 1 nil 'string) (quoted? :quote-char #\`))) (defun tokenize (input) (remove :whitespace (parse-string* (many? (choices () () (chook? :whitespace (choices (whitespace?) "---" () ())))) input))) ;; Actual parsers (defun () (choice (digit?) (sat (rcurry #'member '(#\a #\b #\c #\d #\e #\f))))) (defun () (choice (lower?) (upper?))) (defun () (choices () (digit?) #\_)) (defmacro def-string-parser (name arguments &body body) (with-unique-names (inp) (multiple-value-bind (forms declarations docstring) (parse-body body :documentation t) `(defun ,name ,arguments ,docstring ,@declarations (sat (lambda (,inp) (and (stringp ,inp) (parse-string* ,@forms ,inp :complete t)))))))) (defun concat (&rest args) (apply #'concatenate 'string args)) (defun string-concat (args) (apply #'concatenate 'string (mapcar 'string args))) (def-string-parser () (named-seq? (<- hd (lower?)) (<- tl (many? ())) (coerce (cons hd tl) 'string))) (def-string-parser () (named-seq? (<- hd (upper?)) (<- tl (many? ())) (coerce (cons hd tl) 'string))) (def-string-parser (&optional len) (between? () len len)) (defun () ()) (defstruct ident ns id name) (defun () (named-seq? (<- ns (opt? (seq-list? () #\.))) (<- id ()) (make-ident :ns (car ns) :id id))) (defun () (named-seq? (<- ns (opt? (seq-list? () #\.))) (<- id ()) (make-ident :ns (car ns) :id id))) (defun () (named-seq? (<- id ()) (<- name (opt? (seq-list? #\# ( 8)))) (progn (when name (setf (ident-name id) (second name))) id))) (defun () (many1? (digit?))) (defun () ()) (defun sep? (&optional accept-empty) (whitespace? :accept-empty accept-empty)) (defun () (choice () "_")) (defun () (choice () "_")) (defun () (choices () () "#")) (defun () (choice () ())) (defun (expr) (named? term (choices (seq-list? "(" expr ")") () () () (seq-list? "%" term) (seq-list? () "<" (sepby1? expr ",") ">") ))) (defun (expr) (named? subexpr (choices ( expr) (seq-list? () "+" subexpr) (seq-list? subexpr "+" ())))) (defun () (named? expr (many? ( expr)))) (defun () ()) (defun () ()) (defun () ( ())) (defun () ( ())) (defun () (named-seq? "{" (sep? t) (<- vars (sepby1? () (sep?))) (sep? t) ":" (opt? "!") (<- type-expr ()) (sep? t) "}" (sep? t) (list :opt-args vars type-expr))) (defun () ()) (defun () (choices () "_")) (defun () (seq-list? () (opt? (seq-list? "." ())) "?")) (defun () (named? args (choices (seq-list? () ":" (opt? ()) (opt? "!") ()) (seq-list? (opt? (seq-list? () ":")) (opt? (seq-list? () "*")) "[" (many? args) "]") (seq-list? "(" (many1? ()) ":" (opt? "!") () ")") (seq-list? (opt? "!") ())))) (defun () (choices (seq-list? () (many? ( ()))) (seq-list? () "<" (sepby1? ( ()) ",") ">"))) (defun () (named-seq? (<- comb ()) (sep?) (<- opt-args (many? ())) (sep? t) (<- args (many? ())) (sep? t) "=" (sep?) (<- result-type ()) (sep? t) ";" (list :comb-decl comb opt-args args result-type))) (defun () (choices (named-seq? (<- type ()) (sep?) (<- ex (many1? ( ()))) (sep?) ";" (list :part-type type ex)) (named-seq? (<- type ()) (sep?) "<" (<- ex (sepby1? () ",")) ">" (list :part-type type ex)))) (defun () (seq-list? () (many1? ( ())))) (defun () (choices () ())) (defun () (named-seq? (<- comb ()) (sep?) "?" (sep?) "=" (sep?) (<- type ()) (sep? t) ";" (list :builtin-decl comb type))) (defun () (named-seq? (<- type (choices "New" "Final" "Empty")) (<- ind ()) #\; (list :final-decl type ind))) (defun () (choices () () () ())) (defun () (many? (named-seq? (<- dec ()) #\; dec))) (defun () (many? (named-seq? (<- dec ()) #\; dec))) (defstruct tl-program constructors functions) (defun () (named-seq? (<- hd ()) (<- tl (many? (choice (named-seq? "---" "functions" "---" (<- decs ()) (cons :funcs decs)) (named-seq? "---" "types" "---" (<- decs ()) (cons :constrs decs))))) (make-tl-program :constructors (append hd (mapcar #'cdr (remove :funcs tl :key #'car))) :functions (mapcar #'cdr (remove :constrs tl :key #'car)))))