• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 The Wuffs Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package builtin lists Wuffs' built-in concepts such as status codes.
16package builtin
17
18import (
19	t "github.com/google/wuffs/lang/token"
20)
21
22var FourCCs = [...][2]string{
23	{"ICCP", "International Color Consortium Profile"},
24	{"XMP ", "Extensible Metadata Platform"},
25}
26
27var Statuses = [...]string{
28	// Warnings.
29	`"@end of data"`,
30	`"@metadata reported"`,
31
32	// Suspensions.
33	`"$short read"`,
34	`"$short write"`,
35
36	// Errors.
37	`"#bad I/O position"`,
38	`"#bad argument (length too short)"`,
39	`"#bad argument"`,
40	`"#bad call sequence"`,
41	`"#bad receiver"`,
42	`"#bad restart"`,
43	`"#bad sizeof receiver"`,
44	`"#bad workbuf length"`,
45	`"#bad wuffs version"`,
46	`"#cannot return a suspension"`,
47	`"#disabled by previous error"`,
48	`"#initialize falsely claimed already zeroed"`,
49	`"#initialize not called"`,
50	`"#interleaved coroutine calls"`,
51	`"#not enough data"`,
52	`"#unsupported option"`,
53	`"#too much data"`,
54}
55
56// TODO: a collection of forbidden variable names like and, or, not, as, ref,
57// deref, false, true, in, out, this, u8, u16, etc?
58
59var Types = []string{
60	// TODO: i8, i16, i32, i64.
61	"u8",
62	"u16",
63	"u32",
64	"u64",
65
66	"empty_struct",
67	"bool",
68	"utility",
69
70	"range_ii_u32",
71	"range_ie_u32",
72	"range_ii_u64",
73	"range_ie_u64",
74	"rect_ie_u32",
75	"rect_ii_u32",
76
77	"io_reader",
78	"io_writer",
79	"status",
80
81	"frame_config",
82	"image_config",
83	"pixel_buffer",
84	"pixel_config",
85	"pixel_swizzler",
86
87	"decode_frame_options",
88}
89
90var Funcs = []string{
91	"u8.high_bits(n u32[..8]) u8",
92	"u8.low_bits(n u32[..8]) u8",
93	"u8.max(x u8) u8",
94	"u8.min(x u8) u8",
95
96	"u16.high_bits(n u32[..16]) u16",
97	"u16.low_bits(n u32[..16]) u16",
98	"u16.max(x u16) u16",
99	"u16.min(x u16) u16",
100
101	"u32.high_bits(n u32[..32]) u32",
102	"u32.low_bits(n u32[..32]) u32",
103	"u32.max(x u32) u32",
104	"u32.min(x u32) u32",
105
106	"u64.high_bits(n u32[..64]) u64",
107	"u64.low_bits(n u32[..64]) u64",
108	"u64.max(x u64) u64",
109	"u64.min(x u64) u64",
110
111	// ---- utility
112
113	"utility.make_range_ii_u32(min_incl u32, max_incl u32) range_ii_u32",
114	"utility.make_range_ie_u32(min_incl u32, max_excl u32) range_ie_u32",
115	"utility.make_range_ii_u64(min_incl u64, max_incl u64) range_ii_u64",
116	"utility.make_range_ie_u64(min_incl u64, max_excl u64) range_ie_u64",
117	"utility.make_rect_ii_u32(min_incl_x u32, min_incl_y u32, max_incl_x u32, max_incl_y u32) rect_ii_u32",
118	"utility.make_rect_ie_u32(min_incl_x u32, min_incl_y u32, max_excl_x u32, max_excl_y u32) rect_ie_u32",
119	"utility.null_io_reader() io_reader",
120	"utility.null_io_writer() io_writer",
121	"utility.null_slice_u8() slice u8",
122
123	// ---- ranges
124
125	"range_ie_u32.reset!()",
126	"range_ie_u32.get_min_incl() u32",
127	"range_ie_u32.get_max_excl() u32",
128	"range_ie_u32.intersect(r range_ie_u32) range_ie_u32",
129	"range_ie_u32.unite(r range_ie_u32) range_ie_u32",
130
131	"range_ii_u32.reset!()",
132	"range_ii_u32.get_min_incl() u32",
133	"range_ii_u32.get_max_incl() u32",
134	"range_ii_u32.intersect(r range_ii_u32) range_ii_u32",
135	"range_ii_u32.unite(r range_ii_u32) range_ii_u32",
136
137	"range_ie_u64.reset!()",
138	"range_ie_u64.get_min_incl() u64",
139	"range_ie_u64.get_max_excl() u64",
140	"range_ie_u64.intersect(r range_ie_u64) range_ie_u64",
141	"range_ie_u64.unite(r range_ie_u64) range_ie_u64",
142
143	"range_ii_u64.reset!()",
144	"range_ii_u64.get_min_incl() u64",
145	"range_ii_u64.get_max_incl() u64",
146	"range_ii_u64.intersect(r range_ii_u64) range_ii_u64",
147	"range_ii_u64.unite(r range_ii_u64) range_ii_u64",
148
149	// ---- io_reader
150
151	"io_reader.can_undo_byte() bool",
152	"io_reader.undo_byte!()",
153
154	"io_reader.read_u8?() u8",
155
156	"io_reader.read_u16be?() u16",
157	"io_reader.read_u16le?() u16",
158
159	"io_reader.read_u8_as_u32?() u32[..0xFF]",
160	"io_reader.read_u16be_as_u32?() u32[..0xFFFF]",
161	"io_reader.read_u16le_as_u32?() u32[..0xFFFF]",
162	"io_reader.read_u24be_as_u32?() u32[..0xFFFFFF]",
163	"io_reader.read_u24le_as_u32?() u32[..0xFFFFFF]",
164	"io_reader.read_u32be?() u32",
165	"io_reader.read_u32le?() u32",
166
167	"io_reader.read_u8_as_u64?() u64[..0xFF]",
168	"io_reader.read_u16be_as_u64?() u64[..0xFFFF]",
169	"io_reader.read_u16le_as_u64?() u64[..0xFFFF]",
170	"io_reader.read_u24be_as_u64?() u64[..0xFFFFFF]",
171	"io_reader.read_u24le_as_u64?() u64[..0xFFFFFF]",
172	"io_reader.read_u32be_as_u64?() u64[..0xFFFFFFFF]",
173	"io_reader.read_u32le_as_u64?() u64[..0xFFFFFFFF]",
174	"io_reader.read_u40be_as_u64?() u64[..0xFFFFFFFFFF]",
175	"io_reader.read_u40le_as_u64?() u64[..0xFFFFFFFFFF]",
176	"io_reader.read_u48be_as_u64?() u64[..0xFFFFFFFFFFFF]",
177	"io_reader.read_u48le_as_u64?() u64[..0xFFFFFFFFFFFF]",
178	"io_reader.read_u56be_as_u64?() u64[..0xFFFFFFFFFFFFFF]",
179	"io_reader.read_u56le_as_u64?() u64[..0xFFFFFFFFFFFFFF]",
180	"io_reader.read_u64be?() u64",
181	"io_reader.read_u64le?() u64",
182
183	// TODO: these should have an explicit pre-condition "available() >= N".
184	// For now, that's implicitly checked (i.e. hard coded).
185	//
186	// The io_reader has peek_etc methods and skip_fast, not read_etc_fast,
187	// because we sometimes advance the pointer by less than what's read. See
188	// https://fgiesen.wordpress.com/2018/02/20/reading-bits-in-far-too-many-ways-part-2/
189
190	"io_reader.peek_u8() u8",
191
192	"io_reader.peek_u16be() u16",
193	"io_reader.peek_u16le() u16",
194
195	"io_reader.peek_u8_as_u32() u32[..0xFF]",
196	"io_reader.peek_u16be_as_u32() u32[..0xFFFF]",
197	"io_reader.peek_u16le_as_u32() u32[..0xFFFF]",
198	"io_reader.peek_u24be_as_u32() u32[..0xFFFFFF]",
199	"io_reader.peek_u24le_as_u32() u32[..0xFFFFFF]",
200	"io_reader.peek_u32be() u32",
201	"io_reader.peek_u32le() u32",
202
203	"io_reader.peek_u8_as_u64() u64[..0xFF]",
204	"io_reader.peek_u16be_as_u64() u64[..0xFFFF]",
205	"io_reader.peek_u16le_as_u64() u64[..0xFFFF]",
206	"io_reader.peek_u24be_as_u64() u64[..0xFFFFFF]",
207	"io_reader.peek_u24le_as_u64() u64[..0xFFFFFF]",
208	"io_reader.peek_u32be_as_u64() u64[..0xFFFFFFFF]",
209	"io_reader.peek_u32le_as_u64() u64[..0xFFFFFFFF]",
210	"io_reader.peek_u40be_as_u64() u64[..0xFFFFFFFFFF]",
211	"io_reader.peek_u40le_as_u64() u64[..0xFFFFFFFFFF]",
212	"io_reader.peek_u48be_as_u64() u64[..0xFFFFFFFFFFFF]",
213	"io_reader.peek_u48le_as_u64() u64[..0xFFFFFFFFFFFF]",
214	"io_reader.peek_u56be_as_u64() u64[..0xFFFFFFFFFFFFFF]",
215	"io_reader.peek_u56le_as_u64() u64[..0xFFFFFFFFFFFFFF]",
216	"io_reader.peek_u64be() u64",
217	"io_reader.peek_u64le() u64",
218
219	"io_reader.available() u64",
220	"io_reader.count_since(mark u64) u64",
221	"io_reader.mark() u64",
222	"io_reader.position() u64",
223	"io_reader.since(mark u64) slice u8",
224	"io_reader.take!(n u64) slice u8",
225
226	"io_reader.skip?(n u32)",
227
228	// TODO: this should have explicit pre-conditions "actual <= worst_case"
229	// and "worst_case <= available()". As an implementation restriction, we
230	// also require that worst_case has a constant value. For now, that's all
231	// implicitly checked (i.e. hard coded).
232	"io_reader.skip_fast!(actual u32, worst_case u32)",
233
234	// ---- io_writer
235
236	"io_writer.write_u8?(x u8)",
237	"io_writer.write_u16be?(x u16)",
238	"io_writer.write_u16le?(x u16)",
239	"io_writer.write_u24be?(x u32[..0xFFFFFF])",
240	"io_writer.write_u24le?(x u32[..0xFFFFFF])",
241	"io_writer.write_u32be?(x u32)",
242	"io_writer.write_u32le?(x u32)",
243	"io_writer.write_u40be?(x u64[..0xFFFFFFFFFF])",
244	"io_writer.write_u40le?(x u64[..0xFFFFFFFFFF])",
245	"io_writer.write_u48be?(x u64[..0xFFFFFFFFFFFF])",
246	"io_writer.write_u48le?(x u64[..0xFFFFFFFFFFFF])",
247	"io_writer.write_u56be?(x u64[..0xFFFFFFFFFFFFFF])",
248	"io_writer.write_u56le?(x u64[..0xFFFFFFFFFFFFFF])",
249	"io_writer.write_u64be?(x u64)",
250	"io_writer.write_u64le?(x u64)",
251
252	// TODO: these should have an explicit pre-condition "available() >= N".
253	// For now, that's implicitly checked (i.e. hard coded).
254	//
255	// The io_writer has write_fast_etc methods, not poke_etc and skip_fast,
256	// because skip_fast could leave uninitialized bytes in the io_buffer.
257	"io_writer.write_fast_u8!(x u8)",
258	"io_writer.write_fast_u16be!(x u16)",
259	"io_writer.write_fast_u16le!(x u16)",
260	"io_writer.write_fast_u24be!(x u32[..0xFFFFFF])",
261	"io_writer.write_fast_u24le!(x u32[..0xFFFFFF])",
262	"io_writer.write_fast_u32be!(x u32)",
263	"io_writer.write_fast_u32le!(x u32)",
264	"io_writer.write_fast_u40be!(x u64[..0xFFFFFFFFFF])",
265	"io_writer.write_fast_u40le!(x u64[..0xFFFFFFFFFF])",
266	"io_writer.write_fast_u48be!(x u64[..0xFFFFFFFFFFFF])",
267	"io_writer.write_fast_u48le!(x u64[..0xFFFFFFFFFFFF])",
268	"io_writer.write_fast_u56be!(x u64[..0xFFFFFFFFFFFFFF])",
269	"io_writer.write_fast_u56le!(x u64[..0xFFFFFFFFFFFFFF])",
270	"io_writer.write_fast_u64be!(x u64)",
271	"io_writer.write_fast_u64le!(x u64)",
272
273	"io_writer.available() u64",
274	"io_writer.count_since(mark u64) u64",
275	"io_writer.history_available() u64",
276	"io_writer.mark() u64",
277	"io_writer.position() u64",
278	"io_writer.since(mark u64) slice u8",
279
280	"io_writer.copy_from_slice!(s slice u8) u64",
281	"io_writer.copy_n_from_history!(n u32, distance u32) u32",
282	"io_writer.copy_n_from_reader!(n u32, r io_reader) u32",
283	"io_writer.copy_n_from_slice!(n u32, s slice u8) u32",
284
285	// TODO: this should have explicit pre-conditions:
286	//  - n <= this.available()
287	//  - distance > 0
288	//  - distance <= this.since_mark().length()
289	// For now, that's all implicitly checked (i.e. hard coded).
290	"io_writer.copy_n_from_history_fast!(n u32, distance u32) u32",
291
292	// ---- status
293
294	// TODO: should we add is_complete?
295	"status.is_error() bool",
296	"status.is_ok() bool",
297	"status.is_suspension() bool",
298	"status.is_warning() bool",
299
300	// ---- frame_config
301	// Duration's upper bound is the maximum possible i64 value.
302
303	"frame_config.blend() u8",
304	"frame_config.disposal() u8",
305	"frame_config.duration() u64[..0x7FFFFFFFFFFFFFFF]",
306	"frame_config.index() u64",
307	"frame_config.io_position() u64",
308
309	"frame_config.update!(bounds rect_ie_u32, duration u64[..0x7FFFFFFFFFFFFFFF], " +
310		"index u64, io_position u64, blend u8, disposal u8, background_color u32)",
311
312	// ---- image_config
313
314	"image_config.set!(pixfmt u32, pixsub u32, width u32, height u32, " +
315		"first_frame_io_position u64, first_frame_is_opaque bool)",
316
317	// ---- pixel_buffer
318
319	"pixel_buffer.palette() slice u8",
320	"pixel_buffer.pixel_format() u32",
321	"pixel_buffer.plane(p u32[..3]) table u8",
322
323	// ---- pixel_swizzler
324
325	"pixel_swizzler.prepare!(dst_pixfmt u32, dst_palette slice u8, src_pixfmt u32, src_palette slice u8) status",
326	"pixel_swizzler.swizzle_interleaved!(dst slice u8, dst_palette slice u8, src slice u8) u64",
327}
328
329// The "T1" and "T2" types here are placeholders for generic "slice T" or
330// "table T" types. After tokenizing (but before parsing) these XxxFunc strings
331// (e.g. in the lang/check package), replace "T1" and "T2" with "†" or "‡"
332// daggers, to avoid collision with a user-defined "T1" or "T2" type.
333
334const (
335	GenericOldName1 = t.IDT1
336	GenericOldName2 = t.IDT2
337	GenericNewName1 = t.IDDagger1
338	GenericNewName2 = t.IDDagger2
339)
340
341var SliceFuncs = []string{
342	"T1.copy_from_slice!(s T1) u64",
343	"T1.length() u64",
344	"T1.prefix(up_to u64) T1",
345	"T1.suffix(up_to u64) T1",
346}
347
348var TableFuncs = []string{
349	"T2.height() u64",
350	"T2.stride() u64",
351	"T2.width() u64",
352
353	"T2.row(y u32) T1",
354}
355