[/] [trunk/] [src/] [mcs51/] [maketimed.sml] - Blame information for rev 67

Line No. Rev Author Line
1 62 tbourke
(* $Id: maketimed.sml 62 2008-08-20 11:20:33Z tbourke $
2
 *
3
 * Copyright (c) 2008 Timothy Bourke (University of NSW and NICTA)
4
 * All rights reserved.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the "BSD License" which is distributed with the
8
 * software in the file LICENSE.
9
 *
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the BSD
13
 * License for more details.
14
 *)
15 17 tbourke
 
16
structure MakeTimed = struct
17
 
18 18 tbourke
  (* shortcuts over Atom and AtomSet *)
19
  infix <+ <- ++ <\ \ =:=  (*`*); open Symbol
20
 
21 17 tbourke
  structure ASM = MCS51Instruction
22
        and E = Expression
23 18 tbourke
        and D = Declaration
24 17 tbourke
        and P = ParsedNta
25
 
26 18 tbourke
  val nmCycleConst = `"P"
27
  val nmCycleClk   = `"x"
28
  val nmAccum      = `"A"
29
  val nmCarry      = `"C"
30
  val nmIRAM       = `"IRAM"
31
  val nmERAM       = `"ERAM"
32
  val nmBITS       = `"BITS"
33
  val nmR          = Vector.tabulate (8, (fn i=> `("R"^Int.toString i)))
34 17 tbourke
 
35 43 tbourke
  val cycleConst = E.VarExpr (E.SimpleVar nmCycleConst)
36
  val cycleClk   = E.VarExpr (E.SimpleVar nmCycleClk)
37 18 tbourke
 
38 17 tbourke
  val one  = E.IntCExpr 1
39
  val zero = E.IntCExpr 0
40 18 tbourke
  val maxbyte = E.IntCExpr 255
41 17 tbourke
 
42
  local
43 43 tbourke
    fun makeVar s       = E.VarExpr (E.SimpleVar (Atom.atom s))
44
    val accum = E.VarExpr (E.SimpleVar nmAccum)
45
    val carry = E.VarExpr (E.SimpleVar nmCarry)
46
    val iram  = E.SimpleVar nmIRAM
47
    val eram  = E.SimpleVar nmERAM
48
    val bits  = E.SimpleVar nmBITS
49 17 tbourke
 
50 18 tbourke
    fun regToAtom ASM.R0 = Vector.sub (nmR, 0)
51
      | regToAtom ASM.R1 = Vector.sub (nmR, 1)
52
      | regToAtom ASM.R2 = Vector.sub (nmR, 2)
53
      | regToAtom ASM.R3 = Vector.sub (nmR, 3)
54
      | regToAtom ASM.R4 = Vector.sub (nmR, 4)
55
      | regToAtom ASM.R5 = Vector.sub (nmR, 5)
56
      | regToAtom ASM.R6 = Vector.sub (nmR, 6)
57
      | regToAtom ASM.R7 = Vector.sub (nmR, 7)
58
 
59 43 tbourke
    fun regToVar r      = E.VarExpr (E.SimpleVar (regToAtom r))
60
    fun subscriptVar (v,idxex) = E.VarExpr (E.SubscriptVar (v, idxex))
61 17 tbourke
    fun directToVar d   = subscriptVar (iram, makeVar (ASM.directToString d))
62
    fun indirectToVar r = subscriptVar (iram, makeVar (ASM.indToString r))
63 20 tbourke
    fun immToVar r      = makeVar (ASM.dataToString r)
64 17 tbourke
    fun bitToVar b      = subscriptVar (bits, makeVar (ASM.bitToString b))
65
 
66 43 tbourke
    fun assign (s,v,a) = [E.AssignExpr {var=s, aop=a, expr=v}]
67 17 tbourke
  in
68 20 tbourke
  fun addReset act = act @ assign (cycleClk, zero, E.AssignOp)
69 17 tbourke
 
70 18 tbourke
  fun makeAction (ASM.ADD_reg r)  = assign(accum,regToVar r,E.PlusEqOp)(*{{{1*)
71 17 tbourke
    | makeAction (ASM.ADD_dir d)  = assign (accum, directToVar d,   E.PlusEqOp)
72
    | makeAction (ASM.ADD_ind r)  = assign (accum, indirectToVar r, E.PlusEqOp)
73
    | makeAction (ASM.ADD_imm d)  = assign (accum, immToVar d,      E.PlusEqOp)
74
 
75
    | makeAction (ASM.ADDC_reg r) = assign (accum, regToVar r,     E.PlusEqOp)
76
    | makeAction (ASM.ADDC_dir d) = assign (accum, directToVar d,  E.PlusEqOp)
77
    | makeAction (ASM.ADDC_ind r) = assign (accum, indirectToVar r,E.PlusEqOp)
78
    | makeAction (ASM.ADDC_imm d) = assign (accum, immToVar d,     E.PlusEqOp)
79
 
80
    | makeAction (ASM.SUBB_reg r) = assign (accum, regToVar r,     E.MinusEqOp)
81
    | makeAction (ASM.SUBB_dir d) = assign (accum, directToVar d,  E.MinusEqOp)
82
    | makeAction (ASM.SUBB_ind r) = assign (accum, indirectToVar r,E.MinusEqOp)
83
    | makeAction (ASM.SUBB_imm d) = assign (accum, immToVar d,     E.MinusEqOp)
84
 
85
    | makeAction (ASM.INC_acc)    = assign(accum,           one, E.PlusEqOp)
86
    | makeAction (ASM.INC_reg r)  = assign(regToVar r,      one, E.PlusEqOp)
87
    | makeAction (ASM.INC_dir d)  = assign(directToVar d,   one, E.PlusEqOp)
88
    | makeAction (ASM.INC_ind r)  = assign(indirectToVar r, one, E.PlusEqOp)
89
 
90
    | makeAction (ASM.DEC_acc)    = assign (accum,           one, E.MinusEqOp)
91
    | makeAction (ASM.DEC_reg r)  = assign (regToVar r,      one, E.MinusEqOp)
92
    | makeAction (ASM.DEC_dir d)  = assign (directToVar d,   one, E.MinusEqOp)
93
    | makeAction(ASM.DEC_ind r)   = assign (indirectToVar r, one, E.MinusEqOp)
94
 
95
    | makeAction (ASM.INC_DPTR)   = []
96
    | makeAction (ASM.MUL)        = []
97
    | makeAction (ASM.DIV)        = []
98
    | makeAction (ASM.DA)         = []
99
 
100
    | makeAction (ASM.ANL_reg r)  = assign (accum, regToVar r,    E.BAndEqOp)
101
    | makeAction (ASM.ANL_dir d)  = assign (accum, directToVar d, E.BAndEqOp)
102
    | makeAction (ASM.ANL_ind r)  = assign (accum,indirectToVar r,E.BAndEqOp)
103
    | makeAction (ASM.ANL_imm d)  = assign (accum, immToVar d,    E.BAndEqOp)
104
    | makeAction (ASM.ANL_A_dir d)= assign (directToVar d,accum,  E.BAndEqOp)
105
    | makeAction (ASM.ANL_dir_imm (d,i)) = assign (directToVar d, immToVar i,
106
                                               E.BAndEqOp)
107
 
108
    | makeAction (ASM.ORL_reg r)  = assign (accum, regToVar r,    E.BOrEqOp)
109
    | makeAction (ASM.ORL_dir d)  = assign (accum, directToVar d, E.BOrEqOp)
110
    | makeAction (ASM.ORL_ind r)  = assign (accum,indirectToVar r,E.BOrEqOp)
111
    | makeAction (ASM.ORL_imm d)  = assign (accum, immToVar d,    E.BOrEqOp)
112
    | makeAction (ASM.ORL_A_dir d)= assign (directToVar d, accum, E.BOrEqOp)
113
    | makeAction (ASM.ORL_dir_imm (d,i)) = assign (directToVar d, immToVar i,
114
                                               E.BOrEqOp)
115
 
116
    | makeAction (ASM.XRL_reg r)  = assign (accum, regToVar r,    E.BXorEqOp)
117
    | makeAction (ASM.XRL_dir d)  = assign (accum, directToVar d, E.BXorEqOp)
118
    | makeAction (ASM.XRL_ind r)  = assign (accum,indirectToVar r,E.BXorEqOp)
119
    | makeAction (ASM.XRL_imm d)  = assign (accum, immToVar d,    E.BXorEqOp)
120
    | makeAction (ASM.XRL_A_dir d)= assign (directToVar d, accum, E.BXorEqOp)
121
    | makeAction (ASM.XRL_dir_imm (d,i)) = assign (directToVar d, immToVar i,
122
                                                E.BXorEqOp)
123
 
124
    | makeAction (ASM.CLR)        = assign (accum, zero, E.AssignOp)
125
    | makeAction (ASM.CPL)        = []
126
    | makeAction (ASM.RL)         = []
127
    | makeAction (ASM.RLC)        = []
128
    | makeAction (ASM.RR)         = []
129
    | makeAction (ASM.RRC)        = []
130
    | makeAction (ASM.SWAP)       = []
131
 
132
    | makeAction (ASM.MOV_regToA r)= assign(accum, regToVar r,   E.AssignOp)
133
    | makeAction (ASM.MOV_dirToA d)= assign(accum, directToVar d,E.AssignOp)
134
    | makeAction (ASM.MOV_indToA r)= assign(accum,indirectToVar r,E.AssignOp)
135
    | makeAction (ASM.MOV_immToA d)= assign(accum, immToVar d,   E.AssignOp)
136
 
137
    | makeAction (ASM.MOV_AToReg   r)   = assign (regToVar r, accum,E.AssignOp)
138
    | makeAction (ASM.MOV_dirToReg (r,d)) = assign (regToVar r, directToVar d,
139
                                                    E.AssignOp)
140
    | makeAction (ASM.MOV_immToReg (r,d)) =assign(regToVar r, immToVar d,
141
                                                  E.AssignOp)
142
 
143
    | makeAction (ASM.MOV_AToDir d)       = assign(accum,directToVar d,E.AssignOp)
144
    | makeAction (ASM.MOV_regToDir (d,r)) = assign(directToVar d, regToVar r,
145
                                               E.AssignOp)
146
    | makeAction (ASM.MOV_dirToDir (dd,ds)) = assign(directToVar dd,
147
                                                directToVar ds, E.AssignOp)
148
    | makeAction (ASM.MOV_indToDir (d,r)) = assign(directToVar d,
149
                                              indirectToVar r, E.AssignOp)
150
    | makeAction (ASM.MOV_immToDir (dd,ds)) = assign(directToVar dd,
151
                                                immToVar ds, E.AssignOp)
152
 
153
    | makeAction (ASM.MOV_AToInd   r)     = assign(indirectToVar r, accum,
154
                                               E.AssignOp)
155
    | makeAction (ASM.MOV_dirToInd (r,d)) = assign(indirectToVar r,
156
                                               directToVar d, E.AssignOp)
157
    | makeAction (ASM.MOV_immToInd (r,d)) = assign(indirectToVar r, immToVar d,
158
                                               E.AssignOp)
159
 
160
    | makeAction (ASM.MOVDPTR data16) = []
161
 
162
    | makeAction (ASM.MOVC_DPTR)  = []
163
    | makeAction (ASM.MOVC_PC)    = []
164
 
165
    | makeAction (ASM.MOVX_From8 r)= assign (accum, subscriptVar (eram,
166
                                    makeVar (ASM.indToString r)),E.AssignOp)
167
 
168
    | makeAction (ASM.MOVX_From16)= []
169
    | makeAction (ASM.MOVX_To8 r) = assign (subscriptVar (eram, makeVar
170
                                       (ASM.indToString r)),accum,E.AssignOp)
171
    | makeAction (ASM.MOVX_To16)  = []
172
 
173
    | makeAction (ASM.PUSH _)     = []
174
    | makeAction (ASM.POP _)      = []
175
 
176
    | makeAction (ASM.XCH_rn _)   = []
177
    | makeAction (ASM.XCH_dir _)  = []
178
    | makeAction (ASM.XCH_ind _)  = []
179
 
180
    | makeAction (ASM.XCHD_ind _) = []
181
 
182
    | makeAction (ASM.CLR_c)      = assign (carry,E.falseExpr,E.AssignOp)
183
    | makeAction (ASM.CLR_bit b)  = assign (bitToVar b,E.falseExpr,E.AssignOp)
184
    | makeAction (ASM.SETB_c)     = assign (carry,E.trueExpr,E.AssignOp)
185
    | makeAction (ASM.SETB_bit b) = assign (bitToVar b,E.trueExpr,E.AssignOp)
186
    | makeAction (ASM.CPL_c)      = assign (carry,E.negate carry,E.AssignOp)
187
    | makeAction (ASM.CPL_bit b)  =assign(carry,E.negate(bitToVar b),E.AssignOp)
188
 
189
    | makeAction (ASM.ANL_bit _)  = []
190
    | makeAction (ASM.ANL_cbit _) = []
191
    | makeAction (ASM.ORL_bit _)  = []
192
    | makeAction (ASM.ORL_cbit _) = []
193
 
194
    | makeAction (ASM.MOV_cToBit _)= []
195
    | makeAction (ASM.MOV_bitToC _)= []
196
 
197
    | makeAction (ASM.ACALL _)    = []
198
    | makeAction (ASM.LCALL _)    = []
199
    | makeAction (ASM.RET)        = []
200
    | makeAction (ASM.RETI)       = []
201
    | makeAction (ASM.AJMP _)     = []
202
    | makeAction (ASM.LJMP _)     = []
203
    | makeAction (ASM.SJMP _)     = []
204
    | makeAction (ASM.JMP_DPTR)   = []
205
    | makeAction (ASM.JZ _)       = []
206
    | makeAction (ASM.JNZ _)      = []
207
    | makeAction (ASM.JC _)       = []
208
    | makeAction (ASM.JNC _)      = []
209
    | makeAction (ASM.JB _)       = []
210
    | makeAction (ASM.JNB _)      = []
211
    | makeAction (ASM.JBC (b, _))= assign (bitToVar b,E.falseExpr,E.AssignOp)
212
 
213
    | makeAction (ASM.CJNE_dirToA _)= []
214
    | makeAction (ASM.CJNE_immToA _)= []
215
    | makeAction (ASM.CJNE_immToReg _)= []
216
    | makeAction (ASM.CJNE_immToInd _)= []
217
 
218
    | makeAction (ASM.DJNZ_reg (r,_)) = assign (regToVar r, one, E.MinusEqOp)
219
    | makeAction (ASM.DJNZ_dir (d,_)) = assign (directToVar d, one, E.MinusEqOp)
220
 
221
    | makeAction (ASM.NOP)        = []
222 18 tbourke
    (*}}}1*)
223 17 tbourke
 
224
  fun jumpsTo (ASM.ACALL _)     = NONE (* could try... *)
225
    | jumpsTo (ASM.LCALL _)     = NONE (* ...to simulate... *)
226
    | jumpsTo ASM.RET           = NONE (* ...call... *)
227
    | jumpsTo ASM.RETI          = NONE (* ...stack. *)
228
 
229
    | jumpsTo (ASM.AJMP a)      = SOME (ASM.addr11ToString a)
230
    | jumpsTo (ASM.LJMP a)      = SOME (ASM.addr16ToString a)
231
    | jumpsTo (ASM.SJMP r)      = SOME (ASM.relToString r)
232
    | jumpsTo (ASM.JMP_DPTR)    = NONE
233
    | jumpsTo _                 = NONE
234
 
235
  fun guardCmp (l, cmp, r, dst) = let
236 43 tbourke
      val g = E.RelExpr {left=l, rel=cmp, right=r}
237 17 tbourke
    in SOME (g, ASM.relToString dst) end
238
 
239
  (* For jump expressions: returns a guard and label pair, the former
240
   * guarding a transition to the latter. *)
241
  fun jumpGuard (ASM.JZ rel)      = guardCmp (accum, E.EqOp, zero, rel)
242
    | jumpGuard (ASM.JNZ rel)     = guardCmp (accum, E.NeOp, zero, rel)
243
    | jumpGuard (ASM.JC rel)      = SOME (carry,          ASM.relToString rel)
244
    | jumpGuard (ASM.JNC rel)     = SOME (E.negate carry, ASM.relToString rel)
245
    | jumpGuard (ASM.JB (b,rel))  = SOME (bitToVar b,     ASM.relToString rel)
246
    | jumpGuard (ASM.JNB (b,rel)) = SOME (E.negate(bitToVar b),ASM.relToString rel)
247
    | jumpGuard (ASM.JBC (b,rel)) = SOME (bitToVar b, ASM.relToString rel)
248
    | jumpGuard (ASM.CJNE_dirToA (d,rel))= guardCmp (directToVar d,E.NeOp,accum,rel)
249
    | jumpGuard (ASM.CJNE_immToA (d,rel))= guardCmp (immToVar d,E.NeOp,accum,rel)
250
    | jumpGuard (ASM.CJNE_immToReg (r,d,rel)) = guardCmp (regToVar r, E.NeOp,
251
                                                      immToVar d, rel)
252
    | jumpGuard (ASM.CJNE_immToInd (r,d,rel)) = guardCmp (indirectToVar r, E.NeOp,
253
                                                      immToVar d, rel)
254 20 tbourke
    | jumpGuard (ASM.DJNZ_reg (r,rel)) = guardCmp (regToVar r, E.NeOp, one, rel)
255
    | jumpGuard (ASM.DJNZ_dir (d,rel)) = guardCmp (directToVar d,E.NeOp,one,rel)
256 17 tbourke
    | jumpGuard _ = NONE
257
 
258 20 tbourke
  fun seqGuard (ASM.DJNZ_reg (r,rel)) =SOME (E.RelExpr {left=regToVar r,
259 43 tbourke
                                                        rel=E.EqOp, right=one})
260 20 tbourke
    | seqGuard (ASM.DJNZ_dir (d,rel)) =SOME (E.RelExpr {left=directToVar d,
261 43 tbourke
                                                        rel=E.EqOp, right=one})
262 20 tbourke
    | seqGuard act = Option.map (fn (jg,_)=>E.negate jg) (jumpGuard act)
263
 
264 18 tbourke
  local
265
    val byte = E.INT (SOME (zero, maxbyte), E.NoQual)
266
    fun mkArray (n, ty) = E.ARRAY (ty,E.Type (E.INT
267
                                        (SOME (zero, E.IntCExpr (n - 1)),
268
                                        E.NoQual)))
269 43 tbourke
    fun mkReg (r, rs) = (r, D.VarDecl {id=r, ty=byte, pos=D.nopos,
270
                                       initial=SOME (D.SimpleInit zero)}) :: rs
271 18 tbourke
 
272
    val varMap = foldl AtomMap.insert' AtomMap.empty (
273
      (nmCycleConst,D.VarDecl {id=nmCycleConst, ty=E.INT (NONE, E.Const),
274 43 tbourke
                               initial=NONE, pos=D.nopos})::
275
      (nmCycleClk,  D.VarDecl {id=nmCycleClk, ty=E.CLOCK, initial=NONE,
276
                               pos=D.nopos})::
277
      (nmAccum,     D.VarDecl {id=nmAccum, ty=byte, pos=D.nopos,
278
                               initial=SOME (D.SimpleInit zero)})::
279
      (nmCarry,     D.VarDecl {id=nmAccum, ty=E.BOOL E.NoQual, pos=D.nopos,
280
                               initial=SOME (D.SimpleInit E.falseExpr)})::
281 18 tbourke
      (nmIRAM,      D.VarDecl {id=nmIRAM, ty=mkArray (128, byte),
282 43 tbourke
                               initial=NONE, pos=D.nopos})::
283
      (nmERAM,      D.VarDecl {id=nmERAM, ty=mkArray (10,byte), initial=NONE,
284
                               pos=D.nopos})::
285 20 tbourke
      (nmBITS,      D.VarDecl {id=nmBITS, ty=mkArray (128, E.BOOL E.NoQual),
286 43 tbourke
                               initial=NONE, pos=D.nopos})::
287 18 tbourke
      Vector.foldl mkReg [] nmR)
288
  in
289
  fun varToDecl nm = AtomMap.find (varMap, nm)
290
  end
291
 
292
 
293 17 tbourke
  end (* local *)
294 18 tbourke
 
295
  local
296
    val columnSep       = 280   (* distance between columns               *)
297
    val rowSep          = 120   (* distance between rows                  *)
298
    val invariantHorOff = 6     (* horizontal offset for invariant label  *)
299
    val invariantVerOff = 8     (* vertical offset for invariant label    *)
300
 
301
    infixr :::
302
    fun NONE ::: xs = xs | (SOME x) ::: xs = x::xs
303
  in
304 17 tbourke
  fun actionConstraint (a, rel) = let
305
      val nc = ASM.numCycles a
306
      val t  = if nc = 1 then cycleConst
307
               else E.BinIntExpr {left=E.IntCExpr nc, bop=E.TimesOp,
308 43 tbourke
                                  right=cycleConst}
309
    in E.RelExpr {left=cycleClk, rel=rel, right=t} end
310 17 tbourke
 
311
  fun makeTimed ([], _) = P.Template.new ("", NONE)
312
    | makeTimed (instrs, {showinstrs, position, maxrows}) = let
313
 
314
      local val (currx, curry, n) = (ref 0, ref 0, ref 0)
315 18 tbourke
            fun incx () = (currx := (!currx) + columnSep; curry := 0)
316
            fun incy () = (curry := (!curry) + rowSep)
317 17 tbourke
      in fun incPos () = SOME (!currx, !curry)
318
                         before (n := ((!n) + 1) mod maxrows;
319
                                 if (!n) = 0 then incx () else incy ())
320
      end
321
      val nextPos = if position then incPos else (fn _ => NONE)
322
 
323
      fun makeSync act = if showinstrs
324
                         then SOME (Atom.atom ("'"^ASM.toString act^"'"),
325
                                    E.Output, [])
326
                         else NONE
327
      fun labelToLoc map (label, defaultloc) =
328
            case AtomMap.find (map, Atom.atom label) of
329
              NONE => (Util.warn ["missing location label: ",label]; defaultloc)
330
            | SOME l => l
331
 
332
      fun addJmpTrans map (loc, act) = let
333
          fun f (g, dstlabel) = let
334
              val dst = if dstlabel = "*" then loc
335
                        else labelToLoc map (dstlabel, loc)
336
              val guard = E.andexpr (g, actionConstraint (act, E.GeOp))
337
            in
338
              SOME (P.Transition {id=NONE, source=loc, target=dst,
339
                                  select=([], NONE), guard=(guard, NONE),
340
                                  sync=(makeSync act,NONE),
341 20 tbourke
                                  update=(addReset (makeAction act),NONE),
342 17 tbourke
                                  comments=(SOME (ASM.toString act), NONE),
343
                                  position=NONE, color=NONE, nails=[]})
344
            end
345
        in Option.mapPartial f (jumpGuard act) end
346
 
347 20 tbourke
      fun addloc ((nmo, act), (template, map, lids, n)) = let
348 18 tbourke
          val lid = P.Location.newId template
349
          val pos = nextPos ()
350 20 tbourke
          val npos = Option.map (fn (x, y)=>(x - 25, y - 32)) pos
351 18 tbourke
          val ipos = Option.map (fn (x, y)=>(x + invariantHorOff,
352
                                             y + invariantVerOff)) pos
353 20 tbourke
          val l = P.Location {id=lid, position=pos, color=NONE,
354
                          name=(SOME ("s"^Int.toString n), npos),
355 18 tbourke
                          invariant=(actionConstraint (act, E.LeOp), ipos),
356
                          comments=(nmo, NONE), urgent=false, committed=false}
357
          val map' = case nmo of
358
                       NONE   => map
359
                     | SOME s => AtomMap.insert (map, Atom.atom s, lid)
360 20 tbourke
        in (P.Template.updLocation template l, map', (lid, act)::lids, n+1) end
361 18 tbourke
 
362
      fun addFinal false args = args
363 20 tbourke
        | addFinal true  (template, map, lids, n) = let
364 18 tbourke
          val lid = P.Location.newId template
365 20 tbourke
          val pos = nextPos ()
366
          val npos = Option.map (fn (x, y)=>(x - 25, y - 32)) pos
367
          val l = P.Location {id=lid, position=pos, color=NONE,
368
                    name=(SOME ("s"^Int.toString n), npos),
369
                    invariant=(E.trueExpr, NONE),
370 18 tbourke
                    comments=(SOME "fin", NONE), urgent=false, committed=false}
371 20 tbourke
        in
372
          (P.Template.updLocation template l, map, (lid, ASM.NOP)::lids, n+1)
373
        end
374 18 tbourke
 
375 20 tbourke
      val (template, locmap, rlids, _) = addFinal
376 18 tbourke
            (not (isSome (jumpsTo (#2 (List.last instrs)))))
377 20 tbourke
            (foldl addloc (P.Template.new ("",NONE), AtomMap.empty,[],0) instrs)
378 18 tbourke
 
379
      val lids = rev rlids
380
      val template = P.Template.updInitial template (SOME (#1 (hd lids)))
381
      val locIdToPos = P.Location.toMap (template, valOf o P.Location.selPos)
382
 
383 17 tbourke
      fun addSeqTrans (src, act, dst) = let
384
          val ac = actionConstraint (act, E.GeOp)
385 20 tbourke
          val g  = case seqGuard act of
386
                     NONE    => ac
387
                   | SOME sg => E.andexpr (sg, ac)
388 18 tbourke
 
389
          val (SOME (sp as (sx, _)), SOME (dp as (dx, _))) = (locIdToPos src,
390
                                                              locIdToPos dst)
391
          val nails = if sx = dx then [] else Layout.joinColumns (sp, dp)
392 17 tbourke
        in
393
          P.Transition {id=NONE, source=src, target=dst,
394
                        select=([], NONE), guard=(g, NONE),
395 20 tbourke
                        sync=(makeSync act,NONE),
396
                        update=(addReset (makeAction act),NONE),
397 17 tbourke
                        comments=(SOME (ASM.toString act), NONE), position=NONE,
398 18 tbourke
                        color=NONE, nails=nails}
399 17 tbourke
        end
400
 
401
      fun addSeqTransitions map xs = let
402
          fun f [] = []
403
            | f [(loc,act)] = (case jumpsTo act of
404
                     NONE     => []
405
                   | SOME jdst=> [addSeqTrans(loc,act,labelToLoc map (jdst,loc))])
406
            | f ((src,act)::(ts as (dst,_)::_)) =
407
                    (case jumpsTo act of
408
                       NONE      =>addSeqTrans (src,act,dst)
409
                     | SOME jdst =>addSeqTrans (src,act,labelToLoc map (jdst,dst)))
410
                    ::f ts
411
        in f xs end
412
 
413 18 tbourke
      val seqTrans = addSeqTransitions locmap lids
414
      val jmpTrans  = List.mapPartial (addJmpTrans locmap) lids
415
      val trans = (Layout.matrixTrans (locIdToPos, jmpTrans))
416
                  @ (map (Layout.positionLabels locIdToPos) seqTrans)
417 17 tbourke
 
418 18 tbourke
      val vars = foldl (fn (t, s)=>P.freeTransitionNames t ++ s)
419
                       (emptyset <+ nmCycleConst <+ nmCycleClk) trans
420 17 tbourke
 
421 18 tbourke
      val vardecls = AtomSet.foldl (fn (v,vs)=>varToDecl v:::vs) [] vars
422
      val decls = Environment.addDeclarations (P.noDeclaration,
423
                                               Environment.TemplateScope,
424
                                               vardecls)
425 17 tbourke
    in
426 18 tbourke
      P.Template.updDeclaration (P.Template.updTransitions template trans) decls
427 17 tbourke
    end
428 18 tbourke
  end (* local *)
429 17 tbourke
 
430
end
431