-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgenerate.scm
executable file
·110 lines (94 loc) · 3.5 KB
/
generate.scm
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#! /usr/bin/guile -s
!#
(use-modules (htmlprag)
(sxml xpath)
(srfi srfi-1)
(srfi srfi-9)
(ice-9 regex)
(system foreign))
(define-record-type al-func
(make-al-func name return c-name params)
al-func?
(name al-func-name)
(return al-func-return)
(c-name al-func-c-name)
(params al-func-params))
(define (al-func-valid? func)
(not (string=? (al-func-return func) "unknown")))
(define (format-al-func-params params)
(define (build-params-list)
(let ((param-list (reduce (lambda (param prev)
(string-append prev " " param))
"" params)))
(string-append "(list " param-list ")")))
(if (string=? (car params) "void")
"'()"
(build-params-list)))
(define (print-al-func func)
(format (current-output-port)
"~A(define-foreign %~A\n ~A ~s ~A)\n"
(if (al-func-valid? func) "" "INVALID ")
(al-func-name func)
(al-func-return func)
(al-func-c-name func)
(format-al-func-params (al-func-params func))))
(define (print-export-list funcs)
(display "#:export (")
(for-each (lambda (func)
(when (al-func? func)
(display (al-func-name func))
(newline)))
funcs)
(display ")\n"))
(define regex "al_[[:alnum:]_]+")
(define types '(("^[:word:]+ \\*" . "'*")
("^bool" . "uint8")
("^int" . "int")
("^float" . "float")
("^double" . "double")
("^uint32_t" . "uint32")
("^unsigned char" . "uint8")
("^unsigned int" . "unsigned-int")
("^const char *" . "'*")
("^char const *" . "'*")
("^void" . "void")
("^ALLEGRO_" . "'*")
("^const ALLEGRO_" . "'*")))
(define (make-procedure-name c-name)
(regexp-substitute/global #f "_" c-name 'pre "-" 'post))
(define (parse-parameter param)
(let* ((param (string-trim-both param))
(type (find (lambda (type)
(regexp-match? (string-match (car type) param)))
types)))
(if type
(cdr type)
"unknown")))
(define (generate-binding declaration)
(define (parse-parameters params-string)
(map parse-parameter (string-split params-string #\,)))
(let ((match (string-match regex declaration)))
(when (regexp-match? match)
(let ((prefix (string-trim-both (match:prefix match)))
(suffix (string-trim (string-trim-right (match:suffix match) #\)) #\())
(substring (string-trim-both (match:substring match))))
(make-al-func (make-procedure-name substring)
(parse-parameter prefix)
substring
(parse-parameters suffix))))))
(define (merge-lines lst)
(reduce string-concatenate "" lst))
(call-with-input-file (second (program-arguments))
(lambda (port)
(let* ((declarations ((sxpath '(// pre code)) (html->sxml port)))
(funcs (map (lambda (func)
(generate-binding (string-concatenate (cdr func))))
declarations)))
(print-export-list funcs)
(newline)
(for-each (lambda (func)
(when (al-func? func)
(print-al-func func)
(newline)))
funcs))))
(generate-binding "void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue,\nALLEGRO_EVENT_SOURCE *source)")