##// END OF EJS Templates
Locals
naryl -
r14:b6bc7c3f default
parent child Browse files
Show More
@@ -0,0 +1,8 b''
1
2 # locals
3
4 var = 1
5 dynamic { local var = 2 & *pl var }
6 *pl var
7
8 ----- locals ---------------
@@ -1,6 +1,9 b''
1
2 * string array keys as addition to number keys
3 * arr[] notation (i.e. with empty index)
1
4
2 * Windows GUI (for the compiler)
5 * Windows GUI (for the compiler)
3 * Save-load game in slots
6 * Save-load game in slots
4 * Resizable frames
7 * Resizable frames
5 * Build Istreblenie
8 * Build Istreblenie
6 ** modifying it to suit compiler specifics No newline at end of file
9 ** modifying it to suit compiler specifics
@@ -1,210 +1,241 b''
1
1
2 (in-package sugar-qsp)
2 (in-package sugar-qsp)
3
3
4 ;;; API deals with DOM manipulation and some bookkeeping for the
4 ;;; API deals with DOM manipulation and some bookkeeping for the
5 ;;; intrinsics, namely variables
5 ;;; intrinsics, namely variables
6 ;;; API is an implementation detail and has no QSP documentation. It
6 ;;; API is an implementation detail and has no QSP documentation. It
7 ;;; doesn't call intrinsics
7 ;;; doesn't call intrinsics
8
8
9 (setf (root api) (ps:create))
9 (setf (root api) (ps:create))
10
10
11 ;;; Utils
11 ;;; Utils
12
12
13 (defm (root api make-act-html) (title img)
13 (defm (root api make-act-html) (title img)
14 (+ "<a class='qsp-act' href='#' onclick='SugarQSP.acts[\"" title "\"].act();'>"
14 (+ "<a class='qsp-act' href='#' onclick='SugarQSP.acts[\"" title "\"].act();'>"
15 title
15 title
16 "</a>"))
16 "</a>"))
17
17
18 (defm (root api make-menu-item-html) (num title img loc)
18 (defm (root api make-menu-item-html) (num title img loc)
19 (+ "<a href='#' onclick='SugarQSP.api.runMenu(" num ", \"" loc "\")();'>"
19 (+ "<a href='#' onclick='SugarQSP.api.runMenu(" num ", \"" loc "\")();'>"
20 "<img src='" img "'>"
20 "<img src='" img "'>"
21 title
21 title
22 "</a>"))
22 "</a>"))
23
23
24 ;; To be used in saving game
24 ;; To be used in saving game
25 (defm (root api stash-state) ()
25 (defm (root api stash-state) ()
26 (setf (root state-stash)
26 (setf (root state-stash)
27 (*j-s-o-n.stringify
27 (*j-s-o-n.stringify
28 (ps:create vars (root vars)
28 (ps:create vars (root vars)
29 objs (root objs)
29 objs (root objs)
30 next-location (root current-location))))
30 next-location (root current-location))))
31 (values))
31 (values))
32
32
33 (defm (root api state-to-base64) ()
33 (defm (root api state-to-base64) ()
34 (btoa (encode-u-r-i-component (root state-stash))))
34 (btoa (encode-u-r-i-component (root state-stash))))
35
35
36 (defm (root api base64-to-state) (data)
36 (defm (root api base64-to-state) (data)
37 (setf (root state-stash) (decode-u-r-i-component (atob data)))
37 (setf (root state-stash) (decode-u-r-i-component (atob data)))
38 (let ((data (*j-s-o-n.parse (root state-stash))))
38 (let ((data (*j-s-o-n.parse (root state-stash))))
39 (api-call clear-id :qsp-main)
39 (api-call clear-id :qsp-main)
40 (api-call clear-id :qsp-stat)
40 (api-call clear-id :qsp-stat)
41 (api-call clear-act)
41 (api-call clear-act)
42 (setf (root vars) (ps:@ data vars))
42 (setf (root vars) (ps:@ data vars))
43 (setf (root objs) (ps:@ data objs))
43 (setf (root objs) (ps:@ data objs))
44 (setf (root current-location) (ps:@ data next-location))
44 (setf (root current-location) (ps:@ data next-location))
45 (funcall (root locs (root current-location)))
45 (funcall (root locs (root current-location)))
46 (api-call update-objs)
46 (api-call update-objs)
47 (values)))
47 (values)))
48
48
49 ;;; Misc
49 ;;; Misc
50
50
51 (defm (root api clear-id) (id)
51 (defm (root api clear-id) (id)
52 (setf (ps:chain document (get-element-by-id id) inner-text) ""))
52 (setf (ps:chain document (get-element-by-id id) inner-text) ""))
53
53
54 (defm (root api get-id) (id)
54 (defm (root api get-id) (id)
55 (if (var "USEHTML" 0)
55 (if (var "USEHTML" 0)
56 (ps:chain (document.get-element-by-id id) inner-h-t-m-l)
56 (ps:chain (document.get-element-by-id id) inner-h-t-m-l)
57 (ps:chain (document.get-element-by-id id) inner-text)))
57 (ps:chain (document.get-element-by-id id) inner-text)))
58
58
59 (defm (root api set-id) (id contents)
59 (defm (root api set-id) (id contents)
60 (if (var "USEHTML" 0)
60 (if (var "USEHTML" 0)
61 (setf (ps:chain (document.get-element-by-id id) inner-h-t-m-l) contents)
61 (setf (ps:chain (document.get-element-by-id id) inner-h-t-m-l) contents)
62 (setf (ps:chain (document.get-element-by-id id) inner-text) contents)))
62 (setf (ps:chain (document.get-element-by-id id) inner-text) contents)))
63
63
64 (defm (root api append-id) (id contents)
64 (defm (root api append-id) (id contents)
65 (if (var "USEHTML" 0)
65 (if (var "USEHTML" 0)
66 (incf (ps:chain (document.get-element-by-id id) inner-h-t-m-l) contents)
66 (incf (ps:chain (document.get-element-by-id id) inner-h-t-m-l) contents)
67 (incf (ps:chain (document.get-element-by-id id) inner-text) contents)))
67 (incf (ps:chain (document.get-element-by-id id) inner-text) contents)))
68
68
69 ;;; Function calls
69 ;;; Function calls
70
70
71 (defm (root api init-args) (args)
71 (defm (root api init-args) (args)
72 (dotimes (i (length args))
72 (dotimes (i (length args))
73 (if (numberp (elt args i))
73 (if (numberp (elt args i))
74 (set (var args i) (elt args i))
74 (set (var args i) (elt args i))
75 (set (var $args i) (elt args i)))))
75 (set (var $args i) (elt args i)))))
76
76
77 (defm (root api get-result) ()
77 (defm (root api get-result) ()
78 (if (not (equal "" (var $result 0)))
78 (if (not (equal "" (var $result 0)))
79 (var $result 0)
79 (var $result 0)
80 (var result 0)))
80 (var result 0)))
81
81
82 ;;; Text windows
82 ;;; Text windows
83
83
84 (defm (root api key-to-id) (key)
84 (defm (root api key-to-id) (key)
85 (case key
85 (case key
86 (:main "qsp-main")
86 (:main "qsp-main")
87 (:stat "qsp-stat")
87 (:stat "qsp-stat")
88 (:objs "qsp-objs")
88 (:objs "qsp-objs")
89 (:acts "qsp-acts")
89 (:acts "qsp-acts")
90 (:input "qsp-input")
90 (:input "qsp-input")
91 (:dropdown "qsp-dropdown")
91 (:dropdown "qsp-dropdown")
92 (t (report-error "Internal error!"))))
92 (t (report-error "Internal error!"))))
93
93
94 (defm (root api get-frame) (key)
94 (defm (root api get-frame) (key)
95 (document.get-element-by-id (api-call key-to-id key)))
95 (document.get-element-by-id (api-call key-to-id key)))
96
96
97 (defm (root api add-text) (key text)
97 (defm (root api add-text) (key text)
98 (api-call append-id (api-call key-to-id key) text))
98 (api-call append-id (api-call key-to-id key) text))
99
99
100 (defm (root api get-text) (key)
100 (defm (root api get-text) (key)
101 (api-call get-id (api-call key-to-id key)))
101 (api-call get-id (api-call key-to-id key)))
102
102
103 (defm (root api clear-text) (key)
103 (defm (root api clear-text) (key)
104 (api-call clear-id (api-call key-to-id key)))
104 (api-call clear-id (api-call key-to-id key)))
105
105
106 (defm (root api newline) (key)
106 (defm (root api newline) (key)
107 (let ((div (api-call get-frame key)))
107 (let ((div (api-call get-frame key)))
108 (ps:chain div (append-child (document.create-element "br")))))
108 (ps:chain div (append-child (document.create-element "br")))))
109
109
110 (defm (root api enable-frame) (key enable)
110 (defm (root api enable-frame) (key enable)
111 (let ((clss (ps:getprop (api-call get-frame key) 'class-list)))
111 (let ((clss (ps:getprop (api-call get-frame key) 'class-list)))
112 (setf clss.style.display (if enable "block" "none"))
112 (setf clss.style.display (if enable "block" "none"))
113 (values)))
113 (values)))
114
114
115 ;;; Actions
115 ;;; Actions
116
116
117 (defm (root api add-act) (title img act)
117 (defm (root api add-act) (title img act)
118 (setf (ps:getprop (root acts) title)
118 (setf (ps:getprop (root acts) title)
119 (ps:create :img img :act act))
119 (ps:create :img img :act act))
120 (api-call update-acts))
120 (api-call update-acts))
121
121
122 (defm (root api del-act) (title)
122 (defm (root api del-act) (title)
123 (delete (ps:getprop (root acts) title))
123 (delete (ps:getprop (root acts) title))
124 (api-call update-acts))
124 (api-call update-acts))
125
125
126 (defm (root api clear-act) ()
126 (defm (root api clear-act) ()
127 (setf (root acts) (ps:create))
127 (setf (root acts) (ps:create))
128 (api-call clear-id "qsp-acts"))
128 (api-call clear-id "qsp-acts"))
129
129
130 (defm (root api update-acts) ()
130 (defm (root api update-acts) ()
131 (api-call clear-id "qsp-acts")
131 (api-call clear-id "qsp-acts")
132 (ps:for-in (title (root acts))
132 (ps:for-in (title (root acts))
133 (let ((obj (ps:getprop (root acts) title)))
133 (let ((obj (ps:getprop (root acts) title)))
134 (api-call append-id "qsp-acts"
134 (api-call append-id "qsp-acts"
135 (api-call make-act-html title (ps:getprop obj :img))))))
135 (api-call make-act-html title (ps:getprop obj :img))))))
136
136
137 ;;; Variables
137 ;;; Variables
138
138
139 (defm (root api var-slot) (name)
139 (defm (root api var-slot) (name)
140 (if (= (ps:@ name 0) #\$)
140 (if (= (ps:@ name 0) #\$)
141 :str
141 :str
142 :num))
142 :num))
143
143
144 (defm (root api var-real-name) (name)
144 (defm (root api var-real-name) (name)
145 (if (= (ps:@ name 0) #\$)
145 (if (= (ps:@ name 0) #\$)
146 (ps:chain name (substr 1))
146 (ps:chain name (substr 1))
147 name))
147 name))
148
148
149 (defm (root api ensure-var) (name index)
149 (defm (root api ensure-var) (name index)
150 (unless (in name (root vars))
150 (let ((store (api-call var-ref name)))
151 (setf (ps:getprop (root vars) name)
151 (unless store
152 (ps:create)))
152 (setf store (ps:create))
153 (unless (in index (ps:getprop (root vars) name))
153 (setf (ps:getprop (root vars) name) store)))
154 (setf (ps:getprop (root vars) name index)
154 (unless (in index store)
155 (ps:create :num 0 :str "")))
155 (setf (elt store index) (ps:create :num 0 :str "")))
156 (values))
156 (values))
157
157
158 (defm (root api var-ref) (name)
159 (let ((var-name (api-call var-real-name name))
160 (local-store (api-call current-local-frame)))
161 (cond ((in var-name local-store)
162 (ps:getprop local-store))
163 ((in var-name (root vars))
164 (ps:getprop (root vars) var-name))
165 (t nil))))
166
158 (defm (root api get-var) (name index)
167 (defm (root api get-var) (name index)
159 (let ((var-name (api-call var-real-name name)))
168 (let ((store (var-ref name)))
160 (api-call ensure-var var-name index)
169 (if store
161 (ps:getprop (root vars) var-name index
170 (if (in index store)
162 (api-call var-slot name))))
171 (ps:getprop store index (api-call var-slot name))
172 (report-error (+ "Non-existing index: " name "[" index "]")))
173 (report-error (+ "Unknown variable: " name)))))
163
174
164 (defm (root api set-var) (name index value)
175 (defm (root api set-var) (name index value)
165 (let ((var-name (api-call var-real-name name)))
176 (let ((store (var-ref name)))
166 (api-call ensure-var var-name index)
177 (api-call ensure-var var-name index)
167 (setf (ps:getprop (root vars) var-name index
178 (setf (ps:getprop store index
168 (api-call var-slot name))
179 (api-call var-slot name))
169 value)
180 value)
170 (values)))
181 (values)))
171
182
172 (defm (root api get-array) (name type)
183 (defm (root api get-array) (name)
173 (ps:getprop (root vars) (api-call var-real-name name)))
184 (ps:getprop (root vars) name))
174
185
175 (defm (root api kill-var) (name index)
186 (defm (root api set-array) (name value)
176 (if (eq index :whole)
187 (setf (ps:getprop (root vars) name) value))
177 (ps:delete (ps:getprop (root vars) name))
188
178 (ps:delete (ps:getprop (root vars) name index)))
189 (defm (root api kill-var) (name &optional index)
190 (if index
191 (ps:delete (ps:getprop (root vars) name index))
192 (ps:delete (ps:getprop (root vars) name)))
179 (values))
193 (values))
180
194
181 (defm (root api array-size) (name)
195 (defm (root api array-size) (name)
182 (ps:getprop (root vars) (api-call var-real-name name) 'length))
196 (ps:getprop (root vars) (api-call var-real-name name) 'length))
183
197
184 ;;; Objects
198 ;;; Objects
185
199
186 (defm (root api update-objs) ()
200 (defm (root api update-objs) ()
187 (let ((elt (document.get-element-by-id "qsp-objs")))
201 (let ((elt (document.get-element-by-id "qsp-objs")))
188 (setf elt.inner-h-t-m-l "<ul>")
202 (setf elt.inner-h-t-m-l "<ul>")
189 (loop :for obj :in (root objs)
203 (loop :for obj :in (root objs)
190 :do (incf elt.inner-h-t-m-l (+ "<li>" obj)))
204 :do (incf elt.inner-h-t-m-l (+ "<li>" obj)))
191 (incf elt.inner-h-t-m-l "</ul>")))
205 (incf elt.inner-h-t-m-l "</ul>")))
192
206
193 ;;; Menu
207 ;;; Menu
194
208
195 (defm (root api menu) (menu-data)
209 (defm (root api menu) (menu-data)
196 (let ((elt (document.get-element-by-id "qsp-dropdown"))
210 (let ((elt (document.get-element-by-id "qsp-dropdown"))
197 (i 0))
211 (i 0))
198 (setf elt.inner-h-t-m-l "")
212 (setf elt.inner-h-t-m-l "")
199 (loop :for item :in menu-data
213 (loop :for item :in menu-data
200 :do (incf i)
214 :do (incf i)
201 :do (incf elt.inner-h-t-m-l (api-call make-menu-item-html i item.text item.icon item.loc)))
215 :do (incf elt.inner-h-t-m-l (api-call make-menu-item-html i item.text item.icon item.loc)))
202 (setf elt.style.display "block")))
216 (setf elt.style.display "block")))
203
217
204 ;;; Content
218 ;;; Content
205
219
206 (defm (root api clean-audio) ()
220 (defm (root api clean-audio) ()
207 (loop :for k :in (*object.keys (root playing))
221 (loop :for k :in (*object.keys (root playing))
208 :for v := (ps:getprop (root playing) k)
222 :for v := (ps:getprop (root playing) k)
209 :do (when (ps:@ v ended)
223 :do (when (ps:@ v ended)
210 (ps:delete (ps:@ (root playing) k)))))
224 (ps:delete (ps:@ (root playing) k)))))
225
226 ;;; Locals
227
228 (defm (root api push-local-frame) ()
229 (ps:chain (root locals) (push (ps:create))))
230
231 (defm (root api pop-local-frame) ()
232 (ps:chain (root locals) (pop)))
233
234 (defm (root api current-local-frame) ()
235 (elt (root locals) (1- (length (root locals)))))
236
237 (defm (root api new-local) (name)
238 (let ((frame (api-call current-local-frame))
239 (var-name (api-call var-real-name name)))
240 (unless (in var-name frame)
241 (setf (ps:getprop frame var-name) (ps:create)))))
@@ -1,144 +1,150 b''
1
1
2 (in-package sugar-qsp)
2 (in-package sugar-qsp)
3
3
4 ;;;; Macros implementing some intrinsics where it makes sense
4 ;;;; Macros implementing some intrinsics where it makes sense
5 ;;;; E.g. an equivalent JS function exists, or it's a direct API call
5 ;;;; E.g. an equivalent JS function exists, or it's a direct API call
6
6
7 ;;; 1loc
7 ;;; 1loc
8
8
9 ;;; 2var
9 ;;; 2var
10
10
11 (ps:defpsmacro killvar (varname &optional (index :whole))
11 (ps:defpsmacro killvar (varname &optional index)
12 `(api-call kill-var ,varname ,index))
12 `(api-call kill-var ,varname ,index))
13
13
14 (ps:defpsmacro killall ()
14 (ps:defpsmacro killall ()
15 `(api-call kill-all))
15 `(api-call kill-all))
16
16
17 ;;; 3expr
17 ;;; 3expr
18
18
19 (ps:defpsmacro obj (name)
19 (ps:defpsmacro obj (name)
20 `(funcall (root objs includes) ,name))
20 `(funcall (root objs includes) ,name))
21
21
22 (ps:defpsmacro loc (name)
22 (ps:defpsmacro loc (name)
23 `(funcall (root locs includes) ,name))
23 `(funcall (root locs includes) ,name))
24
24
25 (ps:defpsmacro no (arg)
25 (ps:defpsmacro no (arg)
26 `(- -1 ,arg))
26 `(- -1 ,arg))
27
27
28 ;;; 4code
28 ;;; 4code
29
29
30 (ps:defpsmacro qspver ()
30 (ps:defpsmacro qspver ()
31 "0.0.1")
31 "0.0.1")
32
32
33 (ps:defpsmacro curloc ()
33 (ps:defpsmacro curloc ()
34 `(root current-location))
34 `(root current-location))
35
35
36 (ps:defpsmacro rnd ()
36 (ps:defpsmacro rnd ()
37 `(funcall (root lib rand) 1 1000))
37 `(funcall (root lib rand) 1 1000))
38
38
39 (ps:defpsmacro qspmax (&rest args)
39 (ps:defpsmacro qspmax (&rest args)
40 (if (= 1 (length args))
40 (if (= 1 (length args))
41 `(*math.max.apply nil ,@args)
41 `(*math.max.apply nil ,@args)
42 `(*math.max ,@args)))
42 `(*math.max ,@args)))
43
43
44 (ps:defpsmacro qspmin (&rest args)
44 (ps:defpsmacro qspmin (&rest args)
45 (if (= 1 (length args))
45 (if (= 1 (length args))
46 `(*math.min.apply nil ,@args)
46 `(*math.min.apply nil ,@args)
47 `(*math.min ,@args)))
47 `(*math.min ,@args)))
48
48
49 ;;; 5arrays
49 ;;; 5arrays
50
50
51 (ps:defpsmacro arrsize (name)
51 (ps:defpsmacro arrsize (name)
52 `(api-call array-size ,name))
52 `(api-call array-size ,name))
53
53
54 ;;; 6str
54 ;;; 6str
55
55
56 (ps:defpsmacro len (s)
56 (ps:defpsmacro len (s)
57 `(length ,s))
57 `(length ,s))
58
58
59 (ps:defpsmacro mid (s from &optional count)
59 (ps:defpsmacro mid (s from &optional count)
60 `(ps:chain ,s (substring ,from ,count)))
60 `(ps:chain ,s (substring ,from ,count)))
61
61
62 (ps:defpsmacro ucase (s)
62 (ps:defpsmacro ucase (s)
63 `(ps:chain ,s (to-upper-case)))
63 `(ps:chain ,s (to-upper-case)))
64
64
65 (ps:defpsmacro lcase (s)
65 (ps:defpsmacro lcase (s)
66 `(ps:chain ,s (to-lower-case)))
66 `(ps:chain ,s (to-lower-case)))
67
67
68 (ps:defpsmacro trim (s)
68 (ps:defpsmacro trim (s)
69 `(ps:chain ,s (trim)))
69 `(ps:chain ,s (trim)))
70
70
71 (ps:defpsmacro replace (s from to)
71 (ps:defpsmacro replace (s from to)
72 `(ps:chain ,s (replace ,from ,to)))
72 `(ps:chain ,s (replace ,from ,to)))
73
73
74 (ps:defpsmacro val (s)
74 (ps:defpsmacro val (s)
75 `(parse-int ,s 10))
75 `(parse-int ,s 10))
76
76
77 (ps:defpsmacro qspstr (n)
77 (ps:defpsmacro qspstr (n)
78 `(ps:chain ,n (to-string)))
78 `(ps:chain ,n (to-string)))
79
79
80 ;;; 7if
80 ;;; 7if
81
81
82 ;;; 8sub
82 ;;; 8sub
83
83
84 ;;; 9loops
84 ;;; 9loops
85
85
86 ;; JUMP is in ps-macros.lisp (because it's a part of a huge kludge)
86 ;; JUMP is in ps-macros.lisp (because it's a part of a huge kludge)
87
87
88 (ps:defpsmacro exit ()
88 (ps:defpsmacro exit ()
89 `(return-from nil (values)))
89 `(return-from nil (values)))
90
90
91 ;;; 10dynamic
91 ;;; 10dynamic
92
92
93 ;;; 11main
93 ;;; 11main
94
94
95 (ps:defpsmacro desc (s)
95 (ps:defpsmacro desc (s)
96 (declare (ignore s))
96 (declare (ignore s))
97 "")
97 "")
98
98
99 ;;; 12stat
99 ;;; 12stat
100
100
101 (ps:defpsmacro showstat (enable)
101 (ps:defpsmacro showstat (enable)
102 `(api-call enable-frame :stat ,enable))
102 `(api-call enable-frame :stat ,enable))
103
103
104 ;;; 13diag
104 ;;; 13diag
105
105
106 (ps:defpsmacro msg (text)
106 (ps:defpsmacro msg (text)
107 `(alert ,text))
107 `(alert ,text))
108
108
109 ;;; 14act
109 ;;; 14act
110
110
111 (ps:defpsmacro showacts (enable)
111 (ps:defpsmacro showacts (enable)
112 `(api-call enable-frame :acts ,enable))
112 `(api-call enable-frame :acts ,enable))
113
113
114 (ps:defpsmacro delact (name)
114 (ps:defpsmacro delact (name)
115 `(api-call del-act ,name))
115 `(api-call del-act ,name))
116
116
117 (ps:defpsmacro cla ()
117 (ps:defpsmacro cla ()
118 `(api-call clear-act))
118 `(api-call clear-act))
119
119
120 ;;; 15objs
120 ;;; 15objs
121
121
122 (ps:defpsmacro showobjs (enable)
122 (ps:defpsmacro showobjs (enable)
123 `(api-call enable-frame :objs ,enable))
123 `(api-call enable-frame :objs ,enable))
124
124
125 (ps:defpsmacro countobj ()
125 (ps:defpsmacro countobj ()
126 `(length (root objs)))
126 `(length (root objs)))
127
127
128 (ps:defpsmacro getobj (index)
128 (ps:defpsmacro getobj (index)
129 `(or (elt (root objs) ,index) ""))
129 `(or (elt (root objs) ,index) ""))
130
130
131 ;;; 16menu
131 ;;; 16menu
132
132
133 ;;; 17sound
133 ;;; 17sound
134
134
135 (ps:defpsmacro isplay (filename)
135 (ps:defpsmacro isplay (filename)
136 `(funcall (root playing includes) ,filename))
136 `(funcall (root playing includes) ,filename))
137
137
138 ;;; 18img
138 ;;; 18img
139
139
140 ;;; 19input
140 ;;; 19input
141
141
142 ;;; 20time
142 ;;; 20time
143
143
144 ;;; misc
144 ;;; 21local
145
146 (ps:defpsmacro local (var &optional expr)
147 `(progn
148 (api-call new-local ,(string (second var)))
149 ,@(when expr
150 `((set ,var ,expr)))))
@@ -1,321 +1,323 b''
1
1
2 (in-package sugar-qsp)
2 (in-package sugar-qsp)
3
3
4 ;;;; Functions and procedures defined by the QSP language.
4 ;;;; Functions and procedures defined by the QSP language.
5 ;;;; They can call api and deal with locations and other data directly.
5 ;;;; They can call api and deal with locations and other data directly.
6 ;;;; Except vars. Use VAR and SET or GET-VAR and SET-VAR api calls.
6 ;;;; Except vars. Use VAR and SET or GET-VAR and SET-VAR api calls.
7
7
8 (setf (root lib) (ps:create))
8 (setf (root lib) (ps:create))
9
9
10 ;;; 1loc
10 ;;; 1loc
11
11
12 (defm (root lib goto) (target &rest args)
12 (defm (root lib goto) (target &rest args)
13 (api-call clear-text :main)
13 (api-call clear-text :main)
14 (apply (root lib xgoto) target args))
14 (apply (root lib xgoto) target args))
15
15
16 (defm (root lib xgoto) (target &rest args)
16 (defm (root lib xgoto) (target &rest args)
17 (api-call clear-act)
17 (api-call clear-act)
18 (api-call init-args args)
18 (api-call init-args args)
19 (setf (root current-location) (ps:chain target (to-upper-case)))
19 (setf (root current-location) (ps:chain target (to-upper-case)))
20 (api-call stash-state)
20 (api-call stash-state)
21 (funcall (ps:getprop (root locs) (root current-location))))
21 (funcall (ps:getprop (root locs) (root current-location))))
22
22
23 ;;; 2var
23 ;;; 2var
24
24
25 ;;; 3expr
25 ;;; 3expr
26
26
27 ;;; 4code
27 ;;; 4code
28
28
29 (defm (root lib rand) (a &optional (b 1))
29 (defm (root lib rand) (a &optional (b 1))
30 (let ((min (min a b))
30 (let ((min (min a b))
31 (max (max a b)))
31 (max (max a b)))
32 (+ min (ps:chain *math (random (- max min))))))
32 (+ min (ps:chain *math (random (- max min))))))
33
33
34 ;;; 5arrays
34 ;;; 5arrays
35
35
36 (defm (root lib copyarr) (to from start count)
36 (defm (root lib copyarr) (to from start count)
37 (ps:for ((i start))
37 (ps:for ((i start))
38 ((< i (min (api-call array-size from)
38 ((< i (min (api-call array-size from)
39 (+ start count))))
39 (+ start count))))
40 ((incf i))
40 ((incf i))
41 (api-call set-var to (+ start i)
41 (api-call set-var to (+ start i)
42 (api-call get-var from (+ start i)))))
42 (api-call get-var from (+ start i)))))
43
43
44 (defm (root lib arrpos) (name value &optional (start 0))
44 (defm (root lib arrpos) (name value &optional (start 0))
45 (ps:for ((i start)) ((< i (api-call array-size name))) ((incf i))
45 (ps:for ((i start)) ((< i (api-call array-size name))) ((incf i))
46 (when (eq (api-call get-var name i) value)
46 (when (eq (api-call get-var name i) value)
47 (return i)))
47 (return i)))
48 -1)
48 -1)
49
49
50 (defm (root lib arrcomp) (name pattern &optional (start 0))
50 (defm (root lib arrcomp) (name pattern &optional (start 0))
51 (ps:for ((i start)) ((< i (api-call array-size name))) ((incf i))
51 (ps:for ((i start)) ((< i (api-call array-size name))) ((incf i))
52 (when (funcall (ps:getprop (api-call get-var name i) 'match) pattern)
52 (when (funcall (ps:getprop (api-call get-var name i) 'match) pattern)
53 (return i)))
53 (return i)))
54 -1)
54 -1)
55
55
56 ;;; 6str
56 ;;; 6str
57
57
58 (defm (root lib instr) (s subs &optional (start 1))
58 (defm (root lib instr) (s subs &optional (start 1))
59 (+ start (ps:chain s (substring (- start 1)) (search subs))))
59 (+ start (ps:chain s (substring (- start 1)) (search subs))))
60
60
61 (defm (root lib isnum) (s)
61 (defm (root lib isnum) (s)
62 (if (is-na-n s)
62 (if (is-na-n s)
63 0
63 0
64 -1))
64 -1))
65
65
66 (defm (root lib strcomp) (s pattern)
66 (defm (root lib strcomp) (s pattern)
67 (if (s.match pattern)
67 (if (s.match pattern)
68 -1
68 -1
69 0))
69 0))
70
70
71 (defm (root lib strfind) (s pattern group)
71 (defm (root lib strfind) (s pattern group)
72 (let* ((re (ps:new (*reg-exp pattern)))
72 (let* ((re (ps:new (*reg-exp pattern)))
73 (match (re.exec s)))
73 (match (re.exec s)))
74 (match.group group)))
74 (match.group group)))
75
75
76 (defm (root lib strpos) (s pattern &optional (group 0))
76 (defm (root lib strpos) (s pattern &optional (group 0))
77 (let* ((re (ps:new (*reg-exp pattern)))
77 (let* ((re (ps:new (*reg-exp pattern)))
78 (match (re.exec s))
78 (match (re.exec s))
79 (found (match.group group)))
79 (found (match.group group)))
80 (if found
80 (if found
81 (s.search found)
81 (s.search found)
82 0)))
82 0)))
83
83
84 ;;; 7if
84 ;;; 7if
85
85
86 ;; Has to be a function because it always evaluates all three of its
86 ;; Has to be a function because it always evaluates all three of its
87 ;; arguments
87 ;; arguments
88 (defm (root lib iif) (cond-expr then-expr else-expr)
88 (defm (root lib iif) (cond-expr then-expr else-expr)
89 (if cond-expr then-expr else-expr))
89 (if cond-expr then-expr else-expr))
90
90
91 ;;; 8sub
91 ;;; 8sub
92
92
93 (defm (root lib gosub) (target &rest args)
93 (defm (root lib gosub) (target &rest args)
94 (conserving-vars (args result)
94 (conserving-vars (__funcall args result)
95 (api-call init-args args)
95 (api-call init-args args)
96 (funcall (ps:getprop (root locs) target))
96 (funcall (ps:getprop (root locs) target))
97 (values)))
97 (values)))
98
98
99 (defm (root lib func) (target &rest args)
99 (defm (root lib func) (target &rest args)
100 (conserving-vars (args result)
100 (conserving-vars (__funcall args result)
101 (api-call init-args args)
101 (api-call init-args args)
102 (funcall (ps:getprop (root locs) target))
102 (funcall (ps:getprop (root locs) target))
103 (api-call get-result)))
103 (api-call get-result)))
104
104
105 ;;; 9loops
105 ;;; 9loops
106
106
107 ;;; 10dynamic
107 ;;; 10dynamic
108
108
109 (defm (root lib dyneval) (block &rest args)
109 (defm (root lib dyneval) (block &rest args)
110 (conserving-vars (args result)
110 (conserving-vars (__funcall args result)
111 (api-call init-args args)
111 (api-call init-args args)
112 (funcall block)
112 (funcall block)
113 (api-call get-result)))
113 (api-call get-result)))
114
114
115 (defm (root lib dynamic) (&rest args)
115 (defm (root lib dynamic) (&rest args)
116 (conserving-vars (args result)
116 (conserving-vars (__funcall args result)
117 (api-call init-args args)
117 (api-call init-args args)
118 (funcall block)
118 (funcall block)
119 (values)))
119 (values)))
120
120
121 ;;; 11main
121 ;;; 11main
122
122
123 (defm (root lib main-p) (s)
123 (defm (root lib main-p) (s)
124 (api-call add-text :main s)
124 (api-call add-text :main s)
125 (values))
125 (values))
126
126
127 (defm (root lib main-pl) (s)
127 (defm (root lib main-pl) (s)
128 (api-call add-text :main s)
128 (api-call add-text :main s)
129 (api-call newline :main)
129 (api-call newline :main)
130 (values))
130 (values))
131
131
132 (defm (root lib main-nl) (s)
132 (defm (root lib main-nl) (s)
133 (api-call newline :main)
133 (api-call newline :main)
134 (api-call add-text :main s)
134 (api-call add-text :main s)
135 (values))
135 (values))
136
136
137 (defm (root lib maintxt) (s)
137 (defm (root lib maintxt) (s)
138 (api-call get-text :main)
138 (api-call get-text :main)
139 (values))
139 (values))
140
140
141 ;; For clarity (it leaves a lib.desc() call in JS)
141 ;; For clarity (it leaves a lib.desc() call in JS)
142 (defm (root lib desc) (s)
142 (defm (root lib desc) (s)
143 "")
143 "")
144
144
145 (defm (root lib main-clear) ()
145 (defm (root lib main-clear) ()
146 (api-call clear-text :main)
146 (api-call clear-text :main)
147 (values))
147 (values))
148
148
149 ;;; 12stat
149 ;;; 12stat
150
150
151 (defm (root lib stat-p) (s)
151 (defm (root lib stat-p) (s)
152 (api-call add-text :stat s)
152 (api-call add-text :stat s)
153 (values))
153 (values))
154
154
155 (defm (root lib stat-pl) (s)
155 (defm (root lib stat-pl) (s)
156 (api-call add-text :stat s)
156 (api-call add-text :stat s)
157 (api-call newline :stat)
157 (api-call newline :stat)
158 (values))
158 (values))
159
159
160 (defm (root lib stat-nl) (s)
160 (defm (root lib stat-nl) (s)
161 (api-call newline :stat)
161 (api-call newline :stat)
162 (api-call add-text :stat s)
162 (api-call add-text :stat s)
163 (values))
163 (values))
164
164
165 (defm (root lib stattxt) (s)
165 (defm (root lib stattxt) (s)
166 (api-call get-text :stat)
166 (api-call get-text :stat)
167 (values))
167 (values))
168
168
169 (defm (root lib stat-clear) ()
169 (defm (root lib stat-clear) ()
170 (api-call clear-text :stat)
170 (api-call clear-text :stat)
171 (values))
171 (values))
172
172
173 (defm (root lib cls) ()
173 (defm (root lib cls) ()
174 (funcall (root lib stat-clear))
174 (funcall (root lib stat-clear))
175 (funcall (root lib main-clear))
175 (funcall (root lib main-clear))
176 (funcall (root lib cla))
176 (funcall (root lib cla))
177 (funcall (root lib cmdclear))
177 (funcall (root lib cmdclear))
178 (values))
178 (values))
179
179
180 ;;; 13diag
180 ;;; 13diag
181
181
182 ;;; 14act
182 ;;; 14act
183
183
184 (defm (root lib curacts) ()
184 (defm (root lib curacts) ()
185 (let ((acts (root acts)))
185 (let ((acts (root acts)))
186 (lambda ()
186 (lambda ()
187 (setf (root acts) acts)
187 (setf (root acts) acts)
188 (values))))
188 (values))))
189
189
190 ;;; 15objs
190 ;;; 15objs
191
191
192 (defm (root lib addobj) (name)
192 (defm (root lib addobj) (name)
193 (ps:chain (root objs) (push name))
193 (ps:chain (root objs) (push name))
194 (api-call update-objs)
194 (api-call update-objs)
195 (values))
195 (values))
196
196
197 (defm (root lib delobj) (name)
197 (defm (root lib delobj) (name)
198 (let ((index (ps:chain (root objs) (index-of name))))
198 (let ((index (ps:chain (root objs) (index-of name))))
199 (when (> index -1)
199 (when (> index -1)
200 (funcall (root lib killobj) (1+ index))))
200 (funcall (root lib killobj) (1+ index))))
201 (values))
201 (values))
202
202
203 (defm (root lib killobj) (&optional (num nil))
203 (defm (root lib killobj) (&optional (num nil))
204 (if (eq nil num)
204 (if (eq nil num)
205 (setf (root objs) (list))
205 (setf (root objs) (list))
206 (ps:chain (root objs) (splice (1- num) 1)))
206 (ps:chain (root objs) (splice (1- num) 1)))
207 (api-call update-objs)
207 (api-call update-objs)
208 (values))
208 (values))
209
209
210 ;;; 16menu
210 ;;; 16menu
211
211
212 (defm (root lib menu) (menu-name)
212 (defm (root lib menu) (menu-name)
213 (let ((menu-data (list)))
213 (let ((menu-data (list)))
214 (loop :for item :in (api-call get-array menu-name)
214 (loop :for item :in (api-call get-array (api-call var-real-name menu-name))
215 :do (cond ((string= item "")
215 :do (cond ((string= item "")
216 (break))
216 (break))
217 ((string= item "-:-")
217 ((string= item "-:-")
218 (ps:chain menu-data (push :delimiter)))
218 (ps:chain menu-data (push :delimiter)))
219 (t
219 (t
220 (let* ((tokens (ps:chain item (split ":"))))
220 (let* ((tokens (ps:chain item (split ":"))))
221 (when (= (length tokens) 2)
221 (when (= (length tokens) 2)
222 (tokens.push ""))
222 (tokens.push ""))
223 (let* ((text (ps:chain tokens (splice 0 (- tokens.length 2)) (join ":")))
223 (let* ((text (ps:chain tokens (splice 0 (- tokens.length 2)) (join ":")))
224 (loc (ps:getprop tokens (- tokens.length 2)))
224 (loc (ps:getprop tokens (- tokens.length 2)))
225 (icon (ps:getprop tokens (- tokens.length 1))))
225 (icon (ps:getprop tokens (- tokens.length 1))))
226 (ps:chain menu-data
226 (ps:chain menu-data
227 (push (ps:create text text
227 (push (ps:create text text
228 loc loc
228 loc loc
229 icon icon))))))))
229 icon icon))))))))
230 (api-call menu menu-data)
230 (api-call menu menu-data)
231 (values)))
231 (values)))
232
232
233 ;;; 17sound
233 ;;; 17sound
234
234
235 (defm (root lib play) (filename &optional (volume 100))
235 (defm (root lib play) (filename &optional (volume 100))
236 (let ((audio (ps:new (*audio filename))))
236 (let ((audio (ps:new (*audio filename))))
237 (setf (ps:getprop (root playing) filename) audio)
237 (setf (ps:getprop (root playing) filename) audio)
238 (setf (ps:@ audio volume) (* volume 0.01))
238 (setf (ps:@ audio volume) (* volume 0.01))
239 (ps:chain audio (play))))
239 (ps:chain audio (play))))
240
240
241 (defm (root lib close) (filename)
241 (defm (root lib close) (filename)
242 (funcall (root playing filename) stop)
242 (funcall (root playing filename) stop)
243 (ps:delete (root playing filename)))
243 (ps:delete (root playing filename)))
244
244
245 (defm (root lib closeall) ()
245 (defm (root lib closeall) ()
246 (loop :for k :in (*object.keys (root playing))
246 (loop :for k :in (*object.keys (root playing))
247 :for v := (ps:getprop (root playing) k)
247 :for v := (ps:getprop (root playing) k)
248 :do (funcall v stop))
248 :do (funcall v stop))
249 (setf (root playing) (ps:create)))
249 (setf (root playing) (ps:create)))
250
250
251 ;;; 18img
251 ;;; 18img
252
252
253 (defm (root lib refint) ())
253 (defm (root lib refint) ())
254
254
255 (defm (root lib view) ())
255 (defm (root lib view) ())
256
256
257 ;;; 19input
257 ;;; 19input
258
258
259 (defm (root lib showinput) ())
259 (defm (root lib showinput) ())
260
260
261 (defm (root lib usertxt) ())
261 (defm (root lib usertxt) ())
262
262
263 (defm (root lib cmdclear) ())
263 (defm (root lib cmdclear) ())
264
264
265 (defm (root lib input) ())
265 (defm (root lib input) ())
266
266
267 ;;; 20time
267 ;;; 20time
268
268
269 ;; I wonder if there's a better solution than busy-wait
269 ;; I wonder if there's a better solution than busy-wait
270 (defm (root lib wait) (msec)
270 (defm (root lib wait) (msec)
271 (let* ((now (ps:new (*date)))
271 (let* ((now (ps:new (*date)))
272 (exit-time (+ (funcall now.get-time) msec)))
272 (exit-time (+ (funcall now.get-time) msec)))
273 (loop :while (< (funcall now.get-time) exit-time))))
273 (loop :while (< (funcall now.get-time) exit-time))))
274
274
275 (defm (root lib msecscount) ())
275 (defm (root lib msecscount) ())
276
276
277 (defm (root lib settimer) ())
277 (defm (root lib settimer) ())
278
278
279 ;;; 21local
280
279 ;;; misc
281 ;;; misc
280
282
281 (defm (root lib rgb) ())
283 (defm (root lib rgb) ())
282
284
283 (defm (root lib openqst) ())
285 (defm (root lib openqst) ())
284
286
285 (defm (root lib addqst) ())
287 (defm (root lib addqst) ())
286
288
287 (defm (root lib killqst) ())
289 (defm (root lib killqst) ())
288
290
289 (defm (root lib opengame) (&optional filename)
291 (defm (root lib opengame) (&optional filename)
290 (let ((element (document.create-element :input)))
292 (let ((element (document.create-element :input)))
291 (element.set-attribute :type :file)
293 (element.set-attribute :type :file)
292 (element.set-attribute :id :qsp-opengame)
294 (element.set-attribute :id :qsp-opengame)
293 (element.set-attribute :tabindex -1)
295 (element.set-attribute :tabindex -1)
294 (element.set-attribute "aria-hidden" t)
296 (element.set-attribute "aria-hidden" t)
295 (setf element.style.display :block)
297 (setf element.style.display :block)
296 (setf element.style.visibility :hidden)
298 (setf element.style.visibility :hidden)
297 (setf element.style.position :fixed)
299 (setf element.style.position :fixed)
298 (setf element.onchange
300 (setf element.onchange
299 (lambda (event)
301 (lambda (event)
300 (let* ((file (elt event.target.files 0))
302 (let* ((file (elt event.target.files 0))
301 (reader (ps:new (*file-reader))))
303 (reader (ps:new (*file-reader))))
302 (setf reader.onload
304 (setf reader.onload
303 (lambda (ev)
305 (lambda (ev)
304 (block nil
306 (block nil
305 (let ((target ev.current-target))
307 (let ((target ev.current-target))
306 (unless target.result
308 (unless target.result
307 (return))
309 (return))
308 (api-call base64-to-state target.result)))))
310 (api-call base64-to-state target.result)))))
309 (reader.read-as-text file))))
311 (reader.read-as-text file))))
310 (document.body.append-child element)
312 (document.body.append-child element)
311 (element.click)
313 (element.click)
312 (document.body.remove-child element)))
314 (document.body.remove-child element)))
313
315
314 (defm (root lib savegame) (&optional filename)
316 (defm (root lib savegame) (&optional filename)
315 (let ((element (document.create-element :a)))
317 (let ((element (document.create-element :a)))
316 (element.set-attribute :href (+ "data:text/plain;charset=utf-8," (api-call state-to-base64)))
318 (element.set-attribute :href (+ "data:text/plain;charset=utf-8," (api-call state-to-base64)))
317 (element.set-attribute :download "savegame.sav")
319 (element.set-attribute :download "savegame.sav")
318 (setf element.style.display :none)
320 (setf element.style.display :none)
319 (document.body.append-child element)
321 (document.body.append-child element)
320 (element.click)
322 (element.click)
321 (document.body.remove-child element)))
323 (document.body.remove-child element)))
@@ -1,32 +1,34 b''
1
1
2 (in-package sugar-qsp)
2 (in-package sugar-qsp)
3
3
4 (setf (root)
4 (setf (root)
5 (ps:create
5 (ps:create
6 ;;; Game session state
6 ;;; Game session state
7 ;; Variables
7 ;; Variables
8 vars (ps:create)
8 vars (ps:create)
9 ;; Inventory (objects)
9 ;; Inventory (objects)
10 objs (list)
10 objs (list)
11 ;;; Transient state
11 ;;; Transient state
12 ;; Savegame data
12 ;; Savegame data
13 state-stash (ps:create)
13 state-stash (ps:create)
14 ;; List of audio files being played
14 ;; List of audio files being played
15 playing (ps:create)
15 playing (ps:create)
16 ;; Local variables stack (starts with an empty frame)
17 locals (list)
16 ;;; Game data
18 ;;; Game data
17 ;; ACTions
19 ;; ACTions
18 acts (ps:create)
20 acts (ps:create)
19 ;; Locations
21 ;; Locations
20 locs (ps:create)))
22 locs (ps:create)))
21
23
22 ;; Launch the game from the first location
24 ;; Launch the game from the first location
23 (setf window.onload
25 (setf window.onload
24 (lambda ()
26 (lambda ()
25 (funcall (ps:getprop (root locs)
27 (funcall (ps:getprop (root locs)
26 (ps:chain *object (keys (root locs)) 0)))
28 (ps:chain *object (keys (root locs)) 0)))
27 (values)))
29 (values)))
28
30
29 ;; Close the dropdown on any click
31 ;; Close the dropdown on any click
30 (setf window.onclick
32 (setf window.onclick
31 (lambda (event)
33 (lambda (event)
32 (setf (ps:@ (api-call get-frame :dropdown) style display) "none")))
34 (setf (ps:@ (api-call get-frame :dropdown) style display) "none")))
@@ -1,580 +1,586 b''
1
1
2 (in-package sugar-qsp)
2 (in-package sugar-qsp)
3
3
4 ;;;; Parses TXT source to an intermediate representation
4 ;;;; Parses TXT source to an intermediate representation
5
5
6 ;;; Utility
6 ;;; Utility
7
7
8 (defun remove-nth (list nth)
8 (defun remove-nth (list nth)
9 (append (subseq list 0 nth)
9 (append (subseq list 0 nth)
10 (subseq list (1+ nth))))
10 (subseq list (1+ nth))))
11
11
12 (defun not-quote (char)
12 (defun not-quote (char)
13 (not (eql #\' char)))
13 (not (eql #\' char)))
14
14
15
15
16 (defun not-doublequote (char)
16 (defun not-doublequote (char)
17 (not (eql #\" char)))
17 (not (eql #\" char)))
18
18
19 (defun not-brace (char)
19 (defun not-brace (char)
20 (not (eql #\} char)))
20 (not (eql #\} char)))
21
21
22 (defun not-integer (string)
22 (defun not-integer (string)
23 (when (find-if-not #'digit-char-p string)
23 (when (find-if-not #'digit-char-p string)
24 t))
24 t))
25
25
26 (defun not-newline (char)
26 (defun not-newline (char)
27 (not (eql #\newline char)))
27 (not (eql #\newline char)))
28
28
29 (defun id-any-char (char)
29 (defun id-any-char (char)
30 (and
30 (and
31 (not (digit-char-p char))
31 (not (digit-char-p char))
32 (not (eql #\newline char))
32 (not (eql #\newline char))
33 (not (find char " !:&=<>+-*/,'\"()[]{}"))))
33 (not (find char " !:&=<>+-*/,'\"()[]{}"))))
34
34
35 (defun intern-first (list)
35 (defun intern-first (list)
36 (list* (intern (string-upcase (first list)))
36 (list* (intern (string-upcase (first list)))
37 (rest list)))
37 (rest list)))
38
38
39 (eval-when (:compile-toplevel :load-toplevel :execute)
39 (eval-when (:compile-toplevel :load-toplevel :execute)
40 (defun remove-nil (list)
40 (defun remove-nil (list)
41 (remove nil list)))
41 (remove nil list)))
42
42
43 (defun binop-rest (list)
43 (defun binop-rest (list)
44 (destructuring-bind (ws1 operator ws2 operand2)
44 (destructuring-bind (ws1 operator ws2 operand2)
45 list
45 list
46 (declare (ignore ws1 ws2))
46 (declare (ignore ws1 ws2))
47 (list (intern (string-upcase operator)) operand2)))
47 (list (intern (string-upcase operator)) operand2)))
48
48
49 (defun do-binop% (left-op other-ops)
49 (defun do-binop% (left-op other-ops)
50 (if (null other-ops)
50 (if (null other-ops)
51 left-op
51 left-op
52 (destructuring-bind ((operator right-op) &rest rest-ops)
52 (destructuring-bind ((operator right-op) &rest rest-ops)
53 other-ops
53 other-ops
54 (if (and (listp left-op)
54 (if (and (listp left-op)
55 (eq (first left-op)
55 (eq (first left-op)
56 operator))
56 operator))
57 (do-binop% (append left-op (list right-op)) rest-ops)
57 (do-binop% (append left-op (list right-op)) rest-ops)
58 (do-binop% (list operator left-op right-op) rest-ops)))))
58 (do-binop% (list operator left-op right-op) rest-ops)))))
59
59
60 (defun do-binop (list)
60 (defun do-binop (list)
61 (destructuring-bind (left-op rest-ops)
61 (destructuring-bind (left-op rest-ops)
62 list
62 list
63 (do-binop% left-op
63 (do-binop% left-op
64 (mapcar #'binop-rest rest-ops))))
64 (mapcar #'binop-rest rest-ops))))
65
65
66 (p:defrule line-continuation (and #\_ #\newline)
66 (p:defrule line-continuation (and #\_ #\newline)
67 (:constant nil))
67 (:constant nil))
68
68
69 (p:defrule text-spaces (+ (or #\space #\tab line-continuation))
69 (p:defrule text-spaces (+ (or #\space #\tab line-continuation))
70 (:text t))
70 (:text t))
71
71
72 (p:defrule spaces (+ (or #\space #\tab line-continuation))
72 (p:defrule spaces (+ (or #\space #\tab line-continuation))
73 (:constant nil))
73 (:constant nil))
74
74
75 (p:defrule spaces? (* (or #\space #\tab line-continuation))
75 (p:defrule spaces? (* (or #\space #\tab line-continuation))
76 (:constant nil))
76 (:constant nil))
77
77
78 (p:defrule colon #\:
78 (p:defrule colon #\:
79 (:constant nil))
79 (:constant nil))
80
80
81 (p:defrule alphanumeric (alphanumericp character))
81 (p:defrule alphanumeric (alphanumericp character))
82
82
83 (p:defrule not-newline (not-newline character))
83 (p:defrule not-newline (not-newline character))
84
84
85 (p:defrule squote-esc "''"
85 (p:defrule squote-esc "''"
86 (:lambda (list)
86 (:lambda (list)
87 (p:text (elt list 0))))
87 (p:text (elt list 0))))
88
88
89 (p:defrule dquote-esc "\"\""
89 (p:defrule dquote-esc "\"\""
90 (:lambda (list)
90 (:lambda (list)
91 (p:text (elt list 0))))
91 (p:text (elt list 0))))
92
92
93 (p:defrule sstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "\"exec:")))
93 (p:defrule sstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "\"exec:")))
94 (or squote-esc (not-quote character))))
94 (or squote-esc (not-quote character))))
95 (:lambda (list)
95 (:lambda (list)
96 (p:text (mapcar #'second list))))
96 (p:text (mapcar #'second list))))
97
97
98 (p:defrule dstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "'exec:")))
98 (p:defrule dstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "'exec:")))
99 (or dquote-esc (not-doublequote character))))
99 (or dquote-esc (not-doublequote character))))
100 (:lambda (list)
100 (:lambda (list)
101 (p:text (mapcar #'second list))))
101 (p:text (mapcar #'second list))))
102
102
103 ;;; Identifiers
103 ;;; Identifiers
104
104
105 ;; From the official docs
105 ;; From the official docs
106 (defparameter *keywords* '(act addlib addobj addqst and arrcomp arrpos arrsize cla clear *clear close clr *clr cls cmdclear cmdclr copyarr counter countobj curacts curloc debug delact dellib delobj desc disablescroll disablesubex dynamic dyneval else elseif end exit fcolor fname freelib fsize func getobj gosub goto gs gt if iif inclib input instr isnum isplay jump killall killobj killqst killvar lcase lcolor len let loc maintxt max menu mid min mod msecscount msg nl *nl no nosave obj onactsel ongload ongsave onnewloc onobjadd onobjdel onobjsel opengame openqst or p *p pl *pl play qspver rand refint replace rgb rnd savegame selact selobj set settimer showacts showinput showobjs showstat stattxt str strcomp strfind strpos trim ucase unsel unselect usercom user_text usrtxt val view wait xgoto xgt))
106 (defparameter *keywords* '(act addlib addobj addqst and arrcomp arrpos arrsize cla clear *clear close clr *clr cls cmdclear cmdclr copyarr counter countobj curacts curloc debug delact dellib delobj desc disablescroll disablesubex dynamic dyneval else elseif end exit fcolor fname freelib fsize func getobj gosub goto gs gt if iif inclib input instr isnum isplay jump killall killobj killqst killvar lcase lcolor len let loc local maintxt max menu mid min mod msecscount msg nl *nl no nosave obj onactsel ongload ongsave onnewloc onobjadd onobjdel onobjsel opengame openqst or p *p pl *pl play qspver rand refint replace rgb rnd savegame selact selobj set settimer showacts showinput showobjs showstat stattxt str strcomp strfind strpos trim ucase unsel unselect usercom user_text usrtxt val view wait xgoto xgt))
107
107
108 (defun trim-$ (str)
108 (defun trim-$ (str)
109 (if (char= #\$ (elt str 0))
109 (if (char= #\$ (elt str 0))
110 (subseq str 1)
110 (subseq str 1)
111 str))
111 str))
112
112
113 (defun qsp-keyword-p (id)
113 (defun qsp-keyword-p (id)
114 (member (intern (trim-$ (string-upcase id))) *keywords*))
114 (member (intern (trim-$ (string-upcase id))) *keywords*))
115
115
116 (defun not-qsp-keyword-p (id)
116 (defun not-qsp-keyword-p (id)
117 (not (member (intern (trim-$ (string-upcase id))) *keywords*)))
117 (not (member (intern (trim-$ (string-upcase id))) *keywords*)))
118
118
119 (p:defrule qsp-keyword (qsp-keyword-p identifier-raw))
119 (p:defrule qsp-keyword (qsp-keyword-p identifier-raw))
120
120
121 (p:defrule id-first (id-any-char character))
121 (p:defrule id-first (id-any-char character))
122 (p:defrule id-next (or (id-any-char character)
122 (p:defrule id-next (or (id-any-char character)
123 (digit-char-p character)))
123 (digit-char-p character)))
124 (p:defrule identifier-raw (and id-first (* id-next))
124 (p:defrule identifier-raw (and id-first (* id-next))
125 (:lambda (list)
125 (:lambda (list)
126 (intern (string-upcase (p:text list)))))
126 (intern (string-upcase (p:text list)))))
127
127
128 (p:defrule identifier (not-qsp-keyword-p identifier-raw))
128 (p:defrule identifier (not-qsp-keyword-p identifier-raw))
129
129
130 ;;; Strings
130 ;;; Strings
131
131
132 (p:defrule qsp-string (or normal-string brace-string))
132 (p:defrule qsp-string (or normal-string brace-string))
133
133
134 (p:defrule normal-string (or sstring dstring)
134 (p:defrule normal-string (or sstring dstring)
135 (:lambda (str)
135 (:lambda (str)
136 (list* 'str (or str (list "")))))
136 (list* 'str (or str (list "")))))
137
137
138 (p:defrule sstring (and #\' (* (or string-interpol
138 (p:defrule sstring (and #\' (* (or string-interpol
139 sstring-exec
139 sstring-exec
140 sstring-chars))
140 sstring-chars))
141 #\')
141 #\')
142 (:function second))
142 (:function second))
143
143
144 (p:defrule dstring (and #\" (* (or string-interpol
144 (p:defrule dstring (and #\" (* (or string-interpol
145 dstring-exec
145 dstring-exec
146 dstring-chars))
146 dstring-chars))
147 #\")
147 #\")
148 (:function second))
148 (:function second))
149
149
150 (p:defrule string-interpol (and "<<" expression ">>")
150 (p:defrule string-interpol (and "<<" expression ">>")
151 (:function second))
151 (:function second))
152
152
153 (p:defrule sstring-exec-body (+ (or squote-esc (not-doublequote character)))
153 (p:defrule sstring-exec-body (+ (or squote-esc (not-doublequote character)))
154 (:text t))
154 (:text t))
155
155
156 (p:defrule dstring-exec-body (+ (or dquote-esc (not-quote character)))
156 (p:defrule dstring-exec-body (+ (or dquote-esc (not-quote character)))
157 (:text t))
157 (:text t))
158
158
159 (p:defrule sstring-exec (and (p:~ "\"exec:") sstring-exec-body #\")
159 (p:defrule sstring-exec (and (p:~ "\"exec:") sstring-exec-body #\")
160 (:lambda (list)
160 (:lambda (list)
161 (list* 'exec (p:parse 'exec-body (second list)))))
161 (list* 'exec (p:parse 'exec-body (second list)))))
162
162
163 (p:defrule dstring-exec (and (p:~ "'exec:") dstring-exec-body #\')
163 (p:defrule dstring-exec (and (p:~ "'exec:") dstring-exec-body #\')
164 (:lambda (list)
164 (:lambda (list)
165 (list* 'exec (p:parse 'exec-body (second list)))))
165 (list* 'exec (p:parse 'exec-body (second list)))))
166
166
167 (p:defrule brace-string (and #\{ before-statement block-body #\})
167 (p:defrule brace-string (and #\{ before-statement block-body #\})
168 (:lambda (list)
168 (:lambda (list)
169 (list* 'qspblock (third list))))
169 (list* 'qspblock (third list))))
170
170
171 ;;; Location
171 ;;; Location
172
172
173 (p:defrule sugar-qsp-grammar (and (* (or spaces #\newline))
173 (p:defrule sugar-qsp-grammar (and (* (or spaces #\newline))
174 (* location))
174 (* location))
175 (:function second))
175 (:function second))
176
176
177 (p:defrule location (and location-header block-body location-end)
177 (p:defrule location (and location-header block-body location-end)
178 (:destructure (header body end)
178 (:destructure (header body end)
179 (declare (ignore end))
179 (declare (ignore end))
180 `(location (,header) ,@body)))
180 `(location (,header) ,@body)))
181
181
182 (p:defrule location-header (and #\#
182 (p:defrule location-header (and #\#
183 (+ not-newline)
183 (+ not-newline)
184 (and #\newline spaces? before-statement))
184 (and #\newline spaces? before-statement))
185 (:destructure (spaces1 name spaces2)
185 (:destructure (spaces1 name spaces2)
186 (declare (ignore spaces1 spaces2))
186 (declare (ignore spaces1 spaces2))
187 (string-upcase (string-trim " " (p:text name)))))
187 (string-upcase (string-trim " " (p:text name)))))
188
188
189 (p:defrule location-end (and #\- (* not-newline) #\newline before-statement)
189 (p:defrule location-end (and #\- (* not-newline) #\newline before-statement)
190 (:constant nil))
190 (:constant nil))
191
191
192 ;;; Block body
192 ;;; Block body
193
193
194 (p:defrule newline-block-body (and #\newline spaces? block-body)
194 (p:defrule newline-block-body (and #\newline spaces? block-body)
195 (:function third))
195 (:function third))
196
196
197 (p:defrule block-body (* statement)
197 (p:defrule block-body (* statement)
198 (:function remove-nil))
198 (:function remove-nil))
199
199
200 ;; Just for <a href="exec:...'>
200 ;; Just for <a href="exec:...'>
201 ;; Explicitly called from that rule's production
201 ;; Explicitly called from that rule's production
202 (p:defrule exec-body (and before-statement line-body)
202 (p:defrule exec-body (and before-statement line-body)
203 (:function second))
203 (:function second))
204
204
205 (p:defrule line-body (and inline-statement (* next-inline-statement))
205 (p:defrule line-body (and inline-statement (* next-inline-statement))
206 (:lambda (list)
206 (:lambda (list)
207 (list* (first list) (second list))))
207 (list* (first list) (second list))))
208
208
209 (p:defrule before-statement (* (or #\newline spaces))
209 (p:defrule before-statement (* (or #\newline spaces))
210 (:constant nil))
210 (:constant nil))
211
211
212 (p:defrule statement-end (or statement-end-real statement-end-block-close))
212 (p:defrule statement-end (or statement-end-real statement-end-block-close))
213
213
214 (p:defrule statement-end-real (and (or #\newline
214 (p:defrule statement-end-real (and (or #\newline
215 (and #\& spaces? (p:& statement%)))
215 (and #\& spaces? (p:& statement%)))
216 before-statement)
216 before-statement)
217 (:constant nil))
217 (:constant nil))
218
218
219 (p:defrule statement-end-block-close (or (p:& #\}))
219 (p:defrule statement-end-block-close (or (p:& #\}))
220 (:constant nil))
220 (:constant nil))
221
221
222 (p:defrule inline-statement (and statement% spaces?)
222 (p:defrule inline-statement (and statement% spaces?)
223 (:function first))
223 (:function first))
224
224
225 (p:defrule next-inline-statement (and #\& spaces? inline-statement)
225 (p:defrule next-inline-statement (and #\& spaces? inline-statement)
226 (:function third))
226 (:function third))
227
227
228 (p:defrule not-a-non-statement (and (p:! (p:~ "elseif"))
228 (p:defrule not-a-non-statement (and (p:! (p:~ "elseif"))
229 (p:! (p:~ "else"))
229 (p:! (p:~ "else"))
230 (p:! (p:~ "end"))))
230 (p:! (p:~ "end"))))
231
231
232 (p:defrule statement (and inline-statement statement-end)
232 (p:defrule statement (and inline-statement statement-end)
233 (:function first))
233 (:function first))
234
234
235 (p:defrule statement% (and not-a-non-statement
235 (p:defrule statement% (and not-a-non-statement
236 (or label comment string-output
236 (or label comment string-output
237 block non-returning-intrinsic assignment
237 block non-returning-intrinsic local
238 expression-output))
238 assignment expression-output))
239 (:function second))
239 (:function second))
240
240
241 (p:defrule expr-stopper (or comment block non-returning-intrinsic))
241 (p:defrule expr-stopper (or comment block non-returning-intrinsic))
242
242
243 (p:defrule string-output qsp-string
243 (p:defrule string-output qsp-string
244 (:lambda (string)
244 (:lambda (string)
245 (list 'main-pl string)))
245 (list 'main-pl string)))
246
246
247 (p:defrule expression-output expression
247 (p:defrule expression-output expression
248 (:lambda (list)
248 (:lambda (list)
249 (list 'main-pl list)))
249 (list 'main-pl list)))
250
250
251 (p:defrule label (and colon identifier)
251 (p:defrule label (and colon identifier)
252 (:lambda (list)
252 (:lambda (list)
253 (intern (string (second list)) :keyword)))
253 (intern (string (second list)) :keyword)))
254
254
255 (p:defrule comment (and #\! (* (or qsp-string brace-comment text-spaces not-newline)))
255 (p:defrule comment (and #\! (* (or qsp-string brace-comment text-spaces not-newline)))
256 (:constant nil))
256 (:constant nil))
257
257
258 (p:defrule brace-comment (and #\{ (* (not-brace character)) #\})
258 (p:defrule brace-comment (and #\{ (* (not-brace character)) #\})
259 (:constant nil))
259 (:constant nil))
260
260
261 (p:defrule local (and (p:~ "local") spaces variable (p:? (and spaces? #\= spaces? expression)))
262 (:lambda (list)
263 (list* 'local (third list)
264 (when (fourth list)
265 (list (fourth (fourth list)))))))
266
261 ;;; Blocks
267 ;;; Blocks
262
268
263 (p:defrule block (or block-act block-if))
269 (p:defrule block (or block-act block-if))
264
270
265 (p:defrule block-if (and block-if-head block-if-body)
271 (p:defrule block-if (and block-if-head block-if-body)
266 (:destructure (head body)
272 (:destructure (head body)
267 `(qspcond (,@head ,@(first body))
273 `(qspcond (,@head ,@(first body))
268 ,@(rest body))))
274 ,@(rest body))))
269
275
270 (p:defrule block-if-head (and (p:~ "if") spaces expression spaces? colon spaces?)
276 (p:defrule block-if-head (and (p:~ "if") spaces expression spaces? colon spaces?)
271 (:function remove-nil)
277 (:function remove-nil)
272 (:function cdr))
278 (:function cdr))
273
279
274 (p:defrule block-if-body (or block-if-ml block-if-sl)
280 (p:defrule block-if-body (or block-if-ml block-if-sl)
275 (:destructure (if-body elseifs else &rest ws)
281 (:destructure (if-body elseifs else &rest ws)
276 (declare (ignore ws))
282 (declare (ignore ws))
277 `(,(remove-nil if-body) ,@elseifs ,@(when else `((else ,@else))))))
283 `(,(remove-nil if-body) ,@elseifs ,@(when else `((else ,@else))))))
278
284
279 (p:defrule block-if-sl (and line-body
285 (p:defrule block-if-sl (and line-body
280 (p:? block-if-elseif-inline)
286 (p:? block-if-elseif-inline)
281 (p:? block-if-else-inline)
287 (p:? block-if-else-inline)
282 spaces?))
288 spaces?))
283
289
284 (p:defrule block-if-ml (and (and #\newline spaces?)
290 (p:defrule block-if-ml (and (and #\newline spaces?)
285 block-body
291 block-body
286 (p:? block-if-elseif)
292 (p:? block-if-elseif)
287 (p:? block-if-else)
293 (p:? block-if-else)
288 block-if-end)
294 block-if-end)
289 (:lambda (list)
295 (:lambda (list)
290 (cdr list)))
296 (cdr list)))
291
297
292 (p:defrule block-if-elseif-inline (and block-if-elseif-head line-body (p:? block-if-elseif-inline))
298 (p:defrule block-if-elseif-inline (and block-if-elseif-head line-body (p:? block-if-elseif-inline))
293 (:destructure (head statements elseif)
299 (:destructure (head statements elseif)
294 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
300 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
295
301
296 (p:defrule block-if-elseif (and block-if-elseif-head statement-end block-body (p:? block-if-elseif))
302 (p:defrule block-if-elseif (and block-if-elseif-head statement-end block-body (p:? block-if-elseif))
297 (:destructure (head ws statements elseif)
303 (:destructure (head ws statements elseif)
298 (declare (ignore ws))
304 (declare (ignore ws))
299 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
305 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
300
306
301 (p:defrule block-if-elseif-head (and (p:~ "elseif") spaces expression spaces? colon spaces?)
307 (p:defrule block-if-elseif-head (and (p:~ "elseif") spaces expression spaces? colon spaces?)
302 (:function remove-nil)
308 (:function remove-nil)
303 (:function intern-first))
309 (:function intern-first))
304
310
305 (p:defrule block-if-else-inline (and block-if-else-head line-body)
311 (p:defrule block-if-else-inline (and block-if-else-head line-body)
306 (:function second))
312 (:function second))
307
313
308 (p:defrule block-if-else (and block-if-else-head #\newline spaces? block-body)
314 (p:defrule block-if-else (and block-if-else-head #\newline spaces? block-body)
309 (:function fourth))
315 (:function fourth))
310
316
311 (p:defrule block-if-else-head (and (p:~ "else") spaces?)
317 (p:defrule block-if-else-head (and (p:~ "else") spaces?)
312 (:constant nil))
318 (:constant nil))
313
319
314 (p:defrule block-if-end (and (p:~ "end")
320 (p:defrule block-if-end (and (p:~ "end")
315 (p:? (and spaces (p:~ "if"))))
321 (p:? (and spaces (p:~ "if"))))
316 (:constant nil))
322 (:constant nil))
317
323
318 (p:defrule block-act (and block-act-head (or block-act-ml block-act-sl))
324 (p:defrule block-act (and block-act-head (or block-act-ml block-act-sl))
319 (:lambda (list)
325 (:lambda (list)
320 (apply #'append list)))
326 (apply #'append list)))
321
327
322 (p:defrule block-act-sl line-body)
328 (p:defrule block-act-sl line-body)
323
329
324 (p:defrule block-act-ml (and newline-block-body block-act-end)
330 (p:defrule block-act-ml (and newline-block-body block-act-end)
325 (:lambda (list)
331 (:lambda (list)
326 (apply #'list* (butlast list))))
332 (apply #'list* (butlast list))))
327
333
328 (p:defrule block-act-head (and (p:~ "act") spaces qsp-string spaces?
334 (p:defrule block-act-head (and (p:~ "act") spaces qsp-string spaces?
329 (p:? block-act-head-img)
335 (p:? block-act-head-img)
330 colon spaces?)
336 colon spaces?)
331 (:lambda (list)
337 (:lambda (list)
332 (intern-first (list (first list)
338 (intern-first (list (first list)
333 (third list)
339 (third list)
334 (or (fifth list) '(str ""))))))
340 (or (fifth list) '(str ""))))))
335
341
336 (p:defrule block-act-head-img (and #\, spaces? qsp-string spaces?)
342 (p:defrule block-act-head-img (and #\, spaces? qsp-string spaces?)
337 (:lambda (list)
343 (:lambda (list)
338 (or (third list) "")))
344 (or (third list) "")))
339
345
340 (p:defrule block-act-end (and (p:~ "end"))
346 (p:defrule block-act-end (and (p:~ "end"))
341 (:constant nil))
347 (:constant nil))
342
348
343 ;;; Calls
349 ;;; Calls
344
350
345 (p:defrule first-argument (and expression spaces?)
351 (p:defrule first-argument (and expression spaces?)
346 (:function first))
352 (:function first))
347 (p:defrule next-argument (and "," spaces? expression)
353 (p:defrule next-argument (and "," spaces? expression)
348 (:function third))
354 (:function third))
349 (p:defrule arguments (or parenthesized-arguments plain-arguments no-arguments))
355 (p:defrule arguments (or parenthesized-arguments plain-arguments no-arguments))
350 (p:defrule parenthesized-arguments (and spaces? #\( base-arguments #\))
356 (p:defrule parenthesized-arguments (and spaces? #\( base-arguments #\))
351 (:function third))
357 (:function third))
352 (p:defrule plain-arguments (and spaces base-arguments)
358 (p:defrule plain-arguments (and spaces base-arguments)
353 (:function second))
359 (:function second))
354 (p:defrule no-arguments (or (and spaces? (p:& #\newline))
360 (p:defrule no-arguments (or (and spaces? (p:& #\newline))
355 (and spaces? (p:& #\&))
361 (and spaces? (p:& #\&))
356 spaces?)
362 spaces?)
357 (:constant nil))
363 (:constant nil))
358 (p:defrule base-arguments (or (and first-argument (* next-argument)) spaces?)
364 (p:defrule base-arguments (or (and first-argument (* next-argument)) spaces?)
359 (:lambda (list)
365 (:lambda (list)
360 (if (null list)
366 (if (null list)
361 nil
367 nil
362 (list* (first list) (second list)))))
368 (list* (first list) (second list)))))
363
369
364 ;;; Intrinsics
370 ;;; Intrinsics
365
371
366 (defmacro defintrinsics ((rule-name returning-rule-name non-returning-rule-name) &body clauses)
372 (defmacro defintrinsics ((rule-name returning-rule-name non-returning-rule-name) &body clauses)
367 `(progn
373 `(progn
368 ,@(loop :for clause :in clauses
374 ,@(loop :for clause :in clauses
369 :collect `(defintrinsic ,@clause))
375 :collect `(defintrinsic ,@clause))
370 (p:defrule ,returning-rule-name (or ,@(remove-nil
376 (p:defrule ,returning-rule-name (or ,@(remove-nil
371 (mapcar (lambda (clause)
377 (mapcar (lambda (clause)
372 (when (second clause)
378 (when (second clause)
373 (alexandria:symbolicate
379 (alexandria:symbolicate
374 'intrinsic- (first clause))))
380 'intrinsic- (first clause))))
375 clauses))))
381 clauses))))
376 (p:defrule ,non-returning-rule-name (or ,@(remove-nil
382 (p:defrule ,non-returning-rule-name (or ,@(remove-nil
377 (mapcar (lambda (clause)
383 (mapcar (lambda (clause)
378 (unless (second clause)
384 (unless (second clause)
379 (alexandria:symbolicate
385 (alexandria:symbolicate
380 'intrinsic- (first clause))))
386 'intrinsic- (first clause))))
381 clauses))))
387 clauses))))
382 (p:defrule ,rule-name (or ,returning-rule-name ,non-returning-rule-name))))
388 (p:defrule ,rule-name (or ,returning-rule-name ,non-returning-rule-name))))
383
389
384 (defmacro defintrinsic (sym returning &optional (min-arity 0) (max-arity 10) &rest names)
390 (defmacro defintrinsic (sym returning &optional (min-arity 0) (max-arity 10) &rest names)
385 (declare (ignore returning))
391 (declare (ignore returning))
386 (setf names
392 (setf names
387 (if names
393 (if names
388 (mapcar #'string-upcase names)
394 (mapcar #'string-upcase names)
389 (list (string sym))))
395 (list (string sym))))
390 `(p:defrule ,(alexandria:symbolicate 'intrinsic- sym)
396 `(p:defrule ,(alexandria:symbolicate 'intrinsic- sym)
391 (and (p:? #\$) (or ,@(loop :for name :in names :collect `(p:~ ,name)))
397 (and (p:? #\$) (or ,@(loop :for name :in names :collect `(p:~ ,name)))
392 arguments)
398 arguments)
393 (:destructure (dollar name arguments)
399 (:destructure (dollar name arguments)
394 (declare (ignore dollar))
400 (declare (ignore dollar))
395 (unless (<= ,min-arity (length arguments) ,max-arity)
401 (unless (<= ,min-arity (length arguments) ,max-arity)
396 (error "Intrinsic ~A expects between ~A and ~A arguments but ~A were provided:~%~S"
402 (error "Intrinsic ~A expects between ~A and ~A arguments but ~A were provided:~%~S"
397 name ,min-arity ,max-arity (length arguments) arguments))
403 name ,min-arity ,max-arity (length arguments) arguments))
398 (list* ',sym arguments))))
404 (list* ',sym arguments))))
399
405
400 (defintrinsics (intrinsic returning-intrinsic non-returning-intrinsic)
406 (defintrinsics (intrinsic returning-intrinsic non-returning-intrinsic)
401 ;; Transitions
407 ;; Transitions
402 (goto nil 0 10 "gt" "goto")
408 (goto nil 0 10 "gt" "goto")
403 (xgoto nil 0 10 "xgt" "xgoto")
409 (xgoto nil 0 10 "xgt" "xgoto")
404 ;; Variables
410 ;; Variables
405 (killvar nil 0 2)
411 (killvar nil 0 2)
406 ;; Expressions
412 ;; Expressions
407 (obj t 1 1)
413 (obj t 1 1)
408 (loc t 1 1)
414 (loc t 1 1)
409 (no t 1 1)
415 (no t 1 1)
410 ;; Basic
416 ;; Basic
411 (qspver t 0 0)
417 (qspver t 0 0)
412 (curloc t 0 0)
418 (curloc t 0 0)
413 (rand t 1 2)
419 (rand t 1 2)
414 (rnd t 0 0)
420 (rnd t 0 0)
415 (qspmax t 1 10 "max")
421 (qspmax t 1 10 "max")
416 (qspmin t 1 10 "min")
422 (qspmin t 1 10 "min")
417 ;; Arrays
423 ;; Arrays
418 (killall nil 0 0)
424 (killall nil 0 0)
419 (copyarr nil 2 4)
425 (copyarr nil 2 4)
420 (arrsize t 1 1)
426 (arrsize t 1 1)
421 (arrpos t 2 3)
427 (arrpos t 2 3)
422 (arrcomp t 2 3)
428 (arrcomp t 2 3)
423 ;; Strings
429 ;; Strings
424 (len t 1 1)
430 (len t 1 1)
425 (mid t 2 3)
431 (mid t 2 3)
426 (ucase t 1 1)
432 (ucase t 1 1)
427 (lcase t 1 1)
433 (lcase t 1 1)
428 (trim t 1 1)
434 (trim t 1 1)
429 (replace t 2 3)
435 (replace t 2 3)
430 (instr t 2 3)
436 (instr t 2 3)
431 (isnum t 1 1)
437 (isnum t 1 1)
432 (val t 1 1)
438 (val t 1 1)
433 (qspstr t 1 1 "str")
439 (qspstr t 1 1 "str")
434 (strcomp t 2 2)
440 (strcomp t 2 2)
435 (strfind t 2 3)
441 (strfind t 2 3)
436 (strpos t 2 3)
442 (strpos t 2 3)
437 ;; IF
443 ;; IF
438 (iif t 2 3)
444 (iif t 2 3)
439 ;; Subs
445 ;; Subs
440 (gosub nil 1 10 "gosub" "gs")
446 (gosub nil 1 10 "gosub" "gs")
441 (func t 1 10)
447 (func t 1 10)
442 (exit nil 0 0)
448 (exit nil 0 0)
443 ;; Jump
449 ;; Jump
444 (jump nil 1 1)
450 (jump nil 1 1)
445 ;; Dynamic
451 ;; Dynamic
446 (dynamic nil 1 10)
452 (dynamic nil 1 10)
447 (dyneval t 1 10)
453 (dyneval t 1 10)
448 ;; Main window
454 ;; Main window
449 (main-pl nil 1 1 "*pl")
455 (main-pl nil 1 1 "*pl")
450 (main-nl nil 0 1 "*nl")
456 (main-nl nil 0 1 "*nl")
451 (main-p nil 1 1 "*p")
457 (main-p nil 1 1 "*p")
452 (maintxt t 0 0)
458 (maintxt t 0 0)
453 (desc t 1 1)
459 (desc t 1 1)
454 (main-clear nil 0 0 "*clear" "*clr")
460 (main-clear nil 0 0 "*clear" "*clr")
455 ;; Aux window
461 ;; Aux window
456 (showstat nil 1 1)
462 (showstat nil 1 1)
457 (stat-pl nil 1 1 "pl")
463 (stat-pl nil 1 1 "pl")
458 (stat-nl nil 0 1 "nl")
464 (stat-nl nil 0 1 "nl")
459 (stat-p nil 1 1 "p")
465 (stat-p nil 1 1 "p")
460 (stattxt t 0 0)
466 (stattxt t 0 0)
461 (stat-clear nil 0 0 "clear" "clr")
467 (stat-clear nil 0 0 "clear" "clr")
462 (cls nil 0 0)
468 (cls nil 0 0)
463 ;; Dialog
469 ;; Dialog
464 (msg nil 1 1)
470 (msg nil 1 1)
465 ;; Acts
471 ;; Acts
466 (showacts nil 1 1)
472 (showacts nil 1 1)
467 (delact nil 1 1 "delact" "del act")
473 (delact nil 1 1 "delact" "del act")
468 (curacts t 0 0)
474 (curacts t 0 0)
469 (cla nil 0 0)
475 (cla nil 0 0)
470 ;; Objects
476 ;; Objects
471 (showobjs nil 1 1)
477 (showobjs nil 1 1)
472 (addobj nil 1 3 "addobj" "add obj")
478 (addobj nil 1 3 "addobj" "add obj")
473 (delobj nil 1 1 "delobj" "del obj")
479 (delobj nil 1 1 "delobj" "del obj")
474 (killobj nil 0 1)
480 (killobj nil 0 1)
475 (countobj t 0 0)
481 (countobj t 0 0)
476 (getobj t 1 1)
482 (getobj t 1 1)
477 ;; Menu
483 ;; Menu
478 (menu nil 1 1)
484 (menu nil 1 1)
479 ;; Sound
485 ;; Sound
480 (play nil 1 2)
486 (play nil 1 2)
481 (isplay t 1 1)
487 (isplay t 1 1)
482 (close nil 1 1)
488 (close nil 1 1)
483 (closeall nil 0 0 "close all")
489 (closeall nil 0 0 "close all")
484 ;; Images
490 ;; Images
485 (refint nil 0 0)
491 (refint nil 0 0)
486 (view nil 0 1)
492 (view nil 0 1)
487 ;; Fonts
493 ;; Fonts
488 (rgb t 3 3)
494 (rgb t 3 3)
489 ;; Input
495 ;; Input
490 (showinput nil 1 1)
496 (showinput nil 1 1)
491 (usertxt t 0 0 "user_text" "usrtxt")
497 (usertxt t 0 0 "user_text" "usrtxt")
492 (cmdclear nil 0 0 "cmdclear" "cmdclr")
498 (cmdclear nil 0 0 "cmdclear" "cmdclr")
493 (input t 1 1)
499 (input t 1 1)
494 ;; Files
500 ;; Files
495 (openqst nil 1 1)
501 (openqst nil 1 1)
496 (addqst nil 1 1 "addqst" "addlib" "inclib")
502 (addqst nil 1 1 "addqst" "addlib" "inclib")
497 (killqst nil 1 1 "killqst" "dellib" "freelib")
503 (killqst nil 1 1 "killqst" "dellib" "freelib")
498 (opengame nil 0 0)
504 (opengame nil 0 0)
499 (savegame nil 0 0)
505 (savegame nil 0 0)
500 ;; Real time
506 ;; Real time
501 (wait nil 1 1)
507 (wait nil 1 1)
502 (msecscount t 0 0)
508 (msecscount t 0 0)
503 (settimer nil 1 1))
509 (settimer nil 1 1))
504
510
505 ;;; Expression
511 ;;; Expression
506
512
507 (p:defrule expression or-expr)
513 (p:defrule expression or-expr)
508
514
509 (p:defrule or-expr (and and-expr (* (and spaces? or-op spaces? and-expr)))
515 (p:defrule or-expr (and and-expr (* (and spaces? or-op spaces? and-expr)))
510 (:function do-binop))
516 (:function do-binop))
511
517
512 (p:defrule and-expr (and eq-expr (* (and spaces? and-op spaces? eq-expr)))
518 (p:defrule and-expr (and eq-expr (* (and spaces? and-op spaces? eq-expr)))
513 (:function do-binop))
519 (:function do-binop))
514
520
515 (p:defrule eq-expr (and sum-expr (* (and spaces? (or "<=" ">=" "=<" "=>" "<>"
521 (p:defrule eq-expr (and sum-expr (* (and spaces? (or "<=" ">=" "=<" "=>" "<>"
516 "=" "<" ">" "!")
522 "=" "<" ">" "!")
517 spaces? cat-expr)))
523 spaces? cat-expr)))
518 (:function do-binop))
524 (:function do-binop))
519
525
520 (p:defrule sum-expr (and mod-expr (* (and spaces? (or #\+ #\-) spaces? mod-expr)))
526 (p:defrule sum-expr (and mod-expr (* (and spaces? (or #\+ #\-) spaces? mod-expr)))
521 (:function do-binop))
527 (:function do-binop))
522
528
523 (p:defrule mod-expr (and mul-expr (* (and spaces? (p:~ "mod") spaces? mul-expr)))
529 (p:defrule mod-expr (and mul-expr (* (and spaces? (p:~ "mod") spaces? mul-expr)))
524 (:function do-binop))
530 (:function do-binop))
525
531
526 (p:defrule mul-expr (and unary-expr (* (and spaces? (or #\* #\/) spaces? unary-expr)))
532 (p:defrule mul-expr (and unary-expr (* (and spaces? (or #\* #\/) spaces? unary-expr)))
527 (:function do-binop))
533 (:function do-binop))
528
534
529 (p:defrule unary-expr (and (p:? (or #\+ #\-)) atom-expr)
535 (p:defrule unary-expr (and (p:? (or #\+ #\-)) atom-expr)
530 (:lambda (list)
536 (:lambda (list)
531 (let ((expr (remove-nil list)))
537 (let ((expr (remove-nil list)))
532 (if (= 1 (length expr))
538 (if (= 1 (length expr))
533 (first expr)
539 (first expr)
534 (intern-first expr)))))
540 (intern-first expr)))))
535
541
536 (p:defrule atom-expr (and (or variable literal returning-intrinsic paren-expr) spaces?)
542 (p:defrule atom-expr (and (or variable literal returning-intrinsic paren-expr) spaces?)
537 (:function first))
543 (:function first))
538
544
539 (p:defrule paren-expr (and #\( spaces? expression spaces? #\))
545 (p:defrule paren-expr (and #\( spaces? expression spaces? #\))
540 (:function third))
546 (:function third))
541
547
542 (p:defrule or-op (p:~ "or")
548 (p:defrule or-op (p:~ "or")
543 (:constant "or"))
549 (:constant "or"))
544
550
545 (p:defrule and-op (p:~ "and")
551 (p:defrule and-op (p:~ "and")
546 (:constant "and"))
552 (:constant "and"))
547
553
548 ;;; Variables
554 ;;; Variables
549
555
550 (p:defrule variable (and identifier (p:? array-index))
556 (p:defrule variable (and identifier (p:? array-index))
551 (:destructure (id idx)
557 (:destructure (id idx)
552 (list 'var id (or idx 0))))
558 (list 'var id (or idx 0))))
553
559
554 (p:defrule array-index (and #\[ spaces? (p:? expression) spaces? #\])
560 (p:defrule array-index (and #\[ spaces? (p:? expression) spaces? #\])
555 (:lambda (list)
561 (:lambda (list)
556 (or (third list) :end)))
562 (or (third list) :end)))
557
563
558 (p:defrule assignment (or kw-assignment plain-assignment op-assignment)
564 (p:defrule assignment (or kw-assignment plain-assignment op-assignment)
559 (:destructure (var eq expr)
565 (:destructure (var eq expr)
560 (declare (ignore eq))
566 (declare (ignore eq))
561 (list 'set var expr)))
567 (list 'set var expr)))
562
568
563 (p:defrule kw-assignment (and (or (p:~ "let") (p:~ "set")) spaces? (or op-assignment plain-assignment))
569 (p:defrule kw-assignment (and (or (p:~ "let") (p:~ "set")) spaces? (or op-assignment plain-assignment))
564 (:function third))
570 (:function third))
565
571
566 (p:defrule op-assignment (and variable spaces? (or "+" "-" "*" "/") #\= spaces? expression)
572 (p:defrule op-assignment (and variable spaces? (or "+" "-" "*" "/") #\= spaces? expression)
567 (:destructure (var ws1 op eq ws2 expr)
573 (:destructure (var ws1 op eq ws2 expr)
568 (declare (ignore ws1 ws2))
574 (declare (ignore ws1 ws2))
569 (list var eq (intern-first (list op var expr)))))
575 (list var eq (intern-first (list op var expr)))))
570
576
571 (p:defrule plain-assignment (and variable spaces? #\= spaces? expression)
577 (p:defrule plain-assignment (and variable spaces? #\= spaces? expression)
572 (:function remove-nil))
578 (:function remove-nil))
573
579
574 ;;; Non-string literals
580 ;;; Non-string literals
575
581
576 (p:defrule literal (or qsp-string brace-string number))
582 (p:defrule literal (or qsp-string brace-string number))
577
583
578 (p:defrule number (+ (or #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
584 (p:defrule number (+ (or #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
579 (:lambda (list)
585 (:lambda (list)
580 (parse-integer (p:text list))))
586 (parse-integer (p:text list))))
@@ -1,188 +1,181 b''
1
1
2 (in-package sugar-qsp)
2 (in-package sugar-qsp)
3
3
4 ;;;; Parenscript macros which make the parser's intermediate
4 ;;;; Parenscript macros which make the parser's intermediate
5 ;;;; representation directly compilable by Parenscript
5 ;;;; representation directly compilable by Parenscript
6 ;;;; Some utility macros for other .ps sources too.
6 ;;;; Some utility macros for other .ps sources too.
7
7
8 ;;; Utils
8 ;;; Utils
9
9
10 (ps:defpsmacro defm (path args &body body)
10 (ps:defpsmacro defm (path args &body body)
11 `(setf ,path (lambda ,args ,@body)))
11 `(setf ,path (lambda ,args ,@body)))
12
12
13 (ps:defpsmacro root (&rest path)
13 (ps:defpsmacro root (&rest path)
14 `(ps:@ *sugar-q-s-p ,@path))
14 `(ps:@ *sugar-q-s-p ,@path))
15
15
16 (ps:defpsmacro in (key obj)
16 (ps:defpsmacro in (key obj)
17 `(ps:chain ,obj (has-own-property ,key)))
17 `(ps:chain ,obj (has-own-property ,key)))
18
18
19 (ps:defpsmacro conserving-vars (vars &body body)
20 "Calls body with safely stored away VARS (whole arrays, both namespaces), and restores their values after that returning what BODY returns."
21 `(let ((__conserved (list ,@(loop :for var :in vars
22 :collect `(root vars ,var)))))
23 ,@(loop :for var :in vars
24 :collect `(setf (root vars ,var) (ps:create :num 0 :str "")))
25 (unwind-protect
26 (progn ,@body)
27 (progn
28 ,@(loop :for var :in vars
29 :for i from 0
30 :collect `(setf (root vars ,var) (ps:@ __conserved ,i)))))))
31
32 ;;; Common
19 ;;; Common
33
20
34 (defmacro defpsintrinsic (name)
21 (defmacro defpsintrinsic (name)
35 `(ps:defpsmacro ,name (&rest args)
22 `(ps:defpsmacro ,name (&rest args)
36 `(funcall (root lib ,',name)
23 `(funcall (root lib ,',name)
37 ,@args)))
24 ,@args)))
38
25
39 (defmacro defpsintrinsics (() &rest names)
26 (defmacro defpsintrinsics (() &rest names)
40 `(progn ,@(loop :for name :in names
27 `(progn ,@(loop :for name :in names
41 :collect `(defpsintrinsic ,name))))
28 :collect `(defpsintrinsic ,name))))
42
29
43 (defpsintrinsics ()
30 (defpsintrinsics ()
44 rand copyarr arrpos arrcomp instr isnum strcomp strfind strpos iif gosub func dynamic dyneval main-p main-pl main-nl maintxt main-clear stat-p stat-pl stat-nl stattxt stat-clear cls curacts addobj delobj killobj menu play isplay close closeall refint view rgb showinput usertxt cmdclear input openqst addqst killqst opengame savegame wait msecscount settimer)
31 rand copyarr arrpos arrcomp instr isnum strcomp strfind strpos iif gosub func dynamic dyneval main-p main-pl main-nl maintxt main-clear stat-p stat-pl stat-nl stattxt stat-clear cls curacts addobj delobj killobj menu play isplay close closeall refint view rgb showinput usertxt cmdclear input openqst addqst killqst opengame savegame wait msecscount settimer)
45
32
46 (ps:defpsmacro api-call (func &rest args)
33 (ps:defpsmacro api-call (func &rest args)
47 `(funcall (root api ,func) ,@args))
34 `(funcall (root api ,func) ,@args))
48
35
49 (ps:defpsmacro label-block (&body body)
36 (ps:defpsmacro label-block (&body body)
50 `(block nil
37 (let ((has-labels (some #'keywordp body)))
51 ,@(when (some #'keywordp body)
38 `(block nil
52 '((defvar __labels)))
39 ,@(when has-labels
53 (tagbody
40 '((defvar __labels)))
54 ,@body)
41 (api-call push-local-frame)
55 (values)))
42 (unwind-protect
43 (tagbody
44 ,@body)
45 (api-call pop-local-frame))
46 (values))))
56
47
57 (ps:defpsmacro str (&rest forms)
48 (ps:defpsmacro str (&rest forms)
58 (cond ((zerop (length forms))
49 (cond ((zerop (length forms))
59 "")
50 "")
60 ((and (= 1 (length forms))
51 ((and (= 1 (length forms))
61 (stringp (first forms)))
52 (stringp (first forms)))
62 (first forms))
53 (first forms))
63 (t
54 (t
64 `(& ,@forms))))
55 `(& ,@forms))))
65
56
66 ;;; 1loc
57 ;;; 1loc
67
58
68 (ps:defpsmacro location ((name) &body body)
59 (ps:defpsmacro location ((name) &body body)
69 `(setf (root locs ,name)
60 `(setf (root locs ,name)
70 (lambda ()
61 (lambda ()
71 (label-block
62 (label-block
72 ,@body))))
63 ,@body))))
73
64
74 (ps:defpsmacro goto (target &rest args)
65 (ps:defpsmacro goto (target &rest args)
75 `(progn
66 `(progn
76 (funcall (root lib goto) ,target ,@args)
67 (funcall (root lib goto) ,target ,@args)
77 (exit)))
68 (exit)))
78
69
79 (ps:defpsmacro xgoto (target &rest args)
70 (ps:defpsmacro xgoto (target &rest args)
80 `(progn
71 `(progn
81 (funcall (root lib xgoto) ,target ,@args)
72 (funcall (root lib xgoto) ,target ,@args)
82 (exit)))
73 (exit)))
83
74
84 (ps:defpsmacro desc (target)
75 (ps:defpsmacro desc (target)
85 (declare (ignore target))
76 (declare (ignore target))
86 (report-error "DESC is not supported"))
77 (report-error "DESC is not supported"))
87
78
88 ;;; 2var
79 ;;; 2var
89
80
90 (ps:defpsmacro var (name index)
81 (ps:defpsmacro var (name index)
91 `(api-call get-var ,(string name) ,index))
82 `(api-call get-var ,(string name) ,index))
92
83
93 (ps:defpsmacro set ((var vname vindex) value)
84 (ps:defpsmacro set ((var vname vindex) value)
94 (assert (eq var 'var))
85 (assert (eq var 'var))
95 `(api-call set-var ,(string vname) ,vindex ,value))
86 `(api-call set-var ,(string vname) ,vindex ,value))
96
87
97 ;;; 3expr
88 ;;; 3expr
98
89
99 (ps:defpsmacro <> (op1 op2)
90 (ps:defpsmacro <> (op1 op2)
100 `(not (equal ,op1 ,op2)))
91 `(not (equal ,op1 ,op2)))
101
92
102 (ps:defpsmacro ! (op1 op2)
93 (ps:defpsmacro ! (op1 op2)
103 `(not (equal ,op1 ,op2)))
94 `(not (equal ,op1 ,op2)))
104
95
105 ;;; 4code
96 ;;; 4code
106
97
107 (ps:defpsmacro exec (&body body)
98 (ps:defpsmacro exec (&body body)
108 (format nil "javascript: ~{~A~^~%~}" (mapcar #'ps:ps* body)))
99 (format nil "javascript: ~{~A~^~%~}" (mapcar #'ps:ps* body)))
109
100
110 ;;; 5arrays
101 ;;; 5arrays
111
102
112 ;;; 6str
103 ;;; 6str
113
104
114 (ps:defpsmacro & (&rest args)
105 (ps:defpsmacro & (&rest args)
115 `(ps:chain "" (concat ,@args)))
106 `(ps:chain "" (concat ,@args)))
116
107
117 ;;; 7if
108 ;;; 7if
118
109
119 (ps:defpsmacro qspcond (&rest clauses)
110 (ps:defpsmacro qspcond (&rest clauses)
120 `(cond ,@(loop :for clause :in clauses
111 `(cond ,@(loop :for clause :in clauses
121 :collect (list (first clause)
112 :collect (list (first clause)
122 `(tagbody ,@(rest clause))))))
113 `(tagbody ,@(rest clause))))))
123
114
124 ;;; 8sub
115 ;;; 8sub
125
116
126 ;;; 9loops
117 ;;; 9loops
127 ;;; Yep, that's a huge kludge since Javascript doesn't support arbitrary labels
118 ;;; Yep, that's a huge kludge since Javascript doesn't support arbitrary labels
128
119
129 (ps:defpsmacro jump (target)
120 (ps:defpsmacro jump (target)
130 `(return-from ,(intern (string-upcase (second target)))
121 `(return-from ,(intern (string-upcase (second target)))
131 (funcall (ps:getprop __labels ,target))))
122 (funcall (ps:getprop __labels ,target))))
132
123
133 (ps:defpsmacro tagbody (&body body)
124 (ps:defpsmacro tagbody (&body body)
134 (let ((funcs (list nil :__nil)))
125 (let ((funcs (list nil :__nil)))
135 (dolist (form body)
126 (dolist (form body)
136 (cond ((keywordp form)
127 (cond ((keywordp form)
137 (setf (first funcs) (reverse (first funcs)))
128 (setf (first funcs) (reverse (first funcs)))
138 (push form funcs)
129 (push form funcs)
139 (push nil funcs))
130 (push nil funcs))
140 (t
131 (t
141 (push form (first funcs)))))
132 (push form (first funcs)))))
142 (setf (first funcs) (reverse (first funcs)))
133 (setf (first funcs) (reverse (first funcs)))
143 (setf funcs (reverse funcs))
134 (setf funcs (reverse funcs))
144 (if (= 2 (length funcs))
135 (if (= 2 (length funcs))
145 `(progn
136 `(progn
146 ,@body)
137 ,@body)
147 `(progn
138 `(progn
148 (setf ,@(loop :for f :on funcs :by #'cddr
139 (setf ,@(loop :for f :on funcs :by #'cddr
149 :append (list `(ps:@ __labels ,(first f))
140 :append (list `(ps:@ __labels ,(first f))
150 `(block ,(intern (string-upcase (string (first f))))
141 `(block ,(intern (string-upcase (string (first f))))
151 ,@(second f)
142 ,@(second f)
152 ,@(when (third f)
143 ,@(when (third f)
153 `((funcall
144 `((funcall
154 (ps:getprop __labels ,(third f)))))))))
145 (ps:getprop __labels ,(third f)))))))))
155 (jump (str "__nil"))))))
146 (jump (str "__nil"))))))
156
147
157 ;;; 10dynamic
148 ;;; 10dynamic
158
149
159 (ps:defpsmacro qspblock (&body body)
150 (ps:defpsmacro qspblock (&body body)
160 `(lambda ()
151 `(lambda ()
161 (label-block
152 (label-block
162 ,@body)))
153 ,@body)))
163
154
164 ;;; 11main
155 ;;; 11main
165
156
166 (ps:defpsmacro act (name img &body body)
157 (ps:defpsmacro act (name img &body body)
167 `(api-call add-act ,name ,img
158 `(api-call add-act ,name ,img
168 (lambda ()
159 (lambda ()
169 (label-block
160 (label-block
170 ,@body))))
161 ,@body))))
171
162
172 ;;; 12aux
163 ;;; 12aux
173
164
174 ;;; 13diag
165 ;;; 13diag
175
166
176 ;;; 14act
167 ;;; 14act
177
168
178 ;;; 15objs
169 ;;; 15objs
179
170
180 ;;; 16menu
171 ;;; 16menu
181
172
182 ;;; 17sound
173 ;;; 17sound
183
174
184 ;;; 18img
175 ;;; 18img
185
176
186 ;;; 19input
177 ;;; 19input
187
178
188 ;;; 20time
179 ;;; 20time
180
181 ;;; 21local
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
1 NO CONTENT: file was removed, binary diff hidden
NO CONTENT: file was removed, binary diff hidden
General Comments 0
You need to be logged in to leave comments. Login now