nada_dsl.compiler_frontend

Compiler frontend consisting of wrapper functions for the classes and functions that constitute the Nada embedded domain-specific language (EDSL).

class ClassEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: JSONEncoder

Custom JSON encoder for classes.

default(o)[source]

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return super().default(o)
get_target_dir() str[source]

Get the target directory for compilation output.

nada_compile(outputs: List[Output]) str[source]

Compile Nada to MIR and dump it as JSON.

nada_dsl_to_nada_mir(outputs: List[Output]) Dict[str, Any][source]

Convert Nada DSL to Nada MIR.

to_party_list(parties) List[Dict][source]

Convert parties to a list in MIR format.

to_input_list(inputs) List[Dict][source]

Convert inputs to a list in MIR format.

to_literal_list(literals: Dict[str, Tuple[str, object]]) List[Dict][source]

Convert literals to a list in MIR format.

to_mir_function_list(functions: Dict[int, NadaFunctionASTOperation]) List[Dict][source]

Convert functions to a list in MIR format.

From a starting dictionary of functions, it traverses each one of them, generating the corresponding MIR representation, discovering all the operations in the function.

The algorithm might find new function calls while processing the operations in a function. These function calls might discover of new functions that are not in the original dictionary. These functions will be processed in turn.

This function is designed to be invoked after the initial operation discovery which will find the starting set of functions.

Parameters:

functions (Dict[int, NadaFunctionASTOperation]) – A dictionary containing a starting list of functions

add_input_to_map(operation: InputASTOperation)[source]

Adds an input to the global INPUTS dictionary

exception CompilerException[source]

Bases: Exception

Generic compiler exception

traverse_and_process_operations(operation_id: int, operations: Dict[int, Dict], functions: Dict[int, NadaFunctionASTOperation]) Dict[int, NadaFunctionASTOperation][source]

Traverses the AST operations finding all the operation tree rooted at the given operation. Uses an iterative DFS algorithm.

It invokes process_operation which in turn generates a MIR and optionally discover extra functions.

Parameters:
  • operation_id (int) – The identifier of the root operation where the algorithm will start traversing the operation graph

  • operations (Dict[int, Dict]) – Dictionary that will be updated with the operations found

  • functions (Dict[int, NadaFunctionASTOperation]) – Dictionary of existing functions. If a function is found that is not in this dictionary it will added to the result dictionary

Returns:

Dictionary with all the new functions being found while traversing the operation tree

Return type:

Dict[int, NadaFunctionASTOperation]

class ProcessOperationOutput(mir: Dict[str, Dict], extra_function: NadaFunctionASTOperation | None)[source]

Bases: object

Output of the process_operation function

mir: Dict[str, Dict]
extra_function: NadaFunctionASTOperation | None
__eq__(other)

Return self==value.

process_operation(operation: ASTOperation, functions: Dict[int, NadaFunctionASTOperation]) ProcessOperationOutput[source]

Process an AST operation.

For arithmetic operations it simply returns the MIR representation of the operation.

For inputs and literal types, it adds the corresponding value to the appropriate dictionaries and returns the MIR representation.

For map, reduce and function call operations, adds the nada function if it’s not in the functions dictionary, and returns the MIR representation.

Whenever it finds a nada function, it adds it if it’s not there. But it does not generate a MIR representation as functions are processed separately.

It ignores nada function arguments as they should not be present in the MIR.