Skip to content

Commit

Permalink
create minimal interpreter for example code
Browse files Browse the repository at this point in the history
  • Loading branch information
antonkesy committed Mar 5, 2024
1 parent 37e4518 commit e8539ab
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
4 changes: 3 additions & 1 deletion app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
module Main (main) where

import Interpreter.Interpreter
import Parser.Program
import Text.Parsec (parse)

developProgram :: String
developProgram =
"int i = 1; int j = 2; int k = i + j;"
"int i = 1; int j = 2; int l = 3 + 4; int k = i + j + l;"

main :: IO ()
main = do
Expand All @@ -15,3 +16,4 @@ main = do
Right program -> do
putStrLn "Parsed program:"
print program
interpret program
1 change: 1 addition & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies:
- parsec >= 3.1.16 && < 4
- prettyprinter >= 1.7.1 && < 2
- optparse-applicative >= 0.17.0
- containers

ghc-options:
- -Wall
Expand Down
4 changes: 4 additions & 0 deletions peter.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ source-repository head
library
exposed-modules:
AST
Interpreter.Interpreter
Parser.Assignment
Parser.Comment
Parser.EndOfLine
Expand All @@ -44,6 +45,7 @@ library
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints
build-depends:
base >=4.7 && <5
, containers
, optparse-applicative >=0.17.0
, parsec >=3.1.16 && <4
, prettyprinter >=1.7.1 && <2
Expand All @@ -58,6 +60,7 @@ executable peter-exe
ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
build-depends:
base >=4.7 && <5
, containers
, optparse-applicative >=0.17.0
, parsec >=3.1.16 && <4
, peter
Expand All @@ -77,6 +80,7 @@ test-suite peter-test
build-depends:
HUnit
, base >=4.7 && <5
, containers
, optparse-applicative >=0.17.0
, parsec >=3.1.16 && <4
, peter
Expand Down
63 changes: 63 additions & 0 deletions src/Interpreter/Interpreter.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{-# LANGUAGE GADTs #-}

module Interpreter.Interpreter (module Interpreter.Interpreter) where

import AST
import Control.Monad (foldM)
import Data.Map.Strict as Map

data Value = IntValue Int | FloatValue Float | BoolValue Bool | UnitValue
deriving (Show)

data ProgramState where
ProgramState :: {variables :: Map Name Value} -> ProgramState
deriving (Show)

interpret :: Program -> IO ()
interpret (Program statements) = do
endState <- foldM interpretStatement (ProgramState empty) statements
putStrLn $ "End state: " ++ show endState

interpretStatement :: ProgramState -> Statement -> IO ProgramState
interpretStatement state (VariableStatement (Variable name _ expression)) = do
value <- interpretExpression state expression
return (updateState state name value)
interpretStatement state (AssignmentStatement (Assignment name expression)) = do
value <- interpretExpression state expression
return (updateState state name value)

updateState :: ProgramState -> Name -> Value -> ProgramState
updateState (ProgramState vars) name value = ProgramState $ Map.insert name value vars

interpretExpression :: ProgramState -> Expression -> IO Value
interpretExpression state (AtomicExpression atomic) = do
interpretAtomic state atomic
interpretExpression state (OperationExpression left operator right) = do
leftValue <- interpretExpression state left
rightValue <- interpretExpression state right
let value = interpretOperation operator leftValue rightValue
return value

interpretAtomic :: ProgramState -> Atomic -> IO Value
interpretAtomic _ (LiteralAtomic literal) = do
interpretLiteral literal
interpretAtomic (ProgramState vars) (VariableAtomic name) = do
let varValue = Map.lookup name vars
return $ case varValue of
Just value -> value
Nothing -> error $ "Variable not found: " ++ name

interpretLiteral :: Literal -> IO Value
interpretLiteral (IntLiteral value) = do
return $ IntValue value
interpretLiteral (FloatLiteral value) = do
return $ FloatValue value
interpretLiteral (BoolLiteral value) = do
return $ BoolValue value
interpretLiteral UnitLiteral = do
return UnitValue

interpretOperation :: Operator -> Value -> Value -> Value
interpretOperation Plus (IntValue left) (IntValue right) = IntValue $ left + right
interpretOperation Plus (FloatValue left) (FloatValue right) = FloatValue $ left + right
interpretOperation operator left right = error $ "Unsupported operation: " ++ show operator ++ " " ++ show left ++ " " ++ show right

0 comments on commit e8539ab

Please sign in to comment.