Advertisement
NickMarcha

ReferenceSemantics

Apr 17th, 2022
1,579
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- | PIPLInterpreter: big step operational semantics of PIPL
  2. -- using environment and store for the state.
  3.  
  4. module PIPLInterpreter where
  5.  
  6. import BIPL3AST
  7. import PIPLMeta
  8. import qualified BIPL3State as S
  9. import BIPL3State (Value(..), State)
  10. import BIPL3MetaTypes
  11.  
  12. type FunModel = FunName -> [Value] -> Value
  13.  
  14. type ExecutionModel = (FunModel, Program)
  15.  
  16. getFunModel :: ExecutionModel -> FunModel
  17. getFunModel = fst
  18.  
  19. getProgram :: ExecutionModel -> Program
  20. getProgram = snd
  21.  
  22. -- ///////// EVALUATE EXPRESSIONS ////////////////
  23.  
  24. eval :: Expr -> FunModel -> State -> Value
  25. eval (IL i) _ state = I (fromIntegral i)
  26. eval (BL b) _ state= B b
  27. eval (VarExp var) _ state = S.getValue var state
  28. eval (CallFun op args) funModel state =
  29.     funModel op $ map (\expr -> eval expr funModel state) args
  30.  
  31. -- ///////// EXECUTE STATEMENTS ////////////////
  32.  
  33. exec :: Stmt -> ExecutionModel -> State -> State
  34. exec (Assert expr) (funModel, _) state =
  35.   if cond
  36.     then state
  37.     else error $ "Assert failed for " ++ (show expr)
  38.       ++ " in state " ++ (show state)
  39.   where
  40.     B cond = eval expr funModel state
  41. exec (Assign var expr) (funModel, _) state = S.changeValue var val state
  42.   where val = eval expr funModel state
  43. exec wstmt@(While expr stmt) execModel@(funModel, _) state = state' where
  44.  B cond = eval expr funModel state
  45.  state' = if cond then exec wstmt execModel (exec stmt execModel state) else state
  46. exec (IfStmt expr stmt1 stmt2) execModel@(funModel, _) state = state' where
  47.  B cond = eval expr funModel state
  48.  state' = if cond then exec stmt1 execModel state else exec stmt2 execModel state
  49. exec seq@(Sequence (stmt:stmts)) execModel state =
  50.   exec (Sequence stmts) execModel (exec stmt execModel state)
  51. exec seq@(Sequence []) execModel state = state
  52. exec (CallProc pName args) execModel@(funModel, program) state =
  53.   let
  54.     olderStackFrame :: S.StackFrame
  55.     olderStackFrame = S.getStackFrame state
  56.  
  57.     calledProc ::ProcedureDeclaration
  58.     calledProc = getProc pName program
  59.  
  60.     --evaluatedValues :: [Value]
  61.     --evaluatedValues = map (\arg -> eval arg funModel state) args
  62.     modifiedState:: State
  63.     --modifiedState = addCallStateInputs (procParams calledProc) evaluatedValues $ S.clearEnvironment state
  64.     modifiedState = addCallStateInputsRef funModel (procParams calledProc) args  state $ S.clearEnvironment state
  65.  
  66.     afterPerformState :: State
  67.     afterPerformState = perform calledProc execModel modifiedState
  68.     {-
  69.  
  70.  
  71.     values :: [Value]
  72.     values = getReturnStateOutputs (procParams calledProc) afterPerformState
  73.  
  74.     matchedParamsArgs :: [(Parameter, Expr)]
  75.     matchedParamsArgs = (zip (procParams calledProc) args)
  76.  
  77.     outExprs :: [Expr]
  78.     outExprs = map snd $ filter (\(p,a) -> (fst p) /= Obs) matchedParamsArgs
  79.    
  80.  
  81.     varNames :: [Var]
  82.     varNames  = filterVar outExprs
  83.  
  84.     filterVar:: [Expr] -> [Var]
  85.     filterVar ((VarExp var):exs) = var:filterVar exs
  86.     filterVar (_:exs) = filterVar exs
  87.     filterVar [] = []
  88.    
  89.    
  90.    
  91.  
  92.     finalState :: State
  93.     finalState =
  94.       foldl
  95.       (\s (vn, v) -> S.changeValue vn v s)
  96.       oldEnvState (zip varNames values)
  97.       -}
  98.     oldEnvState :: State
  99.     oldEnvState = S.setStackFrame olderStackFrame afterPerformState
  100.   in oldEnvState
  101.    
  102.  
  103. -- ///////// RUN PROGRAMS ////////////////
  104.  
  105. -- | Run a given procedure in the given program, while passing in the given
  106. -- | values as arguments. Returns the values of the output parameters (upd/out)
  107. -- | after the procedure has been run.
  108. runProgram :: ExecutionModel -> ProcName -> [Value] -> [Value]
  109. runProgram execModel@(funModel, prog) pName args =
  110.   let proc@(Proc _ params _ _) = getProc pName prog
  111.    in run proc execModel args
  112.  
  113. run :: ProcedureDeclaration -> ExecutionModel -> [Value] -> [Value]
  114. run proc@(Proc _ params locals body) execModel args =
  115.     let state = addCallStateInputs params args S.newState
  116.         state' = perform proc execModel state
  117.     in getReturnStateOutputs params state'
  118.  
  119. perform :: ProcedureDeclaration -> ExecutionModel -> State -> State
  120. perform (Proc _ params locals body) prog state =
  121.     let oldStackFrame = S.getStackFrame state
  122.         stateWithLocals = addUninitVars (map varName locals) state
  123.         stateAfterExec = exec body prog stateWithLocals
  124.         stateAfterCleanup = S.setStackFrame oldStackFrame stateAfterExec
  125.      in stateAfterCleanup
  126.  
  127. -- ///////// UTILITY FUNCTIONS ////////////////
  128.  
  129. -- | Add a list of variable names to the state, without initialising them.
  130. addUninitVars :: [Var] -> State -> State
  131. addUninitVars varNames initState = foldl addVar initState varNames
  132.     where addVar state varName = S.allocateVariable varName state
  133.  
  134. addCallStateInputs :: [Parameter] -> [Value] -> State -> State
  135. addCallStateInputs params args =
  136.     let inputVars = getParamNames $ filter isInputParameter params
  137.         outModeVars = getParamNames $ filter (not . isInputParameter) params
  138.         isInputParameter (mode, _) = mode /= Out
  139.         getParamNames = map (varName . paramVar)
  140.         addVar state (varName, value) = S.addVariable varName value state
  141.         addVars varNames values initState = foldl addVar initState (zip varNames values)
  142.      in addUninitVars outModeVars . addVars inputVars args
  143.  
  144. getReturnStateOutputs :: [Parameter] -> State -> [Value]
  145. getReturnStateOutputs params state =
  146.     let outputVars = getParamNames $ filter isOutputParameter params
  147.         isOutputParameter (mode, _) = mode /= Obs
  148.         getParamNames = map (varName . paramVar)
  149.      in map (\varName -> S.getValue varName state) outputVars
  150.  
  151.  
  152. -- | Reference Semantics
  153. addCallStateInputsRef ::  FunModel -> [Parameter] -> [Expr] -> State -> State -> State
  154. addCallStateInputsRef funModel params args srcState state =
  155.     let
  156.       getParamName = (varName . paramVar)
  157.      
  158.       copyVars :: [(Var, Value)]
  159.       copyVars = map (\(p, a) -> ((getParamName p), (eval a funModel srcState ))) $ filter isObsParam paramsWithArgs
  160.  
  161.       refModeVars :: [(Var, Var)]
  162.       refModeVars = map (\(p, a) -> ((getParamName p), (findVar a))) $ filter (not . isObsParam) paramsWithArgs
  163.        where
  164.          findVar :: Expr -> Var
  165.          findVar (VarExp varName) = varName
  166.          findVar _ = error "Expected VarExp"
  167.  
  168.       isObsParam :: (Parameter, Expr) -> Bool
  169.       isObsParam ((mode, _),_) = mode == Obs
  170.        
  171.       paramsWithArgs :: [(Parameter, Expr)]
  172.       paramsWithArgs = zip params args
  173.  
  174.       addVar :: State -> (Var, Value) -> State
  175.       addVar state (varName, value) = S.addVariable varName value state
  176.  
  177.       addVars :: [(Var, Value)] -> State -> State
  178.       addVars vvs initState = foldl addVar initState vvs
  179.  
  180.      in addVars copyVars $ addVarsRef refModeVars srcState state
  181.  
  182. -- | Add a list of variable names to the state, without initialising them.
  183. addVarsRef :: [(Var, Var)] -> State-> State -> State
  184. addVarsRef varNames srcState initState = foldl addVar initState varNames
  185.     where
  186.       addVar :: State -> (Var, Var) -> State
  187.       addVar  desState (varName, aliasName) = S.copyReference aliasName varName srcState desState
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement