aboutsummaryrefslogtreecommitdiff
path: root/module/c/to-token.scm
blob: 53db7e592a14ab977992ca02cac6c87ae551da88 (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
(define-module (c to-token)
  :use-module ((system base lalr)
               :select (make-lexical-token))
  :use-module (c cpp-types)
  :use-module ((c lex2) :select (parse-c-number))
  ;; :use-module (hnh util type)
  :export (preprocessing-token->token))

(define (pp-number->c-number token)
  (parse-c-number (pp-number? token)))

(define keywords
  '("auto" "break" "case" "char" "const" "continue" "default"
    "do" "double" "else" "enum" "extern" "float" "for" "goto"
    "if" "inline" "int" "long" "register" "restrict" "return"
    "short" "signed" "sizeof" "static" "struct" "switch"
    "typedef" "union" "unsigned" "void" "volatile" "while"
    "_Alignas" "_Alignof" "_Atomic" "_Bool" "_Complex"
    "_Generic" "_Imaginary" "_Noreturn" "_Static_assert"
    "_Thread_local"))

;; 6.4 paragraph 2
;; Each preprocessing toket thas is converted to a token shall have the
;; lexcal form of a keyword, an identifier, a constant, a string literal,
;; or a puncturtor
(define (preprocessing-token->token cpp-token)
  ;; Guile's cond handles multiple from expr, if written on the form
  ;; (cond (expr check => proc) ...)
  (cond ((string-token? cpp-token)
         (lambda (a . _) a)
         => (lambda content
              (make-lexical-token 'string-literal #f content)))

        ((identifier-token? cpp-token)
            => (lambda (name)
                 (if (member name keywords)
                     (string->symbol name)
                     (make-lexical-token 'identifier #f name))))

        ((pp-number? cpp-token)
         => (lambda (content)
              ;; TOOD should return an integer-constant or a floating-constant
              (make-lexical-token 'constant #f content)))

        ((character-constant? cpp-token)
         (lambda (a . _) a)
         => (lambda content (make-lexical-token 'constant #f content)))

        ((punctuator-token? cpp-token)
         => (lambda (s)
              (cond ((string=? s "{") 'lbrace)
                    ((string=? s "}") 'rbrace)
                    ((string=? s "[") 'lbrack)
                    ((string=? s "]") 'rbrack)
                    ((string=? s "(") 'lparen)
                    ((string=? s ")") 'rparen)
                    ((string=? s ".") 'dot)
                    ((string=? s "|") 'pipe)
                    ((string=? s "||") 'pipe2)
                    ((string=? s ";") 'semicolon)
                    ((string=? s "|=") 'pipe=)
                    ((string=? s ",") 'comma)
                    ((string=? s "#") 'hash)
                    ((string=? s "##") 'hash2)
                    (else (string->symbol s)))))

        (else
         (scm-error 'cpp-error "preprocessing-token->token"
                    "Can't convert ~s into a \"regular\" token."
                    (list cpp-token) #f))))