Skip to content

Commit 677ca80

Browse files
authored
Merge pull request #186 from atsepkov/valq7711-patch-inbrowser
improve in-browser usage
2 parents 1565269 + 5fe1c52 commit 677ca80

File tree

3 files changed

+196
-171
lines changed

3 files changed

+196
-171
lines changed

src/parser.pyj

+171-159
Original file line numberDiff line numberDiff line change
@@ -20,172 +20,181 @@ from utils import makePredicate, defaults, ImportError, js_error, RAPYD_PREFIX,
2020
import ast
2121
import tokenizer
2222

23+
NATIVE_CLASSES = None
24+
COMMON_STATIC = None
25+
CLASS_MAP = None
26+
BASELIB = None
27+
STDLIB = None
2328

2429
def array_to_hash(a):
2530
ret = {}
2631
for i in range(len(a)):
2732
ret[a[i]] = True
2833
return ret
2934

30-
NATIVE_CLASSES = {
31-
# javascript
32-
'Image': {},
33-
'RegExp': {},
34-
'Error': {},
35-
'Object': {
36-
static: [
37-
"assign", # ES6
38-
"getOwnPropertyNames",
39-
"keys",
40-
"create",
41-
"defineProperty",
42-
"defineProperties",
43-
"getPrototypeOf", # ES6
44-
"setPrototypeOf", # ES6
45-
"getOwnPropertyDescriptor", # ES6
46-
"getOwnPropertyDescriptors", # ES6
47-
48-
# experimental
49-
"values",
50-
"entries"
51-
]
52-
},
53-
'String': {
54-
static: [ "fromCharCode" ]
55-
},
56-
'Array': {
57-
static: [ "isArray", "from", "of" ]
58-
},
59-
'Number': {
60-
static: [ "isFinite", "isNaN" ]
61-
},
62-
'Function': {},
63-
'Date': {
64-
static: [ "UTC", "now", "parse" ]
65-
},
66-
'Boolean': {},
67-
'ArrayBuffer': {
68-
static: [ "isView", "transfer" ]
69-
},
70-
'DataView': {},
71-
'Float32Array': {},
72-
'Float64Array': {},
73-
'Int16Array': {},
74-
'Int32Array': {},
75-
'Int8Array': {},
76-
'Uint16Array': {},
77-
'Uint32Array': {},
78-
'Uint8Array': {},
79-
'Uint8ClampedArray': {},
80-
'Map': {}, # ES6
81-
'WeakMap': {}, # ES6
82-
'Set': {}, # ES6
83-
'WeakSet': {}, # ES6
84-
'Promise': { # ES6
85-
static: [
86-
"all",
87-
"race",
88-
"reject",
89-
"resolve"
90-
]
91-
},
92-
93-
# baselib
94-
"AssertionError": {},
95-
"IndexError": {},
96-
"KeyError": {},
97-
"TypeError": {},
98-
"ValueError": {},
99-
}
100-
COMMON_STATIC = [ "call", "apply", "bind", "toString" ]
101-
102-
CLASS_MAP = {} # top-level classes will be populated into here
103-
104-
# detect common python stdlib methods - these will be auto-injected into the code when called
105-
BASELIB = { key: 0 for key in [
106-
"abs",
107-
"all",
108-
"any",
109-
"bin",
110-
"bind",
111-
"rebind_all",
112-
"cmp",
113-
"chr",
114-
"dir",
115-
"enumerate",
116-
"eslice",
117-
"extends",
118-
"filter",
119-
"hex",
120-
"in",
121-
"iterable",
122-
"len",
123-
"map",
124-
"max",
125-
"min",
126-
"merge",
127-
"mixin",
128-
"print",
129-
"range",
130-
"reduce",
131-
"reversed",
132-
"sorted",
133-
"sum",
134-
"type",
135-
"zip",
136-
"getattr",
137-
"setattr",
138-
"hasattr",
139-
"eq",
140-
"kwargs",
141-
"AssertionError",
142-
"IndexError",
143-
"KeyError",
144-
"TypeError",
145-
"ValueError"
146-
]}
147-
STDLIB = [
148-
"abs",
149-
"bin",
150-
"cmp",
151-
"chr",
152-
"dir",
153-
"hex",
154-
"max",
155-
"min",
156-
"merge",
157-
"mixin",
158-
"print",
159-
"range",
160-
"reduce",
161-
"getattr",
162-
"setattr",
163-
"hasattr",
164-
165-
# unique to RapydScript
166-
"eq",
167-
"bind",
168-
"rebind_all",
169-
"type",
170-
171-
# list operations
172-
"all",
173-
"any",
174-
"enumerate",
175-
"filter",
176-
"len",
177-
"map",
178-
"reversed",
179-
"sum",
180-
"zip",
181-
182-
# errors
183-
"AssertionError",
184-
"IndexError",
185-
"KeyError",
186-
"TypeError",
187-
"ValueError",
188-
]
35+
# it needs for reinitialization between in-browser compilations
36+
def init_mod():
37+
nonlocal NATIVE_CLASSES, COMMON_STATIC, CLASS_MAP, BASELIB, STDLIB
38+
39+
NATIVE_CLASSES = {
40+
# javascript
41+
'Image': {},
42+
'RegExp': {},
43+
'Error': {},
44+
'Object': {
45+
static: [
46+
"assign", # ES6
47+
"getOwnPropertyNames",
48+
"keys",
49+
"create",
50+
"defineProperty",
51+
"defineProperties",
52+
"getPrototypeOf", # ES6
53+
"setPrototypeOf", # ES6
54+
"getOwnPropertyDescriptor", # ES6
55+
"getOwnPropertyDescriptors", # ES6
56+
57+
# experimental
58+
"values",
59+
"entries"
60+
]
61+
},
62+
'String': {
63+
static: [ "fromCharCode" ]
64+
},
65+
'Array': {
66+
static: [ "isArray", "from", "of" ]
67+
},
68+
'Number': {
69+
static: [ "isFinite", "isNaN" ]
70+
},
71+
'Function': {},
72+
'Date': {
73+
static: [ "UTC", "now", "parse" ]
74+
},
75+
'Boolean': {},
76+
'ArrayBuffer': {
77+
static: [ "isView", "transfer" ]
78+
},
79+
'DataView': {},
80+
'Float32Array': {},
81+
'Float64Array': {},
82+
'Int16Array': {},
83+
'Int32Array': {},
84+
'Int8Array': {},
85+
'Uint16Array': {},
86+
'Uint32Array': {},
87+
'Uint8Array': {},
88+
'Uint8ClampedArray': {},
89+
'Map': {}, # ES6
90+
'WeakMap': {}, # ES6
91+
'Set': {}, # ES6
92+
'WeakSet': {}, # ES6
93+
'Promise': { # ES6
94+
static: [
95+
"all",
96+
"race",
97+
"reject",
98+
"resolve"
99+
]
100+
},
101+
102+
# baselib
103+
"AssertionError": {},
104+
"IndexError": {},
105+
"KeyError": {},
106+
"TypeError": {},
107+
"ValueError": {},
108+
}
109+
COMMON_STATIC = [ "call", "apply", "bind", "toString" ]
110+
111+
CLASS_MAP = {} # top-level classes will be populated into here
112+
113+
# detect common python stdlib methods - these will be auto-injected into the code when called
114+
BASELIB = { key: 0 for key in [
115+
"abs",
116+
"all",
117+
"any",
118+
"bin",
119+
"bind",
120+
"rebind_all",
121+
"cmp",
122+
"chr",
123+
"dir",
124+
"enumerate",
125+
"eslice",
126+
"extends",
127+
"filter",
128+
"hex",
129+
"in",
130+
"iterable",
131+
"len",
132+
"map",
133+
"max",
134+
"min",
135+
"merge",
136+
"mixin",
137+
"print",
138+
"range",
139+
"reduce",
140+
"reversed",
141+
"sorted",
142+
"sum",
143+
"type",
144+
"zip",
145+
"getattr",
146+
"setattr",
147+
"hasattr",
148+
"eq",
149+
"kwargs",
150+
"AssertionError",
151+
"IndexError",
152+
"KeyError",
153+
"TypeError",
154+
"ValueError"
155+
]}
156+
STDLIB = [
157+
"abs",
158+
"bin",
159+
"cmp",
160+
"chr",
161+
"dir",
162+
"hex",
163+
"max",
164+
"min",
165+
"merge",
166+
"mixin",
167+
"print",
168+
"range",
169+
"reduce",
170+
"getattr",
171+
"setattr",
172+
"hasattr",
173+
174+
# unique to RapydScript
175+
"eq",
176+
"bind",
177+
"rebind_all",
178+
"type",
179+
180+
# list operations
181+
"all",
182+
"any",
183+
"enumerate",
184+
"filter",
185+
"len",
186+
"map",
187+
"reversed",
188+
"sum",
189+
"zip",
190+
191+
# errors
192+
"AssertionError",
193+
"IndexError",
194+
"KeyError",
195+
"TypeError",
196+
"ValueError",
197+
]
189198

190199

191200
def has_simple_decorator(decorators, name):
@@ -226,6 +235,9 @@ ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]
226235

227236
# -----[ Parser ]-----
228237
def parse($TEXT, options):
238+
if not STDLIB:
239+
init_mod()
240+
229241
options = defaults(options, {
230242
strict: False, # whether to use strict JavaScript mode
231243
filename: None, # name of the file being parsed

src/rapydscript.pyj

+10-11
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,10 @@ def splatBaselib(key, value):
4040
})
4141
})
4242

43-
browser_env = False
44-
if not exports:
43+
browser_env = not exports
44+
if browser_env:
4545
# browser environment
46-
rapydscript = exports = {}
47-
browser_env = True
46+
rapydscript = exports = {}
4847

4948
exports.parse_baselib = exports.parseBaselib = def(srcPath, beautify):
5049
try:
@@ -91,6 +90,12 @@ exports.get_import_dirs = def(paths_string, ignore_env):
9190
# options are shared between input and output and irrelevant options are ignored
9291
exports.compile = compile = def(code, options):
9392
# parse
93+
94+
# because of the use of the same Rapydscript instance,
95+
# we should re-initialize all static objects between compilations
96+
if browser_env:
97+
parser.init_mod()
98+
9499
toplevel = parser.parse(code, utils.defaults(options, {
95100
toplevel: toplevel,
96101
output: {}
@@ -174,10 +179,4 @@ exports.ALL_KEYWORDS = tokenizer.ALL_KEYWORDS
174179
exports.IDENTIFIER_PAT = tokenizer.IDENTIFIER_PAT
175180
exports.colored = utils.colored
176181

177-
# browser environment logic
178-
if browser_env:
179-
if JS('typeof define == "function"') and define.amd:
180-
define([], def(): return exports;)
181-
else:
182-
window.rapydscript = exports
183-
182+
# browser environment logic - moved into self.pyj

0 commit comments

Comments
 (0)