forked from M-Labs/artiq
1
0
Fork 0

compiler: add support for bytes type and b"x" literals (#714).

This commit is contained in:
whitequark 2017-06-09 05:49:55 +00:00
parent d0e92067c3
commit dba4e1a28b
6 changed files with 34 additions and 6 deletions

View File

@ -67,6 +67,10 @@ class TStr(types.TMono):
def __init__(self): def __init__(self):
super().__init__("str") super().__init__("str")
class TBytes(types.TMono):
def __init__(self):
super().__init__("bytes")
class TList(types.TMono): class TList(types.TMono):
def __init__(self, elt=None): def __init__(self, elt=None):
if elt is None: if elt is None:
@ -137,6 +141,9 @@ def fn_float():
def fn_str(): def fn_str():
return types.TConstructor(TStr()) return types.TConstructor(TStr())
def fn_bytes():
return types.TConstructor(TBytes())
def fn_list(): def fn_list():
return types.TConstructor(TList()) return types.TConstructor(TList())
@ -236,6 +243,9 @@ def is_float(typ):
def is_str(typ): def is_str(typ):
return types.is_mono(typ, "str") return types.is_mono(typ, "str")
def is_bytes(typ):
return types.is_mono(typ, "bytes")
def is_numeric(typ): def is_numeric(typ):
typ = typ.find() typ = typ.find()
return isinstance(typ, types.TMono) and \ return isinstance(typ, types.TMono) and \
@ -254,7 +264,12 @@ def is_array(typ, elt=None):
return types.is_mono(typ, "array") return types.is_mono(typ, "array")
def is_listish(typ, elt=None): def is_listish(typ, elt=None):
return is_list(typ, elt) or is_array(typ, elt) or (elt is None and is_str(typ)) if is_list(typ, elt) or is_array(typ, elt):
return True
elif elt is None:
return is_str(typ) or is_bytes(typ)
else:
return False
def is_range(typ, elt=None): def is_range(typ, elt=None):
if elt is not None: if elt is not None:
@ -277,7 +292,7 @@ def is_iterable(typ):
def get_iterable_elt(typ): def get_iterable_elt(typ):
if is_iterable(typ): if is_iterable(typ):
return typ.find()["elt"].find() return typ.find()["elt"].find()
elif is_str(typ): elif is_str(typ) or is_bytes(typ):
return TInt(types.TValue(8)) return TInt(types.TValue(8))
else: else:
assert False assert False

View File

@ -200,6 +200,9 @@ class ASTSynthesizer:
elif isinstance(value, str): elif isinstance(value, str):
return asttyped.StrT(s=value, ctx=None, type=builtins.TStr(), return asttyped.StrT(s=value, ctx=None, type=builtins.TStr(),
loc=self._add(repr(value))) loc=self._add(repr(value)))
elif isinstance(value, bytes):
return asttyped.StrT(s=value, ctx=None, type=builtins.TBytes(),
loc=self._add(repr(value)))
elif isinstance(value, list): elif isinstance(value, list):
begin_loc = self._add("[") begin_loc = self._add("[")
elts = [] elts = []

View File

@ -11,6 +11,8 @@ def globals():
"bool": builtins.fn_bool(), "bool": builtins.fn_bool(),
"int": builtins.fn_int(), "int": builtins.fn_int(),
"float": builtins.fn_float(), "float": builtins.fn_float(),
"str": builtins.fn_str(),
"bytes": builtins.fn_bytes(),
"list": builtins.fn_list(), "list": builtins.fn_list(),
"array": builtins.fn_array(), "array": builtins.fn_array(),
"range": builtins.fn_range(), "range": builtins.fn_range(),

View File

@ -331,8 +331,13 @@ class ASTTypedRewriter(algorithm.Transformer):
n=node.n, loc=node.loc) n=node.n, loc=node.loc)
def visit_Str(self, node): def visit_Str(self, node):
return asttyped.StrT(type=builtins.TStr(), if isinstance(node.s, str):
s=node.s, typ = builtins.TStr()
elif isinstance(node.s, bytes):
typ = builtins.TBytes()
else:
assert False
return asttyped.StrT(type=typ, s=node.s,
begin_loc=node.begin_loc, end_loc=node.end_loc, loc=node.loc) begin_loc=node.begin_loc, end_loc=node.end_loc, loc=node.loc)
def visit_Name(self, node): def visit_Name(self, node):

View File

@ -1054,7 +1054,7 @@ class LLVMIRGenerator:
lloperand = self.map(operand) lloperand = self.map(operand)
if i == 0 and insn.op == "printf" or i == 1 and insn.op == "rtio_log": if i == 0 and insn.op == "printf" or i == 1 and insn.op == "rtio_log":
lloperands.append(self.llbuilder.extract_value(lloperand, 0)) lloperands.append(self.llbuilder.extract_value(lloperand, 0))
elif builtins.is_str(operand.type): elif builtins.is_str(operand.type) or builtins.is_bytes(operand.type):
lloperands.append(self.llbuilder.extract_value(lloperand, 1)) lloperands.append(self.llbuilder.extract_value(lloperand, 1))
lloperands.append(self.llbuilder.extract_value(lloperand, 0)) lloperands.append(self.llbuilder.extract_value(lloperand, 0))
else: else:
@ -1434,7 +1434,7 @@ class LLVMIRGenerator:
elif builtins.is_float(typ): elif builtins.is_float(typ):
assert isinstance(value, float), fail_msg assert isinstance(value, float), fail_msg
return ll.Constant(llty, value) return ll.Constant(llty, value)
elif builtins.is_str(typ): elif builtins.is_str(typ) or builtins.is_bytes(typ):
assert isinstance(value, (str, bytes)), fail_msg assert isinstance(value, (str, bytes)), fail_msg
if isinstance(value, str): if isinstance(value, str):
as_bytes = value.encode("utf-8") as_bytes = value.encode("utf-8")

View File

@ -57,6 +57,9 @@ lambda x, y=1: x
k = "x" k = "x"
# CHECK-L: k:str # CHECK-L: k:str
ka = b"x"
# CHECK-L: ka:bytes
l = array([1]) l = array([1])
# CHECK-L: l:numpy.array(elt=numpy.int?) # CHECK-L: l:numpy.array(elt=numpy.int?)