File: def.cppo

package info (click to toggle)
cppo 1.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 588 kB
  • sloc: ml: 2,133; makefile: 54; sh: 11
file content (88 lines) | stat: -rw-r--r-- 2,216 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
(* This macro application combinator provides call-by-value
   semantics: the actual argument is evaluated up front and
   its value is bound to a variable, which is passed as an
   argument to the macro [F]. *)
#def APPLY(F : [.], X : .)
  (let __x = (X) in F(__x))
    (* Multiple lines permitted; no backslash required. *)
#enddef

(* Some trivial tests. *)
#define ID(X) X
#define C     42
let forty_one = APPLY(ID, 41)
let forty_two = APPLY(ID, C )

(* A [for]-loop macro. *)
#def LOOP(start, finish, body : [.])
(
  for __index = start to finish-1 do
    body(__index)
  done
)
#enddef

(* A [for]-loop macro that performs unrolling. *)
#def UNROLLED_LOOP(start, finish, body : [.]) (
  (* #define can be nested inside #def. *)
  #define BODY(i) APPLY(body, i)
  (* #def can be nested inside #def. *)
  #def INCREMENT(i, k)
    i := !i + k
  #enddef
  let __finish = (finish) in
  let __index = ref (start) in
  while !__index + 2 <= __finish do
    BODY(!__index);
    BODY(!__index + 1);
    INCREMENT(__index, 2)
  done;
  while !__index < __finish do
    BODY(!__index);
    INCREMENT(__index, 1)
  done
)
#enddef

(* In the examples that follow, #scope ... #endscope is used to
   avoid the need to #undefine local macros such as BODY and F. *)

(* Iteration over an array, with a normal loop. *)
let iter f a =
  #scope
  #define BODY(i) (f a.(i))
  LOOP(0, Array.length a, BODY)
  #endscope

(* Iteration over an array, with an unrolled loop. *)
let unrolled_iter f a =
  #scope
  #define BODY(i) (f a.(i))
  UNROLLED_LOOP(0, Array.length a, BODY)
  #endscope

(* Printing an array, with a normal loop. *)
let print_int_array a =
  #scope
  #define F(i) Printf.printf "%d" a.(i)
  LOOP(0, Array.length a, F)
  #endscope

(* A higher-order macro that produces a definition of [iter],
   and accepts an arbitrary definition of the macro [LOOP]. *)
#def DEFINE_ITER(iter, LOOP : [..[.]])
  #scope
  #define BODY(i) (f a.(i))
  let iter f a =
    LOOP(0, Array.length a, BODY)
  #endscope
#enddef

(* Some noise, which does not affect the above definitions. *)
#define BODY(i) "noise"

DEFINE_ITER(iter, LOOP)
DEFINE_ITER(unrolled_iter, UNROLLED_LOOP)

(* Just because we can, undefine BODY. *)
#undef BODY