Skip to content

Commit

Permalink
Implement closures
Browse files Browse the repository at this point in the history
  • Loading branch information
GuiltyDolphin committed Nov 21, 2015
1 parent 180f506 commit 9cb8677
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 64 deletions.
6 changes: 3 additions & 3 deletions src/Angle/Exec/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ import System.IO.Error ( tryIOError
import System.Process (readProcess)

import Angle.Exec.Error
import Angle.Exec.Scope
import Angle.Exec.Types
import Angle.Types.Lang
import Angle.Types.Scope


emptyArgs :: ArgSig
Expand All @@ -108,7 +108,7 @@ builtinVar name = (name, VarVal
, varBuiltin = True })


builtinsVars :: BindEnv Lambda
builtinsVars :: BindEnv LangIdent Lambda
builtinsVars = bindEnvFromList $
map (builtinVar . LangIdent) builtins

Expand All @@ -119,7 +119,7 @@ builtinValue name val = (name, VarVal
, varBuiltin = True })


builtinsValues :: BindEnv LangLit
builtinsValues :: BindEnv LangIdent LangLit
builtinsValues = bindEnvFromList $
map (\(x,y) -> builtinValue (LangIdent x) y) builtinValues

Expand Down
28 changes: 21 additions & 7 deletions src/Angle/Exec/Exec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import Angle.Parse.Parser (program, evalParse)
import Angle.Exec.Builtins
import Angle.Exec.Error
import Angle.Exec.Operations
import Angle.Exec.Scope
import Angle.Exec.Types
import Angle.Types.Lang
import Angle.Types.Scope


updatePos :: SourceRef -> ExecIO ()
Expand All @@ -49,15 +49,15 @@ newScope = do
put env { currentScope = newScope' }


lookupVar :: (Scope -> BindEnv a) -> LangIdent -> ExecIO (Maybe a)
lookupVar :: (Scope -> BindEnv LangIdent a) -> LangIdent -> ExecIO (Maybe a)
lookupVar binds name = do
currScope <- getScope
case resolve binds name currScope of
Nothing -> return Nothing
Just x -> return $ varDef x


lookupVarF :: (Scope -> BindEnv a) -> (LangIdent -> ExecError) -> LangIdent -> ExecIO a
lookupVarF :: (Scope -> BindEnv LangIdent a) -> (LangIdent -> ExecError) -> LangIdent -> ExecIO a
lookupVarF binds err name = lookupVar binds name
>>= maybe (throwExecError $ err name)
return
Expand Down Expand Up @@ -85,7 +85,7 @@ modifyScope f = do
put env {currentScope=newScope'}


lookupVarCurrentScope :: (Scope -> BindEnv a) -> LangIdent -> ExecIO (Maybe (VarVal a))
lookupVarCurrentScope :: (Scope -> BindEnv LangIdent a) -> LangIdent -> ExecIO (Maybe (VarVal a))
lookupVarCurrentScope binds name = do
currScope <- liftM currentScope get
if isDefinedIn binds name currScope
Expand All @@ -104,7 +104,7 @@ assignVarLit n v = assignVar valueBindings handleBuiltinAssignLit


assignVar
:: (Scope -> BindEnv a)
:: (Scope -> BindEnv LangIdent a)
-> (LangIdent -> b -> ExecIO b) -- ^ Builtin handler function.
-> (LangIdent -> VarVal b -> Scope -> Scope)
-> LangIdent
Expand Down Expand Up @@ -321,6 +321,14 @@ callFun x asClass args | isBuiltin x = callBuiltin x args


callLambda :: Lambda -> Bool -> [Expr] -> ExecIO LangLit
callLambda l@(Lambda { lambdaScope = (Just s) }) asClass args
= do
cScope <- getScope
modifyScope (const s)
res <- callLambda l { lambdaScope = Nothing } asClass args
`catchAE` (\e -> modifyScope (const cScope) >> throwError e)
modifyScope (const cScope)
return res
callLambda (Lambda
{ lambdaArgs=params
, lambdaBody=body}) asClass args
Expand Down Expand Up @@ -355,7 +363,13 @@ execSingStmt (StmtReturn x) = do
isGlob <- liftM (isOutermostScope . currentScope) get
if isGlob
then throwExecError returnFromGlobalErr
else execExpr x >>= throwReturn
else do
res <- execExpr x
case res of
LitLambda lam -> do
sc <- getScope
throwReturn $ LitLambda lam { lambdaScope = Just sc }
y -> throwReturn y
execSingStmt (StmtBreak x False)
= case x of
Nothing -> throwBreak Nothing
Expand Down Expand Up @@ -525,7 +539,7 @@ assignVarBuiltinLambda =


assignVarBuiltin
:: (Scope -> BindEnv a)
:: (Scope -> BindEnv LangIdent a)
-> (LangIdent -> VarVal b -> Scope -> Scope)
-> LangIdent
-> b -- ^ Value to assign.
Expand Down
2 changes: 1 addition & 1 deletion src/Angle/Exec/Types/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import Control.Monad.Trans.Except
import Control.Monad.State

import Angle.Exec.Error
import Angle.Exec.Scope
import Angle.Types.Lang
import Angle.Types.Scope


-- | Angle program execution monad.
Expand Down
4 changes: 2 additions & 2 deletions src/Angle/Parse/Parser/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ structDefun = StructDefun
<$> (string "defun " *> identName)
<*> (Lambda
<$> callList <* tokStmtBetween
<*> stmt)
<*> stmt <*> return Nothing)


-- | Exception handling.
Expand Down Expand Up @@ -436,7 +436,7 @@ lambda :: Parser Lambda
lambda = parens $ do
args <- callList <* tokNSpaced
body <- stmt
return $ Lambda args body
return $ Lambda args body Nothing


-- | Set of arguments for a function
Expand Down
12 changes: 9 additions & 3 deletions src/Angle/Types/Lang.hs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ module Angle.Types.Lang
, typeAnnOf
, ArgElt(..)
, Lambda(..)
, Scope
, enumType
, allType
) where
Expand All @@ -110,6 +111,10 @@ import Numeric (showFFloat)
import System.IO (Handle)

import Angle.Scanner (SourcePos, beginningOfFile)
import Angle.Types.Scope (GenScope)


type Scope = GenScope LangIdent LangLit Lambda


-- | Wraps statements to allow for positional tracking as well
Expand Down Expand Up @@ -245,13 +250,14 @@ showSynOpList = showSynSep " " ")" " "
-- The body is the code that is executed upon successful invokation.
data Lambda = Lambda { lambdaArgs :: ArgSig
, lambdaBody :: Stmt
, lambdaScope :: Maybe Scope
} deriving (Show, Eq)


instance ShowSyn Lambda where
showSyn (Lambda args body@(SingleStmt _ _))
showSyn (Lambda args body@(SingleStmt _ _) _)
= concat ["(", showSyn args, " ", init $ showSyn body, ")"]
showSyn (Lambda args body) = concat ["(", showSyn args, " ", showSyn body, ")"]
showSyn (Lambda args body _) = concat ["(", showSyn args, " ", showSyn body, ")"]


-- | An argument signature.
Expand Down Expand Up @@ -477,7 +483,7 @@ instance ShowSyn Expr where
showSyn (ExprList _) = error "showSyn - cannot show unevaluated list"
showSyn (ExprRange{}) = error "showSyn - cannot show unevaluated range"
showSyn (ExprLambdaCall x xs) = showSyn (LitLambda x) ++ " : (" ++ showSynArgs xs ++ ")"
showSyn (ExprParamExpand _) = error "showSyn - ExprParamExpand made it to showSyn"
showSyn (ExprParamExpand x) = ".." ++ showSyn x -- error "showSyn - ExprParamExpand made it to showSyn"


-- | Represents names that can be assigned values.
Expand Down
Loading

0 comments on commit 9cb8677

Please sign in to comment.