Elaborate hierarchy of builtins.

This commit is contained in:
whitequark 2015-06-28 22:40:57 +03:00
parent ea0d11b8be
commit 9044e88983
5 changed files with 49 additions and 29 deletions

View File

@ -38,28 +38,28 @@ class TRange(types.TMono):
super().__init__("range", {"elt": elt}) super().__init__("range", {"elt": elt})
def fn_bool(): def fn_bool():
return types.TBuiltin("class bool") return types.TConstructor("bool")
def fn_int(): def fn_int():
return types.TBuiltin("class int") return types.TConstructor("int")
def fn_float(): def fn_float():
return types.TBuiltin("class float") return types.TConstructor("float")
def fn_list(): def fn_list():
return types.TBuiltin("class list") return types.TConstructor("list")
def fn_range(): def fn_range():
return types.TBuiltin("function range") return types.TBuiltinFunction("range")
def fn_len(): def fn_len():
return types.TBuiltin("function len") return types.TBuiltinFunction("len")
def fn_round(): def fn_round():
return types.TBuiltin("function round") return types.TBuiltinFunction("round")
def fn_syscall(): def fn_syscall():
return types.TBuiltin("function syscall") return types.TBuiltinFunction("syscall")
# Accessors # Accessors

View File

@ -209,6 +209,24 @@ class TBuiltin(Type):
def __ne__(self, other): def __ne__(self, other):
return not (self == other) return not (self == other)
class TBuiltinFunction(TBuiltin):
"""
A type of a builtin function.
"""
class TConstructor(TBuiltin):
"""
A type of a constructor of a builtin class, e.g. ``list``.
Note that this is not the same as the type of an instance of
the class, which is ``TMono("list", ...)``.
"""
class TExceptionConstructor(TBuiltin):
"""
A type of a constructor of a builtin exception, e.g. ``Exception``.
Note that this is not the same as the type of an instance of
the class, which is ``TMono("Exception", ...)``.
"""
class TValue(Type): class TValue(Type):
""" """
@ -306,8 +324,10 @@ class TypePrinter(object):
args += [ "%s:%s" % (arg, self.name(typ.args[arg])) for arg in typ.args] args += [ "%s:%s" % (arg, self.name(typ.args[arg])) for arg in typ.args]
args += ["?%s:%s" % (arg, self.name(typ.optargs[arg])) for arg in typ.optargs] args += ["?%s:%s" % (arg, self.name(typ.optargs[arg])) for arg in typ.optargs]
return "(%s)->%s" % (", ".join(args), self.name(typ.ret)) return "(%s)->%s" % (", ".join(args), self.name(typ.ret))
elif isinstance(typ, TBuiltin): elif isinstance(typ, TBuiltinFunction):
return "<built-in %s>" % typ.name return "<function %s>" % typ.name
elif isinstance(typ, (TConstructor, TExceptionConstructor)):
return "<constructor %s>" % typ.name
elif isinstance(typ, TValue): elif isinstance(typ, TValue):
return repr(typ.value) return repr(typ.value)
else: else:

View File

@ -739,7 +739,7 @@ class Inferencer(algorithm.Visitor):
node.func.loc, notes=valid_forms) node.func.loc, notes=valid_forms)
self.engine.process(diag) self.engine.process(diag)
if builtins.is_builtin(typ, "class bool"): if builtins.is_builtin(typ, "bool"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("bool() -> bool"), valid_form("bool() -> bool"),
valid_form("bool(x:'a) -> bool") valid_form("bool(x:'a) -> bool")
@ -755,7 +755,7 @@ class Inferencer(algorithm.Visitor):
self._unify(node.type, builtins.TBool(), self._unify(node.type, builtins.TBool(),
node.loc, None) node.loc, None)
elif builtins.is_builtin(typ, "class int"): elif builtins.is_builtin(typ, "int"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("int() -> int(width='a)"), valid_form("int() -> int(width='a)"),
valid_form("int(x:'a) -> int(width='b) where 'a is numeric"), valid_form("int(x:'a) -> int(width='b) where 'a is numeric"),
@ -785,7 +785,7 @@ class Inferencer(algorithm.Visitor):
node.loc, None) node.loc, None)
else: else:
diagnose(valid_forms()) diagnose(valid_forms())
elif builtins.is_builtin(typ, "class float"): elif builtins.is_builtin(typ, "float"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("float() -> float"), valid_form("float() -> float"),
valid_form("float(x:'a) -> float where 'a is numeric") valid_form("float(x:'a) -> float where 'a is numeric")
@ -801,7 +801,7 @@ class Inferencer(algorithm.Visitor):
pass pass
else: else:
diagnose(valid_forms()) diagnose(valid_forms())
elif builtins.is_builtin(typ, "class list"): elif builtins.is_builtin(typ, "list"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("list() -> list(elt='a)"), valid_form("list() -> list(elt='a)"),
valid_form("list(x:'a) -> list(elt='b) where 'a is iterable") valid_form("list(x:'a) -> list(elt='b) where 'a is iterable")
@ -828,7 +828,7 @@ class Inferencer(algorithm.Visitor):
self.engine.process(diag) self.engine.process(diag)
else: else:
diagnose(valid_forms()) diagnose(valid_forms())
elif builtins.is_builtin(typ, "function range"): elif builtins.is_builtin(typ, "range"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("range(max:'a) -> range(elt='a)"), valid_form("range(max:'a) -> range(elt='a)"),
valid_form("range(min:'a, max:'a) -> range(elt='a)"), valid_form("range(min:'a, max:'a) -> range(elt='a)"),
@ -855,7 +855,7 @@ class Inferencer(algorithm.Visitor):
self.engine.process(diag) self.engine.process(diag)
else: else:
diagnose(valid_forms()) diagnose(valid_forms())
elif builtins.is_builtin(typ, "function len"): elif builtins.is_builtin(typ, "len"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("len(x:'a) -> int(width='b) where 'a is iterable"), valid_form("len(x:'a) -> int(width='b) where 'a is iterable"),
] ]
@ -880,7 +880,7 @@ class Inferencer(algorithm.Visitor):
self.engine.process(diag) self.engine.process(diag)
else: else:
diagnose(valid_forms()) diagnose(valid_forms())
elif builtins.is_builtin(typ, "function round"): elif builtins.is_builtin(typ, "round"):
valid_forms = lambda: [ valid_forms = lambda: [
valid_form("round(x:float) -> int(width='a)"), valid_form("round(x:float) -> int(width='a)"),
] ]
@ -896,7 +896,7 @@ class Inferencer(algorithm.Visitor):
else: else:
diagnose(valid_forms()) diagnose(valid_forms())
# TODO: add when it is clear what interface syscall() has # TODO: add when it is clear what interface syscall() has
# elif builtins.is_builtin(typ, "function syscall"): # elif builtins.is_builtin(typ, "syscall"):
# valid_Forms = lambda: [ # valid_Forms = lambda: [
# ] # ]

View File

@ -1,32 +1,32 @@
# RUN: %python -m artiq.py2llvm.typing %s >%t # RUN: %python -m artiq.py2llvm.typing %s >%t
# RUN: OutputCheck %s --file-to-check=%t # RUN: OutputCheck %s --file-to-check=%t
# CHECK-L: bool:<built-in class bool>():bool # CHECK-L: bool:<constructor bool>():bool
bool() bool()
# CHECK-L: bool:<built-in class bool>([]:list(elt='a)):bool # CHECK-L: bool:<constructor bool>([]:list(elt='a)):bool
bool([]) bool([])
# CHECK-L: int:<built-in class int>():int(width='b) # CHECK-L: int:<constructor int>():int(width='b)
int() int()
# CHECK-L: int:<built-in class int>(1.0:float):int(width='c) # CHECK-L: int:<constructor int>(1.0:float):int(width='c)
int(1.0) int(1.0)
# CHECK-L: int:<built-in class int>(1.0:float, width=64:int(width='d)):int(width=64) # CHECK-L: int:<constructor int>(1.0:float, width=64:int(width='d)):int(width=64)
int(1.0, width=64) int(1.0, width=64)
# CHECK-L: float:<built-in class float>():float # CHECK-L: float:<constructor float>():float
float() float()
# CHECK-L: float:<built-in class float>(1:int(width='e)):float # CHECK-L: float:<constructor float>(1:int(width='e)):float
float(1) float(1)
# CHECK-L: list:<built-in class list>():list(elt='f) # CHECK-L: list:<constructor list>():list(elt='f)
list() list()
# CHECK-L: len:<built-in function len>([]:list(elt='g)):int(width=32) # CHECK-L: len:<function len>([]:list(elt='g)):int(width=32)
len([]) len([])
# CHECK-L: round:<built-in function round>(1.0:float):int(width='h) # CHECK-L: round:<function round>(1.0:float):int(width='h)
round(1.0) round(1.0)

View File

@ -1,7 +1,7 @@
# RUN: %python -m artiq.py2llvm.typing %s >%t # RUN: %python -m artiq.py2llvm.typing %s >%t
# RUN: OutputCheck %s --file-to-check=%t # RUN: OutputCheck %s --file-to-check=%t
# CHECK-L: x:<built-in function len> # CHECK-L: x:<function len>
x = len x = len
def f(): def f():