File: mlvalues.js

package info (click to toggle)
obrowser 1.1%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 3,216 kB
  • ctags: 3,498
  • sloc: ml: 13,505; makefile: 343; sh: 11
file content (245 lines) | stat: -rw-r--r-- 5,484 bytes parent folder | download
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/***********************************************************************/
/*                              O'Browser                              */
/*                                                                     */
/*  Copyright 2008 Benjamin Canou. This file is distributed under the  */
/*  terms of the GNU Library General Public License described in file  */
/*  ../LICENSE.                                                        */
/*                                                                     */
/***********************************************************************/

// tags

#define NO_SCAN_TAG        251
#define FORWARD_TAG        250
#define INFIX_TAG          249
#define OBJECT_TAG         248
#define CLOSURE_TAG        247
#define LAZY_TAG           246
#define ABSTRACT_TAG       251
#define STRING_TAG         252
#define DOUBLE_TAG         253
#define DOUBLE_ARRAY_TAG   254
#define CUSTOM_TAG         255

// blocks

function Block(size, tag) {
    this.size = size;
    this.tag = tag;
    this.content = [];
    this.offset = 0;
}

METHODS(Block).get = function (i) {
    return this.content[this.offset + i];
}

METHODS(Block).set = function (i, v) {
    this.content[this.offset + i] = v;
}

/* enables the simulation of C pointer arithmetics */
METHODS(Block).shift = function (o) {
    var nsize = this.size - o >= 0 ? this.size - o : 0;
    var b = new Block (nsize, this.tag);
    b.content = this.content;
    b.offset = this.offset + o;
    return b;
}

#define is_block(b)         (b instanceof Block)
#define mk_block(size, tag) (new Block (size, tag))

var ATOM = mk_block (0, 0);

function pair (v0, v1) {
    var b = new Block (2, 0);
    b.set (0, v0);
    b.set (1, v1);
    return b;
}

function singleton (v0) {
    var b = new Block (1, 0);
    b.set (0, v0);
    return b;
}

function box_abstract (v0) {
    var b = new Block (1, ABSTRACT_TAG);
    b.set (0, v0);
    return b;
}

#define unbox_abstract(v) v.get (0)

#define unbox_code(v) (v.tag == CLOSURE_TAG ? v.get (0):v)

// immediates

#define is_long(b) (!(b instanceof Block))

#define UNIT   0

#define FALSE  0
#define TRUE   1

#define mk_bool(v) (v?TRUE:FALSE)

// lists

var nil = 0;
var cons = pair;

// floats

function float_of_int (x) {
    var b = new Block (1, DOUBLE_TAG);
    b.set (0, Number (x));
    return b;
}

function box_float (x) {
    var b = new Block (1, DOUBLE_TAG);
    b.set (0, Number (x));
    return b;
}

#define unbox_float(x) x.get (0)

#define int_of_float(x) Math.round (x.get (0))

function float_of_bytes (bytes) {
    /* sign & exponent */
    var sign = ((bytes[0] >> 7) == 1);
    var exponent = (((bytes[0] & 0x7F) << 4) | (bytes[1] >> 4 )) - 1023;
    /* mantissa in a bool array */
    var ba = [];
    for (var b = 1;b < 8;b++)
	for (var d = 0;d < 8;d++)
	    ba[(b - 1) * 8 + d - 4] = (((bytes[b] >> (7 - d)) & 1) == 1);
    /* proceed */
    var m = Number (1);
    for (var i = 0;i < 52;i++)
	if (ba[i])
	    m += Math.pow (2, -(i + 1));
    return box_float ((sign ? (-1) : 1) * m * Math.pow (2, exponent));
}

function bytes_of_float (x) {
    var x = unbox_float (x);
    var e = Math.ceil (Math.log (Math.abs (x)) / Math.log (2));
    var m = Math.abs (x * Math.pow (2, -e)) * 2 - 1;
    e += 1022;
    var bits = [];
    bits[0] = (x > 0);
    for (var i = 0;i <= 52 ; i++) {
	bits [11 + i] = (m >= 1);
	m = (m - Math.floor (m)) * 2;
    }
    for (var i = 0;i <= 10 ; i++) {
	bits [11 - i] = (((e >>> i) & 1) == 1);
    }
    var bytes = [0,0,0,0,0,0,0,0];
    for (var i = 0;i < 8 ; i++) {
	for (var j = 0;j < 8 ; j++) {
	    bytes[i] = (bytes[i] * 2) | (bits[8 * i + j] ? 1 : 0);
	}
    }
    return bytes;
}

// strings

#include <utf8.js>

var utf8_enabled = TRUE;

RT.caml_js_enable_utf8 /* : bool -> unit */ = function (v) {
    utf8_enabled = v;
    return UNIT;
}

RT.caml_js_utf8_enabled /* : unit -> bool */ = function () {
    return utf8_enabled;
}

function value_from_string (s) {
    if (utf8_enabled == FALSE) {
	var b = mk_block (s.length + 1, STRING_TAG);
	for (var i = 0;i < s.length;i++) {
	    b.set(i,s.charCodeAt (i));
	}
	b.set(i, 0);
	return b;
    } else {
	return encode_utf8 (s);
    }
}

function string_from_value (v) {
    if (utf8_enabled == FALSE) {
	var s = "";
	for (var i = 0;i < v.size - 1;i++) {
	    s += String.fromCharCode (v.get (i));
	}
	return s;
    } else {
	return decode_utf8 (v);
    }
}

function string_array (a) {
    var b = new Block (a.length);
    for (var i = 0;i < a.length;i++)
	b.set (i, value_from_string (a[i]));
    return b;
}

// utils

/* block from an array of values */
function mk_array_from_js (s) {
    var b = mk_block (s.length, 0);
    for (var i = 0;i < s.length;i++) {
	b.set(i,s[i]);
    }
    return b;
}

/* (js) string representation of a value
   (limit of blocks = limit, does not handle cycles) */

function repr (v, limit) {
    var s = "";
    function string_repr_rec (v) {
	if (is_long (v)) {
	    s += sprintf ("0x%X", v);
	} else {
	    switch (v.tag) {
	    case STRING_TAG:
		s += "\"" + string_from_value (v) + "\"";
		break;
	    case DOUBLE_TAG:
		s += v.get (0).toExponential ();
		break;
	    default: {
		s += sprintf ("[(0x%02X) ", v.tag);
		for (var i = 0;i < v.size - 1 && i < limit;i++) {
		    string_repr_rec (v.get (i));
		    s += ", ";
		}
		if (i >= limit) {
		    s += "...";
		} else {
		    string_repr_rec (v.get (i));
		}
		s += "]";
	    }
	    }
	}
    }
    string_repr_rec (v);
    return s;
}