[Wispylisp-devel] !!Ugly!! Loop for javascript message passing

Howard Yeh hayeah at gmail.com
Mon Jun 19 08:51:24 UTC 2006


It's terrible. Not sure how to do better.

* split-by-tests

(defun split-by-tests (msg-lst test-lst &key ((:test default-test) #'eql))
  (flet ((do-test (test msg)
	   (if (functionp test)
	       (funcall test msg)
	       (funcall default-test test msg))))
  (loop with tests = test-lst
	with done-tests = nil
        with section = nil		; What I really want is use collect
instead, but see next comment
	for msgs on msg-lst
	for msg = (car msgs)
        for is-separator? = (loop for test in tests
			       collect test into done-tests2
			       thereis (and (do-test test msg)
					    (setq done-tests (append done-tests2 done-tests)) done-tests2))
        if is-separator?
	  collect (nreverse section) into sections
	  and do (setq section (list msg) ; I need to set section nil here.
Loop facility resets it back when collecting.
		       tests (cdr tests))
	else
	  if (loop for test in done-tests thereis (do-test test msg))
	    do (error "repeated separator ~S found. With tests ~S on list ~S"
msg test-lst msg-lst)
	  else do (push msg section)
	  end
	end
	finally (return (nconc sections (list (nreverse section)))))))
	

This is a utility function I need for parsing the message passing
syntax of javascript forms.


* A few tests for split-by-tests:

(split-by-tests '(~ @) '(~ @))
=> (NIL (~) (@))
(split-by-tests '(1 ~ @) '(~ @))
=> ((1) (~) (@))
(split-by-tests '(~ 2 @) '(~ @))
=> (NIL (~ 2) (@))
(split-by-tests '(~ @ 3) '(~ @))
=> (NIL (~) (@ 3))
(split-by-tests '(~ 2 @ 3) '(~ @))
=> (NIL (~ 2) (@ 3))
(split-by-tests '(1 ~ 2 @ 3) '(~ @))
=> ((1) (~ 2) (@ 3))
(split-by-tests '(1 1 ~ 2 2 @ 3 3) '(~ @))
=> ((1 1) (~ 2 2) (@ 3 3))
(split-by-tests '(1 1 ~ 2 2 @ 3 3 ~ 4 4) '(~ @))
[error]


(defparameter foo (loop for i to 100 collect i))
(defparameter foo-tests (mapcar #'(lambda (x) #'(lambda (y) (eql x y)))
				(loop for i to 100 by 10 collect i)))


(split-by-tests '(1 1 1 1 1 2 1 1 1 1 ) (list #'evenp))
=>
((1 1 1 1 1) (2 1 1 1 1))
(split-by-tests foo foo-tests)
=>
(NIL (0 1 2 3 4 5 6 7 8 9)
     (10 11 12 13 14 15 16 17 18 19)
     (20 21 22 23 24 25 26 27 28 29)
     (30 31 32 33 34 35 36 37 38 39)
     (40 41 42 43 44 45 46 47 48 49)
     (50 51 52 53 54 55 56 57 58 59)
     (60 61 62 63 64 65 66 67 68 69)
     (70 71 72 73 74 75 76 77 78 79)
     (80 81 82 83 84 85 86 87 88 89)
     (90 91 92 93 94 95 96 97 98 99)
     (100))

(split-by-tests foo '(6 25 30 90))
=>
((0 1 2 3 4 5) (6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
 (25 26 27 28 29)
 (30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
  56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
  82 83 84 85 86 87 88 89)
 (90 91 92 93 94 95 96 97 98 99 100))

* The planned javascript syntax is:


(foo ~)
foo();

1 Special Case for 0 arguments application:
(foo)
foo();

foo
foo

(foo @)
foo[];

(foo @ a)
foo[a];


(foo bar ~)
foo.bar();

(foo ~ a b)
foo(a,b);

(foo bar ~ a b @ c d)
foo.bar(a,b)[c][d];

((foo bar ~ a b @ c d) ~ e f)
foo.bar(a,b)[c][d](e,f);



More information about the Wispylisp-devel mailing list