From 6b86c2569d3911531d475ee200b730a1b96b57dd Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Sun, 30 May 2021 12:31:05 +0800 Subject: [PATCH 1/3] Add JS Set --- pscript/__init__.py | 1 - pscript/parser1.py | 51 ++++++++++++++++++++++++--- pscript/stdlib.py | 66 +++++++++++++++++++++++++++++++++++ pscript/tests/test_parser1.py | 55 ++++++++++++++++++++++++++--- 4 files changed, 163 insertions(+), 10 deletions(-) diff --git a/pscript/__init__.py b/pscript/__init__.py index 79873a26..bfc239fa 100644 --- a/pscript/__init__.py +++ b/pscript/__init__.py @@ -176,7 +176,6 @@ Not currently supported: * import (maybe we should translate an import to ``require()``?) -* the ``set`` class (JS has no set, but we could create one?) * slicing with steps (JS does not support this) * Generators, i.e. ``yield`` (not widely supported in JS) diff --git a/pscript/parser1.py b/pscript/parser1.py index 74e63426..582437ee 100644 --- a/pscript/parser1.py +++ b/pscript/parser1.py @@ -291,6 +291,40 @@ def parse_List(self, node): def parse_Tuple(self, node): return self.parse_List(node) # tuple = ~ list in JS + def parse_Set(self, node): + use_make_set_func = False + code = ['new Set(['] + for child in node.element_nodes: + if isinstance(child, (ast.Num, ast.NameConstant)): + result = self.parse(child) + assert len(result) == 1 + if result[0] in code: + use_make_set_func = True + break + code += result + elif (isinstance(child, ast.Str) and isidentifier1.match(child.value) and + child.value[0] not in '0123456789'): + if child.value in code: + use_make_set_func = True + break + code += child.value + else: + use_make_set_func = True + break + code.append(', ') + + if use_make_set_func: + func_args = [] + for child in node.element_nodes: + func_args += [unify(self.parse(child))] + self.use_std_function('create_set', []) + return stdlib.FUNCTION_PREFIX + 'create_set(' + ', '.join(func_args) + ')' + + if node.element_nodes: + code.pop(-1) # skip last comma + code.append('])') + return code + def parse_Dict(self, node): # Oh JS; without the outer braces, it would only be an Object if used # in an assignment ... @@ -321,9 +355,6 @@ def parse_Dict(self, node): return stdlib.FUNCTION_PREFIX + 'create_dict(' + ', '.join(func_args) + ')' return code - def parse_Set(self, node): - raise JSError('No Set in JS') - ## Variables def push_scope_prefix(self, prefix): @@ -408,7 +439,19 @@ def parse_BinOp(self, node): return ["Math.pow(", left, ", ", right, ")"] elif node.op == node.OPS.FloorDiv: return ["Math.floor(", left, "/", right, ")"] - + + C = ast.Set + if (isinstance(node.left_node, C) and + isinstance(node.right_node, C)): + if node.op == node.OPS.BitOr: + return self.use_std_function('op_set_union', [left, right]) + if node.op == node.OPS.BitAnd: + return self.use_std_function('op_set_intersection', [left, right]) + if node.op == node.OPS.BitXor: + return self.use_std_function('op_set_sym_difference', [left, right]) + if node.op == node.OPS.Sub: + return self.use_std_function('op_set_difference', [left, right]) + op = ' %s ' % self.BINARY_OP[node.op] return [left, op, right] diff --git a/pscript/stdlib.py b/pscript/stdlib.py index 8f3bc627..d414a9d8 100644 --- a/pscript/stdlib.py +++ b/pscript/stdlib.py @@ -141,6 +141,14 @@ def get_all_std_names(): } }""" +FUNCTIONS['create_set'] = """function () { + var s = new Set(); + for (var i=0; i=' + setC) == 'true' + def test_indexing_and_slicing(self): c = 'a = [1, 2, 3, 4, 5]\n' From 8164c34a5289c83d8895ecc8d5e63a362466e61f Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 7 Jun 2021 11:02:45 +0200 Subject: [PATCH 2/3] Update pscript/stdlib.py --- pscript/stdlib.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pscript/stdlib.py b/pscript/stdlib.py index d414a9d8..4e0c9d0c 100644 --- a/pscript/stdlib.py +++ b/pscript/stdlib.py @@ -144,7 +144,10 @@ def get_all_std_names(): FUNCTIONS['create_set'] = """function () { var s = new Set(); for (var i=0; i Date: Mon, 7 Jun 2021 11:02:53 +0200 Subject: [PATCH 3/3] Update pscript/stdlib.py --- pscript/stdlib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pscript/stdlib.py b/pscript/stdlib.py index 4e0c9d0c..d896723e 100644 --- a/pscript/stdlib.py +++ b/pscript/stdlib.py @@ -491,7 +491,9 @@ def get_all_std_names(): FUNCTIONS['op_set_union'] = """function (a, b) { // nargs: 2 let _union = new Set(a) for (let elem of b) { - if (!_union.has(elem) && !FUNCTION_PREFIXop_contains(elem, _union)) { _union.add(elem) }; + if (!_union.has(elem) && !FUNCTION_PREFIXop_contains(elem, _union)) { + _union.add(elem) + }; } return _union; }"""