diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f29de95f4..597783e4e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,5 @@ name: "Build" -on: [push, pull_request] +on: [push] jobs: linux-clang-build: runs-on: ${{matrix.os}} diff --git a/include/hobbes/db/series.H b/include/hobbes/db/series.H index 24023d525..48f82acd5 100644 --- a/include/hobbes/db/series.H +++ b/include/hobbes/db/series.H @@ -17,6 +17,17 @@ namespace hobbes { typedef uint64_t ufileref; +// A -> (A) +MonoTypePtr entuple(const MonoTypePtr&); +// A N -> carray A N +MonoTypePtr carrayty(const MonoTypePtr&, const MonoTypePtr&); +// A -> ^x.(()+(A*x@?)) +MonoTypePtr storedListOf(const MonoTypePtr&); +// A N -> fseq A N +MonoTypePtr storedStreamOf(const MonoTypePtr&, size_t); +// A -- StoredAs A B --> B +MonoTypePtr storeAs(cc* c, const MonoTypePtr&); + class RawStoredSeries { public: RawStoredSeries(cc*, writer*, const std::string&, const MonoTypePtr&, size_t); diff --git a/include/hobbes/lang/tylift.H b/include/hobbes/lang/tylift.H index 20025bae5..fd2486c8a 100644 --- a/include/hobbes/lang/tylift.H +++ b/include/hobbes/lang/tylift.H @@ -422,6 +422,33 @@ template template struct lift::type> : public liftEnum { }; +// lift variant records +template + struct liftVariantRecord { + struct descF { + Variant::Members* ctors; + typedb* tenv; + descF(Variant::Members* ctors, typedb* tenv) : ctors(ctors), tenv(tenv) { } + + template + void ctor(const char* n, int id) { + this->ctors->push_back(Variant::Member(n, lift::type(*this->tenv), id)); + } + }; + + static MonoTypePtr type(typedb& tenv) { + Variant::Members ms; + descF f(&ms, &tenv); + T::meta(f); + return Variant::make(ms); + } + }; + +template + struct lift::type> : public liftVariantRecord { }; +template + struct lift::type> : public liftVariantRecord { }; + // lift plain tuples template struct liftTuple { diff --git a/lib/hobbes/db/series.C b/lib/hobbes/db/series.C index 5b2549f7a..382b856f7 100644 --- a/lib/hobbes/db/series.C +++ b/lib/hobbes/db/series.C @@ -154,14 +154,14 @@ void StoredSeries::clear(bool signal) { *******/ // A -> (A) -static MonoTypePtr entuple(const MonoTypePtr& ty) { +MonoTypePtr entuple(const MonoTypePtr& ty) { Record::Members ms; ms.push_back(Record::Member(".f0", ty)); return MonoTypePtr(Record::make(ms)); } // A N -> carray A N -static MonoTypePtr carrayty(const MonoTypePtr& ty, const MonoTypePtr& n) { +MonoTypePtr carrayty(const MonoTypePtr& ty, const MonoTypePtr& n) { Record::Members ms; ms.push_back(Record::Member("avail", primty("long"))); ms.push_back(Record::Member("buffer", FixedArray::make(tvar("t"), tvar("c")))); @@ -169,7 +169,7 @@ static MonoTypePtr carrayty(const MonoTypePtr& ty, const MonoTypePtr& n) { } // A -> ^x.(()+(A*x@?)) -static MonoTypePtr storedListOf(const MonoTypePtr& ty) { +MonoTypePtr storedListOf(const MonoTypePtr& ty) { Record::Members pms; pms.push_back(Record::Member(".f0", ty)); pms.push_back(Record::Member(".f1", fileRefTy(tvar("x")))); @@ -182,12 +182,12 @@ static MonoTypePtr storedListOf(const MonoTypePtr& ty) { } // A N -> fseq A N -static MonoTypePtr storedStreamOf(const MonoTypePtr& ty, size_t n) { +MonoTypePtr storedStreamOf(const MonoTypePtr& ty, size_t n) { return tapp(primty("fseq", tabs(str::strings("t", "c"), fileRefTy(storedListOf(fileRefTy(carrayty(tvar("t"), tvar("c"))))))), list(ty, tlong(n))); } // A -- StoredAs A B --> B -static MonoTypePtr storeAs(cc* c, const MonoTypePtr& ty) { +MonoTypePtr storeAs(cc* c, const MonoTypePtr& ty) { // construct the constraint that the input type stores to some output type MonoTypeUnifier u(c->typeEnv()); MonoTypePtr sty = freshTypeVar(); diff --git a/test/Variants.C b/test/Variants.C index 632014da9..649375941 100644 --- a/test/Variants.C +++ b/test/Variants.C @@ -102,6 +102,19 @@ TEST(Variants, Enums) { EXPECT_EQ((makeStdString(c().compileFn*(PColor pc)>("x", "show(x)")(PColor::Red()))), "|Red|"); } +DEFINE_VARIANT(Item, + (vehicle, int), + (food, float) +); + +TEST(Variants, VariantRecord) { + Item aVehicle = Item::vehicle(123); + Item aFood = Item::food(321.123); + + EXPECT_EQ((c().compileFn("x", "match x with | |vehicle=v| -> v | |food=_| -> 321")(&aVehicle)), 123); + EXPECT_EQ((c().compileFn("x", "match x with | |vehicle=v| -> v | |food=_| -> 321")(&aFood)), 321); +} + TEST(Variants, WithFunctions) { EXPECT_TRUE(c().compileFn("either((\\|1=f|.f(1L,0L))(just(if (0 > 0) then llt else lgt)), false, id)")()); }