diff options
author | Marvin Borner | 2024-12-28 23:33:53 +0100 |
---|---|---|
committer | Marvin Borner | 2024-12-28 23:33:53 +0100 |
commit | 408c3fc38dd6ec577bf6d0b3386a0bda1a45f526 (patch) | |
tree | f16055200d1eb87975d0f52472a3395026a846cf /lllars/parser.hs | |
parent | 0e93cc19dcef679e568d40f06d7b1329d3196562 (diff) |
ABSTRACT
Diffstat (limited to 'lllars/parser.hs')
-rw-r--r-- | lllars/parser.hs | 132 |
1 files changed, 5 insertions, 127 deletions
diff --git a/lllars/parser.hs b/lllars/parser.hs index 3d1e713..bb3afc2 100644 --- a/lllars/parser.hs +++ b/lllars/parser.hs @@ -1,16 +1,8 @@ -import Control.Monad.State -import Data.Bits ( (.&.) - , (.^.) - , (.|.) - ) import Data.Functor ( ($>) ) -import Data.HashMap.Strict ( HashMap ) -import qualified Data.HashMap.Strict as M import Data.List ( intercalate ) import Data.Void import Text.Megaparsec hiding ( Label , Pos - , State , label ) import Text.Megaparsec.Char hiding ( space ) @@ -132,127 +124,13 @@ license = string "!!! all rights reserved to lars <3 !!!\n\n" program :: Parser Program program = license *> sepEndBy instr (some $ char '\n') -type EvalState = HashMap Address Int - -evalAccess :: Access -> State EvalState Int -evalAccess = go 0 - where - go 0 (Access address) = return address - go n (Access address) = do - m <- get - go (n - 1) (Access $ M.lookupDefault 0 address m) - go n (SAccess access) = go (n + 1) access - -evilOperation :: Int -> Operator -> Int -> Int -evilOperation a ADD b = a + b -evilOperation a MUL b = a * b -evilOperation a SUB b = a - b -evilOperation a DIV b = a `div` b -evilOperation a AND b = a .&. b -evilOperation a OR b = a .|. b -evilOperation a XOR b = a .^. b - -evalAddressation :: Addressation -> State EvalState Int -evalAddressation (Address access ) = evalAccess access -evalAddressation (BinaryOperation a operator b) = do - resA <- evalAccess a - resB <- evalAccess b - return $ evilOperation resA operator resB - -eval :: Int -> Program -> State EvalState () -eval n p = go (drop n p) - where - go ((Comment _ ) : ps) = go ps - go ((Write address addressation) : ps) = do - source <- evalAddressation addressation - modify (M.insert address source) - go ps - go ((LarsCall call ) : ps) = go ps -- TODO - go ((Label _ ) : ps) = go ps -- TODO: better - go ((GoTo label) : ps) = do - let is = [ i | (i, l@(Label n)) <- zip [0 ..] p, n == label ] - case is of - [i] -> eval (i + 1) p - _ -> error $ "invalid jump " <> label - go ((Branch IfTrue access label) : ps) = do - address <- evalAccess access - m <- get - case address of - 0 -> go ps - _ -> go [GoTo label] - go ((Branch IfFalse access label) : ps) = do - address <- evalAccess access - m <- get - case address of - 0 -> go [GoTo label] - _ -> go ps - go [] = return () - -compileOperation :: String -> Operator -> String -> String -compileOperation a ADD b = a <> " + " <> b -compileOperation a MUL b = a <> " * " <> b -compileOperation a SUB b = a <> " - " <> b -compileOperation a DIV b = a <> " / " <> b -compileOperation a AND b = a <> " & " <> b -compileOperation a OR b = a <> " | " <> b -compileOperation a XOR b = a <> " ^ " <> b - -compileAccess :: Access -> String -compileAccess (Access address) = show address -compileAccess (SAccess access ) = "heap[" <> compileAccess access <> "]" - -compileAddressation :: Addressation -> String -compileAddressation (Address access) = compileAccess access -compileAddressation (BinaryOperation a operator b) = - compileOperation (compileAccess a) operator (compileAccess b) - -compile :: Program -> String -compile ((Comment comment) : ps) = "// " <> comment <> "\n" ++ compile ps -compile ((Write address addressation) : ps) = - "heap[" - <> show address - <> "] = " - <> compileAddressation addressation - <> ";\n" - ++ compile ps -compile ((LarsCall call ) : ps) = compile ps -- TODO -compile ((Label label) : ps) = "" <> label <> ":\n" ++ compile ps -compile ((GoTo label) : ps) = "goto " <> label <> ";\n" ++ compile ps -compile ((Branch IfTrue access label) : ps) = - "if (" - <> compileAccess access - <> ")" - <> " goto " - <> label - <> ";\n" - ++ compile ps -compile ((Branch IfFalse access label) : ps) = - "if (!(" - <> compileAccess access - <> "))" - <> " goto " - <> label - <> ";\n" - ++ compile ps -compile [] = "" - -preamble :: String -preamble = - "#include <stdio.h>\nint main(int argc, char *argv[]) { unsigned int heap[10000] = { 0 }; " - -postamble :: String -postamble = "printf(\"%x\\n\", heap[8159]); }" - -preamblify :: String -> String -preamblify amble = preamble ++ amble ++ postamble - main :: IO () main = do f <- readFile "fac.lll" case runParser (program <* many (char '\n') <* eof) "" f of - Right ps -> do - -- let ev = runState (eval 0 ps) M.empty - -- print ev - putStrLn $ preamblify $ compile ps - -- putStrLn $ "[" <> intercalate "," (show <$> ps) <> "]" + Right ps -> + putStrLn + $ "{ \"instructions\": [" + <> intercalate "," (show <$> ps) + <> "]}" Left err -> putStrLn $ errorBundlePretty err |