Skip to content

Commit a7ceb53

Browse files
committed
Almost done
1 parent d9056e8 commit a7ceb53

File tree

7 files changed

+130
-59
lines changed

7 files changed

+130
-59
lines changed

app/Main.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,8 @@ repl = runInputT defaultSettings (loop firstModule)
4242
liftError :: ExceptT String IO a -> IO a
4343
liftError = runExceptT >=> either fail return
4444

45+
filesrc :: FilePath
46+
filesrc = "input.txt"
47+
48+
processFile :: IO (Maybe ASTL.Module)
49+
processFile = (readFile filesrc >>= eval firstModule)

src/AST.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ data Op
8181
| Mul
8282
| Divide
8383
| Null
84+
| LessThan
8485
deriving (Show, Ord, Eq)
8586

8687
data Type

src/CodeGen.hs

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,48 @@
22
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
33

44
module CodeGen (
5-
LLVM(..),
5+
LLVM(..),
66
runLLVM,
7+
execCodegen,
8+
79
define,
810
addDef,
9-
getDef,
11+
1012
getType,
1113
getName,
1214
intL,
1315
getArgList,
16+
17+
Codegen(..),
1418
Names(..),
19+
CodegenState(..),
20+
BlockState(..),
21+
unikName,
22+
1523
load,
1624
store,
1725
local,
1826
terminator,
1927
ret,
2028
getvar,
2129
assign,
22-
createBlocks,
23-
external,
24-
Codegen(..),
25-
CodegenState(..),
26-
BlockState(..),
27-
instr,
2830
alloca,
29-
execCodegen,
31+
instr,
32+
external,
33+
34+
createBlocks,
3035
setBlock,
31-
getBlock,
3236
emptyBlock,
33-
unikName,
3437
entryBlockName,
38+
39+
getBlock,
40+
3541
br,
3642
phi,
3743
cbr,
38-
fcmp
39-
44+
fcmp,
45+
uitofp
46+
4047
)where
4148

4249

@@ -71,17 +78,17 @@ import qualified AST as ASTLp
7178

7279

7380

74-
-- -- 1. Variable Declaration Done
75-
-- var = GLB.globalVariableDefaults { name = "Var1", GLB.type' = int }
81+
-- | utility Functions for Working on Module
82+
-- | LLVM monad to manage the contained LLVM module State
7683

77-
-- | Utility Functions for Working on Module
7884
newtype LLVM a = LLVM (State ASTL.Module a)
7985
deriving (Functor, Applicative, Monad, MonadState ASTL.Module )
8086

87+
-- | execute the given LLVM State with the given module as state
8188
runLLVM :: ASTL.Module -> LLVM a -> ASTL.Module
8289
runLLVM mod (LLVM m) = execState m mod
8390

84-
-- Defines a function here the return type is Type
91+
-- | Action to add a function to state
8592
define :: ASTL.Type -> String -> [(ASTL.Type, ASTL.Name)] -> [ASTL.BasicBlock] -> LLVM ()
8693
define retty label argtys body = addDef $
8794
ASTL.GlobalDefinition $ functionDefaults {
@@ -92,18 +99,18 @@ define retty label argtys body = addDef $
9299
}
93100

94101

95-
-- | Defines a function here the return type is Type
102+
-- | Action to add external function
96103
external :: ASTL.Type -> String -> [(ASTL.Type, ASTL.Name)] -> LLVM ()
97104
external retty label argtys = define retty label argtys []
98105

106+
-- | Action to add definition to the LLVM state
99107
addDef :: ASTL.Definition -> LLVM ()
100108
addDef def = do
101109
prev <- gets ASTL.moduleDefinitions
102110
modify $ \s -> s { ASTL.moduleDefinitions = prev ++ [def] }
111+
------------------------------------------------
103112

104113

105-
-- | BackEnd
106-
-- From Parsed ASTL to LLVM Definitions
107114
getDef :: ASTLp.Func -> ASTL.Definition
108115
getDef (ASTLp.Func fname farg fret fbody ) = ASTL.GlobalDefinition $ functionDefaults {
109116
name = getName fname,
@@ -120,6 +127,7 @@ getExtern (ASTLp.ExternDecl fname fargs fret) =
120127
})
121128

122129

130+
-- | Utility Function for conversion and constant
123131
getType :: ASTLp.Type -> TypeQ.Type
124132
getType ASTLp.IntC = ASTL.IntegerType 32
125133

@@ -131,46 +139,51 @@ intL = ASTL.IntegerType 32
131139

132140
getArgList :: ASTLp.ArgList -> [(ASTL.Type, ASTL.Name)]
133141
getArgList = map (\(t, n) -> (getType t, getName n))
142+
------------------------------------------------
134143

135144

136-
type Names = Map.Map String Int
137145

138146

139-
-- Takes a name and check if present in names and then checks if the name already there or not.
147+
-- | Takes a name and check if present in names and then checks if the name already there or not.
140148
-- returns updated map and prev. name if any otherwise the name itself.
141-
-- Can be used to ask if this name is avaible and if so then use it otherwise it returns you
142-
-- an updated name that can be used.
143149
unikName :: String -> Names -> (String, Names)
144150
unikName name mapping = case Map.lookup name mapping of
145151
Nothing -> (name, Map.insert name 1 mapping)
146152
Just idx -> (name ++ (show idx) , Map.insert name (idx+1) mapping)
147153

148-
type SymbolTable = [(String, ASTL.Operand)]
149154

155+
-- | Data Structure that the State stores inside the LLVM monad
156+
type Names = Map.Map String Int
157+
type SymbolTable = [(String, ASTL.Operand)]
150158

151159

152160

161+
-- | A CodegenState represent a file/ code file and the current execution block
153162
data CodegenState
154163
= CodegenState {
155164
currentBlock :: ASTL.Name -- Name of the active block to append to
156165
, blocks :: Map.Map ASTL.Name BlockState -- Blocks for function
157-
, symtab :: SymbolTable -- Function scope symbol table
158-
, blockCount :: Int -- Count of basic blocks
159-
, count :: Word -- Count of unnamed instructions a.k.a like function args
160-
, names :: Names -- Name Supply
166+
, symtab :: SymbolTable -- Function scope symbol table
167+
, blockCount :: Int -- Count of basic blocks
168+
, count :: Word -- Count of unnamed instructions a.k.a like function args
169+
, names :: Names -- Name Supply
161170
} deriving Show
162171

172+
-- | A BlockState represent a function section
163173
data BlockState
164174
= BlockState {
165-
idx :: Int -- Block index
175+
idx :: Int -- Block index
166176
, stack :: [ASTL.Named ASTL.Instruction] -- Stack of instructions Head --> |_| |_| |_| |_|
167177
, term :: Maybe (ASTL.Named ASTL.Terminator) -- Block terminator
168178
} deriving Show
169179

170180

181+
-- | A action executor on LLVM state
171182
newtype Codegen a = Codegen { runCodegen :: State CodegenState a }
172183
deriving (Functor, Applicative, Monad, MonadState CodegenState )
173184

185+
------------------------------- Block Operations ------------------------
186+
174187
sortBlocks :: [(ASTL.Name, BlockState)] -> [(ASTL.Name, BlockState)]
175188
sortBlocks = sortBy (compare `on` (idx . snd))
176189

@@ -189,22 +202,24 @@ entryBlockName = "entry"
189202
emptyBlock :: Int -> BlockState
190203
emptyBlock i = BlockState i [] Nothing
191204

192-
emptyCodegen :: CodegenState
193-
emptyCodegen = CodegenState (ASTL.Name entryBlockName) Map.empty [] 1 0 Map.empty
194-
195-
execCodegen :: Codegen a -> CodegenState
196-
execCodegen m = execState (runCodegen m) emptyCodegen
197-
198-
199-
------------------------------- Block Operations ------------------------
200205

201-
-- Modifies the current block that is being used using the block name arg.
206+
-- | Modifies the current block that is being used using the block name arg.
202207
-- Returns the input bname after successfull updation
203208
setBlock :: ASTL.Name -> Codegen ASTL.Name
204209
setBlock bname = do
205210
modify $ \s -> s { currentBlock = bname }
206211
return bname
207212

213+
------------------------------------------------------------------------
214+
215+
------------------------- CodeGen constants and actions ---------------
216+
217+
emptyCodegen :: CodegenState
218+
emptyCodegen = CodegenState (ASTL.Name entryBlockName) Map.empty [] 1 0 Map.empty
219+
220+
execCodegen :: Codegen a -> CodegenState
221+
execCodegen m = execState (runCodegen m) emptyCodegen
222+
208223
getBlock :: Codegen ASTL.Name
209224
getBlock = gets currentBlock
210225

@@ -224,13 +239,12 @@ fresh = do
224239

225240
instr :: ASTL.Instruction -> Codegen (ASTL.Operand)
226241
instr ins = do
227-
n <- fresh -- Updated the count of variables/ n=count
228-
let ref = (ASTL.UnName n) -- a number for a nameless thing
229-
blk <- current -- got the current blockState
230-
let i = stack blk -- Got the list of statements
231-
modifyBlock (blk { stack = (ref := ins) : i } ) -- (ref := ins ) is a Named Instruction with name ref and ins and instruction
232-
return $ local ref -- Returning the operands
233-
242+
n <- fresh -- Updated the count of variables/ n=count
243+
let ref = (ASTL.UnName n) -- a number for a nameless thing
244+
blk <- current -- got the current blockState
245+
let i = stack blk -- Got the list of statements
246+
modifyBlock (blk { stack = (ref := ins) : i } ) -- (ref := ins ) is a Named Instruction with name ref and ins and instruction
247+
return $ local ref -- Returning the operands
234248

235249

236250
current :: Codegen BlockState
@@ -243,7 +257,7 @@ current = do
243257

244258

245259

246-
-- Updating the blocks with due to addition of named instructions
260+
-- | Updating the blocks with due to addition of named instructions
247261
-- Simply replacing whole prev block with the new one
248262
modifyBlock :: BlockState -> Codegen ()
249263
modifyBlock new = do
@@ -253,7 +267,6 @@ modifyBlock new = do
253267

254268

255269

256-
257270
-- | Update the symbol table with the current value and identifier
258271
assign :: String -> ASTL.Operand -> Codegen ()
259272
assign var x = do
@@ -268,23 +281,22 @@ getvar var = do
268281
Nothing -> error $ "Local variable not in scope: " ++ show var
269282

270283

271-
272-
-- Takes the operand and create a terminator based on that .
284+
-- | Takes the operand and create a terminator based on that .
273285
-- Do simply names the instruction
274286
-- terminator just uplift the value further to Codegen while updating the blockState
275287
ret :: ASTL.Operand -> Codegen (ASTL.Named ASTL.Terminator)
276288
ret val = terminator $ ASTL.Do $ ASTL.Ret (Just val) []
277289

278290

279-
-- Update the terminator of the current active block
291+
-- | Update the terminator of the current active block
280292
terminator :: ASTL.Named ASTL.Terminator -> Codegen (ASTL.Named ASTL.Terminator)
281293
terminator trm = do
282294
blk <- current
283295
modifyBlock (blk { term = Just trm })
284296
return trm
285297

286298

287-
-- Takes a name and gives you an operands
299+
-- | Takes a name and gives you an operands
288300
local :: ASTL.Name -> ASTL.Operand
289301
local = ASTL.LocalReference intL
290302

@@ -308,4 +320,7 @@ phi :: ASTL.Type -> [(ASTL.Operand, ASTL.Name)] -> Codegen ASTL.Operand
308320
phi ty incoming = instr $ ASTL.Phi ty incoming []
309321

310322
fcmp :: IP.IntegerPredicate -> ASTL.Operand -> ASTL.Operand -> Codegen ASTL.Operand
311-
fcmp cond a b = instr $ ICmp cond a b []
323+
fcmp cond a b = instr $ ICmp cond a b []
324+
325+
uitofp :: ASTL.Type -> ASTL.Operand -> Codegen ASTL.Operand
326+
uitofp ty a = instr $ ASTL.UIToFP a ty []

src/Emit.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Emit (
77
fsub,
88
fmul,
99
fdiv,
10+
lesser,
1011

1112
exprGen,
1213
binOpCallGen,
@@ -71,6 +72,7 @@ binops = Map.fromList [
7172
, (ASTp.Minus, fsub)
7273
, (ASTp.Mul, fmul)
7374
, (ASTp.Divide, fdiv)
75+
, (ASTp.LessThan, lesser)
7476
]
7577

7678

@@ -87,6 +89,11 @@ fmul a b = instr $ ASTL.Mul False False a b []
8789
fdiv :: ASTL.Operand -> ASTL.Operand -> Codegen ASTL.Operand
8890
fdiv a b = instr $ ASTL.UDiv False a b []
8991

92+
lesser :: ASTL.Operand -> ASTL.Operand -> Codegen ASTL.Operand
93+
lesser a b = do
94+
test <- fcmp IP.ULT a b
95+
uitofp intL test
96+
9097
externf :: ASTL.Name -> ASTL.Operand
9198
externf = ConstantOperand . C.GlobalReference intL
9299

src/Language.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ haskullstyle = emptyDef {
2828

2929
-- | The language definition for the Haskull language.
3030
haskulldef = haskullstyle {
31-
reservedOpNames = ["+", "/", "-", "*", ";", "="],
31+
reservedOpNames = ["+", "/", "-", "*", ";", "=", "<"],
3232
reservedNames = ["int", "char", "def", "extern", "string","if","then","else"]
3333
}
3434

src/Parser.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
module Parser (
22
moduleParser,
33
funcParser,
4-
ifthenParser
4+
ifthenParser,
5+
binOpCallStmtParser,
6+
binOpCallParser,
7+
literalStmtParser,
8+
funcCallStmtParser
59
)where
610

711
import Lexer

0 commit comments

Comments
 (0)