1 // This file is prepended to the result of compile jscl.lisp, and
2 // contain runtime code that jscl assumes to exist.
11 globalEval = eval; // Just an indirect eval
13 function pv (x) { return x==undefined? nil: x; }
16 var r = [].slice.call(arguments);
17 r['multiple-value'] = true;
21 function forcemv (x) {
22 return typeof x == 'object' && 'multiple-value' in x? x: mv(x);
25 // NOTE: Define VALUES to be MV for toplevel forms. It is because
26 // `eval' compiles the forms and execute the Javascript code at
27 // toplevel with `js-eval', so it is necessary to return multiple
28 // values from the eval function.
31 function checkArgsAtLeast(args, n){
32 if (args < n) throw 'too few arguments';
35 function checkArgsAtMost(args, n){
36 if (args > n) throw 'too many arguments';
39 function checkArgs(args, n){
40 checkArgsAtLeast(args, n);
41 checkArgsAtMost(args, n);
44 // Improper list constructor (like LIST*)
46 if (arguments.length == 1)
49 var i = arguments.length-1;
50 var r = arguments[i--];
52 r = {car: arguments[i], cdr: r};
58 // Return a new Array of strings, each either length-1, or length-2 (a UTF-16 surrogate pair).
59 function codepoints(string) {
60 return string.split(/(?![\udc00-\udfff])/);
63 // Create and return a lisp string for the Javascript string STRING.
64 function make_lisp_string (string){
65 var array = codepoints(string);
70 function char_to_codepoint(ch) {
72 return ch.charCodeAt(0);
74 var xh = ch.charCodeAt(0) - 0xD800;
75 var xl = ch.charCodeAt(1) - 0xDC00;
76 return 0x10000 + (xh << 10) + (xl);
80 function char_from_codepoint(x) {
82 return String.fromCharCode(x);
87 return String.fromCharCode(0xD800 + xh) + String.fromCharCode(0xDC00 + xl);
91 // if a char (JS string) has the same number of codepoints after .toUpperCase(), return that, else the original.
92 function safe_char_upcase(x) {
93 var xu = x.toUpperCase();
94 if (codepoints(xu).length == 1) {
100 function safe_char_downcase(x) {
101 var xl = x.toLowerCase();
102 if (codepoints(xl).length == 1) {
109 function xstring(x){ return x.join(''); }
112 function Symbol(name, package_name){
115 this['package'] = package_name;
118 function lisp_to_js (x) {
119 if (typeof x == 'object' && 'length' in x && x.stringp == 1)
125 else if (typeof x == 'function'){
126 // Trampoline calling the Lisp function
128 var args = Array.prototype.slice.call(arguments);
130 args[i] = js_to_lisp(args[i]);
131 return lisp_to_js(x.apply(this, [pv, arguments.length].concat(args)));
137 function js_to_lisp (x) {
138 if (typeof x == 'string')
139 return make_lisp_string(x);
142 else if (x === false)
144 else if (typeof x == 'function'){
145 // Trampoline calling the JS function
146 return (function(values, nargs){
147 var args = Array.prototype.slice.call(arguments, 2);
149 args[i] = lisp_to_js(args[i]);
150 return values(js_to_lisp(x.apply(this, args)));