diff --git a/spreadsheet.lisp b/spreadsheet.lisp index 230e9e8..a9193fd 100644 --- a/spreadsheet.lisp +++ b/spreadsheet.lisp @@ -12,14 +12,25 @@ (= width (length (car rows))) (assert (apply #'= (mapcar #'length rows))) (= cells-name (gensym "CELLS")) - (= cells `(list ,@(mapcar ))) - (= cells `(make-array (list width (length rows)) - :element-type 'function - :initial-contents - (macrolet ((cell (&rest subscripts) `(aref ,cells-name ,@subscripts))) - ,cells))) - )) - -(sheet - (1 2 3 4 5) - (6 7 8 9 10)) + (= current-index (gensym "CURRENT-INDEX")) + (= cells + `(list + ,@(loop for row in rows + for y from 0 + collecting + `(list + ,@(loop for cell in row + for x from 0 + collecting `(lambda () (let1 ,current-index '(,x ,y) ,cell))))))) + (= cells + `(progn + (defvar ,current-index nil) + (labels ((,cells-name () + (make-array '(,(length rows) ,width) + :element-type 'function + :initial-contents ,cells)) + (cell (x y) + (assert (not (equal (list x y) ,current-index))) + (funcall (aref (,cells-name) y x)))) + (,cells-name)))) + cells)) diff --git a/utils.lisp b/utils.lisp index 699e904..6f099d1 100644 --- a/utils.lisp +++ b/utils.lisp @@ -686,6 +686,12 @@ `(loop for ,(first (car binds)) in ,(second (car binds)) do (doprod ,(cdr binds) ,@body)))) +(defmacro mapprod ((&rest binds) &body body) + (if (null binds) + `(progn ,@body) + `(loop for ,(first (car binds)) in ,(second (car binds)) + collect (mapprod ,(cdr binds) ,@body)))) + (defpattern structure (expr) (match expr ((list 'quote x) `',x)