aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--projects/10/JackParser.hs142
1 files changed, 118 insertions, 24 deletions
diff --git a/projects/10/JackParser.hs b/projects/10/JackParser.hs
index a6fe7b3..d23b878 100644
--- a/projects/10/JackParser.hs
+++ b/projects/10/JackParser.hs
@@ -1,26 +1,120 @@
-- Jack Parser, as the coursework of Project 10 of Nand2Tetris course.
-- Author: Yuchen Pei
-data JClass = JClass JIdentifier [JClassVarDec] [JSubroutineDec]
-data JIdentifier = JIdentifier [Char]
-data JClassVarDec = JClassVarDec JClassVarScope JType JIdentifier
-data JClassVarScope = JStatic | JField
-data JType = JInt | JChar | JBoolean | JVoid
-data JSubroutineDec = JSubroutineDec JSubroutineType JType JIdentifier [JParameter] JSubroutineBody
-data JSubroutineType = JConstructor | JFunction | JMethod
-data JParameter = JParameter JType JIdentifier
-data JSubroutineBody = JSubroutineBody [JVarDec] [JStatement]
-data JVarDec = JVarDec JType JIdentifier
-data JStatement = JLetStatement | JIfStatement | JWhileStatment | JDoStatement | JReturnStatement
-data JLetStatement = JLetStatment JLeftVarId JExpression
-data JIfStatement = JIfStatement JExpression [JStatement] (Maybe [JStatement])
-data JWhileStatment = JWhileStatment JExpression [JStatement]
-type JDoStatement = JSubroutineCall
-type JReturnStatement = Maybe JExpression
-data JExpression = JTerm [(JOp, JTerm)]
-data JTerm = JIntConst | JStrConst | JKeywordConst | JLeftVarId | JSubroutineCall | JExpression | JUnaryOpTerm
-data JLeftVarId = JIdentifier | JLeftVarId JIdentifier (Maybe JExpression)
-data JSubroutineCall = JSubroutineCall Identifier [JExpression] | JSubroutineCall Identifier Identifier [JExpression]
-type JOp = Char
-data JUnaryOpTerm = JUnaryOpTerm JUnaryOp Term
-type JUnaryOp = Char
-data JKeywordConst = JTrue | JFalse | JNull | JThis
+{-# LANGUAGE FlexibleContexts #-}
+import Text.Parsec.Prim
+import Text.Parsec.Char
+import Text.Parsec.Combinator
+import Data.Functor.Identity
+import Data.Either
+
+--turingParse :: Stream s Identity Char => Parsec s () (Int, Char, Rule)
+--solve1 xs = let (initN, initSt, rule) = fromRight (0, 'A', Map.empty) $ parse turingParse "" xs in
+ --sum $ run initN 0 initSt [0] rule
+
+data JClass = JClass JIdentifier [JClassVarDec] [JSubroutineDec] deriving (Show, Eq)
+data JClassVarDec = JClassVarDec JClassVarScope JTypeAndId deriving (Show, Eq)
+data JSubroutineDec = JSubroutineDec JSubroutineHeader JSubroutineBody deriving (Show, Eq)
+data JSubroutineHeader = JSubroutineHeader JSubroutineType JTypeAndId [JParameter] deriving (Show, Eq)
+data JSubroutineBody = JSubroutineBody [JVarDec] [JStatement] deriving (Show, Eq)
+data JClassVarScope = JStatic | JField deriving (Show, Eq)
+data JType = JInt | JChar | JBoolean | JVoid deriving (Show, Eq)
+data JSubroutineType = JConstructor | JFunction | JMethod deriving (Show, Eq)
+data JStatement = JLetStatment JLeftVarId JExpression
+ | JIfStatement JExpression [JStatement] (Maybe [JStatement])
+ | JWhileStatment JExpression [JStatement]
+ | JDoStatement JSubroutineCall
+ | JReturnStatement (Maybe JExpression)
+ deriving (Show, Eq)
+data JExpression = JExpression JTerm [(JBOp, JTerm)] deriving (Show, Eq) -- JBOp can only be one of +-*/&|<>=
+data JTerm = JIntConst Int
+ | JStrConst [Char]
+ | JKeywordConst [Char] -- can only be true, false, null or this
+ | JTermVarId JLeftVarId
+ | JTermCall JSubroutineCall
+ | JTermExp JExpression
+ | JUnaryOpTerm JUOp JTerm -- JOp can only be - or ~ here
+ deriving (Show, Eq)
+data JLeftVarId = JLeftVarId JIdentifier (Maybe JExpression) deriving (Show, Eq)
+data JSubroutineCall = JSubroutineCall JIdentifier (Maybe JIdentifier) [JExpression] deriving (Show, Eq)
+type JBOp = Char
+type JUOp = Char
+type JIdentifier = [Char]
+type JackParser = Parsec [Char] ()
+type JTypeAndId = (JType, JIdentifier)
+type JParameter = JTypeAndId
+type JVarDec = JTypeAndId
+
+
+binaryOpChars = "+-*/&|<>="
+unaryOpChars = "-~"
+keywordConstStrs = ["true", "false", "null", "this"]
+typeStrs' = ["int", "char", "boolean"]
+typeStrs = typeStrs' ++ ["void"]
+classVarScopeStrs = ["static", "field"]
+subroutineTypeStrs = ["constructor", "function", "method"]
+alphaUnderscore = ['a' .. 'z'] ++ ['A' .. 'Z'] ++ ['_']
+alphaNumUnderscore = alphaUnderscore ++ ['0'..'9']
+
+str2JType xs = case xs of "int" -> JInt; "char" -> JChar; "boolean" -> JBoolean; "void" -> JVoid;
+str2JClassVarScope xs = case xs of "static" -> JStatic; "field" -> JField;
+str2JSubroutineType xs = case xs of "constructor" -> JConstructor; "function" -> JFunction; "method" -> JMethod;
+
+parse' parser = parse parser ""
+
+skipSpaces = space >> skipMany space
+
+jack = jClass
+
+jClass :: JackParser JClass
+jClass = undefined
+
+jBOp :: JackParser JBOp
+jBOp = oneOf binaryOpChars
+
+jUOp :: JackParser JUOp
+jUOp = oneOf unaryOpChars
+
+jType :: JackParser JType
+jType = fmap str2JType $ choice $ fmap string typeStrs
+
+jType' :: JackParser JType
+jType' = fmap str2JType $ choice $ fmap string typeStrs'
+
+jClassVarScope :: JackParser JClassVarScope
+jClassVarScope = fmap str2JClassVarScope $ choice $ fmap string classVarScopeStrs
+
+jIdentifier :: JackParser [Char]
+jIdentifier = do
+ x <- oneOf alphaUnderscore
+ xs <- many $ oneOf alphaNumUnderscore
+ return $ x:xs
+
+jClassVarDec :: JackParser JClassVarDec
+jClassVarDec = do
+ scope <- jClassVarScope
+ skipSpaces
+ typeAndId <- jTypeAndId
+ many space >> char ';'
+ return $ JClassVarDec scope typeAndId
+
+jTypeAndId :: JackParser JTypeAndId
+jTypeAndId = do
+ type_ <- jType'
+ skipSpaces
+ id <- jIdentifier
+ return (type_, id)
+jParameter = many space >> jTypeAndId <* many space
+
+jSubroutineType :: JackParser JSubroutineType
+jSubroutineType = fmap str2JSubroutineType $ choice $ fmap string subroutineTypeStrs
+
+{--
+jSubroutineHeader :: JackParser JSubroutineHeader
+jSubroutineHeader = do
+ subtype <- jSubroutineType
+ skipSpaces
+ typeAndId <- jTypeAndId
+ char '('
+ params <- sepBy jParameter (char ',')
+ char ')'
+--}