fix: allow function arguments to shadow commands (#1217)

This fix is a close cousin of the one that allowed let bindings to
shadow global commands. We now allow function arguments to shadow
commands as well by using a local lookup preference for argument names,
making functions such as:

```
(defndynamic foo [car]
  (Symbol.prefix car 'foo)
```

work as anticipated. I've also removed unused code from `apply`.

Fixes #1057
This commit is contained in:
Scott Olsen 2021-05-24 15:07:30 -04:00 committed by GitHub
parent 2701517753
commit 085089e293
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -486,15 +486,14 @@ macroExpand ctx xobj =
apply :: Context -> XObj -> [XObj] -> [XObj] -> IO (Context, Either EvalError XObj)
apply ctx@Context {contextInternalEnv = internal} body params args =
let Just env = contextInternalEnv ctx <|> maybeId (innermostModuleEnv ctx) <|> Just (contextGlobalEnv ctx)
allParams = map getName params
let allParams = map getName params
in case splitWhen (":rest" ==) allParams of
[a, b] -> callWith env a b
[a] -> callWith env a []
[a, b] -> callWith a b
[a] -> callWith a []
_ ->
pure (throwErr (MacroBadArgumentSplit allParams) ctx Nothing)
where
callWith _ proper rest = do
callWith proper rest = do
let n = length proper
insideEnv = Env Map.empty internal Nothing Set.empty InternalEnv 0
insideEnv' =
@ -513,7 +512,8 @@ apply ctx@Context {contextInternalEnv = internal} body params args =
(SymPath [] (head rest))
(XObj (Lst (drop n args)) Nothing Nothing)
)
(c, r) <- (evalDynamic ResolveLocal (replaceInternalEnv ctx insideEnv'') body)
binds = if null rest then proper else proper ++ [(head rest)]
(c, r) <- (eval (replaceInternalEnv ctx insideEnv'') body (PreferLocal (map (\x -> (SymPath [] x)) binds)) ResolveLocal)
pure (c {contextInternalEnv = internal}, r)
-- | Parses a string and then converts the resulting forms to commands, which are evaluated in order.