]> ruin.nu Git - proglang.git/commitdiff
better semantics and show div by zero errors earlier
authorMichael Andreen <harv@ruin.nu>
Wed, 15 Mar 2006 16:20:05 +0000 (16:20 +0000)
committerMichael Andreen <harv@ruin.nu>
Wed, 15 Mar 2006 16:20:05 +0000 (16:20 +0000)
Interpret.hs
documentation

index 652e9793aaf2db2ca81bd396db3ef426e0d9d2ba..a674d1e509f04a2aa0ebb0d91c78300f453d6ead 100644 (file)
@@ -28,7 +28,6 @@ interpret fun st = do
        runStateT (runErrorT  (do mapM addFunction fun; mapM_ execute st)) emptyState
        return ()
 
        runStateT (runErrorT  (do mapM addFunction fun; mapM_ execute st)) emptyState
        return ()
 
---eval :: (MonadState State m, MonadError String m, MonadIO m) => Exp -> m Value
 eval :: (MonadState State m, MonadIO m) => Exp -> EvalM m Value
 eval (EBool b) = return (VBool b)
 eval (EInt n) = return (VInt n)
 eval :: (MonadState State m, MonadIO m) => Exp -> EvalM m Value
 eval (EBool b) = return (VBool b)
 eval (EInt n) = return (VInt n)
@@ -40,7 +39,7 @@ eval (BiOpExp e o e') = do
        v <- eval e
        v'<- eval e'
        if elem o [Eq,NEq] then return $ opE o v v'
        v <- eval e
        v'<- eval e'
        if elem o [Eq,NEq] then return $ opE o v v'
-               else let (VInt n1) = v in let (VInt n2) = v' in return $ op o n1 n2
+               else let (VInt n1) = v in let (VInt n2) = v' in return $! op o n1 n2
 eval (EPost i o) = do
        (VInt n) <- getVariableValue i
        setVariableValue i $ op o n 1
 eval (EPost i o) = do
        (VInt n) <- getVariableValue i
        setVariableValue i $ op o n 1
@@ -89,16 +88,17 @@ getNumber2 =  do
                else return ""
 
 -- op :: Op -> (a -> a -> Value)
                else return ""
 
 -- op :: Op -> (a -> a -> Value)
-opE Eq = \e e' -> VBool $ e == e'
-opE NEq = \e e' -> VBool $ not (e == e')
-op Plus = \e e' -> VInt $ e + e'
-op Minus = \e e' -> VInt $ e - e'
-op Times = \e e' -> VInt $ e * e'
-op Div = \e e' -> VInt $ e `div` e'
-op Lt = \e e' -> VBool $ e < e'
-op ELt = \e e' -> VBool $ e <= e'
-op Gt = \e e' -> VBool $ e > e'
-op EGt = \e e' -> VBool $ e >= e'
+opE Eq e e' = VBool $ e == e'
+opE NEq e e' = VBool $ not (e == e')
+op Plus e e' =VInt $ e + e'
+op Minus e e' = VInt $ e - e'
+op Times e e' = VInt $ e * e'
+op Div _ 0 = error "Division by zero"
+op Div e e' = VInt $ e `div` e'
+op Lt e e' = VBool $ e < e'
+op ELt e e' = VBool $ e <= e'
+op Gt e e' = VBool $ e > e'
+op EGt e e' = VBool $ e >= e'
 
 getVariableValue :: (MonadState State m) => Ident -> m Value 
 getVariableValue i = do
 
 getVariableValue :: (MonadState State m) => Ident -> m Value 
 getVariableValue i = do
@@ -124,7 +124,6 @@ pushAndPop s = do
        s
        modify (\s -> s { variables = tail $ variables s})
 
        s
        modify (\s -> s { variables = tail $ variables s})
 
--- execute :: (MonadState Variables m) => Stm -> m ()
 execute :: (MonadState State m, MonadIO m) => Stm -> EvalM m ()
 execute (SNoop) = return ()
 execute (SExp e) = eval e >> return ()
 execute :: (MonadState State m, MonadIO m) => Stm -> EvalM m ()
 execute (SNoop) = return ()
 execute (SExp e) = eval e >> return ()
index 9127c08827fa09ed2efd4644569d43d8c73e3bfc..196220aa96faa3596dea5c7a9fd1ebf33d76b275 100644 (file)
@@ -72,7 +72,7 @@ Evaluate the arguments in order, find function definition, remove the old variab
 
 [SReturn]
 
 
 [SReturn]
 
-<return e,c> <= <e,c> => <v,c'>, c'[ret->v], STOP
+<return e,c> => c'[ret->v] <= <e,c> => <v,c'>
 
 Evaluate the expression, add the value as return value to the state and stop the execution of the state
 
 
 Evaluate the expression, add the value as return value to the state and stop the execution of the state
 
@@ -87,3 +87,15 @@ Adds the function i with parameters ds and body ss to the context
 <fs ss, c> => c'' <= c[fs] => c', <ss,c'> => c''
 
 Add all the function to the context and execute the statements in this context
 <fs ss, c> => c'' <= c[fs] => c', <ss,c'> => c''
 
 Add all the function to the context and execute the statements in this context
+
+[SEQ]
+
+<s1;s2,c> => c' <= <s1,c> => c', c'(ret)
+
+If the context returned by s1 contains a return-value, return this context without executing the next statement.
+
+[SWhile]
+
+<while e s,c> => c''' => <e,c> => <true,c'> push(c') => c'' <s,c''> => c''', c'''(ret)
+
+If the context returned by the body contains a return-value, return this context and don't try to run the loop again.