From 807ea6f1306f36fd03525aa8b95ece8c35fc9585 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Thu, 26 Sep 2024 23:58:27 +0200 Subject: [PATCH 1/2] implemented the program --- .gitignore | 2 + CHANGELOG.md | 11 +++ LICENSE | 26 ++++++ README.md | 3 + Setup.hs | 2 + app/Main.hs | 18 ++++ package.yaml | 61 ++++++++++++++ src/Lib.hs | 205 +++++++++++++++++++++++++++++++++++++++++++++ src/h.bf | 1 + src/h.ubc | Bin 0 -> 156 bytes src/hello-world.bf | 33 ++++++++ src/out.ubc | Bin 0 -> 916 bytes stack.yaml | 67 +++++++++++++++ stack.yaml.lock | 13 +++ test/Spec.hs | 2 + ubcf.cabal | 73 ++++++++++++++++ 16 files changed, 517 insertions(+) create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Setup.hs create mode 100644 app/Main.hs create mode 100644 package.yaml create mode 100644 src/Lib.hs create mode 100644 src/h.bf create mode 100644 src/h.ubc create mode 100644 src/hello-world.bf create mode 100644 src/out.ubc create mode 100644 stack.yaml create mode 100644 stack.yaml.lock create mode 100644 test/Spec.hs create mode 100644 ubcf.cabal diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c368d45 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.stack-work/ +*~ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2c307f9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog for `ubcf` + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to the +[Haskell Package Versioning Policy](https://pvp.haskell.org/). + +## Unreleased + +## 0.1.0.0 - YYYY-MM-DD diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a92a2d3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,26 @@ +Copyright 2024 VegOwOtenks + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..96d6fd9 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# ubcf +brainfuck to ubc compiler +assumes the output will be on the ubcf-runtime diff --git a/Setup.hs b/Setup.hs new file mode 100644 index 0000000..9a994af --- /dev/null +++ b/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/app/Main.hs b/app/Main.hs new file mode 100644 index 0000000..24e4730 --- /dev/null +++ b/app/Main.hs @@ -0,0 +1,18 @@ +module Main (main) where + +import Lib +import Control.Monad (mapM_) +import Data.Binary (Word32, Word8, encode) +import Data.Bits +import qualified Data.ByteString.Lazy as BL + +convertWord32 :: Word32 -> [Word8] +convertWord32 w = [fromIntegral (w), fromIntegral (w .>>. 8), fromIntegral (w .>>. 16), fromIntegral (w .>>. 24)] + +main :: IO () +main = do + s <- getContents + let tokens = tokenize s + case parseTokens tokens of + Left err -> putStr err + Right ops -> mapM_ (BL.putStr . encode) . (concatMap (convertWord32)) $ (compile ops) diff --git a/package.yaml b/package.yaml new file mode 100644 index 0000000..da29072 --- /dev/null +++ b/package.yaml @@ -0,0 +1,61 @@ +name: ubcf +version: 0.1.0.0 +github: "githubuser/ubcf" +license: BSD-3-Clause +author: "VegOwOtenks" +maintainer: "vegowotenks@jossco.de" +copyright: "AGPL3" + +extra-source-files: +- README.md +- CHANGELOG.md + +# Metadata used when publishing your package +# synopsis: Short description of your package +# category: Web + +# To avoid duplicated efforts in documentation and dealing with the +# complications of embedding Haddock markup inside cabal files, it is +# common to point users to the README.md file. +description: Please see the README on GitHub at + +dependencies: +- base >= 4.7 && < 5 +- binary +- bytestring + +ghc-options: +- -Wall +- -Wcompat +- -Widentities +- -Wincomplete-record-updates +- -Wincomplete-uni-patterns +- -Wmissing-export-lists +- -Wmissing-home-modules +- -Wpartial-fields +- -Wredundant-constraints + +library: + source-dirs: src + +executables: + ubcf-exe: + main: Main.hs + source-dirs: app + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - ubcf + +tests: + ubcf-test: + main: Spec.hs + source-dirs: test + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - ubcf diff --git a/src/Lib.hs b/src/Lib.hs new file mode 100644 index 0000000..dc76e02 --- /dev/null +++ b/src/Lib.hs @@ -0,0 +1,205 @@ +module Lib + ( tokenize, BrainFuckToken, parseTokens, BrainFuckOperation, compile, CompileState + ) where + +import Control.Monad (liftM) +import qualified Data.Word as Word +import Data.Bits +import Data.Int (Int32) + +data BrainFuckToken = OperatorPlus Int | OperatorMinus Int | OperatorLeft Int | OperatorRight Int | OperatorSkip | OperatorContinue | OperatorPut | OperatorRead | Comment String + deriving Show + +partitionOn :: (a -> Bool) -> [a] -> ([a], [a]) +partitionOn condition (a:as) + | condition a = ([], a:as) + | otherwise = (a:pre, post) + where + (pre, post) = partitionOn condition as +partitionOn _ [] = ([], []) + +tokenizeQuantified :: Char -> String -> (Int -> BrainFuckToken) -> [BrainFuckToken] +tokenizeQuantified target cs constructor = constructor (length targetPartition) : tokenize restPartition + where + (targetPartition, restPartition) = partitionOn (/=target) cs + +tokenizeComment :: String -> [BrainFuckToken] +tokenizeComment s = Comment comment : tokenize rest + where + (comment, rest) = partitionOn (flip elem "+-<>[]") s + +tokenize :: String -> [BrainFuckToken] +tokenize [] = [] +tokenize (c:cs) + | c == '+' = tokenizeQuantified '+' (c:cs) OperatorPlus + | c == '-' = tokenizeQuantified '-' (c:cs) OperatorMinus + | c == '<' = tokenizeQuantified '<' (c:cs) OperatorLeft + | c == '>' = tokenizeQuantified '>' (c:cs) OperatorRight + | c == '[' = OperatorSkip : tokenize cs + | c == ']' = OperatorContinue : tokenize cs + | c == '.' = OperatorPut : tokenize cs + | c == ',' = OperatorRead : tokenize cs + | otherwise = tokenizeComment (c:cs) + +data BrainFuckOperation = IncrementCell Int | DecrementCell Int | MoveLeft Int | MoveRight Int | PutChar | ReadChar | Conditionally [BrainFuckOperation] + deriving Show + +parseTokens :: [BrainFuckToken] -> Either String [BrainFuckOperation] +parseTokens ts = liftM (fst) (parseTokens' 0 ts) + +parseTokens' :: Int -> [BrainFuckToken] -> Either String ([BrainFuckOperation], [BrainFuckToken]) +parseTokens' 0 [] = Right ([], []) +parseTokens' n [] = Left ("Missing " ++ show n ++ " closing brackets ']'") +parseTokens' l (OperatorPlus amount:ts) = liftM (\t -> (IncrementCell amount:fst t, snd t)) (parseTokens' l ts) +parseTokens' l (OperatorMinus amount:ts) = liftM (\t -> (DecrementCell amount:fst t, snd t)) (parseTokens' l ts) +parseTokens' l (OperatorLeft amount:ts) = liftM (\t -> (MoveLeft amount:fst t, snd t)) (parseTokens' l ts) +parseTokens' l (OperatorRight amount:ts) = liftM (\t -> (MoveRight amount:fst t, snd t)) (parseTokens' l ts) +parseTokens' l (OperatorSkip :ts) = either (Left) (\(cs, _) -> either (Left) (Right . \(os, rs) -> (Conditionally cs:os, rs)) r) t + where + t = parseTokens' (l+1) ts + r = either (Left) (parseTokens' l . snd) t +parseTokens' 0 (OperatorContinue :_) = Left ("Found ] when there was none expected") +parseTokens' _ (OperatorContinue :ts) = Right ([], ts) +parseTokens' l (OperatorPut :ts) = liftM (\t -> ( PutChar:fst t, snd t)) (parseTokens' l ts) +parseTokens' l (OperatorRead :ts) = liftM (\t -> (ReadChar:fst t, snd t)) (parseTokens' l ts) +parseTokens' l (Comment _ :ts) = parseTokens' l ts + + +ubcOpcodeLoadUpper :: Word.Word32 +ubcOpcodeLoadUpper = 0x02000000 + +ubcOpcodeLoadLower :: Word.Word32 +ubcOpcodeLoadLower = 0x03000000 + +ubcOpcodeMem2Reg :: Word.Word32 +ubcOpcodeMem2Reg = 0x04000000 +ubcOpcodeReg2Mem :: Word.Word32 +ubcOpcodeReg2Mem = 0x05000000 + +ubcOpcodeJumpRel :: Word.Word32 +ubcOpcodeJumpRel = 0x09000000 + +ubcOpcodeForeignCall :: Word.Word32 +ubcOpcodeForeignCall = 0x0F000000 + +ubcOpcodeAddU :: Word.Word32 +ubcOpcodeAddU = 0x80000000 +ubcOpcodeSubU :: Word.Word32 +ubcOpcodeSubU = 0x81000000 +ubcOpcodeCmpU :: Word.Word32 +ubcOpcodeCmpU = 0x89000000 + +ubcConditionNone :: Word.Word32 +ubcConditionNone = 0x00000000 +ubcConditionEq :: Word.Word32 +ubcConditionEq = 0x00800000 + +ubcForeignCall :: Int32 -> Word.Word32 +ubcForeignCall r = ubcOpcodeForeignCall .|. ubcInstructionRegArg1 r + +ubcInstructionRegArg1 :: Int32 -> Word.Word32 +ubcInstructionRegArg1 r + | r < 16 = (shiftL (fromIntegral r .&. 0xF) 16) + | otherwise = error "Register index > 16" + +ubcInstructionRegArg2 :: Int32 -> Word.Word32 +ubcInstructionRegArg2 r + | r < 16 = (shiftL (fromIntegral r .&. 0xF) 12) + | otherwise = error "Register index > 16" + +ubcInstructionRegArg3 :: Int32 -> Word.Word32 +ubcInstructionRegArg3 r + | r < 16 = (shiftL (fromIntegral r .&. 0xF) 8) + | otherwise = error "Register index > 16" + +ubcInstructionPayLoad :: Word.Word32 -> Word.Word32 +ubcInstructionPayLoad w = 0x0000FFFF .&. w + +ubcLoadUpper :: Word.Word16 -> Int32 -> Word.Word32 +ubcLoadUpper w r = ubcOpcodeLoadUpper .|. ubcInstructionRegArg1 r .|. ubcInstructionPayLoad (fromIntegral w) + +ubcLoadLower :: Word.Word16 -> Int32 -> Word.Word32 +ubcLoadLower w r = ubcOpcodeLoadLower .|. ubcInstructionRegArg1 r .|. ubcInstructionPayLoad (fromIntegral w) + +ubcLoadIntWords :: Int32 -> Int32 -> [Word.Word32] +ubcLoadIntWords i r = [ubcLoadUpper (fromIntegral u) r, ubcLoadLower (fromIntegral l) r] + where + w = fromIntegral i :: Word.Word32 + u = w .>>. 16 + l = w .&. 0xFFFF + +ubcCmpU :: Int32 -> Int32 -> Word.Word32 +ubcCmpU a b = ubcOpcodeCmpU .|. ubcInstructionRegArg1 a .|. ubcInstructionRegArg2 b + +ubcJumpRel :: Int32 -> Int32 -> Word.Word32 -> [Word.Word32] +ubcJumpRel d r c = ubcLoadIntWords d r ++ [ubcOpcodeJumpRel .|. ubcInstructionRegArg1 r .|. c] + +ubcLoadCellWord :: Int32 -> Word.Word32 +ubcLoadCellWord r = ubcOpcodeMem2Reg .|. ubcConditionNone .|. ubcInstructionRegArg1 r .|. ubcInstructionRegArg2 0 + +ubcStoreCellWord :: Int32 -> Word.Word32 +ubcStoreCellWord r = ubcOpcodeReg2Mem .|. ubcInstructionRegArg1 0 .|. ubcInstructionRegArg2 r + +ubcAddWord :: Int32 -> Int32 -> Int32 -> Word.Word32 +ubcAddWord d a b = ubcOpcodeAddU .|. ubcInstructionRegArg1 d .|. ubcInstructionRegArg2 a .|. ubcInstructionRegArg3 b + +ubcSubWord :: Int32 -> Int32 -> Int32 -> Word.Word32 +ubcSubWord d a b = ubcOpcodeSubU .|. ubcInstructionRegArg1 d .|. ubcInstructionRegArg2 a .|. ubcInstructionRegArg3 b + +ubcIncrementRegisterWords :: Int32 -> Int32 -> Int32 -> [Word.Word32] +ubcIncrementRegisterWords i ir cr = ubcLoadIntWords i ir ++ [ubcAddWord cr cr ir] + +ubcDecrementRegisterWords :: Int32 -> Int32 -> Int32 -> [Word.Word32] +ubcDecrementRegisterWords i ir cr = ubcLoadIntWords i ir ++ [ubcSubWord cr cr ir] + +data CompileState = CompileState { isCellLoaded :: Bool, isCellModified :: Bool } + +compileIncrement :: CompileState -> Int32 -> [BrainFuckOperation] -> [Word.Word32] +compileIncrement state i os + | isCellLoaded state = ubcIncrementRegisterWords i 2 1 ++ compile' (state{isCellModified=True}) os + | otherwise = ubcLoadCellWord 1 : compileIncrement (state{isCellLoaded=True}) i os + +compileDecrement :: CompileState -> Int32 -> [BrainFuckOperation] -> [Word.Word32] +compileDecrement state i os + | isCellLoaded state = ubcDecrementRegisterWords i 2 1 ++ compile' (state{isCellModified=True}) os + | otherwise = ubcLoadCellWord 1 : compileIncrement (state{isCellLoaded=True}) i os + +compileMoveLeft :: CompileState -> Int32 -> [BrainFuckOperation] -> [Word.Word32] +compileMoveLeft state d os + | isCellModified state = ubcStoreCellWord 1 : compileMoveLeft (state{isCellModified=False}) d os + | otherwise = ubcDecrementRegisterWords d 2 0 ++ compile' (state{isCellLoaded=False}) os + +compileMoveRight :: CompileState -> Int32 -> [BrainFuckOperation] -> [Word.Word32] +compileMoveRight state d os + | isCellModified state = ubcStoreCellWord 1 : compileMoveLeft (state{isCellModified=False}) d os + | otherwise = ubcIncrementRegisterWords d 2 0 ++ compile' (state{isCellLoaded=False}) os + +compileConditionally :: CompileState -> [BrainFuckOperation] -> [BrainFuckOperation] -> [Word.Word32] +compileConditionally s cs os + | isCellLoaded s = skipBlock ++ contained ++ continueBlock ++ compile os + | otherwise = ubcLoadCellWord 1 : compileConditionally (s{isCellLoaded=True}) cs os + where + contained = compile cs + containedLength = length contained + forwardDistance = containedLength + 4 -- plus one to land after the skip Block + continueDistance = negate (containedLength + 10) + -- continueBlock has length 1 + 3 = 4 + continueBlock = ubcStoreCellWord 1 : ubcJumpRel (fromIntegral continueDistance) 2 ubcConditionNone + -- skipBlock has length 2 + 1 + 3 = 6 + skipBlock = ubcLoadIntWords 0 2 ++ [ubcCmpU 1 2] ++ (ubcJumpRel (fromIntegral forwardDistance) 2 ubcConditionEq) + +compile :: [BrainFuckOperation] -> [Word.Word32] +compile = compile' CompileState{isCellLoaded=False, isCellModified=False} + +-- 0: cell pointer register +-- 1: cell value register +-- 2: temporary register +compile' :: CompileState -> [BrainFuckOperation] -> [Word.Word32] +compile' _ [] = [] +compile' state (IncrementCell amount:os) = compileIncrement state (fromIntegral amount) os +compile' state (DecrementCell amount:os) = compileDecrement state (fromIntegral amount) os +compile' state (MoveRight distance:os) = compileMoveRight state (fromIntegral distance) os +compile' state (MoveLeft distance:os) = compileMoveLeft state (fromIntegral distance) os +compile' state (Conditionally ops:os) = compileConditionally state ops os +compile' state (PutChar :os) = ubcLoadIntWords 0 2 ++ [ubcForeignCall 2] ++ compile' state os +compile' state (ReadChar :os) = ubcLoadIntWords 1 2 ++ [ubcForeignCall 2] ++ compile' state os diff --git a/src/h.bf b/src/h.bf new file mode 100644 index 0000000..b7fd0b2 --- /dev/null +++ b/src/h.bf @@ -0,0 +1 @@ +++++++[>++++++++<-]>-. diff --git a/src/h.ubc b/src/h.ubc new file mode 100644 index 0000000000000000000000000000000000000000..b9dbcd777aed7a77495a6865917488fc27cb186d GIT binary patch literal 156 zcmZvVK@LDr3`D2%5mtl?II3^wq>fP?Qn9dT@{)No1*`$c4lI~$6UP;-c8C`-_Cai7 fBAlnwXJuip|KNB5u`CJD literal 0 HcmV?d00001 diff --git a/src/hello-world.bf b/src/hello-world.bf new file mode 100644 index 0000000..6a167f0 --- /dev/null +++ b/src/hello-world.bf @@ -0,0 +1,33 @@ + 1 +++++ +++ Set Cell #0 to 8 + 2 [ + 3 >++++ Add 4 to Cell #1; this will always set Cell #1 to 4 + 4 [ as the cell will be cleared by the loop + 5 >++ Add 4*2 to Cell #2 + 6 >+++ Add 4*3 to Cell #3 + 7 >+++ Add 4*3 to Cell #4 + 8 >+ Add 4 to Cell #5 + 9 <<<<- Decrement the loop counter in Cell #1 +10 ] Loop till Cell #1 is zero +11 >+ Add 1 to Cell #2 +12 >+ Add 1 to Cell #3 +13 >- Subtract 1 from Cell #4 +14 >>+ Add 1 to Cell #6 +15 [<] Move back to the first zero cell you find; this will +16 be Cell #1 which was cleared by the previous loop +17 <- Decrement the loop Counter in Cell #0 +18 ] Loop till Cell #0 is zero +19 +20 The result of this is: +21 Cell No : 0 1 2 3 4 5 6 +22 Contents: 0 0 72 104 88 32 8 +23 Pointer : ^ +24 +25 >>. Cell #2 has value 72 which is 'H' +26 >---. Subtract 3 from Cell #3 to get 101 which is 'e' +27 +++++ ++..+++. Likewise for 'llo' from Cell #3 +28 >>. Cell #5 is 32 for the space +29 <-. Subtract 1 from Cell #4 for 87 to give a 'W' +30 <. Cell #3 was set to 'o' from the end of 'Hello' +31 +++.----- -.----- ---. Cell #3 for 'rl' and 'd' +32 >>+. Add 1 to Cell #5 gives us an exclamation point +33 >++. And finally a newline from Cell #6 diff --git a/src/out.ubc b/src/out.ubc new file mode 100644 index 0000000000000000000000000000000000000000..21d699ce6ba662318b055066d705512e815d1ed0 GIT binary patch literal 916 zcmbVKK@!3+2qdH($CFN9;N8dh1?$ZjALnDdM<4{Lp`Fp&wpo^403Zzjh$CQzDP0+7 zhv_@RDc$-1g)!Xrj1yx7;@A3NrRKa*gRSNWqtl$5ruq2uT|9Cotrw37rtjZNL3|d@ zhhaX?jlBN)F4-e5G+WZQneY1f&76n*zIwl_*&dFoy=B+Z3-I7F*-mZ#&6D!{t=JB~ zI9@l@(Vcwept+Y``aHf*cNbox-euUEG&BS0>n%@7u=njbs=2.9" +# +# Override the architecture used by Stack, especially useful on Windows +# arch: i386 +# arch: x86_64 +# +# Extra directories used by Stack for building +# extra-include-dirs: [/path/to/dir] +# extra-lib-dirs: [/path/to/dir] +# +# Allow a newer minor version of GHC than the snapshot specifies +# compiler-check: newer-minor diff --git a/stack.yaml.lock b/stack.yaml.lock new file mode 100644 index 0000000..f067da3 --- /dev/null +++ b/stack.yaml.lock @@ -0,0 +1,13 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 31a722458578b1f709b6fe098d9027bbb5c04b4430e7338a5e69707bd3990e5d + size: 720019 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/35.yaml + original: + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/35.yaml diff --git a/test/Spec.hs b/test/Spec.hs new file mode 100644 index 0000000..cd4753f --- /dev/null +++ b/test/Spec.hs @@ -0,0 +1,2 @@ +main :: IO () +main = putStrLn "Test suite not yet implemented" diff --git a/ubcf.cabal b/ubcf.cabal new file mode 100644 index 0000000..1429477 --- /dev/null +++ b/ubcf.cabal @@ -0,0 +1,73 @@ +cabal-version: 2.2 + +-- This file has been generated from package.yaml by hpack version 0.35.2. +-- +-- see: https://github.com/sol/hpack + +name: ubcf +version: 0.1.0.0 +description: Please see the README on GitHub at +homepage: https://github.com/githubuser/ubcf#readme +bug-reports: https://github.com/githubuser/ubcf/issues +author: VegOwOtenks +maintainer: vegowotenks@jossco.de +copyright: AGPL3 +license: BSD-3-Clause +license-file: LICENSE +build-type: Simple +extra-source-files: + README.md + CHANGELOG.md + +source-repository head + type: git + location: https://github.com/githubuser/ubcf + +library + exposed-modules: + Lib + other-modules: + Paths_ubcf + autogen-modules: + Paths_ubcf + hs-source-dirs: + src + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + build-depends: + base >=4.7 && <5 + , binary + , bytestring + default-language: Haskell2010 + +executable ubcf-exe + main-is: Main.hs + other-modules: + Paths_ubcf + autogen-modules: + Paths_ubcf + hs-source-dirs: + app + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N + build-depends: + base >=4.7 && <5 + , binary + , bytestring + , ubcf + default-language: Haskell2010 + +test-suite ubcf-test + type: exitcode-stdio-1.0 + main-is: Spec.hs + other-modules: + Paths_ubcf + autogen-modules: + Paths_ubcf + hs-source-dirs: + test + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N + build-depends: + base >=4.7 && <5 + , binary + , bytestring + , ubcf + default-language: Haskell2010 From c83faf4f539bf07029072107235e2b022f87fc2b Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 27 Sep 2024 00:00:16 +0200 Subject: [PATCH 2/2] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 96d6fd9..ad47ca7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # ubcf -brainfuck to ubc compiler +brainfuck to ubc compiler assumes the output will be on the ubcf-runtime