-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathfunctions.js
More file actions
137 lines (111 loc) · 2.89 KB
/
functions.js
File metadata and controls
137 lines (111 loc) · 2.89 KB
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
import Protocol from './protocol';
import Core from '../core';
function iterator_to_reducer(iterable, acc, fun) {
const iterator = iterable[Symbol.iterator]();
let x = iterator.next();
let _acc = acc;
while (x.done === false) {
_acc = fun(x.value, _acc.get(1));
if (_acc.get(0) === Symbol.for('halt')) {
return new Core.Tuple(Symbol.for('halted'), _acc.get(1));
} else if (_acc.get(0) === Symbol.for('suspend')) {
return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => {
return iterator_to_reducer(iterator, new_acc, fun);
});
}
x = iterator.next();
}
return new Core.Tuple(Symbol.for('done'), _acc.get(1));
}
function call_property(item, property) {
if (!property) {
if (item instanceof Function || typeof item === 'function') {
return item();
}
return item;
}
if (item instanceof Map) {
let prop = null;
if (item.has(property)) {
prop = property;
} else if (item.has(Symbol.for(property))) {
prop = Symbol.for(property);
}
if (prop === null) {
throw new Error(`Property ${property} not found in ${item}`);
}
if (
item.get(prop) instanceof Function ||
typeof item.get(prop) === 'function'
) {
return item.get(prop)();
}
return item.get(prop);
}
let prop = null;
if (
typeof item === 'number' ||
typeof item === 'symbol' ||
typeof item === 'boolean' ||
typeof item === 'string'
) {
if (item[property] !== undefined) {
prop = property;
} else if (item[Symbol.for(property)] !== undefined) {
prop = Symbol.for(property);
}
} else if (property in item) {
prop = property;
} else if (Symbol.for(property) in item) {
prop = Symbol.for(property);
}
if (prop === null) {
throw new Error(`Property ${property} not found in ${item}`);
}
if (item[prop] instanceof Function || typeof item[prop] === 'function') {
return item[prop]();
}
return item[prop];
}
function defprotocol(spec) {
return new Protocol(spec);
}
function defimpl(protocol, type, impl) {
protocol.implementation(type, impl);
}
function build_namespace(ns, ns_string) {
let parts = ns_string.split('.');
const root = ns;
let parent = ns;
if (parts[0] === 'Elixir') {
parts = parts.slice(1);
}
for (const part of parts) {
if (typeof parent[part] === 'undefined') {
parent[part] = {};
}
parent = parent[part];
}
root.__table__ = ns.__table__ || {};
root.__table__[Symbol.for(ns_string)] = parent;
return parent;
}
function map_to_object(map) {
const object = {};
for (const [key, value] of map.entries()) {
if (value instanceof Map) {
object[key] = map_to_object(value);
} else {
object[key] = value;
}
}
return object;
}
export default {
call_property,
defprotocol,
defimpl,
build_namespace,
iterator_to_reducer,
map_to_object
};