Source code for nada_dsl.compile

"""
Compilation functions.
"""

import sys
import os.path
import base64
import json
from dataclasses import dataclass
import traceback
import importlib.util
from nada_dsl.compiler_frontend import nada_compile
from nada_dsl.errors import MissingEntryPointError, MissingProgramArgumentError
from nada_dsl.timer import add_timer, timer


[docs] @dataclass class CompilerOutput: """Compiler Output""" mir: str
[docs] @add_timer(timer_name="nada_dsl.compile.compile") def compile_script(script_path: str) -> CompilerOutput: """Compiles a NADA program Args: script_path (str): The nada program path Returns: CompilerOutput: The Compiler Output """ script_dir = os.path.dirname(script_path) sys.path.insert(0, script_dir) script_name = os.path.basename(script_path) if script_name.endswith(".py"): script_name = script_name[:-3] timer.start("nada_dsl.compile.compile.__import__") script = __import__(script_name) timer.stop("nada_dsl.compile.compile.__import__") try: main = getattr(script, "nada_main") except Exception as exc: raise MissingEntryPointError( "'nada_dsl' entrypoint function is missing in program " + script_name ) from exc outputs = main() compile_output = nada_compile(outputs) return CompilerOutput(compile_output)
[docs] @add_timer(timer_name="nada_dsl.compile.compile_string") def compile_string(script: str) -> CompilerOutput: """Compiles a NADA program from a string Args: script (str): The nada program as a base64 encoded string (UTF-8) Returns: CompilerOutput: The Compiler Output """ decoded_program = base64.b64decode(script).decode("utf-8") temp_name = "temp_program" spec = importlib.util.spec_from_loader(temp_name, loader=None) module = importlib.util.module_from_spec(spec) exec(decoded_program, module.__dict__) # pylint:disable=W0122 sys.modules[temp_name] = module globals()[temp_name] = module outputs = module.nada_main() compile_output = nada_compile(outputs) return CompilerOutput(compile_output)
if __name__ == "__main__": try: if os.environ.get("NADA_TIMER"): timer.enable() args_length = len(sys.argv) if args_length < 2: raise MissingProgramArgumentError("expected program as argument") if args_length == 2: output = compile_script(sys.argv[1]) print_output(output) if args_length == 3 and sys.argv[1] == "-s": output = compile_string(sys.argv[2]) print_output(output) except Exception as ex: output = { "result": "Failure", "reason": str(ex), "traceback": str(traceback.format_exc()), } print(json.dumps(output)) finally: if timer.is_enabled(): with open("nada-timers.json", "w", encoding="utf-8") as fd: json.dump(timer.report(), fd)