Support constant integers in AST expressions.

Make it possible to write AST nodes: iconst.i32(imm64(0)).
This commit is contained in:
Jakob Stoklund Olesen
2017-07-28 08:57:32 -07:00
parent ede02e0f97
commit b5076108c1
2 changed files with 49 additions and 3 deletions

View File

@@ -350,8 +350,8 @@ class Apply(Expr):
on this instruction.
Immediate operands in a source pattern can be either free variables or
constants like `Enumerator`. We don't currently support constraints on
free variables, but we may in the future.
constants like `ConstantInt` and `Enumerator`. We don't currently
support constraints on free variables, but we may in the future.
"""
pred = None # type: PredNode
iform = self.inst.format
@@ -415,6 +415,12 @@ class Apply(Expr):
else:
if (s[self_a] != other_a):
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:
assert isinstance(self_a, Enumerator)
@@ -430,6 +436,32 @@ class Apply(Expr):
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):
"""
A value of an enumerated immediate operand.

View File

@@ -8,7 +8,7 @@ try:
from typing import Union, Dict, TYPE_CHECKING # noqa
OperandSpec = Union['OperandKind', ValueType, TypeVar]
if TYPE_CHECKING:
from .ast import Enumerator # noqa
from .ast import Enumerator, ConstantInt # noqa
except ImportError:
pass
@@ -107,6 +107,20 @@ class ImmediateKind(OperandKind):
n=self.name, a=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):
# type: (str) -> str
"""