Skip to content

Concrete

Interpreter dataclass

Interpreter(
    dialects: DialectGroup,
    *,
    fuel: int | None = None,
    debug: bool = False,
    max_depth: int = 128,
    max_python_recursion_depth: int = 8192
)

Bases: BaseInterpreter[Frame[Any], Any]

Concrete interpreter for the IR.

This is a concrete interpreter for the IR. It evaluates the IR by executing the statements in the IR using a simple stack-based interpreter.

keys class-attribute instance-attribute

keys = ['main']

The name of the interpreter to select from dialects by order.

void class-attribute instance-attribute

void = None

What to return when the interpreter evaluates nothing.

initialize_frame

initialize_frame(
    code: Statement, *, has_parent_access: bool = False
) -> Frame[Any]

Create a new frame for the given method.

Source code in src/kirin/interp/concrete.py
24
25
26
27
def initialize_frame(
    self, code: Statement, *, has_parent_access: bool = False
) -> Frame[Any]:
    return Frame(code, has_parent_access=has_parent_access)

run_method

run_method(
    method: Method, args: tuple[Any, ...]
) -> tuple[Frame[Any], Any]

How to run a method.

This is defined by subclasses to describe what's the corresponding value of a method during the interpretation. Usually, this method just calls run_callable.

Parameters:

Name Type Description Default
method Method

the method to run.

required
args tuple[ValueType, ...]

the arguments to the method, does not include self.

required

Returns:

Name Type Description
ValueType tuple[FrameType, ValueType]

the result of the method.

Source code in src/kirin/interp/concrete.py
29
30
31
32
def run_method(
    self, method: Method, args: tuple[Any, ...]
) -> tuple[Frame[Any], Any]:
    return self.run_callable(method.code, (method,) + args)

run_ssacfg_region

run_ssacfg_region(
    frame: Frame[Any], region: Region, args: tuple[Any, ...]
) -> tuple[Any, ...] | None | ReturnValue[Any]

This implements how to run a region with MLIR SSA CFG convention.

Parameters:

Name Type Description Default
frame FrameType

the current frame.

required
region Region

the region to run.

required
args tuple[ValueType, ...]

the arguments to the region.

required

Returns:

Type Description
tuple[ValueType, ...] | None | ReturnValue[ValueType]

tuple[ValueType, ...] | SpecialValue[ValueType]: the result of running the region.

when region returns tuple[ValueType, ...], it means the region terminates normally with YieldValue. When region returns ReturnValue, it means the region terminates and needs to pop the frame. Region cannot return Successor because reference to external region is not allowed.

Source code in src/kirin/interp/concrete.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def run_ssacfg_region(
    self, frame: Frame[Any], region: Region, args: tuple[Any, ...]
) -> tuple[Any, ...] | None | ReturnValue[Any]:
    block = region.blocks[0]
    succ = Successor(block, *args)
    while succ is not None:
        results = self.run_succ(frame, succ)
        if isinstance(results, Successor):
            succ = results
        elif isinstance(results, ReturnValue):
            return results
        elif isinstance(results, YieldValue):
            return results.values
        else:
            return results
    return None  # region without terminator returns empty tuple

run_succ

run_succ(
    frame: Frame[Any], succ: Successor
) -> SpecialValue[Any]

Run a successor within the current frame. Args: frame: the current frame. succ: the successor to run.

Returns:

Name Type Description
SpecialValue SpecialValue[ValueType]

the result of running the successor.

Source code in src/kirin/interp/concrete.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def run_succ(self, frame: Frame[Any], succ: Successor) -> SpecialValue[Any]:
    frame.current_block = succ.block
    frame.set_values(succ.block.args, succ.block_args)
    for stmt in succ.block.stmts:
        if self.consume_fuel() == self.FuelResult.Stop:
            raise FuelExhaustedError("fuel exhausted")
        frame.current_stmt = stmt
        stmt_results = self.eval_stmt(frame, stmt)
        if isinstance(stmt_results, tuple):
            frame.set_values(stmt._results, stmt_results)
        elif stmt_results is None:
            continue  # empty result
        else:  # terminator
            return stmt_results
    return None