aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/table_generation_and_macros.txt
blob: ecaa959e0087005b417c0ba39e80e6c1f7132374 (plain)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

Table generation syntax and macros
----------------------------------

It would be nice to have some form of table generation syntax:

 type CharType = enum {
     Control
     Space
     Special
     Linebreak
     Digit
     Uppercase
     Lowercase
 }

 date byte[128] char_type = table(
     0x0..0x7   = Control
     0x8        = Control
     0x9        = Space
     0xA        = Linebreak
     0xB..0xC   = Control
     0xD        = Linebreak
     0xE..0x1F  = Control
     0x20       = Space
     0x21..0x2F = Special
     0x30..0x39 = Digit
     0x3A..0x40 = Special
     0x41..0x5A = Uppercase
     0x5B..0x60 = Special
     0x61..0x7A = Lowercase
     0x7B..0x7E = Special
     0x7F       = Control
 )

Alternatively, it could be generated through some kind of meta-compilation:

 defmacro make_table(...)
 {
     require_state(.Expression)
     # XXX how to declare that the lifetime of tok is only valid until the next, and possibly implicit, .next() call
     ref Token tok = tokens.next()
     tok.must_be(.Number)
     size arraysize = tok.as_size()
     # implcit length parameter
     ref [arraysize]?ref Expr elements = .new()
     tokens.skip(.Comma)
     for ref Token tok in tokens {
         tok.must_be(.Number)
         size from_num = tok.as_size()
         next tok
         if tok == .DotDot {
             next tok
             tok.must_be(.Number)
             size to_num = tok.as_size()
             next tok
             tok.must_be(.Equal)
             next tok
             # FIXME this does not support multi-token values (e.g. "10+value*2")
             tok.must_be_in_group(.Expression)
             for size i in .range_incl(from_num, to_num) {
                elements[i] = tok.clone()
             }
         } else {
             next tok
             tok.must_be(.Equal)
             next tok
             tok.must_be_in_group(.Expression)
             elements[from_num] = tok.clone()
         }
     }
     output(.LSquare)
     # TODO array index access in for loops?
     size i
     #for size i, ?ref Expr elem in elements { <-- perhaps like this?
     for ?ref Expr elem in elements {
        if elem == none {
            error_param(0, i)
            error("Element number {0} is missing")
        }
        output(elem)
        output(.Comma)
        i += 1
     }
     output(.RSquare)
 }

 date byte[128] char_type = callmacro make_table(128,
     0x0..0x7   = Control
     0x8        = Control
     0x9        = Space
     ...
 )

Restrict where macros can appears, and what they can generate?
- basically, macros should not be able to break out of expressions or definitions
- allow macros at:
    - top level
        - must return at top level
    - type
        - must generate full type, and nothing more
    - expression
        - must generate full (sub-)expression, and nothing more
    - statement
        - can generate any number of statements
        - last statement must be complete
        - must return in starting block
Block macros? To avoid having to pass every "inside/wrapped" token through the macro
  defmacro access_lock(..., {})
  callmacro access_lock(mylock, {
      work()
  })
Macros an ABIs:
- slightly problematic, because macros cannot change in a released version, so
  older versions need to be kept alongside the new ones