compiler: unbreak casts to int32/int64.

This commit is contained in:
whitequark 2016-11-21 14:01:11 +00:00
parent 53b7d59b6a
commit 55ea68da7f
8 changed files with 36 additions and 31 deletions

View File

@ -126,10 +126,10 @@ def fn_int():
return types.TConstructor(TInt()) return types.TConstructor(TInt())
def fn_int32(): def fn_int32():
return types.TConstructor(TInt32()) return types.TBuiltinFunction("int32")
def fn_int64(): def fn_int64():
return types.TConstructor(TInt64()) return types.TBuiltinFunction("int64")
def fn_float(): def fn_float():
return types.TConstructor(TFloat()) return types.TConstructor(TFloat())

View File

@ -14,6 +14,8 @@ def globals():
"list": builtins.fn_list(), "list": builtins.fn_list(),
"array": builtins.fn_array(), "array": builtins.fn_array(),
"range": builtins.fn_range(), "range": builtins.fn_range(),
"int32": builtins.fn_int32(),
"int64": builtins.fn_int64(),
# Exception constructors # Exception constructors
"Exception": builtins.fn_Exception(), "Exception": builtins.fn_Exception(),

View File

@ -1599,7 +1599,8 @@ class ARTIQIRGenerator(algorithm.Visitor):
return self.coerce_to_bool(arg) return self.coerce_to_bool(arg)
else: else:
assert False assert False
elif types.is_builtin(typ, "int"): elif types.is_builtin(typ, "int") or \
types.is_builtin(typ, "int32") or types.is_builtin(typ, "int64"):
if len(node.args) == 0 and len(node.keywords) == 0: if len(node.args) == 0 and len(node.keywords) == 0:
return ir.Constant(0, node.type) return ir.Constant(0, node.type)
elif len(node.args) == 1 and \ elif len(node.args) == 1 and \

View File

@ -622,14 +622,28 @@ class Inferencer(algorithm.Visitor):
self._unify(node.type, builtins.TBool(), self._unify(node.type, builtins.TBool(),
node.loc, None) node.loc, None)
elif types.is_builtin(typ, "int"): elif types.is_builtin(typ, "int") or \
types.is_builtin(typ, "int32") or types.is_builtin(typ, "int64"):
if types.is_builtin(typ, "int"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("int() -> numpy.int?"), valid_form("int() -> numpy.int?"),
valid_form("int(x:'a) -> numpy.int?"), valid_form("int(x:'a) -> numpy.int? where 'a is numeric")
valid_form("int(x:'a, width=?) -> numpy.int?")
] ]
result_typ = builtins.TInt()
elif types.is_builtin(typ, "int32"):
valid_forms = lambda: [
valid_form("numpy.int32() -> numpy.int32"),
valid_form("numpy.int32(x:'a) -> numpy.int32 where 'a is numeric")
]
result_typ = builtins.TInt32()
elif types.is_builtin(typ, "int64"):
valid_forms = lambda: [
valid_form("numpy.int64() -> numpy.int64"),
valid_form("numpy.int64(x:'a) -> numpy.int64 where 'a is numeric")
]
result_typ = builtins.TInt64()
self._unify(node.type, builtins.TInt(), self._unify(node.type, result_typ,
node.loc, None) node.loc, None)
if len(node.args) == 0 and len(node.keywords) == 0: if len(node.args) == 0 and len(node.keywords) == 0:
@ -639,20 +653,7 @@ class Inferencer(algorithm.Visitor):
pass # undetermined yet pass # undetermined yet
elif len(node.args) == 1 and len(node.keywords) == 0 and \ elif len(node.args) == 1 and len(node.keywords) == 0 and \
builtins.is_numeric(node.args[0].type): builtins.is_numeric(node.args[0].type):
self._unify(node.type, builtins.TInt(), self._unify(node.type, result_typ,
node.loc, None)
elif len(node.args) == 1 and len(node.keywords) == 1 and \
builtins.is_numeric(node.args[0].type) and \
node.keywords[0].arg == 'width':
width = node.keywords[0].value
if not (isinstance(width, asttyped.NumT) and isinstance(width.n, int)):
diag = diagnostic.Diagnostic("error",
"the width argument of int() must be an integer literal", {},
node.keywords[0].loc)
self.engine.process(diag)
return
self._unify(node.type, builtins.TInt(types.TValue(width.n)),
node.loc, None) node.loc, None)
else: else:
diagnose(valid_forms()) diagnose(valid_forms())

View File

@ -13,8 +13,8 @@ int()
# CHECK-L: int:<constructor int>(1.0:float):numpy.int? # CHECK-L: int:<constructor int>(1.0:float):numpy.int?
int(1.0) int(1.0)
# CHECK-L: int:<constructor int>(1.0:float, width=64:numpy.int?):numpy.int64 # CHECK-L: int64:<function int64>(1.0:float):numpy.int64
int(1.0, width=64) int64(1.0)
# CHECK-L: float:<constructor float {}>():float # CHECK-L: float:<constructor float {}>():float
float() float()

View File

@ -0,0 +1,5 @@
# RUN: %python -m artiq.compiler.testbench.inferencer +mono %s >%t
# RUN: OutputCheck %s --file-to-check=%t
# CHECK-L: numpy.int64
int64(2)**32

View File

@ -1,10 +1,6 @@
# RUN: %python -m artiq.compiler.testbench.inferencer +diag %s >%t # RUN: %python -m artiq.compiler.testbench.inferencer +diag %s >%t
# RUN: OutputCheck %s --file-to-check=%t # RUN: OutputCheck %s --file-to-check=%t
a = 1
# CHECK-L: ${LINE:+1}: error: the width argument of int() must be an integer literal
int(1.0, width=a)
# CHECK-L: ${LINE:+1}: error: the argument of len() must be of an iterable type # CHECK-L: ${LINE:+1}: error: the argument of len() must be of an iterable type
len(1) len(1)

View File

@ -7,7 +7,7 @@ assert bool() is False
assert int() is 0 assert int() is 0
assert int(1.0) is 1 assert int(1.0) is 1
#ARTIQ#assert int(1, width=64) << 40 is 1099511627776 #ARTIQ#assert int64(1) << 40 is 1099511627776
#ARTIQ#assert float() is 0.0 #ARTIQ#assert float() is 0.0
#ARTIQ#assert float(1) is 1.0 #ARTIQ#assert float(1) is 1.0