diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2022-01-27 21:49:56 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2022-01-27 21:49:56 +0200 |
| commit | 7dbb6e631346cbb790300d823dff6efdf84288d7 (patch) | |
| tree | b1607a7be9339e362b59a9db13f39f13b2b45849 | |
Initial commit
| -rw-r--r-- | .gitignore | 4 | ||||
| -rwxr-xr-x | run.sh | 5 | ||||
| -rw-r--r-- | samples/foo.sample | 1 | ||||
| -rw-r--r-- | src/main.hs | 48 | ||||
| -rw-r--r-- | src/utils.hs | 7 |
5 files changed, 65 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1561641 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.hi +*.o +interpreter +.git/ @@ -0,0 +1,5 @@ +#!/bin/bash + +set -uxo pipefail +ghc -o interpreter src/*.hs +./interpreter $@ diff --git a/samples/foo.sample b/samples/foo.sample new file mode 100644 index 0000000..a64a29c --- /dev/null +++ b/samples/foo.sample @@ -0,0 +1 @@ +1 1 + .
\ No newline at end of file diff --git a/src/main.hs b/src/main.hs new file mode 100644 index 0000000..90de59e --- /dev/null +++ b/src/main.hs @@ -0,0 +1,48 @@ +module Main where + +import Data.Char +import System.Environment (getArgs) +import Utils + +getFilename [] = error "empty argument list" +getFilename (f : fs) = f + +data LWord + = LSymbol String + | LInteger Integer + deriving (Show) + +reprWord (LSymbol a) = a +reprWord (LInteger a) = show a + +parseWord rawStr + | all isDigit rawStr = LInteger (read rawStr) + | otherwise = LSymbol rawStr + +parseSource source = source $> words .> map parseWord + +interpretSource :: [LWord] -> [LWord] -> IO () +interpretSource _ [] = putStrLn "done" +interpretSource stack (word : rest) = do + newStack <- interpretWord stack word + interpretSource newStack rest + +interpretWord :: [LWord] -> LWord -> IO [LWord] +interpretWord stack word@(LInteger value) = pure $ word : stack +interpretWord (a : stack) word@(LSymbol ".") = do + putStrLn $ reprWord a + pure stack +interpretWord ((LInteger a) : (LInteger b) : stack) word@(LSymbol "+") = pure $ LInteger (a + b) : stack +interpretWord _ other = error $ "[error] runtime error at " ++ show other + +main :: IO () +main = do + args <- getArgs + let filename = getFilename args + putStrLn $ "[info] executing file " ++ filename + source <- readFile filename + putStrLn source + let parsed = parseSource source + putStrLn $ "[info] parsed words:\n" ++ show parsed + putStrLn "[info] interpreter output:" + interpretSource [] parsed diff --git a/src/utils.hs b/src/utils.hs new file mode 100644 index 0000000..33f3f6e --- /dev/null +++ b/src/utils.hs @@ -0,0 +1,7 @@ +module Utils where + +(.>) = flip (.) + +($>) = flip ($) + +infixr 6 $> |
