forked from M-Labs/artiq
Add IntMonomorphizer.
This commit is contained in:
parent
7ce9bdf54d
commit
196acb37f6
@ -8,15 +8,18 @@ from . import prelude, types, transforms
|
||||
|
||||
class Module:
|
||||
def __init__(self, source_buffer, engine=diagnostic.Engine(all_errors_are_fatal=True)):
|
||||
parsetree, comments = parse_buffer(source_buffer, engine=engine)
|
||||
self.name = os.path.basename(source_buffer.name)
|
||||
|
||||
asttyped_rewriter = transforms.ASTTypedRewriter(engine=engine)
|
||||
typedtree = asttyped_rewriter.visit(parsetree)
|
||||
self.globals = asttyped_rewriter.globals
|
||||
|
||||
inferencer = transforms.Inferencer(engine=engine)
|
||||
int_monomorphizer = transforms.IntMonomorphizer(engine=engine)
|
||||
|
||||
parsetree, comments = parse_buffer(source_buffer, engine=engine)
|
||||
typedtree = asttyped_rewriter.visit(parsetree)
|
||||
inferencer.visit(typedtree)
|
||||
int_monomorphizer.visit(typedtree)
|
||||
inferencer.visit(typedtree)
|
||||
|
||||
self.name = os.path.basename(source_buffer.name)
|
||||
self.globals = asttyped_rewriter.globals
|
||||
|
||||
@classmethod
|
||||
def from_string(klass, source_string, name="input.py", first_line=1):
|
||||
|
@ -1,2 +1,3 @@
|
||||
from .asttyped_rewriter import ASTTypedRewriter
|
||||
from .inferencer import Inferencer
|
||||
from .int_monomorphizer import IntMonomorphizer
|
||||
|
@ -1,3 +1,8 @@
|
||||
"""
|
||||
:class:`ASTTypedRewriter` rewrites a parsetree (:mod:`pythonparser.ast`)
|
||||
to a typedtree (:mod:`..asttyped`).
|
||||
"""
|
||||
|
||||
from pythonparser import algorithm, diagnostic
|
||||
from .. import asttyped, types, builtins, prelude
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
"""
|
||||
:class:`Inferencer` performs unification-based inference on a typedtree.
|
||||
"""
|
||||
|
||||
from collections import OrderedDict
|
||||
from pythonparser import algorithm, diagnostic, ast
|
||||
from .. import asttyped, types, builtins
|
||||
@ -168,6 +172,7 @@ class Inferencer(algorithm.Visitor):
|
||||
if coerced_node.type.find() == typ.find():
|
||||
return coerced_node
|
||||
elif isinstance(coerced_node, asttyped.CoerceT):
|
||||
node = coerced_node
|
||||
node.type, node.other_expr = typ, other_node
|
||||
else:
|
||||
node = asttyped.CoerceT(type=typ, expr=coerced_node, other_expr=other_node,
|
||||
@ -191,7 +196,7 @@ class Inferencer(algorithm.Visitor):
|
||||
elif any(map(builtins.is_float, node_types)):
|
||||
typ = builtins.TFloat()
|
||||
elif any(map(builtins.is_int, node_types)):
|
||||
widths = map(builtins.get_int_width, node_types)
|
||||
widths = list(map(builtins.get_int_width, node_types))
|
||||
if all(widths):
|
||||
typ = builtins.TInt(types.TValue(max(widths)))
|
||||
else:
|
||||
|
28
artiq/compiler/transforms/int_monomorphizer.py
Normal file
28
artiq/compiler/transforms/int_monomorphizer.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""
|
||||
:class:`IntMonomorphizer` collapses the integer literals of undetermined
|
||||
width to 32 bits, assuming they fit into 32 bits, or 64 bits if they
|
||||
do not.
|
||||
"""
|
||||
|
||||
from pythonparser import algorithm, diagnostic
|
||||
from .. import types, builtins
|
||||
|
||||
class IntMonomorphizer(algorithm.Visitor):
|
||||
def __init__(self, engine):
|
||||
self.engine = engine
|
||||
|
||||
def visit_NumT(self, node):
|
||||
if builtins.is_int(node.type):
|
||||
if types.is_var(node.type["width"]):
|
||||
if -2**31 < node.n < 2**31-1:
|
||||
width = 32
|
||||
elif -2**63 < node.n < 2**63-1:
|
||||
width = 64
|
||||
else:
|
||||
diag = diagnostic.Diagnostic("error",
|
||||
"integer literal out of range for a signed 64-bit value", {},
|
||||
node.loc)
|
||||
self.engine.process(diag)
|
||||
return
|
||||
|
||||
node.type["width"].unify(types.TValue(width))
|
@ -168,8 +168,8 @@ class TFunction(Type):
|
||||
if isinstance(other, TFunction) and \
|
||||
self.args.keys() == other.args.keys() and \
|
||||
self.optargs.keys() == other.optargs.keys():
|
||||
for selfarg, otherarg in zip(self.args.values() + self.optargs.values(),
|
||||
other.args.values() + other.optargs.values()):
|
||||
for selfarg, otherarg in zip(list(self.args.values()) + list(self.optargs.values()),
|
||||
list(other.args.values()) + list(other.optargs.values())):
|
||||
selfarg.unify(otherarg)
|
||||
self.ret.unify(other.ret)
|
||||
elif isinstance(other, TVar):
|
||||
|
Loading…
Reference in New Issue
Block a user