vivjson.evaluator (2025-03-30)
index
https://github.com/benesult/vivjson-python/tree/main/vivjson/evaluator.py

Evaluator for VivJson
 
Evaluator: Constructor.
Evaluator#evaluate: Evaluate the given statements.
 
Refer to:
- "Crafting Interpreters"
  https://craftinginterpreters.com/
Note that this code is made from scratch. The source code
of the above WEB site is not used.
 
Environment:
- Python 3.9 or later
 
License:
Copyright 2025 benesult
 
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
    http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

 
Classes
       
builtins.object
Evaluator

 
class Evaluator(builtins.object)
    Evaluator(config=None)
 
Evaluator class
 
Evaluate statement.
 
Attributes:
    _config (Config or NoneType): Configuration
    _environment (Environment): Environment instance that is used
                                to read/write variable.
    _binary_operations (dict): Token type -> method
    _assign_operations (dict): Token type -> method
    _stack (list[dict]): Stack of evaluated statement.
                         There are two purposes.
                           - Keep limit of the recursive called
                             times.
                           - Avoid software runaway.
                         The each element is a dict that have
                         2 strings.
                           - "name": Block type or the class name
                             of evaluated statement.
                           - "detail": The detail of evaluated
                             statement.
    _max_array_size (int): Maximum array/block size
    _max_depth (int): Maximum recursive called times of evaluate
                      method
    _max_loop_times (int): Maximum loop times of "for", "while",
                           and so on.
    _REPLACED_LETTERS (dict): The escaped letter and real letter.
 
  Methods defined here:
__init__(self, config=None)
Initialize class.
 
Args:
    config (Config or NoneType): Configuration if needed.
evaluate(self, statement)
Evaluate statement.
 
This should not be called. Sub-class, such as Identifier,
should be called.
 
Args:
    statement (Statement): The evaluated statement
 
Raises:
    EvaluateError: This exception always happen when this
                   method is called.
get(self, name)
Get a variable's value.
 
Args:
    name (str): Variable name
 
Returns:
    Any: Its value
         Environment.UNDEFINED is returned if the given name's
         variable is not existed.
 
Raises:
    EvaluateError: It is happen if the given name isn't string.
rewind_after_abort(self)
Rewinds stack and environment after abort.
 
Fix as below. This is clean up for abort (exception).
When Viv.run_method is failed, instance has unnecessary
information. It may be happen unusual behavior in the next
running via its instance. So clean up is needed.
 
- Reset stack of evaluated statement "{@link #stack}".
- Rewind environment "{@link #environment}" to first hierarchy.
 
Note that it is assumed that the first call of evaluate method
is evaluate(self, block: Block).
 
For example,
 
  - The newest Environment #1  : The present position
      - enclosing = #2                |
  - Environment #2                    |
      - enclosing = #3                V
  - Environment #3             : Rewind to this position.
    (This is made by Block statement of making Instance.)
      - enclosing = #4
      - Instance's member variable is available.
      - Instance's method is available.
  - Root Environment #4
      - enclosing = null
set(self, name, value)
Set a variable.
 
Args:
    name (str): Variable name
    value (Any): Its value
 
Raises:
    EvaluateError: It is happen if the given name isn't string.

Static methods defined here:
is_truthy(value) -> bool
Evaluate as boolean.
 
Args:
    value (Any): A value that is evaluated as boolean.
 
Returns:
    bool: The evaluated result
          - None, False, 0, 0.0 --> False
          - Other --> True
            (Note that "0" is True.)
make_str(value, config=None, is_member=False, is_escape=True)
Make string from any value.
 
In this class, values are treated as Python native values.
There are the following difference between VivJson and
Python.
    - null : None
    - true : True
    - false : False
Thus, this method is used instead of str function of Python.
 
Args:
    value (Any): A value for converting to string.
                 int, float, bool, str, list, dict, None, or
                 Statement.
    config (Config or NoneType, optional): Configuration if
                                           needed.
    is_member (bool, optional): True if the above value is a
                                member of block or array,
                                False otherwise.
                                The default is False.
    is_escape (bool, optional): True if escape sequence is
                                enabled, False otherwise.
                                When this is True, control
                                character, the double
                                quotation mark, or reverse
                                solidus is modified as
                                escape sequence.
                                The default is True.
 
Returns:
    str: The given value as string
 
Raises:
    EvaluateError: It is happen if number is Infinity or NaN
                   without permission of Configuration.

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
Functions
       
isinf(x, /)
Return True if x is a positive or negative infinity, and False otherwise.
isnan(x, /)
Return True if x is a NaN (not a number), and False otherwise.

 
Data
        LITERAL = ~LITERAL

 
Author
        Fumiaki Motegi <motegi@benesult.com>