Skip to content

main

Classes:

Functions:

ArxMain dataclass

ArxMain(
    input_files: list[str] = list(),
    output_file: str = "",
    is_lib: bool = False,
    link_mode: Literal["auto", "pie", "no-pie"] = "auto",
)

Methods:

compile

compile(show_llvm_ir: bool = False) -> bool
Source code in src/arx/main.py
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
def compile(self, show_llvm_ir: bool = False) -> bool:
    """
    title: Compile the given input file.
    parameters:
      show_llvm_ir:
        type: bool
    returns:
      type: bool
    """
    _ = show_llvm_ir
    tree_ast = self._get_codegen_astx()
    ir = ArxBuilder()
    self.output_file = self._resolve_output_file()
    emits_executable = not self.is_lib and self._has_main_entry(tree_ast)

    if isinstance(tree_ast, astx.Module) and self._module_has_imports(
        tree_ast
    ):
        root, resolver = self._build_multimodule_context(tree_ast)
        ir.build_modules(
            root,
            resolver,
            output_file=self.output_file,
            link=emits_executable,
            link_mode=self.link_mode,
        )
        return emits_executable

    ir.build(
        tree_ast,
        output_file=self.output_file,
        link=emits_executable,
        link_mode=self.link_mode,
    )
    return emits_executable

run

run(**kwargs: Any) -> None
Source code in src/arx/main.py
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
def run(self, **kwargs: Any) -> None:
    """
    title: Compile the given source code.
    parameters:
      kwargs:
        type: Any
        variadic: keyword
    """
    self.input_files = kwargs.get("input_files", [])
    output_file = kwargs.get("output_file")
    self.output_file = output_file.strip() if output_file else ""
    self.is_lib = kwargs.get("is_lib", False)
    link_mode = str(kwargs.get("link_mode", "auto")).strip().lower()
    if link_mode not in {"auto", "pie", "no-pie"}:
        raise ValueError(
            "Invalid link mode. Expected one of: auto, pie, no-pie."
        )
    self.link_mode = cast(
        Literal["auto", "pie", "no-pie"],
        link_mode,
    )

    if kwargs.get("show_ast"):
        return self.show_ast()

    if kwargs.get("show_tokens"):
        return self.show_tokens()

    if kwargs.get("show_llvm_ir"):
        return self.show_llvm_ir()

    if kwargs.get("shell"):
        return self.run_shell()

    emits_executable = self.compile()
    if kwargs.get("run"):
        if emits_executable is False:
            raise ValueError(
                "`--run` requires `fn main` (or disable `--lib`)."
            )
        self.run_binary()

run_binary

run_binary() -> None
Source code in src/arx/main.py
752
753
754
755
756
757
758
759
760
761
def run_binary(self) -> None:
    """
    title: Run the generated binary.
    """
    binary_path = Path(self.output_file)
    if not binary_path.is_absolute():
        binary_path = Path.cwd() / binary_path
    result = subprocess.run([str(binary_path)], check=False)
    if result.returncode != 0:
        raise SystemExit(result.returncode)

run_shell

run_shell() -> None
Source code in src/arx/main.py
746
747
748
749
750
def run_shell(self) -> None:
    """
    title: Open arx in shell mode.
    """
    raise Exception("Arx Shell is not implemented yet.")

run_tests

run_tests(**kwargs: Any) -> int
Source code in src/arx/main.py
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
def run_tests(self, **kwargs: Any) -> int:
    """
    title: Collect and execute compiled tests from configured paths.
    parameters:
      kwargs:
        type: Any
        variadic: keyword
    returns:
      type: int
    """
    name_filter = str(kwargs.get("name_filter", "")).strip()
    fail_fast = bool(kwargs.get("fail_fast", False))
    keep_artifacts = bool(kwargs.get("keep_artifacts", False))
    list_only = bool(kwargs.get("list_only", False))

    link_mode = str(kwargs.get("link_mode", "auto")).strip().lower()
    if link_mode not in {"auto", "pie", "no-pie"}:
        raise ValueError(
            "Invalid link mode. Expected one of: auto, pie, no-pie."
        )
    self.link_mode = cast(
        Literal["auto", "pie", "no-pie"],
        link_mode,
    )

    testing_module = importlib.import_module("arx.testing")
    runner_cls = testing_module.ArxTestRunner
    settings_module = importlib.import_module("arx.settings")
    try:
        runner_kwargs = self._build_test_runner_kwargs(kwargs)
    except settings_module.ArxProjectError as err:
        print(
            f"ERROR: invalid [tests] configuration: {err}",
            file=sys.stderr,
        )
        return 2

    runner = runner_cls(
        **runner_kwargs,
        name_filter=name_filter,
        fail_fast=fail_fast,
        keep_artifacts=keep_artifacts,
        list_only=list_only,
        link_mode=self.link_mode,
    )
    summary = runner.run()
    return int(summary.exit_code)

show_ast

show_ast() -> None
Source code in src/arx/main.py
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
def show_ast(self) -> None:
    """
    title: Print the AST for the given input file.
    """
    tree_ast = self._get_astx()
    try:
        print(repr(tree_ast))
    except Exception:
        try:
            if hasattr(tree_ast, "to_json"):
                print(tree_ast.to_json())
                return
        except Exception:
            pass

        if isinstance(tree_ast, astx.AST):
            print(self._format_ast_fallback(tree_ast))
            return

        # Fallback for nodes whose repr visualizer path is not supported.
        print(str(tree_ast))

show_llvm_ir

show_llvm_ir() -> None
Source code in src/arx/main.py
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
def show_llvm_ir(self) -> None:
    """
    title: Compile into LLVM IR the given input file.
    """
    tree_ast = self._get_codegen_astx()
    ir = ArxBuilder()

    if isinstance(tree_ast, astx.Module) and self._module_has_imports(
        tree_ast
    ):
        root, resolver = self._build_multimodule_context(tree_ast)
        print(ir.translate_modules(root, resolver))
        return

    print(ir.translate(tree_ast))

show_tokens

show_tokens() -> None
Source code in src/arx/main.py
718
719
720
721
722
723
724
725
726
727
728
def show_tokens(self) -> None:
    """
    title: Print the AST for the given input file.
    """
    lexer = Lexer()

    for input_file in self.input_files:
        ArxIO.file_to_buffer(input_file)
        tokens = lexer.lex()
        for token in tokens:
            print(token)

FileImportResolver dataclass

FileImportResolver(
    input_files: tuple[str, ...],
    cache: dict[str, ParsedModule] = dict(),
    _source_root_cache: dict[Path, Path | None] = dict(),
)

get_module_name_from_file_path

get_module_name_from_file_path(filepath: str) -> str
Source code in src/arx/main.py
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
def get_module_name_from_file_path(filepath: str) -> str:
    """
    title: Return the module name from the source file name.
    parameters:
      filepath:
        type: str
    returns:
      type: str
    """
    file_path = Path(filepath)
    source_root = _find_project_source_root(file_path.parent)
    if source_root is not None:
        module_name = _module_name_from_source_root(file_path, source_root)
        if module_name is not None:
            return module_name
    return file_path.stem