|
29 | 29 | (*semanitc-errors-list*)
|
30 | 30 | (res-ast (match-top syn-tree)))
|
31 | 31 | (values res-ast
|
32 |
| - *semanitc-errors-list*))) |
| 32 | + (nreverse *semanitc-errors-list*)))) |
33 | 33 |
|
34 | 34 | (defun get-id ()
|
35 | 35 | (prog1 *current-id*
|
|
64 | 64 | (cond
|
65 | 65 | ((string= normal-symbol-string "DEFUN")
|
66 | 66 | (match-defun first-s-expr annotations others))
|
67 |
| - (t (match-function-call first-s-expr annotations others)))))))) |
| 67 | + ((string= normal-symbol-string "DEFPARAMETER") |
| 68 | + (match-defparameter first-s-expr annotations others)) |
| 69 | + ((string= normal-symbol-string "LET") |
| 70 | + (match-let first-s-expr annotations others)) |
| 71 | + ((string= normal-symbol-string "IF") |
| 72 | + (match-if first-s-expr annotations others)) |
| 73 | + (t (match-function-call first-s-expr annotations others))))) |
| 74 | + ((:quote) |
| 75 | + (match-quote term-el))))) |
68 | 76 |
|
69 | 77 | (defun make-ill-node-and-push-to-errors-list (error-text ill-term)
|
70 | 78 | (let ((ill-node (make-illegal-node ill-term :is-top? t))
|
|
128 | 136 | (res-obj
|
129 | 137 | (make-instance
|
130 | 138 | 'defun-node
|
131 |
| - :keyword-lexem (make-atom-node keyword-term :atom-type 'keyword-atom) |
132 |
| - :func-name (make-atom-node func-name :atom-type 'func-name-atom) |
| 139 | + :keyword-atom (make-atom-node keyword-term :atom-type 'keyword-atom-node) |
| 140 | + :func-name (make-atom-node func-name :atom-type 'func-name-atom-node) |
133 | 141 | :parenthesis-info par-info
|
134 | 142 | :parameters-list (make-list-node parms)
|
135 | 143 | :body-forms (get-form*-vector forms)
|
|
145 | 153 | "incorrect defun"
|
146 | 154 | `(:list ,par-info ,keyword-term ,@elements)))))
|
147 | 155 |
|
| 156 | +(defun match-defparameter (keyword-term par-info elements) |
| 157 | + (handler-case |
| 158 | + (destructuring-bind (parameter-name value-s-expr) |
| 159 | + elements |
| 160 | + (let* ((node-id (get-id)) |
| 161 | + (res-obj |
| 162 | + (make-instance |
| 163 | + 'defparameter-node |
| 164 | + :keyword-atom (make-atom-node keyword-term :atom-type 'keyword-atom-node) |
| 165 | + :parameter-name (make-atom-node parameter-name :atom-type 'func-name-atom-node) |
| 166 | + :value-s-expr (match-s-expr value-s-expr) |
| 167 | + :parenthesis-info par-info |
| 168 | + :id node-id))) |
| 169 | + (add-to-stats (get-symbol-atom-normal-string-form parameter-name) |
| 170 | + res-obj |
| 171 | + :stat-name :defparameters |
| 172 | + :file-ver *current-file-ver*) |
| 173 | + res-obj)) |
| 174 | + (error (c) |
| 175 | + (declare (ignore c)) |
| 176 | + (make-ill-node-and-push-to-errors-list |
| 177 | + "incorrect defparameter" |
| 178 | + `(:list ,par-info ,keyword-term ,@elements))))) |
| 179 | + |
| 180 | +(defun match-let (keyword-term par-info elements) |
| 181 | + (handler-case |
| 182 | + (destructuring-bind (let-bindings &rest forms) |
| 183 | + elements |
| 184 | + (let* ((node-id (get-id)) |
| 185 | + (res-obj |
| 186 | + (make-instance |
| 187 | + 'let-node |
| 188 | + :keyword-atom (make-atom-node keyword-term :atom-type 'keyword-atom-node) |
| 189 | + :bindings (match-let-bindings let-bindings) |
| 190 | + :parenthesis-info par-info |
| 191 | + :body-forms (get-form*-vector forms) |
| 192 | + :id node-id))) |
| 193 | + res-obj)) |
| 194 | + (error (c) |
| 195 | + ;(declare (ignore c)) |
| 196 | + (print c) |
| 197 | + (make-ill-node-and-push-to-errors-list |
| 198 | + "incorrect let" |
| 199 | + `(:list ,par-info ,keyword-term ,@elements))))) |
| 200 | + |
| 201 | +(defun match-if (keyword-term par-info elements) |
| 202 | + (handler-case |
| 203 | + (destructuring-bind (test-s-expr then-s-expr &optional else-s-expr) |
| 204 | + elements |
| 205 | + (let* ((node-id (get-id)) |
| 206 | + (res-obj |
| 207 | + (make-instance |
| 208 | + 'if-node |
| 209 | + :keyword-atom (make-atom-node keyword-term :atom-type 'keyword-atom-node) |
| 210 | + :test-s-expr (match-s-expr test-s-expr) |
| 211 | + :then-s-expr (match-s-expr then-s-expr) |
| 212 | + :else-s-expr (when else-s-expr (match-s-expr else-s-expr)) |
| 213 | + :parenthesis-info par-info |
| 214 | + :id node-id))) |
| 215 | + res-obj)) |
| 216 | + (error (c) |
| 217 | + ;(declare (ignore c)) |
| 218 | + (print c) |
| 219 | + (make-ill-node-and-push-to-errors-list |
| 220 | + "incorrect if" |
| 221 | + `(:list ,par-info ,keyword-term ,@elements))))) |
| 222 | + |
| 223 | +(defun match-let-bindings (bindings-term) |
| 224 | + (destructuring-bind (term-type par-info &rest bindings) |
| 225 | + bindings-term |
| 226 | + (if (eq term-type :list) |
| 227 | + (let ((node-id (get-id))) |
| 228 | + (make-instance |
| 229 | + 'bindings-list-node |
| 230 | + :id node-id |
| 231 | + :parenthesis-info par-info |
| 232 | + :elements (when bindings |
| 233 | + (get-let-bindings-vector |
| 234 | + bindings)))) |
| 235 | + (make-ill-node-and-push-to-errors-list |
| 236 | + "incorrect let bindings" |
| 237 | + bindings-term)))) |
| 238 | + |
| 239 | +(defun get-let-bindings-vector (bindings) |
| 240 | + (map 'vector #'match-let-binding bindings)) |
| 241 | + |
| 242 | +(defun match-let-binding (binding) |
| 243 | + (destructuring-bind (term-type par-info &rest others) |
| 244 | + binding |
| 245 | + (cond |
| 246 | + ((eq term-type :atom) |
| 247 | + (unless (eq (get-atom-term-type binding) |
| 248 | + :symbol) |
| 249 | + (return-from match-let-binding |
| 250 | + (make-ill-node-and-push-to-errors-list |
| 251 | + "incorrect let binding (only symbol can be used as local var)" |
| 252 | + binding))) |
| 253 | + (make-instance |
| 254 | + 'decl-var-atom-node |
| 255 | + :id (get-id) |
| 256 | + :lexem-info (first others))) |
| 257 | + ((eq term-type :list) |
| 258 | + (let ((len (length others))) |
| 259 | + (unless (or (= len 1) |
| 260 | + (= len 2)) |
| 261 | + (return-from match-let-binding |
| 262 | + (make-ill-node-and-push-to-errors-list |
| 263 | + "malformed let binding" |
| 264 | + binding))) |
| 265 | + (let ((var (first others)) |
| 266 | + (value (second others))) |
| 267 | + (unless (eq (get-term-type var) :atom) |
| 268 | + (return-from match-let-binding |
| 269 | + (make-ill-node-and-push-to-errors-list |
| 270 | + "malformed let binding" |
| 271 | + binding))) |
| 272 | + (let ((node-id (get-id))) |
| 273 | + (make-instance |
| 274 | + 'let-binding-node |
| 275 | + :id node-id |
| 276 | + :parenthesis-info par-info |
| 277 | + :var-atom (make-atom-node var :atom-type 'decl-var-atom-node) |
| 278 | + :value-s-expr (when value |
| 279 | + (match-s-expr value)))))))))) |
| 280 | + |
148 | 281 | (defun make-list-node (list-element)
|
149 | 282 | (when (eq (first list-element) :list)
|
150 | 283 | (let ((node-id (get-id)))
|
|
156 | 289 | (defun match-function-call (func-name-term par-info func-args)
|
157 | 290 | (let ((node-id (get-id)))
|
158 | 291 | (make-instance 'function-call-node
|
159 |
| - :func-lexem (make-atom-node func-name-term :atom-type 'func-name-atom) |
| 292 | + :func-lexem (make-atom-node func-name-term :atom-type 'func-name-atom-node) |
160 | 293 | :parenthesis-info par-info
|
161 | 294 | :func-arg-forms (get-form*-vector func-args)
|
162 | 295 | :id node-id)))
|
| 296 | + |
| 297 | +(defun match-quote (term) |
| 298 | + (let ((node-id (get-id))) |
| 299 | + (make-instance 'quote-node |
| 300 | + :id node-id |
| 301 | + :quote-coord (rest (first (second term))) |
| 302 | + :q-s-expr (make-q-data (third term))))) |
| 303 | + |
| 304 | +(defun make-q-data (term) |
| 305 | + (destructuring-bind (type annotations &rest others) |
| 306 | + term |
| 307 | + (ecase type |
| 308 | + ((:atom) |
| 309 | + (make-atom-node term :atom-type 'q-atom-node)) |
| 310 | + ((:list) |
| 311 | + (make-q-list annotations others)) |
| 312 | + ((:quote) |
| 313 | + (match-quote term))))) |
| 314 | + |
| 315 | +(defun make-q-list (par-info list-elements) |
| 316 | + (let ((node-id (get-id))) |
| 317 | + (make-instance 'q-list-node |
| 318 | + :id node-id |
| 319 | + :parenthesis-info par-info |
| 320 | + :elements (map 'vector #'make-q-data list-elements)))) |
0 commit comments