diff --git a/TODO b/TODO --- a/TODO +++ b/TODO @@ -1,3 +1,6 @@ + +* string array keys as addition to number keys +* arr[] notation (i.e. with empty index) * Windows GUI (for the compiler) * Save-load game in slots diff --git a/examples/21locals.txt b/examples/21locals.txt new file mode 100644 --- /dev/null +++ b/examples/21locals.txt @@ -0,0 +1,8 @@ + +# locals + +var = 1 +dynamic { local var = 2 & *pl var } +*pl var + +----- locals --------------- diff --git a/src/api.ps b/src/api.ps --- a/src/api.ps +++ b/src/api.ps @@ -147,35 +147,49 @@ name)) (defm (root api ensure-var) (name index) - (unless (in name (root vars)) - (setf (ps:getprop (root vars) name) - (ps:create))) - (unless (in index (ps:getprop (root vars) name)) - (setf (ps:getprop (root vars) name index) - (ps:create :num 0 :str ""))) + (let ((store (api-call var-ref name))) + (unless store + (setf store (ps:create)) + (setf (ps:getprop (root vars) name) store))) + (unless (in index store) + (setf (elt store index) (ps:create :num 0 :str ""))) (values)) +(defm (root api var-ref) (name) + (let ((var-name (api-call var-real-name name)) + (local-store (api-call current-local-frame))) + (cond ((in var-name local-store) + (ps:getprop local-store)) + ((in var-name (root vars)) + (ps:getprop (root vars) var-name)) + (t nil)))) + (defm (root api get-var) (name index) - (let ((var-name (api-call var-real-name name))) - (api-call ensure-var var-name index) - (ps:getprop (root vars) var-name index - (api-call var-slot name)))) + (let ((store (var-ref name))) + (if store + (if (in index store) + (ps:getprop store index (api-call var-slot name)) + (report-error (+ "Non-existing index: " name "[" index "]"))) + (report-error (+ "Unknown variable: " name))))) (defm (root api set-var) (name index value) - (let ((var-name (api-call var-real-name name))) + (let ((store (var-ref name))) (api-call ensure-var var-name index) - (setf (ps:getprop (root vars) var-name index + (setf (ps:getprop store index (api-call var-slot name)) value) (values))) -(defm (root api get-array) (name type) - (ps:getprop (root vars) (api-call var-real-name name))) +(defm (root api get-array) (name) + (ps:getprop (root vars) name)) -(defm (root api kill-var) (name index) - (if (eq index :whole) - (ps:delete (ps:getprop (root vars) name)) - (ps:delete (ps:getprop (root vars) name index))) +(defm (root api set-array) (name value) + (setf (ps:getprop (root vars) name) value)) + +(defm (root api kill-var) (name &optional index) + (if index + (ps:delete (ps:getprop (root vars) name index)) + (ps:delete (ps:getprop (root vars) name))) (values)) (defm (root api array-size) (name) @@ -208,3 +222,20 @@ :for v := (ps:getprop (root playing) k) :do (when (ps:@ v ended) (ps:delete (ps:@ (root playing) k))))) + +;;; Locals + +(defm (root api push-local-frame) () + (ps:chain (root locals) (push (ps:create)))) + +(defm (root api pop-local-frame) () + (ps:chain (root locals) (pop))) + +(defm (root api current-local-frame) () + (elt (root locals) (1- (length (root locals))))) + +(defm (root api new-local) (name) + (let ((frame (api-call current-local-frame)) + (var-name (api-call var-real-name name))) + (unless (in var-name frame) + (setf (ps:getprop frame var-name) (ps:create))))) diff --git a/src/intrinsic-macros.lisp b/src/intrinsic-macros.lisp --- a/src/intrinsic-macros.lisp +++ b/src/intrinsic-macros.lisp @@ -8,7 +8,7 @@ ;;; 2var -(ps:defpsmacro killvar (varname &optional (index :whole)) +(ps:defpsmacro killvar (varname &optional index) `(api-call kill-var ,varname ,index)) (ps:defpsmacro killall () @@ -141,4 +141,10 @@ ;;; 20time -;;; misc +;;; 21local + +(ps:defpsmacro local (var &optional expr) + `(progn + (api-call new-local ,(string (second var))) + ,@(when expr + `((set ,var ,expr))))) diff --git a/src/intrinsics.ps b/src/intrinsics.ps --- a/src/intrinsics.ps +++ b/src/intrinsics.ps @@ -91,13 +91,13 @@ ;;; 8sub (defm (root lib gosub) (target &rest args) - (conserving-vars (args result) + (conserving-vars (__funcall args result) (api-call init-args args) (funcall (ps:getprop (root locs) target)) (values))) (defm (root lib func) (target &rest args) - (conserving-vars (args result) + (conserving-vars (__funcall args result) (api-call init-args args) (funcall (ps:getprop (root locs) target)) (api-call get-result))) @@ -107,13 +107,13 @@ ;;; 10dynamic (defm (root lib dyneval) (block &rest args) - (conserving-vars (args result) + (conserving-vars (__funcall args result) (api-call init-args args) (funcall block) (api-call get-result))) (defm (root lib dynamic) (&rest args) - (conserving-vars (args result) + (conserving-vars (__funcall args result) (api-call init-args args) (funcall block) (values))) @@ -211,7 +211,7 @@ (defm (root lib menu) (menu-name) (let ((menu-data (list))) - (loop :for item :in (api-call get-array menu-name) + (loop :for item :in (api-call get-array (api-call var-real-name menu-name)) :do (cond ((string= item "") (break)) ((string= item "-:-") @@ -276,6 +276,8 @@ (defm (root lib settimer) ()) +;;; 21local + ;;; misc (defm (root lib rgb) ()) diff --git a/src/main.ps b/src/main.ps --- a/src/main.ps +++ b/src/main.ps @@ -13,6 +13,8 @@ state-stash (ps:create) ;; List of audio files being played playing (ps:create) + ;; Local variables stack (starts with an empty frame) + locals (list) ;;; Game data ;; ACTions acts (ps:create) diff --git a/src/parser.fasl b/src/parser.fasl deleted file mode 100644 index eeb42ad81c0c6432f60765142df8ff14cef7f18b..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@