forked from M-Labs/artiq
parent
77d47c2fdd
commit
33e8e59cc7
|
@ -138,6 +138,12 @@ def fn_len():
|
||||||
def fn_round():
|
def fn_round():
|
||||||
return types.TBuiltinFunction("round")
|
return types.TBuiltinFunction("round")
|
||||||
|
|
||||||
|
def fn_min():
|
||||||
|
return types.TBuiltinFunction("min")
|
||||||
|
|
||||||
|
def fn_max():
|
||||||
|
return types.TBuiltinFunction("max")
|
||||||
|
|
||||||
def fn_print():
|
def fn_print():
|
||||||
return types.TBuiltinFunction("print")
|
return types.TBuiltinFunction("print")
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ def globals():
|
||||||
# Built-in Python functions
|
# Built-in Python functions
|
||||||
"len": builtins.fn_len(),
|
"len": builtins.fn_len(),
|
||||||
"round": builtins.fn_round(),
|
"round": builtins.fn_round(),
|
||||||
|
"min": builtins.fn_min(),
|
||||||
|
"max": builtins.fn_max(),
|
||||||
"print": builtins.fn_print(),
|
"print": builtins.fn_print(),
|
||||||
|
|
||||||
# ARTIQ decorators
|
# ARTIQ decorators
|
||||||
|
|
|
@ -1667,6 +1667,20 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
||||||
return self.append(ir.Builtin("round", [arg], node.type))
|
return self.append(ir.Builtin("round", [arg], node.type))
|
||||||
else:
|
else:
|
||||||
assert False
|
assert False
|
||||||
|
elif types.is_builtin(typ, "min"):
|
||||||
|
if len(node.args) == 2 and len(node.keywords) == 0:
|
||||||
|
arg0, arg1 = map(self.visit, node.args)
|
||||||
|
cond = self.append(ir.Compare(ast.Lt(loc=None), arg0, arg1))
|
||||||
|
return self.append(ir.Select(cond, arg0, arg1))
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
elif types.is_builtin(typ, "max"):
|
||||||
|
if len(node.args) == 2 and len(node.keywords) == 0:
|
||||||
|
arg0, arg1 = map(self.visit, node.args)
|
||||||
|
cond = self.append(ir.Compare(ast.Gt(loc=None), arg0, arg1))
|
||||||
|
return self.append(ir.Select(cond, arg0, arg1))
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
elif types.is_builtin(typ, "print"):
|
elif types.is_builtin(typ, "print"):
|
||||||
self.polymorphic_print([self.visit(arg) for arg in node.args],
|
self.polymorphic_print([self.visit(arg) for arg in node.args],
|
||||||
separator=" ", suffix="\n")
|
separator=" ", suffix="\n")
|
||||||
|
|
|
@ -789,6 +789,37 @@ class Inferencer(algorithm.Visitor):
|
||||||
node.loc, None)
|
node.loc, None)
|
||||||
else:
|
else:
|
||||||
diagnose(valid_forms())
|
diagnose(valid_forms())
|
||||||
|
elif types.is_builtin(typ, "min") or types.is_builtin(typ, "max"):
|
||||||
|
fn = typ.name
|
||||||
|
|
||||||
|
valid_forms = lambda: [
|
||||||
|
valid_form("{}(x:int(width='a), y:int(width='a)) -> int(width='a)".format(fn)),
|
||||||
|
valid_form("{}(x:float, y:float) -> float".format(fn))
|
||||||
|
]
|
||||||
|
|
||||||
|
if len(node.args) == 2 and len(node.keywords) == 0:
|
||||||
|
arg0, arg1 = node.args
|
||||||
|
|
||||||
|
self._unify(arg0.type, arg1.type,
|
||||||
|
arg0.loc, arg1.loc)
|
||||||
|
|
||||||
|
if builtins.is_int(arg0.type) or builtins.is_float(arg0.type):
|
||||||
|
self._unify(arg0.type, node.type,
|
||||||
|
arg0.loc, node.loc)
|
||||||
|
elif types.is_var(arg0.type):
|
||||||
|
pass # undetermined yet
|
||||||
|
else:
|
||||||
|
note = diagnostic.Diagnostic("note",
|
||||||
|
"this expression has type {type}",
|
||||||
|
{"type": types.TypePrinter().name(arg0.type)},
|
||||||
|
arg0.loc)
|
||||||
|
diag = diagnostic.Diagnostic("error",
|
||||||
|
"the arguments of {fn}() must be of a numeric type",
|
||||||
|
{"fn": fn},
|
||||||
|
node.func.loc, notes=[note])
|
||||||
|
self.engine.process(diag)
|
||||||
|
else:
|
||||||
|
diagnose(valid_forms())
|
||||||
elif types.is_builtin(typ, "print"):
|
elif types.is_builtin(typ, "print"):
|
||||||
valid_forms = lambda: [
|
valid_forms = lambda: [
|
||||||
valid_form("print(args...) -> None"),
|
valid_form("print(args...) -> None"),
|
||||||
|
|
|
@ -10,3 +10,6 @@ len(1)
|
||||||
|
|
||||||
# CHECK-L: ${LINE:+1}: error: the argument of list() must be of an iterable type
|
# CHECK-L: ${LINE:+1}: error: the argument of list() must be of an iterable type
|
||||||
list(1)
|
list(1)
|
||||||
|
|
||||||
|
# CHECK-L: ${LINE:+1}: error: the arguments of min() must be of a numeric type
|
||||||
|
min([1], [1])
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# RUN: %python -m artiq.compiler.testbench.jit %s
|
||||||
|
# RUN: %python %s
|
||||||
|
|
||||||
|
assert min(1, 2) == 1
|
||||||
|
assert max(1, 2) == 2
|
||||||
|
assert min(1.0, 2.0) == 1.0
|
||||||
|
assert max(1.0, 2.0) == 2.0
|
Loading…
Reference in New Issue