RUN-COMMANDS will take NetLogo commands, put them through the various
stages need to turn them into Common Lisp code, and run it."
- (eval (clnl-transpiler:transpile-commands (clnl-parser:parse (clnl-lexer:lex cmds)))))
+ (clnl-nvm:with-stop-handler (eval (clnl-transpiler:transpile-commands (clnl-parser:parse (clnl-lexer:lex cmds))))))
(defun run-reporter (reporter)
"RUN-REPORTER REPORTER => RESULT
(defvar *ticks* nil)
(defvar *breeds* nil)
+(define-condition stop nil nil)
+
+(defmacro with-stop-handler (&rest forms)
+ "MACRO WITH-STOP-HANDLER &rest FORMS => HANDLED-FORM
+
+ARGUMENTS AND VALUES:
+
+ FORMS: body to be handled
+ HANDLED-FORM: body with handling
+
+DESCRIPTION:
+
+ WITH-STOP-HANDLER is a convenience macro to handle when
+ programs issue a stop condition. When one does, a simple
+ :stop is returned."
+ `(handler-case (progn ,@forms) (stop (s) :stop)))
+
(defstruct turtle who color heading xcor ycor (label "") (label-color 9.9d0) (size 1d0) shape)
(defstruct patch color xcor ycor)
(loop
:for agent := (funcall iter)
:while agent
- :do (let ((*myself* *self*) (*self* agent)) (funcall fn)))))
+ :do (let ((*myself* *self*) (*self* agent)) (with-stop-handler (funcall fn))))))
((agent-p agent-or-agentset)
- (let ((*myself* *self*) (*self* agent-or-agentset)) (funcall fn)))
+ (let ((*myself* *self*) (*self* agent-or-agentset)) (with-stop-handler (funcall fn))))
(t
(error "Ask requires an agentset or agent but got: ~A" agent-or-agentset))))
See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#display"
nil)
+(defun stop ()
+ "STOP => RESULT
+
+ARGUMENTS AND VALUES:
+
+ RESULT: undefined
+
+DESCRIPTION:
+
+ Returns from the current stop block, which will halt the currently running
+ thing, be that the program, current ask block, or procedure. Stop has odd
+ semantics that are best gleaned from the actual NetLogo manual.
+
+ See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#stop"
+ (error (make-condition 'stop)))
+
(defun of (fn agent-or-agentset)
"OF FN AGENT-OR-AGENTSET => RESULT
(defpackage #:clnl-nvm
(:use :common-lisp)
(:shadow #:random #:count)
- (:export #:export-world #:create-world #:current-state
+ (:export #:export-world #:create-world #:current-state #:with-stop-handler
; API as used by transpiled NetLogo programs
#:agent-value
#:ask
#:set-default-shape
#:setxy
#:show
+ #:stop
#:turtles
#:tick
#:ticks
(defsimpleprim :set-default-shape :command clnl-nvm:set-default-shape)
(defsimpleprim :setxy :command clnl-nvm:setxy)
(defsimpleprim :show :command clnl-nvm:show)
+(defsimpleprim :stop :command clnl-nvm:stop)
(defagentvalueprim :size)
(defsimpleprim :tick :command clnl-nvm:tick)
(defsimpleprim :ticks :reporter clnl-nvm:ticks)
(defsimplecommandtest "clear-all 1" "crt 10 ask patches [ set pcolor random 100 ] clear-all"
"7B5DF28923D7FD72158018A876DE8ED02CFB0882")
+
+(defsimplecommandtest "stop 1" "crt 10 stop crt 10"
+ "A925E39EC022967568D238D31F70F0A375024A89")
+
+(defsimplecommandtest "stop 2" "crt 10 ask turtles [ fd 1 stop fd 1 ]"
+ "A6C980CC9843CDD211ABD9C13899010D555F3DC5")