1
Alexander Isenko
15.05.2017
https://github.com/cirquit/hjc
https://github.com/cirquit/sl-interpreter
Interpreting Code in Host Language
2
Alexander Isenko
15.05.2017
Lexer
Parser
AST-Interpreter
Source Program
Tokens
AST
Source Program
in Host Language
Lexer
3
Alexander Isenko
15.05.2017
import Text.Megaparsec
-- | 'parens' parses something between parenthesis.
parens :: Parser a -> Parser a
parens = between (symbol "(") (symbol ")")
-- | 'semi' parses a semicolon.
semi :: Parser String
semi = symbol ";"
rws :: [String] -- list of reserved words
rws = ["if","then","else","while","do","skip","true","false","not","and","or", "print"]
identifier :: Parser String
identifier = (lexeme . try) (p >>= check)
where
p = (:) <$> letterChar <*> many alphaNumChar
check x = if x `elem` rws
then fail $ "hjc: keyword " ++ show x ++ " cannot be an identifier"
else return x
Abstract Syntax Tree
4
Alexander Isenko
15.05.2017
data MiniJava = MiniJava
{ _mainClass :: Class
, _otherClasses :: [Class]
} deriving (Eq)
-- class <name> (extends <name>) { [attributes]; [methods]; }
data Class = Class
{ _className :: Identifier
, _variables :: [Variable]
, _methods :: [Method]
} deriving (Show, Eq)
-- public <type> <name> (<argument>) { <body> }
data Method = Method
{ _methodName :: Identifier
, _methodRetType :: Type
, _methodArguments :: [Variable]
, _methodBody :: [Statement]
} deriving (Show, Eq)
Parser
5
Alexander Isenko
15.05.2017
miniJavaParser :: Parser MiniJava
miniJavaParser = MiniJava <$> mainClassP
<*> many usualClassP
mainClassP :: Parser Class
mainClassP = do
symbol "class"
id <- identifier
(vars, main, methods) <- braces $ (,,) <$> many varDeclarationP
<*> mainMethodP
<*> many methodP
return $ Class id vars (main:methods)
methodP :: Parser Method
methodP = do
symbol "public"
typ <- typeP
id <- identifier
vars <- parens $ variableP `sepBy` comma
stms <- braces $ many statementP
return $ Method id typ vars stms
AST - Interpreter
6
Alexander Isenko
15.05.2017
-- | not written yet, pseudocode
type ClassMember = Map Identifier Statement
data JavaMemory = JavaMemory
{ _printValues :: [Type]
, _curReturnValue :: Maybe Type
, _classMap :: Map Identifier ClassMember
-- ...
}
evalMiniJava :: MiniJava -> StateT JavaMemory IO ()
evalMiniJava (MiniJava mainClass otherClasses) =
mapM evalNormalClass otherClasses
evalMainClass mainClass
evalNormalClass :: Class -> StateT JavaMemory IO ()
evalNormalClass (Class id vars methods) =
evalVars id vars
evalMethods methods