summaryrefslogtreecommitdiff
path: root/DSL/Intrinsics.hs
diff options
context:
space:
mode:
authorMatthew Hall <hallmatthew314@gmail.com>2023-02-16 23:05:24 +1300
committerMatthew Hall <hallmatthew314@gmail.com>2023-02-16 23:05:24 +1300
commitb83325c4b5c324a42acfe366cf58b455f8aa941f (patch)
tree7c78add5c12970ebd3f3c50f08808a4d6a636778 /DSL/Intrinsics.hs
parentea59151d80958f14c69105ba6b40162b8e191597 (diff)
Big file-structure refactor
Diffstat (limited to 'DSL/Intrinsics.hs')
-rw-r--r--DSL/Intrinsics.hs110
1 files changed, 110 insertions, 0 deletions
diff --git a/DSL/Intrinsics.hs b/DSL/Intrinsics.hs
new file mode 100644
index 0000000..11b37f3
--- /dev/null
+++ b/DSL/Intrinsics.hs
@@ -0,0 +1,110 @@
+module DSL.Intrinsics where
+
+import DSL.Types
+import DSL.Util
+
+dump :: StackModifier
+dump = StackModifier { smName="DUMP", smTypes=ts, smFunc=f }
+ where
+ ts = [tAny]
+ f (x:xs) = putStrLn (show x) >> return xs
+ f _ = unreachable
+
+drop' :: StackModifier
+drop' = StackModifier { smName="DROP", smTypes=ts, smFunc=f }
+ where
+ ts = [tAny]
+ f (_:xs) = return xs
+ f _ = unreachable
+
+swap :: StackModifier
+swap = StackModifier { smName="SWAP", smTypes=ts, smFunc=f }
+ where
+ ts = [tAny, tAny]
+ f (x:y:xs) = return $ y:x:xs
+ f _ = unreachable
+
+dup :: StackModifier
+dup = StackModifier { smName="DUP", smTypes=ts, smFunc=f }
+ where
+ ts = [tAny]
+ f (x:xs) = return $ x:x:xs
+ f _ = unreachable
+
+over :: StackModifier
+over = StackModifier { smName="OVER", smTypes=ts, smFunc=f }
+ where
+ ts = [tAny, tAny]
+ f (x:y:xs) = return $ y:x:y:xs
+ f _ = unreachable
+
+rot :: StackModifier
+rot = StackModifier { smName="ROT", smTypes=ts, smFunc=f }
+ where
+ ts = [tAny, tAny, tAny]
+ f (x:y:z:xs) = return $ y:z:x:xs
+ f _ = unreachable
+
+binArithmetic :: String -> (Integer -> Integer -> [Integer]) -> StackModifier
+binArithmetic name f = StackModifier { smName=name, smTypes=ts, smFunc=f' }
+ where
+ ts = [tInt, tInt]
+ f' (StackInt x:StackInt y:xs) = return $ (StackInt <$> f x y) ++ xs
+ f' _ = unreachable
+
+plus :: StackModifier
+plus = binArithmetic "PLUS" $ \ x y -> [x + y]
+
+minus :: StackModifier
+minus = binArithmetic "MINUS" $ \ x y -> [x - y]
+
+times :: StackModifier
+times = binArithmetic "TIMES" $ \ x y -> [x * y]
+
+divMod' :: StackModifier
+divMod' = binArithmetic "DIVMOD" $ \ x y -> [mod x y, div x y]
+
+not' :: StackModifier
+not' = StackModifier { smName="NOT", smTypes=ts, smFunc=f }
+ where
+ ts = [tBool]
+ f (StackBool x:xs) = return $ StackBool (not x):xs
+ f _ = unreachable
+
+binBoolean :: String -> (Bool -> Bool -> [Bool]) -> StackModifier
+binBoolean name f = StackModifier { smName=name, smTypes=ts, smFunc=f' }
+ where
+ ts = [tBool, tBool]
+ f' (StackBool x:StackBool y:xs) = return $ (StackBool <$> f x y) ++ xs
+ f' _ = unreachable
+
+and' :: StackModifier
+and' = binBoolean "AND" $ \ x y -> [x && y]
+
+or' :: StackModifier
+or' = binBoolean "OR" $ \ x y -> [x || y]
+
+xor :: StackModifier
+xor = binBoolean "XOR" $ \ x y -> [x /= y]
+
+equal :: StackModifier
+equal = StackModifier { smName="EQUAL", smTypes=ts, smFunc=f }
+ where
+ ts = [tAny, tAny]
+ f (x:y:xs) = return $ StackBool (x == y):xs
+ f _ = unreachable
+
+lessThan :: StackModifier
+lessThan = StackModifier { smName="LESSTHAN", smTypes=ts, smFunc=f }
+ where
+ ts = [tInt, tInt]
+ f (StackInt x:StackInt y:xs) = return $ StackBool(x < y):xs
+ f _ = unreachable
+
+greaterThan :: StackModifier
+greaterThan = StackModifier { smName="GREATERTHAN", smTypes=ts, smFunc=f }
+ where
+ ts = [tInt, tInt]
+ f (StackInt x:StackInt y:xs) = return $ StackBool(x > y):xs
+ f _ = unreachable
+