Browse Source
Hack assembler definitions are now in separate module. This will be handy when I implement VM compilermaster
4 changed files with 187 additions and 145 deletions
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
|
||||
module Main (main) where |
||||
|
||||
import Control.Monad (forM_) |
||||
import Data.Bits (testBit) |
||||
import Data.Foldable (foldl', foldr) |
||||
import qualified Data.Map.Strict as M |
||||
import qualified Data.Text as T |
||||
import qualified Data.Text.IO as TIO |
||||
import Nand2Tetris.Hack (AsmLine (LineInstruction), addLabels, |
||||
addVars, compile, defaultVars, |
||||
hackParser) |
||||
import Options.Applicative (execParser, fullDesc, header, help, |
||||
helper, info, long, metavar, progDesc, |
||||
short, strOption, (<**>)) |
||||
import System.IO (IOMode (WriteMode), hPutStrLn, withFile) |
||||
import Text.Megaparsec (runParser) |
||||
import Text.Megaparsec.Error (ParseErrorBundle, |
||||
ShowErrorComponent (showErrorComponent), |
||||
errorBundlePretty) |
||||
|
||||
data Options = |
||||
Options |
||||
{ |
||||
inputFile :: FilePath, |
||||
outputFile :: FilePath |
||||
} |
||||
|
||||
main :: IO () |
||||
main = do |
||||
options <- execParser opts |
||||
programText <- TIO.readFile (inputFile options) |
||||
let result = runParser hackParser (inputFile options) programText |
||||
case result of |
||||
Left err -> putStrLn $ errorBundlePretty err |
||||
Right parsed -> do |
||||
let labels = addLabels M.empty parsed |
||||
let vars = addVars defaultVars labels parsed |
||||
print vars |
||||
let compiled = compile labels vars $ foldr addInstr [] parsed |
||||
case compiled of |
||||
Left err -> putStrLn $ "Error: " <> T.unpack err |
||||
Right program -> withFile (outputFile options) WriteMode $ \h -> forM_ program (\x -> hPutStrLn h (printInstruction x)) |
||||
where |
||||
printInstruction w = concatMap (\x -> if testBit w x then "1" else "0") $ reverse [0..15] |
||||
regVars = defaultVars |
||||
addInstr (LineInstruction instr) is = instr : is |
||||
addInstr _ is = is |
||||
|
||||
opts = info (hackAsmOptParser <**> helper) |
||||
( fullDesc |
||||
<> progDesc "Compiles a file with Hack assembly instructions to Hask binary code" |
||||
<> header "hackasm - assembler for hack CPU (nand2tetris)" ) |
||||
hackAsmOptParser = Options <$> |
||||
strOption ( long "input" |
||||
<> short 'i' |
||||
<> metavar "FILENAME" |
||||
<> help "Input file" ) <*> |
||||
strOption ( long "output" |
||||
<> short 'o' |
||||
<> metavar "FILENAME" |
||||
<> help "Output file" ) |
||||
@ -1,26 +0,0 @@
@@ -1,26 +0,0 @@
|
||||
name: hackasm |
||||
version: 0.1.0.0 |
||||
-- synopsis: |
||||
-- description: |
||||
homepage: https://github.com/githubuser/hackasm#readme |
||||
license: BSD3 |
||||
license-file: LICENSE |
||||
author: Author name here |
||||
maintainer: example@example.com |
||||
copyright: 2021 Author name here |
||||
category: Web |
||||
build-type: Simple |
||||
cabal-version: >=1.10 |
||||
extra-source-files: README.md |
||||
|
||||
executable hackasm |
||||
hs-source-dirs: src |
||||
main-is: Main.hs |
||||
default-language: Haskell2010 |
||||
build-depends: base >= 4.7 && < 5 |
||||
, text |
||||
, megaparsec |
||||
, optparse-applicative |
||||
, containers |
||||
, bytestring |
||||
, binary |
||||
@ -0,0 +1,37 @@
@@ -0,0 +1,37 @@
|
||||
name: nand2tetris |
||||
version: 0.1.0.0 |
||||
-- synopsis: |
||||
-- description: |
||||
homepage: https://c.asakul.ru/asakul/nand2tetris |
||||
license: BSD3 |
||||
license-file: LICENSE |
||||
author: Denis Tereshkin |
||||
maintainer: denis@kasan.ws |
||||
copyright: 2021 Denis Tereshkin |
||||
category: Web |
||||
build-type: Simple |
||||
cabal-version: >=1.10 |
||||
extra-source-files: README.md |
||||
|
||||
executable hackasm |
||||
hs-source-dirs: app |
||||
main-is: HackAsm.hs |
||||
default-language: Haskell2010 |
||||
build-depends: base >= 4.7 && < 5 |
||||
, nand2tetris |
||||
, text |
||||
, megaparsec |
||||
, optparse-applicative |
||||
, containers |
||||
, bytestring |
||||
|
||||
library |
||||
hs-source-dirs: src |
||||
default-language: Haskell2010 |
||||
exposed-modules: Nand2Tetris.Hack |
||||
build-depends: base >= 4.7 && < 5 |
||||
, text |
||||
, megaparsec |
||||
, containers |
||||
|
||||
|
||||
Loading…
Reference in new issue