Add types for name analysis

This commit is contained in:
2024-07-26 12:22:07 +02:00
parent bf774475cc
commit ce7652c618
7 changed files with 130 additions and 32 deletions

View File

@ -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

View File

@ -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]

View File

@ -0,0 +1,3 @@
module Language.Elna.NameAnalysis
(
) where

View File

@ -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)

View File

@ -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)