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, '')