The YSLib project - main repository
Revisión | f6395e6386ebc5ca83aafc209ae33413f5de959d (tree) |
---|---|
Tiempo | 2022-08-15 07:48:30 |
Autor | FrankHB <frankhb1989@gmai...> |
Commiter | FrankHB |
更新主分支版本: build 952 rev 10 。
@@ -0,0 +1,667 @@ | ||
1 | +/***************************************************************************/ | |
2 | +/* */ | |
3 | +/* ftmodapi.h */ | |
4 | +/* */ | |
5 | +/* FreeType modules public interface (specification). */ | |
6 | +/* */ | |
7 | +/* Copyright 1996-2016 by */ | |
8 | +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |
9 | +/* */ | |
10 | +/* This file is part of the FreeType project, and may only be used, */ | |
11 | +/* modified, and distributed under the terms of the FreeType project */ | |
12 | +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | |
13 | +/* this file you indicate that you have read the license and */ | |
14 | +/* understand and accept it fully. */ | |
15 | +/* */ | |
16 | +/***************************************************************************/ | |
17 | + | |
18 | + | |
19 | +#ifndef FTMODAPI_H_ | |
20 | +#define FTMODAPI_H_ | |
21 | + | |
22 | + | |
23 | +#include <ft2build.h> | |
24 | +#include FT_FREETYPE_H | |
25 | + | |
26 | +#ifdef FREETYPE_H | |
27 | +#error "freetype.h of FreeType 1 has been loaded!" | |
28 | +#error "Please fix the directory search order for header files" | |
29 | +#error "so that freetype.h of FreeType 2 is found first." | |
30 | +#endif | |
31 | + | |
32 | + | |
33 | +FT_BEGIN_HEADER | |
34 | + | |
35 | + | |
36 | + /*************************************************************************/ | |
37 | + /* */ | |
38 | + /* <Section> */ | |
39 | + /* module_management */ | |
40 | + /* */ | |
41 | + /* <Title> */ | |
42 | + /* Module Management */ | |
43 | + /* */ | |
44 | + /* <Abstract> */ | |
45 | + /* How to add, upgrade, remove, and control modules from FreeType. */ | |
46 | + /* */ | |
47 | + /* <Description> */ | |
48 | + /* The definitions below are used to manage modules within FreeType. */ | |
49 | + /* Modules can be added, upgraded, and removed at runtime. */ | |
50 | + /* Additionally, some module properties can be controlled also. */ | |
51 | + /* */ | |
52 | + /* Here is a list of possible values of the `module_name' field in */ | |
53 | + /* the @FT_Module_Class structure. */ | |
54 | + /* */ | |
55 | + /* { */ | |
56 | + /* autofitter */ | |
57 | + /* bdf */ | |
58 | + /* cff */ | |
59 | + /* gxvalid */ | |
60 | + /* otvalid */ | |
61 | + /* pcf */ | |
62 | + /* pfr */ | |
63 | + /* psaux */ | |
64 | + /* pshinter */ | |
65 | + /* psnames */ | |
66 | + /* raster1 */ | |
67 | + /* sfnt */ | |
68 | + /* smooth, smooth-lcd, smooth-lcdv */ | |
69 | + /* truetype */ | |
70 | + /* type1 */ | |
71 | + /* type42 */ | |
72 | + /* t1cid */ | |
73 | + /* winfonts */ | |
74 | + /* } */ | |
75 | + /* */ | |
76 | + /* Note that the FreeType Cache sub-system is not a FreeType module. */ | |
77 | + /* */ | |
78 | + /* <Order> */ | |
79 | + /* FT_Module */ | |
80 | + /* FT_Module_Constructor */ | |
81 | + /* FT_Module_Destructor */ | |
82 | + /* FT_Module_Requester */ | |
83 | + /* FT_Module_Class */ | |
84 | + /* */ | |
85 | + /* FT_Add_Module */ | |
86 | + /* FT_Get_Module */ | |
87 | + /* FT_Remove_Module */ | |
88 | + /* FT_Add_Default_Modules */ | |
89 | + /* */ | |
90 | + /* FT_Property_Set */ | |
91 | + /* FT_Property_Get */ | |
92 | + /* */ | |
93 | + /* FT_New_Library */ | |
94 | + /* FT_Done_Library */ | |
95 | + /* FT_Reference_Library */ | |
96 | + /* */ | |
97 | + /* FT_Renderer */ | |
98 | + /* FT_Renderer_Class */ | |
99 | + /* */ | |
100 | + /* FT_Get_Renderer */ | |
101 | + /* FT_Set_Renderer */ | |
102 | + /* */ | |
103 | + /* FT_Set_Debug_Hook */ | |
104 | + /* */ | |
105 | + /*************************************************************************/ | |
106 | + | |
107 | + | |
108 | + /* module bit flags */ | |
109 | +#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ | |
110 | +#define FT_MODULE_RENDERER 2 /* this module is a renderer */ | |
111 | +#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ | |
112 | +#define FT_MODULE_STYLER 8 /* this module is a styler */ | |
113 | + | |
114 | +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ | |
115 | + /* scalable fonts */ | |
116 | +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ | |
117 | + /* support vector outlines */ | |
118 | +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ | |
119 | + /* own hinter */ | |
120 | +#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800 /* the driver's hinter */ | |
121 | + /* produces LIGHT hints */ | |
122 | + | |
123 | + | |
124 | + /* deprecated values */ | |
125 | +#define ft_module_font_driver FT_MODULE_FONT_DRIVER | |
126 | +#define ft_module_renderer FT_MODULE_RENDERER | |
127 | +#define ft_module_hinter FT_MODULE_HINTER | |
128 | +#define ft_module_styler FT_MODULE_STYLER | |
129 | + | |
130 | +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE | |
131 | +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES | |
132 | +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER | |
133 | +#define ft_module_driver_hints_lightly FT_MODULE_DRIVER_HINTS_LIGHTLY | |
134 | + | |
135 | + | |
136 | + typedef FT_Pointer FT_Module_Interface; | |
137 | + | |
138 | + | |
139 | + /*************************************************************************/ | |
140 | + /* */ | |
141 | + /* <FuncType> */ | |
142 | + /* FT_Module_Constructor */ | |
143 | + /* */ | |
144 | + /* <Description> */ | |
145 | + /* A function used to initialize (not create) a new module object. */ | |
146 | + /* */ | |
147 | + /* <Input> */ | |
148 | + /* module :: The module to initialize. */ | |
149 | + /* */ | |
150 | + typedef FT_Error | |
151 | + (*FT_Module_Constructor)( FT_Module module ); | |
152 | + | |
153 | + | |
154 | + /*************************************************************************/ | |
155 | + /* */ | |
156 | + /* <FuncType> */ | |
157 | + /* FT_Module_Destructor */ | |
158 | + /* */ | |
159 | + /* <Description> */ | |
160 | + /* A function used to finalize (not destroy) a given module object. */ | |
161 | + /* */ | |
162 | + /* <Input> */ | |
163 | + /* module :: The module to finalize. */ | |
164 | + /* */ | |
165 | + typedef void | |
166 | + (*FT_Module_Destructor)( FT_Module module ); | |
167 | + | |
168 | + | |
169 | + /*************************************************************************/ | |
170 | + /* */ | |
171 | + /* <FuncType> */ | |
172 | + /* FT_Module_Requester */ | |
173 | + /* */ | |
174 | + /* <Description> */ | |
175 | + /* A function used to query a given module for a specific interface. */ | |
176 | + /* */ | |
177 | + /* <Input> */ | |
178 | + /* module :: The module to be searched. */ | |
179 | + /* */ | |
180 | + /* name :: The name of the interface in the module. */ | |
181 | + /* */ | |
182 | + typedef FT_Module_Interface | |
183 | + (*FT_Module_Requester)( FT_Module module, | |
184 | + const char* name ); | |
185 | + | |
186 | + | |
187 | + /*************************************************************************/ | |
188 | + /* */ | |
189 | + /* <Struct> */ | |
190 | + /* FT_Module_Class */ | |
191 | + /* */ | |
192 | + /* <Description> */ | |
193 | + /* The module class descriptor. */ | |
194 | + /* */ | |
195 | + /* <Fields> */ | |
196 | + /* module_flags :: Bit flags describing the module. */ | |
197 | + /* */ | |
198 | + /* module_size :: The size of one module object/instance in */ | |
199 | + /* bytes. */ | |
200 | + /* */ | |
201 | + /* module_name :: The name of the module. */ | |
202 | + /* */ | |
203 | + /* module_version :: The version, as a 16.16 fixed number */ | |
204 | + /* (major.minor). */ | |
205 | + /* */ | |
206 | + /* module_requires :: The version of FreeType this module requires, */ | |
207 | + /* as a 16.16 fixed number (major.minor). Starts */ | |
208 | + /* at version 2.0, i.e., 0x20000. */ | |
209 | + /* */ | |
210 | + /* module_init :: The initializing function. */ | |
211 | + /* */ | |
212 | + /* module_done :: The finalizing function. */ | |
213 | + /* */ | |
214 | + /* get_interface :: The interface requesting function. */ | |
215 | + /* */ | |
216 | + typedef struct FT_Module_Class_ | |
217 | + { | |
218 | + FT_ULong module_flags; | |
219 | + FT_Long module_size; | |
220 | + const FT_String* module_name; | |
221 | + FT_Fixed module_version; | |
222 | + FT_Fixed module_requires; | |
223 | + | |
224 | + const void* module_interface; | |
225 | + | |
226 | + FT_Module_Constructor module_init; | |
227 | + FT_Module_Destructor module_done; | |
228 | + FT_Module_Requester get_interface; | |
229 | + | |
230 | + } FT_Module_Class; | |
231 | + | |
232 | + | |
233 | + /*************************************************************************/ | |
234 | + /* */ | |
235 | + /* <Function> */ | |
236 | + /* FT_Add_Module */ | |
237 | + /* */ | |
238 | + /* <Description> */ | |
239 | + /* Add a new module to a given library instance. */ | |
240 | + /* */ | |
241 | + /* <InOut> */ | |
242 | + /* library :: A handle to the library object. */ | |
243 | + /* */ | |
244 | + /* <Input> */ | |
245 | + /* clazz :: A pointer to class descriptor for the module. */ | |
246 | + /* */ | |
247 | + /* <Return> */ | |
248 | + /* FreeType error code. 0~means success. */ | |
249 | + /* */ | |
250 | + /* <Note> */ | |
251 | + /* An error will be returned if a module already exists by that name, */ | |
252 | + /* or if the module requires a version of FreeType that is too great. */ | |
253 | + /* */ | |
254 | + FT_EXPORT( FT_Error ) | |
255 | + FT_Add_Module( FT_Library library, | |
256 | + const FT_Module_Class* clazz ); | |
257 | + | |
258 | + | |
259 | + /*************************************************************************/ | |
260 | + /* */ | |
261 | + /* <Function> */ | |
262 | + /* FT_Get_Module */ | |
263 | + /* */ | |
264 | + /* <Description> */ | |
265 | + /* Find a module by its name. */ | |
266 | + /* */ | |
267 | + /* <Input> */ | |
268 | + /* library :: A handle to the library object. */ | |
269 | + /* */ | |
270 | + /* module_name :: The module's name (as an ASCII string). */ | |
271 | + /* */ | |
272 | + /* <Return> */ | |
273 | + /* A module handle. 0~if none was found. */ | |
274 | + /* */ | |
275 | + /* <Note> */ | |
276 | + /* FreeType's internal modules aren't documented very well, and you */ | |
277 | + /* should look up the source code for details. */ | |
278 | + /* */ | |
279 | + FT_EXPORT( FT_Module ) | |
280 | + FT_Get_Module( FT_Library library, | |
281 | + const char* module_name ); | |
282 | + | |
283 | + | |
284 | + /*************************************************************************/ | |
285 | + /* */ | |
286 | + /* <Function> */ | |
287 | + /* FT_Remove_Module */ | |
288 | + /* */ | |
289 | + /* <Description> */ | |
290 | + /* Remove a given module from a library instance. */ | |
291 | + /* */ | |
292 | + /* <InOut> */ | |
293 | + /* library :: A handle to a library object. */ | |
294 | + /* */ | |
295 | + /* <Input> */ | |
296 | + /* module :: A handle to a module object. */ | |
297 | + /* */ | |
298 | + /* <Return> */ | |
299 | + /* FreeType error code. 0~means success. */ | |
300 | + /* */ | |
301 | + /* <Note> */ | |
302 | + /* The module object is destroyed by the function in case of success. */ | |
303 | + /* */ | |
304 | + FT_EXPORT( FT_Error ) | |
305 | + FT_Remove_Module( FT_Library library, | |
306 | + FT_Module module ); | |
307 | + | |
308 | + | |
309 | + /********************************************************************** | |
310 | + * | |
311 | + * @function: | |
312 | + * FT_Property_Set | |
313 | + * | |
314 | + * @description: | |
315 | + * Set a property for a given module. | |
316 | + * | |
317 | + * @input: | |
318 | + * library :: | |
319 | + * A handle to the library the module is part of. | |
320 | + * | |
321 | + * module_name :: | |
322 | + * The module name. | |
323 | + * | |
324 | + * property_name :: | |
325 | + * The property name. Properties are described in the `Synopsis' | |
326 | + * subsection of the module's documentation. | |
327 | + * | |
328 | + * Note that only a few modules have properties. | |
329 | + * | |
330 | + * value :: | |
331 | + * A generic pointer to a variable or structure that gives the new | |
332 | + * value of the property. The exact definition of `value' is | |
333 | + * dependent on the property; see the `Synopsis' subsection of the | |
334 | + * module's documentation. | |
335 | + * | |
336 | + * @return: | |
337 | + * FreeType error code. 0~means success. | |
338 | + * | |
339 | + * @note: | |
340 | + * If `module_name' isn't a valid module name, or `property_name' | |
341 | + * doesn't specify a valid property, or if `value' doesn't represent a | |
342 | + * valid value for the given property, an error is returned. | |
343 | + * | |
344 | + * The following example sets property `bar' (a simple integer) in | |
345 | + * module `foo' to value~1. | |
346 | + * | |
347 | + * { | |
348 | + * FT_UInt bar; | |
349 | + * | |
350 | + * | |
351 | + * bar = 1; | |
352 | + * FT_Property_Set( library, "foo", "bar", &bar ); | |
353 | + * } | |
354 | + * | |
355 | + * Note that the FreeType Cache sub-system doesn't recognize module | |
356 | + * property changes. To avoid glyph lookup confusion within the cache | |
357 | + * you should call @FTC_Manager_Reset to completely flush the cache if | |
358 | + * a module property gets changed after @FTC_Manager_New has been | |
359 | + * called. | |
360 | + * | |
361 | + * It is not possible to set properties of the FreeType Cache | |
362 | + * sub-system itself with FT_Property_Set; use @FTC_Property_Set | |
363 | + * instead. | |
364 | + * | |
365 | + * @since: | |
366 | + * 2.4.11 | |
367 | + * | |
368 | + */ | |
369 | + FT_EXPORT( FT_Error ) | |
370 | + FT_Property_Set( FT_Library library, | |
371 | + const FT_String* module_name, | |
372 | + const FT_String* property_name, | |
373 | + const void* value ); | |
374 | + | |
375 | + | |
376 | + /********************************************************************** | |
377 | + * | |
378 | + * @function: | |
379 | + * FT_Property_Get | |
380 | + * | |
381 | + * @description: | |
382 | + * Get a module's property value. | |
383 | + * | |
384 | + * @input: | |
385 | + * library :: | |
386 | + * A handle to the library the module is part of. | |
387 | + * | |
388 | + * module_name :: | |
389 | + * The module name. | |
390 | + * | |
391 | + * property_name :: | |
392 | + * The property name. Properties are described in the `Synopsis' | |
393 | + * subsection of the module's documentation. | |
394 | + * | |
395 | + * @inout: | |
396 | + * value :: | |
397 | + * A generic pointer to a variable or structure that gives the | |
398 | + * value of the property. The exact definition of `value' is | |
399 | + * dependent on the property; see the `Synopsis' subsection of the | |
400 | + * module's documentation. | |
401 | + * | |
402 | + * @return: | |
403 | + * FreeType error code. 0~means success. | |
404 | + * | |
405 | + * @note: | |
406 | + * If `module_name' isn't a valid module name, or `property_name' | |
407 | + * doesn't specify a valid property, or if `value' doesn't represent a | |
408 | + * valid value for the given property, an error is returned. | |
409 | + * | |
410 | + * The following example gets property `baz' (a range) in module `foo'. | |
411 | + * | |
412 | + * { | |
413 | + * typedef range_ | |
414 | + * { | |
415 | + * FT_Int32 min; | |
416 | + * FT_Int32 max; | |
417 | + * | |
418 | + * } range; | |
419 | + * | |
420 | + * range baz; | |
421 | + * | |
422 | + * | |
423 | + * FT_Property_Get( library, "foo", "baz", &baz ); | |
424 | + * } | |
425 | + * | |
426 | + * It is not possible to retrieve properties of the FreeType Cache | |
427 | + * sub-system with FT_Property_Get; use @FTC_Property_Get instead. | |
428 | + * | |
429 | + * @since: | |
430 | + * 2.4.11 | |
431 | + * | |
432 | + */ | |
433 | + FT_EXPORT( FT_Error ) | |
434 | + FT_Property_Get( FT_Library library, | |
435 | + const FT_String* module_name, | |
436 | + const FT_String* property_name, | |
437 | + void* value ); | |
438 | + | |
439 | + | |
440 | + /*************************************************************************/ | |
441 | + /* */ | |
442 | + /* <Function> */ | |
443 | + /* FT_Reference_Library */ | |
444 | + /* */ | |
445 | + /* <Description> */ | |
446 | + /* A counter gets initialized to~1 at the time an @FT_Library */ | |
447 | + /* structure is created. This function increments the counter. */ | |
448 | + /* @FT_Done_Library then only destroys a library if the counter is~1, */ | |
449 | + /* otherwise it simply decrements the counter. */ | |
450 | + /* */ | |
451 | + /* This function helps in managing life-cycles of structures that */ | |
452 | + /* reference @FT_Library objects. */ | |
453 | + /* */ | |
454 | + /* <Input> */ | |
455 | + /* library :: A handle to a target library object. */ | |
456 | + /* */ | |
457 | + /* <Return> */ | |
458 | + /* FreeType error code. 0~means success. */ | |
459 | + /* */ | |
460 | + /* <Since> */ | |
461 | + /* 2.4.2 */ | |
462 | + /* */ | |
463 | + FT_EXPORT( FT_Error ) | |
464 | + FT_Reference_Library( FT_Library library ); | |
465 | + | |
466 | + | |
467 | + /*************************************************************************/ | |
468 | + /* */ | |
469 | + /* <Function> */ | |
470 | + /* FT_New_Library */ | |
471 | + /* */ | |
472 | + /* <Description> */ | |
473 | + /* This function is used to create a new FreeType library instance */ | |
474 | + /* from a given memory object. It is thus possible to use libraries */ | |
475 | + /* with distinct memory allocators within the same program. Note, */ | |
476 | + /* however, that the used @FT_Memory structure is expected to remain */ | |
477 | + /* valid for the life of the @FT_Library object. */ | |
478 | + /* */ | |
479 | + /* Normally, you would call this function (followed by a call to */ | |
480 | + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ | |
481 | + /* instead of @FT_Init_FreeType to initialize the FreeType library. */ | |
482 | + /* */ | |
483 | + /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ | |
484 | + /* library instance. */ | |
485 | + /* */ | |
486 | + /* <Input> */ | |
487 | + /* memory :: A handle to the original memory object. */ | |
488 | + /* */ | |
489 | + /* <Output> */ | |
490 | + /* alibrary :: A pointer to handle of a new library object. */ | |
491 | + /* */ | |
492 | + /* <Return> */ | |
493 | + /* FreeType error code. 0~means success. */ | |
494 | + /* */ | |
495 | + /* <Note> */ | |
496 | + /* See the discussion of reference counters in the description of */ | |
497 | + /* @FT_Reference_Library. */ | |
498 | + /* */ | |
499 | + FT_EXPORT( FT_Error ) | |
500 | + FT_New_Library( FT_Memory memory, | |
501 | + FT_Library *alibrary ); | |
502 | + | |
503 | + | |
504 | + /*************************************************************************/ | |
505 | + /* */ | |
506 | + /* <Function> */ | |
507 | + /* FT_Done_Library */ | |
508 | + /* */ | |
509 | + /* <Description> */ | |
510 | + /* Discard a given library object. This closes all drivers and */ | |
511 | + /* discards all resource objects. */ | |
512 | + /* */ | |
513 | + /* <Input> */ | |
514 | + /* library :: A handle to the target library. */ | |
515 | + /* */ | |
516 | + /* <Return> */ | |
517 | + /* FreeType error code. 0~means success. */ | |
518 | + /* */ | |
519 | + /* <Note> */ | |
520 | + /* See the discussion of reference counters in the description of */ | |
521 | + /* @FT_Reference_Library. */ | |
522 | + /* */ | |
523 | + FT_EXPORT( FT_Error ) | |
524 | + FT_Done_Library( FT_Library library ); | |
525 | + | |
526 | + /* */ | |
527 | + | |
528 | + typedef void | |
529 | + (*FT_DebugHook_Func)( void* arg ); | |
530 | + | |
531 | + | |
532 | + /*************************************************************************/ | |
533 | + /* */ | |
534 | + /* <Function> */ | |
535 | + /* FT_Set_Debug_Hook */ | |
536 | + /* */ | |
537 | + /* <Description> */ | |
538 | + /* Set a debug hook function for debugging the interpreter of a font */ | |
539 | + /* format. */ | |
540 | + /* */ | |
541 | + /* <InOut> */ | |
542 | + /* library :: A handle to the library object. */ | |
543 | + /* */ | |
544 | + /* <Input> */ | |
545 | + /* hook_index :: The index of the debug hook. You should use the */ | |
546 | + /* values defined in `ftobjs.h', e.g., */ | |
547 | + /* `FT_DEBUG_HOOK_TRUETYPE'. */ | |
548 | + /* */ | |
549 | + /* debug_hook :: The function used to debug the interpreter. */ | |
550 | + /* */ | |
551 | + /* <Note> */ | |
552 | + /* Currently, four debug hook slots are available, but only two (for */ | |
553 | + /* the TrueType and the Type~1 interpreter) are defined. */ | |
554 | + /* */ | |
555 | + /* Since the internal headers of FreeType are no longer installed, */ | |
556 | + /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ | |
557 | + /* This is a bug and will be fixed in a forthcoming release. */ | |
558 | + /* */ | |
559 | + FT_EXPORT( void ) | |
560 | + FT_Set_Debug_Hook( FT_Library library, | |
561 | + FT_UInt hook_index, | |
562 | + FT_DebugHook_Func debug_hook ); | |
563 | + | |
564 | + | |
565 | + /*************************************************************************/ | |
566 | + /* */ | |
567 | + /* <Function> */ | |
568 | + /* FT_Add_Default_Modules */ | |
569 | + /* */ | |
570 | + /* <Description> */ | |
571 | + /* Add the set of default drivers to a given library object. */ | |
572 | + /* This is only useful when you create a library object with */ | |
573 | + /* @FT_New_Library (usually to plug a custom memory manager). */ | |
574 | + /* */ | |
575 | + /* <InOut> */ | |
576 | + /* library :: A handle to a new library object. */ | |
577 | + /* */ | |
578 | + FT_EXPORT( void ) | |
579 | + FT_Add_Default_Modules( FT_Library library ); | |
580 | + | |
581 | + | |
582 | + | |
583 | + /************************************************************************** | |
584 | + * | |
585 | + * @section: | |
586 | + * truetype_engine | |
587 | + * | |
588 | + * @title: | |
589 | + * The TrueType Engine | |
590 | + * | |
591 | + * @abstract: | |
592 | + * TrueType bytecode support. | |
593 | + * | |
594 | + * @description: | |
595 | + * This section contains a function used to query the level of TrueType | |
596 | + * bytecode support compiled in this version of the library. | |
597 | + * | |
598 | + */ | |
599 | + | |
600 | + | |
601 | + /************************************************************************** | |
602 | + * | |
603 | + * @enum: | |
604 | + * FT_TrueTypeEngineType | |
605 | + * | |
606 | + * @description: | |
607 | + * A list of values describing which kind of TrueType bytecode | |
608 | + * engine is implemented in a given FT_Library instance. It is used | |
609 | + * by the @FT_Get_TrueType_Engine_Type function. | |
610 | + * | |
611 | + * @values: | |
612 | + * FT_TRUETYPE_ENGINE_TYPE_NONE :: | |
613 | + * The library doesn't implement any kind of bytecode interpreter. | |
614 | + * | |
615 | + * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: | |
616 | + * Deprecated and removed. | |
617 | + * | |
618 | + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: | |
619 | + * The library implements a bytecode interpreter that covers | |
620 | + * the full instruction set of the TrueType virtual machine (this | |
621 | + * was governed by patents until May 2010, hence the name). | |
622 | + * | |
623 | + * @since: | |
624 | + * 2.2 | |
625 | + * | |
626 | + */ | |
627 | + typedef enum FT_TrueTypeEngineType_ | |
628 | + { | |
629 | + FT_TRUETYPE_ENGINE_TYPE_NONE = 0, | |
630 | + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, | |
631 | + FT_TRUETYPE_ENGINE_TYPE_PATENTED | |
632 | + | |
633 | + } FT_TrueTypeEngineType; | |
634 | + | |
635 | + | |
636 | + /************************************************************************** | |
637 | + * | |
638 | + * @func: | |
639 | + * FT_Get_TrueType_Engine_Type | |
640 | + * | |
641 | + * @description: | |
642 | + * Return an @FT_TrueTypeEngineType value to indicate which level of | |
643 | + * the TrueType virtual machine a given library instance supports. | |
644 | + * | |
645 | + * @input: | |
646 | + * library :: | |
647 | + * A library instance. | |
648 | + * | |
649 | + * @return: | |
650 | + * A value indicating which level is supported. | |
651 | + * | |
652 | + * @since: | |
653 | + * 2.2 | |
654 | + * | |
655 | + */ | |
656 | + FT_EXPORT( FT_TrueTypeEngineType ) | |
657 | + FT_Get_TrueType_Engine_Type( FT_Library library ); | |
658 | + | |
659 | + /* */ | |
660 | + | |
661 | + | |
662 | +FT_END_HEADER | |
663 | + | |
664 | +#endif /* FTMODAPI_H_ */ | |
665 | + | |
666 | + | |
667 | +/* END */ |
@@ -59,7 +59,8 @@ | ||
59 | 59 | "\tThe output directory is determined as \".CONF\".\n" |
60 | 60 | "\n" |
61 | 61 | "SHBOPT_BASE ...\n" |
62 | - "\tThe base options remained to pass to SHBuild, including SRCPATH.\n\n" | |
62 | + "\tThe base options remained to pass to SHBuild, including SRCPATH. If" | |
63 | + " this is empty, it is assumed as a single '.'.\n\n" | |
63 | 64 | "There are several other environment variables to control the build.\n" |
64 | 65 | "\n" |
65 | 66 | "SHBuild_NoAdjustSubsystem\n" |
@@ -72,6 +73,7 @@ | ||
72 | 73 | ( |
73 | 74 | putss "Found configuration \"" arg1 "\"."; |
74 | 75 | $def! SHBOPT_BASE arg-rest args; |
76 | + $if (null? SHBOPT_BASE) ($redef! SHBOPT_BASE list "."); | |
75 | 77 | $assert-nonempty arg1; |
76 | 78 | "XXX", "The argument cannot be empty, so there is no default value."; |
77 | 79 | $def! SHBuild_Conf arg1; |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file NPLA1.h |
12 | 12 | \ingroup NPL |
13 | 13 | \brief NPLA1 公共接口。 |
14 | -\version r9631 | |
14 | +\version r9692 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 472 |
17 | 17 | \par 创建时间: |
18 | 18 | 2014-02-02 17:58:24 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-26 22:05 +0800 | |
20 | + 2022-08-15 05:15 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -38,12 +38,14 @@ | ||
38 | 38 | // ystdex::exclude_self_params_t, YSLib::AreEqualHeld, ystdex::or_, |
39 | 39 | // std::is_constructible, ystdex::decay_t, ystdex::expanded_caller, |
40 | 40 | // ystdex::make_parameter_list_t, ystdex::make_function_type_t, ystdex::true_, |
41 | -// AssertCombiningTerm, IsList, ThrowListTypeErrorForNonList, RemoveHead, | |
42 | -// ArityMismatch, TermTags, RegularizeTerm, TokenValue, Environment, | |
43 | -// ParseResultOf, ByteParser, SourcedByteParser, type_info, type_id, | |
44 | -// SourceInformation, std::bind, std::placeholders::_1, std::integral_constant, | |
45 | -// SourceName, NPL::tuple, NPL::get, NPL::forward_as_tuple, ReaderState, | |
46 | -// YSLib::allocate_shared, ystdex::is_bitwise_swappable; | |
41 | +// AssertCombiningTerm, IsList, TryAccessLeaf, TermReference, IsSticky, | |
42 | +// ThrowListTypeErrorForNonList, ResolveSuffix, ThrowInsufficientTermsError, | |
43 | +// CountPrefix, ArityMismatch, TermTags, RegularizeTerm, TokenValue, function, | |
44 | +// Environment, ParseResultOf, ByteParser, SourcedByteParser, type_info, | |
45 | +// type_id, SourceInformation, std::bind, std::placeholders::_1, | |
46 | +// std::integral_constant, SourceName, NPL::tuple, NPL::get, | |
47 | +// NPL::forward_as_tuple, ReaderState, YSLib::allocate_shared, | |
48 | +// ystdex::is_bitwise_swappable; | |
47 | 49 | #include YFM_YSLib_Core_YEvent // for YSLib::GHEvent, YSLib::GCombinerInvoker, |
48 | 50 | // YSLib::GDefaultLastValueInvoker; |
49 | 51 | #include <ystdex/algorithm.hpp> // for ystdex::fast_any_of, ystdex::split; |
@@ -632,10 +634,12 @@ | ||
632 | 634 | \warning 若不满足上下文状态类型要求,行为未定义。 |
633 | 635 | \sa ContextState::DefaultReduceOnce |
634 | 636 | \sa ContextState::ReduceOnce |
637 | +\sa ContextState::SetNextTermRef | |
635 | 638 | \since build 806 |
636 | 639 | |
637 | 640 | 转换第二参数为 NPLA1 上下文状态引用,访问其中的 NPLA1 表达式节点一次规约续延并调用。 |
638 | -若使用异步实现,在尾上下文支持尾调用优化。 | |
641 | +若使用异步实现,首先设置下一求值项为第一参数指定的项。 | |
642 | +对使用 TCO 的异步实现,在尾上下文支持尾调用优化。 | |
639 | 643 | */ |
640 | 644 | YF_API ReductionStatus |
641 | 645 | ReduceOnce(TermNode&, ContextNode&); |
@@ -1275,24 +1279,60 @@ | ||
1275 | 1279 | 抛出的异常同 FormContextHandler::CheckArguments ,但通常直接用于底层合并子实现。 |
1276 | 1280 | */ |
1277 | 1281 | inline PDefH(void, CheckArgumentList, const TermNode& term) |
1278 | - ImplExpr(AssertCombiningTerm(term), IsList(term) ? void() | |
1279 | - // NOTE: The combiner position is skipped. | |
1280 | - : ThrowListTypeErrorForNonList(term, {}, 1)) | |
1282 | +#if true | |
1283 | + ImplExpr(AssertCombiningTerm(term), YB_LIKELY(IsList(term)) ? void() | |
1284 | + : [&] YB_LAMBDA_ANNOTATE(() , , flatten){ | |
1285 | + if(const auto p = TryAccessLeaf<const TermReference>(term)) | |
1286 | + { | |
1287 | + auto& nd(p->get()); | |
1288 | + | |
1289 | + if(!IsList(nd)) | |
1290 | + { | |
1291 | + const bool is_ref(term.size() == 1 | |
1292 | + || IsSticky(std::next(term.begin())->Tags)); | |
1293 | + | |
1294 | + ThrowListTypeErrorForNonList(nd, is_ref, is_ref ? 0 : 1); | |
1295 | + } | |
1296 | + } | |
1297 | + else | |
1298 | + // NOTE: The combiner position is skipped. | |
1299 | + ThrowListTypeErrorForNonList(term, {}, 1); | |
1300 | + }()) | |
1301 | +#else | |
1302 | + // NOTE: Any optimized implemenations shall be equivalent to this. | |
1303 | + ImplExpr(AssertCombiningTerm(term), | |
1304 | + ResolveSuffix([&](const TermNode& nd, bool has_ref){ | |
1305 | + if(YB_UNLIKELY(!IsList(nd))) | |
1306 | + { | |
1307 | + // NOTE: The combination of a pair with a prefixed subterm and | |
1308 | + // another object is recognized as %IsAtom with 1 prefixed | |
1309 | + // subterm. | |
1310 | + // XXX: Currently only subobject references can have irregular | |
1311 | + // subterms. Nevertheless, this is not assumed in general. | |
1312 | + const bool is_ref(has_ref && (term.size() == 1 | |
1313 | + || IsSticky(std::next(term.begin())->Tags))); | |
1314 | + | |
1315 | + // NOTE: The combiner position is skipped unless the rest | |
1316 | + // subterms are parts of a reference value. | |
1317 | + ThrowListTypeErrorForNonList(nd, is_ref, is_ref ? 0 : 1); | |
1318 | + } | |
1319 | + }, term)) | |
1320 | +#endif | |
1281 | 1321 | |
1282 | 1322 | /*! |
1283 | 1323 | \brief 检查可变参数数量。 |
1284 | 1324 | \pre 间接断言:参数指定的项是分支列表节点。 |
1285 | 1325 | \exception ParameterMismatch 缺少项的错误。 |
1286 | -\sa RemoveHead | |
1287 | 1326 | \sa ThrowInsufficientTermsError |
1288 | -\since build 924 | |
1327 | +\since build 952 | |
1289 | 1328 | |
1290 | 1329 | 检查第一参数的子项数大于第二参数指定的参数个数。 |
1291 | -若具有不大于第二参数指定的参数个数,则移除第一个子项,抛出缺少项的异常。 | |
1330 | +若具有不大于第二参数指定的参数个数,则抛出缺少项的异常。 | |
1331 | +抛出缺少项的异常时,异常消息的项移除第一个子项。 | |
1292 | 1332 | */ |
1293 | -inline PDefH(void, CheckVariadicArity, TermNode& term, size_t n) | |
1333 | +inline PDefH(void, CheckVariadicArity, const TermNode& term, size_t n) | |
1294 | 1334 | ImplExpr(AssertCombiningTerm(term), CountPrefix(term) - 1 > n ? void() |
1295 | - : (RemoveHead(term), ThrowInsufficientTermsError(term, {}))) | |
1335 | + : ThrowInsufficientTermsError(term, {}, 1)) | |
1296 | 1336 | |
1297 | 1337 | /*! |
1298 | 1338 | \pre 间接断言:参数指定的项是分支列表节点或项的容器非空(对应枝节点)。 |
@@ -1304,11 +1344,12 @@ | ||
1304 | 1344 | \pre 间接断言:参数指定的项是分支列表节点。 |
1305 | 1345 | \return 项作为列表操作数被匹配的最大实际参数的个数。 |
1306 | 1346 | \exception ListReductionFailure 异常中立:由 CheckArgumentList 抛出。 |
1347 | +\sa CountPrefix | |
1307 | 1348 | \since build 951 |
1308 | 1349 | */ |
1309 | 1350 | YB_ATTR_nodiscard YB_PURE inline |
1310 | 1351 | PDefH(size_t, FetchArgumentN, const TermNode& term) |
1311 | - ImplRet(CheckArgumentList(term), term.size() - 1) | |
1352 | + ImplRet(CheckArgumentList(term), CountPrefix(term) - 1) | |
1312 | 1353 | |
1313 | 1354 | /*! |
1314 | 1355 | \note 保留求值留作保留用途,一般不需要被作为用户代码直接使用。 |
@@ -1390,10 +1431,10 @@ | ||
1390 | 1431 | /*! |
1391 | 1432 | \brief 求值标识符。 |
1392 | 1433 | \note 不验证标识符是否为字面量;仅以字面量处理时可能需要重规约。 |
1434 | +\sa ContextState::TrySetTailOperatorName | |
1393 | 1435 | \sa LiteralHandler |
1394 | 1436 | \sa ReferenceTerm |
1395 | 1437 | \sa ResolveIdentifier |
1396 | -\sa SetupTailOperatorName | |
1397 | 1438 | \sa TermReference |
1398 | 1439 | \since build 745 |
1399 | 1440 |
@@ -1759,6 +1800,8 @@ | ||
1759 | 1800 | template<typename _fParse> |
1760 | 1801 | using GParsedValue = typename ParseResultOf<_fParse>::value_type; |
1761 | 1802 | |
1803 | +// XXX: Use %function instead of %ystdex::unchecked_function is no less | |
1804 | +// efficient. | |
1762 | 1805 | //! \brief 泛型标记器:分析解析结果元素转换为可能包含记号的节点。 |
1763 | 1806 | template<typename _fParse> |
1764 | 1807 | using GTokenizer = function<TermNode(const GParsedValue<_fParse>&)>; |
@@ -1989,6 +2032,8 @@ | ||
1989 | 2032 | template<LoadOption _vOpt = Contextual> |
1990 | 2033 | using LoadOptionTag = std::integral_constant<LoadOption, _vOpt>; |
1991 | 2034 | //@} |
2035 | + // XXX: Use %function instead of %ystdex::unchecked_function is a bit more | |
2036 | + // efficient. | |
1992 | 2037 | /*! |
1993 | 2038 | \brief 加载器。 |
1994 | 2039 | \since build 899 |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file NPLA1Forms.h |
12 | 12 | \ingroup NPL |
13 | 13 | \brief NPLA1 语法形式。 |
14 | -\version r8865 | |
14 | +\version r8873 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 882 |
17 | 17 | \par 创建时间: |
18 | 18 | 2020-02-15 11:19:21 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-27 22:56 +0800 | |
20 | + 2022-08-13 17:19 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -2050,6 +2050,16 @@ | ||
2050 | 2050 | ContinuationToApplicative(TermNode&); |
2051 | 2051 | //@} |
2052 | 2052 | |
2053 | +/*! | |
2054 | +\brief 应用续延。 | |
2055 | +\since build 952 | |
2056 | + | |
2057 | +参考调用文法: | |
2058 | +<pre>apply-continuation \<continuation> \<object></pre> | |
2059 | +*/ | |
2060 | +YF_API ReductionStatus | |
2061 | +ApplyContinuation(TermNode&, ContextNode&); | |
2062 | + | |
2053 | 2063 | |
2054 | 2064 | /*! |
2055 | 2065 | \brief 调用 UTF-8 字符串的系统命令,并保存 int 类型的结果到项的值中。 |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file SContext.h |
12 | 12 | \ingroup NPL |
13 | 13 | \brief S 表达式上下文。 |
14 | -\version r4516 | |
14 | +\version r4552 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 304 |
17 | 17 | \par 创建时间: |
18 | 18 | 2012-08-03 19:55:41 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-06 08:26 +0800 | |
20 | + 2022-08-06 01:10 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -474,12 +474,39 @@ | ||
474 | 474 | {} |
475 | 475 | //! \brief 复制构造:使用参数和参数指定的分配器。 |
476 | 476 | TermNode(const TermNode& nd, allocator_type a) |
477 | + // XXX: Explicit inlining is more efficient. | |
478 | +#if false | |
479 | + : TermNode(nd.Tags, nd, a) | |
480 | +#else | |
477 | 481 | : container(ConSub(nd.container, a)), Value(nd.Value), Tags(nd.Tags) |
482 | +#endif | |
483 | + {} | |
484 | + //! \since build 952 | |
485 | + TermNode(TermTags tags, const TermNode& nd) | |
486 | + : TermNode(tags, nd, nd.get_allocator()) | |
487 | + {} | |
488 | + //! \since build 952 | |
489 | + TermNode(TermTags tags, const TermNode& nd, allocator_type a) | |
490 | + : container(ConSub(nd.container, a)), Value(nd.Value), Tags(tags) | |
478 | 491 | {} |
479 | 492 | DefDeMoveCtor(TermNode) |
480 | - TermNode(TermNode&& nd, allocator_type a) | |
493 | + TermNode(TermNode&& nd, allocator_type a) | |
494 | + // XXX: Ditto. | |
495 | +#if false | |
496 | + : TermNode(nd.Tags, std::move(nd), a) | |
497 | +#else | |
481 | 498 | : container(std::move(nd.container), a), Value(std::move(nd.Value)), |
482 | 499 | Tags(nd.Tags) |
500 | +#endif | |
501 | + {} | |
502 | + //! \since build 952 | |
503 | + TermNode(TermTags tags, TermNode&& nd) | |
504 | + : TermNode(tags, std::move(nd), nd.get_allocator()) | |
505 | + {} | |
506 | + //! \since build 952 | |
507 | + TermNode(TermTags tags, TermNode&& nd, allocator_type a) | |
508 | + : container(std::move(nd.container), a), Value(std::move(nd.Value)), | |
509 | + Tags(tags) | |
483 | 510 | {} |
484 | 511 | //@} |
485 | 512 |
@@ -859,6 +886,15 @@ | ||
859 | 886 | PDefH(bool, IsPair, const TermNode& nd) ynothrow |
860 | 887 | ImplRet(!IsAtom(nd)) |
861 | 888 | //@} |
889 | + | |
890 | +/*! | |
891 | +\brief 判断项表示具有一个元素的列表。 | |
892 | +\since build 952 | |
893 | +*/ | |
894 | +YB_ATTR_nodiscard YB_PURE inline PDefH(bool, IsSingleElementList, | |
895 | + const TermNode& term) ynothrow | |
896 | + // XXX: First calling %IsList is more efficient in most case. | |
897 | + ImplRet(IsList(term) && term.size() == 1) | |
862 | 898 | //@} |
863 | 899 | |
864 | 900 | //! \since build 928 |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file Dependency.cpp |
12 | 12 | \ingroup NPL |
13 | 13 | \brief 依赖管理。 |
14 | -\version r7113 | |
14 | +\version r7133 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 623 |
17 | 17 | \par 创建时间: |
18 | 18 | 2015-08-09 22:14:45 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-27 12:34 +0800 | |
20 | + 2022-08-15 06:18 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -1067,7 +1067,7 @@ | ||
1067 | 1067 | # endif |
1068 | 1068 | R"NPL( |
1069 | 1069 | $def! list% $lambda &x forward! x; |
1070 | -$def! rlist $lambda ((.&x)) move! x; | |
1070 | +$def! rlist $lambda ((.&x)) forward! (check-list-reference x); | |
1071 | 1071 | )NPL" |
1072 | 1072 | # endif |
1073 | 1073 | R"NPL( |
@@ -1193,7 +1193,7 @@ | ||
1193 | 1193 | $defl%! rest% ((#ignore .%xs)) $move-resolved! xs; |
1194 | 1194 | $defl%! rest& (&l) |
1195 | 1195 | ($lambda% ((#ignore .&xs)) xs) (check-pair-reference (forward! l)); |
1196 | -$defl%! restv ((#ignore .xs)) $move-resolved! xs; | |
1196 | +$defl! restv ((#ignore .xs)) $move-resolved! xs; | |
1197 | 1197 | $defl! set-first! (&l x) assign@! (first@ (forward! l)) (move! x); |
1198 | 1198 | $defl! set-first@! (&l &x) assign@! (first@ (forward! l)) (forward! x); |
1199 | 1199 | $defl! set-first%! (&l &x) assign%! (first@ (forward! l)) (forward! x); |
@@ -1773,6 +1773,16 @@ | ||
1773 | 1773 | RegisterStrict(renv, "call/1cc", Call1CC); |
1774 | 1774 | RegisterStrict(renv, "continuation->applicative", |
1775 | 1775 | ContinuationToApplicative); |
1776 | +#if NPL_Impl_NPLA1_Native_Forms | |
1777 | + RegisterStrict(renv, "apply-continuation", | |
1778 | + ApplyContinuation); | |
1779 | +#else | |
1780 | + context.ShareCurrentSource("<lib:std.continuations>"); | |
1781 | + context.Perform(R"NPL( | |
1782 | +$defl! apply-continuation (&k &arg) | |
1783 | + apply (continuation->applicative (forward! k)) (forward! arg); | |
1784 | + )NPL"); | |
1785 | +#endif | |
1776 | 1786 | } |
1777 | 1787 | |
1778 | 1788 | void |
@@ -1815,8 +1825,13 @@ | ||
1815 | 1825 | }); |
1816 | 1826 | #else |
1817 | 1827 | context.ShareCurrentSource("<lib:std.promises>"); |
1818 | - // NOTE: Call of 'set-first%!' does not check cyclic references. This is | |
1828 | + // NOTE: The call to 'set-first%!' does not check cyclic references. This is | |
1819 | 1829 | // kept safe since it can occur only with NPLA1 undefined behavior. |
1830 | + // XXX: The internal construct uses lists instead of pairs as [RnRK] even | |
1831 | + // after pairs are supported, since the assignment to the referent of the | |
1832 | + // value introduced by trailing sequence has unspecified behavior in the | |
1833 | + // object language (and it will not change the shared referent in the | |
1834 | + // current implementation).. | |
1820 | 1835 | context.Perform(R"NPL( |
1821 | 1836 | $provide/let! (promise? memoize $lazy $lazy% $lazy/d $lazy/d% force) |
1822 | 1837 | ((mods $as-environment ( |
@@ -2414,9 +2429,9 @@ | ||
2414 | 2429 | get-requirement-filename |
2415 | 2430 | (($remote-eval% force std.promises) prom_pathspecs) req; |
2416 | 2431 | $defl/e%! require mods (&req .&opt) |
2417 | - $if (registered-requirement? req) (get-cell% (move! req)) | |
2432 | + $if (registered-requirement? req) (get-cell% (forward! req)) | |
2418 | 2433 | ($let*% ((filename find-requirement-filename req) |
2419 | - (env register-requirement! req) (&res get-cell% (move! req))) | |
2434 | + (env register-requirement! req) (&res get-cell% (forward! req))) | |
2420 | 2435 | $sequence |
2421 | 2436 | ($unless (null? opt) |
2422 | 2437 | ($set! env module-parameters $let (((&e .&eopt) opt)) |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file NPLA.cpp |
12 | 12 | \ingroup NPL |
13 | 13 | \brief NPLA 公共接口。 |
14 | -\version r4188 | |
14 | +\version r4191 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 663 |
17 | 17 | \par 创建时间: |
18 | 18 | 2016-01-07 10:32:45 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-06 20:50 +0800 | |
20 | + 2022-08-10 23:09 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -39,7 +39,7 @@ | ||
39 | 39 | // TryAccessLeaf, AccessFirstSubterm, YSLib::FilterExceptions, type_id, |
40 | 40 | // ystdex::addrof, ystdex::second_of, type_info, std::current_exception, |
41 | 41 | // std::rethrow_exception, std::throw_with_nested, ystdex::retry_on_cond, |
42 | -// ystdex::id, pair, NPL::IsMovable, YSLib::ExtractException; | |
42 | +// ystdex::id, pair, IsAtom, NPL::IsMovable, YSLib::ExtractException; | |
43 | 43 | #include <ystdex/function.hpp> // for ystdex::unchecked_function; |
44 | 44 | |
45 | 45 | //! \since build 903 |
@@ -1229,7 +1229,7 @@ | ||
1229 | 1229 | ResolveEnvironment(const TermNode& term) |
1230 | 1230 | { |
1231 | 1231 | return ResolveTerm([&](const TermNode& nd, bool has_ref){ |
1232 | - if(!IsExtendedList(nd)) | |
1232 | + if(IsAtom(nd)) | |
1233 | 1233 | return ResolveEnvironment(nd.Value); |
1234 | 1234 | ThrowResolveEnvironmentFailure(nd, has_ref); |
1235 | 1235 | }, term); |
@@ -1238,7 +1238,7 @@ | ||
1238 | 1238 | ResolveEnvironment(TermNode& term) |
1239 | 1239 | { |
1240 | 1240 | return ResolveTerm([&](TermNode& nd, ResolvedTermReferencePtr p_ref){ |
1241 | - if(!IsExtendedList(nd)) | |
1241 | + if(IsAtom(nd)) | |
1242 | 1242 | return ResolveEnvironment(nd.Value, NPL::IsMovable(p_ref)); |
1243 | 1243 | ThrowResolveEnvironmentFailure(nd, p_ref); |
1244 | 1244 | }, term); |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file NPLA1.cpp |
12 | 12 | \ingroup NPL |
13 | 13 | \brief NPLA1 公共接口。 |
14 | -\version r23582 | |
14 | +\version r23611 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 472 |
17 | 17 | \par 创建时间: |
18 | 18 | 2014-02-02 18:02:47 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-29 03:04 +0800 | |
20 | + 2022-08-11 02:15 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -31,17 +31,17 @@ | ||
31 | 31 | // ystdex::equal_to, YSLib::unordered_map, YSLib::lock_guard, YSLib::mutex, |
32 | 32 | // std::ref, ListReductionFailure, ystdex::sfmt, TermToStringWithReferenceMark, |
33 | 33 | // std::next, IsBranch, TermReference, std::allocator_arg, in_place_type, |
34 | -// CheckReducible, IsNPLAExtendedLiteralNonDigitPrefix, IsAllSignLexeme, | |
35 | -// AllocatorHolder, YSLib::IValueHolder, ystdex::ref, | |
34 | +// CheckReducible, IsNPLAExtendedLiteralNonDigitPrefix, | |
35 | +// IsAllSignLexeme, AllocatorHolder, YSLib::IValueHolder, ystdex::ref, | |
36 | 36 | // YSLib::AllocatedHolderOperations, any, ystdex::as_const, |
37 | 37 | // NPL::forward_as_tuple, uintmax_t, ystdex::bind1, TokenValue, |
38 | 38 | // Forms::Sequence, ReduceBranchToList, YSLib::stack, vector, GetLValueTagsOf, |
39 | 39 | // TermTags, function, TryAccessLeafAtom, PropagateTo, InvalidReference, |
40 | -// IsList, IsIgnore, tuple, TNCIter, NPL::get, NPL::Deref, | |
41 | -// YSLib::allocate_shared, LiftTermRef, TryAccessLeaf, IsTyped, ResolveTerm, | |
42 | -// std::prev, ThrowListTypeErrorForNonList, ThrowInsufficientTermsError, | |
43 | -// ReferenceTerm, ystdex::begins_with, FindStickySubterm, Environment, | |
44 | -// shared_ptr, ystdex::retry_on_cond, AccessFirstSubterm, ystdex::ref_eq, | |
40 | +// IsList, IsIgnore, tuple, TNCIter, NPL::get, NPL::Deref, LiftTermRef, | |
41 | +// TryAccessLeaf, IsTyped, ResolveTerm, std::prev, | |
42 | +// ThrowListTypeErrorForNonList, ThrowInsufficientTermsError, ReferenceTerm, | |
43 | +// ystdex::begins_with, FindStickySubterm, Environment, shared_ptr, | |
44 | +// ystdex::retry_on_cond, AccessFirstSubterm, ystdex::ref_eq, | |
45 | 45 | // ystdex::make_transform, IsCombiningTerm, NPL::IsMovable, std::placeholders, |
46 | 46 | // NoContainer, ystdex::try_emplace, Access, YSLib::Informative, |
47 | 47 | // ystdex::unique_guard, CategorizeBasicLexeme, DeliteralizeUnchecked, |
@@ -318,7 +318,8 @@ | ||
318 | 318 | ThrowCombiningFailure(TermNode& term, const ContextNode& ctx, |
319 | 319 | const TermNode& fm, bool has_ref) |
320 | 320 | { |
321 | - // NOTE: Try to extract the identifier set by %SetupTailOperatorName. | |
321 | + // NOTE: Try to extract the identifier set by | |
322 | + // %ContextState::TrySetTailOperatorName. | |
322 | 323 | string name(term.get_allocator()); |
323 | 324 | |
324 | 325 | if(const auto p = ContextState::Access(ctx).TryGetTailOperatorName(term)) |
@@ -687,7 +688,7 @@ | ||
687 | 688 | // The anchor here (if any) is not accurate because it refers |
688 | 689 | // to the anchor saved by the reference (if any), not |
689 | 690 | // necessarily the original environment owning the referent. |
690 | - mv(TermNode::Container(o.get_allocator()), | |
691 | + mv(TermNode::Container(a), | |
691 | 692 | // XXX: Term tags on prvalues are reserved and should be |
692 | 693 | // ignored normally except for future internal use. Note |
693 | 694 | // that %TermTags::Temporary can be provided by a bound |
@@ -732,21 +733,10 @@ | ||
732 | 733 | if(sigil == '%' || sigil == char()) |
733 | 734 | BindSubpairCopySubterms(t, o, first); |
734 | 735 | else |
735 | - { | |
736 | - auto p_sub(A1::AllocateSharedTerm(a)); | |
737 | - auto& sub(NPL::Deref(p_sub)); | |
738 | - | |
739 | 736 | // XXX: The container is ignored, since it is assumed always |
740 | 737 | // living when %Value is accessed (otherwise, the behavior |
741 | 738 | // is undefined in the object language). |
742 | - LiftTermRef(sub, o.Value); | |
743 | - tcon.push_back( | |
744 | - A1::MakeSubobjectReferent(a, std::move(p_sub))); | |
745 | - // XXX: The anchor indicated by %Referenced is not accurate, | |
746 | - // as the overload %operator() above. | |
747 | - t.Value = ValueObject(std::allocator_arg, a, | |
748 | - in_place_type<TermReference>, tags, sub, Referenced); | |
749 | - } | |
739 | + LiftTermRef(t.Value, o.Value); | |
750 | 740 | } |
751 | 741 | else |
752 | 742 | // XXX: As in %LiftPrefixToReturn. |
@@ -766,7 +756,8 @@ | ||
766 | 756 | // XXX: Reuse %tcon. |
767 | 757 | tcon.clear(); |
768 | 758 | tcon.push_back(MakeSubobjectReferent(a, std::move(p_sub))); |
769 | - // XXX: Ditto. | |
759 | + // XXX: The anchor indicated by %Referenced is not accurate, as | |
760 | + // the overload %operator() above. | |
770 | 761 | mv(std::move(tcon), ValueObject(std::allocator_arg, a, |
771 | 762 | in_place_type<TermReference>, tags, sub, Referenced)); |
772 | 763 | } |
@@ -1305,8 +1296,10 @@ | ||
1305 | 1296 | // NOTE: The remained ptree subterms (if any) shall be parts of the |
1306 | 1297 | // suffix. This may happen when the suffix is a reference to |
1307 | 1298 | // symbol. The operand may still be a pair, though. |
1299 | +#if NPL_Impl_NPLA1_AssertParameterMatch | |
1308 | 1300 | YAssert(mid == FindStickySubterm(NPL::get<PTreeRef>(e)), |
1309 | 1301 | "Invalid state found."); |
1302 | +#endif | |
1310 | 1303 | Bind(o_nd, NPL::get<OperandFirst>(e), *p, NPL::get<OperandTags>(e), |
1311 | 1304 | NPL::get<EnvironmentRef>(e)); |
1312 | 1305 | } |
@@ -1534,7 +1527,7 @@ | ||
1534 | 1527 | { |
1535 | 1528 | YAssert(term.size() != 0, "Invalid term found."); |
1536 | 1529 | // NOTE: List with single element shall be reduced as the element. |
1537 | - if(!IsList(term) || term.size() != 1) | |
1530 | + if(!IsSingleElementList(term)) | |
1538 | 1531 | return DoAdministratives(cs.EvaluateList, term, ctx); |
1539 | 1532 | |
1540 | 1533 | // XXX: This may be slightly more efficient, and more importantly, |
@@ -1542,10 +1535,8 @@ | ||
1542 | 1535 | // implementation well by only allow one level of direct recursion. |
1543 | 1536 | auto term_ref(ystdex::ref(term)); |
1544 | 1537 | |
1545 | - ystdex::retry_on_cond([&]{ | |
1546 | - auto& tm(term_ref.get()); | |
1547 | - | |
1548 | - return IsList(tm) && tm.size() == 1; | |
1538 | + ystdex::retry_on_cond([&] YB_LAMBDA_ANNOTATE((), ynothrow, pure){ | |
1539 | + return IsSingleElementList(term_ref); | |
1549 | 1540 | }, [&]{ |
1550 | 1541 | term_ref = AccessFirstSubterm(term_ref); |
1551 | 1542 | }); |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file NPLA1Forms.cpp |
12 | 12 | \ingroup NPL |
13 | 13 | \brief NPLA1 语法形式。 |
14 | -\version r27814 | |
14 | +\version r27920 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 882 |
17 | 17 | \par 创建时间: |
18 | 18 | 2014-02-15 11:19:51 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-29 03:07 +0800 | |
20 | + 2022-08-15 06:05 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -46,19 +46,21 @@ | ||
46 | 46 | // NPL::AsTermNode, ystdex::exchange, NPLException, GuardFreshEnvironment, |
47 | 47 | // TermTags, YSLib::Debug, YSLib::sfmt, ReduceCombinedBranch, A1::MakeForm, |
48 | 48 | // ystdex::expand_proxy, AccessRegular, GetLValueTagsOf, RegularizeTerm, |
49 | -// IsPair, IsSticky, LiftMovedOther, LiftOtherValue, IsList, | |
50 | -// ThrowValueCategoryError, IsAtom, ThrowListTypeErrorForAtom, | |
49 | +// IsPair, IsSticky, LiftPropagatedReference, LiftMovedOther, LiftOtherValue, | |
50 | +// IsList, ThrowValueCategoryError, IsAtom, ThrowListTypeErrorForAtom, | |
51 | 51 | // ThrowInvalidSyntaxError, CheckEnvironmentFormal, LiftTermOrCopy, |
52 | 52 | // EnsureValueTags, type_id, ystdex::update_thunk, |
53 | 53 | // ThrowListTypeErrorForNonList, IsTyped, IsBranchedList, EnvironmentGuard, |
54 | 54 | // TryAccessLeaf, BindSymbol, A1::AsForm, ystdex::bind1, IsNPLASymbol, |
55 | 55 | // ystdex::fast_all_of, ystdex::isdigit, std::strchr, ystdex::call_value_or, |
56 | -// LiftCollapsed, YSLib::usystem, std::mem_fn; | |
56 | +// LiftCollapsed, AssertCombiningTerm, CountPrefix, YSLib::usystem, | |
57 | +// std::mem_fn; | |
57 | 58 | #include "NPLA1Internals.h" // for A1::Internals API; |
58 | 59 | #include YFM_NPL_SContext // for Session; |
59 | 60 | #include <ystdex/scope_guard.hpp> // for ystdex::unique_guard, ystdex::dismiss, |
60 | 61 | // ystdex::make_guard; |
61 | 62 | #include <ystdex/container.hpp> // for ystdex::prefix_eraser; |
63 | +#include <ystdex/functor.hpp> // for ystdex::equal_to; | |
62 | 64 | |
63 | 65 | namespace NPL |
64 | 66 | { |
@@ -1019,8 +1021,8 @@ | ||
1019 | 1021 | } |
1020 | 1022 | |
1021 | 1023 | // XXX: Returning term instead of the container allows to pass improper lists, |
1022 | -// also perserves the allocator on | |
1023 | -// copy. | |
1024 | +// also perserves the allocator on copy. | |
1025 | +// XXX: This is like %LiftOtherOrCopy, but with the result in the return value. | |
1024 | 1026 | //! \since build 947 |
1025 | 1027 | YB_ATTR_nodiscard TermNode |
1026 | 1028 | ConsItem(TermNode& y) |
@@ -1361,10 +1363,18 @@ | ||
1361 | 1363 | LiftCopyPropagate(TermNode& term, TermNode& tm, TermTags tags) |
1362 | 1364 | { |
1363 | 1365 | // XXX: Similar to the implementation of %ReduceToReference in NPLA.cpp. |
1366 | +#if true | |
1367 | + // NOTE: Propagate tags if it is a term reference. | |
1368 | + if(const auto p = TryAccessLeafAtom<TermReference>(term)) | |
1369 | + LiftPropagatedReference(term, tm, tags); | |
1370 | + else | |
1371 | + term.CopyContent(tm); | |
1372 | +#else | |
1364 | 1373 | term.CopyContent(tm); |
1365 | 1374 | // NOTE: Propagate tags if it is a term reference. |
1366 | 1375 | if(const auto p = TryAccessLeafAtom<TermReference>(term)) |
1367 | 1376 | p->PropagateFrom(tags); |
1377 | +#endif | |
1368 | 1378 | // XXX: Term tags are currently not respected in prvalues. |
1369 | 1379 | } |
1370 | 1380 | //! \since build 915 |
@@ -1411,6 +1421,7 @@ | ||
1411 | 1421 | LiftPropagatedReference(term, tm, p_ref->GetTags()); |
1412 | 1422 | else |
1413 | 1423 | LiftMovedOther(term, *p, p->IsMovable()); |
1424 | + // XXX: %RegularizeTerm would imply %EnsureValueTags. | |
1414 | 1425 | return ReductionStatus::Retained; |
1415 | 1426 | } |
1416 | 1427 | else if(list_not_move) |
@@ -1499,21 +1510,24 @@ | ||
1499 | 1510 | }, term); |
1500 | 1511 | } |
1501 | 1512 | |
1513 | +// XXX: Following instances of %YB_FLATTEN keep the implementations same | |
1514 | +// efficient to those previously not using %ThrowListTypeErrorForNonList in | |
1515 | +// %CheckResolvedListReference. | |
1516 | + | |
1502 | 1517 | //! \since build 859 |
1503 | -void | |
1518 | +YB_FLATTEN void | |
1504 | 1519 | CheckResolvedListReference(TermNode& nd, bool has_ref) |
1505 | 1520 | { |
1506 | 1521 | if(has_ref) |
1507 | 1522 | { |
1508 | 1523 | if(YB_UNLIKELY(!IsList(nd))) |
1509 | - throw ListTypeError(ystdex::sfmt("Expected a list, got '%s'.", | |
1510 | - TermToStringWithReferenceMark(nd, true).c_str())); | |
1524 | + ThrowListTypeErrorForNonList(nd, true); | |
1511 | 1525 | } |
1512 | 1526 | else |
1513 | 1527 | ThrowValueCategoryError(nd); |
1514 | 1528 | } |
1515 | 1529 | |
1516 | -void | |
1530 | +YB_FLATTEN void | |
1517 | 1531 | CheckResolvedPairReference(TermNode& nd, bool has_ref) |
1518 | 1532 | { |
1519 | 1533 | if(has_ref) |
@@ -1922,43 +1936,58 @@ | ||
1922 | 1936 | } |
1923 | 1937 | |
1924 | 1938 | |
1925 | -//! \since build 951 | |
1926 | -//@{ | |
1927 | -//! \pre 第三参数非空。 | |
1939 | +/*! | |
1940 | +\pre 断言:<tt>n <= term.size()</tt> 。 | |
1941 | +\since build 952 | |
1942 | +*/ | |
1928 | 1943 | ReductionStatus |
1929 | -ApplyFor(TermNode& term, ContextNode& ctx, shared_ptr<Environment> p_env) | |
1930 | -{ | |
1931 | - YAssert(p_env, "Invalid environment found."); | |
1944 | +ApplyImpl(TermNode& term, ContextNode& ctx, bool check_list = {}) | |
1945 | +{ | |
1946 | + RetainList(term); | |
1947 | + | |
1948 | + const auto n(CountPrefix(term)); | |
1949 | + | |
1950 | + // NOTE: The count of the prefix shall not great than the number of | |
1951 | + // subterms. | |
1952 | + YAssert(n <= term.size(), "Invalid size found."); | |
1953 | +#if true | |
1954 | + AssertCombiningTerm(term); | |
1955 | + if(YB_UNLIKELY(n <= 2)) | |
1956 | + ThrowInsufficientTermsError(term, {}, 1); | |
1957 | +#else | |
1958 | + // NOTE: Any optimized implemenations shall be equivalent to this. | |
1959 | + CheckVariadicArity(term, 1); | |
1960 | +#endif | |
1932 | 1961 | |
1933 | 1962 | auto i(term.begin()); |
1934 | - auto& comb(NPL::Deref(++i)); | |
1935 | - | |
1936 | - ForwardToUnwrapped(comb); | |
1937 | - { | |
1938 | - auto t(ConsItem(NPL::Deref(++i))); | |
1939 | - | |
1940 | - t.GetContainerRef().push_front(std::move(comb)); | |
1941 | - swap(t, term); | |
1942 | - } | |
1963 | + auto i_comb(++i); | |
1964 | + | |
1965 | + ForwardToUnwrapped(NPL::Deref(i_comb)); | |
1966 | + | |
1967 | + auto& arg(NPL::Deref(++i)); | |
1968 | + | |
1969 | + if(check_list) | |
1970 | + ResolveTerm([&](const TermNode& nd, bool has_ref){ | |
1971 | + if(YB_UNLIKELY(!IsList(nd))) | |
1972 | + ThrowListTypeErrorForNonList(nd, has_ref); | |
1973 | + }, arg); | |
1974 | + | |
1975 | + auto t(ConsItem(arg)); | |
1976 | + | |
1977 | + t.GetContainerRef().splice(t.begin(), term.GetContainerRef(), i_comb); | |
1978 | + swap(t, term); | |
1943 | 1979 | // NOTE: The precondition is same to the last call in %EvalImplUnchecked. |
1944 | 1980 | // See also the precondition of %Combine<TailCall>::RelayEnvSwitch. |
1945 | - return Combine<TailCall>::RelayEnvSwitch(ctx, term, std::move(p_env)); | |
1946 | -} | |
1947 | - | |
1948 | -ReductionStatus | |
1949 | -ApplyImpl(TermNode& term, ContextNode& ctx) | |
1950 | -{ | |
1951 | - const auto size(term.size()); | |
1952 | - | |
1953 | - if(size == 3) | |
1954 | - return ApplyFor(term, ctx, | |
1955 | - NPL::AllocateEnvironment(term.get_allocator())); | |
1956 | - if(size == 4) | |
1957 | - return ApplyFor(term, ctx, FetchValidEnvironment( | |
1958 | - ResolveEnvironment(*std::next(term.begin(), 3)).first)); | |
1959 | - ThrowInvalidSyntaxError("Syntax error in applying form."); | |
1960 | -} | |
1961 | -//@} | |
1981 | + return Combine<TailCall>::RelayEnvSwitch(ctx, term, | |
1982 | + [&]() -> shared_ptr<Environment>{ | |
1983 | + if(n == 3) | |
1984 | + return NPL::AllocateEnvironment(term.get_allocator()); | |
1985 | + if(n == 4) | |
1986 | + return FetchValidEnvironment( | |
1987 | + ResolveEnvironment(NPL::Deref(++i)).first); | |
1988 | + ThrowInvalidSyntaxError("Syntax error in applying form."); | |
1989 | + }()); | |
1990 | +} | |
1962 | 1991 | |
1963 | 1992 | //! \since build 951 |
1964 | 1993 | void |
@@ -2242,7 +2271,7 @@ | ||
2242 | 2271 | { |
2243 | 2272 | YAssert(!tr.empty(), "Invalid term found."); |
2244 | 2273 | LiftOtherOrCopyPropagate(term, NPL::Deref(tr.First), move, tr.Tags); |
2245 | - ++tr.First; | |
2274 | + EnsureValueTags(term.Tags), ++tr.First; | |
2246 | 2275 | } |
2247 | 2276 | |
2248 | 2277 | ReductionStatus |
@@ -2385,7 +2414,10 @@ | ||
2385 | 2414 | if(p_ref) |
2386 | 2415 | { |
2387 | 2416 | if(p_ref->IsMovable()) |
2417 | + { | |
2388 | 2418 | LiftOther(tm, nd); |
2419 | + EnsureValueTags(tm.Tags); | |
2420 | + } | |
2389 | 2421 | else |
2390 | 2422 | { |
2391 | 2423 | auto i(tcon.begin()); |
@@ -2394,6 +2426,7 @@ | ||
2394 | 2426 | { |
2395 | 2427 | i = tcon.emplace(i); |
2396 | 2428 | LiftCopyPropagate(*i, *j, *p_ref); |
2429 | + EnsureValueTags(i->Tags); | |
2397 | 2430 | } |
2398 | 2431 | return; |
2399 | 2432 | } |
@@ -2471,6 +2504,7 @@ | ||
2471 | 2504 | else |
2472 | 2505 | LiftOtherOrCopy(nterm, tm, move); |
2473 | 2506 | #else |
2507 | + AssertValueTags(nterm); | |
2474 | 2508 | // NOTE: Any optimized implemenations shall be equivalent to this. |
2475 | 2509 | if(move) |
2476 | 2510 | LiftOther(nterm, tm); |
@@ -3353,10 +3387,9 @@ | ||
3353 | 3387 | // applicative in %SymbolsToImports, with some optimizations |
3354 | 3388 | // (see below). |
3355 | 3389 | // XXX: Different to %EvaluateIdentifier, identifiers here are |
3356 | - // not used of operator, so %SetupTailOperatorName is not | |
3357 | - // called. | |
3358 | - if(const auto p | |
3359 | - = TryAccessLeafAtom<const TermReference>(bound)) | |
3390 | + // not used as operators, so | |
3391 | + // %ContextState::TrySetTailOperatorName is not called. | |
3392 | + if(const auto p = TryAccessLeafAtom<const TermReference>(bound)) | |
3360 | 3393 | { |
3361 | 3394 | if(p->IsTemporary()) |
3362 | 3395 | LiftOtherOrCopy(nterm, p->get(), p->IsModifiable()); |
@@ -3522,6 +3555,7 @@ | ||
3522 | 3555 | else |
3523 | 3556 | LiftOtherOrCopyPropagateTags(term, tm, |
3524 | 3557 | p_ref->GetTags()); |
3558 | + // XXX: %RegularizeTerm would imply %EnsureValueTags. | |
3525 | 3559 | return ReductionStatus::Retained; |
3526 | 3560 | } |
3527 | 3561 | } |
@@ -3874,6 +3908,7 @@ | ||
3874 | 3908 | LiftOther(term, tm); |
3875 | 3909 | else |
3876 | 3910 | LiftOtherOrCopyPropagateTags(term, tm, p_ref->GetTags()); |
3911 | + // XXX: %RegularizeTerm would imply %EnsureValueTags. | |
3877 | 3912 | return ReductionStatus::Retained; |
3878 | 3913 | }); |
3879 | 3914 | } |
@@ -3924,7 +3959,12 @@ | ||
3924 | 3959 | |
3925 | 3960 | // XXX: As %LiftElementsToReturn. |
3926 | 3961 | for(; first != last && !IsSticky(first->Tags); ++first) |
3927 | - LiftCopyPropagate(tcon.emplace_back(), *first, tags); | |
3962 | + { | |
3963 | + auto& nterm(tcon.emplace_back()); | |
3964 | + | |
3965 | + LiftCopyPropagate(nterm, *first, tags); | |
3966 | + EnsureValueTags(nterm.Tags); | |
3967 | + } | |
3928 | 3968 | // XXX: As %LiftCopyPropagate, with range suffix instead of |
3929 | 3969 | // the subterm container. |
3930 | 3970 | CopyRestContainer(tcon, first, last); |
@@ -4385,15 +4425,13 @@ | ||
4385 | 4425 | ReductionStatus |
4386 | 4426 | Apply(TermNode& term, ContextNode& ctx) |
4387 | 4427 | { |
4388 | - Retain(term); | |
4389 | 4428 | return ApplyImpl(term, ctx); |
4390 | 4429 | } |
4391 | 4430 | |
4392 | 4431 | ReductionStatus |
4393 | 4432 | ApplyList(TermNode& term, ContextNode& ctx) |
4394 | 4433 | { |
4395 | - RetainList(term); | |
4396 | - return ApplyImpl(term, ctx); | |
4434 | + return ApplyImpl(term, ctx, true); | |
4397 | 4435 | } |
4398 | 4436 | |
4399 | 4437 | ReductionStatus |
@@ -4967,6 +5005,31 @@ | ||
4967 | 5005 | }, term); |
4968 | 5006 | } |
4969 | 5007 | |
5008 | +ReductionStatus | |
5009 | +ApplyContinuation(TermNode& term, ContextNode& ctx) | |
5010 | +{ | |
5011 | + RetainN(term, 2); | |
5012 | + | |
5013 | + auto i(term.begin()); | |
5014 | + auto i_comb(++i); | |
5015 | + auto& comb(NPL::Deref(i_comb)); | |
5016 | + | |
5017 | + // NOTE: As %ContinuationToApplicative. | |
5018 | + NPL::ResolveTerm([&](TermNode& nd, ResolvedTermReferencePtr p_ref){ | |
5019 | + WrapO(comb, AccessRegular<Continuation>(nd, p_ref).Handler, p_ref); | |
5020 | + }, comb); | |
5021 | + comb.ClearContainer(); | |
5022 | + // NOTE: As %ApplyImpl. | |
5023 | + ForwardToUnwrapped(comb); | |
5024 | + | |
5025 | + auto t(ConsItem(NPL::Deref(++i))); | |
5026 | + | |
5027 | + t.GetContainerRef().splice(t.begin(), term.GetContainerRef(), i_comb); | |
5028 | + swap(t, term); | |
5029 | + return Combine<TailCall>::RelayEnvSwitch(ctx, term, | |
5030 | + NPL::AllocateEnvironment(term.get_allocator())); | |
5031 | +} | |
5032 | + | |
4970 | 5033 | |
4971 | 5034 | void |
4972 | 5035 | CallSystem(TermNode& term) |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file Font.cpp |
12 | 12 | \ingroup Adaptor |
13 | 13 | \brief 平台无关的字体库。 |
14 | -\version r3682 | |
14 | +\version r3727 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 296 |
17 | 17 | \par 创建时间: |
18 | 18 | 2009-11-12 22:06:13 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2021-12-24 23:50 +0800 | |
20 | + 2022-08-01 19:12 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -27,26 +27,36 @@ | ||
27 | 27 | |
28 | 28 | #include "Helper/YModules.h" |
29 | 29 | #include YFM_YSLib_Adaptor_Font |
30 | -#include YFM_YSLib_Core_YApplication | |
30 | +#include YFM_YSLib_Core_YException // for LoggedEvent; | |
31 | 31 | #include YFM_YSLib_Service_FileSystem |
32 | 32 | #include YFM_Helper_Initialization |
33 | 33 | #include YFM_YCLib_Debug |
34 | 34 | #include <ystdex/deref_op.hpp> // for ystdex::call_value_or; |
35 | 35 | #include <ft2build.h> |
36 | -#include FT_FREETYPE_H | |
37 | -#include FT_CACHE_H | |
38 | -#include FT_SIZES_H | |
39 | -#include FT_BITMAP_H | |
40 | -//#include FT_GLYPH_H | |
41 | -//#include FT_OUTLINE_H | |
42 | -//#include FT_SYNTHESIS_H | |
36 | +#include FT_FREETYPE_H // for ::FT_Matrix, ::FT_Memory; | |
37 | +#include FT_SIZES_H // for ::FT_New_Size, FT_Done::Size; | |
38 | +#include FT_BITMAP_H // for ::FT_GlyphSlot_Own_Bitmap, ::FT_Bitmap_Embolden; | |
39 | +//! \since build 952 | |
40 | +#define YF_Impl_Adaptor_Font_FreeTypeVer \ | |
41 | + (FREETYPE_MAJOR * 10000 + FREETYPE_MINOR * 100 + FREETYPE_PATCH) | |
42 | +// XXX: This is only used when the modified version in "3rdparty" is enabled, | |
43 | +// current only for platform %DS and %MinGW32. | |
43 | 44 | #if defined(FT_CONFIG_OPTION_OLD_INTERNALS) \ |
44 | - && (FREETYPE_MAJOR * 10000 + FREETYPE_MINOR * 100 + FREETYPE_PATCH >= 20500) | |
45 | + && YF_Impl_Adaptor_Font_FreeTypeVer >= 20500 | |
45 | 46 | # define YF_Impl_Use_FT_Internal true |
46 | -# include <freetype/internal/internal.h> // for FreeType internal macros; | |
47 | -# include FT_INTERNAL_TRUETYPE_TYPES_H // for TT_Face, TT_FaceRec_; | |
47 | +// XXX: The internal header <freetype/internal/internal.h> was removed since | |
48 | +// FreeType 2.10.3. (Before that, the macro for the internal header is only | |
49 | +// available when %FT2_BUILD_LIBRARY is defined, so it would still rely on the | |
50 | +// layout which was once changed in FreeType 2.5; although the modified version | |
51 | +// in "3rdparty" always has the known layout and fixed header names.) Thus, the | |
52 | +// header is not used. | |
53 | +# include <freetype/internal/tttypes.h> // for ::TT_Face; | |
48 | 54 | # include <ystdex/type_pun.hpp> // for ystdex::aligned_cast; |
49 | 55 | #endif |
56 | +#include <cstdlib> // for std::malloc, std::free, std::realloc; | |
57 | +#include FT_MODULE_H // for ::FT_New_Library, ::FT_Add_Default_Modules, | |
58 | +// ::FT_Done_Library; | |
59 | +#include <ystdex/string.hpp> // for ystdex::sfmt; | |
50 | 60 | |
51 | 61 | using namespace ystdex; |
52 | 62 | using namespace platform; |
@@ -105,6 +115,8 @@ | ||
105 | 115 | return v >> 6; |
106 | 116 | } |
107 | 117 | |
118 | +// XXX: This should be 'const', but not allowed by the signature of | |
119 | +// %::FT_Set_Transform. | |
108 | 120 | /*! |
109 | 121 | \since build 421 |
110 | 122 | \see ::FT_GlyphSlot_Oblique 实现。 |
@@ -260,6 +272,8 @@ | ||
260 | 272 | // memory handlers are not customized. |
261 | 273 | // NOTE: Be cautious for DLLs. For documented default behavior, see: |
262 | 274 | // http://www.freetype.org/freetype2/docs/design/design-4.html. |
275 | + // This is now implemented in the constructor of %FontCache. | |
276 | + // NOTE: See also $2022-08 @ %Documentation::Workflow. | |
263 | 277 | return; |
264 | 278 | } |
265 | 279 | #undef YSL_Impl_SB_CheckChar |
@@ -277,7 +291,7 @@ | ||
277 | 291 | } |
278 | 292 | Typeface::SmallBitmapData::~SmallBitmapData() |
279 | 293 | { |
280 | - // NOTE: See constructor. | |
294 | + // NOTE: See the notes in the constructor. | |
281 | 295 | std::free(buffer); |
282 | 296 | } |
283 | 297 |
@@ -404,8 +418,25 @@ | ||
404 | 418 | { |
405 | 419 | ::FT_Error error; |
406 | 420 | |
407 | - if(YB_LIKELY((error = ::FT_Init_FreeType(&library)) == 0)) | |
421 | + if(YB_LIKELY((error = [&]{ | |
422 | + // XXX: This should be probably 'const', but not allowed by the | |
423 | + // signature of %::FT_New_Library. Note that exception specifications | |
424 | + // are not allowed by FreeType. | |
425 | + static ::FT_MemoryRec_ mrec{yimpl({}), [](::FT_Memory, long size){ | |
426 | + return std::malloc(size_t(size)); | |
427 | + }, [](::FT_Memory, void* block){ | |
428 | + std::free(block); | |
429 | + }, | |
430 | + [](::FT_Memory, long, long new_size, void* block){ | |
431 | + return ::realloc(block, size_t(new_size)); | |
432 | + }}; | |
433 | + | |
434 | + return ::FT_New_Library(&mrec, &library); | |
435 | + }()) == 0)) | |
436 | + { | |
437 | + ::FT_Add_Default_Modules(library); | |
408 | 438 | YTraceDe(Informative, "FreeType library instance initialized."); |
439 | + } | |
409 | 440 | else |
410 | 441 | // TODO: More precise error message. |
411 | 442 | throw LoggedEvent( |
@@ -415,7 +446,7 @@ | ||
415 | 446 | { |
416 | 447 | mFaces.clear(); |
417 | 448 | mFamilies.clear(); |
418 | - ::FT_Done_FreeType(library); | |
449 | + ::FT_Done_Library(library); | |
419 | 450 | } |
420 | 451 | |
421 | 452 | observer_ptr<const FontFamily> |
@@ -573,5 +604,7 @@ | ||
573 | 604 | |
574 | 605 | } // namespace Drawing; |
575 | 606 | |
607 | +#undef YF_Impl_Adaptor_Font_FreeTypeVer | |
608 | + | |
576 | 609 | } // namespace YSLib; |
577 | 610 |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file ChangeLog.V0.9.txt |
12 | 12 | \ingroup Documentation |
13 | 13 | \brief 版本更新历史记录 - V0.9 。 |
14 | -\version r10497 | |
14 | +\version r10766 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 800 |
17 | 17 | \par 创建时间: |
18 | 18 | 2020-10-12 17:19:23 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-29 03:10 +0800 | |
20 | + 2022-08-15 06:19 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -32,6 +32,201 @@ | ||
32 | 32 | |
33 | 33 | $now |
34 | 34 | ( |
35 | + + $revert_ex(b826) "recovered header %ftmodapi.h from FreeType" | |
36 | + @ "directory %freetype/include/freetype" @ "%3rdparty", | |
37 | + // See $2022-08 @ %Documentation::Workflow. | |
38 | + / %YFramework $= | |
39 | + ( | |
40 | + / %YSLib.YAdaptor.Font $= | |
41 | + ( | |
42 | + / DLDI "simplified internal FreeType version access" ^ "macro", | |
43 | + / "prevented <freetype/internal/internal.h> and \ | |
44 | + %FT_INTERNAL_TRUETYPE_TYPES_H" @ \ | |
45 | + "'defined(FT_CONFIG_OPTION_OLD_INTERNALS)' since FreeType 2.5" | |
46 | + // See $2022-08 @ %Documentation::Workflow. | |
47 | + ( | |
48 | + / @ "class %FontCache" $= | |
49 | + ( | |
50 | + / "initialized %::FT_Library instance" ^ "%::(FT_New_Library, \ | |
51 | + FT_Add_Default_Modules, FT_Done_Library)" | |
52 | + ~ "%::(FT_Init_FreeType, FT_Done_FreeType)" | |
53 | + $dep_from "%3rdparty", | |
54 | + - $comp "the call to %FT_Set_Default_Properties whether \ | |
55 | + FreeType is configured with \ | |
56 | + %FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES" | |
57 | + // See $2022-08 @ %Documentation::Workflow. | |
58 | + ); | |
59 | + * $comp $lib "mismatched deallocation" | |
60 | + @ "destructor %Typeface::SmallBitmapData" $since b420 | |
61 | + // See $2022-08 @ %Documentation::Workflow. | |
62 | + ), | |
63 | + / DLDI "simplified header inclusion" $= | |
64 | + ( | |
65 | + / ^ %YSLib.Core.Exception ~ %YSLib.Core.YApplication, | |
66 | + - "unused FreeType header inclusions" | |
67 | + ) | |
68 | + ), | |
69 | + / %NPL $= | |
70 | + ( | |
71 | + / %SContext $= | |
72 | + ( | |
73 | + + "4 constructors with %TermTags parameters with \ | |
74 | + 'const TermNode&'/'TermNode&&' and optional \ | |
75 | + %allocator_type parameter" @ "class %TermNode", | |
76 | + // Other constructors are not touched, as the \ | |
77 | + simplification of other constructors using new ones \ | |
78 | + would be inefficient. | |
79 | + + "function %IsSingleElementList" | |
80 | + ), | |
81 | + * "missing support irregular representation of reference \ | |
82 | + values to environment" | |
83 | + @ "functions %ResolveEnvironment#(3, 4)" @ %NPLA $since b949 | |
84 | + // The irregular representation was supported since b949 and \ | |
85 | + it could be introduced by interoperations, while the \ | |
86 | + object language devices (non-list trailing sequences in \ | |
87 | + binding constructs) allowing to construct such reference \ | |
88 | + values was supported since b951. | |
89 | + $= (/ $impl ^ "%IsAtom" ~ "%IsExtendedList"), | |
90 | + / %NPLA1 $= | |
91 | + ( | |
92 | + * DD "outdated mentioning of the tail operator name setting \ | |
93 | + function" @ "Doxgyen comment" | |
94 | + @ "function %EvaluateIdentifier" $since b948 | |
95 | + $= (/ "'\sa' command" | |
96 | + ^ 'ContextState::TrySetTailOperatorName' | |
97 | + ~ 'EvaluateIdentifier'), | |
98 | + / ("alias template %GTokenizer", "alias %REPLContext::Loader") | |
99 | + ^ "%ystdex::unchecked_function" ~ "%function", | |
100 | + / DLDI "simplified allocator using" @ "binding with sigil '&'" | |
101 | + @ "functions %(BindParameter, BindParameterWellFormed, \ | |
102 | + BindSymbol)", | |
103 | + * "ill-formed access of non-existing state" @ "trailing \ | |
104 | + sequence matching" @ !'NPL_Impl_NPLA1_AssertParameterMatch' | |
105 | + @ "functions %(MatchParameter, BindParameter, \ | |
106 | + BindParameterWellFormed)" $since b951, | |
107 | + / DLI "simplified static member function \ | |
108 | + %ContextState::DefaultReduceOnce" ^ ($dep_from | |
109 | + ("%IsSingleElementList" @ %SContext), 'YB_PURE'), | |
110 | + * "redundant indirection level of the referent of subpair \ | |
111 | + reference created" @ "trailing bindings with sigil '&'" | |
112 | + @ "functions %(MatchParameter, BindParameter, \ | |
113 | + BindParamaterWellFormed)" $since b951, | |
114 | + / @ "function %CheckVariadicArity" $= | |
115 | + ( | |
116 | + / "%RemoveHead call" | |
117 | + -> ("skipping the 1st subterm" @ "exception message"); | |
118 | + + 'const' @ "term parameter type" | |
119 | + ), | |
120 | + / @ "function %CheckArgumentList" $= | |
121 | + ( | |
122 | + * "missing accepting list with null reference element at \ | |
123 | + end" $since b951 | |
124 | + $= (/ $impl ^ ("%ResolveSuffix" @ %NPLA)), | |
125 | + * "missing supported reference mark" @ "exception message" | |
126 | + $since b951 | |
127 | + ), | |
128 | + * "incorrect results for list with irregular representation of \ | |
129 | + last element" @ "function %FetchArgumentN" $since b951 | |
130 | + ^ "%CountPrefix" ~ "%TermNode::size" | |
131 | + ), | |
132 | + / @ %NPLA1Forms $= | |
133 | + ( | |
134 | + + DLDI "header inclusion <ystdex/functor.hpp>", | |
135 | + / @ "namespace %Forms" $= | |
136 | + ( | |
137 | + / DLDI "simplified function %CheckListReference" | |
138 | + ^ "%ThrowListTypeErrorForNonList", | |
139 | + / DLDI "alternative implementation" @ "functions \ | |
140 | + %ListExtractFirst and other binding functions" | |
141 | + ^ "%AssertValueTags", | |
142 | + // To be consistent with the changes below. | |
143 | + * "missing clear tags for nested list elements from the \ | |
144 | + referent" @ ("functions %(ListContcat, Append)" | |
145 | + $since b912, "function %RestFwd" $since b913, | |
146 | + ("functions %(FoldR1, Map1)") $since b899) | |
147 | + ^ "%EnsureValueTags", | |
148 | + / DLI "simplified reference propagation" @ "functions \ | |
149 | + %(RestFwd, FoldR1, Map1, ListConcat, Append, \ | |
150 | + ListExtractFirst, Let, LetRef, LetWithEnvironment, \ | |
151 | + LetWithEnvironmentRef, LetRec, LetRecRef, LetAsterisk, \ | |
152 | + LetAsteriskRef, BindingsWithParentToEnvironment, \ | |
153 | + BindingsToEnvironment, ProvideLet, Assq, Assv)" | |
154 | + ^ "%LiftPropagatedReference", | |
155 | + / @ "functions %(Apply, ApplyList)" $= | |
156 | + ( | |
157 | + / "checked variadic arguments at first" | |
158 | + ^ $dep_from ("%CheckVariadicArity" @ %NPLA1), | |
159 | + * $comp "missing support irregular representation as \ | |
160 | + the last element in the object parameter" | |
161 | + $since b951 | |
162 | + // Previously the object is a list as %ApplyList \ | |
163 | + not requiring to support the non-list argument. | |
164 | + ), | |
165 | + * "missing checking against improper lists" | |
166 | + @ "function %Apply" $since b951, | |
167 | + // This shall be same to %Apply. Only in one of the \ | |
168 | + argument there are differences. | |
169 | + * "missing checking against non-list 2nd argument" | |
170 | + @ "function %ApplyList" $since b951, | |
171 | + + "function %ApplyContinuation" | |
172 | + ) | |
173 | + ), | |
174 | + / %Dependency $= | |
175 | + ( | |
176 | + / @ "function %LoadGroundContext" $= | |
177 | + ( | |
178 | + / DLDI "alternative derivation" @ "applicative %restv" | |
179 | + ^ '$defl!' ~ '$def%!', | |
180 | + // To be more consistent to 'firstv'. | |
181 | + * "missing forwarding and checking the list parameter" | |
182 | + @ '!NPL_Impl_NPLA1_Use_Id_Vau' @ "alternative derivation" | |
183 | + @ "applicative %rlist" $since b951 | |
184 | + // This is inconsistent to the derivation with \ | |
185 | + 'NPL_Impl_NPLA1_Use_Id_Vau'. | |
186 | + $= (/ $re_ex(b951) | |
187 | + ^ (('forward!' ~ 'move!'), 'check-list-reference')), | |
188 | + * "native implemenation behaviors not same to derivations \ | |
189 | + on syntax error" @ ("applicative %apply" $dep_from | |
190 | + ("%Forms::Apply" @ %NPLA1Forms) $since b859, | |
191 | + @ "applicative %apply" $dep_from | |
192 | + ("%Forms::ApplyList" @ %NPLA1Forms) $since b951) | |
193 | + // The old diagnostics in native implemenations were \ | |
194 | + less clear because the exception message of \ | |
195 | + violation of subterms size check would have no \ | |
196 | + term information at all and such check would come \ | |
197 | + first. | |
198 | + ), | |
199 | + * "unexpectedly moved the 1st argument" | |
200 | + @ "alternative derivation" @ "applicative %require" | |
201 | + @ "function %LoadModule_std_modules" $since b942, | |
202 | + + "applicative 'apply-continuation'" | |
203 | + @ "function %LoadModule_std_continuations" | |
204 | + ^ $dep_from ("function %ApplyContinuation" @ %NPLA1Forms) | |
205 | + ) | |
206 | + ) | |
207 | + ), | |
208 | + / %Tools.Scripts $= | |
209 | + ( | |
210 | + / @ "%SHBuild-BuildApp.txt" $= | |
211 | + ( | |
212 | + / "handled empty SHBOPT_BASE as if a single '.'"; | |
213 | + * $comp "implicit building command line argument implied for \ | |
214 | + SRCPATH in SHBOPT_BASE" $since b900 | |
215 | + // Defferent to the previous shell script, SHBOPT_BASE in this \ | |
216 | + NPLA1 script is optional. The wrong SRCPATH is \ | |
217 | + '-std=c++11'. Now it is default to '.' when empty, but \ | |
218 | + still can be wrong when SHBOPT_BASE only has SHBuild \ | |
219 | + options. | |
220 | + ), | |
221 | + * $comp "possible crashes caused by automatically detected library \ | |
222 | + when external dynamically linked FreeType library is used" | |
223 | + @ !"platform %(DS, MinGW32, Android)" $since b563 | |
224 | + // See $2022-08 @ %Documentation::Workflow. | |
225 | + ) | |
226 | +), | |
227 | + | |
228 | +b951 | |
229 | +( | |
35 | 230 | / %YFramework.NPL $= |
36 | 231 | ( |
37 | 232 | / %NPLA1 $= |
@@ -214,85 +409,81 @@ | ||
214 | 409 | @ "functions %(BindParameter, BindParameterWellFormed)" @ %NPLA1, |
215 | 410 | ("functions %Forms::(Cons, ListAsterisk, RestVal, SetRest)" |
216 | 411 | @ %NPLA1Forms) ^ ("%LiftPrefixToReturn" @ %NPLA)), |
217 | - / %Dependency $= | |
218 | - ( | |
219 | - / @ "function %LoadGroundContext" $= | |
220 | - ( | |
221 | - + "applicative 'check-pair-reference'" | |
222 | - ^ $dep_from ("%Forms::CheckPairReference" @%NPLA1Forms), | |
223 | - / "supported pairs" @ "applicatives ('first@', 'first&', \ | |
224 | - 'rest&')" $= | |
225 | - ( | |
226 | - / $comp "native implementation" $dep_from ("functions \ | |
227 | - %Forms::(FirstAt, FirstRef, RestRef)" @ %NPLA1Forms), | |
228 | - / "alternative derivations" ^ $dep_from | |
229 | - 'check-pair-reference' ~ 'check-list-reference' | |
230 | - ), | |
231 | - / "supported returning reference values" | |
232 | - @ "applicatives ('rest%', %restv)" $= | |
233 | - ( | |
234 | - / $comp "native implementation" | |
235 | - $dep_from ("%Forms::(RestFwd, RestVal)" @ %NPLA1Forms), | |
236 | - / "alternative derivations" | |
237 | - ^ ('$defl%!' ~ '$defl!', '$move-resolved!' ~ 'move!') | |
238 | - // To allow reference to reference, 'restv' also make \ | |
239 | - the result forwarded, as 'idv'. '$move-resolved!' \ | |
240 | - is necessary for 'restv' whose parameter has no \ | |
241 | - sigil in the derivation, and also good for 'rest%'. | |
242 | - ), | |
243 | - ( | |
244 | - / $comp "accepted empty lists" | |
245 | - @ "applicative 'check-list-reference'" | |
246 | - $dep_from ("%Forms::CheckListReference" @ %NPLA1Forms); | |
247 | - / DLDI "checked the list parameter" @ "derivations" | |
248 | - @ "applicatives (%(rlist, foldr1, rulist), 'map-reverse')" | |
249 | - ^ 'check-list-reference' | |
250 | - $dep_to "adding list checks", | |
251 | - // This is nothing different without the changes in the \ | |
252 | - support pairs of variable binding. | |
253 | - / $forced DLDI "checked parameter to ensure list" | |
254 | - $dep_from "cons reference" @ "alternative derivation" | |
255 | - @ "applicative 'list-push-front!'" | |
256 | - $= (/ $impl ^ 'check-list-reference') | |
257 | - ), | |
258 | - / $comp "supported pairs as argument" @ "applicatives \ | |
259 | - (%(first, firstv, restv), 'first&', 'first%', 'rest&')" $= | |
260 | - ( | |
261 | - / "native implementation" $dep_from | |
262 | - "pair handling in native implementations", | |
263 | - / "alternative derivations" @ ("trailing bindings" @ %NPLA1) | |
264 | - ) | |
265 | - / $comp "supported forwarding non-list argument" | |
266 | - @ "applicative %apply" $dep_from ("cons reference", | |
267 | - "%ContextState::DefaultReduceOnce" @ %NPLA1), | |
268 | - / DLDI "reordered alternative derivation" | |
269 | - @ "applicative %apply before operative '$sequence'", | |
270 | - // Now 'apply' is more fundamental. | |
271 | - / $re_add(b950) "forward parameter" @ "alternative derivation" | |
272 | - @ "applicative 'rlist'" ^ 'forward!' ~ 'move!' | |
273 | - $dep_to "forwarding trailing", | |
274 | - // This is no change even when the traling sequence is a \ | |
275 | - reference, since the bound referent is in the \ | |
276 | - irregular representation. However, it is relied on by \ | |
277 | - the change of trailing binding conceptually. | |
278 | - ( | |
279 | - + "applicative 'list?'; | |
280 | - + "applicative 'apply-list'" | |
281 | - $dep_from ("%Forms::ApplyList" @ %NPLA1Forms); | |
282 | - / $forced DLI "checked against non-list arugment alternative \ | |
283 | - derivations" @ ("operative '$sequence'" $dep_from | |
284 | - ("%Forms::Sequence" @ %NPLA1Forms), "operative '$cond'" | |
285 | - $dep_from ("%Forms::Cond" @ %NPLA1Forms)) | |
286 | - // The check to ensure the combination having an argument \ | |
287 | - list is before the actual access in the old \ | |
288 | - implementation. It is necessary for the correct \ | |
289 | - behavior of side effects and the exception message \ | |
290 | - ("expect a list" instead of "expect a pair"). | |
291 | - $= (/ $impl ^ 'apply-list') | |
292 | - ), | |
293 | - / DLI "simplified alternative derivation" | |
294 | - @ "applicative 'equal?'" | |
295 | - ) | |
412 | + / %Dependency @ "function %LoadGroundContext" $= | |
413 | + ( | |
414 | + + "applicative 'check-pair-reference'" | |
415 | + ^ $dep_from ("%Forms::CheckPairReference" @%NPLA1Forms), | |
416 | + / "supported pairs" @ "applicatives ('first@', 'first&', 'rest&')" | |
417 | + $= | |
418 | + ( | |
419 | + / $comp "native implementation" $dep_from ("functions \ | |
420 | + %Forms::(FirstAt, FirstRef, RestRef)" @ %NPLA1Forms), | |
421 | + / "alternative derivations" ^ $dep_from | |
422 | + 'check-pair-reference' ~ 'check-list-reference' | |
423 | + ), | |
424 | + / "supported returning reference values" | |
425 | + @ "applicatives ('rest%', %restv)" $= | |
426 | + ( | |
427 | + / $comp "native implementation" | |
428 | + $dep_from ("%Forms::(RestFwd, RestVal)" @ %NPLA1Forms), | |
429 | + / "alternative derivations" | |
430 | + ^ ('$defl%!' ~ '$defl!', '$move-resolved!' ~ 'move!') | |
431 | + // To allow reference to reference, 'restv' also make the \ | |
432 | + result forwarded, as 'idv'. '$move-resolved!' is \ | |
433 | + necessary for 'restv' whose parameter has no sigil in \ | |
434 | + the derivation, and also good for 'rest%'. | |
435 | + ), | |
436 | + ( | |
437 | + / $comp "accepted empty lists" | |
438 | + @ "applicative 'check-list-reference'" | |
439 | + $dep_from ("%Forms::CheckListReference" @ %NPLA1Forms); | |
440 | + / DLDI "checked the list parameter" @ "derivations" | |
441 | + @ "applicatives (%(rlist, foldr1, rulist), 'map-reverse')" | |
442 | + ^ 'check-list-reference' $dep_to "adding list checks", | |
443 | + // This is nothing different without the changes in the \ | |
444 | + support pairs of variable binding. | |
445 | + / $forced DLDI "checked parameter to ensure list" | |
446 | + $dep_from "cons reference" @ "alternative derivation" | |
447 | + @ "applicative 'list-push-front!'" | |
448 | + $= (/ $impl ^ 'check-list-reference') | |
449 | + ), | |
450 | + / $comp "supported pairs as argument" @ "applicatives (%(first, \ | |
451 | + firstv, restv), 'first&', 'first%', 'rest&')" $= | |
452 | + ( | |
453 | + / "native implementation" | |
454 | + $dep_from "pair handling in native implementations", | |
455 | + / "alternative derivations" @ ("trailing bindings" @ %NPLA1) | |
456 | + ), | |
457 | + / $comp "supported forwarding non-list argument" | |
458 | + @ "applicative %apply" $dep_from ("cons reference", | |
459 | + "%ContextState::DefaultReduceOnce" @ %NPLA1), | |
460 | + / DLDI "reordered alternative derivation" | |
461 | + @ "applicative %apply before operative '$sequence'", | |
462 | + // Now 'apply' is more fundamental. | |
463 | + / $re_add(b950) "forward parameter" @ "alternative derivation" | |
464 | + @ "applicative 'rlist'" ^ 'forward!' ~ 'move!' | |
465 | + $dep_to "forwarding trailing", | |
466 | + // This is no change even when the traling sequence is a \ | |
467 | + reference, since the bound referent is in the \ | |
468 | + irregular representation. However, it is relied on by \ | |
469 | + the change of trailing binding conceptually. | |
470 | + ( | |
471 | + + "applicative 'list?'; | |
472 | + + "applicative 'apply-list'" | |
473 | + $dep_from ("%Forms::ApplyList" @ %NPLA1Forms); | |
474 | + / $forced DLI "checked against non-list arugment alternative \ | |
475 | + derivations" @ ("operative '$sequence'" $dep_from | |
476 | + ("%Forms::Sequence" @ %NPLA1Forms), "operative '$cond'" | |
477 | + $dep_from ("%Forms::Cond" @ %NPLA1Forms)) | |
478 | + // The check to ensure the combination having an argument \ | |
479 | + list is before the actual access in the old \ | |
480 | + implementation. It is necessary for the correct \ | |
481 | + behavior of side effects and the exception message \ | |
482 | + ("expect a list" instead of "expect a pair"). | |
483 | + $= (/ $impl ^ 'apply-list') | |
484 | + ), | |
485 | + / DLI "simplified alternative derivation" | |
486 | + @ "applicative 'equal?'" | |
296 | 487 | ) |
297 | 488 | ), |
298 | 489 | * $comp "missing non-empty list condition" @ "description of applicative \ |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file Definitions.txt |
12 | 12 | \ingroup Documentation |
13 | 13 | \brief 方法和公共域定义与说明。 |
14 | -\version r14460 | |
14 | +\version r14477 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since 早于 build 132 |
17 | 17 | \par 创建时间: |
18 | 18 | 2010-01-26 19:34:51 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-06-29 08:34 +0800 | |
20 | + 2022-08-01 19:02 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -692,6 +692,14 @@ | ||
692 | 692 | { |
693 | 693 | static recursive_mutex mtx; |
694 | 694 | } |
695 | + | |
696 | +$unit Font | |
697 | +{ | |
698 | +FontCache::FontCache(size_t) | |
699 | +{ | |
700 | + static ::FT_MemoryRec_ mrec; | |
701 | +} | |
702 | +} | |
695 | 703 | } |
696 | 704 | |
697 | 705 | $unit Image |
@@ -835,6 +843,19 @@ | ||
835 | 843 | $dir YSLib |
836 | 844 | { |
837 | 845 | |
846 | +$dir Adaptor | |
847 | +{ | |
848 | + | |
849 | +$unit Font | |
850 | +{ | |
851 | +namespace | |
852 | +{ | |
853 | +::FT_Matrix italic_matrix; | |
854 | +} | |
855 | +} | |
856 | + | |
857 | +} | |
858 | + | |
838 | 859 | $dir Core |
839 | 860 | { |
840 | 861 |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file NPL.txt |
12 | 12 | \ingroup Documentation |
13 | 13 | \brief NPL 规范和实现规格说明。 |
14 | -\version r29342 | |
14 | +\version r29354 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 304 |
17 | 17 | \par 创建时间: |
18 | 18 | 2012-04-25 10:34:20 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-07-28 12:09 +0800 | |
20 | + 2022-08-15 03:33 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -2813,6 +2813,8 @@ | ||
2813 | 2813 | 按以上基本分类和第一个子项(若存在)的粘滞位(@6.2.2) ,提供以下扩展分类谓词: |
2814 | 2814 | IsAtom |
2815 | 2815 | IsPair |
2816 | +判断特定结构的列表可使用以下谓词: | |
2817 | +IsSingleElementList | |
2816 | 2818 | 判断值数据成员(@6.2) 具有的类型或值的模板以 Is 或 Has 起始: |
2817 | 2819 | IsTyped |
2818 | 2820 | IsTypedRegular |
@@ -5885,10 +5887,11 @@ | ||
5885 | 5887 | Forms::FoldR1 和 Forms::Map1 当前可使用不在对象语言中的右值的表示中支持的标签(@6.2.2.1) 。 |
5886 | 5888 | |
5887 | 5889 | @8.4.10 一等续延支持: |
5890 | +一等续延的实现依赖实现选项 NPL_Impl_NPLA1_Enable_Thunked 启用异步规约(@7.9.2) ,否则应用续延的行为未定义。 | |
5888 | 5891 | Forms 提供以下在对象语言中实现一等续延(@4.5.3.3) 相关操作: |
5889 | 5892 | Forms::Call1CC |
5890 | 5893 | Forms::ContinuationToApplicative |
5891 | -一等续延的实现依赖实现选项 NPL_Impl_NPLA1_Enable_Thunked 启用异步规约(@7.9.2) ,否则应用续延的行为未定义。 | |
5894 | +Forms::ApplyContinuation | |
5892 | 5895 | |
5893 | 5896 | @8.4.11 外部调用: |
5894 | 5897 | Forms 提供以下在对象语言中调用实现环境外部功能的函数: |
@@ -8057,9 +8060,9 @@ | ||
8057 | 8060 | 不直接使用本机实现的替代实现仅供参考,可能引入和本机实现不同的未指定行为(如子对象(@9.8.2) 的生存期(@5.6.6) 不同),且可能有和核心特性实现相关的限制,包括: |
8058 | 8061 | 以下不同实现可引起不同的诊断: |
8059 | 8062 | 由合并子调用的参数绑定(@8.4.5.3) 引起(@9.5.1) 的静态语法错误(@9.5.1) 。 |
8060 | - 类型检查(@9.5.4.1) 可具有不同的顺序而引起不同的类型错误。 | |
8061 | - 对要求为列表的参数的类型检查中的诊断消息(@1.2.4) 可能指示对象或其子对象不符合要求。 | |
8062 | - 列表元素检查的错误中的诊断消息。 | |
8063 | + 类型检查(@9.5.4.1) 可具有不同的顺序而引起不同的类型错误(@9.5.4.1) 。 | |
8064 | + 类型错误中关于元素的表示的诊断消息可能不同。 | |
8065 | + 例如,对要求为列表的参数的类型检查中的诊断消息(@1.2.4) 可能指示对象或其子对象不符合要求。 | |
8063 | 8066 | 使用 TCO 实现 PTC(@9.7.4) ,可能具有不同的支持(@9.7.4.1) 和实现(如 TCO 动作消除(@7.10.9) )。 |
8064 | 8067 | 操作的语义允许时,操作的结果和作用(@10.3.1) 引起改变的对象中可包含符合具体操作的约定的未指定值(但不含没有附加限制条件的未指定值(@10.7.2.3) )。 |
8065 | 8068 | 没有明确指定时,创建的对象的具体内部表示及其宿主类型。 |
@@ -8471,6 +8474,9 @@ | ||
8471 | 8474 | 捕获的续延之后允许被复制。 |
8472 | 8475 | continuation->applicative <continuation> :转换续延为应用子。 |
8473 | 8476 | 结果是转换的 <applicative> 类型的值。调用这个值蕴含以相同参数对参数指定的续延的调用。 |
8477 | +apply-continuation <continuation> <object> :应用续延。 | |
8478 | +以第二参数作为参数,以 apply 应用第一参数指定的续延转换的应用子,即同求值: | |
8479 | +apply (apply-continuation <continuation>) <object> | |
8474 | 8480 | **原理** |
8475 | 8481 | 类似 Kernel 语言,NPLA1 续延不是合并子。这一设计的基本原理参见 [RnRK] §7 ,但理由不充分。更完整的分析如下: |
8476 | 8482 | 使用守卫选择子(guard selector) 是 Kernel 的具体特性的设计,不是一般求值算法中蕴含需要实现的选项,因此仅在 [RnRK] 内部生效。 |
@@ -8545,10 +8551,12 @@ | ||
8545 | 8551 | 在 [RnRK] ,正常程序运行的顶层续延界限以 root-continuation 提供。此外,提供 error-continuation 处理错误。 |
8546 | 8552 | 在完善的设计中,提供一个顶层的续延界限并非困难。因此,可能缺少取得续延界限的方法的问题不是核心困难。此外,如 [RnRK] 的 error-continuation 显示了其它类似的续延的实用性。 |
8547 | 8553 | 类似的特性可能会被加入此处的设计中 NPLA1 。 |
8554 | +同 [RnRK] ,apply-continuation 不接受可选的环境,因为非正常控制忽略动态环境。 | |
8548 | 8555 | **注释** |
8549 | 8556 | call1/cc 的名称来自 https://legacy.cs.indiana.edu/~dyb/pubs/call1cc.pdf ,同 Chez Scheme 。 |
8550 | 8557 | 类似 Kernel 而不同于 Scheme ,续延具有单独的类型,续延应用也不是蕴含过程调用的函数应用。 |
8551 | 8558 | 另见关于一次调用检查的实现(@7.4.2.1) 。 |
8559 | +apply-continuation 同 [RnRK] 。取得非 <list> 结果依赖 apply 对 <pair> 的支持,这在 Scheme 中无法实现。 | |
8552 | 8560 | |
8553 | 8561 | @12.2 代理求值: |
8554 | 8562 | 通过初始化基础上下文后调用 Forms::LoadModule_std_promises(@8.5.2) 初始化,默认加载为根环境下的 std.promises 环境。 |
@@ -11,13 +11,13 @@ | ||
11 | 11 | /*! \file Workflow.txt |
12 | 12 | \ingroup Documentation |
13 | 13 | \brief 工作流汇总报告。 |
14 | -\version r4958 | |
14 | +\version r4995 | |
15 | 15 | \author FrankHB <frankhb1989@gmail.com> |
16 | 16 | \since build 433 |
17 | 17 | \par 创建时间: |
18 | 18 | 2013-07-31 01:27:41 +0800 |
19 | 19 | \par 修改时间: |
20 | - 2022-06-14 18:57 +0800 | |
20 | + 2022-08-03 02:58 +0800 | |
21 | 21 | \par 文本编码: |
22 | 22 | UTF-8 |
23 | 23 | \par 模块名称: |
@@ -249,7 +249,7 @@ | ||
249 | 249 | The reference-counted 'std::basic_string' implementation in libstdc++ is still not conforming to ISO C++11. |
250 | 250 | See $2013-10 report.impl. |
251 | 251 | See $ref b449 "libstdc++ std::basic_string conformance" for references. |
252 | - Though ABI has changed before, the string implementation is not included, and even other breaking changes like 'std::list::size' implementation are reverted: http://gcc.gnu.org/wiki/Cxx11AbiCompatibility. | |
252 | + Though the ABI has changed before, the string implementation is not included, and even other breaking changes like 'std::list::size' implementation are reverted: http://gcc.gnu.org/wiki/Cxx11AbiCompatibility. | |
253 | 253 | It seems that the ABI would not switched in near future, or at early as of GCC 4.9: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56166. |
254 | 254 | Use libstdc++ '__gnu_cxx::__versa_string' from <ext/vstring.h> instead, if necessary. |
255 | 255 | See $2013-10 report.impl. |
@@ -4893,5 +4893,43 @@ | ||
4893 | 4893 | Similar calls out of the NPL implementation and calls like 'YSLib::make_observer' are also subjected to the cleanup. |
4894 | 4894 | To make the changes in the current revision neat, the changes are planned in future. |
4895 | 4895 | |
4896 | +$2022-08: | |
4897 | + | |
4898 | +report.impl: | |
4899 | +A bug in YSLib Font module of deallocating small bitmap memory has been fixed. | |
4900 | + This is caused directly by mismatching of 'std::free' call from the allocation calls in the FreeType implementation. | |
4901 | + The bug will typically cause application crash for dynamically linked FreeType with different source of allocations, e.g. Windows DLLs. | |
4902 | + It is known and acknowledged but it is not a breking bug since build 420 because there are no such configurations using dynamically linked FreeType. | |
4903 | + This is not totally true now, since there can be external binary FreeType library used mixing with the shipped modified headers located in the top-level directory "3rdparty". | |
4904 | + For MinGW platforms, FreeType headers in "3rdparty" are used. Otherwise, since build 563, the headers are detected via 'pkg-config' detection of "freetype2" instead of "3rdparty" one. | |
4905 | + The detection in YFramework building is implemented in the NPLA1 script "Tools/Scripts/SHBuild-YSLib-build.txt". | |
4906 | + The detection of pre-built binary files is derived from the shell script "Tools/install-sysroot.sh" since build 838. | |
4907 | + The similar logic for application building is implemented in the NPLA1 script "Tools/Scripts/SHBuild-BuildApp.txt", which also detects the existense of static library deployed in the YSLib Sysroot installation (basically same to the pre-built libraries). | |
4908 | + The detection of pre-built binary files is derived from the shell script "Tools/Scripts/SHBuild-BuildApp.sh" since build 885. | |
4909 | + The pre-built FreeType binary library images are official available only for "arm-ds-eabi", "i686-w64-mingw32" and "arm-linux-androideabi" targets. | |
4910 | + Platform MinGW32 uses the shipped modified version and statically links to the library, so it should not be affected. | |
4911 | + However, there can be some bit subtle configurations for other platforms, like MSYS2 with package "mingw64/mingw-w64-x86_64-freetype" installed. | |
4912 | + Because there are no pre-built binary FreeType library used for these platforms, this would use the system FreeType library, which is dynamically link to libFramework. | |
4913 | + Otherwise, having dynamically linked FreeType are not formally supported unitl now (esp. platform MinGW64). | |
4914 | + The change now also fix for these cases. | |
4915 | + To implemented the change, '::FT_New_libaray' is used instead '::FT_Init_FreeType' as well as some other calls, as suggested in http://www.freetype.org/freetype2/docs/design/design-4.html. | |
4916 | + As a result, parsing of the 'FREETYPE_PROPERTIES' environment variable is no longer performed even when the the library is configured with 'FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES'. | |
4917 | + This is more efficient by default, at the cost of not supporting the 'FREETYPE_PROPERTIES' environment variable. | |
4918 | + However, the feature was introduced in 2.6.5 and never relied on by the modified build in YFramework, so it should be OK in most cases. | |
4919 | + API allowing direct hack on internal '::FT_Library' by dedicated FreeType library calls to recover the old behavior is possible, but not provided at current. | |
4920 | + The calls need header <freetype/ftmodapi.h> is needed. | |
4921 | + The file is directly reverted from build 826, as there are no real differences to the current newest release (2.12.1) except that some macro checks change since 2.10.3 (see below) which is not relied on here. | |
4922 | + Besides the change above, there is also a bit cleanup on the internal headers of modified "3rdparty" version (configured with 'FT_CONFIG_OPTION_OLD_INTERNALS') used. | |
4923 | + Notably, <freetype/internal/internal.h> and 'FT_INTERNAL_TRUETYPE_TYPES_H' are no longer used. | |
4924 | + Instead, <freetype/internal/tttypes.h> is used directly. | |
4925 | + This is neutral to the directory layout change of headers in FreeType 2.5.1 (but laterly reverted in 2.6.1), because the layout is fixed in "3rdparty". | |
4926 | + See https://sourceforge.net/projects/freetype/files/freetype2/2.5.1/. | |
4927 | + See https://sourceforge.net/projects/freetype/files/freetype2/2.6.1/. | |
4928 | + See also http://lists.nongnu.org/archive/html/freetype-devel/2015-06/msg00041.html. | |
4929 | + The cleanup is compatible to newer FreeType, which has removed the internal header since 2.10.3. | |
4930 | + See https://sourceforge.net/projects/freetype/files/freetype2/2.10.3/. | |
4931 | + FreeType still support external header names named by macros for compatibility, so there are no other changes needed for public header inclusions. | |
4932 | + This is neutral to the directory layout change of headers in FreeType 2.5.1, as stated in the release notes (see above). | |
4933 | + | |
4896 | 4934 | //// |
4897 | 4935 |