From b7e579dc20089550b7c550e388c3b9c1aab1374f Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 15 Aug 2025 12:37:34 +0200 Subject: [PATCH 1/5] fix[core]: remove redundant imports --- src/Language/Scalie/Core/Provenance/SourceLocation.hs | 3 --- src/Language/Scalie/Domain/Type.hs | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Language/Scalie/Core/Provenance/SourceLocation.hs b/src/Language/Scalie/Core/Provenance/SourceLocation.hs index ab1f76f..301b1e2 100644 --- a/src/Language/Scalie/Core/Provenance/SourceLocation.hs +++ b/src/Language/Scalie/Core/Provenance/SourceLocation.hs @@ -1,9 +1,6 @@ {-# LANGUAGE Safe #-} module Language.Scalie.Core.Provenance.SourceLocation (SourceLocation(..)) where import Data.Kind (Type) -import Text.Show (Show) -import Text.Read (Read) -import Data.Eq (Eq) type SourceLocation :: Type data SourceLocation diff --git a/src/Language/Scalie/Domain/Type.hs b/src/Language/Scalie/Domain/Type.hs index 92f9f87..106c061 100644 --- a/src/Language/Scalie/Domain/Type.hs +++ b/src/Language/Scalie/Domain/Type.hs @@ -3,11 +3,9 @@ module Language.Scalie.Domain.Type (Type(..)) where import Data.Kind qualified -import Text.Show (Show) -import Text.Read (Read) -import Data.Eq (Eq) import Test.QuickCheck (Arbitrary (arbitrary), Gen, oneof) -import Control.Applicative (Applicative(pure)) + +-- | The type of an expression in Scalie, not to be confused with the 'Type' provided by GHC type Type :: Data.Kind.Type data Type From 3847e1e81ea412bd1eed593e4069abf99ba0abe8 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 15 Aug 2025 12:49:40 +0200 Subject: [PATCH 2/5] doc[core] --- src/Language/Scalie/Core/Definition.hs | 2 ++ src/Language/Scalie/Core/Expression.hs | 2 ++ src/Language/Scalie/Core/Module.hs | 2 +- src/Language/Scalie/Core/Provenance.hs | 2 ++ src/Language/Scalie/Core/Provenance/SourceLocation.hs | 4 ++++ src/Language/Scalie/Domain/Type.hs | 2 ++ 6 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Language/Scalie/Core/Definition.hs b/src/Language/Scalie/Core/Definition.hs index c1f0f60..60e2cb8 100644 --- a/src/Language/Scalie/Core/Definition.hs +++ b/src/Language/Scalie/Core/Definition.hs @@ -60,6 +60,8 @@ deriving stock instance (Show (f (Expression f)), Show (f Scalie.Domain.Type), S deriving stock instance (Read (f (Expression f)), Read (f Scalie.Domain.Type), Read (f Text)) => Read (Definition f) deriving stock instance (Eq (f (Expression f)), Eq (f Scalie.Domain.Type) , Eq (f Text)) => Eq (Definition f) +-- | Using custom instances allows extracting just the text whereever possible. + instance ImplicitKeyOf (Definition (Provenance a)) where type KeyType (Definition (Provenance a)) = Text keyOf :: Definition (Provenance a) -> KeyType (Definition (Provenance a)) diff --git a/src/Language/Scalie/Core/Expression.hs b/src/Language/Scalie/Core/Expression.hs index 3c84c15..6511fb7 100644 --- a/src/Language/Scalie/Core/Expression.hs +++ b/src/Language/Scalie/Core/Expression.hs @@ -24,6 +24,8 @@ import Test.QuickCheck.Gen (Gen) import Test.QuickCheck qualified as Gen +-- | Desugared expression. + type Expression :: (Type -> Type) -> Type type role Expression nominal data Expression f diff --git a/src/Language/Scalie/Core/Module.hs b/src/Language/Scalie/Core/Module.hs index 0a0ce69..b344fa7 100644 --- a/src/Language/Scalie/Core/Module.hs +++ b/src/Language/Scalie/Core/Module.hs @@ -9,7 +9,7 @@ import Data.Kind (Type) import Language.Scalie.Core.Definition (Definition) import Data.Map.Implicit (ImplicitMap) --- | A module groups multiple related definitions. +-- | A module groups multiple related variable definitions. -- -- >>> import Data.Functor.Identity (Identity(..)) -- >>> import Data.Map.Implicit qualified as ImplicitMap diff --git a/src/Language/Scalie/Core/Provenance.hs b/src/Language/Scalie/Core/Provenance.hs index d067c69..50714c7 100644 --- a/src/Language/Scalie/Core/Provenance.hs +++ b/src/Language/Scalie/Core/Provenance.hs @@ -11,6 +11,8 @@ import Data.Bifunctor (Bifunctor (bimap)) import Data.Bifoldable (Bifoldable (bifoldMap)) import Data.Bitraversable (Bitraversable (bitraverse)) +-- | Provenance records where something comes from. E.g. file name, file line, other sources. + type Provenance :: Type -> Type -> Type type role Provenance representational representational data Provenance source value = Provenance diff --git a/src/Language/Scalie/Core/Provenance/SourceLocation.hs b/src/Language/Scalie/Core/Provenance/SourceLocation.hs index 301b1e2..3ecf436 100644 --- a/src/Language/Scalie/Core/Provenance/SourceLocation.hs +++ b/src/Language/Scalie/Core/Provenance/SourceLocation.hs @@ -2,6 +2,10 @@ module Language.Scalie.Core.Provenance.SourceLocation (SourceLocation(..)) where import Data.Kind (Type) +-- | Location of anything in a user-provided source file. +-- +-- TODO: Add more constructors + type SourceLocation :: Type data SourceLocation = Synthesized diff --git a/src/Language/Scalie/Domain/Type.hs b/src/Language/Scalie/Domain/Type.hs index 106c061..97354de 100644 --- a/src/Language/Scalie/Domain/Type.hs +++ b/src/Language/Scalie/Domain/Type.hs @@ -12,6 +12,8 @@ data Type = RawInt deriving stock (Show, Read, Eq) + -- add to the arbitrary instance when defining constructors + instance Arbitrary Type where arbitrary :: Gen Type arbitrary = oneof [ pure RawInt ] From ebe94e2d9bde0cafc5eaf12b4972dedfd81f6b72 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 15 Aug 2025 13:03:31 +0200 Subject: [PATCH 3/5] feat[core]: Algebraic Data Types --- scalie.cabal | 5 +++++ src/Language/Scalie/Core/AlgebraicDatatype.hs | 19 ++++++++++++++++ .../Core/AlgebraicDatatype/Constructor.hs | 13 +++++++++++ .../Scalie/Core/AlgebraicDatatype/Field.hs | 16 ++++++++++++++ .../Core/AlgebraicDatatype/FieldIdentifier.hs | 8 +++++++ .../Scalie/Core/AlgebraicDatatype/TypeName.hs | 22 +++++++++++++++++++ 6 files changed, 83 insertions(+) create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/Field.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs diff --git a/scalie.cabal b/scalie.cabal index bf5a427..5d04b75 100644 --- a/scalie.cabal +++ b/scalie.cabal @@ -24,6 +24,11 @@ library Language.Scalie.Bytecode.Object Language.Scalie.Bytecode.Object.Builder Language.Scalie.Compiler.Bytecode + Language.Scalie.Core.AlgebraicDatatype + Language.Scalie.Core.AlgebraicDatatype.Constructor + Language.Scalie.Core.AlgebraicDatatype.Field + Language.Scalie.Core.AlgebraicDatatype.FieldIdentifier + Language.Scalie.Core.AlgebraicDatatype.TypeName Language.Scalie.Core.Definition Language.Scalie.Core.Expression Language.Scalie.Core.Expression.ConstructorIdentifier diff --git a/src/Language/Scalie/Core/AlgebraicDatatype.hs b/src/Language/Scalie/Core/AlgebraicDatatype.hs new file mode 100644 index 0000000..3b001db --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype.hs @@ -0,0 +1,19 @@ +{-# LANGUAGE Trustworthy #-} +module Language.Scalie.Core.AlgebraicDatatype (AlgebraicDatatype(..)) where + +-- meta +import Data.Kind (Type) + +-- data structures +import Data.Vector (Vector) + +-- scalie +import Language.Scalie.Core.AlgebraicDatatype.TypeName (TypeName) +import Language.Scalie.Core.AlgebraicDatatype.Constructor (Constructor) + +type AlgebraicDatatype :: (Type -> Type) -> Type +type role AlgebraicDatatype nominal +data AlgebraicDatatype f = AlgebraicDatatype + { name :: f TypeName + , constructors :: f (Vector (Constructor f)) + } diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs b/src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs new file mode 100644 index 0000000..e70144c --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE Trustworthy #-} -- uses vector operations +module Language.Scalie.Core.AlgebraicDatatype.Constructor (Constructor(..)) where +import Data.Kind (Type) +import Language.Scalie.Core.Expression.ConstructorIdentifier (ConstructorIdentifier) +import Data.Vector (Vector) +import Language.Scalie.Core.AlgebraicDatatype.Field (Field) + +type Constructor :: (Type -> Type) -> Type +type role Constructor nominal +data Constructor f = Constructor + { name :: f ConstructorIdentifier + , fields :: f (Vector (Field f)) + } diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/Field.hs b/src/Language/Scalie/Core/AlgebraicDatatype/Field.hs new file mode 100644 index 0000000..808b4b8 --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/Field.hs @@ -0,0 +1,16 @@ +{-# LANGUAGE Safe #-} +module Language.Scalie.Core.AlgebraicDatatype.Field (Field(..)) where + +-- meta +import Data.Kind qualified + +-- scalie +import Language.Scalie.Core.AlgebraicDatatype.FieldIdentifier (FieldIdentifier) +import Language.Scalie.Domain.Type qualified as Scalie.Domain + +type Field :: (Data.Kind.Type -> Data.Kind.Type) -> Data.Kind.Type +type role Field nominal +data Field f = Field + { name :: f FieldIdentifier + , typ :: f Scalie.Domain.Type + } diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs b/src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs new file mode 100644 index 0000000..8892208 --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE Safe #-} +module Language.Scalie.Core.AlgebraicDatatype.FieldIdentifier (FieldIdentifier(..)) where +import Data.Text (Text) +import Data.Kind (Type) + +type FieldIdentifier :: Type +newtype FieldIdentifier = FieldIdentifier { get :: Text } + deriving stock (Show, Read, Eq) diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs b/src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs new file mode 100644 index 0000000..14d2667 --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs @@ -0,0 +1,22 @@ +{-# LANGUAGE Safe #-} +{-# LANGUAGE InstanceSigs #-} +module Language.Scalie.Core.AlgebraicDatatype.TypeName (TypeName(..)) where + +-- meta +import Data.Kind (Type) + +-- data structures +import Data.Text (Text) +import Data.Text qualified as Text + +-- library: QuickCheck +import Test.QuickCheck (Arbitrary (arbitrary), Gen, UnicodeString (getUnicodeString)) + +type TypeName :: Type +newtype TypeName = TypeName { get :: Text } + deriving stock (Show, Read, Eq) + +instance Arbitrary TypeName where + arbitrary :: Gen TypeName + arbitrary = TypeName . Text.pack . getUnicodeString <$> arbitrary + From ca8d84fe5f80b2a2aebb7398508927585d8b0ae6 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 15 Aug 2025 13:07:38 +0200 Subject: [PATCH 4/5] feat[core]: datatypes in modules --- src/Language/Scalie/Core/Module.hs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Language/Scalie/Core/Module.hs b/src/Language/Scalie/Core/Module.hs index b344fa7..2516038 100644 --- a/src/Language/Scalie/Core/Module.hs +++ b/src/Language/Scalie/Core/Module.hs @@ -5,10 +5,16 @@ {-# LANGUAGE UndecidableInstances #-} -- instance head no smaller... module Language.Scalie.Core.Module (Module(..)) where +-- meta import Data.Kind (Type) -import Language.Scalie.Core.Definition (Definition) + +-- data types import Data.Map.Implicit (ImplicitMap) +-- scalie +import Language.Scalie.Core.Definition (Definition) +import safe Language.Scalie.Core.AlgebraicDatatype ( AlgebraicDatatype ) + -- | A module groups multiple related variable definitions. -- -- >>> import Data.Functor.Identity (Identity(..)) @@ -29,9 +35,10 @@ import Data.Map.Implicit (ImplicitMap) type Module :: (Type -> Type) -> Type type role Module nominal -newtype Module f = Module +data Module f = Module { definitions :: f (ImplicitMap (Definition f)) + , datatypes :: f (ImplicitMap (AlgebraicDatatype f)) } -deriving stock instance (Show (f (ImplicitMap (Definition f)))) => Show (Module f) -deriving stock instance (Read (f (ImplicitMap (Definition f)))) => Read (Module f) +deriving stock instance (Show (f (ImplicitMap (Definition f))), Show (f (ImplicitMap (AlgebraicDatatype f)))) => Show (Module f) +deriving stock instance (Read (f (ImplicitMap (Definition f))), Read (f (ImplicitMap (AlgebraicDatatype f)))) => Read (Module f) From 6a28e979872b9c4c58bdef731a7047934889d09e Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 15 Aug 2025 13:07:56 +0200 Subject: [PATCH 5/5] doc[core]: remove old read/show examples --- src/Language/Scalie/Core/Module.hs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Language/Scalie/Core/Module.hs b/src/Language/Scalie/Core/Module.hs index 2516038..6266529 100644 --- a/src/Language/Scalie/Core/Module.hs +++ b/src/Language/Scalie/Core/Module.hs @@ -16,22 +16,6 @@ import Language.Scalie.Core.Definition (Definition) import safe Language.Scalie.Core.AlgebraicDatatype ( AlgebraicDatatype ) -- | A module groups multiple related variable definitions. --- --- >>> import Data.Functor.Identity (Identity(..)) --- >>> import Data.Map.Implicit qualified as ImplicitMap --- >>> Module (Identity ImplicitMap.empty) --- Module {definitions = Identity ImplicitMapElems []} --- --- >>> import Data.Maybe (Maybe(..)) --- >>> Module Nothing --- Module {definitions = Nothing} --- --- >>> import Text.Read (readMaybe) --- >>> readMaybe "Module { definitions = Just (ImplicitMapElems []) }" :: Maybe (Module Maybe) --- Just (Module {definitions = Just ImplicitMapElems []}) --- --- >>> readMaybe "Module { definitions = Just (ImplicitMapElems [Definition { signature = Nothing, name = Just \"x\", body = Nothing } ]) }" :: Maybe (Module Maybe) --- Just (Module {definitions = Just ImplicitMapElems [Definition {signature = Nothing, name = Just "x", body = Nothing}]}) type Module :: (Type -> Type) -> Type type role Module nominal