Support constant integers in AST expressions.
Make it possible to write AST nodes: iconst.i32(imm64(0)).
This commit is contained in:
@@ -350,8 +350,8 @@ class Apply(Expr):
|
|||||||
on this instruction.
|
on this instruction.
|
||||||
|
|
||||||
Immediate operands in a source pattern can be either free variables or
|
Immediate operands in a source pattern can be either free variables or
|
||||||
constants like `Enumerator`. We don't currently support constraints on
|
constants like `ConstantInt` and `Enumerator`. We don't currently
|
||||||
free variables, but we may in the future.
|
support constraints on free variables, but we may in the future.
|
||||||
"""
|
"""
|
||||||
pred = None # type: PredNode
|
pred = None # type: PredNode
|
||||||
iform = self.inst.format
|
iform = self.inst.format
|
||||||
@@ -415,6 +415,12 @@ class Apply(Expr):
|
|||||||
else:
|
else:
|
||||||
if (s[self_a] != other_a):
|
if (s[self_a] != other_a):
|
||||||
return None
|
return None
|
||||||
|
elif isinstance(self_a, ConstantInt):
|
||||||
|
if not isinstance(other_a, ConstantInt):
|
||||||
|
return None
|
||||||
|
assert self_a.kind == other_a.kind
|
||||||
|
if (self_a.value != other_a.value):
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
assert isinstance(self_a, Enumerator)
|
assert isinstance(self_a, Enumerator)
|
||||||
|
|
||||||
@@ -430,6 +436,32 @@ class Apply(Expr):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
class ConstantInt(Expr):
|
||||||
|
"""
|
||||||
|
A value of an integer immediate operand.
|
||||||
|
|
||||||
|
Immediate operands like `imm64` or `offset32` can be specified in AST
|
||||||
|
expressions using the call syntax: `imm64(5)` which greates a `ConstantInt`
|
||||||
|
node.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, kind, value):
|
||||||
|
# type: (ImmediateKind, int) -> None
|
||||||
|
self.kind = kind
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
# type: () -> str
|
||||||
|
"""
|
||||||
|
Get the Rust expression form of this constant.
|
||||||
|
"""
|
||||||
|
return str(self.value)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
# type: () -> str
|
||||||
|
return '{}({})'.format(self.kind, self.value)
|
||||||
|
|
||||||
|
|
||||||
class Enumerator(Expr):
|
class Enumerator(Expr):
|
||||||
"""
|
"""
|
||||||
A value of an enumerated immediate operand.
|
A value of an enumerated immediate operand.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ try:
|
|||||||
from typing import Union, Dict, TYPE_CHECKING # noqa
|
from typing import Union, Dict, TYPE_CHECKING # noqa
|
||||||
OperandSpec = Union['OperandKind', ValueType, TypeVar]
|
OperandSpec = Union['OperandKind', ValueType, TypeVar]
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .ast import Enumerator # noqa
|
from .ast import Enumerator, ConstantInt # noqa
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -107,6 +107,20 @@ class ImmediateKind(OperandKind):
|
|||||||
n=self.name, a=value))
|
n=self.name, a=value))
|
||||||
return Enumerator(self, value)
|
return Enumerator(self, value)
|
||||||
|
|
||||||
|
def __call__(self, value):
|
||||||
|
# type: (int) -> ConstantInt
|
||||||
|
"""
|
||||||
|
Create an AST node representing a constant integer:
|
||||||
|
|
||||||
|
iconst(imm64(0))
|
||||||
|
"""
|
||||||
|
from .ast import ConstantInt # noqa
|
||||||
|
if self.values:
|
||||||
|
raise AssertionError(
|
||||||
|
"{}({}): Can't make a constant numeric value for an enum"
|
||||||
|
.format(self.name, value))
|
||||||
|
return ConstantInt(self, value)
|
||||||
|
|
||||||
def rust_enumerator(self, value):
|
def rust_enumerator(self, value):
|
||||||
# type: (str) -> str
|
# type: (str) -> str
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user