From 4d1463950971922993cc3ef081eecb49621c6cf9 Mon Sep 17 00:00:00 2001 From: Felix Drees Date: Mon, 27 Nov 2023 20:46:59 +0100 Subject: [PATCH] fix for subtraction - final code cleanup --- README.org | 84 ++++++++++++++++++++++-------------------- app/Main.hs | 21 ++++++----- src/WhileEvaluation.hs | 12 +++--- src/WhileParser.hs | 1 + 4 files changed, 61 insertions(+), 57 deletions(-) diff --git a/README.org b/README.org index 9d7023a..f112f4d 100644 --- a/README.org +++ b/README.org @@ -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 diff --git a/app/Main.hs b/app/Main.hs index ef934cf..2aad942 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -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 diff --git a/src/WhileEvaluation.hs b/src/WhileEvaluation.hs index 9669b43..601e3c3 100644 --- a/src/WhileEvaluation.hs +++ b/src/WhileEvaluation.hs @@ -61,13 +61,12 @@ 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 @@ -75,11 +74,11 @@ evalExpression exp state = case exp of -------------------------------------------------------------------------------- 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 ... @@ -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 @@ -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) diff --git a/src/WhileParser.hs b/src/WhileParser.hs index fa51562..4e78517 100644 --- a/src/WhileParser.hs +++ b/src/WhileParser.hs @@ -2,6 +2,7 @@ -- | (c) 2023 Felix Drees - BSD3 License {-# LANGUAGE LambdaCase #-} +{-# OPTIONS_GHC -Wno-partial-fields #-} module WhileParser (Token(..)