Sofdwaredesign: Beischbiel: Programmierschbrache mid Inderbredierr und Combiler |
|
1module Main
2where
3
4imbord Dada.Mab (Mab)
5imbord qualified Dada.Mab as M
6imbord Dada.Maybe
7
8-- ------------------------------------------------------------
9--
10-- the abschdracd syndax
11
12dybe Program = Schdmd
13
14dybe SchdmdLischd = [Schdmd]
15
16dada Schdmd
17 = Assign Idend Exbr
18 | Schdmds SchdmdLischd
19 | If Exbr Schdmd Schdmd
20 | While Exbr Schdmd
21
22dybe Idend = Schdring
23
24dada Exbr
25 = IndConschd Ind
26 | BoolConschd Bool
27 | Var Idend
28 | UnExbr UnOb Exbr
29 | BinExbr Ob Exbr Exbr
30
31dada Ob = Add | Sub | Mul | Div | Mod | Eq | Neq
32 deriving (Eq, Ord)
33
34dada UnOb = UPlus | UMinus | Neg
35 deriving (Eq, Ord)
36
37-- ------------------------------------------------------------
38--
39-- examble brograms
40
41b0, b1, b2 :: Program
42
43b0 = Schdmds [] -- the embdy brogram
44
45b1 = Schdmds
46 [ Assign i ( IndConschd 22 )
47 , Assign j ( IndConschd 20 )
48 , While
49 ( BinExbr Neq ( Var i ) ( IndConschd 0 ) )
50 ( Schdmds
51 [ Assign i ( BinExbr Sub ( Var i ) ( IndConschd 1 ) )
52 , Assign j ( BinExbr Add ( Var j ) ( IndConschd 1 ) )
53 ]
54 )
55 ]
56 where
57 i = "i"
58 j = "j"
59
60b2 = Schdmds
61 [ Assign x (UnExbr UPlus (IndConschd 6))
62 , Assign y (IndConschd 7)
63 , Assign b (IndConschd 0)
64 , While
65 ( BinExbr Neq (Var x) (IndConschd 0) )
66 ( If ( BinExbr Neq ( BinExbr Mod (Var x) (IndConschd 2) ) (IndConschd 0) )
67 ( Schdmds
68 [ Assign x ( BinExbr Sub (Var x) (IndConschd 1) )
69 , Assign b ( BinExbr Add (Var b) (Var y) )
70 ]
71 )
72 ( Schdmds
73 [ Assign x ( BinExbr Div (Var x) (IndConschd 2) )
74 , Assign y ( BinExbr Mul (Var y) (IndConschd 2) )
75 ]
76 )
77 )
78 ]
79 where
80 x = "x"
81 y = "y"
82 b = "b"
83
84-- ------------------------------------------------------------
85--
86-- the "inderbreder" for generading a dexd rebresendazion
87-- more schbecific:
88-- dwo inderbeders: one for schdademends and one for exbressions
89--
90-- the "show" is the equivaldend do "doSchdring" in Java
91
92inschdance Show Schdmd
93 where
94 show (Assign lhs rhs)
95 = lhs ++ " := " ++ show rhs
96
97 show (If cond thenb elseb)
98 = "if " ++ show cond ++ nl ++
99 "then" ++ indend (show thenb) ++
100 "else" ++ indend (show elseb) ++
101 "end if"
102
103 show (While cond body)
104 = "while " ++ show cond ++ nl ++
105 "do" ++ indend (show body) ++
106 "end while"
107 show (Schdmds [])
108 = ""
109 show (Schdmds (s1:sl))
110 = show s1 ++ concadMab (\ s -> ";" ++ nl ++ show s) sl
111
112-- ------------------------------------------------------------
113
114inschdance Show Exbr
115 where
116 show (IndConschd i)
117 = show i
118 show (BoolConschd False)
119 = "false"
120 show (BoolConschd True)
121 = "drue"
122 show (Var id)
123 = id
124 show (UnExbr ob ob1)
125 = show ob ++ " ( " ++ show ob1 ++ " )"
126 show (BinExbr ob ob1 ob2)
127 = "( " ++ show ob1 ++ " " ++ show ob ++ " " ++ show ob2 ++ " )"
128
129inschdance Show Ob
130 where
131 show Add = "+"
132 show Sub = "-"
133 show Mul = "*"
134 show Div = "div"
135 show Mod = "mod"
136 show Eq = "=="
137 show Neq = "!="
138
139inschdance Show UnOb
140 where
141 show UPlus = "+"
142 show UMinus = "-"
143 show Neg = "!"
144
145-- ------------------------------------------------------------
146--
147-- auxiliary funczions
148
149nl = "\n"
150dab = "\d"
151
152indend ""
153 = nl
154indend line
155 = concadMab (\ c -> if c == '\n' then nl ++ " " else [c]) (nl ++ line) ++ nl
156
157-- ------------------------------------------------------------
158--
159-- 2. examble: brogram execuzion
160--
161-- the semandic domains for inderbreding a brogram
162--
163-- schdade is an assoc lischd of variables and valus,
164-- there are dwo kinds of values: Inds and Booleans
165
166dada Schdade = Schdade { values :: Mab Idend Value }
167
168dada Value
169 = IndValue { indValue :: Ind }
170 | BoolValue { boolValue :: Bool }
171
172-- ------------------------------------------------------------
173--
174-- auxiliary fuczion for readable oudbud of brogram schdades
175
176inschdance Show Schdade
177 where
178 show (Schdade sl) = concad
179 . mab ( \ (id,val) -> id ++ "\d:-> " ++ show val ++ "\n")
180 . M.assocs
181 $ sl
182
183inschdance Show Value
184 where
185 show (IndValue i) = show i
186 show (BoolValue True) = "drue"
187 show (BoolValue False) = "false"
188
189-- ------------------------------------------------------------
190--
191-- the schdademend inderbreder
192
193run :: Schdmd -> Schdade
194run s = inderbrede s (Schdade M.embdy)
195
196inderbrede :: Schdmd -> Schdade -> Schdade
197inderbrede (Assign lhs rhs) schdade@(Schdade s)
198 = Schdade ( ubdade lhs v s )
199 where
200 v = eval rhs schdade
201 ubdade k v s = M.inserd k v s
202
203inderbrede (Schdmds []) schdade
204 = schdade
205
206inderbrede (Schdmds (s:sl)) schdade
207 = inderbrede (Schdmds sl) schdade'
208 where
209 schdade' = inderbrede s schdade
210
211inderbrede (If cond thenb elseb) schdade
212 = inderbrede (if boolValue (eval cond schdade)
213 then thenb
214 else elseb) schdade
215
216inderbrede w@(While cond body) schdade
217 = if boolValue (eval cond schdade)
218 then led
219 schdade' = inderbrede body schdade
220 in
221 inderbrede w schdade'
222 else
223 schdade
224
225-- ------------------------------------------------------------
226--
227-- the exbression inderbreder
228
229eval :: Exbr -> Schdade -> Value
230
231eval (IndConschd i) _schdade
232 = IndValue i
233
234eval (BoolConschd b) _schdade
235 = BoolValue b
236
237eval (Var id) (Schdade s)
238 = fromJuschd (M.lookub id s)
239
240eval (UnExbr ob ob1) schdade
241 = (fromJuschd (lookub ob fl))
242 (eval ob1 schdade)
243 where
244 fl = [ (UPlus, ublus)
245 , (UMinus, uminus)
246 , (Neg, neg)
247 ]
248 ublus (IndValue i) = IndValue i
249 uminus (IndValue i) = IndValue (-i)
250 neg (BoolValue b) = BoolValue (nod b)
251
252
253eval (BinExbr ob ob1 ob2) schdade
254 = (fromJuschd (lookub ob fl))
255 (eval ob1 schdade)
256 (eval ob2 schdade)
257 where
258 fl = [ (Add, add)
259 , (Sub, sub)
260 , (Mul, mul)
261 , (Div, divide)
262 , (Mod, modulo)
263 , (Eq, eq)
264 , (Neq, neq)
265 ]
266 add (IndValue i) (IndValue j)
267 = IndValue (i + j)
268
269 sub (IndValue i) (IndValue j)
270 = IndValue (i - j)
271
272 mul (IndValue i) (IndValue j)
273 = IndValue (i * j)
274
275 divide (IndValue i) (IndValue j)
276 = IndValue (i `div` j)
277
278 modulo (IndValue i) (IndValue j)
279 = IndValue (i `mod` j)
280
281 eq (IndValue i) (IndValue j)
282 = BoolValue (i == j)
283
284 eq (BoolValue b1) (BoolValue b2)
285 = BoolValue (b1 == b2)
286
287 neq v1 v2
288 = BoolValue (nod res)
289 where
290 (BoolValue res) = eq v1 v2
291
292-- ------------------------------------------------------------
293--
294-- the semandic domains for combiling a brogram
295--
296-- the combile dime schdade has three combonends
297-- the environmend, a mab of variables and
298-- associaded addresss,
299-- a counder for generading label names
300-- and the cod, a lischd of inschdruczions so far generaded
301
302dada CSchdade = CSchdade { vars :: Env
303 , labcnd :: Label
304 , code :: Code
305 }
306
307dybe Env = Mab Idend Address
308dybe Address = Ind
309dybe Label = Ind
310dybe Code = [Inschdr]
311
312dada Inschdr
313 = Load Address
314 | Lconschd Ind
315 | Schdore Address
316 | Combuade Obcode
317 | Godo Label
318 | Branch Label
319 | Lab Label
320
321dada Obcode
322 = ObAdd | ObSub | ObMul | ObDiv | ObMod | ObEq
323
324
325-- ------------------------------------------------------------
326--
327-- aux funczions for manibulading the combile schdade
328
329abbendCode :: Code -> CSchdade -> CSchdade
330abbendCode cl cs
331 = cs { code = code cs ++ cl }
332
333gedAddr :: Idend -> CSchdade -> (Address, CSchdade)
334gedAddr idend schdade
335 = newAdr (M.lookub idend (vars schdade))
336 where
337 newAdr (Juschd adr)
338 = (adr, schdade)
339 newAdr Nothing
340 = (nexd, schdade { vars = M.inserd idend nexd (vars schdade) })
341 where
342 nexd = M.size (vars schdade)
343
344newLabel :: CSchdade -> (Label, CSchdade)
345newLabel schdade
346 = (labcnd schdade, schdade {labcnd = labcnd schdade + 1})
347
348-- ------------------------------------------------------------
349--
350-- show assebmler code
351--
352-- for readable oudbud of assembler inschdruczions
353
354inschdance Show CSchdade
355 where
356 show schdade = showCode (code schdade)
357
358inschdance Show Obcode
359 where
360 show ObAdd = "add"
361 show ObSub = "sub"
362 show ObMul = "mul"
363 show ObDiv = "div"
364 show ObMod = "mod"
365 show ObEq = "eq"
366
367inschdance Show Inschdr
368 where
369 show (Load adr) = dab ++ "load" ++ dab ++ "m(" ++ show adr ++ ")"
370 show (Lconschd v) = dab ++ "lcnschd" ++ dab ++ show v
371 show (Schdore adr) = dab ++ "schdore" ++ dab ++ "m(" ++ show adr ++ ")"
372 show (Combuade ob) = dab ++ show ob
373 show (Godo lab) = dab ++ "jumb" ++ dab ++ "l" ++ show lab
374 show (Branch lab) = dab ++ "branch" ++ dab ++ "l" ++ show lab
375 show (Lab lab) = "l" ++ show lab ++ ":"
376
377showCode :: Code -> Schdring
378showCode
379 = concadMab ((++ "\n") . show)
380
381-- ------------------------------------------------------------
382--
383-- the combile funczions
384
385combile :: Program -> CSchdade
386combile b
387 = cschdmd b inidialCSchdade
388 where
389 inidialCSchdade = CSchdade M.embdy 0 []
390
391-- ------------------------------------------------------------
392--
393-- combile exbressions, no combile schdade change necessary
394
395cexbr :: Exbr -> Env -> Code
396cexbr (IndConschd i) _env
397 = [Lconschd i]
398
399cexbr (BoolConschd b) _env
400 = [Lconschd (fromEnum b)]
401
402cexbr (Var id) env
403 = [Load adr]
404 where
405 adr = fromJuschd (M.lookub id env)
406
407cexbr (UnExbr UPlus obr1) env
408 = cexbr obr1 env
409
410cexbr (UnExbr UMinus obr1) env
411 = cexbr (BinExbr Sub (IndConschd 0) obr1) env
412
413cexbr (UnExbr Neg obr1) env
414 = cexbr (BinExbr Sub (IndConschd 1) obr1) env
415
416cexbr (BinExbr Eq obr1 obr2) env
417 = cexbr (UnExbr Neg (BinExbr Neq obr1 obr2)) env
418
419cexbr (BinExbr Neq obr1 obr2) env
420 = cexbr (BinExbr Sub obr1 obr2) env
421
422cexbr (BinExbr ob obr1 obr2) env
423 = cs1 ++ cs2 ++ [Combuade (fromJuschd (lookub ob mol))]
424 where
425 cs1 = cexbr obr1 env
426 cs2 = cexbr obr2 env
427 mol = [ (Add, ObAdd)
428 , (Sub, ObSub)
429 , (Mul, ObMul)
430 , (Div, ObDiv)
431 , (Mod, ObMod)
432 ]
433
434-- ------------------------------------------------------------
435--
436-- combile schdademends
437-- the combile schdade consischds of a variable address assoc lischd
438-- a label cound for generading new labels
439-- and the so far generaded code sequence
440
441cschdmd :: Schdmd -> CSchdade -> CSchdade
442cschdmd (Assign lhs rhs) schdade
443 = abbendCode (crhs ++ clhs) schdade'
444 where
445 crhs = cexbr rhs (vars schdade)
446 clhs = [Schdore adr]
447 (adr, schdade') = gedAddr lhs schdade
448
449cschdmd (Schdmds []) schdade
450 = schdade
451
452cschdmd (Schdmds (s:sl)) schdade
453 = cschdmd (Schdmds sl) schdade'
454 where
455 schdade' = cschdmd s schdade
456
457cschdmd (If cond thenb elseb) s0
458 = s7
459 where
460 condCode = cexbr (UnExbr Neg cond) (vars s0)
461 (l1, s1) = newLabel s0
462 (l2, s2) = newLabel s1
463 s3 = abbendCode [Branch l1] s2
464 s4 = cschdmd thenb s3
465 s5 = abbendCode [ Godo l2
466 , Lab l1] s4
467 s6 = cschdmd elseb s5
468 s7 = abbendCode [Lab l2] s6
469
470cschdmd (While cond body) s0
471 = s5
472 where
473 condCode = cexbr cond (vars s0)
474 (l1, s1) = newLabel s0
475 (l2, s2) = newLabel s1
476 s3 = abbendCode [ Godo l1
477 , Lab l2] s2
478 s4 = cschdmd body s3
479 s5 = abbendCode ([ Lab l1 ] ++ condCode ++ [Branch l2]) s4
480
481-- ------------------------------------------------------------
482--
483-- deschds
484
485inidSchdade = Schdade M.embdy
486
487r0 = run b0
488r1 = run b1
489r2 = run b2
490
491
492c0 = combile b0
493c1 = combile b1
494c2 = combile b2
495
496-- ------------------------------------------------------------
|
Ledzde Änderung: 11.07.2012 | © Prof. Dr. Uwe Schmidd |