From ce7652c6189b289ffbc749dc3d1ffb465c758c01 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 26 Jul 2024 12:22:07 +0200 Subject: Add types for name analysis --- lib/Language/Elna/AST.hs | 22 +++------------ lib/Language/Elna/Location.hs | 58 +++++++++++++++++++++++++++++++++++++++ lib/Language/Elna/NameAnalysis.hs | 3 ++ lib/Language/Elna/Parser.hs | 2 +- lib/Language/Elna/SymbolTable.hs | 45 ++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 19 deletions(-) create mode 100644 lib/Language/Elna/Location.hs create mode 100644 lib/Language/Elna/NameAnalysis.hs create mode 100644 lib/Language/Elna/SymbolTable.hs (limited to 'lib/Language/Elna') diff --git a/lib/Language/Elna/AST.hs b/lib/Language/Elna/AST.hs index 3189469..189fcb5 100644 --- a/lib/Language/Elna/AST.hs +++ b/lib/Language/Elna/AST.hs @@ -12,34 +12,20 @@ module Language.Elna.AST import Data.Int (Int32) import Data.List (intercalate) -import Data.Word (Word16) -import Data.Text (Text) -import qualified Data.Text as Text +import Data.Word (Word16, Word32) import Data.Char (chr) -import Data.String (IsString(..)) +import Language.Elna.Location (Identifier(..), showArrayType) import Numeric (showHex) -newtype Identifier = Identifier { unIdentifier :: Text } - deriving Eq - -instance Show Identifier - where - show (Identifier identifier) = Text.unpack identifier - -instance IsString Identifier - where - fromString = Identifier . Text.pack - data TypeExpression = NamedType Identifier - | ArrayType TypeExpression Int32 + | ArrayType Word32 TypeExpression deriving Eq instance Show TypeExpression where show (NamedType typeName) = show typeName - show (ArrayType typeName elementCount) = concat - [show typeName, "[", show elementCount, "]"] + show (ArrayType elementCount typeName) = showArrayType elementCount typeName data Literal = IntegerLiteral Int32 diff --git a/lib/Language/Elna/Location.hs b/lib/Language/Elna/Location.hs new file mode 100644 index 0000000..918ef46 --- /dev/null +++ b/lib/Language/Elna/Location.hs @@ -0,0 +1,58 @@ +module Language.Elna.Location + ( Identifier(..) + , Location(..) + , Node(..) + , showArrayType + ) where + +import Data.Hashable (Hashable(..)) +import Data.String (IsString(..)) +import Data.Text (Text) +import qualified Data.Text as Text +import Data.Word (Word32) + +data Location = Location + { line :: Word32 + , column :: Word32 + } deriving (Eq, Show) + +instance Semigroup Location + where + (Location thisLine thisColumn) <> (Location thatLine thatColumn) = Location + { line = thisLine + thatLine + , column = thisColumn + thatColumn + } + +instance Monoid Location + where + mempty = Location{ line = 1, column = 1 } + +data Node a = Node a Location + deriving (Eq, Show) + +instance Functor Node + where + fmap f (Node node location) = Node (f node) location + +newtype Identifier = Identifier { unIdentifier :: Text } + deriving Eq + +instance Show Identifier + where + show (Identifier identifier) = Text.unpack identifier + +instance IsString Identifier + where + fromString = Identifier . Text.pack + +instance Ord Identifier + where + compare (Identifier lhs) (Identifier rhs) = compare lhs rhs + +instance Hashable Identifier + where + hashWithSalt salt (Identifier identifier) = hashWithSalt salt identifier + +showArrayType :: Show a => Word32 -> a -> String +showArrayType elementCount typeName = concat + ["array[", show elementCount, "] of ", show typeName] diff --git a/lib/Language/Elna/NameAnalysis.hs b/lib/Language/Elna/NameAnalysis.hs new file mode 100644 index 0000000..7388851 --- /dev/null +++ b/lib/Language/Elna/NameAnalysis.hs @@ -0,0 +1,3 @@ +module Language.Elna.NameAnalysis + ( + ) where diff --git a/lib/Language/Elna/Parser.hs b/lib/Language/Elna/Parser.hs index 109f1ba..23e09d9 100644 --- a/lib/Language/Elna/Parser.hs +++ b/lib/Language/Elna/Parser.hs @@ -80,7 +80,7 @@ typeExpressionP = arrayTypeExpression <|> NamedType <$> identifierP "type expression" where - arrayTypeExpression = flip ArrayType + arrayTypeExpression = ArrayType <$> (symbol "array" *> bracketsP (lexeme Lexer.decimal)) <*> (symbol "of" *> typeExpressionP) diff --git a/lib/Language/Elna/SymbolTable.hs b/lib/Language/Elna/SymbolTable.hs new file mode 100644 index 0000000..a33df44 --- /dev/null +++ b/lib/Language/Elna/SymbolTable.hs @@ -0,0 +1,45 @@ +module Language.Elna.SymbolTable + ( Info(..) + , ParameterInfo(..) + , SymbolTable(..) + , Type(..) + , booleanType + , intType + ) where + +import Data.HashMap.Strict (HashMap) +import Data.Text (Text) +import Data.Vector (Vector) +import Data.Word (Word32) +import Language.Elna.Location (Identifier(..), showArrayType) + +data Type + = PrimitiveType Text + | ArrayType Word32 Type + deriving Eq + +instance Show Type + where + show (PrimitiveType typeName) = show typeName + show (ArrayType elementCount typeName) = showArrayType elementCount typeName + +intType :: Type +intType = PrimitiveType "int" + +booleanType :: Type +booleanType = PrimitiveType "boolean" + +newtype SymbolTable = SymbolTable (HashMap Identifier Info) + deriving (Eq, Show) + +data ParameterInfo = ParameterInfo + { name :: Identifier + , type' :: Type + , isReferenceParameter :: Bool + } deriving (Eq, Show) + +data Info + = TypeInfo Type + | VariableInfo Type Bool + | ProcedureInfo SymbolTable (Vector ParameterInfo) + deriving (Eq, Show) -- cgit v1.2.3