diff --git a/artiq/compiler/builtins.py b/artiq/compiler/builtins.py index 6ab7ffe15..3e82f955f 100644 --- a/artiq/compiler/builtins.py +++ b/artiq/compiler/builtins.py @@ -126,10 +126,10 @@ def fn_int(): return types.TConstructor(TInt()) def fn_int32(): - return types.TConstructor(TInt32()) + return types.TBuiltinFunction("int32") def fn_int64(): - return types.TConstructor(TInt64()) + return types.TBuiltinFunction("int64") def fn_float(): return types.TConstructor(TFloat()) diff --git a/artiq/compiler/prelude.py b/artiq/compiler/prelude.py index b0b8db762..f50e4f2fa 100644 --- a/artiq/compiler/prelude.py +++ b/artiq/compiler/prelude.py @@ -14,6 +14,8 @@ def globals(): "list": builtins.fn_list(), "array": builtins.fn_array(), "range": builtins.fn_range(), + "int32": builtins.fn_int32(), + "int64": builtins.fn_int64(), # Exception constructors "Exception": builtins.fn_Exception(), diff --git a/artiq/compiler/transforms/artiq_ir_generator.py b/artiq/compiler/transforms/artiq_ir_generator.py index 6ccd74f43..8e10b77de 100644 --- a/artiq/compiler/transforms/artiq_ir_generator.py +++ b/artiq/compiler/transforms/artiq_ir_generator.py @@ -1599,7 +1599,8 @@ class ARTIQIRGenerator(algorithm.Visitor): return self.coerce_to_bool(arg) else: 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: return ir.Constant(0, node.type) elif len(node.args) == 1 and \ diff --git a/artiq/compiler/transforms/inferencer.py b/artiq/compiler/transforms/inferencer.py index 41cee75d1..b55dfa98d 100644 --- a/artiq/compiler/transforms/inferencer.py +++ b/artiq/compiler/transforms/inferencer.py @@ -622,14 +622,28 @@ class Inferencer(algorithm.Visitor): self._unify(node.type, builtins.TBool(), node.loc, None) - elif types.is_builtin(typ, "int"): - valid_forms = lambda: [ - valid_form("int() -> numpy.int?"), - valid_form("int(x:'a) -> numpy.int?"), - valid_form("int(x:'a, width=?) -> numpy.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_form("int() -> numpy.int?"), + valid_form("int(x:'a) -> numpy.int? where 'a is numeric") + ] + 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) if len(node.args) == 0 and len(node.keywords) == 0: @@ -639,20 +653,7 @@ class Inferencer(algorithm.Visitor): pass # undetermined yet elif len(node.args) == 1 and len(node.keywords) == 0 and \ builtins.is_numeric(node.args[0].type): - self._unify(node.type, builtins.TInt(), - 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)), + self._unify(node.type, result_typ, node.loc, None) else: diagnose(valid_forms()) diff --git a/artiq/test/lit/inferencer/builtin_calls.py b/artiq/test/lit/inferencer/builtin_calls.py index c461d5a03..bd33dd140 100644 --- a/artiq/test/lit/inferencer/builtin_calls.py +++ b/artiq/test/lit/inferencer/builtin_calls.py @@ -13,8 +13,8 @@ int() # CHECK-L: int:(1.0:float):numpy.int? int(1.0) -# CHECK-L: int:(1.0:float, width=64:numpy.int?):numpy.int64 -int(1.0, width=64) +# CHECK-L: int64:(1.0:float):numpy.int64 +int64(1.0) # CHECK-L: float:():float float() diff --git a/artiq/test/lit/inferencer/cast.py b/artiq/test/lit/inferencer/cast.py new file mode 100644 index 000000000..0f9c4c8d9 --- /dev/null +++ b/artiq/test/lit/inferencer/cast.py @@ -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 diff --git a/artiq/test/lit/inferencer/error_builtin_calls.py b/artiq/test/lit/inferencer/error_builtin_calls.py index 172f01e8f..f3d8b7df8 100644 --- a/artiq/test/lit/inferencer/error_builtin_calls.py +++ b/artiq/test/lit/inferencer/error_builtin_calls.py @@ -1,10 +1,6 @@ # RUN: %python -m artiq.compiler.testbench.inferencer +diag %s >%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 len(1) diff --git a/artiq/test/lit/integration/builtin.py b/artiq/test/lit/integration/builtin.py index dbb7e471c..1562edf57 100644 --- a/artiq/test/lit/integration/builtin.py +++ b/artiq/test/lit/integration/builtin.py @@ -7,7 +7,7 @@ assert bool() is False assert int() is 0 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(1) is 1.0