Parsing and testing of `routine` and `call`.
Chris Pressey
2 months ago
59 | 59 |
|
60 | 60 |
let foo = 0 in LDA# foo
|
61 | 61 |
===> Bind "foo" (IntLit 0) (Apply LDA_i (VarRef "foo"))
|
|
62 |
|
|
63 |
Syntax of `routine` and `call`, including typical usage in `let`, and precedence.
|
|
64 |
|
|
65 |
call routine (LDA# 0; TAX)
|
|
66 |
===> Call (Routine (Seq (Apply LDA_i (IntLit 0)) TAX))
|
|
67 |
|
|
68 |
call (routine LDA# 0); TAX
|
|
69 |
===> Call (Seq (Routine (Apply LDA_i (IntLit 0))) TAX)
|
|
70 |
|
|
71 |
let foo = routine (LDA# 0; TAX) in call foo
|
|
72 |
===> Bind "foo" (Routine (Seq (Apply LDA_i (IntLit 0)) TAX)) (Call (VarRef "foo"))
|
62 | 73 |
|
63 | 74 |
Note the precedence of `;` is higher than that of `while`.
|
64 | 75 |
|
|
217 | 228 |
let foo = INX in (LDA# foo ; TAX)
|
218 | 229 |
???> error: Unacceptable argument type
|
219 | 230 |
|
|
231 |
Type of routines.
|
|
232 |
|
|
233 |
routine (LDA# 0; TAX)
|
|
234 |
===> Routine(State[/] -> State[A,X,Z,N/])
|
|
235 |
|
|
236 |
call routine (LDA# 0; TAX)
|
|
237 |
===> (State[/] -> State[A,X,Z,N/])
|
|
238 |
|
220 | 239 |
Code Extraction
|
221 | 240 |
---------------
|
222 | 241 |
|
9 | 9 |
-- Expr1 ::= Expr2 [Expr1].
|
10 | 10 |
-- Expr2 ::= Instruction
|
11 | 11 |
-- | IntLit
|
12 | |
-- | Location -- TODO
|
13 | |
-- | VarName -- TODO
|
|
12 |
-- | Location
|
|
13 |
-- | VarName
|
|
14 |
-- | "routine" Expr
|
|
15 |
-- | "call" Expr
|
|
16 |
-- | "let" {VarName "=" Expr} "in" Expr
|
14 | 17 |
-- | "if" Condition Expr "else" Expr
|
15 | 18 |
-- | "repeat" Expr "until" Condition
|
16 | 19 |
-- | "while" Condition "do" Expr
|
17 | |
-- | "let" {VarName "=" Expr} "in" Expr
|
18 | 20 |
-- | "(" Expr ")".
|
19 | 21 |
-- Instruction ::= "LDA#" | "CLC" | etc.
|
20 | 22 |
-- Condition ::= Flag | "~" Flag.
|
|
41 | 43 |
Token.reservedNames =
|
42 | 44 |
[
|
43 | 45 |
"LDA#", "TAX", "TAY", "CLC", "INX", "INY",
|
|
46 |
"let", "in", "routine", "call",
|
44 | 47 |
"if", "else", "repeat", "until", "while", "do",
|
45 | |
"let", "in",
|
46 | 48 |
"Z", "C", "A", "X", "Y"
|
47 | 49 |
],
|
48 | 50 |
Token.reservedOpNames = [";", "~", "&", "="]
|
|
101 | 103 |
s <- identifier
|
102 | 104 |
return $ VarRef s
|
103 | 105 |
|
|
106 |
routineP :: Parser Expr
|
|
107 |
routineP = do
|
|
108 |
reserved "routine"
|
|
109 |
e <- expr
|
|
110 |
return $ Routine e
|
|
111 |
|
|
112 |
callP :: Parser Expr
|
|
113 |
callP = do
|
|
114 |
reserved "call"
|
|
115 |
e <- expr
|
|
116 |
return $ Call e
|
|
117 |
|
104 | 118 |
lda_i :: Parser Expr
|
105 | 119 |
lda_i = reserved "LDA#" >> return LDA_i
|
106 | 120 |
sta_a = reserved "STA" >> return STA_a
|
|
189 | 203 |
return $ foldl Apply e es
|
190 | 204 |
|
191 | 205 |
expr2 :: Parser Expr
|
192 | |
expr2 = ifP <|> repeatP <|> whileP <|> letP <|> parens expr <|> instruction <|> litInt <|> litLoc <|> varRef
|
|
206 |
expr2 = letP <|> ifP <|> repeatP <|> whileP
|
|
207 |
<|> callP <|> routineP
|
|
208 |
<|> litInt <|> litLoc
|
|
209 |
<|> parens expr
|
|
210 |
<|> instruction
|
|
211 |
<|> varRef
|
193 | 212 |
|
194 | 213 |
-- expression parser
|
195 | 214 |
program :: Parser Expr
|