1 (in-package #:cl-nl.parser)
3 ; Ok, after thinking about this a little, the parser is completely contextual
4 ; based on what has come before. We can't do a contextless parsing, like we
5 ; could in other languages, due to amiguity about reporters vs reporter tasks
7 ; So, for instance, we could have:
9 ; x + y => (x (task +) y)
10 ; So the definition of "+" is completely dependent on the nature of x
12 ; The goal of this parser should be to turn in the amiguous lexed ast representing
13 ; NetLogo into an unambigious S-expression, and nothing more, so things like
14 ; expectation of commands being the first symbol is not be necessary until later
16 ; In general, the parser will:
17 ; * Parse the structure of the lexed output first
18 ; * Parse the structure of the individual expressions (finding ('s and ['s and doing the right thing)
19 ; * Coalate things into an unambigious expressions
20 ; * Then we're done, let someone else make it evaluatable
21 ; - We don't really care if things are commands or reporters right now
23 (defparameter *prims* nil)
25 (defun prim-name (prim) (getf prim :name))
26 (defun prim-num-args (prim) (length (getf prim :args)))
28 (defun find-prim (symb) (find symb *prims* :key #'prim-name))
30 ; We don't care if it's a command!
31 ;(defun is-command (symb)
33 ; ((prim (find-prim symb)))
34 ; (and prim (eql :command (getf prim :type)))))
36 ; Make this only as complicated as it needs to be, letting it grow
37 ; as we take on more and more of the language
38 (defun parse (lexed-ast)
41 ((numberp (car lexed-ast)) (cons (coerce (car lexed-ast) 'double-float) (parse (cdr lexed-ast))))
42 ((and (symbolp (car lexed-ast)) (find-prim (car lexed-ast)))
44 ((prim (find-prim (car lexed-ast)))
45 (num-args (prim-num-args prim))
46 (parsed-remainder (parse (cdr lexed-ast))))
50 (butlast parsed-remainder (- (length parsed-remainder) num-args)))
51 (nthcdr num-args parsed-remainder))))
52 (t (error "Couldn't parse ~S" lexed-ast))))
54 (defmacro defprim (name args)
56 (list :name ,name :args ',args)
59 ; This list of prims will get combined with the mapping to actual code later
60 ; Current list of argument types we accept:
63 (defprim :crt (:number))