Mercurial > pub > dyncall > dyncall
comparison test/suite_aggrs/mk-cases.lua @ 462:653b65580cb4
suite_aggr:
- added arrays (inside of structs/unions, only, as only way to pass/return them by value)
- cleanups and pregen of source
author | Tassilo Philipp |
---|---|
date | Tue, 01 Feb 2022 21:44:18 +0100 |
parents | 236015fdf7a8 |
children | 0f3b6898078d |
comparison
equal
deleted
inserted
replaced
461:236015fdf7a8 | 462:653b65580cb4 |
---|---|
28 aggr_sig[0] = '' | 28 aggr_sig[0] = '' |
29 for i = 1, #sig do | 29 for i = 1, #sig do |
30 local name = "a"..pos | 30 local name = "a"..pos |
31 local ch = sig:sub(i,i) | 31 local ch = sig:sub(i,i) |
32 | 32 |
33 | |
33 -- aggregate nest level change? | 34 -- aggregate nest level change? |
34 if ch == '{' or ch == '<' then | 35 if ch == '{' or ch == '<' then |
35 n_nest = n_nest + 1 | 36 n_nest = n_nest + 1 |
36 aggr[n_nest] = { } | 37 aggr[n_nest] = { } |
37 aggr_sig[n_nest] = '' | 38 aggr_sig[n_nest] = '' |
38 end | 39 end |
39 | 40 |
40 aggr_sig[n_nest] = aggr_sig[n_nest]..ch | 41 aggr_sig[n_nest] = aggr_sig[n_nest]..ch |
41 | 42 |
42 if ch == '}' or ch == '>' then | 43 -- array? Just append to name of member var from prev loop |
43 -- register yet unseen aggregates, key is sig, val is body and name | 44 if ch:match('[%[%]0123456789]') ~= nil then |
44 if seen_aggrs[aggr_sig[n_nest]] == nil then | 45 aggr[n_nest][#aggr[n_nest]] = aggr[n_nest][#aggr[n_nest]]..ch |
45 aggrs[#aggrs+1] = aggr_sig[n_nest] | 46 else |
46 ch = ch..#aggrs | 47 |
47 seen_aggrs[aggr_sig[n_nest]] = { aggr[n_nest], ch } | 48 if ch == '}' or ch == '>' then |
48 end | 49 -- register yet unseen aggregates, key is sig, val is body and name |
49 ch = seen_aggrs[aggr_sig[n_nest]][2] | 50 if seen_aggrs[aggr_sig[n_nest]] == nil then |
50 | 51 aggrs[#aggrs+1] = aggr_sig[n_nest] |
51 n_nest = n_nest - 1 | 52 ch = ch..#aggrs |
52 aggr_sig[n_nest] = aggr_sig[n_nest]..aggr_sig[n_nest+1] | 53 seen_aggrs[aggr_sig[n_nest]] = { aggr[n_nest], ch } |
53 end | 54 end |
54 | 55 ch = seen_aggrs[aggr_sig[n_nest]][2] |
55 if ch ~= '{' and ch ~= '}' and ch ~= '<' and ch ~= '>' then | 56 |
56 aggr[n_nest][#aggr[n_nest]+1] = canon_type(ch) | 57 n_nest = n_nest - 1 |
57 aggr[n_nest][#aggr[n_nest]+1] = 'm'..(#aggr[n_nest] >> 1) | 58 aggr_sig[n_nest] = aggr_sig[n_nest]..aggr_sig[n_nest+1] |
58 end | 59 end |
59 | 60 |
60 | 61 if ch ~= '{' and ch ~= '}' and ch ~= '<' and ch ~= '>' then |
61 if n_nest == 0 then | 62 aggr[n_nest][#aggr[n_nest]+1] = canon_type(ch) |
62 h[#h+1] = canon_type(ch) | 63 aggr[n_nest][#aggr[n_nest]+1] = 'm'..(#aggr[n_nest] >> 1) |
63 -- aggregate types (more than one char) need copying via a func | 64 end |
64 if #h[#h] > 1 then | 65 |
65 t[#t+1] = 'f_cp'..h[#h]:sub(8)..'(V_a['..pos.."],&"..name..");" | 66 -- no nesting (= actual func args), generate case code |
66 else | 67 if n_nest == 0 then |
67 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" | 68 h[#h+1] = canon_type(ch) |
68 end | 69 -- aggregate types (more than one char) need copying via a func |
69 | 70 if #h[#h] > 1 then |
70 -- is return type or func arg? | 71 t[#t+1] = 'f_cp'..h[#h]:sub(8)..'(V_a['..pos.."],&"..name..");" |
71 if pos == 0 then | 72 else |
72 h[#h+1] = " f"..id.."(" | 73 t[#t+1] = "V_"..ch.."["..pos.."]="..name..";" |
73 h[#h+1] = '' | 74 end |
74 t[#t] = '' -- clear; aggr return type handled explicitly | 75 |
75 else | 76 -- is return type or func arg? |
76 h[#h+1] = ' '..name | 77 if pos == 0 then |
77 h[#h+1] = "," | 78 h[#h+1] = " f"..id.."(" |
78 end | 79 h[#h+1] = '' |
79 | 80 t[#t] = '' -- clear; aggr return type handled explicitly |
80 pos = pos + 1 | 81 else |
82 h[#h+1] = ' '..name | |
83 h[#h+1] = "," | |
84 end | |
85 | |
86 pos = pos + 1 | |
87 end | |
81 end | 88 end |
82 end | 89 end |
83 maxargs = max(maxargs, pos-1) | 90 maxargs = max(maxargs, pos-1) |
84 h[#h] = "){" | 91 h[#h] = "){" |
85 if #h[6] == 1 then | 92 if #h[6] == 1 then |
104 for k,v in pairs(sigs) do | 111 for k,v in pairs(sigs) do |
105 s[#s+1] = '\t"'..v..'",\n' | 112 s[#s+1] = '\t"'..v..'",\n' |
106 end | 113 end |
107 s[#s+1] = "};\n" | 114 s[#s+1] = "};\n" |
108 return table.concat(s,"") | 115 return table.concat(s,"") |
116 end | |
117 | |
118 function split_array_decl(s) | |
119 local name = s | |
120 local n = nil -- not an array | |
121 local array_i = s:find('%[') | |
122 if array_i ~= nil then | |
123 name = name:sub(1, array_i-1) | |
124 n = tonumber(s:sub(array_i):match('[0123456789]+')) | |
125 end | |
126 return { name, n } | |
109 end | 127 end |
110 | 128 |
111 function mkall() | 129 function mkall() |
112 local lineno = 0 | 130 local lineno = 0 |
113 local sigtab = { } | 131 local sigtab = { } |
121 | 139 |
122 agg_sizes = {} | 140 agg_sizes = {} |
123 agg_sigs = {} | 141 agg_sigs = {} |
124 agg_names = {} | 142 agg_names = {} |
125 for a = 1, #aggrs do | 143 for a = 1, #aggrs do |
126 k = aggrs[a] | 144 local k = aggrs[a] |
127 v = seen_aggrs[k] | 145 local v = seen_aggrs[k] |
128 st = canon_type(v[2]) | 146 local at = canon_type(v[2]) -- aggregate type |
129 | 147 local am = v[1] -- aggregate members |
130 agg_sizes[#agg_sizes + 1] = 'sizeof('..st..')' | 148 |
149 agg_sizes[#agg_sizes + 1] = 'sizeof('..at..')' | |
131 agg_sigs [#agg_sigs + 1] = k | 150 agg_sigs [#agg_sigs + 1] = k |
132 agg_names[#agg_names + 1] = st:sub(8) | 151 agg_names[#agg_names + 1] = at:sub(8) |
133 | 152 |
134 -- aggregate def | 153 -- aggregate def |
135 io.write('/* '..k..' */\n') | 154 io.write('/* '..k..' */\n') |
136 io.write(st..' { ') | 155 io.write(at..' { ') |
137 for i = 1, #v[1], 2 do | 156 for i = 1, #am, 2 do |
138 io.write(v[1][i]..' '..v[1][i+1]..'; ') | 157 io.write(am[i]..' '..am[i+1]..'; ') |
139 end | 158 end |
140 io.write("};\n") | 159 io.write("};\n") |
141 | 160 |
142 -- aggregate cp and cmp funcs | 161 -- aggregate cp and cmp funcs |
143 s = { | 162 s = { |
144 'void f_cp'..st:sub(8)..'('..st..' *x, const '..st..' *y) { ', | 163 'void f_cp'..at:sub(8)..'('..at..' *x, const '..at..' *y) { ', |
145 'int f_cmp'..st:sub(8)..'(const '..st..' *x, const '..st..' *y) { return ' | 164 'int f_cmp'..at:sub(8)..'(const '..at..' *x, const '..at..' *y) { return ' |
146 } | 165 } |
147 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' } | 166 o = { '=', '==', 'f_cp', 'f_cmp', '; ', ' && ', '', '1' } |
148 for t = 1, 2 do | 167 for t = 1, 2 do |
149 io.write(s[t]) | 168 io.write(s[t]) |
150 b = {} | 169 local b = {} |
151 for i = 1, #v[1], 2 do | 170 for i = 1, #am, 2 do |
152 if string.match(v[1][i], ' ') then -- aggregate canonical types contain at least one space | 171 local m = split_array_decl(am[i+1]) |
153 b[#b+1] = o[t+2]..v[1][i]:sub(8)..'(&x->'..v[1][i+1]..', &y->'..v[1][i+1]..')'; | 172 local fmt = '' |
154 else | 173 if m[2] ~= nil then -- need array suffixes? |
155 b[#b+1] = 'x->'..v[1][i+1]..' '..o[t]..' y->'..v[1][i+1]; | 174 fmt = '[%d]' |
156 end | 175 else |
176 m[2] = 1 | |
177 end | |
178 | |
179 for j = 1, m[2] do | |
180 name = m[1]..string.format(fmt, j-1) | |
181 if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space | |
182 b[#b+1] = o[t+2]..am[i]:sub(8)..'(&x->'..name..', &y->'..name..')' | |
183 else | |
184 b[#b+1] = 'x->'..name..' '..o[t]..' y->'..name | |
185 end | |
186 end | |
157 end | 187 end |
158 if #b == 0 then -- to handle empty aggregates | 188 if #b == 0 then -- to handle empty aggregates |
159 b[1] = o[t+6] | 189 b[1] = o[t+6] |
160 end | 190 end |
161 io.write(table.concat(b,o[t+4]).."; };\n") | 191 io.write(table.concat(b,o[t+4]).."; };\n") |
162 end | 192 end |
163 | 193 |
164 -- convenient dcnewstruct helper funcs | 194 -- convenient dcnewstruct helper funcs |
165 io.write('DCstruct* f_touchdcst'..st:sub(8)..'() {\n\tstatic DCstruct* st = NULL;\n\tif(!st) {\n\t\tst = dcNewStruct('..(#v[1]>>1)..', sizeof('..st..'), DC_TRUE);\n\t\t') | 195 io.write('DCstruct* f_touchdcst'..at:sub(8)..'() {\n\tstatic DCstruct* at = NULL;\n\tif(!at) {\n\t\tat = dcNewStruct('..(#am>>1)..', sizeof('..at..'), DC_TRUE);\n\t\t') |
166 for i = 1, #v[1], 2 do | 196 for i = 1, #am, 2 do |
167 if string.match(v[1][i], ' ') then -- aggregate canonical types contain at least one space | 197 local m = split_array_decl(am[i+1]) |
168 io.write('dcStructField(st, DC_SIGCHAR_STRUCT, offsetof('..st..', '..v[1][i+1]..'), 1, f_touchdcst'..v[1][i]:sub(8)..'());\n\t\t') | 198 if m[2] == nil then -- need array suffixes? |
169 else | 199 m[2] = 1 |
170 io.write("dcStructField(st, '"..v[1][i].."', offsetof("..st..', '..v[1][i+1]..'), 1);\n\t\t') | 200 end |
171 end | 201 if string.match(am[i], ' ') then -- aggregate canonical types contain at least one space |
172 end | 202 io.write('dcStructField(at, DC_SIGCHAR_STRUCT, offsetof('..at..', '..m[1]..'), '..m[2]..', f_touchdcst'..am[i]:sub(8)..'());\n\t\t') |
173 io.write("dcCloseStruct(st);\n\t}\n\treturn st;\n};\n") | 203 else |
204 io.write("dcStructField(at, '"..am[i].."', offsetof("..at..', '..m[1]..'), '..m[2]..');\n\t\t') | |
205 end | |
206 end | |
207 io.write("dcCloseStruct(at);\n\t}\n\treturn at;\n};\n") | |
174 end | 208 end |
175 | 209 |
176 -- make table.concat work | 210 -- make table.concat work |
177 if #agg_names > 0 then | 211 if #agg_names > 0 then |
178 table.insert(agg_names, 1, '') | 212 table.insert(agg_names, 1, '') |