forked from skulpt/skulpt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ffi.js
140 lines (133 loc) · 3.7 KB
/
ffi.js
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
Sk.ffi = Sk.ffi || {};
/**
* maps from Javascript Object/Array/string to Python dict/list/str.
*
* only works on basic objects that are being used as storage, doesn't handle
* functions, etc.
*/
Sk.ffi.remapToPy = function (obj) {
var k;
var kvs;
var i;
var arr;
if (Object.prototype.toString.call(obj) === "[object Array]") {
arr = [];
for (i = 0; i < obj.length; ++i) {
arr.push(Sk.ffi.remapToPy(obj[i]));
}
return new Sk.builtin.list(arr);
}
else if (typeof obj === "object") {
kvs = [];
for (k in obj) {
kvs.push(Sk.ffi.remapToPy(k));
kvs.push(Sk.ffi.remapToPy(obj[k]));
}
return new Sk.builtin.dict(kvs);
}
else if (typeof obj === "string") {
return new Sk.builtin.str(obj);
}
else if (typeof obj === "number") {
return new Sk.builtin.nmber(obj, undefined);
}
else if (typeof obj === "boolean") {
return obj;
}
goog.asserts.fail("unhandled remap type " + typeof(obj));
};
goog.exportSymbol("Sk.ffi.remapToPy", Sk.ffi.remapToPy);
/**
* maps from Python dict/list/str to Javascript Object/Array/string.
*/
Sk.ffi.remapToJs = function (obj) {
var i;
var kAsJs;
var v;
var iter, k;
var ret;
if (obj instanceof Sk.builtin.dict) {
ret = {};
for (iter = obj.tp$iter(), k = iter.tp$iternext();
k !== undefined;
k = iter.tp$iternext()) {
v = obj.mp$subscript(k);
if (v === undefined) {
v = null;
}
kAsJs = Sk.ffi.remapToJs(k);
// todo; assert that this is a reasonble lhs?
ret[kAsJs] = Sk.ffi.remapToJs(v);
}
return ret;
}
else if (obj instanceof Sk.builtin.list || obj instanceof Sk.builtin.tuple) {
ret = [];
for (i = 0; i < obj.v.length; ++i) {
ret.push(Sk.ffi.remapToJs(obj.v[i]));
}
return ret;
}
else if (obj instanceof Sk.builtin.nmber) {
return Sk.builtin.asnum$(obj);
}
else if (obj instanceof Sk.builtin.lng) {
return Sk.builtin.asnum$(obj);
}
else if (typeof obj === "number" || typeof obj === "boolean") {
return obj;
}
else {
return obj.v;
}
};
goog.exportSymbol("Sk.ffi.remapToJs", Sk.ffi.remapToJs);
Sk.ffi.callback = function (fn) {
if (fn === undefined) {
return fn;
}
return function () {
return Sk.misceval.apply(fn, undefined, undefined, undefined, Array.prototype.slice.call(arguments, 0));
};
};
goog.exportSymbol("Sk.ffi.callback", Sk.ffi.callback);
Sk.ffi.stdwrap = function (type, towrap) {
var inst = new type();
inst["v"] = towrap;
return inst;
};
goog.exportSymbol("Sk.ffi.stdwrap", Sk.ffi.stdwrap);
/**
* for when the return type might be one of a variety of basic types.
* number|string, etc.
*/
Sk.ffi.basicwrap = function (obj) {
if (obj instanceof Sk.builtin.nmber) {
return Sk.builtin.asnum$(obj);
}
if (obj instanceof Sk.builtin.lng) {
return Sk.builtin.asnum$(obj);
}
if (typeof obj === "number" || typeof obj === "boolean") {
return obj;
}
if (typeof obj === "string") {
return new Sk.builtin.str(obj);
}
goog.asserts.fail("unexpected type for basicwrap");
};
goog.exportSymbol("Sk.ffi.basicwrap", Sk.ffi.basicwrap);
Sk.ffi.unwrapo = function (obj) {
if (obj === undefined) {
return undefined;
}
return obj["v"];
};
goog.exportSymbol("Sk.ffi.unwrapo", Sk.ffi.unwrapo);
Sk.ffi.unwrapn = function (obj) {
if (obj === null) {
return null;
}
return obj["v"];
};
goog.exportSymbol("Sk.ffi.unwrapn", Sk.ffi.unwrapn);