Skip to content

Commit 1a478ca

Browse files
committed
Added Repl, some LLVM funnctions and binary op bug fixs
1 parent 0ae4829 commit 1a478ca

File tree

5 files changed

+354
-112
lines changed

5 files changed

+354
-112
lines changed

src/AST.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ module AST (
99
Args,
1010
Declaration(..),
1111
BinOpCall(..),
12+
Func(..),
13+
Module(..),
1214
FuncCall(..)
1315
) where
1416

@@ -43,9 +45,15 @@ module AST (
4345
-- Name : ident
4446
-- ArgList : Type Name[, ArgList]
4547

48+
-- Func : def Name([ArgList]) : Type { Command-list }
49+
-- Command-list = Command [Command-list]
50+
51+
-- Command = Expr ;
52+
4653
data Module
4754
= Command Expr
4855
| Method Func
56+
deriving (Show)
4957

5058
data Func
5159
= Func {
@@ -54,12 +62,14 @@ data Func
5462
retType:: Type ,
5563
body :: [Expr]
5664
}
65+
deriving (Show)
5766

5867
data Expr
5968
= DeclarationStmt Declaration
6069
| FuncCallStmt FuncCall
6170
| BinOpCallStmt BinOpCall
6271
| LiteralStmt Literal
72+
| Var Name
6373
deriving (Show)
6474

6575

src/CodeGen.hs

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3+
4+
module CodeGen where
5+
6+
import LLVM.Module
7+
import LLVM.Context
8+
9+
import qualified LLVM.AST as AST
10+
import qualified LLVM.AST.Constant as C
11+
import qualified LLVM.AST.Float as F
12+
import qualified LLVM.AST.FloatingPointPredicate as FP
13+
14+
import Data.Word
15+
import Data.String
16+
import Data.List
17+
import Data.Function
18+
import Data.Int
19+
import Control.Monad.Except
20+
import qualified Data.Map as Map
21+
22+
import Control.Monad.State
23+
import Control.Applicative
24+
25+
import qualified AST as ASTp
26+
27+
import LLVM.AST
28+
import qualified LLVM.AST as AST
29+
import LLVM.AST.Global
30+
import LLVM.Context
31+
import LLVM.Module
32+
import qualified LLVM.AST.Type as TypeQ
33+
import qualified LLVM.AST.Global as GLB
34+
import qualified LLVM.AST.Linkage as Linkage
35+
36+
37+
-- -- 1. Variable Declaration Done
38+
-- var = GLB.globalVariableDefaults { name = "Var1", GLB.type' = int }
39+
40+
-- | Utility Functions for Working on Module
41+
newtype LLVM a = LLVM (State AST.Module a)
42+
deriving (Functor, Applicative, Monad, MonadState AST.Module )
43+
44+
addDef :: Definition -> LLVM ()
45+
addDef def = do
46+
prev <- gets moduleDefinitions
47+
modify $ \s -> s { moduleDefinitions = def:prev }
48+
49+
50+
-- | BackEnd
51+
-- From Parsed AST to LLVM Definitions
52+
getDef :: ASTp.Func -> Definition
53+
getDef (ASTp.Func fname farg fret fbody ) = GlobalDefinition $ functionDefaults {
54+
name = Name fname,
55+
parameters = ([Parameter (getType tp) (getName nm) [] | (tp, nm) <- farg], False),
56+
returnType = (getType fret)
57+
-- basicBlocks = getBlk fbody
58+
}
59+
60+
getExtern :: ASTp.Declaration -> Definition
61+
getExtern (ASTp.ExternDecl fname fargs fret) =
62+
let (GlobalDefinition func) = (getDef (ASTp.Func fname fargs fret []))
63+
in (GlobalDefinition $ func {
64+
linkage = Linkage.External
65+
})
66+
67+
68+
getType :: ASTp.Type -> TypeQ.Type
69+
getType ASTp.IntC = IntegerType 32
70+
71+
getName :: ASTp.Name -> AST.Name
72+
getName = AST.Name
73+
74+
-- getBlk :: [ASTp.Expr] -> [GLB.BasicBlock]
75+
-- getBlk
76+
77+
type Names = Map.Map String Int
78+
79+
80+
-- Takes a name and check if present in names and then checks if the name already there or not.
81+
-- returns updated map and prev. name if any otherwise the name itself.
82+
-- Can be used to ask if this name is avaible and if so then use it otherwise it returns you
83+
-- an updated name that can be used.
84+
unikName :: String -> Names -> (String, Names)
85+
unikName name mapping = case Map.lookup name mapping of
86+
Nothing -> (name, Map.insert name 1 mapping)
87+
Just idx -> (name ++ (show idx) , Map.insert name (idx+1) mapping)
88+
89+
type SymbolTable = [(String, AST.Operand)]
90+
91+
92+
93+
94+
data ModuleState
95+
= ModuleState {
96+
crntBlk :: AST.Name,
97+
funcs :: Map.Map AST.Name FuncState,
98+
funcCount:: Int,
99+
symTab :: SymbolTable,
100+
count :: Word,
101+
names :: Names
102+
} deriving (Show)
103+
104+
data FuncState
105+
= FuncState {
106+
idx :: Int ,
107+
insts :: [Named Instruction],
108+
term :: Maybe (Named Terminator)
109+
} deriving (Show)
110+
111+
112+
newtype CodeGen a = CodeGen { runCodeGen :: State ModuleState a }
113+
deriving (Functor, Applicative, Monad, MonadState ModuleState)
114+
115+
116+
sortBlocks :: [(Name, FuncState)] -> [(Name, FuncState)]
117+
sortBlocks = sortBy (compare `on` (idx . snd))
118+
119+
createBlocks :: ModuleState -> [BasicBlock]
120+
createBlocks m = map makeBlock $ sortBlocks $ Map.toList (funcs m)
121+
122+
makeBlock :: (Name, FuncState) -> BasicBlock
123+
makeBlock (l, (FuncState _ s t)) = BasicBlock l (reverse s) (maketerm t)
124+
where
125+
maketerm (Just x) = x
126+
maketerm Nothing = error $ "Block has no terminator: " ++ (show l)
127+
128+
entryBlockName :: String
129+
entryBlockName = "entry"
130+
131+
emptyBlock :: Int -> FuncState
132+
emptyBlock i = FuncState i [] Nothing
133+
134+
emptyCodegen :: ModuleState
135+
emptyCodegen = ModuleState (Name entryBlockName) Map.empty 1 [] 0 Map.empty
136+
137+
execCodegen :: CodeGen a -> ModuleState
138+
execCodegen m = execState (runCodeGen m) emptyCodegen
139+
140+
141+
-- int :: Type
142+
-- int = IntegerType 32
143+
144+
-- defAdd :: Definition
145+
-- defAdd = GlobalDefinition functionDefaults
146+
-- { name = Name "add"
147+
-- , parameters =
148+
-- ( [ Parameter int (Name "a") []
149+
-- , Parameter int (Name "b") [] ]
150+
-- , False )
151+
-- , returnType = int
152+
-- , basicBlocks = [body]
153+
-- }
154+
-- where
155+
-- body = BasicBlock
156+
-- (Name "entry")
157+
-- [ Name "a" :=
158+
-- Add False -- no signed wrap
159+
-- False -- no unsigned wrap
160+
-- (LocalReference int (Name "a"))
161+
-- (LocalReference int (Name "b"))
162+
-- []]
163+
-- (Do $ Ret (Just (LocalReference int (Name "a"))) [])
164+
165+
-- -- literalStmtCodegen :: AST.Module -> AST.Module
166+
-- -- literalStmtCodegen =
167+
-- -- declInt :: AST.Module -> AST.Module
168+
-- -- declInt obj =
169+
170+
-- -- mainDef :: Definition
171+
-- -- mainDef =
172+
173+
-- module_ :: AST.Module
174+
-- module_ = defaultModule
175+
-- { moduleName = "basic"
176+
-- , moduleDefinitions = [defAdd]
177+
-- }
178+
179+
180+
181+
-- toLLVM :: AST.Module -> IO AST.Module
182+
-- toLLVM mod = withContext $ \ctx -> do
183+
-- liftError $ withModuleFromAST ctx mod ultimate
184+
-- return mod
185+
-- where
186+
-- ultimate = \m -> do
187+
-- llstr <- moduleLLVMAssembly m
188+
-- putStrLn llstr
189+
-- return m
190+
-- -- BS.putStrLn llvm
191+
192+
-- liftError :: ExceptT String IO a -> IO a
193+
-- liftError = runExceptT >=> either fail return
194+
195+
-- exec :: IO AST.Module
196+
-- exec = toLLVM module_
197+
198+
199+
200+
201+
202+
203+
204+
205+
206+
207+
208+
209+
210+
211+
212+
213+
214+
215+
216+
217+
218+
219+
220+
221+
222+
223+
224+
225+
-- import Data.ByteString.Char8 as BS
226+
227+
-- module_ :: AST.Module
228+
-- module_ = AST.defaultModule {
229+
-- AST.moduleName = "Main-Module",
230+
-- AST.moduleDefinitions = []
231+
-- }
232+
233+
-- toFound = withModuleFromAST
234+
-- runner :: AST.Module -> IO ()
235+
-- runner mod = withContext $ \ctx -> do
236+
-- llvm <- withModuleFromAST ctx mod moduleLLVMAssembly
237+
-- BS.putStrLn llvm
238+
239+
-- toLLVM :: AST.Module -> IO ()
240+
-- toLLVM mod = withContext $ \ctx -> do
241+
-- llvm <- withModuleFromAST ctx mod moduleLLVMAssembly
242+
-- BS.putStrLn llvm
243+
244+
-- toLLVM :: AST.Module -> IO AST.Module
245+
-- toLLVM mod = withContext $ \ctx -> do
246+
-- liftError $ withModuleFromAST ctx mod ultimate
247+
-- return mod
248+
-- where
249+
-- ultimate = \m -> do
250+
-- llstr <- moduleLLVMAssembly m
251+
-- BS.putStrLn llstr
252+
-- return m
253+
-- -- BS.putStrLn llvm
254+
255+
-- liftError :: ExceptT String IO a -> IO a
256+
-- liftError = runExceptT >=> either fail return

src/Emit.hs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
3+
module Emit where
4+
5+
6+
-- | Parser AST to LLVM code
7+
8+
-- nameGen :: Name -> LLVM ()
9+
10+
-- codegenTop :: S.Expr -> LLVM () --Stack 1.1
11+
-- codegenTop (S.Function name args body) = do -- args = ["a", "b"]
12+
-- define double name fnargs bls
13+
-- where
14+
-- fnargs = toSig args
15+
-- bls = createBlocks $ execCodegen $ do
16+
-- entry <- addBlock entryBlockName -- entryBlockName is just "entry"::String / entry is just the name to refer to the block
17+
-- setBlock entry
18+
-- forM args $ \a -> do -- For each argument we are assigning a variable
19+
-- var <- alloca double -- Var contains the (LocalReference Type Name)
20+
-- store var (local (AST.Name a)) -- Store the value in the variable
21+
-- assign a var -- Update the symbol table
22+
-- cgen body >>= ret -- cgen body ~ Codegen Operand for (Float 1.0)
23+
24+
-- codegenTop (S.Extern name args) = do
25+
-- external double name fnargs
26+
-- where fnargs = toSig args

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"]
3333
}
3434

0 commit comments

Comments
 (0)