introduction.lisp 3.02 KB
Newer Older
1
(in-package :ps)
2
3

;;; Introduction
4
;;;
5
6
;;; Parenscript is a language that looks a lot like Common Lisp, but
;;; is JavaScript in disguise. This way, JavaScript programs can be
7
8
9
10
11
;;; seamlessly integrated in a Lisp web application. The programmer
;;; doesn't have to resort to a different syntax, and JavaScript code
;;; can easily be generated without having to resort to complicated
;;; string generation or `FORMAT' expressions.
;;;
12
13
;;; The following Lisp expression is a call to the Parenscript
;;; translator Parenscript transforms the expression in Parenscript
14
15
;;; into an equivalent, human-readable expression in JavaScript.

16
(ps
17
  (defun foobar (a b)
18
    (+ a b)))
19
20

;;; The resulting javascript is:
21

Henrik Hjelte's avatar
Henrik Hjelte committed
22
"
23
24
25
function foobar(a, b) {
  return a + b;
}
Henrik Hjelte's avatar
Henrik Hjelte committed
26
"
27

28
29
30
;;; Great care has been given to the indentation and overall
;;; readability of the generated JavaScript code.

31
;;; Features
32
;;;
33
;;; Parenscript supports all the statements and expressions defined by
34
35
;;; the EcmaScript 262 standard. Lisp symbols are converted to
;;; camelcase, javascript-compliant syntax. This idea is taken from
36
37
38
39
40
41
42
43
44
45
46
;;; Linj by Antonio Menezes Leitao. Case sensitivity (using the
;;; :invert readtable-case option) is supported. Here are a few
;;; examples of Lisp symbol to JavaScript name conversion:

(ps foobar)      => "foobar"
(ps foo-bar)     => "fooBar"
(ps foo-b@r)     => "fooBatr"
(ps *array)      => "Array"
(ps FooBar)      => "FooBar"

;;; Parenscript supports a subset of Common Lisp iteration constructs.
47
;;; `for' loops can be written using the customary `DO*' syntax.
48

49
(ps
50
51
52
  (do* ((i 0 (incf i))
        (j (aref arr i) (aref arr i)))
       ((>= i 10))
53
54
    (alert (+ "i is " i " and j is " j))))

55
;; compiles to
Henrik Hjelte's avatar
Henrik Hjelte committed
56
"
57
for (var i = 0, j = arr[i]; i < 10; i = ++i, j = arr[i]) {
Henrik Hjelte's avatar
Henrik Hjelte committed
58
  alert('i is ' + i + ' and j is ' + j);
59
};
Henrik Hjelte's avatar
Henrik Hjelte committed
60
"
61
;;; Parenscript uses the Lisp reader, allowing for reader macros. It
62
;;; also comes with its own macro environment, allowing host Lisp
63
;;; macros and Parenscript macros to coexist without interfering with
64
;;; each other.  For example, the `1+' construct is implemented using
65
;;; a Parenscript macro:
66
67

(defpsmacro 1+ (form)
68
69
  `(+ ,form 1))

70
;;; Parenscript allows the creation of JavaScript objects in a Lispy
71
72
;;; way, using keyword arguments.

73
(ps
74
75
76
  (create :foo "foo"
          :bla "bla"))

77
;; compiles to
Henrik Hjelte's avatar
Henrik Hjelte committed
78
"
79
{ foo : 'foo',
Henrik Hjelte's avatar
Henrik Hjelte committed
80
81
  bla : 'bla' }
"
82
;;; Parenscript features a HTML generator. Using the same syntax as
83
;;; the HTMLGEN package of Franz, Inc., it can generate JavaScript
84
;;; string expressions. This allows for a clean integration of HTML in
85
;;; Parenscript code, instead of writing the tedious and error-prone
86
87
;;; string generation code generally found in JavaScript.

88
(ps
89
  (defun add-div (name href link-text)
90
91
92
93
    (funcall (getprop document 'write)
             (ps-html ((:div :id name)
                       "The link is: "
                       ((:a :href href) link-text))))))
94

95
;; compiles to
Henrik Hjelte's avatar
Henrik Hjelte committed
96
"
97
function addDiv(name, href, linkText) {
98
99
    return document.write(['<div id=\\\"', name, '\\\">The link is: <a href=\\\"', href, '\\\">', linkText, '</a></div>'].join(''));
};
Henrik Hjelte's avatar
Henrik Hjelte committed
100
"