##// END OF EJS Templates
FOR loop
naryl -
r17:44cead28 default
parent child Browse files
Show More
@@ -0,0 +1,18 b''
1
2 # for
3 FOR k1=0 TO 5:
4 *PL k1
5 IF k1=3: EXIT
6 END
7
8 FOR Π½ΠΎΠΌΠ΅Ρ€_Π½ΠΏΡ† = 1 TO количСство_Π½ΠΏΡ†: GS 'ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΏΡ†', Π½ΠΎΠΌΠ΅Ρ€_Π½ΠΏΡ†
9
10 ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ['ΠΌΠ΅Ρ‡'] = 10
11 ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ['доспСх'] = 250
12 ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ['Ρ‰ΠΈΡ‚'] = 15
13 ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ_снаряТСния = 0
14 FOR Π½ΠΎΠΌΠ΅Ρ€_ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π° = 0 TO ARRSIZE('ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ')-1: ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ_снаряТСния += ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ[Π½ΠΎΠΌΠ΅Ρ€_ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π°]
15
16 FOR i = 1 TO 10 STEP 2: *PL i
17
18 -
@@ -1,6 +1,10 b''
1
1
2 * Finish lib
3 * CLI build for Linux
4 * CLI build for Windows
5
6 * Build Istreblenie
2 * Windows GUI (for the compiler)
7 * Windows GUI (for the compiler)
3 * Save-load game in slots
8 * Save-load game in slots
4 * Resizable frames
9 * Resizable frames
5 * Build Istreblenie
6 ** modifying it to suit compiler specifics No newline at end of file
10 ** modifying it to suit compiler specifics
@@ -1,587 +1,612 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 equal #\=
82 (:constant nil))
83
81 (p:defrule alphanumeric (alphanumericp character))
84 (p:defrule alphanumeric (alphanumericp character))
82
85
83 (p:defrule not-newline (not-newline character))
86 (p:defrule not-newline (not-newline character))
84
87
85 (p:defrule squote-esc "''"
88 (p:defrule squote-esc "''"
86 (:lambda (list)
89 (:lambda (list)
87 (p:text (elt list 0))))
90 (p:text (elt list 0))))
88
91
89 (p:defrule dquote-esc "\"\""
92 (p:defrule dquote-esc "\"\""
90 (:lambda (list)
93 (:lambda (list)
91 (p:text (elt list 0))))
94 (p:text (elt list 0))))
92
95
93 (p:defrule sstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "\"exec:")))
96 (p:defrule sstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "\"exec:")))
94 (or squote-esc (not-quote character))))
97 (or squote-esc (not-quote character))))
95 (:lambda (list)
98 (:lambda (list)
96 (p:text (mapcar #'second list))))
99 (p:text (mapcar #'second list))))
97
100
98 (p:defrule dstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "'exec:")))
101 (p:defrule dstring-chars (+ (and (and (p:! "<<") (p:! (p:~ "'exec:")))
99 (or dquote-esc (not-doublequote character))))
102 (or dquote-esc (not-doublequote character))))
100 (:lambda (list)
103 (:lambda (list)
101 (p:text (mapcar #'second list))))
104 (p:text (mapcar #'second list))))
102
105
103 ;;; Identifiers
106 ;;; Identifiers
104
107
105 ;; From the official docs
108 (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 for 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 step str strcomp strfind strpos to 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
109
108 (defun trim-$ (str)
110 (defun trim-$ (str)
109 (if (char= #\$ (elt str 0))
111 (if (char= #\$ (elt str 0))
110 (subseq str 1)
112 (subseq str 1)
111 str))
113 str))
112
114
113 (defun qsp-keyword-p (id)
115 (defun qsp-keyword-p (id)
114 (member (intern (trim-$ (string-upcase id))) *keywords*))
116 (member (intern (trim-$ (string-upcase id))) *keywords*))
115
117
116 (defun not-qsp-keyword-p (id)
118 (defun not-qsp-keyword-p (id)
117 (not (member (intern (trim-$ (string-upcase id))) *keywords*)))
119 (not (member (intern (trim-$ (string-upcase id))) *keywords*)))
118
120
119 (p:defrule qsp-keyword (qsp-keyword-p identifier-raw))
121 (p:defrule qsp-keyword (qsp-keyword-p identifier-raw))
120
122
121 (p:defrule id-first (id-any-char character))
123 (p:defrule id-first (id-any-char character))
122 (p:defrule id-next (or (id-any-char character)
124 (p:defrule id-next (or (id-any-char character)
123 (digit-char-p character)))
125 (digit-char-p character)))
124 (p:defrule identifier-raw (and id-first (* id-next))
126 (p:defrule identifier-raw (and id-first (* id-next))
125 (:lambda (list)
127 (:lambda (list)
126 (intern (string-upcase (p:text list)))))
128 (intern (string-upcase (p:text list)))))
127
129
128 (p:defrule identifier (not-qsp-keyword-p identifier-raw))
130 (p:defrule identifier (not-qsp-keyword-p identifier-raw))
129
131
130 ;;; Strings
132 ;;; Strings
131
133
132 (p:defrule qsp-string (or normal-string brace-string))
134 (p:defrule qsp-string (or normal-string brace-string))
133
135
134 (p:defrule normal-string (or sstring dstring)
136 (p:defrule normal-string (or sstring dstring)
135 (:lambda (str)
137 (:lambda (str)
136 (list* 'str (or str (list "")))))
138 (list* 'str (or str (list "")))))
137
139
138 (p:defrule sstring (and #\' (* (or string-interpol
140 (p:defrule sstring (and #\' (* (or string-interpol
139 sstring-exec
141 sstring-exec
140 sstring-chars))
142 sstring-chars))
141 #\')
143 #\')
142 (:function second))
144 (:function second))
143
145
144 (p:defrule dstring (and #\" (* (or string-interpol
146 (p:defrule dstring (and #\" (* (or string-interpol
145 dstring-exec
147 dstring-exec
146 dstring-chars))
148 dstring-chars))
147 #\")
149 #\")
148 (:function second))
150 (:function second))
149
151
150 (p:defrule string-interpol (and "<<" expression ">>")
152 (p:defrule string-interpol (and "<<" expression ">>")
151 (:function second))
153 (:function second))
152
154
153 (p:defrule sstring-exec-body (+ (or squote-esc (not-doublequote character)))
155 (p:defrule sstring-exec-body (+ (or squote-esc (not-doublequote character)))
154 (:text t))
156 (:text t))
155
157
156 (p:defrule dstring-exec-body (+ (or dquote-esc (not-quote character)))
158 (p:defrule dstring-exec-body (+ (or dquote-esc (not-quote character)))
157 (:text t))
159 (:text t))
158
160
159 (p:defrule sstring-exec (and (p:~ "\"exec:") sstring-exec-body #\")
161 (p:defrule sstring-exec (and (p:~ "\"exec:") sstring-exec-body #\")
160 (:lambda (list)
162 (:lambda (list)
161 (list* 'exec (p:parse 'exec-body (second list)))))
163 (list* 'exec (p:parse 'exec-body (second list)))))
162
164
163 (p:defrule dstring-exec (and (p:~ "'exec:") dstring-exec-body #\')
165 (p:defrule dstring-exec (and (p:~ "'exec:") dstring-exec-body #\')
164 (:lambda (list)
166 (:lambda (list)
165 (list* 'exec (p:parse 'exec-body (second list)))))
167 (list* 'exec (p:parse 'exec-body (second list)))))
166
168
167 (p:defrule brace-string (and #\{ before-statement block-body #\})
169 (p:defrule brace-string (and #\{ before-statement block-body #\})
168 (:lambda (list)
170 (:lambda (list)
169 (list* 'qspblock (third list))))
171 (list* 'qspblock (third list))))
170
172
171 ;;; Location
173 ;;; Location
172
174
173 (p:defrule sugar-qsp-grammar (and (* (or spaces #\newline))
175 (p:defrule sugar-qsp-grammar (and (* (or spaces #\newline))
174 (* location))
176 (* location))
175 (:function second))
177 (:function second))
176
178
177 (p:defrule location (and location-header block-body location-end)
179 (p:defrule location (and location-header block-body location-end)
178 (:destructure (header body end)
180 (:destructure (header body end)
179 (declare (ignore end))
181 (declare (ignore end))
180 `(location (,header) ,@body)))
182 `(location (,header) ,@body)))
181
183
182 (p:defrule location-header (and #\#
184 (p:defrule location-header (and #\#
183 (+ not-newline)
185 (+ not-newline)
184 (and #\newline spaces? before-statement))
186 (and #\newline spaces? before-statement))
185 (:destructure (spaces1 name spaces2)
187 (:destructure (spaces1 name spaces2)
186 (declare (ignore spaces1 spaces2))
188 (declare (ignore spaces1 spaces2))
187 (string-upcase (string-trim " " (p:text name)))))
189 (string-upcase (string-trim " " (p:text name)))))
188
190
189 (p:defrule location-end (and #\- (* not-newline) #\newline before-statement)
191 (p:defrule location-end (and #\- (* not-newline) #\newline before-statement)
190 (:constant nil))
192 (:constant nil))
191
193
192 ;;; Block body
194 ;;; Block body
193
195
194 (p:defrule newline-block-body (and #\newline spaces? block-body)
196 (p:defrule newline-block-body (and #\newline spaces? block-body)
195 (:function third))
197 (:function third))
196
198
197 (p:defrule block-body (* statement)
199 (p:defrule block-body (* statement)
198 (:function remove-nil))
200 (:function remove-nil))
199
201
200 ;; Just for <a href="exec:...'>
202 ;; Just for <a href="exec:...'>
201 ;; Explicitly called from that rule's production
203 ;; Explicitly called from that rule's production
202 (p:defrule exec-body (and before-statement line-body)
204 (p:defrule exec-body (and before-statement line-body)
203 (:function second))
205 (:function second))
204
206
205 (p:defrule line-body (and inline-statement (* next-inline-statement))
207 (p:defrule line-body (and inline-statement (* next-inline-statement))
206 (:lambda (list)
208 (:lambda (list)
207 (list* (first list) (second list))))
209 (list* (first list) (second list))))
208
210
209 (p:defrule before-statement (* (or #\newline spaces))
211 (p:defrule before-statement (* (or #\newline spaces))
210 (:constant nil))
212 (:constant nil))
211
213
212 (p:defrule statement-end (or statement-end-real statement-end-block-close))
214 (p:defrule statement-end (or statement-end-real statement-end-block-close))
213
215
214 (p:defrule statement-end-real (and (or #\newline
216 (p:defrule statement-end-real (and (or #\newline
215 (and #\& spaces? (p:& statement%)))
217 (and #\& spaces? (p:& statement%)))
216 before-statement)
218 before-statement)
217 (:constant nil))
219 (:constant nil))
218
220
219 (p:defrule statement-end-block-close (or (p:& #\}))
221 (p:defrule statement-end-block-close (or (p:& #\}))
220 (:constant nil))
222 (:constant nil))
221
223
222 (p:defrule inline-statement (and statement% spaces?)
224 (p:defrule inline-statement (and statement% spaces?)
223 (:function first))
225 (:function first))
224
226
225 (p:defrule next-inline-statement (and #\& spaces? inline-statement)
227 (p:defrule next-inline-statement (and #\& spaces? inline-statement)
226 (:function third))
228 (:function third))
227
229
228 (p:defrule not-a-non-statement (and (p:! (p:~ "elseif"))
230 (p:defrule not-a-non-statement (and (p:! (p:~ "elseif"))
229 (p:! (p:~ "else"))
231 (p:! (p:~ "else"))
230 (p:! (p:~ "end"))))
232 (p:! (p:~ "end"))))
231
233
232 (p:defrule statement (and inline-statement statement-end)
234 (p:defrule statement (and inline-statement statement-end)
233 (:function first))
235 (:function first))
234
236
235 (p:defrule statement% (and not-a-non-statement
237 (p:defrule statement% (and not-a-non-statement
236 (or label comment string-output
238 (or label comment string-output
237 block non-returning-intrinsic local
239 block non-returning-intrinsic local
238 assignment expression-output))
240 assignment expression-output))
239 (:function second))
241 (:function second))
240
242
241 (p:defrule expr-stopper (or comment block non-returning-intrinsic))
243 (p:defrule expr-stopper (or comment block non-returning-intrinsic))
242
244
243 (p:defrule string-output qsp-string
245 (p:defrule string-output qsp-string
244 (:lambda (string)
246 (:lambda (string)
245 (list 'main-pl string)))
247 (list 'main-pl string)))
246
248
247 (p:defrule expression-output expression
249 (p:defrule expression-output expression
248 (:lambda (list)
250 (:lambda (list)
249 (list 'main-pl list)))
251 (list 'main-pl list)))
250
252
251 (p:defrule label (and colon identifier)
253 (p:defrule label (and colon identifier)
252 (:lambda (list)
254 (:lambda (list)
253 (intern (string (second list)) :keyword)))
255 (intern (string (second list)) :keyword)))
254
256
255 (p:defrule comment (and #\! (* (or qsp-string brace-comment text-spaces not-newline)))
257 (p:defrule comment (and #\! (* (or qsp-string brace-comment text-spaces not-newline)))
256 (:constant nil))
258 (:constant nil))
257
259
258 (p:defrule brace-comment (and #\{ (* (not-brace character)) #\})
260 (p:defrule brace-comment (and #\{ (* (not-brace character)) #\})
259 (:constant nil))
261 (:constant nil))
260
262
261 (p:defrule local (and (p:~ "local") spaces variable (p:? (and spaces? #\= spaces? expression)))
263 (p:defrule local (and (p:~ "local") spaces variable (p:? (and spaces? #\= spaces? expression)))
262 (:lambda (list)
264 (:lambda (list)
263 (list* 'local (third list)
265 (list* 'local (third list)
264 (when (fourth list)
266 (when (fourth list)
265 (list (fourth (fourth list)))))))
267 (list (fourth (fourth list)))))))
266
268
267 ;;; Blocks
269 ;;; Blocks
268
270
269 (p:defrule block (or block-act block-if))
271 (p:defrule block (or block-act block-if block-for))
270
272
271 (p:defrule block-if (and block-if-head block-if-body)
273 (p:defrule block-if (and block-if-head block-if-body)
272 (:destructure (head body)
274 (:destructure (head body)
273 `(qspcond (,@head ,@(first body))
275 `(qspcond (,@head ,@(first body))
274 ,@(rest body))))
276 ,@(rest body))))
275
277
276 (p:defrule block-if-head (and (p:~ "if") spaces expression spaces? colon spaces?)
278 (p:defrule block-if-head (and (p:~ "if") spaces expression spaces? colon spaces?)
277 (:function remove-nil)
279 (:function remove-nil)
278 (:function cdr))
280 (:function cdr))
279
281
280 (p:defrule block-if-body (or block-if-ml block-if-sl)
282 (p:defrule block-if-body (or block-if-ml block-if-sl)
281 (:destructure (if-body elseifs else &rest ws)
283 (:destructure (if-body elseifs else &rest ws)
282 (declare (ignore ws))
284 (declare (ignore ws))
283 `(,(remove-nil if-body) ,@elseifs ,@(when else `((else ,@else))))))
285 `(,(remove-nil if-body) ,@elseifs ,@(when else `((else ,@else))))))
284
286
285 (p:defrule block-if-sl (and line-body
287 (p:defrule block-if-sl (and line-body
286 (p:? block-if-elseif-inline)
288 (p:? block-if-elseif-inline)
287 (p:? block-if-else-inline)
289 (p:? block-if-else-inline)
288 spaces?))
290 spaces?))
289
291
290 (p:defrule block-if-ml (and (and #\newline spaces?)
292 (p:defrule block-if-ml (and (and #\newline spaces?)
291 block-body
293 block-body
292 (p:? block-if-elseif)
294 (p:? block-if-elseif)
293 (p:? block-if-else)
295 (p:? block-if-else)
294 block-if-end)
296 block-if-end)
295 (:lambda (list)
297 (:lambda (list)
296 (cdr list)))
298 (cdr list)))
297
299
298 (p:defrule block-if-elseif-inline (and block-if-elseif-head line-body (p:? block-if-elseif-inline))
300 (p:defrule block-if-elseif-inline (and block-if-elseif-head line-body (p:? block-if-elseif-inline))
299 (:destructure (head statements elseif)
301 (:destructure (head statements elseif)
300 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
302 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
301
303
302 (p:defrule block-if-elseif (and block-if-elseif-head statement-end block-body (p:? block-if-elseif))
304 (p:defrule block-if-elseif (and block-if-elseif-head statement-end block-body (p:? block-if-elseif))
303 (:destructure (head ws statements elseif)
305 (:destructure (head ws statements elseif)
304 (declare (ignore ws))
306 (declare (ignore ws))
305 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
307 `((,@(rest head) ,@(remove-nil statements)) ,@elseif)))
306
308
307 (p:defrule block-if-elseif-head (and (p:~ "elseif") spaces expression spaces? colon spaces?)
309 (p:defrule block-if-elseif-head (and (p:~ "elseif") spaces expression spaces? colon spaces?)
308 (:function remove-nil)
310 (:function remove-nil)
309 (:function intern-first))
311 (:function intern-first))
310
312
311 (p:defrule block-if-else-inline (and block-if-else-head line-body)
313 (p:defrule block-if-else-inline (and block-if-else-head line-body)
312 (:function second))
314 (:function second))
313
315
314 (p:defrule block-if-else (and block-if-else-head #\newline spaces? block-body)
316 (p:defrule block-if-else (and block-if-else-head #\newline spaces? block-body)
315 (:function fourth))
317 (:function fourth))
316
318
317 (p:defrule block-if-else-head (and (p:~ "else") spaces?)
319 (p:defrule block-if-else-head (and (p:~ "else") spaces?)
318 (:constant nil))
320 (:constant nil))
319
321
320 (p:defrule block-if-end (and (p:~ "end")
322 (p:defrule block-if-end (and (p:~ "end")
321 (p:? (and spaces (p:~ "if"))))
323 (p:? (and spaces (p:~ "if"))))
322 (:constant nil))
324 (:constant nil))
323
325
324 (p:defrule block-act (and block-act-head (or block-act-ml block-act-sl))
326 (p:defrule block-act (and block-act-head (or block-act-ml block-act-sl))
325 (:lambda (list)
327 (:lambda (list)
326 (apply #'append list)))
328 (apply #'append list)))
327
329
328 (p:defrule block-act-sl line-body)
329
330 (p:defrule block-act-ml (and newline-block-body block-act-end)
331 (:lambda (list)
332 (apply #'list* (butlast list))))
333
334 (p:defrule block-act-head (and (p:~ "act") spaces qsp-string spaces?
330 (p:defrule block-act-head (and (p:~ "act") spaces qsp-string spaces?
335 (p:? block-act-head-img)
331 (p:? block-act-head-img)
336 colon spaces?)
332 colon spaces?)
337 (:lambda (list)
333 (:lambda (list)
338 (intern-first (list (first list)
334 (intern-first (list (first list)
339 (third list)
335 (third list)
340 (or (fifth list) '(str ""))))))
336 (or (fifth list) '(str ""))))))
341
337
342 (p:defrule block-act-head-img (and #\, spaces? qsp-string spaces?)
338 (p:defrule block-act-head-img (and #\, spaces? qsp-string spaces?)
343 (:lambda (list)
339 (:lambda (list)
344 (or (third list) "")))
340 (or (third list) "")))
345
341
346 (p:defrule block-act-end (and (p:~ "end"))
342 (p:defrule block-for (and block-for-head (or block-ml block-sl))
343 (:lambda (list)
344 (apply #'append list)))
345
346 (p:defrule block-for-head (and (p:~ "for") spaces variable spaces? equal spaces? expression
347 (p:~ "to") spaces expression
348 block-for-head-step
349 colon spaces?)
350 (:lambda (list)
351 (unless (eq (fourth (third list)) :num)
352 (error "For counter variable must be numeric."))
353 (list 'qspfor
354 (elt list 2)
355 (elt list 6)
356 (elt list 9)
357 (elt list 10))))
358
359 (p:defrule block-for-head-step (p:? (and (p:~ "step") spaces expression spaces?))
360 (:lambda (list)
361 (if list
362 (third list)
363 1)))
364
365 (p:defrule block-sl line-body)
366
367 (p:defrule block-ml (and newline-block-body block-end)
368 (:lambda (list)
369 (apply #'list* (butlast list))))
370
371 (p:defrule block-end (and (p:~ "end"))
347 (:constant nil))
372 (:constant nil))
348
373
349 ;;; Calls
374 ;;; Calls
350
375
351 (p:defrule first-argument (and expression spaces?)
376 (p:defrule first-argument (and expression spaces?)
352 (:function first))
377 (:function first))
353 (p:defrule next-argument (and "," spaces? expression)
378 (p:defrule next-argument (and "," spaces? expression)
354 (:function third))
379 (:function third))
355 (p:defrule arguments (or parenthesized-arguments plain-arguments no-arguments))
380 (p:defrule arguments (or parenthesized-arguments plain-arguments no-arguments))
356 (p:defrule parenthesized-arguments (and spaces? #\( base-arguments #\))
381 (p:defrule parenthesized-arguments (and spaces? #\( base-arguments #\))
357 (:function third))
382 (:function third))
358 (p:defrule plain-arguments (and spaces base-arguments)
383 (p:defrule plain-arguments (and spaces base-arguments)
359 (:function second))
384 (:function second))
360 (p:defrule no-arguments (or (and spaces? (p:& #\newline))
385 (p:defrule no-arguments (or (and spaces? (p:& #\newline))
361 (and spaces? (p:& #\&))
386 (and spaces? (p:& #\&))
362 spaces?)
387 spaces?)
363 (:constant nil))
388 (:constant nil))
364 (p:defrule base-arguments (or (and first-argument (* next-argument)) spaces?)
389 (p:defrule base-arguments (or (and first-argument (* next-argument)) spaces?)
365 (:lambda (list)
390 (:lambda (list)
366 (if (null list)
391 (if (null list)
367 nil
392 nil
368 (list* (first list) (second list)))))
393 (list* (first list) (second list)))))
369
394
370 ;;; Intrinsics
395 ;;; Intrinsics
371
396
372 (defmacro defintrinsics ((rule-name returning-rule-name non-returning-rule-name) &body clauses)
397 (defmacro defintrinsics ((rule-name returning-rule-name non-returning-rule-name) &body clauses)
373 `(progn
398 `(progn
374 ,@(loop :for clause :in clauses
399 ,@(loop :for clause :in clauses
375 :collect `(defintrinsic ,@clause))
400 :collect `(defintrinsic ,@clause))
376 (p:defrule ,returning-rule-name (or ,@(remove-nil
401 (p:defrule ,returning-rule-name (or ,@(remove-nil
377 (mapcar (lambda (clause)
402 (mapcar (lambda (clause)
378 (when (second clause)
403 (when (second clause)
379 (alexandria:symbolicate
404 (alexandria:symbolicate
380 'intrinsic- (first clause))))
405 'intrinsic- (first clause))))
381 clauses))))
406 clauses))))
382 (p:defrule ,non-returning-rule-name (or ,@(remove-nil
407 (p:defrule ,non-returning-rule-name (or ,@(remove-nil
383 (mapcar (lambda (clause)
408 (mapcar (lambda (clause)
384 (unless (second clause)
409 (unless (second clause)
385 (alexandria:symbolicate
410 (alexandria:symbolicate
386 'intrinsic- (first clause))))
411 'intrinsic- (first clause))))
387 clauses))))
412 clauses))))
388 (p:defrule ,rule-name (or ,returning-rule-name ,non-returning-rule-name))))
413 (p:defrule ,rule-name (or ,returning-rule-name ,non-returning-rule-name))))
389
414
390 (defmacro defintrinsic (sym returning &optional (min-arity 0) (max-arity 10) &rest names)
415 (defmacro defintrinsic (sym returning &optional (min-arity 0) (max-arity 10) &rest names)
391 (declare (ignore returning))
416 (declare (ignore returning))
392 (setf names
417 (setf names
393 (if names
418 (if names
394 (mapcar #'string-upcase names)
419 (mapcar #'string-upcase names)
395 (list (string sym))))
420 (list (string sym))))
396 `(p:defrule ,(alexandria:symbolicate 'intrinsic- sym)
421 `(p:defrule ,(alexandria:symbolicate 'intrinsic- sym)
397 (and (p:? #\$) (or ,@(loop :for name :in names :collect `(p:~ ,name)))
422 (and (p:? #\$) (or ,@(loop :for name :in names :collect `(p:~ ,name)))
398 arguments)
423 arguments)
399 (:destructure (dollar name arguments)
424 (:destructure (dollar name arguments)
400 (declare (ignore dollar))
425 (declare (ignore dollar))
401 (unless (<= ,min-arity (length arguments) ,max-arity)
426 (unless (<= ,min-arity (length arguments) ,max-arity)
402 (error "Intrinsic ~A expects between ~A and ~A arguments but ~A were provided:~%~S"
427 (error "Intrinsic ~A expects between ~A and ~A arguments but ~A were provided:~%~S"
403 name ,min-arity ,max-arity (length arguments) arguments))
428 name ,min-arity ,max-arity (length arguments) arguments))
404 (list* ',sym arguments))))
429 (list* ',sym arguments))))
405
430
406 (defintrinsics (intrinsic returning-intrinsic non-returning-intrinsic)
431 (defintrinsics (intrinsic returning-intrinsic non-returning-intrinsic)
407 ;; Transitions
432 ;; Transitions
408 (goto nil 0 10 "gt" "goto")
433 (goto nil 0 10 "gt" "goto")
409 (xgoto nil 0 10 "xgt" "xgoto")
434 (xgoto nil 0 10 "xgt" "xgoto")
410 ;; Variables
435 ;; Variables
411 (killvar nil 0 2)
436 (killvar nil 0 2)
412 ;; Expressions
437 ;; Expressions
413 (obj t 1 1)
438 (obj t 1 1)
414 (loc t 1 1)
439 (loc t 1 1)
415 (no t 1 1)
440 (no t 1 1)
416 ;; Basic
441 ;; Basic
417 (qspver t 0 0)
442 (qspver t 0 0)
418 (curloc t 0 0)
443 (curloc t 0 0)
419 (rand t 1 2)
444 (rand t 1 2)
420 (rnd t 0 0)
445 (rnd t 0 0)
421 (qspmax t 1 10 "max")
446 (qspmax t 1 10 "max")
422 (qspmin t 1 10 "min")
447 (qspmin t 1 10 "min")
423 ;; Arrays
448 ;; Arrays
424 (killall nil 0 0)
449 (killall nil 0 0)
425 (copyarr nil 2 4)
450 (copyarr nil 2 4)
426 (arrsize t 1 1)
451 (arrsize t 1 1)
427 (arrpos t 2 3)
452 (arrpos t 2 3)
428 (arrcomp t 2 3)
453 (arrcomp t 2 3)
429 ;; Strings
454 ;; Strings
430 (len t 1 1)
455 (len t 1 1)
431 (mid t 2 3)
456 (mid t 2 3)
432 (ucase t 1 1)
457 (ucase t 1 1)
433 (lcase t 1 1)
458 (lcase t 1 1)
434 (trim t 1 1)
459 (trim t 1 1)
435 (replace t 2 3)
460 (replace t 2 3)
436 (instr t 2 3)
461 (instr t 2 3)
437 (isnum t 1 1)
462 (isnum t 1 1)
438 (val t 1 1)
463 (val t 1 1)
439 (qspstr t 1 1 "str")
464 (qspstr t 1 1 "str")
440 (strcomp t 2 2)
465 (strcomp t 2 2)
441 (strfind t 2 3)
466 (strfind t 2 3)
442 (strpos t 2 3)
467 (strpos t 2 3)
443 ;; IF
468 ;; IF
444 (iif t 2 3)
469 (iif t 2 3)
445 ;; Subs
470 ;; Subs
446 (gosub nil 1 10 "gosub" "gs")
471 (gosub nil 1 10 "gosub" "gs")
447 (func t 1 10)
472 (func t 1 10)
448 (exit nil 0 0)
473 (exit nil 0 0)
449 ;; Jump
474 ;; Jump
450 (jump nil 1 1)
475 (jump nil 1 1)
451 ;; Dynamic
476 ;; Dynamic
452 (dynamic nil 1 10)
477 (dynamic nil 1 10)
453 (dyneval t 1 10)
478 (dyneval t 1 10)
454 ;; Main window
479 ;; Main window
455 (main-pl nil 1 1 "*pl")
480 (main-pl nil 1 1 "*pl")
456 (main-nl nil 0 1 "*nl")
481 (main-nl nil 0 1 "*nl")
457 (main-p nil 1 1 "*p")
482 (main-p nil 1 1 "*p")
458 (maintxt t 0 0)
483 (maintxt t 0 0)
459 (desc t 1 1)
484 (desc t 1 1)
460 (main-clear nil 0 0 "*clear" "*clr")
485 (main-clear nil 0 0 "*clear" "*clr")
461 ;; Aux window
486 ;; Aux window
462 (showstat nil 1 1)
487 (showstat nil 1 1)
463 (stat-pl nil 1 1 "pl")
488 (stat-pl nil 1 1 "pl")
464 (stat-nl nil 0 1 "nl")
489 (stat-nl nil 0 1 "nl")
465 (stat-p nil 1 1 "p")
490 (stat-p nil 1 1 "p")
466 (stattxt t 0 0)
491 (stattxt t 0 0)
467 (stat-clear nil 0 0 "clear" "clr")
492 (stat-clear nil 0 0 "clear" "clr")
468 (cls nil 0 0)
493 (cls nil 0 0)
469 ;; Dialog
494 ;; Dialog
470 (msg nil 1 1)
495 (msg nil 1 1)
471 ;; Acts
496 ;; Acts
472 (showacts nil 1 1)
497 (showacts nil 1 1)
473 (delact nil 1 1 "delact" "del act")
498 (delact nil 1 1 "delact" "del act")
474 (curacts t 0 0)
499 (curacts t 0 0)
475 (cla nil 0 0)
500 (cla nil 0 0)
476 ;; Objects
501 ;; Objects
477 (showobjs nil 1 1)
502 (showobjs nil 1 1)
478 (addobj nil 1 3 "addobj" "add obj")
503 (addobj nil 1 3 "addobj" "add obj")
479 (delobj nil 1 1 "delobj" "del obj")
504 (delobj nil 1 1 "delobj" "del obj")
480 (killobj nil 0 1)
505 (killobj nil 0 1)
481 (countobj t 0 0)
506 (countobj t 0 0)
482 (getobj t 1 1)
507 (getobj t 1 1)
483 ;; Menu
508 ;; Menu
484 (menu nil 1 1)
509 (menu nil 1 1)
485 ;; Sound
510 ;; Sound
486 (play nil 1 2)
511 (play nil 1 2)
487 (isplay t 1 1)
512 (isplay t 1 1)
488 (close nil 1 1)
513 (close nil 1 1)
489 (closeall nil 0 0 "close all")
514 (closeall nil 0 0 "close all")
490 ;; Images
515 ;; Images
491 (refint nil 0 0)
516 (refint nil 0 0)
492 (view nil 0 1)
517 (view nil 0 1)
493 ;; Fonts
518 ;; Fonts
494 (rgb t 3 3)
519 (rgb t 3 3)
495 ;; Input
520 ;; Input
496 (showinput nil 1 1)
521 (showinput nil 1 1)
497 (usertxt t 0 0 "user_text" "usrtxt")
522 (usertxt t 0 0 "user_text" "usrtxt")
498 (cmdclear nil 0 0 "cmdclear" "cmdclr")
523 (cmdclear nil 0 0 "cmdclear" "cmdclr")
499 (input t 1 1)
524 (input t 1 1)
500 ;; Files
525 ;; Files
501 (openqst nil 1 1)
526 (openqst nil 1 1)
502 (addqst nil 1 1 "addqst" "addlib" "inclib")
527 (addqst nil 1 1 "addqst" "addlib" "inclib")
503 (killqst nil 1 1 "killqst" "dellib" "freelib")
528 (killqst nil 1 1 "killqst" "dellib" "freelib")
504 (opengame nil 0 0)
529 (opengame nil 0 0)
505 (savegame nil 0 0)
530 (savegame nil 0 0)
506 ;; Real time
531 ;; Real time
507 (wait nil 1 1)
532 (wait nil 1 1)
508 (msecscount t 0 0)
533 (msecscount t 0 0)
509 (settimer nil 1 1))
534 (settimer nil 1 1))
510
535
511 ;;; Expression
536 ;;; Expression
512
537
513 (p:defrule expression or-expr)
538 (p:defrule expression or-expr)
514
539
515 (p:defrule or-expr (and and-expr (* (and spaces? or-op spaces? and-expr)))
540 (p:defrule or-expr (and and-expr (* (and spaces? or-op spaces? and-expr)))
516 (:function do-binop))
541 (:function do-binop))
517
542
518 (p:defrule and-expr (and eq-expr (* (and spaces? and-op spaces? eq-expr)))
543 (p:defrule and-expr (and eq-expr (* (and spaces? and-op spaces? eq-expr)))
519 (:function do-binop))
544 (:function do-binop))
520
545
521 (p:defrule eq-expr (and sum-expr (* (and spaces? (or "<=" ">=" "=<" "=>" "<>"
546 (p:defrule eq-expr (and sum-expr (* (and spaces? (or "<=" ">=" "=<" "=>" "<>"
522 "=" "<" ">" "!")
547 "=" "<" ">" "!")
523 spaces? cat-expr)))
548 spaces? cat-expr)))
524 (:function do-binop))
549 (:function do-binop))
525
550
526 (p:defrule sum-expr (and mod-expr (* (and spaces? (or #\+ #\-) spaces? mod-expr)))
551 (p:defrule sum-expr (and mod-expr (* (and spaces? (or #\+ #\-) spaces? mod-expr)))
527 (:function do-binop))
552 (:function do-binop))
528
553
529 (p:defrule mod-expr (and mul-expr (* (and spaces? (p:~ "mod") spaces? mul-expr)))
554 (p:defrule mod-expr (and mul-expr (* (and spaces? (p:~ "mod") spaces? mul-expr)))
530 (:function do-binop))
555 (:function do-binop))
531
556
532 (p:defrule mul-expr (and unary-expr (* (and spaces? (or #\* #\/) spaces? unary-expr)))
557 (p:defrule mul-expr (and unary-expr (* (and spaces? (or #\* #\/) spaces? unary-expr)))
533 (:function do-binop))
558 (:function do-binop))
534
559
535 (p:defrule unary-expr (and (p:? (or #\+ #\-)) atom-expr)
560 (p:defrule unary-expr (and (p:? (or #\+ #\-)) atom-expr)
536 (:lambda (list)
561 (:lambda (list)
537 (let ((expr (remove-nil list)))
562 (let ((expr (remove-nil list)))
538 (if (= 1 (length expr))
563 (if (= 1 (length expr))
539 (first expr)
564 (first expr)
540 (intern-first expr)))))
565 (intern-first expr)))))
541
566
542 (p:defrule atom-expr (and (or variable literal returning-intrinsic paren-expr) spaces?)
567 (p:defrule atom-expr (and (or variable literal returning-intrinsic paren-expr) spaces?)
543 (:function first))
568 (:function first))
544
569
545 (p:defrule paren-expr (and #\( spaces? expression spaces? #\))
570 (p:defrule paren-expr (and #\( spaces? expression spaces? #\))
546 (:function third))
571 (:function third))
547
572
548 (p:defrule or-op (p:~ "or")
573 (p:defrule or-op (p:~ "or")
549 (:constant "or"))
574 (:constant "or"))
550
575
551 (p:defrule and-op (p:~ "and")
576 (p:defrule and-op (p:~ "and")
552 (:constant "and"))
577 (:constant "and"))
553
578
554 ;;; Variables
579 ;;; Variables
555
580
556 (p:defrule variable (and identifier (p:? array-index))
581 (p:defrule variable (and identifier (p:? array-index))
557 (:destructure (id idx)
582 (:destructure (id idx)
558 (if (char= #\$ (elt (string id) 0))
583 (if (char= #\$ (elt (string id) 0))
559 (list 'var (intern (subseq (string-upcase id) 1)) (or idx 0) :str)
584 (list 'var (intern (subseq (string-upcase id) 1)) (or idx 0) :str)
560 (list 'var id (or idx 0) :num))))
585 (list 'var id (or idx 0) :num))))
561
586
562 (p:defrule array-index (and #\[ spaces? (p:? expression) spaces? #\])
587 (p:defrule array-index (and #\[ spaces? (p:? expression) spaces? #\])
563 (:function third))
588 (:function third))
564
589
565 (p:defrule assignment (or kw-assignment plain-assignment op-assignment)
590 (p:defrule assignment (or kw-assignment plain-assignment op-assignment)
566 (:destructure (var eq expr)
591 (:destructure (var eq expr)
567 (declare (ignore eq))
592 (declare (ignore eq))
568 (list 'set var expr)))
593 (list 'set var expr)))
569
594
570 (p:defrule kw-assignment (and (or (p:~ "let") (p:~ "set")) spaces? (or op-assignment plain-assignment))
595 (p:defrule kw-assignment (and (or (p:~ "let") (p:~ "set")) spaces? (or op-assignment plain-assignment))
571 (:function third))
596 (:function third))
572
597
573 (p:defrule op-assignment (and variable spaces? (or "+" "-" "*" "/") #\= spaces? expression)
598 (p:defrule op-assignment (and variable spaces? (or "+" "-" "*" "/") #\= spaces? expression)
574 (:destructure (var ws1 op eq ws2 expr)
599 (:destructure (var ws1 op eq ws2 expr)
575 (declare (ignore ws1 ws2))
600 (declare (ignore ws1 ws2))
576 (list var eq (intern-first (list op var expr)))))
601 (list var eq (intern-first (list op var expr)))))
577
602
578 (p:defrule plain-assignment (and variable spaces? #\= spaces? expression)
603 (p:defrule plain-assignment (and variable spaces? #\= spaces? expression)
579 (:function remove-nil))
604 (:function remove-nil))
580
605
581 ;;; Non-string literals
606 ;;; Non-string literals
582
607
583 (p:defrule literal (or qsp-string brace-string number))
608 (p:defrule literal (or qsp-string brace-string number))
584
609
585 (p:defrule number (+ (or #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
610 (p:defrule number (+ (or #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
586 (:lambda (list)
611 (:lambda (list)
587 (parse-integer (p:text list))))
612 (parse-integer (p:text list))))
@@ -1,193 +1,203 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 with-frame (&body body)
19 (ps:defpsmacro with-frame (&body body)
20 `(progn
20 `(progn
21 (api-call push-local-frame)
21 (api-call push-local-frame)
22 (unwind-protect
22 (unwind-protect
23 ,@body
23 ,@body
24 (api-call pop-local-frame))))
24 (api-call pop-local-frame))))
25
25
26 ;;; Common
26 ;;; Common
27
27
28 (defmacro defpsintrinsic (name)
28 (defmacro defpsintrinsic (name)
29 `(ps:defpsmacro ,name (&rest args)
29 `(ps:defpsmacro ,name (&rest args)
30 `(funcall (root lib ,',name)
30 `(funcall (root lib ,',name)
31 ,@args)))
31 ,@args)))
32
32
33 (defmacro defpsintrinsics (() &rest names)
33 (defmacro defpsintrinsics (() &rest names)
34 `(progn ,@(loop :for name :in names
34 `(progn ,@(loop :for name :in names
35 :collect `(defpsintrinsic ,name))))
35 :collect `(defpsintrinsic ,name))))
36
36
37 (defpsintrinsics ()
37 (defpsintrinsics ()
38 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)
38 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)
39
39
40 (ps:defpsmacro api-call (func &rest args)
40 (ps:defpsmacro api-call (func &rest args)
41 `(funcall (root api ,func) ,@args))
41 `(funcall (root api ,func) ,@args))
42
42
43 (ps:defpsmacro label-block ((&key (locals t)) &body body)
43 (ps:defpsmacro label-block ((&key (locals t)) &body body)
44 (let ((has-labels (some #'keywordp body)))
44 (let ((has-labels (some #'keywordp body)))
45 `(block nil
45 `(block nil
46 ,@(when has-labels
46 ,@(when has-labels
47 '((defvar __labels)))
47 '((defvar __labels)))
48 ,@(if locals
48 ,@(if locals
49 `((with-frame
49 `((with-frame
50 (tagbody
50 (tagbody
51 ,@body)))
51 ,@body)))
52 `((tagbody
52 `((tagbody
53 ,@body))))))
53 ,@body))))))
54
54
55 (ps:defpsmacro str (&rest forms)
55 (ps:defpsmacro str (&rest forms)
56 (cond ((zerop (length forms))
56 (cond ((zerop (length forms))
57 "")
57 "")
58 ((and (= 1 (length forms))
58 ((and (= 1 (length forms))
59 (stringp (first forms)))
59 (stringp (first forms)))
60 (first forms))
60 (first forms))
61 (t
61 (t
62 `(& ,@forms))))
62 `(& ,@forms))))
63
63
64 ;;; 1loc
64 ;;; 1loc
65
65
66 (ps:defpsmacro location ((name) &body body)
66 (ps:defpsmacro location ((name) &body body)
67 `(setf (root locs ,name)
67 `(setf (root locs ,name)
68 (lambda (args)
68 (lambda (args)
69 (label-block ()
69 (label-block ()
70 (api-call init-args args)
70 (api-call init-args args)
71 ,@body
71 ,@body
72 (api-call get-result)))))
72 (api-call get-result)))))
73
73
74 (ps:defpsmacro goto (target &rest args)
74 (ps:defpsmacro goto (target &rest args)
75 `(progn
75 `(progn
76 (funcall (root lib goto) ,target ,args)
76 (funcall (root lib goto) ,target ,args)
77 (exit)))
77 (exit)))
78
78
79 (ps:defpsmacro xgoto (target &rest args)
79 (ps:defpsmacro xgoto (target &rest args)
80 `(progn
80 `(progn
81 (funcall (root lib xgoto) ,target ,args)
81 (funcall (root lib xgoto) ,target ,args)
82 (exit)))
82 (exit)))
83
83
84 (ps:defpsmacro desc (target)
84 (ps:defpsmacro desc (target)
85 (declare (ignore target))
85 (declare (ignore target))
86 (report-error "DESC is not supported"))
86 (report-error "DESC is not supported"))
87
87
88 ;;; 2var
88 ;;; 2var
89
89
90 (ps:defpsmacro var (name index slot)
90 (ps:defpsmacro var (name index slot)
91 `(api-call get-var ,(string name) ,index ,slot))
91 `(api-call get-var ,(string name) ,index ,slot))
92
92
93 (ps:defpsmacro set ((var vname vindex vslot) value)
93 (ps:defpsmacro set ((var vname vindex vslot) value)
94 (assert (eq var 'var))
94 (assert (eq var 'var))
95 `(api-call set-var ,(string vname) ,vindex ,vslot ,value))
95 `(api-call set-var ,(string vname) ,vindex ,vslot ,value))
96
96
97 ;;; 3expr
97 ;;; 3expr
98
98
99 (ps:defpsmacro <> (op1 op2)
99 (ps:defpsmacro <> (op1 op2)
100 `(not (equal ,op1 ,op2)))
100 `(not (equal ,op1 ,op2)))
101
101
102 (ps:defpsmacro ! (op1 op2)
102 (ps:defpsmacro ! (op1 op2)
103 `(not (equal ,op1 ,op2)))
103 `(not (equal ,op1 ,op2)))
104
104
105 ;;; 4code
105 ;;; 4code
106
106
107 (ps:defpsmacro exec (&body body)
107 (ps:defpsmacro exec (&body body)
108 (format nil "javascript: ~{~A~^~%~}" (mapcar #'ps:ps* body)))
108 (format nil "javascript: ~{~A~^~%~}" (mapcar #'ps:ps* body)))
109
109
110 ;;; 5arrays
110 ;;; 5arrays
111
111
112 ;;; 6str
112 ;;; 6str
113
113
114 (ps:defpsmacro & (&rest args)
114 (ps:defpsmacro & (&rest args)
115 `(ps:chain "" (concat ,@args)))
115 `(ps:chain "" (concat ,@args)))
116
116
117 ;;; 7if
117 ;;; 7if
118
118
119 (ps:defpsmacro qspcond (&rest clauses)
119 (ps:defpsmacro qspcond (&rest clauses)
120 `(cond ,@(loop :for clause :in clauses
120 `(cond ,@(loop :for clause :in clauses
121 :collect (list (first clause)
121 :collect (list (first clause)
122 `(tagbody
122 `(tagbody
123 ,@(rest clause))))))
123 ,@(rest clause))))))
124
124
125 ;;; 8sub
125 ;;; 8sub
126
126
127 ;;; 9loops
127 ;;; 9loops
128 ;;; Yep, that's a huge kludge since Javascript doesn't support arbitrary labels
128 ;;; Yep, that's a huge kludge since Javascript doesn't support arbitrary labels
129
129
130 (ps:defpsmacro jump (target)
130 (ps:defpsmacro jump (target)
131 `(return-from ,(intern (string-upcase (second target)))
131 `(return-from ,(intern (string-upcase (second target)))
132 (funcall (ps:getprop __labels ,target))))
132 (funcall (ps:getprop __labels ,target))))
133
133
134 (ps:defpsmacro tagbody (&body body)
134 (ps:defpsmacro tagbody (&body body)
135 (let ((funcs (list nil :__nil)))
135 (let ((funcs (list nil :__nil)))
136 (dolist (form body)
136 (dolist (form body)
137 (cond ((keywordp form)
137 (cond ((keywordp form)
138 (setf (first funcs) (reverse (first funcs)))
138 (setf (first funcs) (reverse (first funcs)))
139 (push form funcs)
139 (push form funcs)
140 (push nil funcs))
140 (push nil funcs))
141 (t
141 (t
142 (push form (first funcs)))))
142 (push form (first funcs)))))
143 (setf (first funcs) (reverse (first funcs)))
143 (setf (first funcs) (reverse (first funcs)))
144 (setf funcs (reverse funcs))
144 (setf funcs (reverse funcs))
145 (if (= 2 (length funcs))
145 (if (= 2 (length funcs))
146 `(progn
146 `(progn
147 ,@body)
147 ,@body)
148 `(progn
148 `(progn
149 (setf ,@(loop :for f :on funcs :by #'cddr
149 (setf ,@(loop :for f :on funcs :by #'cddr
150 :append `((ps:@ __labels ,(first f))
150 :append `((ps:@ __labels ,(first f))
151 (block ,(intern (string-upcase (string (first f))))
151 (block ,(intern (string-upcase (string (first f))))
152 ,@(second f)
152 ,@(second f)
153 ,@(when (third f)
153 ,@(when (third f)
154 `((funcall
154 `((funcall
155 (ps:getprop __labels ,(third f)))))))))
155 (ps:getprop __labels ,(third f)))))))))
156 (jump (str "__nil"))))))
156 (jump (str "__nil"))))))
157
157
158 ;;; 10dynamic
158 ;;; 10dynamic
159
159
160 (ps:defpsmacro qspblock (&body body)
160 (ps:defpsmacro qspblock (&body body)
161 `(lambda (args)
161 `(lambda (args)
162 (label-block ()
162 (label-block ()
163 (api-call init-args args)
163 (api-call init-args args)
164 ,@body
164 ,@body
165 (api-call get-result))))
165 (api-call get-result))))
166
166
167 ;;; 11main
167 ;;; 11main
168
168
169 (ps:defpsmacro act (name img &body body)
169 (ps:defpsmacro act (name img &body body)
170 `(api-call add-act ,name ,img
170 `(api-call add-act ,name ,img
171 (lambda ()
171 (lambda ()
172 (label-block ()
172 (label-block ()
173 ,@body))))
173 ,@body))))
174
174
175 ;;; 12aux
175 ;;; 12aux
176
176
177 ;;; 13diag
177 ;;; 13diag
178
178
179 ;;; 14act
179 ;;; 14act
180
180
181 ;;; 15objs
181 ;;; 15objs
182
182
183 ;;; 16menu
183 ;;; 16menu
184
184
185 ;;; 17sound
185 ;;; 17sound
186
186
187 ;;; 18img
187 ;;; 18img
188
188
189 ;;; 19input
189 ;;; 19input
190
190
191 ;;; 20time
191 ;;; 20time
192
192
193 ;;; 21local
193 ;;; 21local
194
195 ;;; 22for
196
197 (ps:defpsmacro qspfor (var from to step &body body)
198 `(block nil
199 (set ,var ,from)
200 (ps:for ()
201 ((< ,var ,to))
202 ((set ,var (+ ,var ,step)))
203 ,@body)))
General Comments 0
You need to be logged in to leave comments. Login now