Skip to content

Commit c273ea2

Browse files
committed
Use ByteString
1 parent ce886e2 commit c273ea2

File tree

6 files changed

+122
-22
lines changed

6 files changed

+122
-22
lines changed

kaleidoscope-hs/app/Main.hs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
module Main where
22

3-
import Control.Monad.Trans
4-
import Data.Text (Text)
3+
import Control.Monad.Trans ( MonadIO(liftIO) )
4+
import Data.ByteString.UTF8 (ByteString)
5+
import Data.ByteString.UTF8 qualified as ByteString
56
import Data.Text qualified as Text
67
import Data.Text.IO qualified as Text
78
import System.Console.Haskeline qualified as Haskeline
89

910
import AST.Parse qualified as Parse
1011

11-
process :: Text -> IO ()
12+
process :: ByteString -> IO ()
1213
process line = do
1314
let res = Parse.parse line
1415
case res of
@@ -26,7 +27,8 @@ main =
2627
Nothing ->
2728
Haskeline.outputStrLn "Goodbye."
2829
Just input -> do
29-
liftIO (process (Text.pack input))
30+
let inputBS = ByteString.fromString input
31+
liftIO (process inputBS)
3032
loop
3133
in
3234
Haskeline.runInputT Haskeline.defaultSettings loop

kaleidoscope-hs/kaleidoscope-hs.cabal

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ source-repository head
2525

2626
library
2727
exposed-modules:
28+
AST.Codegen
2829
AST.Parse
2930
AST.Syntax
3031
other-modules:
@@ -72,13 +73,16 @@ library
7273
StrictData
7374
build-depends:
7475
base >=4.7 && <5
76+
, bytestring
7577
, containers
7678
, haskeline
7779
, llvm-hs
80+
, llvm-hs-pure
7881
, megaparsec
7982
, mtl
8083
, parser-combinators
8184
, text
85+
, utf8-string
8286
default-language: Haskell2010
8387

8488
executable kaleidoscope-hs-exe
@@ -129,14 +133,17 @@ executable kaleidoscope-hs-exe
129133
ghc-options: -threaded -rtsopts -with-rtsopts=-N
130134
build-depends:
131135
base >=4.7 && <5
136+
, bytestring
132137
, containers
133138
, haskeline
134139
, kaleidoscope-hs
135140
, llvm-hs
141+
, llvm-hs-pure
136142
, megaparsec
137143
, mtl
138144
, parser-combinators
139145
, text
146+
, utf8-string
140147
default-language: Haskell2010
141148

142149
test-suite kaleidoscope-hs-test
@@ -188,12 +195,15 @@ test-suite kaleidoscope-hs-test
188195
ghc-options: -threaded -rtsopts -with-rtsopts=-N
189196
build-depends:
190197
base >=4.7 && <5
198+
, bytestring
191199
, containers
192200
, haskeline
193201
, kaleidoscope-hs
194202
, llvm-hs
203+
, llvm-hs-pure
195204
, megaparsec
196205
, mtl
197206
, parser-combinators
198207
, text
208+
, utf8-string
199209
default-language: Haskell2010

kaleidoscope-hs/package.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ description: Please see the README on GitHub at <https://github.com/gith
2121

2222
dependencies:
2323
- base >= 4.7 && < 5
24+
- bytestring
25+
- utf8-string
2426
- containers
2527
- haskeline
2628
- llvm-hs
29+
- llvm-hs-pure
2730
- megaparsec
2831
- mtl
2932
- parser-combinators

kaleidoscope-hs/src/AST/Codegen.hs

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
module AST.Codegen where
2+
3+
import Data.ByteString (ByteString)
4+
import Data.ByteString qualified as ByteString
5+
import Data.ByteString.Short qualified as ByteString.Short
6+
import Data.Map (Map)
7+
import Data.Map qualified as Map
8+
9+
import Control.Monad.State (State, MonadState)
10+
import Control.Monad.State qualified as State
11+
12+
import LLVM.AST qualified as LLVM
13+
import LLVM.AST.Global qualified as LLVM
14+
import LLVM.AST.Linkage qualified as Linkage
15+
import LLVM.AST.Constant qualified as Constant
16+
import LLVM.AST.Attribute qualified as Attribute
17+
import LLVM.AST.CallingConvention qualified as Convention
18+
import LLVM.AST.FloatingPointPredicate as FloatingPoint
19+
20+
import AST.Syntax (Expr, BinOp)
21+
import AST.Syntax qualified as Syntax
22+
23+
-------------------------------------------------------------------------------
24+
25+
double :: LLVM.Type
26+
double = LLVM.FloatingPointType LLVM.DoubleFP
27+
28+
-------------------------------------------------------------------------------
29+
30+
type Names = Map ByteString Int
31+
32+
type SymbolTable = Map ByteString LLVM.Operand
33+
34+
data CodegenState = CodegenState
35+
{ currentBlock :: LLVM.Name -- Name of the active block to append to
36+
, blocks :: Map LLVM.Name BlockState -- Blocks for function
37+
, symbols :: SymbolTable -- Function scope symbol table
38+
, blockCount :: Int -- Count of basic blocks
39+
, count :: Word -- Count of unnamed instructions
40+
, names :: Names -- Name Supply
41+
}
42+
deriving Show
43+
44+
data BlockState = BlockState
45+
{ idx :: Int -- Block index
46+
, stack :: [LLVM.Named LLVM.Instruction] -- Stack of instructions
47+
, term :: Maybe (LLVM.Named LLVM.Terminator) -- Block terminator
48+
}
49+
deriving Show
50+
51+
newtype Codegen a = Codegen (State CodegenState a)
52+
deriving (Functor, Applicative, Monad, MonadState CodegenState)
53+
54+
newtype LLVMState a = LLVMState (State LLVM.Module a)
55+
deriving (Functor, Applicative, Monad, MonadState LLVM.Module)
56+
57+
runLLVM :: LLVM.Module -> LLVMState a -> LLVM.Module
58+
runLLVM mod (LLVMState llvm) = State.execState llvm mod
59+
60+
emptyModule :: ByteString -> LLVM.Module
61+
emptyModule label = LLVM.defaultModule
62+
{ LLVM.moduleName = ByteString.Short.toShort label
63+
}

kaleidoscope-hs/src/AST/Parse.hs

+38-15
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ module AST.Parse
55
) where
66

77
import Control.Monad.Combinators.Expr qualified as Combinators
8+
import Data.ByteString (ByteString)
9+
import Data.ByteString qualified as ByteString
810
import Data.Char qualified as Char
911
import Data.Function ((&))
1012
import Data.List (foldl')
@@ -14,43 +16,64 @@ import Data.Set qualified as Set
1416
import Data.Text (Text)
1517
import Data.Text qualified as Text
1618
import Data.Void (Void)
19+
import Data.Word (Word8)
1720
import Text.Megaparsec (Parsec, (<?>))
1821
import Text.Megaparsec qualified as Parsec
19-
import Text.Megaparsec.Char qualified as ParsecChar
20-
import Text.Megaparsec.Char.Lexer qualified as Lexer
22+
import Text.Megaparsec.Byte qualified as Parsec.Byte
23+
import Text.Megaparsec.Byte.Lexer qualified as Lexer
2124
import Text.Megaparsec.Error qualified as ParsecError
2225

2326
import AST.Syntax (Name, Expr)
2427
import AST.Syntax qualified as Syntax
2528

2629
--------------------------------------------------------------------------------
2730

28-
type Parser a = Parsec Void Text a
31+
type Parser a = Parsec Void ByteString a
2932

3033
newtype Error = Error Text
3134

3235
--------------------------------------------------------------------------------
3336

37+
isUpper :: Word8 -> Bool
38+
isUpper c = 65 <= c && c <= 90
39+
40+
isLower :: Word8 -> Bool
41+
isLower c = 97 <= c && c <= 122
42+
43+
isAlpha :: Word8 -> Bool
44+
isAlpha c = isUpper c || isLower c
45+
46+
isSpace :: Word8 -> Bool
47+
isSpace c = c == 9 || c == 10 || c == 13 || c == 32
48+
49+
isNumber :: Word8 -> Bool
50+
isNumber c = 48 <= c && c <= 57
51+
52+
underscore :: Word8
53+
underscore = 95
54+
55+
--------------------------------------------------------------------------------
56+
3457
space :: Parser ()
3558
space =
3659
Lexer.space
37-
ParsecChar.space1
60+
Parsec.Byte.space1
3861
(Lexer.skipLineComment "//")
3962
(Lexer.skipBlockComment "/*" "*/")
4063

4164
lexeme :: Parser a -> Parser a
4265
lexeme =
4366
Lexer.lexeme space
4467

45-
symbol :: Text -> Parser ()
68+
symbol :: ByteString -> Parser ()
4669
symbol s =
4770
() <$ Lexer.symbol space s
4871

4972
float :: Parser Double
5073
float =
5174
lexeme Lexer.float
5275

53-
keywords :: Set Text
76+
keywords :: Set ByteString
5477
keywords = Set.fromList
5578
[ "if"
5679
, "then"
@@ -59,26 +82,26 @@ keywords = Set.fromList
5982
, "extern"
6083
]
6184

62-
keyword :: Text -> Parser ()
85+
keyword :: ByteString -> Parser ()
6386
keyword str =
6487
lexeme $
65-
() <$ ParsecChar.string str
66-
<* Parsec.notFollowedBy ParsecChar.alphaNumChar
88+
() <$ Parsec.Byte.string str
89+
<* Parsec.notFollowedBy Parsec.Byte.alphaNumChar
6790

68-
identifierOrKeyword :: Parser Text
91+
identifierOrKeyword :: Parser ByteString
6992
identifierOrKeyword =
7093
let
7194
alphaChar =
7295
Parsec.satisfy
73-
(\c -> (Char.isAlpha c || c == '_') && Char.isAscii c)
96+
(\c -> isAlpha c || c == underscore)
7497
<?> "alphabet"
7598

7699
alphaNumChars =
77100
Parsec.takeWhileP
78101
(Just "alphabets or numbers")
79-
(\c -> (Char.isAlpha c || Char.isNumber c || c == '_') && Char.isAscii c)
102+
(\c -> isAlpha c || isNumber c || c == underscore)
80103
in
81-
lexeme (Text.cons <$> alphaChar <*> alphaNumChars)
104+
lexeme (ByteString.cons <$> alphaChar <*> alphaNumChars)
82105

83106
identifier :: Parser Name
84107
identifier =
@@ -87,7 +110,7 @@ identifier =
87110
word <- identifierOrKeyword
88111
if Set.member word keywords then
89112
let
90-
actual = ParsecError.Tokens (NonEmpty.fromList (Text.unpack word))
113+
actual = ParsecError.Tokens (NonEmpty.fromList (ByteString.unpack word))
91114
expected = ParsecError.Label (NonEmpty.fromList "identifier")
92115
err = ParsecError.TrivialError offset (Just actual) (Set.singleton expected)
93116
in
@@ -172,7 +195,7 @@ toplevel =
172195
*> Parsec.many (defn <* symbol ";")
173196
<* Parsec.eof
174197

175-
parse :: Text -> Either Error [Expr]
198+
parse :: ByteString -> Either Error [Expr]
176199
parse source =
177200
case Parsec.parse toplevel "<stdin>" source of
178201
Left errors ->

kaleidoscope-hs/src/AST/Syntax.hs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
module AST.Syntax where
22

3-
import Data.Text (Text)
4-
import Data.Text qualified as Text
3+
import Data.ByteString.Char8 (ByteString)
54

6-
type Name = Text
5+
type Name = ByteString
76

87
data Expr
98
= Float Double

0 commit comments

Comments
 (0)