mix-language 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/mix-compile +26 -0
- data/lib/javascript/base/array.js +496 -0
- data/lib/javascript/base/env.js +83 -0
- data/lib/javascript/base/eval.js +419 -0
- data/lib/javascript/base/false.js +23 -0
- data/lib/javascript/base/function.js +95 -0
- data/lib/javascript/base/null.js +23 -0
- data/lib/javascript/base/number.js +251 -0
- data/lib/javascript/base/object.js +299 -0
- data/lib/javascript/base/string.js +75 -0
- data/lib/javascript/base/true.js +23 -0
- data/lib/javascript/dom/div.js +11 -0
- data/lib/javascript/dom/drag.js +211 -0
- data/lib/javascript/dom/element.js +307 -0
- data/lib/javascript/dom/event.js +113 -0
- data/lib/javascript/dom/mouse.js +16 -0
- data/lib/javascript/dom/table.js +11 -0
- data/lib/javascript/dom/td.js +18 -0
- data/lib/javascript/dom/text.js +73 -0
- data/lib/javascript/dom/tr.js +11 -0
- data/lib/ruby/compiler.rb +528 -0
- data/lib/ruby/mix.grammar +238 -0
- data/lib/ruby/mix.tab.rb +1396 -0
- metadata +78 -0
data/bin/mix-compile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# Copyright © 2011 Jesse Sielaff
|
5
|
+
#
|
6
|
+
require_relative '../lib/ruby/compiler.rb'
|
7
|
+
|
8
|
+
Encoding.default_external = "UTF-8"
|
9
|
+
|
10
|
+
unless name = ARGV[0]
|
11
|
+
puts "usage: mix-compile [filename]"
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
|
15
|
+
basename = name.match(/(.*?)(\.mix$|$)/)[1]
|
16
|
+
filename = basename + '.mix'
|
17
|
+
|
18
|
+
unless File.exists?(filename)
|
19
|
+
puts "no such file #{filename}"
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
compiler = MixCompiler.new(filename)
|
24
|
+
js_string = compiler.compile
|
25
|
+
|
26
|
+
File.open(basename + '.js','w') {|f| f.write(js_string) }
|
@@ -0,0 +1,496 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright © 2011 Jesse Sielaff
|
3
|
+
*/
|
4
|
+
|
5
|
+
var ARRAY =
|
6
|
+
{
|
7
|
+
functions: {}
|
8
|
+
};
|
9
|
+
|
10
|
+
copy_functions(ARRAY, OBJECT);
|
11
|
+
|
12
|
+
function new_array (value)
|
13
|
+
{
|
14
|
+
var ary =
|
15
|
+
{
|
16
|
+
object_type: ARRAY_TYPE,
|
17
|
+
functions: {},
|
18
|
+
data: {},
|
19
|
+
keys: [],
|
20
|
+
unknown: Object_bad_key,
|
21
|
+
value: value
|
22
|
+
};
|
23
|
+
|
24
|
+
copy_functions(ary, ARRAY);
|
25
|
+
|
26
|
+
return ary;
|
27
|
+
}
|
28
|
+
|
29
|
+
function Array_all_q (self, args)
|
30
|
+
{
|
31
|
+
var func = args[0];
|
32
|
+
|
33
|
+
if (xself(self, ARRAY_TYPE, "#all?") || xarg(func, FUNCTION_TYPE, "Array#all?", "function"))
|
34
|
+
{
|
35
|
+
return self;
|
36
|
+
}
|
37
|
+
|
38
|
+
var body = func.value;
|
39
|
+
var bound = func.bound;
|
40
|
+
var items = self.value;
|
41
|
+
|
42
|
+
for (var i = 0, l = items.length; i < l; ++i)
|
43
|
+
{
|
44
|
+
ITERATING += 1;
|
45
|
+
var item_result = body(bound, [items[i]]);
|
46
|
+
ITERATING -= 1;
|
47
|
+
|
48
|
+
if (BREAK_VALUE)
|
49
|
+
{
|
50
|
+
var result = BREAK_VALUE;
|
51
|
+
|
52
|
+
BREAK_VALUE = null;
|
53
|
+
return result;
|
54
|
+
}
|
55
|
+
else if (RETURN_VALUE)
|
56
|
+
{
|
57
|
+
RETURN_VALUE = null;
|
58
|
+
}
|
59
|
+
|
60
|
+
if (item_result === NULL || item_result === FALSE)
|
61
|
+
{
|
62
|
+
return FALSE;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
return TRUE;
|
67
|
+
}
|
68
|
+
|
69
|
+
function Array_any_q (self, args)
|
70
|
+
{
|
71
|
+
var func = args[0];
|
72
|
+
|
73
|
+
if (xself(self, ARRAY_TYPE, "#any?") || xarg(func, FUNCTION_TYPE, "Array#any?", "function"))
|
74
|
+
{
|
75
|
+
return self;
|
76
|
+
}
|
77
|
+
|
78
|
+
var body = func.value;
|
79
|
+
var bound = func.bound;
|
80
|
+
var items = self.value;
|
81
|
+
|
82
|
+
for (var i = 0, l = items.length; i < l; ++i)
|
83
|
+
{
|
84
|
+
ITERATING += 1;
|
85
|
+
var item_result = body(bound, [items[i]]);
|
86
|
+
ITERATING -= 1;
|
87
|
+
|
88
|
+
if (BREAK_VALUE)
|
89
|
+
{
|
90
|
+
var result = BREAK_VALUE;
|
91
|
+
|
92
|
+
BREAK_VALUE = null;
|
93
|
+
return result;
|
94
|
+
}
|
95
|
+
else if (RETURN_VALUE)
|
96
|
+
{
|
97
|
+
RETURN_VALUE = null;
|
98
|
+
}
|
99
|
+
|
100
|
+
if (item_result !== NULL && item_result !== FALSE)
|
101
|
+
{
|
102
|
+
return TRUE;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
return FALSE;
|
107
|
+
}
|
108
|
+
|
109
|
+
function Array_each (self, args)
|
110
|
+
{
|
111
|
+
var func = args[0];
|
112
|
+
|
113
|
+
if (xself(self, ARRAY_TYPE, "#each") || xarg(func, FUNCTION_TYPE, "Array#each", "function"))
|
114
|
+
{
|
115
|
+
return self;
|
116
|
+
}
|
117
|
+
|
118
|
+
var body = func.value;
|
119
|
+
var bound = func.bound;
|
120
|
+
var items = self.value;
|
121
|
+
|
122
|
+
for (var i = 0, l = items.length; i < l; ++i)
|
123
|
+
{
|
124
|
+
ITERATING += 1;
|
125
|
+
body(bound, [items[i]]);
|
126
|
+
ITERATING -= 1;
|
127
|
+
|
128
|
+
if (BREAK_VALUE)
|
129
|
+
{
|
130
|
+
var result = BREAK_VALUE;
|
131
|
+
|
132
|
+
BREAK_VALUE = null;
|
133
|
+
return result;
|
134
|
+
}
|
135
|
+
else if (RETURN_VALUE)
|
136
|
+
{
|
137
|
+
RETURN_VALUE = null;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
return self;
|
142
|
+
}
|
143
|
+
|
144
|
+
function Array_empty_q (self, args)
|
145
|
+
{
|
146
|
+
if (xself(self, ARRAY_TYPE, "#empty?"))
|
147
|
+
{
|
148
|
+
return NULL;
|
149
|
+
}
|
150
|
+
|
151
|
+
return (self.value.length == 0) ? TRUE : FALSE;
|
152
|
+
}
|
153
|
+
|
154
|
+
function Array_first (self, args)
|
155
|
+
{
|
156
|
+
var num = args[0];
|
157
|
+
var items = self.value;
|
158
|
+
|
159
|
+
if (xself(self, ARRAY_TYPE, "#first"))
|
160
|
+
{
|
161
|
+
return NULL;
|
162
|
+
}
|
163
|
+
|
164
|
+
if (!num)
|
165
|
+
{
|
166
|
+
return items[0] || NULL;
|
167
|
+
}
|
168
|
+
|
169
|
+
if (xarg(num, NUMBER_TYPE, "Array#first", "number or no"))
|
170
|
+
{
|
171
|
+
return NULL;
|
172
|
+
}
|
173
|
+
|
174
|
+
var n = num.value;
|
175
|
+
var first_n = [];
|
176
|
+
|
177
|
+
for (var i = 0; i < n; ++i)
|
178
|
+
{
|
179
|
+
var item = items[i];
|
180
|
+
|
181
|
+
if (!item)
|
182
|
+
{
|
183
|
+
break;
|
184
|
+
}
|
185
|
+
|
186
|
+
first_n[i] = item;
|
187
|
+
}
|
188
|
+
|
189
|
+
return new_array(first_n);
|
190
|
+
}
|
191
|
+
|
192
|
+
function Array_get (self, args)
|
193
|
+
{
|
194
|
+
var num = args[0];
|
195
|
+
|
196
|
+
if (xself(self, ARRAY_TYPE, "#get") || xarg(num, NUMBER_TYPE, "number"))
|
197
|
+
{
|
198
|
+
return NULL;
|
199
|
+
}
|
200
|
+
|
201
|
+
var items = self.value;
|
202
|
+
var i = num.value;
|
203
|
+
var l = items.length;
|
204
|
+
|
205
|
+
if (i < 0)
|
206
|
+
{
|
207
|
+
i += l;
|
208
|
+
}
|
209
|
+
|
210
|
+
return (i < l && i >= 0) ? items[i] : NULL;
|
211
|
+
}
|
212
|
+
|
213
|
+
function Array_inspect (self, args)
|
214
|
+
{
|
215
|
+
return new_string('[...]');
|
216
|
+
}
|
217
|
+
|
218
|
+
function Array_join (self, args)
|
219
|
+
{
|
220
|
+
if (xself(self, ARRAY_TYPE, "#join"))
|
221
|
+
{
|
222
|
+
return NULL;
|
223
|
+
}
|
224
|
+
|
225
|
+
var separator = args[0];
|
226
|
+
var items = self.value;
|
227
|
+
var s = (separator) ? call_function(separator, 'stringify', []).value : '';
|
228
|
+
var string = '';
|
229
|
+
|
230
|
+
for (var i = 0, l = items.length; i < l; ++i)
|
231
|
+
{
|
232
|
+
string += call_function(items[i], 'stringify', []).value;
|
233
|
+
|
234
|
+
if (i < l - 1)
|
235
|
+
{
|
236
|
+
string += separator;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
return new_string(string);
|
241
|
+
}
|
242
|
+
|
243
|
+
function Array_last (self, args)
|
244
|
+
{
|
245
|
+
if (xself(self, ARRAY_TYPE, "#last"))
|
246
|
+
{
|
247
|
+
return NULL;
|
248
|
+
}
|
249
|
+
|
250
|
+
var num = args[0];
|
251
|
+
var items = self.value;
|
252
|
+
var l = items.length;
|
253
|
+
|
254
|
+
if (!num)
|
255
|
+
{
|
256
|
+
return (l === 0) ? NULL : items[l - 1];
|
257
|
+
}
|
258
|
+
|
259
|
+
if (xarg(num, NUMBER_TYPE, "Array#last", "number or no"))
|
260
|
+
{
|
261
|
+
return NULL;
|
262
|
+
}
|
263
|
+
|
264
|
+
var n = num.value;
|
265
|
+
var last_n = [];
|
266
|
+
|
267
|
+
for (var i = 1; i <= n; ++i)
|
268
|
+
{
|
269
|
+
var item = items[l - i];
|
270
|
+
|
271
|
+
if (!item)
|
272
|
+
{
|
273
|
+
break;
|
274
|
+
}
|
275
|
+
|
276
|
+
last_n[n - i] = item;
|
277
|
+
}
|
278
|
+
|
279
|
+
return new_array(last_n);
|
280
|
+
}
|
281
|
+
|
282
|
+
function Array_length (self, args)
|
283
|
+
{
|
284
|
+
if (xself(self, ARRAY_TYPE, "#length"))
|
285
|
+
{
|
286
|
+
return NULL;
|
287
|
+
}
|
288
|
+
|
289
|
+
return new_number(self.value.length);
|
290
|
+
}
|
291
|
+
|
292
|
+
function Array_pop (self, args)
|
293
|
+
{
|
294
|
+
if (xself(self, ARRAY_TYPE, "#pop"))
|
295
|
+
{
|
296
|
+
return NULL;
|
297
|
+
}
|
298
|
+
|
299
|
+
var num = args[0];
|
300
|
+
var items = self.value;
|
301
|
+
var l = items.length;
|
302
|
+
|
303
|
+
if (!num)
|
304
|
+
{
|
305
|
+
return (l === 0) ? NULL : items.pop();
|
306
|
+
}
|
307
|
+
|
308
|
+
if (xarg(num, NUMBER_TYPE, "Array#pop", "number or no"))
|
309
|
+
{
|
310
|
+
return NULL;
|
311
|
+
}
|
312
|
+
|
313
|
+
var n = num.value;
|
314
|
+
var popped = [];
|
315
|
+
|
316
|
+
for (var i = 0; i < n; ++i)
|
317
|
+
{
|
318
|
+
var item = items.pop();
|
319
|
+
|
320
|
+
if (!item)
|
321
|
+
{
|
322
|
+
break;
|
323
|
+
}
|
324
|
+
|
325
|
+
popped[i] = item;
|
326
|
+
}
|
327
|
+
|
328
|
+
return new_array(popped);
|
329
|
+
}
|
330
|
+
|
331
|
+
function Array_push (self, args)
|
332
|
+
{
|
333
|
+
if (xself(self, ARRAY_TYPE, "#push"))
|
334
|
+
{
|
335
|
+
return NULL;
|
336
|
+
}
|
337
|
+
|
338
|
+
var obj = args[0];
|
339
|
+
|
340
|
+
if (xarg(obj, null, "Array#push", "an"))
|
341
|
+
{
|
342
|
+
return self;
|
343
|
+
}
|
344
|
+
|
345
|
+
self.value.push(obj);
|
346
|
+
|
347
|
+
return self;
|
348
|
+
}
|
349
|
+
|
350
|
+
function Array_sample (self, args)
|
351
|
+
{
|
352
|
+
if (xself(self, ARRAY_TYPE, "#sample"))
|
353
|
+
{
|
354
|
+
return NULL;
|
355
|
+
}
|
356
|
+
|
357
|
+
var items = self.value;
|
358
|
+
var l = items.length;
|
359
|
+
|
360
|
+
if (!l)
|
361
|
+
{
|
362
|
+
return NULL;
|
363
|
+
}
|
364
|
+
|
365
|
+
var i = Math.floor(Math.random() * l);
|
366
|
+
|
367
|
+
return items[i];
|
368
|
+
}
|
369
|
+
|
370
|
+
function Array_set (self, args)
|
371
|
+
{
|
372
|
+
var num = args[0];
|
373
|
+
var value = args[1]
|
374
|
+
|
375
|
+
if (xself(self, ARRAY_TYPE, "#set") || xarg(num, NUMBER_TYPE, "number") || xarg(value, null, "value"))
|
376
|
+
{
|
377
|
+
return NULL;
|
378
|
+
}
|
379
|
+
|
380
|
+
var items = self.value;
|
381
|
+
var i = num.value;
|
382
|
+
var l = items.length;
|
383
|
+
|
384
|
+
if (i < 0)
|
385
|
+
{
|
386
|
+
i += l;
|
387
|
+
}
|
388
|
+
|
389
|
+
if (i < 0)
|
390
|
+
{
|
391
|
+
warn("Ignoring out-of-range array assignment");
|
392
|
+
return value;
|
393
|
+
}
|
394
|
+
|
395
|
+
while (items.length < i)
|
396
|
+
{
|
397
|
+
items.push(NULL);
|
398
|
+
}
|
399
|
+
|
400
|
+
return items[i] = value;
|
401
|
+
}
|
402
|
+
|
403
|
+
function Array_shuffle (self, args)
|
404
|
+
{
|
405
|
+
if (xself(self, ARRAY_TYPE, "#shuffle"))
|
406
|
+
{
|
407
|
+
return NULL;
|
408
|
+
}
|
409
|
+
|
410
|
+
var items = self.value;
|
411
|
+
var l = items.length;
|
412
|
+
|
413
|
+
if (l === 0)
|
414
|
+
{
|
415
|
+
return new_array([]);
|
416
|
+
}
|
417
|
+
|
418
|
+
var shuffled = [items[0]];
|
419
|
+
|
420
|
+
for (var i = 1, j; i < l; ++i)
|
421
|
+
{
|
422
|
+
j = Math.floor(Math.random() * (i + 1));
|
423
|
+
shuffled[i] = shuffled[j];
|
424
|
+
shuffled[j] = items[i];
|
425
|
+
};
|
426
|
+
|
427
|
+
return new_array(shuffled);
|
428
|
+
}
|
429
|
+
|
430
|
+
function Array_shuffle_x (self, args)
|
431
|
+
{
|
432
|
+
if (xself(self, ARRAY_TYPE, "#shuffle!"))
|
433
|
+
{
|
434
|
+
return NULL;
|
435
|
+
}
|
436
|
+
|
437
|
+
var items = self.value;
|
438
|
+
var l = items.length;
|
439
|
+
|
440
|
+
if (l > 1)
|
441
|
+
{
|
442
|
+
for (var i = l - 1, j, x; i > 0; --i)
|
443
|
+
{
|
444
|
+
j = Math.floor(Math.random() * (i + 1));
|
445
|
+
x = items[i];
|
446
|
+
items[i] = items[j];
|
447
|
+
items[j] = x;
|
448
|
+
}
|
449
|
+
}
|
450
|
+
|
451
|
+
return self;
|
452
|
+
}
|
453
|
+
|
454
|
+
function Array_stringify (self, args)
|
455
|
+
{
|
456
|
+
if (xself(self, ARRAY_TYPE, "#stringify"))
|
457
|
+
{
|
458
|
+
return NULL;
|
459
|
+
}
|
460
|
+
|
461
|
+
var items = self.value;
|
462
|
+
var string = '';
|
463
|
+
|
464
|
+
for (var i = 0, l = items.length; i < l; ++i)
|
465
|
+
{
|
466
|
+
string += call_function(items[i], 'inspect', []).value;
|
467
|
+
|
468
|
+
if (i < l - 1)
|
469
|
+
{
|
470
|
+
string += ', ';
|
471
|
+
}
|
472
|
+
}
|
473
|
+
|
474
|
+
return new_string('[' + string + ']');
|
475
|
+
}
|
476
|
+
|
477
|
+
add_function(ARRAY, 'all?', Array_all_q, ['function']);
|
478
|
+
add_function(ARRAY, 'any?', Array_any_q, ['function']);
|
479
|
+
add_function(ARRAY, 'brackets', Array_get, ['index']);
|
480
|
+
add_function(ARRAY, 'brackets_eq', Array_set, ['index','value']);
|
481
|
+
add_function(ARRAY, 'each', Array_each, ['function']);
|
482
|
+
add_function(ARRAY, 'empty?', Array_empty_q, []);
|
483
|
+
add_function(ARRAY, 'first', Array_first, ['(n)']);
|
484
|
+
add_function(ARRAY, 'get', Array_get, ['index']);
|
485
|
+
add_function(ARRAY, 'inspect', Array_inspect, []);
|
486
|
+
add_function(ARRAY, 'join', Array_join, ['(separator)']);
|
487
|
+
add_function(ARRAY, 'last', Array_last, ['(n)']);
|
488
|
+
add_function(ARRAY, 'length', Array_length, []);
|
489
|
+
add_function(ARRAY, 'ltlt', Array_push, ['object']);
|
490
|
+
add_function(ARRAY, 'pop', Array_pop, ['(n)']);
|
491
|
+
add_function(ARRAY, 'push', Array_push, ['object']);
|
492
|
+
add_function(ARRAY, 'sample', Array_sample, []);
|
493
|
+
add_function(ARRAY, 'set', Array_set, ['index','value']);
|
494
|
+
add_function(ARRAY, 'shuffle', Array_shuffle, []);
|
495
|
+
add_function(ARRAY, 'shuffle!', Array_shuffle_x, []);
|
496
|
+
add_function(ARRAY, 'stringify', Array_stringify, []);
|
@@ -0,0 +1,83 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright © 2011 Jesse Sielaff
|
3
|
+
*/
|
4
|
+
|
5
|
+
var MIXINS = [];
|
6
|
+
var VARIABLES = {};
|
7
|
+
var LINE = 0;
|
8
|
+
var FILE = '';
|
9
|
+
var APP = null;
|
10
|
+
var SELF = null;
|
11
|
+
var ITERATING = 0;
|
12
|
+
var BREAK_VALUE = null;
|
13
|
+
var RETURN_VALUE = null;
|
14
|
+
|
15
|
+
var startup = function ()
|
16
|
+
{
|
17
|
+
SELF = APP = new_object({}, []);
|
18
|
+
};
|
19
|
+
|
20
|
+
function add_function (obj, fname, body, parameters)
|
21
|
+
{
|
22
|
+
body.parameters = parameters;
|
23
|
+
obj.functions[fname] = body;
|
24
|
+
}
|
25
|
+
|
26
|
+
function bug (message)
|
27
|
+
{
|
28
|
+
throw(message + ':\t' + FILE + ':' + LINE);
|
29
|
+
}
|
30
|
+
|
31
|
+
function call_function (obj, fname, args)
|
32
|
+
{
|
33
|
+
var body = obj.functions[fname];
|
34
|
+
|
35
|
+
if (!body)
|
36
|
+
{
|
37
|
+
var str = call_function(obj, 'inspect', []);
|
38
|
+
bug("Tried to call `" + fname + "' on " + str.value + " using call_function");
|
39
|
+
}
|
40
|
+
|
41
|
+
return body(obj, args);
|
42
|
+
}
|
43
|
+
|
44
|
+
function copy_functions (obj, source)
|
45
|
+
{
|
46
|
+
var functions = source.functions;
|
47
|
+
|
48
|
+
for (var fname in functions)
|
49
|
+
{
|
50
|
+
obj.functions[fname] = functions[fname];
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
function output (message)
|
55
|
+
{
|
56
|
+
if (console && console.log)
|
57
|
+
{
|
58
|
+
console.log(message)
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
function warn (message)
|
63
|
+
{
|
64
|
+
output(message + ":\t" + FILE + ":" + LINE);
|
65
|
+
}
|
66
|
+
|
67
|
+
function xarg (obj, type, fname, expectation)
|
68
|
+
{
|
69
|
+
if (!obj || (type && (obj.object_type !== type)))
|
70
|
+
{
|
71
|
+
warn("Ignoring " + fname + ";" + " expected " + expectation + " argument");
|
72
|
+
return true;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
function xself (obj, type, fname)
|
77
|
+
{
|
78
|
+
if (!obj || (type && (obj.object_type !== type)))
|
79
|
+
{
|
80
|
+
warn("Ignoring " + fname + ";" + " unexpected receiver");
|
81
|
+
return true;
|
82
|
+
}
|
83
|
+
}
|