| | 830 | (defclass js-for (statement) |
|---|
| | 831 | ((vars :initarg :vars :accessor for-vars) |
|---|
| | 832 | (steps :initarg :steps :accessor for-steps) |
|---|
| | 833 | (check :initarg :check :accessor for-check) |
|---|
| | 834 | (body :initarg :body :accessor for-body))) |
|---|
| | 835 | |
|---|
| | 836 | (defun make-for-vars (decls) |
|---|
| | 837 | (loop for decl in decls |
|---|
| | 838 | for var = (if (atom decl) decl (first decl)) |
|---|
| | 839 | for init = (if (atom decl) nil (second decl)) |
|---|
| | 840 | collect (make-instance 'js-defvar :names (list (js-compile-to-symbol var)) |
|---|
| | 841 | :value (js-compile-to-expression init)))) |
|---|
| | 842 | |
|---|
| | 843 | (defun make-for-steps (decls) |
|---|
| | 844 | (loop for decl in decls |
|---|
| | 845 | when (= (length decl) 3) |
|---|
| | 846 | collect (js-compile-to-expression (third decl)))) |
|---|
| | 847 | |
|---|
| | 848 | (define-js-compiler-macro do (decls termination &rest body) |
|---|
| | 849 | (let ((vars (make-for-vars decls)) |
|---|
| | 850 | (steps (make-for-steps decls)) |
|---|
| | 851 | (check (js-compile-to-expression (list 'not (first termination)))) |
|---|
| | 852 | (body (js-compile-to-body (cons 'progn body) :indent " "))) |
|---|
| | 853 | (make-instance 'js-for |
|---|
| | 854 | :vars vars |
|---|
| | 855 | :steps steps |
|---|
| | 856 | :check check |
|---|
| | 857 | :body body))) |
|---|
| | 858 | |
|---|
| | 859 | (defun strings-length (string-list) |
|---|
| | 860 | (reduce #'max (mapcar #'length string-list) :initial-value most-negative-fixnum)) |
|---|
| | 861 | |
|---|
| | 862 | (defmethod js-to-statement-strings ((for js-for) start-pos) |
|---|
| | 863 | (let* ((init (dwim-join (mapcar #'(lambda (x) |
|---|
| | 864 | (dwim-join (list (list (symbol-to-js (first (var-names x)))) |
|---|
| | 865 | (js-to-strings (var-value x) |
|---|
| | 866 | (+ start-pos 2))) |
|---|
| | 867 | (- 80 start-pos 2) |
|---|
| | 868 | :join-after " =")) |
|---|
| | 869 | (for-vars for)) |
|---|
| | 870 | (- 80 start-pos 2) |
|---|
| | 871 | :start "var " :join-after ",")) |
|---|
| | 872 | #+nil |
|---|
| | 873 | (init-len (strings-length init)) |
|---|
| | 874 | (check (js-to-strings (for-check for) (+ start-pos 2))) |
|---|
| | 875 | #+nil |
|---|
| | 876 | (check-len (strings-length check)) |
|---|
| | 877 | (steps (dwim-join (mapcar #'(lambda (x) |
|---|
| | 878 | (js-to-strings x (- start-pos 2))) |
|---|
| | 879 | (for-steps for)) |
|---|
| | 880 | (- 80 start-pos 2) |
|---|
| | 881 | :join-after ",")) |
|---|
| | 882 | (header (dwim-join (list init check steps) |
|---|
| | 883 | (- 80 start-pos 2) |
|---|
| | 884 | :start "for (" :end ") {" |
|---|
| | 885 | :join-after ";")) |
|---|
| | 886 | (body (js-to-statement-strings (for-body for) (+ start-pos 2)))) |
|---|
| | 887 | (nconc header body (list "}")))) |
|---|
| | 888 | |
|---|
| | 889 | (let ((fun-header (dwim-join (mapcar #'(lambda (x) (list (symbol-to-js x))) |
|---|
| | 890 | (d-args defun)) |
|---|
| | 891 | (- 80 start-pos 2) |
|---|
| | 892 | :start (format nil "function ~A(" |
|---|
| | 893 | (symbol-to-js (d-name defun))) |
|---|
| | 894 | :end ") {" :join-after ",")) |
|---|
| | 895 | (fun-body (js-to-statement-strings (d-body defun) (+ start-pos 2)))) |
|---|
| | 896 | (nconc fun-header fun-body (list "}")))) |
|---|
| | 897 | |
|---|
| | 898 | (defclass for-each (statement) |
|---|
| | 899 | ((name :initarg :name :accessor fe-name) |
|---|
| | 900 | (value :initarg :value :accessor fe-value) |
|---|
| | 901 | (body :initarg :value :accessor fe-body))) |
|---|
| | 902 | |
|---|
| | 903 | (define-js-compiler-macro do-each (decl &rest body) |
|---|
| | 904 | (make-instance 'for-each :name (js-compile-to-symbol (first decl)) |
|---|
| | 905 | :value (js-compile-to-expression (second decl)) |
|---|
| | 906 | :body (js-compile-to-body (cons 'progn body) :indent " "))) |
|---|
| | 907 | |
|---|
| | 908 | (defmethod js-to-statement-strings ((fe for-each) start-pos) |
|---|
| | 909 | (let ((header (dwim-join (list (list (symbol-to-js (fe-name fe)) " in ") |
|---|
| | 910 | (js-to-strings (fe-value fe) (+ start-pos 2))) |
|---|
| | 911 | :start "for (var " |
|---|
| | 912 | :end ") {")) |
|---|
| | 913 | (body (js-to-statement-strings (fe-body fe) (+ start-pos 2)))) |
|---|
| | 914 | (nconc header body (list "}")))) |
|---|
| | 915 | |
|---|
| | 916 | (defclass js-while (statement) |
|---|
| | 917 | ((check :initarg :check :accessor while-check) |
|---|
| | 918 | (body :initarg :body :accessor while-body))) |
|---|
| | 919 | |
|---|
| | 920 | (define-js-compiler-macro while (check &rest body) |
|---|
| | 921 | (make-instance 'js-while |
|---|
| | 922 | :check (js-compile-to-expression check) |
|---|
| | 923 | :body (js-compile-to-body (cons 'progn body) :indent " "))) |
|---|
| | 924 | |
|---|
| | 925 | (defmethod js-to-statement-strings ((while js-while) start-pos) |
|---|
| | 926 | (let ((header (dwim-join (list (js-to-strings (while-check while) (+ start-pos 2))) |
|---|
| | 927 | (- 80 start-pos 2) |
|---|
| | 928 | :start "while (" |
|---|
| | 929 | :end ") {")) |
|---|
| | 930 | (body (js-to-statement-strings (while-body while) (+ start-pos 2)))) |
|---|
| | 931 | (nconc header body (list "}")))) |
|---|
| | 932 | |
|---|
| | 953 | (defclass js-case (statement) |
|---|
| | 954 | ((value :initarg :value :accessor case-value) |
|---|
| | 955 | (clauses :initarg :clauses :accessor case-clauses))) |
|---|
| | 956 | |
|---|
| | 957 | ;;; XXX DEFAULT exporten |
|---|
| | 958 | (define-js-compiler-macro case (value &rest clauses) |
|---|
| | 959 | (let ((clauses (mapcar #'(lambda (clause) |
|---|
| | 960 | (let ((val (first clause)) |
|---|
| | 961 | (body (cdr clause))) |
|---|
| | 962 | (list (if (eql val 'default) |
|---|
| | 963 | 'default |
|---|
| | 964 | (js-compile-to-expression val)) |
|---|
| | 965 | (js-compile-to-body (cons 'progn body) :indent " ")))) |
|---|
| | 966 | clauses)) |
|---|
| | 967 | (check (js-compile-to-expression value))) |
|---|
| | 968 | (make-instance 'js-case :value check |
|---|
| | 969 | :clauses clauses))) |
|---|
| | 970 | |
|---|
| | 971 | (defmethod js-to-statement-strings ((case js-case) start-pos) |
|---|
| | 972 | (let ((body (mapcan #'(lambda (clause) |
|---|
| | 973 | (let ((val (car clause)) |
|---|
| | 974 | (body (second clause))) |
|---|
| | 975 | (dwim-join (list (if (eql val 'default) |
|---|
| | 976 | (list "") |
|---|
| | 977 | (js-to-strings val (+ start-pos 2))) |
|---|
| | 978 | (js-to-statement-strings body (+ start-pos 2))) |
|---|
| | 979 | (- 80 start-pos 2) |
|---|
| | 980 | :start (if (eql val 'default) " default" " case ") |
|---|
| | 981 | :white-space " " |
|---|
| | 982 | :join-after ":"))) (case-clauses case)))) |
|---|
| | 983 | |
|---|
| | 984 | (format t "body: ~S~%" body) |
|---|
| | 985 | (nconc (dwim-join (list (js-to-strings (case-value case) (+ start-pos 2))) |
|---|
| | 986 | (- 80 start-pos 2) |
|---|
| | 987 | :start "switch (" :end ") {") |
|---|
| | 988 | body |
|---|
| | 989 | (list "}")))) |
|---|
| | 990 | |
|---|
| | 992 | |
|---|
| | 993 | (defclass js-try (statement) |
|---|
| | 994 | ((body :initarg :body :accessor try-body) |
|---|
| | 995 | (catch :initarg :catch :accessor try-catch) |
|---|
| | 996 | (finally :initarg :finally :accessor try-finally))) |
|---|
| | 997 | |
|---|
| | 998 | (define-js-compiler-macro try (body clauses) |
|---|
| | 999 | (let ((body (js-compile-to-body body :indent " ")) |
|---|
| | 1000 | (catch (cdr (assoc :catch clauses))) |
|---|
| | 1001 | (finally (cdr (assoc :finally clauses)))) |
|---|
| | 1002 | (make-instance 'js-try |
|---|
| | 1003 | :body body |
|---|
| | 1004 | :catch (when catch (list (js-compile-to-symbol (first catch)) |
|---|
| | 1005 | (js-compile-to-body (cons 'progn (cdr catch)) |
|---|
| | 1006 | :indent " "))) |
|---|
| | 1007 | :finally (when finally (js-compile-to-body finally :indent " "))))) |
|---|
| | 1008 | |
|---|
| | 1009 | (defmethod js-to-statement-strings ((try js-try) start-pos) |
|---|
| | 1010 | (let* ((catch (try-catch try)) |
|---|
| | 1011 | (finally (try-finally try)) |
|---|
| | 1012 | (catch-list (when catch |
|---|
| | 1013 | (dwim-join (list (list (symbol-to-js (first catch))) |
|---|
| | 1014 | (js-to-strings (second catch) (+ start-pos 2))) |
|---|
| | 1015 | (- 80 start-pos 2) |
|---|
| | 1016 | :start "} catch (" |
|---|
| | 1017 | :end ") {"))) |
|---|
| | 1018 | (finally-list (when finally |
|---|
| | 1019 | (dwim-join (list (js-to-strings finally (+ start-pos 2))) |
|---|
| | 1020 | (- 80 start-pos 2) |
|---|
| | 1021 | :start "finally {")))) |
|---|
| | 1022 | (nconc (dwim-join (list (js-to-statement-strings (try-body try) (+ start-pos 2))) |
|---|
| | 1023 | (- 80 start-pos 2) |
|---|
| | 1024 | :start "try {") |
|---|
| | 1025 | catch-list |
|---|
| | 1026 | finally-list |
|---|
| | 1027 | (list "}")))) |
|---|