git.fiddlerwoaroof.com
Browse code

initial commit

fiddlerwoaroof authored on 28/06/2016 16:49:44
Showing 4 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1 @@
1
+This is the stub README.txt for the "phpgen" project.
0 2
new file mode 100644
... ...
@@ -0,0 +1,5 @@
1
+;;;; package.lisp
2
+
3
+(defpackage #:phpgen
4
+  (:use #:cl #:alexandria #:serapeum #:fw.lu))
5
+
0 6
new file mode 100644
... ...
@@ -0,0 +1,13 @@
1
+;;;; phpgen.asd
2
+
3
+(asdf:defsystem #:phpgen
4
+  :description "Describe phpgen here"
5
+  :author "Your Name <your.name@example.com>"
6
+  :license "Specify license here"
7
+  :depends-on (#:fwoar.lisputils
8
+               #:alexandria
9
+               #:serapeum)
10
+  :serial t
11
+  :components ((:file "package")
12
+               (:file "phpgen")))
13
+
0 14
new file mode 100644
... ...
@@ -0,0 +1,120 @@
1
+;;;; phpgen.lisp
2
+
3
+(in-package #:phpgen)
4
+
5
+;;; "phpgen" goes here. Hacks and glory await!
6
+
7
+(defgeneric generate-php (ast &optional level))
8
+
9
+(defclass ast ()
10
+  ((%children :initarg :children :accessor children :initform '())))
11
+
12
+(defclass statement (ast)
13
+  ((%statement-control :initarg :statement-control :accessor statement-control :initform nil))
14
+  (:documentation "A linguistic construct without a return value"))
15
+
16
+(defclass expression (ast)
17
+  ()
18
+  (:documentation "A linguistic construct with a return value"))
19
+
20
+(defmethod generate-php ((ast string) &optional level)
21
+  (declare (ignore level))
22
+  (when (ends-with #\; ast)
23
+    (setf ast (subseq ast (length ast))))
24
+  (trim-whitespace ast))
25
+
26
+(defmethod separate-children ((ast ast))
27
+  " ")
28
+
29
+(defmethod separate-children ((ast statement))
30
+  (format nil ";~%"))
31
+
32
+
33
+(defmethod generate-php ((ast ast) &optional (level 0))
34
+  (apply #'concatenate 'string
35
+         (loop for child in (children ast)
36
+               collect (format nil "~vt~a~a"
37
+                               (* 4 (1+ level))
38
+                               (generate-php child (1+ level))
39
+                               (separate-children ast)))))
40
+
41
+(defmethod generate-php :around ((ast statement) &optional (level 0))
42
+  (declare (ignore level))
43
+  (format nil "~a{~%~a~&}~a~%"
44
+          (format-preamble ast (statement-control ast))
45
+          (call-next-method)
46
+          (format-postamble ast (statement-control ast))))
47
+
48
+(defclass conditional-statement (statement)
49
+  ())
50
+
51
+(defmethod format-postamble ((ast conditional-statement) value)
52
+  (declare (ignore ast))
53
+  (format nil "" value))
54
+
55
+(defmethod format-preamble ((ast conditional-statement) value)
56
+  (declare (ignore ast))
57
+  (format nil "(~a)" value))
58
+
59
+(defclass if-statement (conditional-statement)
60
+  ())
61
+
62
+(defclass while-statement (conditional-statement)
63
+  ())
64
+
65
+(defclass do-while-statement (conditional-statement)
66
+  ())
67
+
68
+(defmacro define-conditional-statement (name &optional (keyword (string-downcase name)))
69
+  (let ((name (intern (format nil "~a-STATEMENT" name))))
70
+    `(progn
71
+       (defclass ,name (conditional-statement)
72
+         ())
73
+
74
+       (defmethod generate-php :around ((ast ,name) &optional level)
75
+         (declare (ignore level))
76
+         (format nil ,(format nil "~a ~~a" keyword)
77
+                 (call-next-method))))))
78
+
79
+(define-conditional-statement if)
80
+(define-conditional-statement elseif "elseif")
81
+(define-conditional-statement while "while")
82
+
83
+(defmethod generate-php :around ((ast do-while-statement) &optional level)
84
+  (declare (ignore level))
85
+  (format nil "do ~a"
86
+          (call-next-method)))
87
+
88
+(defmethod format-preamble ((ast do-while-statement) value)
89
+  "")
90
+
91
+(defmethod format-postamble ((ast do-while-statement) value)
92
+  (format nil " while (~a)" value))
93
+
94
+(defclass assignment (expression)
95
+  ((place :initarg :place :accessor ast-place :initform nil)
96
+   (value :initarg :value :accessor ast-value :initform nil)))
97
+
98
+(defclass function-call (expression)
99
+  ((name :initarg :name :accessor ast-name :initform nil)))
100
+
101
+(defmethod generate-php ((ast function-call) &optional level)
102
+  (declare (ignore level))
103
+  (format nil "~a(~{~a~^, ~})"
104
+          (ast-name ast)
105
+          (mapcar #'generate-php (children ast))))
106
+
107
+(defmethod generate-php ((ast assignment) &optional level)
108
+  (declare (ignore level))
109
+  (format nil "~a = ~a"
110
+          (generate-php (ast-place ast))
111
+          (generate-php (ast-value ast))))
112
+
113
+(trace generate-php)
114
+
115
+(generate-php "bar")
116
+(generate-php (make-instance 'ast :children (list "bar" "baz")))
117
+(generate-php (make-instance 'function-call :name "foo" :children (list "bar" "baz")))
118
+(generate-php (make-instance 'do-while-statement :statement-control "foo"
119
+                             :children (list "bar"
120
+                                             "baz")))