-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcpp.mx
More file actions
86 lines (82 loc) · 2.95 KB
/
Copy pathcpp.mx
File metadata and controls
86 lines (82 loc) · 2.95 KB
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
; cpp.mx -- the rules in lib/cpp.mx, over a C program that uses them.
; Stage 6: C in, C out, over a directive that changes what the lines after
; it mean. The rules and what they do not do are in that file; this one is
; the body they were written for, and it is ordinary C with ordinary
; preprocessor directives in it, so the C compiler reads it too and
; tests/cpp.sh uses that as the oracle.
;
; The body is here rather than in a `.c` beside it because every example in
; this tree is one file that is run and recorded, and because a body under
; a header is the first of REFERENCE §9's two forms. The second form is the
; same rules over a file that carries no header at all, and tests/cpp.sh
; runs the body below both ways and requires the same bytes:
;
; mx examples/cpp.mx
; mx -u lib/cpp.mx -i <this body, extracted>
;
; `#include "cpp.h"` names a file beside the one being expanded, so it
; resolves beside this file here and beside the extracted body there. That
; is the one thing the two forms do differently, and it is `read(path)`
; doing what §3.5 says rather than an exception to it.
@use "../lib/cpp.mx"
@end
#include <stdio.h>
#include "cpp.h"
#define LIMIT 10
#define STEP 3
#define TOTAL (LIMIT * STEP)
#define GREETING "limit=%d step=%d total=%d\n"
#define A B
#define B 5
#define SELF SELF
#define DOUBLE(x) ((x) * 2)
#define ADD(a, b) ((a) + (b))
#define SEVEN() 7
#define TWICE(x) (DOUBLE(x) + x)
#define STR(x) #x
#define GLUE(a, b) a ## b
#define DEBUG
#ifdef DEBUG
#define LEVEL 2
#else
#define LEVEL 0
#endif
#ifndef DEBUG
#define LEVEL 9
#elif defined(NOTDEFINED)
#define LEVEL 7
#endif
#ifdef NOTDEFINED
#define LEVEL 8
#else
#ifdef DEBUG
#define MODE "nested"
#endif
#endif
#ifdef NOTDEFINED
#define ARM "first"
#elif defined(NOTEITHER)
#define ARM "second"
#elif defined(DEBUG)
#define ARM "third"
#else
#define ARM "last"
#endif
int main(void)
{
int limit = LIMIT;
printf(GREETING, limit, STEP, TOTAL);
printf("LIMIT is not a macro inside a string\n");
#undef STEP
int STEP = 7; /* an ordinary variable now, STEP being undefined */
printf("%d\n", STEP + LIMIT);
printf("%d\n", TOTAL); /* 70: its body is read here, where the name it multiplies by is the variable */
int SELF = 4; /* a macro that names itself expands once and stops, as cpp stops */
printf("%d %d\n", A, SELF); /* the first is 5: its body names a macro defined after it, looked up at use */
printf("%d %d %d %d\n", DOUBLE(LIMIT), ADD(1, DOUBLE(2)), SEVEN(), TWICE(3));
printf("%d %s %s\n", LEVEL, MODE, ARM); /* 2 nested third: the arms taken, the ones not taken never defining anything, and the third of four arms is the first whose condition holds */
printf("%d\n", helper(TWICE(1))); /* 103: the function and the constant it adds come from the included file */
int value = 5;
printf("%d %s %d\n", GLUE(val, ue), STR(hello world), GLUE(LIM, IT)); /* pasted, quoted, and pasted then expanded */
return 0;
}