Skip to content

Commit

Permalink
fix for subtraction - final code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
felixbd committed Nov 27, 2023
1 parent 8518b8e commit 4d14639
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 57 deletions.
84 changes: 44 additions & 40 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,65 @@ Parser and interpreter for the While programming language
*** example

#+begin_src shell
felix in ~/git-repos/hub/while on main λ stack run
felix in ~/git-repos/hub/while on main ● λ stack build
felix in ~/git-repos/hub/while on main ● λ stack run

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Enter the file name:
./examples/simple.while
[READING .WHILE FILE] "./examples/simple.while"
[MetaToken {getLineNumber = 1, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 1, getToken = AssignToken},
MetaToken {getLineNumber = 1, getToken = ConstToken {getConstInt = 10}},
MetaToken {getLineNumber = 1, getToken = SemicolonToken},
MetaToken {getLineNumber = 2, getToken = VarToken {getVarName = "x_2"}},
MetaToken {getLineNumber = 2, getToken = AssignToken},
MetaToken {getLineNumber = 2, getToken = ConstToken {getConstInt = 0}},
MetaToken {getLineNumber = 2, getToken = SemicolonToken},
MetaToken {getLineNumber = 4, getToken = WhileToken},
MetaToken {getLineNumber = 4, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 4, getToken = NotEqualToken},
MetaToken {getLineNumber = 4, getToken = ConstToken {getConstInt = 0}},
MetaToken {getLineNumber = 4, getToken = DoToken},
MetaToken {getLineNumber = 5, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 5, getToken = AssignToken},
MetaToken {getLineNumber = 5, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 5, getToken = MinusToken},
MetaToken {getLineNumber = 5, getToken = ConstToken {getConstInt = 1}},
MetaToken {getLineNumber = 5, getToken = SemicolonToken},
MetaToken {getLineNumber = 6, getToken = LoopToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 6, getToken = DoToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_2"}},
MetaToken {getLineNumber = 6, getToken = AssignToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_2"}},
MetaToken {getLineNumber = 6, getToken = PlusToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 6, getToken = EndToken},
MetaToken {getLineNumber = 7, getToken = EndToken}]

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

[DONE TOKENIZE]:
[MetaToken {getLineNumber = 1, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 1, getToken = AssignToken},
MetaToken {getLineNumber = 1, getToken = ConstToken {getConstInt = 10}},
MetaToken {getLineNumber = 1, getToken = SemicolonToken},
MetaToken {getLineNumber = 2, getToken = VarToken {getVarName = "x_2"}},
MetaToken {getLineNumber = 2, getToken = AssignToken},
MetaToken {getLineNumber = 2, getToken = ConstToken {getConstInt = 0}},
MetaToken {getLineNumber = 2, getToken = SemicolonToken},
MetaToken {getLineNumber = 4, getToken = WhileToken},
MetaToken {getLineNumber = 4, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 4, getToken = NotEqualToken},
MetaToken {getLineNumber = 4, getToken = ConstToken {getConstInt = 0}},
MetaToken {getLineNumber = 4, getToken = DoToken},
MetaToken {getLineNumber = 5, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 5, getToken = AssignToken},
MetaToken {getLineNumber = 5, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 5, getToken = MinusToken},
MetaToken {getLineNumber = 5, getToken = ConstToken {getConstInt = 1}},
MetaToken {getLineNumber = 5, getToken = SemicolonToken},
MetaToken {getLineNumber = 6, getToken = LoopToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 6, getToken = DoToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_2"}},
MetaToken {getLineNumber = 6, getToken = AssignToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_2"}},
MetaToken {getLineNumber = 6, getToken = PlusToken},
MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_1"}},
MetaToken {getLineNumber = 6, getToken = EndToken},
MetaToken {getLineNumber = 7, getToken = EndToken}]

[DONE PARSING AST]:
Sequential
(Assignment "x_1" (Constant {getConst = 10}))
(Sequential
(Assignment "x_2" (Constant {getConst = 0}))
(While
(Neq (Variable {getVar = "x_1"}) (Constant {getConst = 0}))
(Sequential
(Assignment "x_1" (Subtract (Variable {getVar = "x_1"}) (Constant {getConst = 1})))
(Loop
(Variable {getVar = "x_1"})
(Assignment "x_2" (Add (Variable {getVar = "x_2"}) (Variable {getVar = "x_1"})))))))
(Sequential
(Assignment "x_1" (Subtract (Variable {getVar = "x_1"}) (Constant {getConst = 1})))
(Loop
(Variable {getVar = "x_1"})
(Assignment "x_2" (Add (Variable {getVar = "x_2"}) (Variable {getVar = "x_1"})))))))

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

[OUTPUT]:
[OUTPUT OF EVALUATION]:
[("x_2",285),("x_1",0)]

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

felix in ~/git-repos/hub/while on main ● λ
#+end_src

*** compile
Expand Down
21 changes: 11 additions & 10 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,30 @@

module Main (main) where

import WhileParser (WhileAST(..), tokenize, readFileContent, runASTParser)
import WhileEvaluation (eval, evalM, VarName, VarVal, VarState, VarStateWorld)
import WhileParser (tokenize, readFileContent, runASTParser) -- WhileAST(..),
import WhileEvaluation (eval) --, evalM, VarName, VarVal, VarState, VarStateWorld)


main :: IO ()
main = do

putStrLn $ "\n" ++ concat (replicate 40 " =") ++ "\n"

whileLines <- readFileContent "./examples/simple.while"
-- Prompt the user for the file name
putStrLn "Enter the file name:"
fileName <- getLine

-- Read the content of the specified file
whileLines <- readFileContent fileName -- "./examples/simple.while"
let tokens = tokenize whileLines

putStrLn "\n\ESC[92m[DONE TOKENIZE]\ESC[0m:"
print tokens

putStrLn $ "\n" ++ concat (replicate 40 " =") ++ "\n"

let astOfFoo = runASTParser tokens
putStrLn "\n\ESC[92m[DONE PARSING AST]\ESC[0m:"
print astOfFoo

putStrLn $ "\n" ++ concat (replicate 40 " =") ++ "\n"

putStrLn "\ESC[92m[OUTPUT]\ESC[0m:"

putStrLn "\n\ESC[92m[OUTPUT OF EVALUATION]\ESC[0m:"
let a = eval astOfFoo []
print a

Expand Down
12 changes: 5 additions & 7 deletions src/WhileEvaluation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,24 @@ updateVarState name val states | name `notElem` map fst states = (name, val):sta
--------------------------------------------------------------------------------

evalExpression :: Expression -> VarStateWorld -> Int
evalExpression exp state = case exp of
evalExpression expr state = case expr of
(Constant c) -> c
(Variable varName) -> lookUpVarState varName state
(Add exp1 exp2) -> helper (+) [exp1, exp2]
(Subtract exp1 exp2) -> evalExpression exp1 state - evalExpression exp2 state
(Subtract exp1 exp2) -> max 0 $ evalExpression exp1 state - evalExpression exp2 state
(Neq exp1 exp2) -> fromEnum $ evalExpression exp1 state /= evalExpression exp2 state
_ -> undefined
where
-- helper :: (Int -> Int -> Int) -> [Expression] -> Int
helper f = foldl (\acc x -> f acc (evalExpression x state)) 0

--------------------------------------------------------------------------------

evalAssignment :: WhileAST -> VarStateWorld -> VarStateWorld
evalAssignment (Assignment name exp) state = updateVarState name (evalExpression exp state) state
evalAssignment (Assignment name expr) state = updateVarState name (evalExpression expr state) state
evalAssignment _ _ = undefined

evalWhileExp :: WhileAST -> VarStateWorld -> VarStateWorld
evalWhileExp (While exp whileAST) state = helperWhile exp whileAST state
evalWhileExp (While expr whileAST) state = helperWhile expr whileAST state
evalWhileExp _ _ = undefined

-- NOTE maybe check if `evalExpression p state` returns either 0 or 1 ...
Expand All @@ -90,7 +89,7 @@ helperWhile p ast state = if evalExpression p state == 1

evalLoopExp :: WhileAST -> VarStateWorld -> VarStateWorld
-- evalLoopExp (Loop exp whileAST) state = (foldr (.) id (replicate (evalExpression exp state) eval))
evalLoopExp (Loop exp whileAST) state = helperLoop whileAST state (evalExpression exp state)
evalLoopExp (Loop expr whileAST) state = helperLoop whileAST state (evalExpression expr state)
evalLoopExp _ _ = undefined

helperLoop :: WhileAST -> VarStateWorld -> Int -> VarStateWorld
Expand All @@ -107,7 +106,6 @@ eval ast vs = case ast of
w@(While _ _) -> evalWhileExp w vs
l@(Loop _ _) -> evalLoopExp l vs
Pass -> vs
_ -> vs

evalT :: WhileAST -> VarStateT ()
evalT ast w = ((), eval ast w)
Expand Down
1 change: 1 addition & 0 deletions src/WhileParser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
-- | (c) 2023 Felix Drees - BSD3 License

{-# LANGUAGE LambdaCase #-}
{-# OPTIONS_GHC -Wno-partial-fields #-}

module WhileParser
(Token(..)
Expand Down

0 comments on commit 4d14639

Please sign in to comment.