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.

new_frame

new_frame(code: Statement) -> Frame[Any]

Create a new frame for the given method.

Source code in src/kirin/interp/concrete.py
24
25
def new_frame(self, code: Statement) -> Frame[Any]:
    return Frame.from_func_like(code)

run_block

run_block(
    frame: Frame[Any], block: Block
) -> SpecialValue[Any]

Run a block within the current frame.

Parameters:

Name Type Description Default
frame FrameType

the current frame.

required
block Block

the block to run.

required

Returns:

Name Type Description
SpecialValue SpecialValue[ValueType]

the result of running the block terminator.

Source code in src/kirin/interp/concrete.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def run_block(self, frame: Frame[Any], block: Block) -> SpecialValue[Any]:
    for stmt in block.stmts:
        if self.consume_fuel() == self.FuelResult.Stop:
            raise FuelExhaustedError("fuel exhausted")
        frame.stmt = stmt
        frame.lino = stmt.source.lineno if stmt.source else 0
        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

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
27
28
29
30
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
) -> 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

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def run_ssacfg_region(
    self, frame: Frame[Any], region: Region
) -> tuple[Any, ...] | None | ReturnValue[Any]:
    block = region.blocks[0]
    while block is not None:
        results = self.run_block(frame, block)
        if isinstance(results, Successor):
            block = results.block
            frame.set_values(block.args, results.block_args)
        elif isinstance(results, ReturnValue):
            return results
        elif isinstance(results, YieldValue):
            return results.values
        else:
            return results
    return None  # region without terminator returns empty tuple