diff --git a/include/npcomp/Dialect/Basicpy/BasicpyDialect.h b/include/npcomp/Dialect/Basicpy/BasicpyDialect.h index 7b73e32e3..30b7d4901 100644 --- a/include/npcomp/Dialect/Basicpy/BasicpyDialect.h +++ b/include/npcomp/Dialect/Basicpy/BasicpyDialect.h @@ -22,6 +22,7 @@ namespace BasicpyTypes { enum Kind { // Dialect types. BoolType = TypeRanges::Basicpy, + BytesType, EllipsisType, NoneType, SlotObjectType, @@ -49,6 +50,16 @@ public: } }; +/// The type of the Python `bytes` values. +class BytesType : public Type::TypeBase { +public: + using Base::Base; + static bool kindof(unsigned kind) { return kind == BasicpyTypes::BytesType; } + static BytesType get(MLIRContext *context) { + return Base::get(context, BasicpyTypes::BytesType); + } +}; + /// The type of the Python `Ellipsis` value. class EllipsisType : public Type::TypeBase { public: diff --git a/include/npcomp/Dialect/Basicpy/BasicpyDialect.td b/include/npcomp/Dialect/Basicpy/BasicpyDialect.td index 7a44af7c8..6e9940a47 100644 --- a/include/npcomp/Dialect/Basicpy/BasicpyDialect.td +++ b/include/npcomp/Dialect/Basicpy/BasicpyDialect.td @@ -46,6 +46,14 @@ def Basicpy_BoolType : DialectType()">, "Bytes type">, + BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::BytesType>()"> { + let typeDescription = [{ + Represents Python 'bytes' values. + }]; +} + def Basicpy_EllipsisType : DialectType()">, "Ellipsis type">, BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::EllipsisType>()"> { diff --git a/include/npcomp/Dialect/Basicpy/BasicpyOps.td b/include/npcomp/Dialect/Basicpy/BasicpyOps.td index 597d278cf..98d14b3dd 100644 --- a/include/npcomp/Dialect/Basicpy/BasicpyOps.td +++ b/include/npcomp/Dialect/Basicpy/BasicpyOps.td @@ -27,6 +27,21 @@ def Basicpy_BoolConstantOp : Basicpy_Op<"bool_constant", [ let assemblyFormat = "$value attr-dict"; } +def Basicpy_BytesConstantOp : Basicpy_Op<"bytes_constant", [ + ConstantLike, NoSideEffect]> { + let summary = "Constant bytes value"; + let description = [{ + A bytes value of BytesType. The value is represented by a StringAttr. + }]; + let arguments = (ins + StrAttr:$value + ); + let results = (outs + Basicpy_BytesType:$result + ); + let assemblyFormat = "$value attr-dict"; +} + def Basicpy_SlotObjectMakeOp : Basicpy_Op<"slot_object_make", [ NoSideEffect]> { let summary = "Creates an instance of a SlotObject type"; diff --git a/lib/Dialect/Basicpy/BasicpyDialect.cpp b/lib/Dialect/Basicpy/BasicpyDialect.cpp index 73d020cd8..931bb4a8f 100644 --- a/lib/Dialect/Basicpy/BasicpyDialect.cpp +++ b/lib/Dialect/Basicpy/BasicpyDialect.cpp @@ -19,7 +19,7 @@ BasicpyDialect::BasicpyDialect(MLIRContext *context) #define GET_OP_LIST #include "npcomp/Dialect/Basicpy/BasicpyOps.cpp.inc" >(); - addTypes(); // TODO: Make real ops for everything we need. @@ -33,6 +33,8 @@ Type BasicpyDialect::parseType(DialectAsmParser &parser) const { if (keyword == "BoolType") return BoolType::get(getContext()); + if (keyword == "BytesType") + return BytesType::get(getContext()); if (keyword == "EllipsisType") return EllipsisType::get(getContext()); if (keyword == "NoneType") @@ -69,6 +71,9 @@ void BasicpyDialect::printType(Type type, DialectAsmPrinter &os) const { case BasicpyTypes::BoolType: os << "BoolType"; return; + case BasicpyTypes::BytesType: + os << "BytesType"; + return; case BasicpyTypes::EllipsisType: os << "EllipsisType"; return; diff --git a/pytest/Compiler/constants.py b/pytest/Compiler/constants.py index 273b921a7..90b3641a6 100644 --- a/pytest/Compiler/constants.py +++ b/pytest/Compiler/constants.py @@ -61,6 +61,14 @@ def joined_string_constant(): a = "I am" " still here" return a +# CHECK-LABEL: func @bytes_constant +@import_global +def bytes_constant(): + # CHECK: %[[A:.*]] = basicpy.bytes_constant "foobar" + # CHECK: basicpy.unknown_cast %[[A]] + a = b"foobar" + return a + # CHECK-LABEL: func @ellipsis @import_global def ellipsis(): diff --git a/python/npcomp/compiler/frontend.py b/python/npcomp/compiler/frontend.py index c1d6c65e2..69e540c4d 100644 --- a/python/npcomp/compiler/frontend.py +++ b/python/npcomp/compiler/frontend.py @@ -210,6 +210,8 @@ class ExpressionImporter(BaseNodeVisitor): self.fctx.abort("unknown named constant '%r'" % (ast_node.value,)) elif isinstance(ast_node, ast.Str): self.value = ir_h.basicpy_str_constant_op(ast_node.s).result + elif isinstance(ast_node, ast.Bytes): + self.value = ir_h.basicpy_bytes_constant_op(ast_node.s).result elif isinstance(ast_node, ast.Ellipsis): self.value = ir_h.basicpy_singleton_op(ir_h.basicpy_EllipsisType).result else: diff --git a/python/npcomp/dialect/Basicpy.py b/python/npcomp/dialect/Basicpy.py index 4c66b8b8f..ff245cedb 100644 --- a/python/npcomp/dialect/Basicpy.py +++ b/python/npcomp/dialect/Basicpy.py @@ -50,11 +50,15 @@ class DialectHelper(_BaseDialectHelper): def basicpy_bool_constant_op(self, value): c = self.context ival = 1 if value else 0 - attrs = c.dictionary_attr({ - "value": c.integer_attr(self.i1_type, ival) - }) + attrs = c.dictionary_attr({"value": c.integer_attr(self.i1_type, ival)}) return self.op("basicpy.bool_constant", [self.basicpy_BoolType], [], attrs) + def basicpy_bytes_constant_op(self, value): + c = self.context + attrs = c.dictionary_attr({"value": c.string_attr(value)}) + return self.op("basicpy.bytes_constant", [self.basicpy_BytesType], [], + attrs) + def basicpy_singleton_op(self, singleton_type): return self.op("basicpy.singleton", [singleton_type], []) @@ -69,14 +73,12 @@ class DialectHelper(_BaseDialectHelper): def basicpy_str_constant_op(self, value): c = self.context - attrs = c.dictionary_attr({ - "value": c.string_attr(value.encode("utf-8")) - }) + attrs = c.dictionary_attr({"value": c.string_attr(value.encode("utf-8"))}) return self.op("basicpy.str_constant", [self.basicpy_StrType], [], attrs) def basicpy_unknown_cast_op(self, result_type, operand): return self.op("basicpy.unknown_cast", [result_type], [operand]) - + if __name__ == "__main__": import doctest diff --git a/python_native/NpcompDialect.cpp b/python_native/NpcompDialect.cpp index 73a3fc434..4c6ac03bb 100644 --- a/python_native/NpcompDialect.cpp +++ b/python_native/NpcompDialect.cpp @@ -26,6 +26,11 @@ public: return Basicpy::BoolType::get( &self.context->context); }) + .def_property_readonly("basicpy_BytesType", + [](BasicpyDialectHelper &self) -> PyType { + return Basicpy::BytesType::get( + &self.context->context); + }) .def_property_readonly("basicpy_EllipsisType", [](BasicpyDialectHelper &self) -> PyType { return Basicpy::EllipsisType::get(