Skip to content

Commit

Permalink
Binding and unbinding functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Mercerenies committed Jun 20, 2017
1 parent 90fa33b commit d65d151
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 3 deletions.
35 changes: 34 additions & 1 deletion Shiny/Standard.hs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,11 @@ stdFuncs = fromList [
(Var "ge", func gets),
(Var "-", func' interaction),
(Var "print", func putsPrint),
(Var "pn", func putsPrint)
(Var "pn", func putsPrint),
(Var "define", func' defineVar),
(Var ",-", func' defineVar),
(Var "undefine", func' undefineVar),
(Var "-,", func' undefineVar)
]

stdValues :: SymbolTable Expr
Expand Down Expand Up @@ -1043,3 +1047,32 @@ putsPrint [] = do
putsPrint xs = do
forM_ xs $ \x -> liftIO . putStrLn $ printable x
return Nil

{-
- (define) - Binds the variable % in the local scope
- (define x) - Binds the variable x (not evaluated) in the local scope, returning its value
- (define x ... y) - Binds each variable locally, returning the value of the last one
- (define) == (,-)
-}
defineVar :: [Expr] -> Symbols Expr Expr
defineVar [] = defineVar [Atom "%"]
defineVar xs = do
result <- forM (toVars xs) $ \x -> do
prev <- getSymbolOrDefault x Nil
defSymbol x prev
return prev
-- We know that xs is nonempty since the [] case is handled above, so result is nonempty
return $ last result

{-
- (undefine) - Unbinds the tightest binding of %
- (undefine x ... y) - Unbinds each variable (not evaluated), skipping any which do not exist
- (undefine) == (-,)
-}
undefineVar :: [Expr] -> Symbols Expr Expr
undefineVar [] = undefineVar [Atom "%"]
undefineVar xs = do
forM_ (toVars xs) $ \x -> do
exists <- hasSymbol x
when exists $ undefSymbol x
return Nil
2 changes: 1 addition & 1 deletion Shiny/Symbol.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ defSymbol v y = do

undefSymbol :: Var -> Symbols e ()
undefSymbol v = get >>= helper >>= put
where helper [] = throwS "call stack is empty"
where helper [] = throwS "variable does not exist"
helper (x:xs)
| Map.member v x = pure $ Map.delete v x : xs
| otherwise = helper xs
Expand Down
2 changes: 1 addition & 1 deletion examples/upper.slp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

"This script will convert stdin to uppercase and output it"
_:+:Uc
_:+:Uc

0 comments on commit d65d151

Please sign in to comment.