From 7f588ec5611e308ebfe69715d5babf7adbb8fc37 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Fri, 29 Sep 2023 18:01:47 -0500 Subject: [PATCH 01/13] Reorganize program --- package.yaml | 2 +- really-bad-compiler-in-haskell.cabal | 8 ++++---- {main/Compiler => src/Forth}/LLVMGen.hs | 9 +++------ main/Parser/Expr.hs => src/Forth/Parser.hs | 4 ++-- {main => src/Forth}/Types/Expr.hs | 2 +- {main => src}/Main.hs | 7 ++++--- 6 files changed, 15 insertions(+), 17 deletions(-) rename {main/Compiler => src/Forth}/LLVMGen.hs (89%) rename main/Parser/Expr.hs => src/Forth/Parser.hs (91%) rename {main => src/Forth}/Types/Expr.hs (71%) rename {main => src}/Main.hs (91%) diff --git a/package.yaml b/package.yaml index 99c82b0..84d4766 100644 --- a/package.yaml +++ b/package.yaml @@ -19,7 +19,7 @@ ghc-options: -threaded -Wall -j8 +RTS -A64M -RTS -fllvm # source-dirs: src executable: - source-dirs: main + source-dirs: src main: Main.hs # tests: # testall: diff --git a/really-bad-compiler-in-haskell.cabal b/really-bad-compiler-in-haskell.cabal index d82f626..d55ad95 100644 --- a/really-bad-compiler-in-haskell.cabal +++ b/really-bad-compiler-in-haskell.cabal @@ -16,12 +16,12 @@ tested-with: executable really-bad-compiler-in-haskell main-is: Main.hs other-modules: - Compiler.LLVMGen - Parser.Expr - Types.Expr + Forth.LLVMGen + Forth.Parser + Forth.Types.Expr Paths_really_bad_compiler_in_haskell hs-source-dirs: - main + src default-extensions: OverloadedStrings, LambdaCase ghc-options: -threaded -Wall -j8 +RTS -A64M -RTS -fllvm diff --git a/main/Compiler/LLVMGen.hs b/src/Forth/LLVMGen.hs similarity index 89% rename from main/Compiler/LLVMGen.hs rename to src/Forth/LLVMGen.hs index d36277d..662783b 100644 --- a/main/Compiler/LLVMGen.hs +++ b/src/Forth/LLVMGen.hs @@ -4,13 +4,11 @@ -- see https://gh.sudoer.ch/danieljharvey/mimsa/blob/trunk/llvm-calc/src/Calc/Compile/ToLLVM.hs -module Compiler.LLVMGen (llvmGen) where - --- import LLVM.Pretty +module Forth.LLVMGen (llvmGen) where import Data.ByteString (ByteString) -import Debug.Trace -import LLVM (moduleLLVMAssembly, withModuleFromAST, writeLLVMAssemblyToFile) +import Forth.Types.Expr as Expr +import LLVM (moduleLLVMAssembly, withModuleFromAST) import LLVM.AST hiding (function) import LLVM.AST.Type import LLVM.Context @@ -18,7 +16,6 @@ import LLVM.IRBuilder.Constant import LLVM.IRBuilder.Instruction import LLVM.IRBuilder.Module import LLVM.IRBuilder.Monad -import Types.Expr as Expr getLLVM :: Expr -> Module getLLVM expr = diff --git a/main/Parser/Expr.hs b/src/Forth/Parser.hs similarity index 91% rename from main/Parser/Expr.hs rename to src/Forth/Parser.hs index a2f3f4c..d2726c7 100644 --- a/main/Parser/Expr.hs +++ b/src/Forth/Parser.hs @@ -1,15 +1,15 @@ -- see https://markkarpov.com/tutorial/megaparsec.html {-# LANGUAGE ImportQualifiedPost #-} -module Parser.Expr (parseExpr, ParseResult) where +module Forth.Parser (parseExpr, ParseResult) where import Control.Monad.Combinators.Expr import Data.Functor.Identity qualified import Data.Void (Void) +import Forth.Types.Expr import Text.Megaparsec as MP import Text.Megaparsec.Char as C import Text.Megaparsec.Char.Lexer as L -import Types.Expr type Parser = Parsec Void String diff --git a/main/Types/Expr.hs b/src/Forth/Types/Expr.hs similarity index 71% rename from main/Types/Expr.hs rename to src/Forth/Types/Expr.hs index 51c8925..ff8741d 100644 --- a/main/Types/Expr.hs +++ b/src/Forth/Types/Expr.hs @@ -1,4 +1,4 @@ -module Types.Expr (Expr (..)) where +module Forth.Types.Expr (Expr (..)) where data Expr = Lit Int diff --git a/main/Main.hs b/src/Main.hs similarity index 91% rename from main/Main.hs rename to src/Main.hs index dda57c6..d0795c1 100644 --- a/main/Main.hs +++ b/src/Main.hs @@ -4,13 +4,14 @@ module Main (main) where -- import Compiler.ExeGen -import Compiler.LLVMGen + import Data.ByteString.Char8 qualified as B import Data.Text.Lazy.IO qualified as T -import Parser.Expr +import Forth.LLVMGen +import Forth.Parser +import Forth.Types.Expr import System.Environment import System.Process -import Types.Expr getRight :: ParseResult -> Expr getRight (Right r) = r From e7083c1c4089a46d990e9fc2d86bf624518d28bf Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Fri, 29 Sep 2023 22:59:25 -0500 Subject: [PATCH 02/13] Change Parser from string to text --- src/Forth/Parser.hs | 19 ++++++++++++++----- src/Forth/Types/Expr.hs | 3 ++- src/Main.hs | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Forth/Parser.hs b/src/Forth/Parser.hs index d2726c7..32247ba 100644 --- a/src/Forth/Parser.hs +++ b/src/Forth/Parser.hs @@ -1,22 +1,24 @@ -- see https://markkarpov.com/tutorial/megaparsec.html {-# LANGUAGE ImportQualifiedPost #-} +{-# LANGUAGE OverloadedStrings #-} module Forth.Parser (parseExpr, ParseResult) where import Control.Monad.Combinators.Expr import Data.Functor.Identity qualified +import Data.Text.Lazy import Data.Void (Void) import Forth.Types.Expr import Text.Megaparsec as MP import Text.Megaparsec.Char as C import Text.Megaparsec.Char.Lexer as L -type Parser = Parsec Void String +type Parser = Parsec Void Text lexemeParser :: Parser a -> Parser a lexemeParser = L.lexeme C.space -symbolParser :: String -> Parser String +symbolParser :: Text -> Parser Text symbolParser = L.symbol C.space intParser :: Parser Int @@ -32,18 +34,25 @@ table = ], [ binaryOp "+" Add, binaryOp "-" Sub + -- binaryOp "." Pop ] ] -binaryOp :: String -> (a -> a -> a) -> Operator (ParsecT Void String Data.Functor.Identity.Identity) a +binaryOp :: Text -> (a -> a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a binaryOp name f = InfixL (f <$ symbolParser name) +-- prefixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a +-- prefixOp name f = Prefix (f <$ symbolParser name) + +-- postfixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a +-- postfixOp name f = Postfix (f <$ symbolParser name) + expr :: Parser Expr expr = makeExprParser term table -type ParseResult = Either (ParseErrorBundle String Void) Expr +type ParseResult = Either (ParseErrorBundle Text Void) Expr -parseExpr :: String -> ParseResult +parseExpr :: Text -> ParseResult parseExpr = MP.parse (C.space *> expr <* eof) "" -- parseE = parseExpr \ No newline at end of file diff --git a/src/Forth/Types/Expr.hs b/src/Forth/Types/Expr.hs index ff8741d..71dbcec 100644 --- a/src/Forth/Types/Expr.hs +++ b/src/Forth/Types/Expr.hs @@ -7,5 +7,6 @@ data Expr | Mul Expr Expr | Div Expr Expr deriving - ( Show + ( -- | Pop Expr Expr + Show ) \ No newline at end of file diff --git a/src/Main.hs b/src/Main.hs index d0795c1..4bfc1b6 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -19,7 +19,7 @@ getRight (Right r) = r main :: IO () main = do fileName <- fmap head getArgs - contents <- readFile fileName + contents <- T.readFile fileName T.putStrLn "- Parsing file..." let parsed = getRight (parseExpr contents) T.putStrLn "- Generating LLVM to './a.out.ll'..." From 01ff0985307c430af0fbce7c88ae83c9e7b3815c Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Sat, 30 Sep 2023 03:57:03 -0500 Subject: [PATCH 03/13] Update Readme --- README.md | 6 ++++-- example/{1 => 1.hear} | 0 example/{2 => 2.hear} | 0 src/Main.hs | 6 +++--- src/{Forth => Main}/LLVMGen.hs | 4 ++-- src/{Forth/Parser.hs => Main/Parser/Megaparsec.hs} | 12 ++++++------ src/{Forth => Main}/Types/Expr.hs | 2 +- 7 files changed, 16 insertions(+), 14 deletions(-) rename example/{1 => 1.hear} (100%) rename example/{2 => 2.hear} (100%) rename src/{Forth => Main}/LLVMGen.hs (95%) rename src/{Forth/Parser.hs => Main/Parser/Megaparsec.hs} (74%) rename src/{Forth => Main}/Types/Expr.hs (75%) diff --git a/README.md b/README.md index e6b3a8f..8d68f4d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Really Bad Compiler in Haskell -A compiler written in Haskell which can currently perform basic arithmetic. Currently using the megaparsec and llvm-hs-\* libraries, but I may reimplement certain libraries myself. Built for the Introduction to Compiler Design class at The University of Texas at Dallas. +A compiler for Hear, a language for when you cannot C. + +Written in Haskell, and currently using the megaparsec and llvm-hs-\* libraries, but I plan to eventually rewrite the lexar/parser from scratch. Built for the Introduction to Compiler Design class at The University of Texas at Dallas. Main repo: https://git.sudoer.ch/me/really-bad-compiler-in-haskell @@ -12,7 +14,7 @@ Main repo: https://git.sudoer.ch/me/really-bad-compiler-in-haskell ## Run Instructions -- Use `stack run ` to run the program (for example, `stack run example/1`). +- Use `stack run ` to run the program (for example, `stack run example/1.hear`). - The LLVM will be generated as `a.out.ll`, and the executable will be generated as `a.out`. ## To edit diff --git a/example/1 b/example/1.hear similarity index 100% rename from example/1 rename to example/1.hear diff --git a/example/2 b/example/2.hear similarity index 100% rename from example/2 rename to example/2.hear diff --git a/src/Main.hs b/src/Main.hs index 4bfc1b6..f8a556f 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -7,9 +7,9 @@ module Main (main) where import Data.ByteString.Char8 qualified as B import Data.Text.Lazy.IO qualified as T -import Forth.LLVMGen -import Forth.Parser -import Forth.Types.Expr +import Main.LLVMGen +import Main.Parser.Megaparsec +import Main.Types.Expr import System.Environment import System.Process diff --git a/src/Forth/LLVMGen.hs b/src/Main/LLVMGen.hs similarity index 95% rename from src/Forth/LLVMGen.hs rename to src/Main/LLVMGen.hs index 662783b..38fe242 100644 --- a/src/Forth/LLVMGen.hs +++ b/src/Main/LLVMGen.hs @@ -4,10 +4,9 @@ -- see https://gh.sudoer.ch/danieljharvey/mimsa/blob/trunk/llvm-calc/src/Calc/Compile/ToLLVM.hs -module Forth.LLVMGen (llvmGen) where +module Main.LLVMGen (llvmGen) where import Data.ByteString (ByteString) -import Forth.Types.Expr as Expr import LLVM (moduleLLVMAssembly, withModuleFromAST) import LLVM.AST hiding (function) import LLVM.AST.Type @@ -16,6 +15,7 @@ import LLVM.IRBuilder.Constant import LLVM.IRBuilder.Instruction import LLVM.IRBuilder.Module import LLVM.IRBuilder.Monad +import Main.Types.Expr as Expr getLLVM :: Expr -> Module getLLVM expr = diff --git a/src/Forth/Parser.hs b/src/Main/Parser/Megaparsec.hs similarity index 74% rename from src/Forth/Parser.hs rename to src/Main/Parser/Megaparsec.hs index 32247ba..e1c9f27 100644 --- a/src/Forth/Parser.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -2,13 +2,13 @@ {-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE OverloadedStrings #-} -module Forth.Parser (parseExpr, ParseResult) where +module Main.Parser.Megaparsec (parseExpr, ParseResult) where import Control.Monad.Combinators.Expr import Data.Functor.Identity qualified import Data.Text.Lazy import Data.Void (Void) -import Forth.Types.Expr +import Main.Types.Expr import Text.Megaparsec as MP import Text.Megaparsec.Char as C import Text.Megaparsec.Char.Lexer as L @@ -41,11 +41,11 @@ table = binaryOp :: Text -> (a -> a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a binaryOp name f = InfixL (f <$ symbolParser name) --- prefixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a --- prefixOp name f = Prefix (f <$ symbolParser name) +prefixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a +prefixOp name f = Prefix (f <$ symbolParser name) --- postfixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a --- postfixOp name f = Postfix (f <$ symbolParser name) +postfixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a +postfixOp name f = Postfix (f <$ symbolParser name) expr :: Parser Expr expr = makeExprParser term table diff --git a/src/Forth/Types/Expr.hs b/src/Main/Types/Expr.hs similarity index 75% rename from src/Forth/Types/Expr.hs rename to src/Main/Types/Expr.hs index 71dbcec..30f0a1d 100644 --- a/src/Forth/Types/Expr.hs +++ b/src/Main/Types/Expr.hs @@ -1,4 +1,4 @@ -module Forth.Types.Expr (Expr (..)) where +module Main.Types.Expr (Expr (..)) where data Expr = Lit Int From d14c5ace00ba4f87665ea8ff0d4b3a27c35e36f5 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Sat, 30 Sep 2023 04:07:45 -0500 Subject: [PATCH 04/13] Reorganize Parser method --- really-bad-compiler-in-haskell.cabal | 6 ++-- src/Main.hs | 10 ++----- src/Main/Parser/Megaparsec.hs | 43 +++++++++++++++------------- src/Main/Types/Expr.hs | 4 +-- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/really-bad-compiler-in-haskell.cabal b/really-bad-compiler-in-haskell.cabal index d55ad95..13f796f 100644 --- a/really-bad-compiler-in-haskell.cabal +++ b/really-bad-compiler-in-haskell.cabal @@ -16,9 +16,9 @@ tested-with: executable really-bad-compiler-in-haskell main-is: Main.hs other-modules: - Forth.LLVMGen - Forth.Parser - Forth.Types.Expr + Main.LLVMGen + Main.Parser.Megaparsec + Main.Types.Expr Paths_really_bad_compiler_in_haskell hs-source-dirs: src diff --git a/src/Main.hs b/src/Main.hs index f8a556f..7c4d935 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -3,25 +3,19 @@ module Main (main) where --- import Compiler.ExeGen - import Data.ByteString.Char8 qualified as B -import Data.Text.Lazy.IO qualified as T +import Data.Text.IO qualified as T import Main.LLVMGen import Main.Parser.Megaparsec -import Main.Types.Expr import System.Environment import System.Process -getRight :: ParseResult -> Expr -getRight (Right r) = r - main :: IO () main = do fileName <- fmap head getArgs contents <- T.readFile fileName T.putStrLn "- Parsing file..." - let parsed = getRight (parseExpr contents) + let parsed = parse contents T.putStrLn "- Generating LLVM to './a.out.ll'..." llvmGen parsed >>= B.writeFile "a.out.ll" T.putStrLn "- Compiling to executable './a.out'..." diff --git a/src/Main/Parser/Megaparsec.hs b/src/Main/Parser/Megaparsec.hs index e1c9f27..e78c623 100644 --- a/src/Main/Parser/Megaparsec.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -2,30 +2,31 @@ {-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE OverloadedStrings #-} -module Main.Parser.Megaparsec (parseExpr, ParseResult) where +module Main.Parser.Megaparsec (parse) where import Control.Monad.Combinators.Expr import Data.Functor.Identity qualified -import Data.Text.Lazy +import Data.Text import Data.Void (Void) import Main.Types.Expr -import Text.Megaparsec as MP -import Text.Megaparsec.Char as C -import Text.Megaparsec.Char.Lexer as L +import Text.Megaparsec as MP hiding (parse) +import Text.Megaparsec qualified as MP +import Text.Megaparsec.Char qualified as C +import Text.Megaparsec.Char.Lexer qualified as L type Parser = Parsec Void Text -lexemeParser :: Parser a -> Parser a -lexemeParser = L.lexeme C.space +lexeme :: Parser a -> Parser a +lexeme = L.lexeme C.space -symbolParser :: Text -> Parser Text -symbolParser = L.symbol C.space +symbol :: Text -> Parser Text +symbol = L.symbol C.space -intParser :: Parser Int -intParser = lexemeParser L.decimal +int :: Parser Int +int = lexeme L.decimal term :: Parser Expr -term = Lit <$> intParser +term = Lit <$> int table :: [[Operator Parser Expr]] table = @@ -34,25 +35,27 @@ table = ], [ binaryOp "+" Add, binaryOp "-" Sub - -- binaryOp "." Pop ] ] binaryOp :: Text -> (a -> a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -binaryOp name f = InfixL (f <$ symbolParser name) +binaryOp name f = InfixL (f <$ symbol name) prefixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -prefixOp name f = Prefix (f <$ symbolParser name) +prefixOp name f = Prefix (f <$ symbol name) postfixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -postfixOp name f = Postfix (f <$ symbolParser name) +postfixOp name f = Postfix (f <$ symbol name) expr :: Parser Expr expr = makeExprParser term table -type ParseResult = Either (ParseErrorBundle Text Void) Expr - -parseExpr :: Text -> ParseResult +parseExpr :: Text -> Either (ParseErrorBundle Text Void) Expr parseExpr = MP.parse (C.space *> expr <* eof) "" --- parseE = parseExpr \ No newline at end of file +parse :: Text -> Expr +parse t = do + case parseExpr t of + Right r -> r + +-- TODO: add error handling \ No newline at end of file diff --git a/src/Main/Types/Expr.hs b/src/Main/Types/Expr.hs index 30f0a1d..9fc0b32 100644 --- a/src/Main/Types/Expr.hs +++ b/src/Main/Types/Expr.hs @@ -6,7 +6,7 @@ data Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr + | Print Expr deriving - ( -- | Pop Expr Expr - Show + ( Show ) \ No newline at end of file From d40467bc00d7a58cb30e128b582941f496ccd51b Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Sat, 30 Sep 2023 04:35:15 -0500 Subject: [PATCH 05/13] Parse negative numbers --- example/1.hear | 2 +- src/Main/Parser/Megaparsec.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/1.hear b/example/1.hear index 0f9d1ef..a8482c2 100644 --- a/example/1.hear +++ b/example/1.hear @@ -1 +1 @@ -5*3+2 \ No newline at end of file +5*3-2+-4-4 \ No newline at end of file diff --git a/src/Main/Parser/Megaparsec.hs b/src/Main/Parser/Megaparsec.hs index e78c623..a82e02a 100644 --- a/src/Main/Parser/Megaparsec.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -23,7 +23,7 @@ symbol :: Text -> Parser Text symbol = L.symbol C.space int :: Parser Int -int = lexeme L.decimal +int = lexeme $ L.signed (return ()) L.decimal term :: Parser Expr term = Lit <$> int From e162d55439b65be605be78d5b4cce7095a1540f1 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Sat, 30 Sep 2023 05:04:39 -0500 Subject: [PATCH 06/13] Parse "print" statement --- example/1.hear | 2 +- src/Main/Parser/Megaparsec.hs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/example/1.hear b/example/1.hear index a8482c2..210d2c9 100644 --- a/example/1.hear +++ b/example/1.hear @@ -1 +1 @@ -5*3-2+-4-4 \ No newline at end of file +print 5*3-2+-4-4 \ No newline at end of file diff --git a/src/Main/Parser/Megaparsec.hs b/src/Main/Parser/Megaparsec.hs index a82e02a..931038d 100644 --- a/src/Main/Parser/Megaparsec.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -25,12 +25,16 @@ symbol = L.symbol C.space int :: Parser Int int = lexeme $ L.signed (return ()) L.decimal +string :: Text -> Parser Text +string = C.string + term :: Parser Expr term = Lit <$> int table :: [[Operator Parser Expr]] table = - [ [ binaryOp "*" Mul, + [ [methodOp "print" Print], + [ binaryOp "*" Mul, binaryOp "/" Div ], [ binaryOp "+" Add, @@ -41,11 +45,14 @@ table = binaryOp :: Text -> (a -> a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a binaryOp name f = InfixL (f <$ symbol name) -prefixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -prefixOp name f = Prefix (f <$ symbol name) +-- prefixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a +-- prefixOp name f = Prefix (f <$ symbol name) -postfixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -postfixOp name f = Postfix (f <$ symbol name) +methodOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a +methodOp name f = Prefix (f <$ (string name <* C.space)) + +-- postfixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a +-- postfixOp name f = Postfix (f <$ symbol name) expr :: Parser Expr expr = makeExprParser term table From 7f9e3c35092bde6862056e663a79f843d0636084 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Sat, 30 Sep 2023 05:12:32 -0500 Subject: [PATCH 07/13] Add parenthesis --- example/1.hear | 2 +- src/Main.hs | 2 +- src/Main/LLVMGen.hs | 1 + src/Main/Parser/Megaparsec.hs | 9 ++++++++- src/Main/Types/Expr.hs | 1 + 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/example/1.hear b/example/1.hear index 210d2c9..62c2d80 100644 --- a/example/1.hear +++ b/example/1.hear @@ -1 +1 @@ -print 5*3-2+-4-4 \ No newline at end of file +(5*(3-2)+-4-4) \ No newline at end of file diff --git a/src/Main.hs b/src/Main.hs index 7c4d935..13e893f 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -8,7 +8,7 @@ import Data.Text.IO qualified as T import Main.LLVMGen import Main.Parser.Megaparsec import System.Environment -import System.Process +import System.Process (callCommand) main :: IO () main = do diff --git a/src/Main/LLVMGen.hs b/src/Main/LLVMGen.hs index 38fe242..818a79f 100644 --- a/src/Main/LLVMGen.hs +++ b/src/Main/LLVMGen.hs @@ -35,6 +35,7 @@ exprToLLVM :: Expr -> m Operand exprToLLVM (Lit prim) = pure $ primToLLVM prim +exprToLLVM (Paren e) = exprToLLVM e exprToLLVM (Expr.Add a b) = mdo lhs <- exprToLLVM a rhs <- exprToLLVM b diff --git a/src/Main/Parser/Megaparsec.hs b/src/Main/Parser/Megaparsec.hs index 931038d..6178a9d 100644 --- a/src/Main/Parser/Megaparsec.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -28,8 +28,15 @@ int = lexeme $ L.signed (return ()) L.decimal string :: Text -> Parser Text string = C.string +container :: Text -> Text -> Parser a -> Parser a +container b e = between (symbol b) (symbol e) + term :: Parser Expr -term = Lit <$> int +term = + choice + [ Lit <$> int, + container "(" ")" expr + ] table :: [[Operator Parser Expr]] table = diff --git a/src/Main/Types/Expr.hs b/src/Main/Types/Expr.hs index 9fc0b32..c91cfb7 100644 --- a/src/Main/Types/Expr.hs +++ b/src/Main/Types/Expr.hs @@ -2,6 +2,7 @@ module Main.Types.Expr (Expr (..)) where data Expr = Lit Int + | Paren Expr | Add Expr Expr | Sub Expr Expr | Mul Expr Expr From 7e9d8b434a5a214766c531bbdb7dbe4c6ec415a0 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Mon, 2 Oct 2023 11:41:21 -0500 Subject: [PATCH 08/13] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8d68f4d..1370de1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Really Bad Compiler in Haskell +# HEAR Compiler in Haskell -A compiler for Hear, a language for when you cannot C. +A compiler for HEAR, a language for when you cannot C. Written in Haskell, and currently using the megaparsec and llvm-hs-\* libraries, but I plan to eventually rewrite the lexar/parser from scratch. Built for the Introduction to Compiler Design class at The University of Texas at Dallas. From 5325a845f2d73b9352884252c2e958d6f29265a4 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Fri, 6 Oct 2023 00:29:36 -0500 Subject: [PATCH 09/13] Fix haskell language server broken --- README.md | 2 +- really-bad-compiler-in-haskell.cabal | 2 +- src/Main.hs | 9 ++++----- src/Main/LLVMGen.hs | 18 ++++++++++++------ src/Main/Parser/Megaparsec.hs | 6 +++--- stack.yaml | 9 ++++++++- 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 1370de1..ec14e4f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Main repo: https://git.sudoer.ch/me/really-bad-compiler-in-haskell - Install `ghcup` (for managing Haskell tools) and `nix` (for managing external dependencies). - Clone the repo. -- Use `ghcup` to install `stack 2.9.3`, `HLS 2.2.0.0`, `GHC 9.2.8`, and `cabal 3.6.2.0`. +- Use `ghcup` to install `stack 2.11.1`, `HLS 2.3.0.0`, and `cabal 3.8.1.0`. ## Run Instructions diff --git a/really-bad-compiler-in-haskell.cabal b/really-bad-compiler-in-haskell.cabal index 13f796f..f153056 100644 --- a/really-bad-compiler-in-haskell.cabal +++ b/really-bad-compiler-in-haskell.cabal @@ -1,6 +1,6 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.1. +-- This file has been generated from package.yaml by hpack version 0.35.2. -- -- see: https://github.com/sol/hpack diff --git a/src/Main.hs b/src/Main.hs index 13e893f..c8b387f 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -12,12 +12,11 @@ import System.Process (callCommand) main :: IO () main = do - fileName <- fmap head getArgs + fileName <- head <$> getArgs contents <- T.readFile fileName - T.putStrLn "- Parsing file..." - let parsed = parse contents T.putStrLn "- Generating LLVM to './a.out.ll'..." - llvmGen parsed >>= B.writeFile "a.out.ll" + result <- (llvmGen . parse) contents + B.writeFile "a.out.ll" result T.putStrLn "- Compiling to executable './a.out'..." callCommand "clang a.out.ll" - T.putStrLn "- Done." + T.putStrLn "- Done." \ No newline at end of file diff --git a/src/Main/LLVMGen.hs b/src/Main/LLVMGen.hs index 818a79f..a8ce6c6 100644 --- a/src/Main/LLVMGen.hs +++ b/src/Main/LLVMGen.hs @@ -17,6 +17,9 @@ import LLVM.IRBuilder.Module import LLVM.IRBuilder.Monad import Main.Types.Expr as Expr +-- printf :: Operand +-- printf = externVarArgs "printf" [ptr] i32 + getLLVM :: Expr -> Module getLLVM expr = buildModule "program" $ mdo @@ -26,7 +29,12 @@ getLLVM expr = numFormatStr <- globalStringPtr "%d\n" (mkName "str") ourExpression <- exprToLLVM expr _ <- call (FunctionType i32 [ptr] True) printf [(ConstantOperand numFormatStr, []), (ourExpression, [])] - ret (int32 0) + ret $ int32 0 + +-- getLLVM2 expr = +-- getLLVM $ + +-- return (printf) exprToLLVM :: ( MonadIRBuilder m, @@ -36,6 +44,7 @@ exprToLLVM :: m Operand exprToLLVM (Lit prim) = pure $ primToLLVM prim exprToLLVM (Paren e) = exprToLLVM e +-- exprToLLVM (Print e) = mdo exprToLLVM (Expr.Add a b) = mdo lhs <- exprToLLVM a rhs <- exprToLLVM b @@ -54,12 +63,9 @@ exprToLLVM (Expr.Div a b) = mdo sdiv lhs rhs primToLLVM :: Int -> Operand -primToLLVM i = int32 (fromIntegral i) +primToLLVM i = int32 $ fromIntegral i llvmGen :: Expr -> IO ByteString llvmGen expr = do let l = getLLVM expr - withContext - ( \c -> - withModuleFromAST c l moduleLLVMAssembly - ) \ No newline at end of file + withContext $ \c -> withModuleFromAST c l moduleLLVMAssembly \ No newline at end of file diff --git a/src/Main/Parser/Megaparsec.hs b/src/Main/Parser/Megaparsec.hs index 6178a9d..33543de 100644 --- a/src/Main/Parser/Megaparsec.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -50,13 +50,13 @@ table = ] binaryOp :: Text -> (a -> a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -binaryOp name f = InfixL (f <$ symbol name) +binaryOp name f = InfixL $ f <$ symbol name -- prefixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -- prefixOp name f = Prefix (f <$ symbol name) methodOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -methodOp name f = Prefix (f <$ (string name <* C.space)) +methodOp name f = Prefix $ f <$ (string name <* C.space) -- postfixOp :: Text -> (a -> a) -> Operator (ParsecT Void Text Data.Functor.Identity.Identity) a -- postfixOp name f = Postfix (f <$ symbol name) @@ -68,7 +68,7 @@ parseExpr :: Text -> Either (ParseErrorBundle Text Void) Expr parseExpr = MP.parse (C.space *> expr <* eof) "" parse :: Text -> Expr -parse t = do +parse t = case parseExpr t of Right r -> r diff --git a/stack.yaml b/stack.yaml index 45dc800..c54066b 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,4 +1,11 @@ resolver: lts-20.26 +compiler: ghc-9.2.8 +# setup-info: +# ghc: +# aarch64: +# 9.4.6: +# url: "https://downloads.haskell.org/~ghc/9.4.6/ghc-9.4.6-aarch64-deb10-linux.tar.xz" +# sha256: "05896fc4bc52c117d281eac9c621c6c3a0b14f9f9eed5e42cce5e1c4485c7623" packages: - . @@ -12,4 +19,4 @@ nix: enable: true packages: [llvm_15, clang_15, libxml2] system-ghc: true -install-ghc: true +install-ghc: false From f7e64faed51c3d004d3072d1c67fa214aad53435 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Fri, 6 Oct 2023 23:21:55 -0500 Subject: [PATCH 10/13] Add print functionality --- example/2.hear | 2 +- package.yaml | 4 ++ really-bad-compiler-in-haskell.cabal | 4 ++ src/Main/LLVMGen.hs | 76 ++++++++++++++++++++++------ 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/example/2.hear b/example/2.hear index 50f4893..2078094 100644 --- a/example/2.hear +++ b/example/2.hear @@ -1 +1 @@ -6+8/3 \ No newline at end of file + (6+8/3) \ No newline at end of file diff --git a/package.yaml b/package.yaml index 84d4766..72cd6c8 100644 --- a/package.yaml +++ b/package.yaml @@ -7,9 +7,13 @@ dependencies: - parser-combinators - text - process + - mtl + - containers - llvm-hs >= 15 && < 16 - llvm-hs-pure >= 15 && < 16 - bytestring + - string-conversions + - transformers tested-with: GHC == 9.2.8 category: Compilers/Interpreters diff --git a/really-bad-compiler-in-haskell.cabal b/really-bad-compiler-in-haskell.cabal index f153056..31bd2b4 100644 --- a/really-bad-compiler-in-haskell.cabal +++ b/really-bad-compiler-in-haskell.cabal @@ -28,10 +28,14 @@ executable really-bad-compiler-in-haskell build-depends: base >=4.14.3 && <5 , bytestring + , containers , llvm-hs ==15.* , llvm-hs-pure ==15.* , megaparsec >=9.0.1 && <10 + , mtl , parser-combinators , process + , string-conversions , text + , transformers default-language: Haskell2010 diff --git a/src/Main/LLVMGen.hs b/src/Main/LLVMGen.hs index a8ce6c6..0032b14 100644 --- a/src/Main/LLVMGen.hs +++ b/src/Main/LLVMGen.hs @@ -1,12 +1,19 @@ +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecursiveDo #-} -- see https://gh.sudoer.ch/danieljharvey/mimsa/blob/trunk/llvm-calc/src/Calc/Compile/ToLLVM.hs +-- see https://blog.josephmorag.com/posts/mcc3/ module Main.LLVMGen (llvmGen) where +import Control.Monad.State +import Control.Monad.Trans.Class (lift) import Data.ByteString (ByteString) +import Data.Map qualified as M +import Data.String.Conversions +import Data.Text import LLVM (moduleLLVMAssembly, withModuleFromAST) import LLVM.AST hiding (function) import LLVM.AST.Type @@ -17,34 +24,71 @@ import LLVM.IRBuilder.Module import LLVM.IRBuilder.Monad import Main.Types.Expr as Expr --- printf :: Operand --- printf = externVarArgs "printf" [ptr] i32 +data Env = Env + { operands :: M.Map Text Operand, + strings :: M.Map Text Operand + } + deriving (Eq, Show) + +registerOperand :: (MonadState Env m) => Text -> Operand -> m () +registerOperand name op = + modify $ \env -> env {operands = M.insert name op (operands env)} + +registerString :: (MonadState Env m) => Text -> Operand -> m () +registerString name op = + modify $ \env -> env {strings = M.insert name op (operands env)} + +getOperand :: (MonadState Env m, MonadModuleBuilder m, MonadIRBuilder m) => Text -> m Operand +getOperand name = do + env <- get + case M.lookup name (operands env) of + Just op -> return op + Nothing -> error $ "Unknown operand: " ++ show name + +getString :: (MonadState Env m, MonadModuleBuilder m, MonadIRBuilder m) => Text -> m Operand +getString str = do + env <- get + case M.lookup str (strings env) of + Just s -> return s + Nothing -> do + s <- globalStringPtr (unpack str) (mkName "str") + let operand = ConstantOperand s + modify $ \env -> env {strings = M.insert str operand (strings env)} + return operand getLLVM :: Expr -> Module getLLVM expr = - buildModule "program" $ mdo - -- TODO: better module name - printf <- externVarArgs "printf" [ptr] i32 - function "main" [] i32 $ \_ -> mdo - numFormatStr <- globalStringPtr "%d\n" (mkName "str") - ourExpression <- exprToLLVM expr - _ <- call (FunctionType i32 [ptr] True) printf [(ConstantOperand numFormatStr, []), (ourExpression, [])] - ret $ int32 0 + flip evalState (Env {operands = M.empty, strings = M.empty}) $ + buildModuleT "program" $ mdo + -- TODO: better module name + printf <- externVarArgs "printf" [ptr] i32 + lift $ registerOperand "printf" printf + function "main" [] i32 $ \_ -> mdo + printNumStr <- globalStringPtr "%d\n" (mkName "str") + lift $ registerString "%d\n" $ ConstantOperand printNumStr + _ <- exprToLLVM expr + ret $ int32 0 --- getLLVM2 expr = --- getLLVM $ - --- return (printf) +-- +-- ourExpression <- exprToLLVM expr +-- _ <- call (FunctionType i32 [ptr] True) printf [(ConstantOperand numFormatStr, []), (ourExpression, [])] +-- ret $ int32 0 exprToLLVM :: ( MonadIRBuilder m, - MonadModuleBuilder m + MonadModuleBuilder m, + MonadState Env m ) => Expr -> m Operand exprToLLVM (Lit prim) = pure $ primToLLVM prim exprToLLVM (Paren e) = exprToLLVM e --- exprToLLVM (Print e) = mdo +exprToLLVM (Print e) = mdo + val <- exprToLLVM e + printf <- getOperand "printf" + formatStr <- getString "%d\n" + _ <- call (FunctionType i32 [ptr] True) printf [(formatStr, []), (val, [])] + pure val exprToLLVM (Expr.Add a b) = mdo lhs <- exprToLLVM a rhs <- exprToLLVM b From b52fe34667eb46fd7e86e081cd9986f4649f07ea Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Fri, 6 Oct 2023 23:32:00 -0500 Subject: [PATCH 11/13] Move Expr to Type.hs --- README.md | 6 ++++++ really-bad-compiler-in-haskell.cabal | 2 +- src/Main/LLVMGen.hs | 2 +- src/Main/Parser/Megaparsec.hs | 2 +- src/Main/{Types/Expr.hs => Type.hs} | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) rename src/Main/{Types/Expr.hs => Type.hs} (76%) diff --git a/README.md b/README.md index ec14e4f..a62097b 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ Main repo: https://git.sudoer.ch/me/really-bad-compiler-in-haskell - Use `stack run ` to run the program (for example, `stack run example/1.hear`). - The LLVM will be generated as `a.out.ll`, and the executable will be generated as `a.out`. +## Currently Supported functionality + +- Arithmetic +- Parenthesis +- print() statement + ## To edit I recommend using VSCodium, which is preconfigured to have syntax highlighting and (currently broken) debugging features and will automatically suggest the Haskell extensions to install. diff --git a/really-bad-compiler-in-haskell.cabal b/really-bad-compiler-in-haskell.cabal index 31bd2b4..7e52a66 100644 --- a/really-bad-compiler-in-haskell.cabal +++ b/really-bad-compiler-in-haskell.cabal @@ -18,7 +18,7 @@ executable really-bad-compiler-in-haskell other-modules: Main.LLVMGen Main.Parser.Megaparsec - Main.Types.Expr + Main.Type Paths_really_bad_compiler_in_haskell hs-source-dirs: src diff --git a/src/Main/LLVMGen.hs b/src/Main/LLVMGen.hs index 0032b14..8394fb7 100644 --- a/src/Main/LLVMGen.hs +++ b/src/Main/LLVMGen.hs @@ -22,7 +22,7 @@ import LLVM.IRBuilder.Constant import LLVM.IRBuilder.Instruction import LLVM.IRBuilder.Module import LLVM.IRBuilder.Monad -import Main.Types.Expr as Expr +import Main.Type as Expr data Env = Env { operands :: M.Map Text Operand, diff --git a/src/Main/Parser/Megaparsec.hs b/src/Main/Parser/Megaparsec.hs index 33543de..9435ca0 100644 --- a/src/Main/Parser/Megaparsec.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -8,7 +8,7 @@ import Control.Monad.Combinators.Expr import Data.Functor.Identity qualified import Data.Text import Data.Void (Void) -import Main.Types.Expr +import Main.Type import Text.Megaparsec as MP hiding (parse) import Text.Megaparsec qualified as MP import Text.Megaparsec.Char qualified as C diff --git a/src/Main/Types/Expr.hs b/src/Main/Type.hs similarity index 76% rename from src/Main/Types/Expr.hs rename to src/Main/Type.hs index c91cfb7..1c38360 100644 --- a/src/Main/Types/Expr.hs +++ b/src/Main/Type.hs @@ -1,4 +1,4 @@ -module Main.Types.Expr (Expr (..)) where +module Main.Type (Expr (..)) where data Expr = Lit Int From bdbe823bc3d215c3823976d7466c525ed6d2ba94 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Fri, 6 Oct 2023 23:55:57 -0500 Subject: [PATCH 12/13] Add command line argument parsing --- README.md | 5 +++-- package.yaml | 1 + really-bad-compiler-in-haskell.cabal | 1 + src/Main.hs | 33 ++++++++++++++++++++++++---- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a62097b..3f59fd2 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,13 @@ I recommend using VSCodium, which is preconfigured to have syntax highlighting a - https://danieljharvey.github.io/posts/2023-02-08-llvm-compiler-part-1.html (for help using llvm-hs-pure) - https://gh.sudoer.ch/danieljharvey/mimsa/blob/trunk/llvm-calc/src/Calc/Compile/ToLLVM.hs (source code for above resource) - https://9to5tutorial.com/homebrew-compiler-made-with-haskell-llvm-configuration (for help using llvm-hs-pure) +- https://blog.ocharles.org.uk/blog/posts/2012-12-17-24-days-of-hackage-optparse-applicative.html (for help parsing command line arguments with optparse-applicative) ### Tools - Language: Haskell -- Haskell tools: GHCup, Stack, Cabal, GHC 9.2 -- Libraries: megaparsec, parser-combinators, text, process, llvm-hs 15, llvm-hs-pure 15, +- Haskell/management tools: GHCup, Stack, Cabal, GHC 9.2, Nix +- Libraries: See `package.yaml` - Dependencies: llvm 15, clang 15 - IDE: VSCodium - Git platform: Forgejo diff --git a/package.yaml b/package.yaml index 72cd6c8..5e889c5 100644 --- a/package.yaml +++ b/package.yaml @@ -14,6 +14,7 @@ dependencies: - bytestring - string-conversions - transformers + - optparse-applicative >= 0.17 && < 1 tested-with: GHC == 9.2.8 category: Compilers/Interpreters diff --git a/really-bad-compiler-in-haskell.cabal b/really-bad-compiler-in-haskell.cabal index 7e52a66..0b1bace 100644 --- a/really-bad-compiler-in-haskell.cabal +++ b/really-bad-compiler-in-haskell.cabal @@ -33,6 +33,7 @@ executable really-bad-compiler-in-haskell , llvm-hs-pure ==15.* , megaparsec >=9.0.1 && <10 , mtl + , optparse-applicative >=0.17 && <1 , parser-combinators , process , string-conversions diff --git a/src/Main.hs b/src/Main.hs index c8b387f..dee11e3 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -7,16 +7,41 @@ import Data.ByteString.Char8 qualified as B import Data.Text.IO qualified as T import Main.LLVMGen import Main.Parser.Megaparsec +import Options.Applicative import System.Environment import System.Process (callCommand) -main :: IO () -main = do - fileName <- head <$> getArgs +data Opt = Opt + { filePath :: String, + showLLVM :: Bool, + showDebug :: Bool + } + +run :: Opt -> IO () +run opts = do + let fileName = filePath opts contents <- T.readFile fileName T.putStrLn "- Generating LLVM to './a.out.ll'..." result <- (llvmGen . parse) contents B.writeFile "a.out.ll" result T.putStrLn "- Compiling to executable './a.out'..." callCommand "clang a.out.ll" - T.putStrLn "- Done." \ No newline at end of file + T.putStrLn "- Done." + +main :: IO () +main = execParser opts >>= run + where + parser = + Opt + <$> argument str (metavar "FILE_PATH") + <*> switch + ( short 'l' + <> long "showLLVM" + <> help "Create .ll with LLVM used to compile the binary" + ) + <*> switch + ( short 'd' + <> long "showDebug" + <> help "Show debug output" + ) + opts = info parser mempty From e145e9107463f90c61f130bee477939f89ffeda5 Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Sat, 7 Oct 2023 00:50:33 -0500 Subject: [PATCH 13/13] Allow multiple print statements --- example/1.hear | 2 +- example/2.hear | 3 ++- src/Main/LLVMGen.hs | 6 +++--- src/Main/Parser/Megaparsec.hs | 9 ++++++--- src/Main/Type.hs | 21 +++++++++++++++++++-- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/example/1.hear b/example/1.hear index 62c2d80..62b1f81 100644 --- a/example/1.hear +++ b/example/1.hear @@ -1 +1 @@ -(5*(3-2)+-4-4) \ No newline at end of file +print(5*(3-2)+-4-4); \ No newline at end of file diff --git a/example/2.hear b/example/2.hear index 2078094..977a5ab 100644 --- a/example/2.hear +++ b/example/2.hear @@ -1 +1,2 @@ - (6+8/3) \ No newline at end of file + print(6+8/3); + print(5000); \ No newline at end of file diff --git a/src/Main/LLVMGen.hs b/src/Main/LLVMGen.hs index 8394fb7..620e168 100644 --- a/src/Main/LLVMGen.hs +++ b/src/Main/LLVMGen.hs @@ -56,7 +56,7 @@ getString str = do modify $ \env -> env {strings = M.insert str operand (strings env)} return operand -getLLVM :: Expr -> Module +getLLVM :: [Expr] -> Module getLLVM expr = flip evalState (Env {operands = M.empty, strings = M.empty}) $ buildModuleT "program" $ mdo @@ -66,7 +66,7 @@ getLLVM expr = function "main" [] i32 $ \_ -> mdo printNumStr <- globalStringPtr "%d\n" (mkName "str") lift $ registerString "%d\n" $ ConstantOperand printNumStr - _ <- exprToLLVM expr + _ <- forM_ expr exprToLLVM ret $ int32 0 -- @@ -109,7 +109,7 @@ exprToLLVM (Expr.Div a b) = mdo primToLLVM :: Int -> Operand primToLLVM i = int32 $ fromIntegral i -llvmGen :: Expr -> IO ByteString +llvmGen :: [Expr] -> IO ByteString llvmGen expr = do let l = getLLVM expr withContext $ \c -> withModuleFromAST c l moduleLLVMAssembly \ No newline at end of file diff --git a/src/Main/Parser/Megaparsec.hs b/src/Main/Parser/Megaparsec.hs index 9435ca0..aa1ea72 100644 --- a/src/Main/Parser/Megaparsec.hs +++ b/src/Main/Parser/Megaparsec.hs @@ -64,10 +64,13 @@ methodOp name f = Prefix $ f <$ (string name <* C.space) expr :: Parser Expr expr = makeExprParser term table -parseExpr :: Text -> Either (ParseErrorBundle Text Void) Expr -parseExpr = MP.parse (C.space *> expr <* eof) "" +statement :: Parser Expr +statement = expr <* symbol ";" -parse :: Text -> Expr +parseExpr :: Text -> Either (ParseErrorBundle Text Void) [Expr] +parseExpr = MP.parse (C.space *> many statement <* eof) "" + +parse :: Text -> [Expr] parse t = case parseExpr t of Right r -> r diff --git a/src/Main/Type.hs b/src/Main/Type.hs index 1c38360..23178b8 100644 --- a/src/Main/Type.hs +++ b/src/Main/Type.hs @@ -1,4 +1,10 @@ -module Main.Type (Expr (..)) where +module Main.Type + ( Expr (..), + -- AST (..) + ) +where + +import Data.Graph (Tree (Node)) data Expr = Lit Int @@ -10,4 +16,15 @@ data Expr | Print Expr deriving ( Show - ) \ No newline at end of file + ) + +-- data AST = AST Node + +-- data Node +-- = Reg +-- { cur :: Expr, +-- next :: Node +-- } +-- | End +-- { cur :: Expr +-- } \ No newline at end of file