forked from M-Labs/artiq
compiler: add support for bytes type and b"x" literals (#714).
This commit is contained in:
parent
d0e92067c3
commit
dba4e1a28b
|
@ -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
|
||||||
|
|
|
@ -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 = []
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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?)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue