Mercurial > pub > dyncall > dyncall
comparison test/suite_aggrs/mk-cases.lua @ 434:3d2c5d156d78
- test/suite_aggrs: support for nested structs, now
author | Tassilo Philipp |
---|---|
date | Sun, 23 Jan 2022 23:20:02 +0100 |
parents | 45662241d9cd |
children | a29baee68340 |
comparison
equal
deleted
inserted
replaced
433:45662241d9cd | 434:3d2c5d156d78 |
---|---|
1 require"math" | 1 require"math" |
2 local max = math.max | 2 local max = math.max |
3 local maxargs = 0 | 3 local maxargs = 0 |
4 | 4 |
5 local n_aggrs = 0 | 5 local aggrs = { } |
6 local seen_aggrs = { } | 6 local seen_aggrs = { } |
7 | 7 |
8 | |
9 function canon_type(t) | |
10 -- struct types have more than one char | |
11 if #t > 1 then | |
12 return 'struct '..t | |
13 end | |
14 return t | |
15 end | |
8 | 16 |
9 function trim(l) return l:gsub("^%s+",""):gsub("%s+$","") end | 17 function trim(l) return l:gsub("^%s+",""):gsub("%s+$","") end |
10 function mkcase(id,sig) | 18 function mkcase(id,sig) |
11 local sig = trim(sig) | 19 local sig = trim(sig) |
12 local h = { "/* ",id,":",sig," */ " } | 20 local h = { "/* ",id,":",sig," */ " } |
13 local t = { "" } | 21 local t = { "" } |
14 local pos = 0 | 22 local pos = 0 |
15 local n_nest = 0 | 23 local n_nest = 0 |
16 local aggr | 24 local aggr = { } |
17 local aggr_sig = '' | 25 local aggr_sig = { } |
26 aggr[0] = { } -- non-sequential [0] collects all non-aggr types | |
27 aggr_sig[0] = '' | |
18 for i = 1, #sig do | 28 for i = 1, #sig do |
19 local name = "a"..pos | 29 local name = "a"..pos |
20 local ch = sig:sub(i,i) | 30 local ch = sig:sub(i,i) |
21 | 31 |
22 aggr_sig = aggr_sig..ch | |
23 | |
24 -- aggregate nest level change? | 32 -- aggregate nest level change? |
25 if ch == '{' then | 33 if ch == '{' then |
26 n_nest = n_nest + 1 | 34 n_nest = n_nest + 1 |
27 aggr = { } | 35 aggr[n_nest] = { } |
28 aggr_sig = ch -- @@@ handle nesting | 36 aggr_sig[n_nest] = '' |
29 else | |
30 if ch == '}' then -- @@@ handle nesting, here, by reusing structs | |
31 n_nest = n_nest - 1 | |
32 -- aggr sig complete? | |
33 if n_nest == 0 then | |
34 -- register yet unseen aggregates, key is sig, val is body and name | |
35 if seen_aggrs[aggr_sig] == nil then | |
36 n_aggrs = n_aggrs + 1 | |
37 ch = 'A'..n_aggrs | |
38 seen_aggrs[aggr_sig] = { aggr, ch } | |
39 end | |
40 ch = seen_aggrs[aggr_sig][2] | |
41 end | |
42 else | |
43 if n_nest > 0 then | |
44 aggr[#aggr+1] = ch | |
45 aggr[#aggr+1] = 'm'..(#aggr >> 1) | |
46 end | |
47 end | |
48 end | 37 end |
49 | 38 |
39 aggr_sig[n_nest] = aggr_sig[n_nest]..ch | |
40 | |
41 if ch == '}' then | |
42 -- register yet unseen aggregates, key is sig, val is body and name | |
43 if seen_aggrs[aggr_sig[n_nest]] == nil then | |
44 aggrs[#aggrs+1] = aggr_sig[n_nest] | |
45 ch = 'A'..#aggrs | |
46 seen_aggrs[aggr_sig[n_nest]] = { aggr[n_nest], ch } | |
47 end | |
48 ch = seen_aggrs[aggr_sig[n_nest]][2] | |
49 | |
50 n_nest = n_nest - 1 | |
51 aggr_sig[n_nest] = aggr_sig[n_nest]..aggr_sig[n_nest+1] | |
52 end | |
53 | |
54 if ch ~= '{' and ch ~= '}' then | |
55 aggr[n_nest][#aggr[n_nest]+1] = canon_type(ch) | |
56 aggr[n_nest][#aggr[n_nest]+1] = 'm'..(#aggr[n_nest] >> 1) | |
57 end | |
58 | |
59 | |
50 if n_nest == 0 then | 60 if n_nest == 0 then |
61 h[#h+1] = canon_type(ch) | |
51 -- struct types (more than one char) need copying via a func | 62 -- struct types (more than one char) need copying via a func |
52 if #ch > 1 then | 63 if #ch > 1 then |
53 h[#h+1] = 'struct '..ch | |
54 t[#t+1] = 'f_cp'..ch..'(V_a['..pos.."],&"..name..");" | 64 t[#t+1] = 'f_cp'..ch..'(V_a['..pos.."],&"..name..");" |
55 else | 65 else |
56 h[#h+1] = ch | |
57 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" | 66 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" |
58 end | 67 end |
59 | 68 |
60 -- is return type or func arg? | 69 -- is return type or func arg? |
61 if pos == 0 then | 70 if pos == 0 then |
110 end | 119 end |
111 | 120 |
112 agg_sizes = {} | 121 agg_sizes = {} |
113 agg_sigs = {} | 122 agg_sigs = {} |
114 agg_names = {} | 123 agg_names = {} |
115 for k, v in pairs(seen_aggrs) do | 124 for a = 1, #aggrs do |
125 k = aggrs[a] | |
126 v = seen_aggrs[k] | |
116 st = 'struct '..v[2] | 127 st = 'struct '..v[2] |
117 | 128 |
118 agg_sizes[#agg_sizes + 1] = 'sizeof('..st..')' | 129 agg_sizes[#agg_sizes + 1] = 'sizeof('..st..')' |
119 agg_sigs [#agg_sigs + 1] = k | 130 agg_sigs [#agg_sigs + 1] = k |
120 agg_names[#agg_names + 1] = v[2] | 131 agg_names[#agg_names + 1] = v[2] |
121 | 132 |
122 -- struct def | 133 -- struct def |
123 io.write('/* '..k..' */\n') | 134 io.write('/* '..k..' */\n') |
124 io.write(st..'{ ') | 135 io.write(st..' { ') |
125 for i = 1, #v[1], 2 do | 136 for i = 1, #v[1], 2 do |
126 io.write(v[1][i]..' '..v[1][i+1]..'; ') | 137 io.write(v[1][i]..' '..v[1][i+1]..'; ') |
127 end | 138 end |
128 io.write("};\n") | 139 io.write("};\n") |
129 | 140 |
130 -- struct cp and cmp funcs | 141 -- struct cp and cmp funcs |
131 s = { | 142 s = { |
132 'void f_cp'..v[2]..'('..st..' *x, const '..st..' *y) { ', | 143 'void f_cp'..v[2]..'('..st..' *x, const '..st..' *y) { ', |
133 'int f_cmp'..v[2]..'(const '..st..' *x, const '..st..' *y) { return ' | 144 'int f_cmp'..v[2]..'(const '..st..' *x, const '..st..' *y) { return ' |
134 } | 145 } |
135 o = { '=', '==', '; ', ' && ' } | 146 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ' } |
136 for t = 1, 2 do | 147 for t = 1, 2 do |
137 io.write(s[t]) | 148 io.write(s[t]) |
138 b = {} | 149 b = {} |
139 for i = 1, #v[1], 2 do | 150 for i = 1, #v[1], 2 do |
140 b[#b+1] = 'x->'..v[1][i+1]..' '..o[t]..' y->'..v[1][i+1]; | 151 if string.match(v[1][i], '^struct') then |
152 b[#b+1] = o[t+2]..v[1][i]:sub(8)..'(&x->'..v[1][i+1]..', &y->'..v[1][i+1]..')'; | |
153 else | |
154 b[#b+1] = 'x->'..v[1][i+1]..' '..o[t]..' y->'..v[1][i+1]; | |
155 end | |
141 end | 156 end |
142 if #b == 0 then | 157 if #b == 0 then |
143 b[1] = '1' -- to handle empty structs | 158 b[1] = '1' -- to handle empty structs |
144 end | 159 end |
145 io.write(table.concat(b,o[t+2]).."; };\n") | 160 io.write(table.concat(b,o[t+4]).."; };\n") |
146 end | 161 end |
147 | 162 |
148 -- convenient dcnewstruct helper funcs | 163 -- convenient dcnewstruct helper funcs |
149 io.write('DCstruct* f_newdcst'..v[2]..'() { DCstruct* st = dcNewStruct('..(#v[1]>>1)..', sizeof('..st..'), 0, 1); ') | 164 io.write('static int nfields'..v[2]..' = '..(#v[1]>>1)..';\n') |
165 io.write('DCstruct* f_newdcst'..v[2]..'(DCstruct* parent) {\n\tDCstruct* st = parent;\n\tif(!st) st = dcNewStruct(nfields'..v[2]..', sizeof('..st..'), 0, 1);\n\t') | |
150 for i = 1, #v[1], 2 do | 166 for i = 1, #v[1], 2 do |
151 io.write("dcStructField(st, '"..v[1][i].."', offsetof("..st..', '..v[1][i+1]..'), 1); ') | 167 if string.match(v[1][i], '^struct') then |
168 io.write('dcSubStruct(st, nfields'..v[1][i]:sub(8)..', offsetof('..st..', '..v[1][i+1]..'), sizeof('..v[1][i]..'), 0, DC_TRUE, 1);\n\t') | |
169 io.write("f_newdcst"..v[1][i]:sub(8)..'(st);\n\t') | |
170 else | |
171 io.write("dcStructField(st, '"..v[1][i].."', offsetof("..st..', '..v[1][i+1]..'), 1);\n\t') | |
172 end | |
152 end | 173 end |
153 io.write(" dcCloseStruct(st); return st; };\n") | 174 io.write("dcCloseStruct(st);\n\treturn st;\n};\n") |
154 end | 175 end |
155 | 176 |
156 -- make table.concat work | 177 -- make table.concat work |
157 if #agg_names > 0 then | 178 if #agg_names > 0 then |
158 table.insert(agg_names, 1, '') | 179 table.insert(agg_names, 1, '') |