Create instruction parser

This commit is contained in:
2021-11-04 00:01:18 +01:00
parent 969f1cf517
commit c5e17bce26

View File

@@ -148,7 +148,8 @@ tokenizers = anyTokenizer
, tokenizeString
]
data AST = OperatorNode VM.Op
data AST = EmptyNode
| OperatorNode VM.Op
| IntegerNode Int
| IdentifierNode String
| ColonNode
@@ -156,6 +157,8 @@ data AST = OperatorNode VM.Op
| LabelDefNode String
| LabelRefNode String
| ParamNode AST
| ParamsNode [AST]
| InstructionNode AST AST
deriving (Eq, Show)
type ConsumedTokens = Int
@@ -194,6 +197,22 @@ parseLabelRef = parseSeq [parseAmpersand, parseIdentifier] combine
parseParam :: Parser
parseParam = parseAlt [parseInt, parseLabelRef] ParamNode
parseInstr :: Parser
parseInstr = parseSeq [parseOperator, parseMany parseParam ParamsNode] (\[op, ps] -> InstructionNode op ps)
parseMany :: Parser -> ([AST] -> AST) -> Parser
parseMany parser combiner tokens = Just $ ParseResult ast consumed
where
results = parseGreedy parser tokens
consumed = sum $ map (\(ParseResult _ c) -> c) results
asts = map (\(ParseResult a _) -> a) results
ast = if null asts then EmptyNode else combiner asts
parseGreedy :: Parser -> [Token] -> [ParseResult]
parseGreedy parser tokens = case parser tokens of
(Just r@(ParseResult ast consumed)) -> r : parseGreedy parser (drop consumed tokens)
Nothing -> []
parseAlt :: [Parser] -> (AST -> AST) -> Parser
parseAlt parsers mapper tokens = do
(ParseResult ast consumed) <- parseAny parsers tokens
@@ -229,4 +248,5 @@ parsers :: Parser
parsers = parseAny
[ parseLabelDef
, parseLabelRef
, parseInstr
]