summaryrefslogtreecommitdiff
path: root/header.lisp
blob: 36b34d9c1eb0683a889ab2430e8d85cd1a48bdc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(in-package #:header)

; TODO: structs/unions, enums, typedefs, handle preprocessor stuff.

(defparser whitespace ()
  (optional (many (unit #'whitespace?))))

(defparser preprocessor ()
  (comp ((_ (unit #\#))
         (keyword (many (unit #'alphanumericp)))
         (_ whitespace)
         (body (optional (many (one-of (unit (char/= it #\Newline))
                                       (comp ((_ (unit #\Backslash))
                                              (c (unit)))
                                         c)))))
         (_ (unit #\Newline)))
    (cons (coerce keyword 'string) (coerce body 'string))))

(defparser block-comment ()
  (comp ((_ (literal "/*"))
         (_ (optional
              (many
                (comp ((end? (optional (literal "*/")))
                       (other (if end?
                                (fail "Unreachable")
                                (unit))))
                  other))))
         (_ (literal "*/")))
    nil))

(defparser line-comment ()
  (comp ((_ (literal "//"))
         (_ (optional (many (unit (char/= it #\Newline)))))
         (_ (unit #\Newline)))
    nil))

(defun valid-char? (c first?)
  (or (if first?
        (alpha-char-p c)
        (alphanumericp c))
      (some (lambda (x) (char= c x))
            '(#\_ #\@ #\# #\$))))

(defparser identifier ()
  (comp ((first (unit (valid-char? it t)))
         (rest (optional (many (unit (valid-char? it nil))))))
    (coerce (cons first rest) 'string)))

(defparser function-declaration ()
  (comp ((type identifier)
         (_ whitespace)
         (name identifier)
         (_ whitespace)
         (args (within
                 (unit #\()
                 (optional (interlinked
                             (comp ((_ whitespace)
                                    (type (identifier))
                                    (_ whitespace)
                                    (stars (optional (many (unit #\*))))
                                    (_ whitespace)
                                    (name (optional identifier))
                                    (_ whitespace))
                               (list type (length stars) name))
                             (unit #\,)))
                 (unit #\))))
         (_ whitespace)
         (_ (unit #\;)))
    (list type name args)))

(defparser parser ()
  (optional (many (within whitespace
                          (one-of block-comment
                                  line-comment
                                  preprocessor
                                  function-declaration))
                  :all t)))