summaryrefslogtreecommitdiff
path: root/addons/web/static/lib/py.js/README.rst
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/lib/py.js/README.rst
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web/static/lib/py.js/README.rst')
-rw-r--r--addons/web/static/lib/py.js/README.rst196
1 files changed, 196 insertions, 0 deletions
diff --git a/addons/web/static/lib/py.js/README.rst b/addons/web/static/lib/py.js/README.rst
new file mode 100644
index 00000000..5380f3e6
--- /dev/null
+++ b/addons/web/static/lib/py.js/README.rst
@@ -0,0 +1,196 @@
+What
+====
+
+
+
+Syntax
+------
+
+* Lambdas and ternaries should be parsed but are not implemented (in
+ the evaluator)
+* Only floats are implemented, ``int`` literals are parsed as floats.
+* Octal and hexadecimal literals are not implemented
+* Srings are backed by JavaScript strings and probably behave like
+ ``unicode`` more than like ``str``
+* Slices don't work
+
+Builtins
+--------
+
+``py.js`` currently implements the following builtins:
+
+``type``
+ Restricted to creating new types, can't be used to get an object's
+ type (yet)
+
+``None``
+
+``True``
+
+``False``
+
+``NotImplemented``
+ Returned from rich comparison methods when the comparison is not
+ implemented for this combination of operands. In ``py.js``, this
+ is also the default implementation for all rich comparison methods.
+
+``issubclass``
+
+``object``
+
+``bool``
+ Does not inherit from ``int``, since ``int`` is not currently
+ implemented.
+
+``float``
+
+``str``
+
+``tuple``
+ Constructor/coercer is not implemented, only handles literals
+
+``list``
+ Same as tuple (``list`` is currently an alias for ``tuple``)
+
+``dict``
+ Implements trivial getting, setting and len, nothing beyond that.
+
+Note that most methods are probably missing from all of these.
+
+Data model protocols
+--------------------
+
+``py.js`` currently implements the following protocols (or
+sub-protocols) of the `Python 2.7 data model
+<>`_:
+
+Rich comparisons
+ Pretty much complete (including operator fallbacks), although the
+ behavior is currently undefined if an operation does not return
+ either a ``py.bool`` or ``NotImplemented``.
+
+ ``__hash__`` is supported (and used), but it should return **a
+ javascript string**. ``py.js``'s dict build on javascript objects,
+ reimplementing numeral hashing is worthless complexity at this
+ point.
+
+Boolean conversion
+ Implementing ``__nonzero__`` should work.
+
+Customizing attribute access
+ Protocols for getting and setting attributes (including new-style
+ extension) fully implemented but for ``__delattr__`` (since
+ ``del`` is a statement)
+
+Descriptor protocol
+ As with attributes, ``__delete__`` is not implemented.
+
+Callable objects
+ Work, although the handling of arguments isn't exactly nailed
+ down. For now, callables get two (javascript) arguments ``args``
+ and ``kwargs``, holding (respectively) positional and keyword
+ arguments.
+
+ Conflicts are *not* handled at this point.
+
+Collections Abstract Base Classes
+ Container is the only implemented ABC protocol (ABCs themselves
+ are not currently implemented) (well technically Callable and
+ Hashable are kind-of implemented as well)
+
+Numeric type emulation
+ Operators are implemented (but not tested), ``abs``, ``divmod``
+ and ``pow`` builtins are not implemented yet. Neither are ``oct``
+ and ``hex`` but I'm not sure we care (I'm not sure we care about
+ ``pow`` or even ``divmod`` either, for that matter)
+
+Utilities
+---------
+
+``py.js`` also provides (and exposes) a few utilities for "userland"
+implementation:
+
+``def``
+ Wraps a native javascript function into a ``py.js`` function, so
+ that it can be called from native expressions.
+
+ Does not ensure the return types are type-compatible with
+ ``py.js`` types.
+
+ When accessing instance methods, ``py.js`` automatically wraps
+ these in a variant of ``py.def``, to behave as Python's (bound)
+ methods.
+
+Why
+===
+
+Originally, to learn about Pratt parsers (which are very, very good at
+parsing expressions with lots of infix or mixfix symbols). The
+evaluator part came because "why not" and because I work on a product
+with the "feature" of transmitting Python expressions (over the wire)
+which the client is supposed to evaluate.
+
+How
+===
+
+At this point, only three steps exist in ``py.js``: tokenizing,
+parsing and evaluation. It is possible that a compilation step be
+added later (for performance reasons).
+
+To evaluate a Python expression, the caller merely needs to call
+`py.eval`_. `py.eval`_ takes a mandatory Python
+expression to evaluate (as a string) and an optional context, for the
+substitution of the free variables in the expression::
+
+ > py.eval("type in ('a', 'b', 'c') and foo", {type: 'c', foo: true});
+ true
+
+This is great for one-shot evaluation of expressions. If the
+expression will need to be repeatedly evaluated with the same
+parameters, the various parsing and evaluation steps can be performed
+separately: `py.eval`_ is really a shortcut for sequentially calling
+`py.tokenize`_, `py.parse`_ and `py.evaluate`_.
+
+API
+===
+
+.. _py.eval:
+
+``py.eval(expr[, context])``
+ "Do everything" function, to use for one-shot evaluation of a
+ Python expression: it will internally handle the tokenizing,
+ parsing and actual evaluation of the Python expression without
+ having to perform these separately.
+
+ ``expr``
+ Python expression to evaluate
+ ``context``
+ context dictionary holding the substitutions for the free
+ variables in the expression
+
+.. _py.tokenize:
+
+``py.tokenize(expr)``
+ ``expr``
+ Python expression to tokenize
+
+.. _py.parse:
+
+``py.parse(tokens)``
+ Parses a token stream and returns an abstract syntax tree of the
+ expression (if the token stream represents a valid Python
+ expression).
+
+ A parse tree is stateless and can be memoized and used multiple
+ times in separate evaluations.
+
+ ``tokens``
+ stream of tokens returned by `py.tokenize`_
+
+.. _py.evaluate:
+
+``py.evaluate(ast[, context])``
+ ``ast``
+ The output of `py.parse`_
+ ``context``
+ The evaluation context for the Python expression.