Beispiel #1
0
def jsify_dict(node: ast.Dict) -> List[Compilable]:
    # keys, values
    output = []
    for k, v in zip(node.keys, node.values):
        jk = jsify_node(k)
        jv = jsify_node(v)
        if len(jk) != 1:
            raise CompilationError(
                f'Dict key: Expected only one JSExpression (or Compilable) while got '
                f'{len(jk)}: {jk!r}')
        if len(jv) != 1:
            raise CompilationError(
                f'Dict value: Expected only one JSExpression (or Compilable) while got '
                f'{len(jv)}: {jv!r}')

        output.append(
            JSExpression([
                JSExpression(['[', jk[0], ']', ':']),
                jv[0],
            ]))
    return [JSExpression([
        '{',
        JSExpression(output),
        '}',
    ])]
Beispiel #2
0
def jsify_import(node: ast.Import) -> typing.List[Compilable]:
    requires = []
    names = node.names
    for alias in names:
        alias: ast.alias
        requires.append(
            JSStatement('const ', [
                JSExpression([alias.asname or alias.name]), ' = ', 'require(',
                JSExpression([f'"not_python/{alias.name}.js"']), ')'
            ]))
    return requires
Beispiel #3
0
def jsify_fstring(node: ast.JoinedStr) -> typing.List[Compilable]:
    values = []
    for i in node.values:
        if isinstance(i, ast.FormattedValue):
            values.append(JSExpression(['${', *jsify_node(i), '}']))
        else:
            if isinstance(i, ast.Constant):
                values.append(JSExpression([i.value]))
            else:
                values.extend(jsify_node(i))

    return [JSExpression(['`', *values, '`'])]
Beispiel #4
0
def _jsify_sequential_container(node, prefix, suffix) -> List[Compilable]:
    elts = []
    for i in node.elts:
        v = jsify_node(i)
        if len(v) != 1:
            raise CompilationError(
                f'Expected only one JSExpression (or Compilable) while got {len(v)}: {v!r}'
            )
        elts.append(v[0])
        elts.append(', ')

    return [JSExpression([prefix, JSExpression(elts), suffix])]
Beispiel #5
0
def jsify_formatted_value(node: ast.FormattedValue) -> typing.List[Compilable]:
    value = jsify_node(node.value)
    if node.format_spec:
        fspec = jsify_node(node.format_spec)
        return [
            JSExpression(['unholy_js.py__format(', *value, ', ', *fspec, ')'])
        ]
    else:
        return value
Beispiel #6
0
def jsify_comparison(node: ast.Compare) -> List[Compilable]:
    # left, ops, comparators,
    left_most = node.left
    values = node.comparators
    out = []
    left = left_most
    for num, val in enumerate(values):
        right = val
        oper = type(node.ops[num])

        try:
            out.append(PY_TO_JS_OPERATORS[oper](left, right))
        except KeyError as e:
            raise CompilationError(f'no known way to compile comparison operator {oper}') from e

        left = right

    new_out = []
    for i in out:
        new_out.append(JSExpression(['&&']))
        new_out.append(i)

    new_out.pop(0)  # remove leading '&&'
    return [JSExpression(new_out)]
Beispiel #7
0
import ast
from typing import List

# noinspection PyUnresolvedReferences
from typechecker import ensure_typecheck
from unholy import jsify_node
# noinspection PyUnresolvedReferences
from unholy.classes import Compilable, CompilationError, JSExpression

PY_TO_JS_OPERATORS = {
    ast.Mult: lambda l, r: JSExpression([
        *jsify_node(l),
        '*',
        *jsify_node(r),
    ]),
    ast.Div: lambda l, r: JSExpression([
        *jsify_node(l),
        '/',
        *jsify_node(r),
    ]),
    ast.Add: lambda l, r: JSExpression([
        *jsify_node(l),
        '+',
        *jsify_node(r),
    ]),
    ast.Pow: lambda l, r: JSExpression([
        *jsify_node(l),
        '**',
        *jsify_node(r),
    ]),
    ast.USub: lambda l, r: JSExpression([