Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>What you want to do is to keep track of the value of variables during <em>evaluation</em> of expressions, not during parsing. Let's assume you parse your expressions into the following types:</p> <pre><code>data Expr = Literal Int | Variable Var | Assign Var Expr | Add Expr Expr | ... newtype Var = Var String deriving (Ord, Eq, Show) </code></pre> <p>Then you could simply pass a Map around your evaluation function with the current value of all variables:</p> <pre><code>import qualified Data.Map as M import Control.Monad.State data Expr = Literal Int | Variable Var | Assign Var Expr | Add Expr Expr newtype Var = Var String deriving (Ord, Eq, Show) -- Each Expr corresponds to a single line in your language, so -- a = 2+1 -- a + 2 -- corresponds to -- [Assign (Var "a") (Add (Literal 2) (Literal 1)), -- Add (Variable (Var "a")) (Literal 2)] eval :: [Expr] -&gt; Int eval es = last $ evalState (mapM eval' es) M.empty -- M.empty :: M.Map Var Int where eval' (Literal n) = return n eval' (Variable v) = do vs &lt;- get case M.lookup v vs of Just x -&gt; return x _ -&gt; error $ "variable " ++ show v ++ " is undefined!" eval' (Assign v ex) = do x &lt;- eval' ex modify (M.insert v x) return x eval' (Add a b) = do x &lt;- eval' a y &lt;- eval' b return (x+y) </code></pre> <p>Of course, there's nothing to prevent you from evaluating expressions as you parse them, eliminating the need for an abstract syntax tree such as this. The general idea is the same there; you'll need to keep some state with you during the entire parsing, that keeps track of the current value of all your variables.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload