Changeset 454


Ignore:
Timestamp:
Jan 18, 2011, 7:23:28 PM (6 years ago)
Author:
sacerdot
Message:

CSC + Nicolas + Dominic:

1) back-porting of changes by Nicolas from the compiler
2) new file ASMCosts to compute the cost of labels
3) several changes here and there to implement 2)

Location:
Deliverables/D4.1
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • Deliverables/D4.1/ASM.mli

    r200 r454  
    113113type preamble = (string * int) list
    114114
    115 type assembly_program = preamble * labelled_instruction list;;
     115(* has_main currently unused *)
     116type 'a program =
     117    { preamble   : preamble ;
     118      exit_label : string ;
     119      code       : 'a list ;
     120      has_main   : bool }
  • Deliverables/D4.1/ASMInterpret.ml

    r444 r454  
    6161{
    6262  (* Memory *)
    63   code_memory: WordMap.map;        (* can be reduced *)
     63  code_memory: Physical.WordMap.map;        (* can be reduced *)
    6464  low_internal_ram: Byte7Map.map;
    6565  high_internal_ram: Byte7Map.map;
    66   external_ram: WordMap.map;
     66  external_ram: Physical.WordMap.map;
    6767
    6868  (* Program counter *)
     
    219219
    220220let initialize = {
    221   code_memory = WordMap.empty;
     221  code_memory = Physical.WordMap.empty;
    222222  low_internal_ram = Byte7Map.empty;
    223223  high_internal_ram = Byte7Map.empty;
    224   external_ram = WordMap.empty;
     224  external_ram = Physical.WordMap.empty;
    225225 
    226226  pc = zero `Sixteen;
     
    378378  let next pc =
    379379    let _carry, res = half_add pc (vect_of_int 1 `Sixteen) in
    380     res, WordMap.find pc pmem
     380    res, Physical.WordMap.find pc pmem
    381381  in
    382382  let pc,instr = next pc in
     
    918918;;
    919919
    920 let fold_lefti f =
    921  let rec aux i acc =
    922   function
    923      [] -> acc
    924    | he::tl -> aux (i+1) (f i acc he) tl
    925  in
    926   aux 0
    927 ;;
    928 
    929 let load_code_memory = fold_lefti (fun i mem v -> WordMap.add (vect_of_int i `Sixteen) v mem) WordMap.empty
     920let load_code_memory = Util.fold_lefti (fun i mem v -> Physical.WordMap.add (vect_of_int i `Sixteen) v mem) Physical.WordMap.empty
    930921
    931922let load_mem mem status = { status with code_memory = mem }
     
    933924
    934925module StringMap = Map.Make(String);;
    935 module IntMap = Map.Make(struct type t = int let compare = compare end);;
    936 
     926module WordMap = Map.Make(struct type t = BitVectors.word let compare = compare end);;
     927
     928type labelled_memory = BitVectors.byte list * string WordMap.t * bool (* has main *)
    937929
    938930let assembly_jump addr_of =
     
    949941;;
    950942
    951 let assembly (preamble,l) =
     943let half_add_with_overflow = assert false;;
     944
     945let assembly p =
    952946 let datalabels,_ =
    953947  List.fold_left
     
    955949     let addr16 = vect_of_int addr `Sixteen in
    956950      StringMap.add name addr16 datalabels, addr+size
    957    ) (StringMap.empty,0) preamble
     951   ) (StringMap.empty,0) p.ASM.preamble
    958952 in
    959953 let pc,labels,costs =
     
    962956     match i with
    963957        `Label s -> pc, StringMap.add s pc labels, costs
    964       | `Cost s -> pc, labels, IntMap.add pc s costs
     958      | `Cost s -> pc, labels, WordMap.add pc s costs
    965959      | `Mov (_,_) -> pc, labels, costs
    966960      | `Jmp _
    967       | `Call _ -> pc + 3, labels, costs  (*CSC: very stupid: always expand to worst opcode *)
     961      | `Call _ -> (snd (half_add_with_overflow pc (BitVectors.vect_of_int 3 `Sixteen))), labels, costs  (*CSC: very stupid: always expand to worst opcode *)
    968962      | `WithLabel i ->
    969963          let fake_addr _ = `REL (zero `Eight) in
     
    971965          let i',pc',_ = fetch (load_code_memory (assembly1 fake_jump)) (vect_of_int 0 `Sixteen) in
    972966           assert (fake_jump = i');
    973            (pc + int_of_vect pc',labels, costs)
     967           (snd (half_add_with_overflow pc pc'),labels, costs)
    974968      | #instruction as i ->
    975969        let i',pc',_ = fetch (load_code_memory (assembly1 i)) (vect_of_int 0 `Sixteen) in
    976970         assert (i = i');
    977          (pc + int_of_vect pc',labels, costs)
    978    ) (0,StringMap.empty,IntMap.empty) l
     971         (snd (half_add_with_overflow pc pc'),labels, costs)
     972   ) (BitVectors.zero `Sixteen,StringMap.empty,WordMap.empty) p.ASM.code
    979973 in
    980   if pc >= 65536 then
    981    raise CodeTooLarge
    982   else
    983       List.flatten (List.map
    984          (function
    985             `Label _
    986           | `Cost _ -> []
    987           | `WithLabel i ->
    988               let addr_of (`Label s) =
    989                let addr = StringMap.find s labels in
    990                (* NOT IMPLEMENTED YET; NEEDS SMART ALGORITHM *)
    991                 assert (addr < 256);
    992                 `REL (vect_of_int addr `Eight)
    993               in
    994                assembly1 (assembly_jump addr_of i)
    995           | `Mov (`DPTR,s) ->
    996               let addrr16 = StringMap.find s datalabels in
    997                assembly1 (`MOV (`U4 (`DPTR,`DATA16 addrr16)))
    998           | `Jmp s ->
    999               let pc_offset = StringMap.find s labels in
    1000                 assembly1 (`LJMP (`ADDR16 (vect_of_int pc_offset `Sixteen)))
    1001           | `Call s ->
    1002               let pc_offset = StringMap.find s labels in
    1003                 assembly1 (`LCALL (`ADDR16 (vect_of_int pc_offset `Sixteen)))
    1004           | #instruction as i -> assembly1 i) l), costs
     974  List.flatten (List.map
     975     (function
     976        `Label _
     977      | `Cost _ -> []
     978      | `WithLabel i ->
     979          let addr_of (`Label s) =
     980           let addr = StringMap.find s labels in
     981            (* NOT IMPLEMENTED YET; NEEDS SMART ALGORITHM *)
     982            `REL (assert false) (*addr*)
     983          in
     984           assembly1 (assembly_jump addr_of i)
     985      | `Mov (`DPTR,s) ->
     986          let addrr16 = StringMap.find s datalabels in
     987           assembly1 (`MOV (`U4 (`DPTR,`DATA16 addrr16)))
     988      | `Jmp s ->
     989          let pc_offset = StringMap.find s labels in
     990            assembly1 (`LJMP (`ADDR16 pc_offset))
     991      | `Call s ->
     992          let pc_offset = StringMap.find s labels in
     993            assembly1 (`LCALL (`ADDR16 pc_offset ))
     994      | #instruction as i -> assembly1 i) p.ASM.code), costs, p.ASM.has_main
    1005995;;
    1006996
     
    10351025          assert false for now. Try to understand what DEC really does *)
    10361026       let cry,addr = half_add dpr (mk_word (vect_of_int 0 `Eight) status.acc) in
    1037          WordMap.find addr status.external_ram
     1027         Physical.WordMap.find addr status.external_ram
    10381028  | `A_PC ->
    10391029       (* CSC: what is the right behaviour in case of overflow?
    10401030          assert false for now *)
    10411031       let cry,addr = half_add status.pc (mk_word (vect_of_int 0 `Eight) status.acc) in
    1042          WordMap.find addr status.external_ram
     1032         Physical.WordMap.find addr status.external_ram
    10431033  | `EXT_INDIRECT b ->
    10441034         let addr = get_register status (false,false,b) in
    1045            WordMap.find (mk_word (zero `Eight) addr) status.external_ram
     1035           Physical.WordMap.find (mk_word (zero `Eight) addr) status.external_ram
    10461036  | `EXT_IND_DPTR ->
    10471037       let dpr = mk_word status.dph status.dpl in
    1048          WordMap.find dpr status.external_ram
     1038         Physical.WordMap.find dpr status.external_ram
    10491039;;
    10501040
     
    11181108      let dpr = mk_word status.dph status.dpl in
    11191109      { status with external_ram =
    1120           WordMap.add dpr v status.external_ram }
     1110          Physical.WordMap.add dpr v status.external_ram }
    11211111    | `EXT_INDIRECT b ->
    11221112      let addr = get_register status (false,false,b) in
    11231113      { status with external_ram =
    1124           WordMap.add (mk_word (zero `Eight) addr) v status.external_ram }
     1114          Physical.WordMap.add (mk_word (zero `Eight) addr) v status.external_ram }
    11251115;;
    11261116
     
    17281718        let dptr = mk_word status.dph status.dpl in
    17291719        let cry, addr = half_add dptr big_acc in
    1730         let lookup = WordMap.find addr status.code_memory in
     1720        let lookup = Physical.WordMap.find addr status.code_memory in
    17311721        { status with acc = lookup }
    17321722      | `MOVC (`A, `A_PC) ->
     
    17371727        let status = { status with pc = inc_pc } in
    17381728        let cry,addr = half_add inc_pc big_acc in
    1739         let lookup = WordMap.find addr status.code_memory in
     1729        let lookup = Physical.WordMap.find addr status.code_memory in
    17401730        { status with acc = lookup }
    17411731      (* data transfer *)
     
    17441734      | `MOVX (`U2 (a1, a2)) -> set_arg_8 status (get_arg_8 status false a2) a1
    17451735      | `SETB b -> set_arg_1 status true b
    1746       | `PUSH (`DIRECT b) ->
     1736      | `PUSH a ->
    17471737       (* DPM: What happens if we overflow? *)
    17481738        let cry,new_sp = half_add status.sp (vect_of_int 1 `Eight) in
    17491739        let status = { status with sp = new_sp } in
    1750         write_at_sp status b
     1740        write_at_sp status (get_arg_8 status false a)
    17511741      | `POP (`DIRECT b) ->
    17521742        let contents = read_at_sp status in
     
    18241814        let status = { status with sp = new_sp } in
    18251815        let status = write_at_sp status pc_upper_byte in
    1826         let n1, n2 = from_byte pc_upper_byte in
    1827         let (b1,b2,b3,_) = from_word11 a in
    1828         let (p1,p2,p3,p4),(p5,_,_,_) = from_nibble n1, from_nibble n2 in
    1829         let addr = mk_word (mk_byte (mk_nibble p1 p2 p3 p4) (mk_nibble p5 b1 b2 b3)) pc_lower_byte in
     1816        let addr = addr16_of_addr11 status.pc a in
    18301817        { status with pc = addr }
    18311818      | `LCALL (`ADDR16 addr) ->
     
    18391826        { status with pc = addr }
    18401827      | `AJMP (`ADDR11 a) ->
    1841         let pc_upper_byte, pc_lower_byte = from_word status.pc in
    1842         let n1, n2 = from_byte pc_upper_byte in
    1843         let (p1,p2,p3,p4),(p5,_,_,_) = from_nibble n1, from_nibble n2 in
    1844         let (b1,b2,b3,b) = from_word11 a in
    1845         let addr = mk_word (mk_byte (mk_nibble p1 p2 p3 p4) (mk_nibble p5 b1 b2 b3)) b in
    1846         let cry, new_pc = half_add status.pc addr in
    1847         { status with pc = new_pc }
     1828        let addr = addr16_of_addr11 status.pc a in
     1829        { status with pc = addr }
    18481830      | `LJMP (`ADDR16 a) ->
    18491831        { status with pc = a }
  • Deliverables/D4.1/ASMInterpret.mli

    r216 r454  
    100100val string_of_status: status -> string
    101101
    102 module IntMap: Map.S with type key = int
     102module WordMap: Map.S with type key = BitVectors.word
    103103
    104 val assembly: ASM.assembly_program -> BitVectors.byte list (*ASM.instruction list * symbol_table *) * string IntMap.t
     104type labelled_memory = BitVectors.byte list * string WordMap.t * bool (* has main *)
     105
     106val assembly:
     107 [< ASM.labelled_instruction] ASM.program ->
     108  (*ASM.instruction list * symbol_table *) labelled_memory
    105109
    106110(*
     
    111115val initialize: status
    112116
     117val load_code_memory: BitVectors.byte list -> Physical.WordMap.map
    113118val load_mem: Physical.WordMap.map -> status -> status
    114119val load: BitVectors.byte list -> status -> status
  • Deliverables/D4.1/Physical.ml

    r448 r454  
    103103  | _ -> assert false
    104104;;
     105
     106let addr16_of_addr11 pc a =
     107 let pc_upper, _ = from_word pc in
     108 let n1, n2 = from_byte pc_upper in
     109 let (b1,b2,b3,b) = from_word11 a in
     110 let (p1,p2,p3,p4),(p5,_,_,_) = from_nibble n1, from_nibble n2 in
     111  mk_word (mk_byte (mk_nibble p1 p2 p3 p4) (mk_nibble p5 b1 b2 b3)) b
     112;;
  • Deliverables/D4.1/Physical.mli

    r448 r454  
    2828val dec: byte -> byte (* with roll-over *)
    2929val inc: byte -> byte (* with roll-over *)
     30
     31val addr16_of_addr11: word -> word11 -> word
  • Deliverables/D4.1/Pretty.ml

    r200 r454  
    1010  | `ADDR11 x -> hex_string_of_vect x
    1111  | `ADDR16 x -> hex_string_of_vect x
    12   | `DATA x -> "#" ^ hex_string_of_vect x
    13   | `DATA16 x -> "#" ^ hex_string_of_vect x
     12  | `DATA x -> "#0" ^ hex_string_of_vect x ^ "h"
     13  | `DATA16 x -> "#0" ^ hex_string_of_vect x ^ "h"
    1414  | `BIT x -> "bit " ^ hex_string_of_vect (x: byte)
    1515  | `NBIT x -> "nbit " ^ hex_string_of_vect (x: byte)
     
    1818  | `A_DPTR -> "@DPTR"
    1919  | `A_PC -> "@PC"
    20   | `DIRECT x -> hex_string_of_vect (x: byte)
     20  | `DIRECT x -> "0" ^ (hex_string_of_vect (x: byte)) ^ "h"
    2121  | `EXT_INDIRECT x -> "ext_indirect " ^ string_of_bool x
    22   | `EXT_IND_DPTR -> "ext_indirect_dptr"
     22  | `EXT_IND_DPTR -> "@DPTR"
    2323(* DPM: weird: this seems to be reversed in mcu8051ide: change made. *)
    2424  | `INDIRECT x -> if not x then "@R0" else "@R1"
     
    2929let pp_jump =
    3030 function
    31     `CJNE (`U1 (a1,a2),a3) -> "cjne " ^ pp_arg a1 ^ " " ^ pp_arg a2 ^ " " ^ pp_arg a3
    32   | `CJNE (`U2 (a1,a2),a3) -> "cjne " ^ pp_arg a1 ^ " " ^ pp_arg a2 ^ " " ^ pp_arg a3
    33   | `DJNZ (a1,a2) -> "djnz " ^ pp_arg a1 ^ " " ^ pp_arg a2
    34   | `JB (a1,a2) -> "jb " ^ pp_arg a1 ^ " " ^ pp_arg a2
    35   | `JBC (a1,a2) -> "jbc " ^ pp_arg a1 ^ " " ^ pp_arg a2
     31    `CJNE (`U1 (a1,a2),a3) -> "cjne " ^ pp_arg a1 ^ ", " ^ pp_arg a2 ^ ", " ^ pp_arg a3
     32  | `CJNE (`U2 (a1,a2),a3) -> "cjne " ^ pp_arg a1 ^ ", " ^ pp_arg a2 ^ ", " ^ pp_arg a3
     33  | `DJNZ (a1,a2) -> "djnz " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     34  | `JB (a1,a2) -> "jb " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     35  | `JBC (a1,a2) -> "jbc " ^ pp_arg a1 ^ ", " ^ pp_arg a2
    3636  | `JC a1 -> "jc " ^ pp_arg a1
    37   | `JNB (a1,a2) -> "jnb " ^ pp_arg a1 ^ " " ^ pp_arg a2
     37  | `JNB (a1,a2) -> "jnb " ^ pp_arg a1 ^ ", " ^ pp_arg a2
    3838  | `JNC a1 -> "jnc " ^ pp_arg a1
    3939  | `JNZ a1 -> "jnz " ^ pp_arg a1
     
    4444    `Label l -> l ^ ":"
    4545  | `Cost l -> l ^ ":"
    46   | `Jmp j -> "Jump " ^ j
     46  | `Jmp j -> "Jmp " ^ j
    4747  | `Call j -> "Call " ^ j
    4848  | `WithLabel i -> pp_jump i
     49  | `Begin_fun -> "\n; Begin function"
     50  | `End_fun -> "; End function\n"
    4951  |  (#jump as i) -> pp_jump i
    50   | `Mov (a1,a2) -> "Mov " ^ pp_arg a1 ^ " " ^ a2
     52  | `Mov (a1,a2) -> "mov " ^ pp_arg a1 ^ ", " ^ a2
    5153  | `ACALL a1 -> "acall " ^ pp_arg a1
    52   | `ADD (a1,a2) -> "add " ^ pp_arg a1 ^ " " ^ pp_arg a2
    53   | `ADDC (a1,a2) -> "addc " ^ pp_arg a1 ^ " " ^ pp_arg a2
     54  | `ADD (a1,a2) -> "add " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     55  | `ADDC (a1,a2) -> "addc " ^ pp_arg a1 ^ ", " ^ pp_arg a2
    5456  | `AJMP a1 -> "ajmp " ^ pp_arg a1
    55   | `ANL (`U1 (a1,a2)) -> "anl " ^ pp_arg a1 ^ " " ^ pp_arg a2
    56   | `ANL (`U2 (a1,a2)) -> "anl " ^ pp_arg a1 ^ " " ^ pp_arg a2
    57   | `ANL (`U3 (a1,a2)) -> "anl " ^ pp_arg a1 ^ " " ^ pp_arg a2
     57  | `ANL (`U1 (a1,a2)) -> "anl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     58  | `ANL (`U2 (a1,a2)) -> "anl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     59  | `ANL (`U3 (a1,a2)) -> "anl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
    5860  | `CLR a1 -> "clr " ^ pp_arg a1
    5961  | `CPL a1 -> "cpl " ^ pp_arg a1
    6062  | `DA a1 -> "da " ^ pp_arg a1
    6163  | `DEC a1 -> "dec " ^ pp_arg a1
    62   | `DIV (a1,a2) -> "div " ^ pp_arg a1 ^ " " ^ pp_arg a2
     64  | `DIV (a1,a2) -> "div AB"
    6365  | `INC a1 -> "inc " ^ pp_arg a1
    6466  | `JMP a1 -> "jmp " ^ pp_arg a1
    6567  | `LCALL a1 -> "lcall " ^ pp_arg a1
    6668  | `LJMP a1 -> "ljmp " ^ pp_arg a1
    67   | `MOV (`U1 (a1,a2)) -> "mov " ^ pp_arg a1 ^ " " ^ pp_arg a2
    68   | `MOV (`U2 (a1,a2)) -> "mov " ^ pp_arg a1 ^ " " ^ pp_arg a2
    69   | `MOV (`U3 (a1,a2)) -> "mov " ^ pp_arg a1 ^ " " ^ pp_arg a2
    70   | `MOV (`U4 (a1,a2)) -> "mov " ^ pp_arg a1 ^ " " ^ pp_arg a2
    71   | `MOV (`U5 (a1,a2)) -> "mov " ^ pp_arg a1 ^ " " ^ pp_arg a2
    72   | `MOV (`U6 (a1,a2)) -> "mov " ^ pp_arg a1 ^ " " ^ pp_arg a2
    73   | `MOVC (a1,a2) -> "movc " ^ pp_arg a1 ^ " " ^ pp_arg a2
    74   | `MOVX (`U1 (a1,a2)) -> "movx " ^ pp_arg a1 ^ " " ^ pp_arg a2
    75   | `MOVX (`U2 (a1,a2)) -> "movx " ^ pp_arg a1 ^ " " ^ pp_arg a2
    76   | `MUL(a1, a2) -> "mul " ^ pp_arg a1 ^ " " ^ pp_arg a2
     69  | `MOV (`U1 (a1,a2)) -> "mov " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     70  | `MOV (`U2 (a1,a2)) -> "mov " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     71  | `MOV (`U3 (a1,a2)) -> "mov " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     72  | `MOV (`U4 (a1,a2)) -> "mov " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     73  | `MOV (`U5 (a1,a2)) -> "mov " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     74  | `MOV (`U6 (a1,a2)) -> "mov " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     75  | `MOVC (a1,a2) -> "movc " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     76  | `MOVX (`U1 (a1,a2)) -> "movx " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     77  | `MOVX (`U2 (a1,a2)) -> "movx " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     78  | `MUL(a1, a2) -> "mul AB"
    7779  | `NOP -> "nop"
    78   | `ORL (`U1(a1,a2)) -> "orl " ^ pp_arg a1 ^ " " ^ pp_arg a2
    79   | `ORL (`U2(a1,a2)) -> "orl " ^ pp_arg a1 ^ " " ^ pp_arg a2
    80   | `ORL (`U3(a1,a2)) -> "orl " ^ pp_arg a1 ^ " " ^ pp_arg a2
     80  | `ORL (`U1(a1,a2)) -> "orl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     81  | `ORL (`U2(a1,a2)) -> "orl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     82  | `ORL (`U3(a1,a2)) -> "orl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
    8183  | `POP a1 -> "pop " ^ pp_arg a1
    8284  | `PUSH a1 -> "push " ^ pp_arg a1
     
    8991  | `SETB a1 -> "setb " ^ pp_arg a1
    9092  | `SJMP a1 -> "sjmp " ^ pp_arg a1
    91   | `SUBB (a1,a2) -> "subb " ^ pp_arg a1 ^ " " ^ pp_arg a2
     93  | `SUBB (a1,a2) -> "subb " ^ pp_arg a1 ^ ", " ^ pp_arg a2
    9294  | `SWAP a1 -> "swap " ^ pp_arg a1
    93   | `XCH (a1,a2) -> "xch " ^ pp_arg a1 ^ " " ^ pp_arg a2
    94   | `XCHD(a1,a2) -> "xchd " ^ pp_arg a1 ^ " " ^ pp_arg a2
    95   | `XRL(`U1(a1,a2)) -> "xrl " ^ pp_arg a1 ^ " " ^ pp_arg a2
    96   | `XRL(`U2(a1,a2)) -> "xrl " ^ pp_arg a1 ^ " " ^ pp_arg a2
     95  | `XCH (a1,a2) -> "xch " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     96  | `XCHD(a1,a2) -> "xchd " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     97  | `XRL(`U1(a1,a2)) -> "xrl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     98  | `XRL(`U2(a1,a2)) -> "xrl " ^ pp_arg a1 ^ ", " ^ pp_arg a2
     99
     100let print_program p =
     101  let f s i = Printf.sprintf "%s%s\n" s (pp_instruction i) in
     102  "Org 0\n\n" ^ (List.fold_left f "" p.ASM.code) ^ "\nEND\n"
  • Deliverables/D4.1/Pretty.mli

    r163 r454  
    2020     | `REL of 'e BitVectors.vect ] -> string
    2121val pp_instruction: [< ASM.labelled_instruction] -> string
     22
     23val print_program : [< ASM.labelled_instruction] ASM.program -> string
  • Deliverables/D4.1/Util.ml

    r137 r454  
    2929  in
    3030    List.rev $ aux s 0 []
     31
     32let fold_lefti f =
     33 let rec aux i acc =
     34  function
     35     [] -> acc
     36   | he::tl -> aux (i+1) (f i acc he) tl
     37 in
     38  aux 0
     39;;
     40
Note: See TracChangeset for help on using the changeset viewer.