diff --git a/doc/libraries.org b/doc/libraries.org index 8e1367d..8823e17 100644 --- a/doc/libraries.org +++ b/doc/libraries.org @@ -1,5 +1,7 @@ #+title: on libraries +* libraries and the file system + R⁷RS leaves it unspecified how exactly libraries correspond to files: #+begin_quote @@ -7,3 +9,11 @@ Programs and libraries are typically stored in files, although in some implement #+end_quote thus the implementation of ~define-library~ is open to much interpretation. we could possibly define libraries as first-class objects, or deal with them statically. the former case is appealing to me, as it could massively simplify interactive use. + +* semantics of declaration order + +mercifully, R⁷RS is similarly ambiguous when it comes to the significance of declaration order. the authors note explicitly example two equally acceptable approaches: + +#+begin_quote +One possible implementation of libraries is as follows: _After all cond-expand library declarations are expanded, a new environment is constructed for the library consisting of all imported bindings._ The expressions from all begin, include and include-ci library declarations are expanded in that environment in the order in which they occur in the library. _Alternatively, cond-expand and import declarations may be processed in left to right order interspersed with the processing of other declarations_, with the environment growing as imported bindings are added to it by each import declaration. +#+end_quote diff --git a/gyehoek.cabal b/gyehoek.cabal index b75cfcc..b4c6693 100644 --- a/gyehoek.cabal +++ b/gyehoek.cabal @@ -66,6 +66,7 @@ library Gyehoek.GenSym Gyehoek.Jalmot Gyehoek.Language + Gyehoek.Language.Common Gyehoek.Lift1 Gyehoek.Options Gyehoek.Prelude @@ -111,17 +112,17 @@ library , process , recursion-schemes , scientific + , semialign , string-interpolate , tardis , template-haskell , text , text-short + , these , typed-process , unordered-containers , vector , witherable - , semialign - , these hs-source-dirs: src default-language: GHC2024 diff --git a/src/Gyehoek/Language/Common.hs b/src/Gyehoek/Language/Common.hs new file mode 100644 index 0000000..14d7c57 --- /dev/null +++ b/src/Gyehoek/Language/Common.hs @@ -0,0 +1,64 @@ +{-# LANGUAGE DeriveAnyClass #-} +module Gyehoek.Language.Common + ( + -- * Syntax + Lib(..) + , LibName(..) + , Exports + , Imports + , ExternName(..) + , Name(..) + ) where + +import Gyehoek.Prelude +import Data.String (IsString) +import Gyehoek.GenSym (Gen) +import qualified Gyehoek.Sexp as S + + +-- | R⁷RS 라이프러리의 표현. +data Lib name body = MkLib + { name :: LibName + , exports :: Exports name + , imports :: Imports name + } + deriving (Show) + +newtype LibName = MkLibName { getLibName :: NonEmpty Text } + deriving stock (Show, Generic, Data, Eq) + deriving anyclass (NFData, Hashable) + +-- | A map whose keys are names of library definitions and whose +-- values are the names they are exported as. An @⟨identifier⟩@ @x@ +-- corresponds to an entry @(⟨identifier⟩, ⟨identifier⟩)@, while a +-- @(rename ⟨identifier₁⟩ ⟨identifier₂⟩)@ form corresponds to an entry +-- @(⟨identifier₁⟩, ⟨identifier₂⟩)@. +type Exports name = HashMap name ExternName + +-- | A map whose keys are symbols to be brought into the library's +-- environment and whose values are pairs of the library in which the +-- symbol is defined and the name the symbol is exported as. +type Imports name = HashMap name (LibName, ExternName) + +-- | Representation of an identifier at the library boundary. While +-- 'Name's are used within a compilation unit and may be decorated +-- with additional structure and metadata, they are exported as +-- 'ExternName's, which are essentially just plain strings. +newtype ExternName = MkExternName { getExternName :: Text } + deriving newtype (Show) + +newtype Name = MkName { inner :: Text } + deriving newtype (Show, Eq, Ord, IsString, Gen, Hashable) + deriving stock (Generic, Data) + deriving anyclass (Wrapped, NFData) + +instance Prefixed Name where + prefixed (MkName s) = _Wrapped' . prefixed @Text s . from _Wrapped' + + +--- DatumIsos + +instance S.DatumIso Name where + datumIso = S.decorate S.SynVariable + >>> S.symbol + >>> S.iso coerce coerce