Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for [[/eggref/5/spock|the CHICKEN 5 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-5.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. [[tags:eggs]] <nowiki> <center><img style="margin-top:3em;" src="http://www.call-with-current-continuation.org/star-trek-spock1.jpg"/> </center> </nowiki> [[toc:]] == spock === Introduction SPOCK is a compiler and runtime system for translating most of R5RS Scheme into JavaScript. You can use it either by statically generating JavaScript files from Scheme source files or by translating s-expressions containing Scheme code on the fly. The compiler uses Henry Baker's [[http://home.pipeline.com/~hbaker1/CheneyMTA.html|Cheney-on-the-MTA]] compilation strategy. This extension is still in a very early state and is likely to contain numerous bugs. There are known problems with Internet Explorer and the system has only been tested on a few browsers. Moreover, the compilation strategy used stresses JavaScript implementations in unusual ways and the results indicate that many JavaScript engines seem to have quite serious limitations regarding static function nesting and closure performance. === Programming interface ==== State management Compilation of Scheme to JavaScript is controlled by a ''state'' object that specifies options relevant to the translation process together with a syntactic ''environment'', i.e. the macro-definitions available to the code to be compiled. Depending on the use of the compiler, it must be possible to explicitly create a new state or re-use an existing one. For example, in a web-server, one usually needs a state local to the current request - syntactic definitions and compilation options should not necessarily be shared between multiple requests. ===== Compilation options Compilation options are given as a list of symbols, where some symbols must be followed by an argument: <table> <tr><th>Option</th><th>Argument</th><th>Meaning</th></tr> <tr><td>source</td><td></td> <td>show source forms</td></tr> <tr><td>expand</td><td></td> <td>show forms after macro-expansion</td></tr> <tr><td>canonicalized</td><td></td> <td>show forms after canonicalization</td></tr> <tr><td>optimized</td><td></td> <td>show forms after optimization</td></tr> <tr><td>cps</td><td></td> <td>show forms after CPS-conversion</td></tr> <tr><td>strict</td><td></td> <td>enable strict mode</td></tr> <tr><td>optimize</td><td></td> <td>enable optimizations</td></tr> <tr><td>block</td><td></td> <td>enable block-compilation</td></tr> <tr><td>library-path</td><td>[DIR]</td> <td>add DIR to library path or return library path</td></tr> <tr><td>namespace</td><td> VAR</td> <td>put globals into module</td></tr> <tr><td>xref</td><td></td> <td>show cross-reference</td></tr> <tr><td>runtime</td><td></td> <td>include runtime-system in generated code</td></tr> <tr><td>library</td><td></td> <td>compile runtime library</td></tr> <tr><td>seal</td><td></td> <td>wrap toplevel definitions into local scope</td></tr> <tr><td>debug</td><td></td> <td>enable debug-mode</td></tr> <tr><td>usage</td><td>PROC</td> <td>invoke PROC on usage-errors</td></tr> <tr><td>fail</td><td>PROC</td> <td>invoke PROC on compiler-errors</td></tr> <tr><td>import</td><td> FILENAME</td> <td>expand FILENAME</td></tr> <tr><td>environment</td><td> STORE</td> <td>provide syntactic environment</td></tr> <tr><td>debug-syntax</td><td></td> <td>show debug-output during expansion</td></tr> <tr><td>verbose</td><td></td> <td>show diagnostic messages</td></tr> <tr><td>prepare</td><td></td> <td>just prepare state without compiling</td></tr> <tr><td>code</td><td>EXP</td> <td>code to be compiled instead of file</td></tr> <tr><td>output-file </td><td>FILENAME</td> <td>specify output-file</td></tr> </table> Note that the argument to the {{library-path}} option may be omitted, which means it must be the last element in the option list. ===== make-spock-state <procedure>(make-spock-state OPTION ...)</procedure> Creates a fresh compilation state, with settings given in {{OPTION ..}} and returns this state. ===== spock-state? <procedure>(spock-state? X)</procedure> Returns {{#t}} if {{X}} is a compilaton state or {{#f}} otherwise. ===== current-spock-state <parameter>current-spock-state</parameter> The currently active compilation state. Defaults to {{#f}}, which means a new state will be created automatically for the next compilation (via {{<spock>}}) and will be re-used on subsequent compilations. ===== spock <procedure>(spock FILENAME-OR-OPTION ...)</procedure> The main interface to the compiler. Any string-argument given will be taken as the name of a Scheme source file to be compiled. If the {{code}} option is given and followed by an expression, then that expression is compiled instead of reading source from files. The other options are the same as those that can be passed to {{make-spock-state}}. ===== spock-initialize <procedure>(spock-initialize OPTIONS ...)</procedure> Creates a compilation state using the given options and sets the value of the parameter {{current-spock-state}}. Initialization of a compilation state needs a bit of internal setup, so it is advisable to call this procedure in time-critical applications that need to generate code quickly. ===== <spock> <syntax>(<spock> FORM)</syntax> Compiles the Scheme (unquoted) expression {{FORM}} using the current compilation state and returns the generated JavaScript code as a string. {{FORM}} may contain sub-expressions of the form {{(<unscript>}} and {{<unscript-splicing>}}, respectively, which work similar to {{unquote}} and {{unquote-splicing}} in R5RS Scheme, but switch between code to be compiled and code or literal data to be computed in the host environment, e.g. (<spock> (begin (define (square x) (* x x)) (print (square '(<unscript> (read)))))) will return a {{<script>}} HTML element containing JavaScript code that defines a function and calls it with the argument read at execution of the {{<spock>}} expression. Note that the compiled form needs runtime support code to execute successfully. See {{<spock-header>}} below. ===== <spock-header> <procedure>(<spock-header> #!key minified debug path)</procedure> Emits HTML to load the runtime system. Keyword-arguments are available to specify whether a "minified" version of the runtime library should be loaded, and whether a debug version should be used. Minified means a compressed library that can be loaded faster by the client. The debug version performs additional error checks and keeps a trace of recently invoked functions. Note that the JavaScript files containing the runtime library need to be available to be transmitted to the client. In the usual case of web-server code generating script content this means, one of the files spock-runtime.js spock-runtime-min.js spock-runtime-debug.js spock-runtime-debug-min.js should be in a location that holds files to be retrieved by the client and it should match the keyword arguments given to {{<spock-header>}}. The {{path}} keyword argument can be used to override the path prefix and defaults to an empty path. The runtime library is installed in {{spock}} subdirectory of the extension repository and can be located in the path returned by entering chicken-spock -library-path ==== Special read syntax To make embedding of Scheme code fragments easier, read syntax is available that simplifies the use of the {{<spock>}}: #`EXPRESSION ---> (<spock> EXPRESSION) #^EXPRESSION ---> (<unscript> EXPRESSION) #^@EXPRESSION ---> (<unscript-splicing> EXPRESSION) In compiled code, you must explicitly load the {{spock}} extension to make the read-syntax available by passing {{-X spock}} to the compiler and the {{spock}} module must be imported. === Using the static compiler The compiler takes one or more Scheme files are translates them into a single JavaScript file, writing it by default to stdout. You can use the {{-o}} option to specify a file into which the code should be written instead. The compiler understands most of the options that can be given to {{make-spock-state}}, enter chicken-spock -help for a list of command-line switches. === Supported language ==== Deviations from R5RS ; 4.1.1 : Access to unbound variables will trigger whatever error-handling the underlying JavScript implementation provides. ; 6.1 : {{eq?}} will return {{#f}} when given standard procedures, since these are mostly implemented by using so called "identifier syntax" - in other words (eq? car car) ===> #f ; 6.2.2 : there is no concept of ''exactness'' in JavaScript - all numbers are internally represented as floating-point numbers and are thus inexact; "bignums", exact rational numbers and complex numbers are not supported. ; 6.2.5 : the following standard procedures are not implemented: {{denominator}}, {{numerator}}, {{image-part}}, {{real-part}}, {{rationalize}}, {{make-polar}} and {{make-rectangular}}. {{inexact->exact}} merely rounds its argument, {{exact->inexact}} returns its argument unchanged. ; 6.3.5 : non-integral string indices are not checked and return undefined result. ; 6.3.6 : non-integral vector indices are not checked and return undefined result. ; 6.4 : continuations captured over the program toplevel can not be re-entered, so (define k (call-with-current-continuation (lambda (k) k))) (display "once\n") (k #f) will not print {{once}} a second time and will simply return at the next toplevel expression. ; 6.5 : {{eval}} is not supported. ; 6.6.4 : {{load}} can only load JavaScript code and always does so asynchronously; {{transcript-on}} and {{transcript-off}} are not supported. ==== Extensions to R5RS ; 4.1.1 : SPOCK provides a special notation to simplify access to object properties, similar to the ''dot notation'' supported by several Java- and JavaScript-based Scheme implementations: .NAME ==> (%property-ref "NAME") .NAME1.NAME2 ==> (%property-ref "NAME1.NAME2") NAME1.NAME2 ==> (%host-ref "NAME1.NAME2") NAME. ==> (%host-ref "NAME") (set! NAME1.NAME2 X) ==> (%host-set! "NAME1.NAME2" X) (set! NAME1. X) ==> (%host-set! "NAME1" X) (set! (.NAME X) Y) ==> (%property-set! "NAME" X Y) (set! (.NAME1.NAME2 X) Y) ==> (%property-set! "NAME1.NAME2" X Y) ; 6.3.5 : the second argument to {{substring}} is optional and defaults to the length of the argument string; {{string-fill!}} accepts an optional third and fourth argument specifying the start end end index of the region whould should be filled. ; 6.3.6 : {{vector-fill!}} accepts an optional third and fourth argument specifying the start end end index of the region whould should be filled. ; 6.4 : {{for-each}} and {{map}} accept a vector as their second argument, but only when called with two arguments; {{apply}} accepts a vector as last argument. ; 6.6.4 : {{load}} takes an optional second argument, which should be a procedure of one argument; this procedure will be called with the filename argument when the file could be successfully loaded; the filename is actually an URL. ==== Non-standard syntax SPOCK uses ''alexpander'', a R5RS {{syntax-rules}} implementation by Al Petrofsky. This macro package provides numerous extensions which are currently not documented here. Additionally, the following non-standard syntax is available: ===== begin1 <syntax>(begin1 X1 X2 ...)</syntax> Evaluates the forms and returns the result(s) of the first one. ===== fluid-let <syntax>(fluid-let ((ID1 X1) ...) BODY ...)</syntax> Dynamically binds the variables {{ID1 ...}} during the execution of {{BODY}}. ===== when ===== unless <syntax>(when X1 BODY ...)</syntax> <syntax>(unless X1 BODY ...)</syntax> Conditionals with the usual meaning. ===== cut <syntax>(cut ...)</syntax> [[http://srfi.schemers.org/srfi-26/srfi-26.html|Syntactic sugar for specializing parameters]]. ===== cond-expand <syntax>(cond-expand CLAUSE ...)</syntax> [[http://srfi.schemers.org/srfi-0/srfi-0.html|Feature-based conditional expansion]]. ===== define-syntax-rule <syntax>(define-syntax-rule (NAME ARG ...) BODY)</syntax> Equivalent to <enscript highlight=scheme> (define-syntax NAME (syntax-rules () ((_ ARG ...) BODY))) </enscript> ===== new <syntax>(new CLASS KEY1 VALUE1 ...)</syntax> Creates a JavaScript object that has the constructor {{CLASS}}, which must be a native JavaScript function. The arguments should be a list of alternating keys (native strings) and values. ===== define-native <syntax>(define-native NAME ...)</syntax> Declares {{NAME}} to be a native JavaScript function. ===== define-native-method <syntax>(define-native-method NAME ...)</syntax> Declares {{NAME}} to be a native JavaScript method, which takes an additional initial argument (the "this" object). ===== define-entry-point <syntax>(define-entry-point NAME EXP)</syntax> <syntax>(define-entry-point (NAME . LLIST) BODY ...)</syntax> Declares {{NAME}} to be a global JavaScript variable which will execute {{BODY}} when called from native code. ==== Non-standard library procedures ===== % <procedure>(% STRING1 VALUE1 ...)</procedure> Creates an anonymous JavaScript object from the keys and values given by {{STRING1 VALUES1 ...}}. ===== bind-method <procedure>(bind-method JSFUNC OBJECT)</procedure> Returns a procedure that will invoke the native JavaScript function {{JSFUNC}} with {{OBJECT}} as the implicit "this" parameter. ===== callback <procedure>(callback PROC)</procedure> Returns a native JavaScript function that, when invoked, will call the Scheme procedure {{PROC}}. ===== callback-method <procedure>(callback-method PROC)</procedure> Returns a native JavaScript function that, when invoked as a method, will pass the implicit "this" parameter as an additional first argument to the Scheme procedure {{PROC}}. ===== compl <procedure>(compl PROC)</procedure> Equivalent to {{(lambda (x) (not (PROC x)))}}. ===== const <procedure>(const X)</procedure> Equivalent to {{(lambda _ (X))}}. ===== current-error-port <procedure>(current-error-port)</procedure> Returns the port that will receive error output. The exact behaviour depends on the host environment. ===== exit <procedure>(exit [CODE])</procedure> Exits the JavaScript interpreter (not functional inside the browser). ===== file-exists? <procedure>(file-exists? STRING)</procedure> Returns {{#t}} if a file with the given name exists (not functional inside the browser). ===== id <procedure>(id X)</procedure> Returns {{X}}. ===== jstring <procedure>(jstring X)</procedure> If {{X}} is a mutable string, returns a native JavaScript string. Any other argument is returned unchanged. ===== milliseconds <procedure>(milliseconds [THUNK])</procedure> Returns the current time in milliseconds. ===== native <procedure>(native JSFUNC)</procedure> Returns a procedure that, when called, will invoke the native JavaScript function {{JSFUNC}}. ===== native-method <procedure>(native-method JSFUNC)</procedure> Returns a procedure that, when called, will pass the first argument as the implicit "this" parameter to {{JSFUNC}}. ===== o <procedure>(o PROC ...)</procedure> Function-composition. ===== print <procedure>(print X ...)</procedure> Prints its argument to the current output port. Depends on the host environment. ===== void <procedure>(void ...)</procedure> Ignores its arguments and returns the undefined value. ===== void? <procedure>(void? X)</procedure> Returns {{#t}} if {{X}} is the undefined value. ===== with-input-from-port ===== with-output-to-port <procedure>(with-input-from-port PORT THUNK)</procedure> <procedure>(with-output-to-port PORT THUNK)</procedure> Invoke the zero-argument procedure {{THUNK}} with the current input or output port changed to {{PORT}}. ==== Internal special forms ===== %code <syntax>(%code STRING ...)</syntax> Embeds JavaScript code directly. ===== %host-ref ===== %host-set! <syntax>(%host-ref NAME ...)</syntax> <syntax>(%host-set! NAME X)</syntax> Retrieves a JavaScript variable or assigns a new value to it. Note that no automatic value conversion takes place, in particular, strings should be converted to the native representation when assigned. ===== %inline <syntax>(%inline .NAME THIS X ...)</syntax> <syntax>(%inline NAME X ...)</syntax> Embeds code for an inline JavaScript operation. The first form invokes the method {{NAME}} on the object {{THIS}}. The second invokes a normal JavaScript function. ===== %native-lambda <syntax>(%native-lambda STRING ...)</syntax> Returns a procedure containing native JavaScript code. Use {{arguments}} to refer to the function arguments. The implicit variable {{K}} holds the continuation and should be invoked with the result value(s) on return. ===== %new <syntax>(%new CLASS X ...)</syntax> Invokes the object constructor {{CLASS}} (which should be a string or symbol) with the given arguments and returns the object. ===== %property-ref ===== %property-set! <syntax>(%property-ref NAME [X])</syntax> <syntax>(%property-set! NAME X Y)</syntax> Retrieve or set the named property {{NAME}} (a string or symbol) of object {{X}}. The second form assigns {{Y}} to the property {{NAME}} of {{X}}. No automatic argument conversions take place. {{(%property-ref NAME)}} is a shortcut for {{(lambda (x) (%property-ref NAME))}}. ==== How Scheme types map to JavaScript types <table> <tr><th>Scheme</th><th>JavaScript</th></tr> <tr><td>number</td><td>number</td></tr> <tr><td>character</td><td>[Object SPOCK.Char]</td></tr> <tr><td>eof-object</td><td>[Object SPOCK.EndOfFile] == SPOCK.EOF</td></tr> <tr><td>string</td><td>string or [Object SPOCK.String]</td></tr> <tr><td>symbol</td><td>[Object SPOCK.Symbol]</td></tr> <tr><td>port</td><td>[Object SPOCK.Port]</td></tr> <tr><td>boolean</td><td>boolean</td></tr> <tr><td>pair</td><td>[Object SPOCK.Pair]</td></tr> <tr><td>vector</td><td>Array</td></tr> <tr><td>null</td><td>null</td></tr> <tr><td>void</td><td>undefined</td></tr> </table> Scheme code can handle native JavaScript strings, which are immutable. String literals will be directly represented as native JavaScript strings. Mutable strings (as returned by {{make-string}}, for example) will be instances of {{SPOCK.String}} and must be manually converted to JavaScript strings when passed to JavaScript code. ==== Notes * Argument counts are not checked. If a procedure is called with fewer arguments, the formal variables corresponding to the omitted arguments are initialized to the ''void'' value (as returned by the {{void}} procedure); surplus arguments are ignored. === Examples ==== Using dynamic code generation <enscript highlight=scheme> (use spock) (display (<spock-header> debug: #t)) (display #`(print #^(+ 3 4))) </enscript> produces: <enscript highlight=html> <script type='text/javascript' src='spock-runtime-debug-min.js'></script> </enscript> and: <enscript highlight=html> <script type='text/javascript'> /* CODE GENERATED BY SPOCK 0 */ var t2 = function (k1) { return ___print(k1, 7); }; SPOCK.run(t2); SPOCK.flush(); /* END OF GENERATED CODE */ </script> </enscript> ==== Using the static compiler <enscript highlight=html> <!-- drag.html - drag a box around the screen --> <html> <head> <script src="spock-runtime-debug.js"></script> <script src="drag.js"></script> <style type="text/css"> body { font-family: Arial, Helvetica; font-size: x-large; } #info { position: absolute; right-margin: auto; left: 0px; top-margin; auto; bottom: 0px; } #box { width: 200px; height: 200px; background-color: red; position: absolute; left: 50%; top: 50%; } </style> </head> <body> <div id="info">xxx</div> <div id="box">Push me.</div> </body> </html> </enscript> <enscript highlight=scheme> ;;;; drag.scm (define (box) (%inline "document.getElementById" "box")) (define (info) (%inline "document.getElementById" "info")) (define (mouse-position event) (values (- (+ (.clientX event) document.body.scrollLeft) document.body.clientLeft) (- (+ (.clientY event) document.body.scrollTop) document.body.clientTop))) (define (mouse-move event) (call-with-values (cut mouse-position event) (lambda (x y) (move-element (box) x y) (show-position x y)))) (define (move-element elt x y) (set! (.style.left elt) x) (set! (.style.top elt) y)) (define (move-element-by elt x y) (call-with-values (cut element-position elt) (lambda (x1 y1) (move-element elt (+ x1 x) (+ y1 y))))) (define (element-position elt) (values (.offsetLeft elt) (.offsetTop elt))) (define (show-position x y) (set! (.innerHTML (info)) (jstring (string-append (number->string x) "/" (number->string y))))) (set! document.onmousemove (callback mouse-move)) </enscript> To compile this, enter: chicken-spock drag.scm -o drag.js Now copy {{spock-runtime.js}} from the repository into the same directory holding {{drag.js}} and {{drag.html}} and open {{drag.html}} in your browser. ==== Using continuations for cooperative multitasking <enscript highlight=scheme> ;; http://www.pixelwit.com/blog/2008/04/how-to-draw-a-spiral/ ;; centerX-- X origin of the spiral. ;; centerY-- Y origin of the spiral. ;; radius--- Distance from origin to outer arm. ;; sides---- Number of points or sides along the spiral's arm. ;; coils---- Number of coils or full rotations. (Positive numbers spin clockwise, negative numbers spin counter-clockwise) ;; rotation- Overall rotation of the spiral. ('0'=no rotation, '1'=360 degrees, '180/360'=180 degrees) (define (spiral ctx center-x center-y radius sides coils rotation) (let* ((away-step (/ radius sides)) (around-step (/ coils sides)) (around-radians (* around-step 2 Math.PI)) (rotation (* rotation 2 Math.PI))) (let loop ((i 0) (px center-x) (py center-y)) (yield) (cond ((<= i sides) (%inline ".beginPath" ctx) (%inline ".moveTo" ctx px py) (let* ((away (* i away-step)) (around (+ (* i around-radians) rotation)) (x (+ center-x (* (%inline "Math.cos" around) away))) (y (+ center-y (* (%inline "Math.sin" around) away)))) (%inline ".lineTo" ctx x y) (%inline ".stroke" ctx) (loop (+ i 1) x y))) (else (%inline ".fillRect" ctx (- center-x radius 10) (- center-y radius 10) (+ 20 (* radius 2)) (+ 20 (* radius 2))) (loop 0 center-x center-y)))))) (define canvas (%inline "document.getElementById" "canvas")) (define ctx (%inline ".getContext" canvas "2d")) (set! (.lineWidth ctx) 5) (set! (.lineStyle ctx) "rgb(0, 0, 255)") (set! (.fillStyle ctx) "rgb(255, 200, 255)") (%inline ".fillRect" ctx 0 0 600 600) (define halt #f) (define threads '()) (let* ((n 4) (wh (/ 600 n))) (do ((x 1 (+ x 1))) ((> x n)) (let ((cx (- (* wh x) (/ wh 2)))) (do ((y 1 (+ y 1))) ((> y n)) (let ((cy (- (* wh y) (/ wh 2)))) (set! threads (cons (lambda () ;;(%inline "console.log" cx cy) (spiral ctx cx cy (/ wh 2) 200 4 (%inline "Math.random"))) threads))))))) (define current threads) (define (yield) (call-with-current-continuation (lambda (k) (set-car! current (lambda () (k #f))) (set! current (cdr current)) (when (null? current) (set! current threads)) (%inline "setTimeout" (callback (lambda () ((car current)))) 1) (halt)))) (call-with-current-continuation (lambda (k) (set! halt (lambda () (k #f))) ((car threads)))) </enscript> <enscript highlight=html> <html> <head> <style> canvas#canvas { position: absolute; left: 100px; top: 50px; width: 600px; height: 600px; } </style> </head> <body> <canvas id="canvas" width="600" height="600"></canvas> <script src="../spock/spock-runtime-min.js"></script> <script src="threads.js"></script> </body> </html> </enscript> See it in action here (needs browser with {{<canvas>}} support): [[http://www.call-with-current-continuation.org/spock/threads.html]] === Authors [[/users/felix winkelmann|felix winkelmann]] === License Copyright (c) 2011-2012, Felix L. Winkelmann All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The pattern matching library used by SPOCK is derived from code is written by Alex Shinn and placed in the Public Domain. The pretty printer used internally is Copyright (c) 1991, Marc Feeley (feeley@iro.umontreal.ca), Distribution restrictions: none The syntax-rules expander used is ''alexpander'', Copyright 2002-2004 Al Petrofsky <alexpander@petrofsky.org> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. === Version History ; 0.097 : fix in {{SPOCK.stringify}} for non-proper lists, contributed by Hugo Arregui ; 0.096 : fixed implementation of {{cadXXr}}, thanks to Hugo Arregui ; 0.095 : fixed CPS-conversion of conditionals; use correct logging port on node.js and handle sign-character in string->number conversion (thanks to Alexander Shendi) ; 0.05 : runtime code uses "SPOCK.global" instead of "this" ; 0.04 : fixed incorrect version number in setup script (reported by Mario Domenech Goulart) ; 0.03 : renamed {{<script>}} to {{<spock>}}, fixed bug in {{spock}} driver procedure (Thanks to Mario Domenech Goulart) ; 0.02 : metafile fix reported by mario ; 0.01 : initial release
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you add 10 to 21?