• R/O
  • SSH

YSLib: Commit

The YSLib project - main repository


Commit MetaInfo

Revisiona0edf9d1c9a2ea1c7d864087c57556f7cf0e7ff2 (tree)
Zeit2021-11-19 07:25:50
AutorFrankHB <frankhb1989@gmai...>
CommiterFrankHB

Log Message

更新主分支版本: build 931 rev 10 。

Ändern Zusammenfassung

Diff

diff -r 91142b01d66f -r a0edf9d1c9a2 Tools/CreationTimeManager/CreationTimeManager.vcxproj
--- a/Tools/CreationTimeManager/CreationTimeManager.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/Tools/CreationTimeManager/CreationTimeManager.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -19,14 +19,14 @@
1919 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'" Label="Configuration">
2020 <ConfigurationType>Application</ConfigurationType>
2121 <UseDebugLibraries>true</UseDebugLibraries>
22- <PlatformToolset>v142</PlatformToolset>
22+ <PlatformToolset>v143</PlatformToolset>
2323 </PropertyGroup>
2424 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
2525 <ConfigurationType>Application</ConfigurationType>
2626 <UseDebugLibraries>false</UseDebugLibraries>
2727 <WholeProgramOptimization>true</WholeProgramOptimization>
2828 <CharacterSet>NotSet</CharacterSet>
29- <PlatformToolset>v142</PlatformToolset>
29+ <PlatformToolset>v143</PlatformToolset>
3030 </PropertyGroup>
3131 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
3232 <ImportGroup Label="ExtensionSettings">
diff -r 91142b01d66f -r a0edf9d1c9a2 Tools/PredefinedMacroDetector/PredefinedMacroDetector.vcxproj
--- a/Tools/PredefinedMacroDetector/PredefinedMacroDetector.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/Tools/PredefinedMacroDetector/PredefinedMacroDetector.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -20,14 +20,14 @@
2020 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'" Label="Configuration">
2121 <ConfigurationType>Application</ConfigurationType>
2222 <UseDebugLibraries>true</UseDebugLibraries>
23- <PlatformToolset>v142</PlatformToolset>
23+ <PlatformToolset>v143</PlatformToolset>
2424 </PropertyGroup>
2525 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
2626 <ConfigurationType>Application</ConfigurationType>
2727 <UseDebugLibraries>false</UseDebugLibraries>
2828 <WholeProgramOptimization>true</WholeProgramOptimization>
2929 <CharacterSet>Unicode</CharacterSet>
30- <PlatformToolset>v142</PlatformToolset>
30+ <PlatformToolset>v143</PlatformToolset>
3131 </PropertyGroup>
3232 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
3333 <ImportGroup Label="ExtensionSettings">
diff -r 91142b01d66f -r a0edf9d1c9a2 Tools/SHBuild/SHBuild.vcxproj
--- a/Tools/SHBuild/SHBuild.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/Tools/SHBuild/SHBuild.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -23,13 +23,13 @@
2323 <ConfigurationType>Application</ConfigurationType>
2424 <UseDebugLibraries>true</UseDebugLibraries>
2525 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
26- <PlatformToolset>v142</PlatformToolset>
26+ <PlatformToolset>v143</PlatformToolset>
2727 </PropertyGroup>
2828 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
2929 <ConfigurationType>Application</ConfigurationType>
3030 <UseDebugLibraries>false</UseDebugLibraries>
3131 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
32- <PlatformToolset>v142</PlatformToolset>
32+ <PlatformToolset>v143</PlatformToolset>
3333 <WholeProgramOptimization>true</WholeProgramOptimization>
3434 </PropertyGroup>
3535 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
diff -r 91142b01d66f -r a0edf9d1c9a2 YBase/Android/YBase_Android.vcxproj
--- a/YBase/Android/YBase_Android.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YBase/Android/YBase_Android.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -21,12 +21,12 @@
2121 </PropertyGroup>
2222 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2323 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
24- <PlatformToolset>v142</PlatformToolset>
24+ <PlatformToolset>v143</PlatformToolset>
2525 <ConfigurationType>Makefile</ConfigurationType>
2626 <UseDebugLibraries>true</UseDebugLibraries>
2727 </PropertyGroup>
2828 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM'" Label="Configuration">
29- <PlatformToolset>v142</PlatformToolset>
29+ <PlatformToolset>v143</PlatformToolset>
3030 <ConfigurationType>Makefile</ConfigurationType>
3131 <UseDebugLibraries>false</UseDebugLibraries>
3232 </PropertyGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YBase/DS/YBase_DS.vcxproj
--- a/YBase/DS/YBase_DS.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YBase/DS/YBase_DS.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -21,12 +21,12 @@
2121 </PropertyGroup>
2222 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2323 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
24- <PlatformToolset>v142</PlatformToolset>
24+ <PlatformToolset>v143</PlatformToolset>
2525 <ConfigurationType>Makefile</ConfigurationType>
2626 <UseDebugLibraries>true</UseDebugLibraries>
2727 </PropertyGroup>
2828 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM'" Label="Configuration">
29- <PlatformToolset>v142</PlatformToolset>
29+ <PlatformToolset>v143</PlatformToolset>
3030 <ConfigurationType>Makefile</ConfigurationType>
3131 <UseDebugLibraries>false</UseDebugLibraries>
3232 </PropertyGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YBase/YBase.vcxproj
--- a/YBase/YBase.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YBase/YBase.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -125,13 +125,13 @@
125125 <ConfigurationType>StaticLibrary</ConfigurationType>
126126 <UseDebugLibraries>true</UseDebugLibraries>
127127 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
128- <PlatformToolset>v142</PlatformToolset>
128+ <PlatformToolset>v143</PlatformToolset>
129129 </PropertyGroup>
130130 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
131131 <ConfigurationType>StaticLibrary</ConfigurationType>
132132 <UseDebugLibraries>false</UseDebugLibraries>
133133 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
134- <PlatformToolset>v142</PlatformToolset>
134+ <PlatformToolset>v143</PlatformToolset>
135135 </PropertyGroup>
136136 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
137137 <ImportGroup Label="ExtensionSettings">
diff -r 91142b01d66f -r a0edf9d1c9a2 YBase/include/ystdex/functor.hpp
--- a/YBase/include/ystdex/functor.hpp Thu Nov 11 18:37:42 2021 +0800
+++ b/YBase/include/ystdex/functor.hpp Fri Nov 19 06:25:50 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2010-2020 FrankHB.
2+ © 2010-2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file functor.hpp
1212 \ingroup YStandardEx
1313 \brief 通用仿函数。
14-\version r987
14+\version r996
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 588
1717 \par 创建时间:
1818 2015-03-29 00:35:44 +0800
1919 \par 修改时间:
20- 2020-07-17 01:19 +0800
20+ 2021-11-11 20:31 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -78,7 +78,6 @@
7878
7979 /*! \defgroup functors General Functors
8080 \brief 仿函数。
81-\warning 可能非虚析构。
8281 \note 函数对象包含函数指针和仿函数。
8382 \warning 其中的类类型一般可被继承但非虚析构。
8483 \since build 243
@@ -385,11 +384,18 @@
385384 \
386385 YB_Impl_Functor_Ops_Spec_Ptr(_n)
387386
387+#if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
388+ YB_Diag_Push
389+ YB_Diag_Ignore(float-equal)
390+#endif
388391 //! \brief 等于关系仿函数。
389392 YB_Impl_Functor_bool(equal_to, ==)
390393
391394 //! \brief 不等于关系仿函数。
392395 YB_Impl_Functor_bool(not_equal_to, !=)
396+#if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
397+ YB_Diag_Pop
398+#endif
393399
394400 //! \brief 大于关系仿函数。
395401 YB_Impl_Functor_bool_Ordered(greater, >)
diff -r 91142b01d66f -r a0edf9d1c9a2 YBase/include/ystdex/type_traits.hpp
--- a/YBase/include/ystdex/type_traits.hpp Thu Nov 11 18:37:42 2021 +0800
+++ b/YBase/include/ystdex/type_traits.hpp Fri Nov 19 06:25:50 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2011-2019 FrankHB.
2+ © 2011-2019, 2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file type_traits.hpp
1212 \ingroup YStandardEx
1313 \brief ISO C++ 类型特征扩展。
14-\version r2030
14+\version r2038
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 201
1717 \par 创建时间:
1818 2015-11-04 09:34:17 +0800
1919 \par 修改时间:
20- 2019-09-13 13:43 +0800
20+ 2021-11-11 20:32 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -91,11 +91,18 @@
9191 template<typename _type, typename _type2>
9292 using subscript_t = decltype(std::declval<_type>()[std::declval<_type2>()]);
9393
94+#if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
95+ YB_Diag_Push
96+ YB_Diag_Ignore(float-equal)
97+#endif
9498 template<typename _type, typename _type2 = _type>
9599 using equal_t = decltype(std::declval<_type>() == std::declval<_type2>());
96100
97101 template<typename _type, typename _type2 = _type>
98102 using not_equal_t = decltype(std::declval<_type>() != std::declval<_type2>());
103+#if YB_IMPL_GNUCPP || YB_IMPL_CLANGPP
104+ YB_Diag_Pop
105+#endif
99106 //@}
100107
101108
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/Android/YFramework_Android.vcxproj
--- a/YFramework/Android/YFramework_Android.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/Android/YFramework_Android.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -31,12 +31,12 @@
3131 </PropertyGroup>
3232 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
3333 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
34- <PlatformToolset>v142</PlatformToolset>
34+ <PlatformToolset>v143</PlatformToolset>
3535 <ConfigurationType>Makefile</ConfigurationType>
3636 <UseDebugLibraries>true</UseDebugLibraries>
3737 </PropertyGroup>
3838 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM'" Label="Configuration">
39- <PlatformToolset>v142</PlatformToolset>
39+ <PlatformToolset>v143</PlatformToolset>
4040 <ConfigurationType>Makefile</ConfigurationType>
4141 <UseDebugLibraries>false</UseDebugLibraries>
4242 </PropertyGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/DS/YFramework_DS.vcxproj
--- a/YFramework/DS/YFramework_DS.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/DS/YFramework_DS.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -24,12 +24,12 @@
2424 </PropertyGroup>
2525 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2626 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
27- <PlatformToolset>v142</PlatformToolset>
27+ <PlatformToolset>v143</PlatformToolset>
2828 <ConfigurationType>Makefile</ConfigurationType>
2929 <UseDebugLibraries>true</UseDebugLibraries>
3030 </PropertyGroup>
3131 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM'" Label="Configuration">
32- <PlatformToolset>v142</PlatformToolset>
32+ <PlatformToolset>v143</PlatformToolset>
3333 <ConfigurationType>Makefile</ConfigurationType>
3434 <UseDebugLibraries>false</UseDebugLibraries>
3535 </PropertyGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/MinGW32/YFramework_MinGW32.vcxproj
--- a/YFramework/MinGW32/YFramework_MinGW32.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/MinGW32/YFramework_MinGW32.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -19,13 +19,13 @@
1919 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|Win32'" Label="Configuration">
2020 <ConfigurationType>Makefile</ConfigurationType>
2121 <UseDebugLibraries>true</UseDebugLibraries>
22- <PlatformToolset>v142</PlatformToolset>
22+ <PlatformToolset>v143</PlatformToolset>
2323 <CharacterSet>MultiByte</CharacterSet>
2424 </PropertyGroup>
2525 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
2626 <ConfigurationType>Makefile</ConfigurationType>
2727 <UseDebugLibraries>false</UseDebugLibraries>
28- <PlatformToolset>v142</PlatformToolset>
28+ <PlatformToolset>v143</PlatformToolset>
2929 <WholeProgramOptimization>true</WholeProgramOptimization>
3030 <CharacterSet>MultiByte</CharacterSet>
3131 </PropertyGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/YFramework.vcxproj
--- a/YFramework/YFramework.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/YFramework.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -483,13 +483,13 @@
483483 <ConfigurationType>StaticLibrary</ConfigurationType>
484484 <UseDebugLibraries>true</UseDebugLibraries>
485485 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
486- <PlatformToolset>v142</PlatformToolset>
486+ <PlatformToolset>v143</PlatformToolset>
487487 </PropertyGroup>
488488 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
489489 <ConfigurationType>StaticLibrary</ConfigurationType>
490490 <UseDebugLibraries>false</UseDebugLibraries>
491491 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
492- <PlatformToolset>v142</PlatformToolset>
492+ <PlatformToolset>v143</PlatformToolset>
493493 </PropertyGroup>
494494 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
495495 <ImportGroup Label="ExtensionSettings">
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/include/NPL/NPLA.h
--- a/YFramework/include/NPL/NPLA.h Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/include/NPL/NPLA.h Fri Nov 19 06:25:50 2021 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA.h
1212 \ingroup NPL
1313 \brief NPLA 公共接口。
14-\version r8648
14+\version r8656
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 663
1717 \par 创建时间:
1818 2016-01-07 10:32:34 +0800
1919 \par 修改时间:
20- 2021-10-21 18:09 +0800
20+ 2021-11-11 20:32 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -721,7 +721,7 @@
721721 //! \sa LexemeCategory
722722 //@{
723723 /*!
724-\pre 断言:字符串参数的数据指针非空。
724+\pre 间接断言:字符串参数的数据指针非空。
725725 \return 判断的非扩展字面量分类。
726726 */
727727 //@{
@@ -742,7 +742,7 @@
742742
743743 /*!
744744 \brief 判断不是非扩展字面量的词素是否为 NPLA 扩展字面量。
745-\pre 断言:字符串参数的数据指针非空且字符串非空。
745+\pre 断言:字符串参数的数据指针非空。
746746 \pre 词素不是代码字面量或数据字面量。
747747 \since build 771
748748 */
@@ -3492,7 +3492,12 @@
34923492 namespace ystdex
34933493 {
34943494
3495-//! \relates NPL::A1::Continuation
3495+//! \relates NPL::EnvironmentReference
3496+template<>
3497+struct is_bitwise_swappable<NPL::EnvironmentReference> : true_
3498+{};
3499+
3500+//! \relates NPL::EnvironmentSwitcher
34963501 template<>
34973502 struct is_bitwise_swappable<NPL::EnvironmentSwitcher> : true_
34983503 {};
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/include/NPL/NPLA1Forms.h
--- a/YFramework/include/NPL/NPLA1Forms.h Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/include/NPL/NPLA1Forms.h Fri Nov 19 06:25:50 2021 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Forms.h
1212 \ingroup NPL
1313 \brief NPLA1 语法形式。
14-\version r8559
14+\version r8563
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2020-02-15 11:19:21 +0800
1919 \par 修改时间:
20- 2021-10-21 18:09 +0800
20+ 2021-11-11 20:32 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -49,6 +49,8 @@
4949
5050 /*!
5151 \brief 判断字符串值是否可构成符号。
52+\note 不依赖具体字符集。
53+\note 不排除假阴性结果。
5254 \since build 779
5355 */
5456 YB_ATTR_nodiscard YF_API YB_PURE bool
@@ -72,7 +74,7 @@
7274 \since build 786
7375
7476 参考调用文法:
75-<pre>symbol-string? \<object></pre>
77+<pre>symbol->string \<object></pre>
7678 */
7779 YB_ATTR_nodiscard YF_API YB_STATELESS const string&
7880 SymbolToString(const TokenValue&) ynothrow;
@@ -1319,7 +1321,6 @@
13191321 /*!
13201322 \throw InvalidSyntax 标识符不是符号。
13211323 \throw TypeError 当前环境被冻结。
1322-\sa IsNPLASymbol
13231324 \sa RemoveIdentifier
13241325 \since build 867
13251326 */
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/source/NPL/NPLA.cpp
--- a/YFramework/source/NPL/NPLA.cpp Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/source/NPL/NPLA.cpp Fri Nov 19 06:25:50 2021 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA.cpp
1212 \ingroup NPL
1313 \brief NPLA 公共接口。
14-\version r3658
14+\version r3669
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 663
1717 \par 创建时间:
1818 2016-01-07 10:32:45 +0800
1919 \par 修改时间:
20- 2021-10-30 09:10 +0800
20+ 2021-11-14 20:51 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -391,25 +391,26 @@
391391 // XXX: Use other type without overhead of check on call of %operator()?
392392 using Redirector = function<observer_ptr<const ValueObject>()>;
393393
394-//! \since build 884
394+//! \since build 931
395395 observer_ptr<const ValueObject>
396-RedirectEnvironmentList(EnvironmentList::const_iterator first,
397- EnvironmentList::const_iterator last, string_view id, Redirector& cont)
396+RedirectEnvironmentList(Environment::allocator_type a, Redirector& cont,
397+ EnvironmentList::const_iterator first, EnvironmentList::const_iterator last)
398398 {
399399 if(first != last)
400400 {
401- cont = std::bind(
401+ cont = ystdex::make_obj_using_allocator<Redirector>(a,
402+ any_ops::trivial_swap, std::bind(
402403 [=, &cont](EnvironmentList::const_iterator i, Redirector& c){
403404 cont = std::move(c);
404- return RedirectEnvironmentList(i, last, id, cont);
405- }, std::next(first), std::move(cont));
405+ return RedirectEnvironmentList(a, cont, i, last);
406+ }, std::next(first), std::move(cont)));
406407 return NPL::make_observer(&*first);
407408 }
408409 return {};
409410 }
410411
411412 //! \since build 857
412-YB_ATTR_nodiscard YB_PURE TermTags
413+YB_ATTR_nodiscard YB_STATELESS TermTags
413414 MergeTermTags(TermTags x, TermTags y) ynothrow
414415 {
415416 return (((x & ~TermTags::Temporary) | y) & ~TermTags::Unique)
@@ -1259,8 +1260,9 @@
12591260 {
12601261 auto& envs(parent.GetObject<EnvironmentList>());
12611262
1262- p_next = RedirectEnvironmentList(envs.cbegin(),
1263- envs.cend(), id, cont);
1263+ p_next = RedirectEnvironmentList(
1264+ p_env->Bindings.get_allocator(), cont,
1265+ envs.cbegin(), envs.cend());
12641266 }
12651267 while(!p_next && bool(cont))
12661268 p_next = ystdex::exchange(cont, Redirector())();
diff -r 91142b01d66f -r a0edf9d1c9a2 YFramework/source/NPL/NPLAMath.cpp
--- a/YFramework/source/NPL/NPLAMath.cpp Thu Nov 11 18:37:42 2021 +0800
+++ b/YFramework/source/NPL/NPLAMath.cpp Fri Nov 19 06:25:50 2021 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLAMath.cpp
1212 \ingroup NPL
1313 \brief NPLA 数学功能。
14-\version r24396
14+\version r24519
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 930
1717 \par 创建时间:
1818 2021-11-03 12:50:49 +0800
1919 \par 修改时间:
20- 2021-11-11 12:02 +0800
20+ 2021-11-19 05:47 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -1017,31 +1017,128 @@
10171017 return {};
10181018 }
10191019
1020+//! \since build 931
1021+//@{
1022+// XXX: Keeping the type of numeric literals without sign 'int' is also more
1023+// compatible to old operations.
1024+using ReadIntType = int;
1025+using ReadExtIntType = long long;
1026+using ReadCommonType = ystdex::common_type_t<ReadExtIntType, std::uint64_t>;
1027+
1028+YB_ATTR_nodiscard YB_STATELESS yconstfn PDefH(bool, IsDecimalPoint, char c)
1029+ ynothrow
1030+ ImplRet(c == '.')
1031+
1032+YB_ATTR_nodiscard YB_STATELESS yconstfn PDefH(bool, IsExponent, char c) ynothrow
1033+ ImplRet(c == 'e' || c == 'E')
1034+
1035+YB_ATTR_nodiscard YB_PURE inline double
1036+ScaleDecimalFlonum(char sign, double ans, ptrdiff_t scale)
1037+{
1038+ return (sign != '-' ? double(ans) : -double(ans)) * std::pow(10, scale);
1039+}
1040+
1041+YB_ATTR_nodiscard YB_PURE ptrdiff_t
1042+ReadDecimalExponent(string_view::const_iterator first, string_view id)
1043+{
1044+ bool minus = {};
1045+
1046+ switch(*first)
1047+ {
1048+ case '-':
1049+ minus = true;
1050+ YB_ATTR_fallthrough;
1051+ case '+':
1052+ ++first;
1053+ YB_ATTR_fallthrough;
1054+ default:
1055+ break;
1056+ }
1057+ if(first != id.end())
1058+ {
1059+ ptrdiff_t res(0);
1060+
1061+ ystdex::retry_on_cond(ystdex::id<>(), [&]() -> bool{
1062+ if(ystdex::isdigit(*first))
1063+ {
1064+ if(DecimalAccumulate(res, *first))
1065+ return ++first != id.end();
1066+ // XXX: Assume the values (with or without the minus sign) are
1067+ // out of the range of the supported exponents.
1068+ res = std::numeric_limits<ptrdiff_t>::max();
1069+ return {};
1070+ }
1071+ throw InvalidSyntax(ystdex::sfmt("Invalid character '%c' found in"
1072+ " the exponent of '%s'.", *first, id.data()));
1073+ });
1074+ return minus ? -res : res;
1075+ }
1076+ throw
1077+ InvalidSyntax(ystdex::sfmt("Empty exponent found in '%s'.", id.data()));
1078+}
1079+
1080+// XXX: This assumes %ReadCommonType can save more digits than %double.
10201081 void
10211082 ReadDecimalInexact(ValueObject& vo, string_view::const_iterator first,
1022- string_view id, double ans, size_t shift = 0)
1083+ string_view id, ReadCommonType ans, string_view::const_iterator dpos)
10231084 {
10241085 YAssert(!id.empty(), "Invalid lexeme found.");
1025- YAssert(shift <= id.size(), "Invalid pointer position found.");
1086+
1087+ // NOTE: This is the beginning position known to ignore the subsequent
1088+ // digits after. Digits after this position are checked but then ignored.
1089+ auto cut(id.end());
1090+
10261091 ystdex::retry_on_cond(ystdex::id<>(), [&]() -> bool{
1092+ const auto ret([&](ptrdiff_t scale) YB_FLATTEN{
1093+ vo = ScaleDecimalFlonum(id[0], ans, scale);
1094+ return false;
1095+ });
1096+
10271097 if(ystdex::isdigit(*first))
1028- ans = DecimalCarryAddDigit(ans, *first);
1029- else if(*first == '.')
10301098 {
1031- if(shift == 0)
1032- shift = size_t(id.end() - first);
1099+ if(cut == id.end())
1100+ {
1101+ // NOTE: The intermediate result cannot save more digits, do
1102+ // rounding.
1103+ if(!DecimalAccumulate(ans, *first))
1104+ {
1105+ ans += *first >= '5' ? 1 : 0;
1106+ cut = first;
1107+ }
1108+ }
1109+ }
1110+ else if(IsDecimalPoint(*first))
1111+ {
1112+ if(dpos == id.end())
1113+ // NOTE: No exponent part has been found.
1114+ dpos = first;
10331115 else
10341116 throw InvalidSyntax(ystdex::sfmt(
10351117 "More than one decimal points found in '%s'.", id.data()));
10361118 }
1119+ else if(IsExponent(*first))
1120+ {
1121+ const auto el(id.end() - first);
1122+
1123+ // NOTE: If a decimal point in the representation of the cut digits
1124+ // is found, it is also shifted as one digit.
1125+ return ret((cut == id.end() ? 0 : id.end() - cut - el
1126+ - (dpos != id.end() && dpos > cut ? 1 : 0))
1127+ - (dpos == id.end() ? 0 : id.end() - dpos - el - 1)
1128+ + ReadDecimalExponent(first + 1, id));
1129+ }
10371130 else
10381131 ThrowForInvalidLiteralSuffix(&*first, id.data());
10391132 if(++first != id.end())
10401133 return true;
1041- vo = (id[0] != '-' ? ans : -ans) * std::pow(10, shift);
1042- return {};
1134+ // NOTE: Similar to above without the exponent, so %el is always equals
1135+ // to 0.
1136+ return ret((cut == id.end() ? 0 : id.end() - cut
1137+ - (dpos != id.end() && dpos > cut ? 1 : 0))
1138+ - (dpos == id.end() ? 0 : id.end() - dpos - 1));
10431139 });
10441140 }
1141+//@}
10451142
10461143 template<typename _tInt>
10471144 YB_ATTR_nodiscard bool
@@ -1061,10 +1158,15 @@
10611158 if(ystdex::isdigit(*first))
10621159 return DecimalAccumulate(ans, *first) ? ReductionStatus::Retrying
10631160 : ReductionStatus::Partial;
1064- if(*first == '.')
1161+ if(IsDecimalPoint(*first))
10651162 {
1066- ReadDecimalInexact(vo, first + 1, id, ans,
1067- size_t(id.end() - first));
1163+ ReadDecimalInexact(vo, first + 1, id, ReadCommonType(ans), first);
1164+ return ReductionStatus::Clean;
1165+ }
1166+ if(IsExponent(*first))
1167+ {
1168+ vo = ScaleDecimalFlonum(id[0], double(ans),
1169+ ReadDecimalExponent(first + 1, id));
10681170 return ReductionStatus::Clean;
10691171 }
10701172 ThrowForInvalidLiteralSuffix(&*first, id.data());
@@ -1304,37 +1406,40 @@
13041406 // unsigned types, operations like minus would result in different types
13051407 // depending on types, and the type of negative values computed from
13061408 // unsinged values by these operations would be promoted too quick.
1307- // XXX: Keeping the type of numeric literals without sign 'int' is also more
1308- // compatible to old operations.
1309- using int_type = int;
1310- using ext_int_type = long long;
13111409 YAssert(!id.empty(), "Invalid lexeme found.");
13121410 YAssert(first >= id.begin() && size_t(first - id.begin()) < id.size(),
13131411 "Invalid first iterator found.");
13141412
13151413 // NOTE: Skip leading zeros.
13161414 while(YB_UNLIKELY(*first == '0'))
1317- if(YB_UNLIKELY(++first == id.end()))
1415+ if(first + 1 != id.end())
1416+ ++first;
1417+ else
13181418 break;
1319- yconstexpr_if(std::numeric_limits<int_type>::max()
1320- != std::numeric_limits<ext_int_type>::max())
1419+ yconstexpr_if(std::numeric_limits<ReadIntType>::max()
1420+ != std::numeric_limits<ReadExtIntType>::max())
13211421 {
1322- int_type ans(0);
1422+ ReadIntType ans(0);
13231423
13241424 if(YB_UNLIKELY(ReadDecimalExact(vo, id, first, ans)))
13251425 {
1326- ext_int_type lans(ans);
1426+ ReadExtIntType lans(ans);
13271427
13281428 if(YB_UNLIKELY(ReadDecimalExact(vo, id, first, lans)))
1329- ReadDecimalInexact(vo, first, id, lans);
1429+ // NOTE: The cast is safe even when %ReadCommonType is unsigned
1430+ // because %ReadDecimalExact may only add the minus sign on a
1431+ // complete parse.
1432+ ReadDecimalInexact(vo, first, id, ReadCommonType(lans),
1433+ id.end());
13301434 }
13311435 }
13321436 else
13331437 {
1334- int_type ans(0);
1438+ ReadIntType ans(0);
13351439
13361440 if(YB_UNLIKELY(ReadDecimalExact(vo, id, first, ans)))
1337- ReadDecimalInexact(vo, first, id, ans);
1441+ // NOTE: Ditto.
1442+ ReadDecimalInexact(vo, first, id, ReadCommonType(ans), id.end());
13381443 }
13391444 }
13401445
diff -r 91142b01d66f -r a0edf9d1c9a2 YSTest/Android/YSTest_Android.vcxproj
--- a/YSTest/Android/YSTest_Android.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YSTest/Android/YSTest_Android.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -20,13 +20,13 @@
2020 <ConfigurationType>Makefile</ConfigurationType>
2121 <CharacterSet>MultiByte</CharacterSet>
2222 <WholeProgramOptimization>true</WholeProgramOptimization>
23- <PlatformToolset>v142</PlatformToolset>
23+ <PlatformToolset>v143</PlatformToolset>
2424 </PropertyGroup>
2525 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
2626 <ConfigurationType>Makefile</ConfigurationType>
2727 <CharacterSet>MultiByte</CharacterSet>
2828 <WholeProgramOptimization>true</WholeProgramOptimization>
29- <PlatformToolset>v142</PlatformToolset>
29+ <PlatformToolset>v143</PlatformToolset>
3030 </PropertyGroup>
3131 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
3232 <ImportGroup Label="ExtensionSettings">
diff -r 91142b01d66f -r a0edf9d1c9a2 YSTest/Android/YSTest_Android.vcxproj.filters
--- a/YSTest/Android/YSTest_Android.vcxproj.filters Thu Nov 11 18:37:42 2021 +0800
+++ b/YSTest/Android/YSTest_Android.vcxproj.filters Fri Nov 19 06:25:50 2021 +0800
@@ -17,12 +17,6 @@
1717 </Filter>
1818 </ItemGroup>
1919 <ItemGroup>
20- <None Include="data\logo.bmp">
21- <Filter>data</Filter>
22- </None>
23- <None Include="data\logo_wifi.bmp">
24- <Filter>data</Filter>
25- </None>
2620 <None Include="Makefile" />
2721 </ItemGroup>
2822 <ItemGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YSTest/DS/YSTest_DS.vcxproj
--- a/YSTest/DS/YSTest_DS.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YSTest/DS/YSTest_DS.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -20,13 +20,13 @@
2020 <ConfigurationType>Makefile</ConfigurationType>
2121 <CharacterSet>MultiByte</CharacterSet>
2222 <WholeProgramOptimization>true</WholeProgramOptimization>
23- <PlatformToolset>v142</PlatformToolset>
23+ <PlatformToolset>v143</PlatformToolset>
2424 </PropertyGroup>
2525 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
2626 <ConfigurationType>Makefile</ConfigurationType>
2727 <CharacterSet>MultiByte</CharacterSet>
2828 <WholeProgramOptimization>true</WholeProgramOptimization>
29- <PlatformToolset>v142</PlatformToolset>
29+ <PlatformToolset>v143</PlatformToolset>
3030 </PropertyGroup>
3131 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
3232 <ImportGroup Label="ExtensionSettings">
diff -r 91142b01d66f -r a0edf9d1c9a2 YSTest/DS_ARM7/YSTest_ARM7.vcxproj
--- a/YSTest/DS_ARM7/YSTest_ARM7.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YSTest/DS_ARM7/YSTest_ARM7.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -24,12 +24,12 @@
2424 </PropertyGroup>
2525 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2626 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
27- <PlatformToolset>v142</PlatformToolset>
27+ <PlatformToolset>v143</PlatformToolset>
2828 <ConfigurationType>Makefile</ConfigurationType>
2929 <UseDebugLibraries>true</UseDebugLibraries>
3030 </PropertyGroup>
3131 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM'" Label="Configuration">
32- <PlatformToolset>v142</PlatformToolset>
32+ <PlatformToolset>v143</PlatformToolset>
3333 <ConfigurationType>Makefile</ConfigurationType>
3434 <UseDebugLibraries>false</UseDebugLibraries>
3535 </PropertyGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YSTest/DS_ARM9/YSTest_ARM9.vcxproj
--- a/YSTest/DS_ARM9/YSTest_ARM9.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YSTest/DS_ARM9/YSTest_ARM9.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -48,12 +48,12 @@
4848 </PropertyGroup>
4949 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
5050 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|ARM'" Label="Configuration">
51- <PlatformToolset>v142</PlatformToolset>
51+ <PlatformToolset>v143</PlatformToolset>
5252 <ConfigurationType>Makefile</ConfigurationType>
5353 <UseDebugLibraries>true</UseDebugLibraries>
5454 </PropertyGroup>
5555 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|ARM'" Label="Configuration">
56- <PlatformToolset>v142</PlatformToolset>
56+ <PlatformToolset>v143</PlatformToolset>
5757 <ConfigurationType>Makefile</ConfigurationType>
5858 <UseDebugLibraries>false</UseDebugLibraries>
5959 </PropertyGroup>
diff -r 91142b01d66f -r a0edf9d1c9a2 YSTest/YSTest.vcxproj
--- a/YSTest/YSTest.vcxproj Thu Nov 11 18:37:42 2021 +0800
+++ b/YSTest/YSTest.vcxproj Fri Nov 19 06:25:50 2021 +0800
@@ -47,13 +47,13 @@
4747 <ConfigurationType>Application</ConfigurationType>
4848 <UseDebugLibraries>true</UseDebugLibraries>
4949 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
50- <PlatformToolset>v142</PlatformToolset>
50+ <PlatformToolset>v143</PlatformToolset>
5151 </PropertyGroup>
5252 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|Win32'" Label="Configuration">
5353 <ConfigurationType>Application</ConfigurationType>
5454 <UseDebugLibraries>false</UseDebugLibraries>
5555 <OutDir>$(SolutionDir)build\Win32\$(ProjectName)\$(Configuration)\</OutDir>
56- <PlatformToolset>v142</PlatformToolset>
56+ <PlatformToolset>v143</PlatformToolset>
5757 <WholeProgramOptimization>true</WholeProgramOptimization>
5858 </PropertyGroup>
5959 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
diff -r 91142b01d66f -r a0edf9d1c9a2 YSTest/source/DSReader.cpp
--- a/YSTest/source/DSReader.cpp Thu Nov 11 18:37:42 2021 +0800
+++ b/YSTest/source/DSReader.cpp Fri Nov 19 06:25:50 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2010-2016, 2019 FrankHB.
2+ © 2010-2016, 2019, 2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file DSReader.cpp
1212 \ingroup YReader
1313 \brief 适用于 DS 的双屏阅读器。
14-\version r3291
14+\version r3383
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since 早于 build 132
1717 \par 创建时间:
1818 2010-01-05 14:04:05 +0800
1919 \par 修改时间:
20- 2019-01-14 18:55 +0800
20+ 2021-11-12 18:20 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -25,10 +25,11 @@
2525 */
2626
2727
28-#include "DSReader.h" // for ystdex::max;
28+#include "DSReader.h" // for ptrdiff_t, ystdex::max;
2929 #include <algorithm> // for std::copy_n;
3030 #include YFM_YSLib_UI_YWindow
3131 #include YFM_YSLib_Service_TextLayout
32+#include <limits> // for std::numeric_limits;
3233
3334 namespace YSLib
3435 {
@@ -167,11 +168,11 @@
167168 {
168169 // XXX: Conversion to 'SPos' might be implementation-defined.
169170 YAssert(SPos(area_up.GetHeight()) - area_up.Margin.Bottom - SPos(n) > 0,
170- "No enough space of areas found.");
171+ "No enough space of the up area for scrolling found.");
171172
172173 const SDst up_btm(SDst(ystdex::max<SPos>(area_up.Margin.Bottom, 0)));
173174
174- if(YB_UNLIKELY(area_up.GetHeight() <= up_btm + n))
175+ if(area_up.GetHeight() > up_btm + n)
175176 {
176177 auto src_off(SDst(ystdex::max<SPos>(area_dn.Margin.Top, 0))),
177178 dst_off(SDst(area_up.GetHeight() - up_btm - n));
@@ -319,64 +320,73 @@
319320 bool
320321 DualScreenReader::Execute(Command cmd)
321322 {
322- if(YB_UNLIKELY(!p_text || p_text->GetTextSize() == 0))
323- return {};
324- if(YB_UNLIKELY(~cmd & Scroll))
325- return {};
326- if(AdjustScrollOffset() != 0)
327- return {};
328- if(cmd & Up)
323+ if(p_text && p_text->GetTextSize() != 0 && bool(cmd & Scroll)
324+ && AdjustScrollOffset() == 0)
329325 {
330- if(YB_UNLIKELY(IsTextTop()))
331- return {};
332- }
333- else if(YB_UNLIKELY(IsTextBottom()))
334- return {};
335- YAssert(area_up.LineGap == area_dn.LineGap, "Distinct line gaps found.");
336- // TODO: Assert the fonts are same.
337- cmd &= ~Scroll;
338- if(cmd & Line)
339- {
340- const FontSize h(area_up.Font.GetHeight()), hx(h + GetLineGap());
326+ const bool up(cmd & Up);
341327
342- if(cmd & Up)
328+ if((up && !IsTextTop()) || (!up && !IsTextBottom()))
343329 {
344- MoveScrollArea(area_up, area_dn, hx, SDst(h));
345- SetCurrentTextLineNOf(area_up, 0);
346- AdjustForPrevNewline();
347- CarriageReturn(area_up);
348- PutLine(area_up, next_if_eq(i_top, '\n'), p_text->end(), '\n');
349- if(overread_line_n > 0)
350- --overread_line_n;
330+ YAssert(area_up.LineGap == area_dn.LineGap,
331+ "Distinct line gaps found.");
332+ // TODO: Assert the fonts are same.
333+ // XXX: %Scroll is not used currently.
334+ if(cmd & Line)
335+ {
336+ const size_t h(area_up.Font.GetHeight()), hx(h + GetLineGap());
337+
338+ if(hx >= h && h <= std::numeric_limits<ptrdiff_t>::max())
339+ {
340+ if(up)
341+ {
342+ MoveScrollArea(area_up, area_dn, ptrdiff_t(hx),
343+ SDst(h));
344+ SetCurrentTextLineNOf(area_up, 0);
345+ AdjustForPrevNewline();
346+ CarriageReturn(area_up);
347+ PutLine(area_up, next_if_eq(i_top, '\n'), p_text->end(),
348+ '\n');
349+ if(overread_line_n > 0)
350+ --overread_line_n;
351+ else
352+ AdjustPrevious(area_up, i_btm, *p_text);
353+ }
354+ else
355+ {
356+ MoveUpForLastLine(-ptrdiff_t(hx), h);
357+ // NOTE: The buffer is not ensured with null character
358+ // at end.
359+ CarriageReturn(area_dn);
360+ i_btm = PutLastLine();
361+ AdjustForFirstNewline();
362+ }
363+ Invalidate();
364+ }
365+ else
366+ {
367+ ShowError(u"字形大小溢出,渲染失败!");
368+ return {};
369+ }
370+ }
351371 else
352- AdjustPrevious(area_up, i_btm, *p_text);
353- }
354- else
355- {
356- MoveUpForLastLine(-hx, h);
357- // NOTE: The buffer is not ensured with null character at end.
358- CarriageReturn(area_dn);
359- i_btm = PutLastLine();
360- AdjustForFirstNewline();
372+ {
373+ auto ln(area_up.GetTextLineNEx() + area_dn.GetTextLineNEx());
374+
375+ if(up)
376+ while(ln--)
377+ AdjustForPrevNewline();
378+ else
379+ while(ln-- && !IsTextBottom())
380+ {
381+ AdjustForNewline(area_dn, i_btm, *p_text);
382+ AdjustForFirstNewline();
383+ }
384+ UpdateView();
385+ }
386+ return true;
361387 }
362- Invalidate();
363388 }
364- else
365- {
366- auto ln(area_up.GetTextLineNEx() + area_dn.GetTextLineNEx());
367-
368- if(cmd & Up)
369- while(ln--)
370- AdjustForPrevNewline();
371- else
372- while(ln-- && !IsTextBottom())
373- {
374- AdjustForNewline(area_dn, i_btm, *p_text);
375- AdjustForFirstNewline();
376- }
377- UpdateView();
378- }
379- return true;
389+ return {};
380390 }
381391
382392 void
diff -r 91142b01d66f -r a0edf9d1c9a2 doc/ChangeLog.V0.9.txt
--- a/doc/ChangeLog.V0.9.txt Thu Nov 11 18:37:42 2021 +0800
+++ b/doc/ChangeLog.V0.9.txt Fri Nov 19 06:25:50 2021 +0800
@@ -11,13 +11,13 @@
1111 /*! \file ChangeLog.V0.9.txt
1212 \ingroup Documentation
1313 \brief 版本更新历史记录 - V0.9 。
14-\version r6182
14+\version r6281
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 800
1717 \par 创建时间:
1818 2020-10-12 17:19:23 +0800
1919 \par 修改时间:
20- 2021-11-11 18:37 +0800
20+ 2021-11-19 05:50 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -32,6 +32,105 @@
3232
3333 $now
3434 (
35+ / $re_ex(b773) $build "updated to Microsoft VC++ 2022" ~ "Microsoft VC++ \
36+ 2019" @ "Microsoft VC++ projects" $effective @ %(YBase, YFramework,
37+ Tools.(CreationTimeManager, PredefinedMacroDetector, SHBuild))
38+ $= (/ $re_ex(b862) "retargeted platform toolset" -> 'v143' ~ 'v142'),
39+ + $re_add(b928) $dev $lib "#pragma directive" @ ('YB_IMPL_GNUCPP \
40+ || YB_IMPL_CLANGPP' @ "alias templates %(equal_t, not_equal_t)"
41+ @ %TypeTraits, "functors %(equal_to, not_equal_to)" @ %Functor)
42+ @ %YBase.YStandardEx,
43+ // To elimiante Clang++ warning: [-Wfloat-equal].
44+ / %YFramework.NPL $=
45+ (
46+ / %NPLA $=
47+ (
48+ * DD "wrong precondition" @ "'\pre' command" @ "Doxygen comment"
49+ @ "function %IsNPLAExtendedLiteral" $since b822,
50+ / DLI "list environment redirection"
51+ @ "static member function %ContextNode::DefaultResolve" $=
52+ (
53+ / "simplified" !^ "identifier",
54+ // This does not perform better without the allocator.
55+ / ^ ("allocator", 'any_ops::trivial_swap_t')
56+ ),
57+ / DLI "term tag merge" ^ 'YB_STATELESS' ~ 'YB_PURE',
58+ / @ "namespace %ystdex" $=
59+ (
60+ * "wrong '\relates' command" @ "Doxygen comment"
61+ @ "class template specialization \
62+ %is_bitwise_swapple<NPL::EnvironmentSwitcher>" $since b926,
63+ + $re_add(b927) $lib "class template specializations \
64+ %is_bitwise_swappable for %NPL::EnvironmentReference"
65+ )
66+ ),
67+ * DD "wrong syntax" @ "Doxygen comment" @ "function %SymbolToString"
68+ @ %NPLA1Forms $since b924,
69+ / @ "function %ReadDecimal" @ %NPLAMath $=
70+ (
71+ * "wrong parsing result of flonums with '.' caused by wrong factor \
72+ adjustment used" $since b930,
73+ // Both exact and inexact number parsing were wrong.
74+ * "wrongly rejected number literals with '.' at the end and in \
75+ the range of fixnums" $since b930,
76+ // There would be an error of unsupported literal suffix \
77+ '' if the value is acceptable by the largest integer \
78+ type, or the wrong value for flonums (see ablove).
79+ * "wrongly treated integer zero lexeme prefixed with a sign as \
80+ empty lexemes" $since b930,
81+ // The wrong results were caused by the trailing zeros \
82+ removal.
83+ (
84+ * "too lossy intermediate results" $since b930 $=
85+ (
86+ / "saved internal data for ineacxt results"
87+ ^ "common type of internally used extended integer \
88+ type (i.e. 'long long') and %std::uint64_t" ~ "%double";
89+ // With some changes on the call sitees, this also to \
90+ eliminate Microsoft VC++ warning: C4244.
91+ / $impl "converted to %double at last"
92+ ^ "signed shift on the final result"
93+ );
94+ * $comp "wrong infinite values caused by the overflow fraction \
95+ even after the decimal point has occurred" $since b930,
96+ // This should not overflow to infinite.
97+ ),
98+ + "support of exponents syntaxes on inexact numbers"
99+ )
100+ ),
101+ / @ "class %DualScreenReader" @ %YReader.DSReader $=
102+ (
103+ / "moving scrolling area"
104+ @ "functions %(Execute, (MoveUpForLastLine; ScrollByPixel))" $=
105+ (
106+ / $lib $design ^ "more precise assertion message"
107+ @ "space checking for scrolling",
108+ * "missing scrolling of the old text area caused by negated \
109+ condition of scrolling check" $since b850
110+ ),
111+ / @ "function %Execute" $=
112+ (
113+ / DLDI "simplified condition checks",
114+ / DLI "simplified command selection",
115+ // The %Scroll bit in the command parameter is just ignored now.
116+ / @ "the scrolling up command execution" $=
117+ (
118+ / $revert_ex(b292)
119+ "extended allowed line height to %size_t" ~ "%FontSize";
120+ // %FontSize is effectively %std::uint8_t, which is too \
121+ small in some cases. Originally (before b292) it was \
122+ 'u32' as the type of the total height and there was \
123+ no implicit limitation of the height of a line.
124+ / "showed error on the size too large";
125+ * $comp "missing the check to prevent the use of the wrongly \
126+ wrapped size as the line height" $since b292
127+ )
128+ )
129+ )
130+),
131+
132+b930
133+(
35134 + "'-fno-semantic-interposition' after '-fPIC' except for platform %Android"
36135 $effective @ ("%SHBuild-common-options.sh", "%SHBuild-YSLib-common.txt")
37136 @ %Tools.Scripts,
@@ -44,6 +143,7 @@
44143 (
45144 / %YDefinition $=
46145 (
146+ * DD "typo" @ "comment" @ "Doxygen group %traits" $since b845,
47147 / $resolve(#39) $dev "cleared substitution list" @ "macros \
48148 %(ynoexcept_param, ynoexcept_qual)" @ 'YB_IMPL_MSCPP',
49149 / $re_add(b927) DLDI "all 'yconstexpr const'" @ "namespace scope"
diff -r 91142b01d66f -r a0edf9d1c9a2 doc/NPL.txt
--- a/doc/NPL.txt Thu Nov 11 18:37:42 2021 +0800
+++ b/doc/NPL.txt Fri Nov 19 06:25:50 2021 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPL.txt
1212 \ingroup Documentation
1313 \brief NPL 规范和实现规格说明。
14-\version r25545
14+\version r25665
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 304
1717 \par 创建时间:
1818 2012-04-25 10:34:20 +0800
1919 \par 修改时间:
20- 2021-11-11 18:35 +0800
20+ 2021-11-19 01:06 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -139,6 +139,10 @@
139139 PicoLisp :https://software-lab.de/doc/faq.html#lambda
140140 newLISP :http://www.newlisp.org/downloads/newlisp_manual.html#define-macro
141141 和 Kernel 以及本设计不同,这两个例子的设计使用动态作用域(@4.6.1.2) ;在主要的特性中存在一些关键的不同而在形式模型的适用性上有显著的区别。
142+**注释**
143+Kernel 语言的原始参考实现是 SINK ,在 https://web.cs.wpi.edu/~jshutt/kernel.html 上取得,是依赖 MzScheme version 103 的解释器实现,和 [RnRK] 有一定差异。例如,字面量 #ignore 和 #inert 用 %ignore 和 %inert 代替。
144+klisp (http://klisp.org) 是 Kernel 语言的另一个更完善的实现。
145+有些特性(如复数支持)都没有在这两个中实现提供,而仅在 [RnRK] 中指定。
142146
143147 @1.5 领域设计原则:
144148 本节描述适用于满足通用目的的语言(@1.3) 的设计。
@@ -1986,8 +1990,9 @@
19861990 当宿主语言提供函数调用支持 PTC 时,可直接使用宿主语言的 PTC 调用,否则,需要使用其它替代实现机制确保 PTC 。
19871991 注意非对象语言的调用的上下文中,若被调用时间接使用,也仍需要保证 PTC 。
19881992 PTC 确保仅有一个活动(@4.5.3.1) 的调用。不满足 PTC 的情形下,语言没有提供用户访问非活动记录帧(@4.5.3.4) 资源的手段,因此可以认为是资源泄漏。但为简化语义规则,NPLA 不要求避免相关的弱内存泄漏(5.2.2.2) 。
1989-NPL 不保证一般对象存在引用(@4.2.3) ,NPLA 也不添加保证活动记录的帧(@4.5.3.4) 中保存引用,销毁活动记录的帧可能影响环境中的变量生存期而改变语义;因此 NPLA 不保证 PTC 支持,实现一般的 PTC 依赖派生实现定义的附加规则。
1990-为满足 PTC ,在 @5.9 的基础上,尾上下文内的可以确定(@5.9) 并调整对象生存期结束时机:
1993+NPL 不保证一般对象存在引用(@4.2.3) ,NPLA 也不添加保证活动记录的帧(@4.5.3.4) 中保存引用,销毁活动记录的帧可能影响环境中的变量生存期而改变语义。
1994+因此,除非依赖本节中以下的规则,NPLA 不保证 PTC 支持;实现更一般的 PTC 依赖派生实现定义的附加规则。
1995+为满足 PTC ,在生存期附加约定(@5.9) 的基础上,尾上下文内的可以确定(@5.9) 并调整对象生存期结束时机:
19911996 作为临时对象(@5.8.5) 的合并子及其参数可以延长生存期至多到尾上下文结束;
19921997 被证明不再需要之后引用的对象,或未被绑定到活动记录上的项中的对象,可以缩短生存期;
19931998 被延长生存期的对象生存期起始和结束的相对顺序保持不变;
@@ -1995,7 +2000,9 @@
19952000 推论:被缩短生存期和延长生存期的对象的生存期结束的相对顺序保持不变。这由没有被调整生存期的对象与被调整生存期对象之间的生存期结束的顺序关系(@5.10) 的传递性保证。
19962001 延长临时对象生存期和宿主语言中允许扩展非完全表达式内的临时对象的效果类似,但条件不同。
19972002 **注释**
1998-理论上 PTC 不要求延长生存期,仅要求特定情形下缩短生存期,且其它情形被释放的对象生存期不延长到尾上下文外;延长生存期是 @5.9 的推论。
2003+以上规则中被调整生存期的对象一般仅是参数和函数体内创建的对象。因此,不保证理论上允许的尾上下文的都满足 PTC 。一个例子是合并子中可以保存动态环境(@4.6.1.2) ,这个环境可能被递归的调用引用,而无法提前释放。
2004+理论上 PTC 不要求延长生存期,仅要求特定情形下缩短生存期,且其它情形被释放的对象生存期不延长到尾上下文外;
2005+允许延长生存期是生存期附加约定(@5.9) 的结果。
19992006
20002007 @5.10.3 PTR(proper tail recursion ,真尾递归):
20012008 PTC 的活动记录性质也在一般的递归规约时体现,被称为 PTR 。
@@ -2590,7 +2597,7 @@
25902597 Environment::EnsureValid(@6.8.1) ,失败时抛出异常;
25912598 shared_ptr<Environment> 值作为当前环境(@5.7.3) 的来源,同时提供指定为断言和具有异常的接口,参见上下文类(@6.11.3.1) ;
25922599 由 NPL_NPLA_CheckParentEnvironment(@6.1.2.1) 配置的可选的附加检查,失败时同 Environment::EnsureValid 。
2593-对象语言的动态类型的值需要进行环境类型的类型检查时,只区分对象语言中的类型,不特别排除具有宿主类型的非宿主值,因此不断言失败;
2600+对象语言的动态类型的值需要进行环境类型的类型检查(@4.7.3) 时,只区分对象语言中的类型,不特别排除具有宿主类型的非宿主值,因此不断言失败;
25942601 其余情形可能静态确定不存在来自可能通过互操作(@5.3) 来源取得的非空值,此时一般使用断言而不是异常。
25952602
25962603 @6.8.2.2 循环环境引用和环境引用所有权:
@@ -3067,10 +3074,10 @@
30673074 NPLA 上下文中,被激活的动作被移除。因为没有全局的垃圾回收(@4.2.2.3) ,这保证激活的动作在执行后能保证其中直接或间接捕获的资源被及时释放。
30683075 若需通过重复使用动作(实现非正常控制(@4.8) 等),需在动作被激活前进行处理(例如,复制或另行构造动作)。
30693076 以循环实现重写(@4.1.2) 时,有效的当前动作可用于作为保持重写循环的条件。当不存在有效的当前动作时,规约在完成已激活的规约操作后终止。
3070-以抽象机描述操作语义(@2.2.3) 时,定界动在尾上下文外提供剩余的动作,作为一个序列,称为尾部动作(trailing actions) ,是当前动作的后继动作(subsequent action) 。另见 http://www.brics.dk/RS/03/41/BRICS-RS-03-41.pdf 。
3077+以抽象机描述操作语义(@2.2.3) 时,定界动在尾上下文(@4.4.8) 外提供剩余的动作,作为一个序列,称为尾部动作(trailing actions) ,是当前动作的后继动作(subsequent action) 。另见 http://www.brics.dk/RS/03/41/BRICS-RS-03-41.pdf 。
30713078 当前动作起始的当前动作序列表示语言实现中(不作为一等对象(@4.1) 的)未被捕获的当前续延(@4.5.2.1) 。
30723079 动作和尾部动作整体构成求值上下文(@4.4.8) 的实现。后者在元语言中提供操作,又称为元上下文(meta-context) 。另见 http://www.brics.dk/RS/05/16/BRICS-RS-05-16.pdf 。
3073-当前动作可作为尾上下文(@4.4.8) 的实现,称为尾动作(tail action) 。特定的尾动作可实现符合 PTC 的尾调用(@5.10.2) 。
3080+当前动作可作为尾上下文的实现,称为尾动作(tail action) 。特定的尾动作可实现符合 PTC 的尾调用(@5.10.2) 。
30743081 配合重写循环提供基于尾动作的循环 API 可实现 CPS(contiuation passing style) 风格的异步调用。相关 API 参见 @6.11.4 。
30753082
30763083 @6.11.3.1 上下文类:
@@ -3203,33 +3210,46 @@
32033210 精确数和不精确数在数值上可能相等,而类型不同。
32043211 宿主类型中的本机整数和浮点数是数值类型的子类型,分别称为 fixnum 和 flonum 。这些类型在项的内部表示(在值数据成员(@6.2) 中)预期直接占据本机存储而不需要动态分配。
32053212 Fixnum 总是精确数;flonum 总是不精确数。
3206-**注释** 当前实现中,所有数值是 fixnum 或 flonum 之一。
3213+**注释** 当前实现中,所有数值是 fixnum 或 flonum 之一。两者分别是宿主的整数类型(排除字符和 bool 类型)以及浮点数类型。
3214+Flonum 支持带符号的无限大值,以及 NaN(not-a-number) 值作为特殊数值。其它值都是有限值。特殊数值可能具有不唯一的内部表示,但和有限值的表示都不同。
3215+Flonum 中可存在小的非零数,可能具有不唯一的内部表示。
3216+**注释** 宿主类型中的非规格化(denormalized) 浮点数是具有不唯一的内部表示的小的非零数值。
32073217 整数值的数值具有整数类型。这包括所有的 fixnum ,以及 flonum 中是整数的数值。这不和宿主类型直接对应。
32083218 **注释** 一个 flonum 是整数,当且仅当它的值取 std::round 、std::floor 或 std::ceil 后结果和原值相等。[R7RS] 对不精确数有类似的定义(仅使用 round )。
3209-如其它大多数类型,NPLA1 数值类型(@6.14.1) 符合正规表示(@6.10.7) ,只使用值数据成员(@6.2) 表示有效的数据。
3219+如其它大多数类型,数值类型符合正规表示(@6.10.7) ,只使用值数据成员(@6.2) 表示有效的数据。
32103220 **注释**
32113221 精确性、fixnum 和 flonum 等区分同 [R6RS] ,但具体实现要求不尽相同。
32123222 和 [RnRK] 不同,本文档没有指定可选的模块,也没有指定精确的 ±∞ 值。
32133223
32143224 @6.14.2 数值操作约定:
3215-在对象语言中,数值操作是使用数值类型作为输入的值的操作。NPLA1 提供本机 API 支持这些操作的实现。
3225+在对象语言中,数值操作是可使用数值作为算法输入的值的操作。NPLA1 提供本机 API 支持这些操作的实现。
3226+数值操作蕴含对应的数值计算,具有数值或者非数值类型的操作数和计算结果(@4.5.2.1) 。计算结果依赖影响计算结果的操作数。计算结果依赖至少一个数值类型的操作数。
3227+数值操作接受至少一个操作数,其中至少一个操作数被对应的数值计算的计算结果依赖。
32163228 除非另行指定:
3217-在数学上有意义的前提下,数值操作同时支持以上尽可能多的类型作为输入;
3218-数值操作预期输入的类型是数值类型,否则出错,抛出 NPL::TypeError 异常(@6.5) ;
3219-除数值操作不区分输入的数值上等价的精确数或不精确数;
3220-若数值操作的所有输入都是精确数,除非不能表示计算结果的范围,结果不是不精确数;
3229+在数学上有意义的前提下,数值操作同时支持以上尽可能多的数值类型的操作数;
3230+对预期是数值类型的操作数,数值操作进行类型检查(@4.7.3) ,失败时出错,抛出 NPL::TypeError 异常(@6.5) ;
3231+数值操作不区分数值类型的操作数中数值上等价的精确数或不精确数;
3232+若数值操作的所有数值类型的操作数都是精确数,除非不能表示计算结果的范围,结果不是不精确数;
32213233 除非不能表示计算结果的范围,数值操作不损失结果的精度;
3234+若计算结果是数值,则对应的数值操作的结果是不超过所有数值操作数结果的数值类型;
32223235 数值操作的输出的类型是能表示操作结果的数,其类型的值域能表示操作结果,具体类型未指定;
3223-实现假定输入和计算过程中不出现 SNaN(signaling NaN) 值。
3236+若计算结果是小于最小可唯一表示的数值的不精确数,则对应的数值操作结果是不精确数 0 ;
3237+若计算结果中无限大数值不能通过数学上有意义的方式确定符号,则对应的数值操作结果是无限大值或 NaN 之一,具体选择未指定;
3238+可假定数值计算的操作数和计算过程中不出现 SNaN(signaling NaN) 值;
3239+若被计算结果依赖的任一操作数中具有 NaN 值,则依赖这个操作数的数值操作结果也是 NaN 值。
32243240 **注释**
3241+数值操作可能允许非数值的操作数,这些操作数也可被计算结果依赖。
3242+因为 Flonum 能表示所有实数数值范围,所以实数范围以内的操作不会引入操作数以外的其它 flonum 类型。
32253243 数值操作抛出异常的要求不一定在每一个实现数值操作的 API 中蕴含,因为这些 API 不一定是数值操作的完整实现。
3244+计算结果中 NaN 值的符号实际由宿主实现决定。
3245+若数值操作指定非数值计算结果(如布尔值(@4.1) )或者不能表示的 NaN 值的计算结果,则即使依赖 NaN 数值操作数,也不是 NaN 值。
32263246
32273247 @6.14.3 标签类型:
32283248 以下类型具有 NPL::TypedValueAccessor(@6.9.6) 的相关特化。
32293249 NumberLeaf
32303250 NumberNode
3231-相关的特化检查数值类型输入,若失败则抛出异常。
3232-**注释** 使用这种方式访问的 API 可直接以输入表示数值类型作为前置条件,而不需要在内部检查输入的值是否具有数值类型。
3251+相关的特化检查数值类型的操作数,若失败则抛出异常。
3252+**注释** 使用这种方式访问的 API 可直接以操作数表示数值类型作为前置条件,而不需要在内部检查操作数的值是否具有数值类型。
32333253 对应的特化决定这些类型的不同。
32343254 NumberLeaf 直接传递数值类型中的值数据成员;
32353255 NumberNode 传递 NPL::ResolvedArg<>(@6.9.6) ,包含被 NPL::ResolveTerm(@6.9.6) 解析后的节点和访问引用的指针( NPL::ResolvedTermReferencePtr(@6.9.6) 类型的值)。
@@ -3276,24 +3296,37 @@
32763296 @6.14.6 数值表示:
32773297 以下函数提供和数值表示相关的操作:
32783298 ReadDecimal
3279-支持的数值以字符串作为表示,包括:
3280-支持的表示具体包括:
3281-匹配正则表达式 (+|-)?[0-9]+ :精确数数值。
3299+支持的数值以字符串作为表示。
3300+支持的表示具体包括(优先匹配较长的模式):
3301+匹配正则表达式 (+|-)?[0-9]+ :十进制精确数数值。
32823302 不论符号,当前精确数数值字面量默认都具有宿主类型(@5.5) int ,除非其绝对值太大而无法被表示,使用其它类型代替。
32833303 除非精确数字面量的数值超过所有 fixnum 的可表示范围,都具有 fixnum 值。
3284-除非精确数字面量的数值超过所有支持的精确数的可表示范围,都具有精确数类型。(这可能会在以后改变。)
3285-匹配正则表达式 (+|-)?[0-9]+\.[0-9]+? :不精确数数值。
3304+除非精确数字面量的数值超过所有支持的精确数的可表示范围,都是精确数。
3305+**注释** 当前精确数的表示范围是 fixnum 中宿主类型的值域的并集,因此超过 fixnum 可表示范围的数值不是精确数。
3306+匹配正则表达式 (+|-)?[0-9]+\.[0-9]* 或 (+|-)?[0-9]+(\.[0-9]*)?(E|e)(+|-)?[0-9]+ :十进制不精确数数值。
32863307 若不精确数数值不能以规格化范围内的数值表示,则结果是对应符号的无限大值。
3287-不精确数数值字面量的解析误差不大于最后一个在规格化范围内表示的十进制小数位为 1 时的绝对值的真值大小,以任意可能符合宿主语言要求的舍入模式下的最大值计。
3308+不精确数数值字面量的解析使用宿主语言允许的未指定的浮点数舍入模式,其误差不大于最后一个在规格化范围内表示的十进制小数位为 1 时的绝对值的真值大小(以任意可能符合宿主语言要求的舍入模式下的最大值计)。
3309+第二种形式是科学记数法,其中的 E 和 e 的含义是等价的,之后是指数。
32883310 **原理**
3289-浮点数解析存在误差不大于 1ULP(unit in the last place) 的精确算法,但对宿主实现的要求较高,且性能可能明显较低,故不作要求。
3290-和宿主语言的 std::strtod 不同,不要求考虑宿主语言实现中的具体浮点数舍入模式。
3311+浮点数解析存在不同精度的算法。
3312+若以二进制浮点数和经过舍入的十进制表示相互转换不损失精度为前提,宿主语言的 std::numeric_limits 的 max_digits10 位十进制数字足够表示。
3313+(对 IEEE-754 的二进制浮点数情形的证明,参见 https://www.itu.dk/~sestoft/bachelor/IEEE754_article.pdf Theorem 15 。)
3314+但是,对任意有效输入的结果误差都不大于 1ULP(unit in the last place) 的不经舍入的值完全精确值(full precision) 的精确解析算法,对实现的要求较高,且性能可能明显较低,故不作要求。
3315+(对 IEEE-754 的二进制浮点数的情形,需要数十倍的中间存储,参见 https://stackoverflow.com/questions/554063/62542806#62542806 。)
3316+和宿主语言的 std::strtod 不同,允许使用宿主语言中的任意浮点数舍入模式,而不要求不同浮点数舍入模式下的结果一致性。
32913317 **注释**
3292-串模式 (+|-) 表示带有可选前缀符号(仅限一个),影响值的数值。对 fixnum ,+0 和 -0 是相等的数值,但 flonum 不同符号的零值不同。
3318+串模式 (+|-) 表示带有可选前缀符号(仅限一个),影响值的数值。对 fixnum ,+0 和 -0 是相等的数值。Flonum 不同符号的零值在值的表示中可以不同,但不要求实现表现这种不同。
32933319 同 klisp 而不同于 [RnRS] 的字面量词法,小数点不能出现在词素中符号以外的第一个字符;但 klisp 的 string->number 没有这个限制。
3320+同 [RnRS] 而不同于 klisp(两者包括字面量词法和 string->number ),小数点允许出现在词素的结尾。
3321+当前不精确数数值都具有宿主类型 double 。即便 long double 可能具有更大的数值范围,也不能通过解析数值表示直接取得。
3322+类似地,[Racket] 默认不启用 extflonum(关于数值操作也类似,参见数值操作约定(@6.14.2) )。
3323+当前允许在宿主值不能完全存储不精确数的字面量数字时,解析十进制不精确数字面量存储的值可能和字面量的数值的真值之间具有超过 1ULP 的误差。这可能影响和精确数之间的比较。
3324+当前实现使用四舍五入。
32943325 关于宿主语言中 std::strtod(同 ISO C 标准库的 strtod )舍入要求的一些问题,参见:
32953326 https://www.exploringbinary.com/incorrectly-rounded-conversions-in-gcc-and-glibc/
32963327 https://www.sourceware.org/bugzilla/show_bug.cgi?id=3479
3328+[RnRK] 没有明确指定字面量词法规则。
3329+当前 klisp 的实现不允许 E 和 e 之前没有小数点,且在存在 E 或 e 时省略之后的指数的任意部分,和 SINK 以及 [RnRS] 都不同。本设计遵循后者。
32973330
32983331 @6.15 派生实现和应用实例:
32993332 除 NPLA 公共实现和派生实现 NPLA1 外,NPLA API 还具有一些其它应用实例。
@@ -4081,7 +4114,7 @@
40814114 当前未支持宿主栈展开(stack unwinding) 的互操作(@5.3) 。
40824115 C++ 异常调用重写循环(@6.11.3) 内资源对象的析构函数顺序是未指定的。但是,对 C++ API 异常安全保证的要求(@7.4.1.4) 仍然不变。
40834116 在 NPLA1 API 中同时提供对应的异步规约但不使用 TCO 的实现,不满足本节要求,仅供参考。
4084-TCO 应能支持实现 PTC(@5.10.2) 。
4117+TCO 应能按 NPLA 尾上下文约定(@5.10) ,支持在尾上下文(@4.4.8) 实现 PTC(@5.10.2) 。
40854118 在启用异步规约实现(@7.9.2) 的基础上,启用 TCO 的实现定义为实现选项(@7.1) NPL_Impl_NPLA1_Enable_TCO 。
40864119 以下指定当前对 TCO 的有限支持。没有明确指出的情形不保证支持 TCO 。
40874120
@@ -4101,7 +4134,7 @@
41014134 基于异步重规约和 TCO 的互操作提供目标 TCO 。
41024135
41034136 @7.10.2 整体设计约束:
4104-TCO 要求尾上下文(@4.4.8) 的续延(@4.5.2.1) 保持等效。考虑到计算资源的限制,排除构造相同的外部的求值环境(@4.6.1.2) 的实现方式,这蕴含同一性。
4137+TCO 要求尾上下文的续延(@4.5.2.1) 保持等效。考虑到计算资源的限制,排除构造相同的外部的求值环境(@4.6.1.2) 的实现方式,这蕴含同一性。
41054138 NPLA 的 TCO 基于异步规约(@7.9) ,基本方式是尾调用合并(@7.10) 。TCO 动作(@7.10.3) 是支持了尾调用合并的动作。
41064139 考虑到当前动作(@6.11.3) 预期直接构成当前续延(@6.11.3.1) ,对 NPLA1 ,这需要限制尾动作(@6.11.3) 的下一动作(@6.12.2) 不是 TCO 动作。
41074140
@@ -4179,7 +4212,7 @@
41794212 但注意调整语义规则或通过区分出非平凡析构等方式证明可观察行为不变后,减少父环境被隐藏的变量而完全实现 PTC 是可能的。
41804213 基于语义规则的许可,实现应支持部分非幂等操作的被合并,以支持 PTC :
41814214 若设置前的环境是被设置的环境的直接或间接父环境,其中可能影响可观察行为的变量都被新的环境隐藏,可确定父环境不再使用且不影响可观察行为,则仍然合并操作,并释放该父环境的资源。
4182-NPLA 规则 @5.10 允许可合并临时对象分配的非幂等操作实现 PTC ,即若存在已在 TCO 动作中分配的相等(以宿主环境(@2.7.1) 约定,参见 @7.11.5)的临时对象,则不再分配。
4215+NPLA 尾上下文约定允许可合并临时对象分配的非幂等操作实现 PTC ,即若存在已在 TCO 动作中分配的相等(以宿主环境(@2.7.1) 约定,参见 @7.11.5)的临时对象,则不再分配。
41834216
41844217 @7.10.4.2 非幂等操作合并约束:
41854218 同一个 TCO 动作内,以下尾调用合并的效果仍然有效:
@@ -4320,45 +4353,74 @@
43204353
43214354 @7.11.2 动作组合:
43224355 动作组合通过调用 NPL::RelaySwitched(@6.12.7) 。
4323-这和通过续延并保证异步调用(如 klisp 中 kapply_cc )不同,不把维护状态的操作放在待组合的后续操作中。
4356+这和通过续延并保证异步调用不同,不把维护状态的操作放在待组合的后续操作中。
43244357 这能同时支持同步和异步实现,同时在当前动作以序列表示时,不需要无效化被组合的动作的宿主对象。
4358+**注释** klisp 实现的 kapply_cc 是通过续延并保证异步调用的一个例子。
43254359
43264360 @7.11.3 函数合并(@4.5.3) 的实现:
43274361 NPLA1 规范求值算法(@7.8.2) 相对 Kernel 更简单以支持函数合并的 TCO 实现(@7.11.5) 。
4328-对应地,函数合并和 klisp 的 eval 实现略有不同:在处理器调用(@7.6.1.2) 实现参数列表中参数的求值。
4362+对应地,函数合并在处理器调用(@7.6.1.2) 实现参数列表中参数的求值。
4363+**注释** 这和 klisp 的 eval 实现略有不同。
43294364 NPLA1 使用包装数(@7.6.1.1) 处理包装调用,支持多重包装(这在 [RnRK] 被求值算法蕴含);而当前 klisp 的实现没有正确地支持多重包装调用,参见:https://bitbucket.org/AndresNavarro/klisp/issues/11 。
4330-和 klisp 类似,参数列表求值前检查不存在实际参数(而无需求值)的情形进行优化。
4365+**注释** 和 klisp 类似,参数列表求值前检查不存在实际参数(而无需求值)的情形进行优化。
43314366
43324367 @7.11.4 PTC 和尾调用本机实现:
43334368 符合 PTC 的尾调用通过 TCO 动作(@7.10.3) 实现。
43344369 TCO 动作(@7.10.3) 作为 NPLA 续延和之后在 PLDI 2020 公开的论文 https://doi.org/10.1145/3385412.3385981 中的 extra continuation frame 类似。
43354370 TCO 动作可扩展实现类似 SRFI-157 的续延标记(continuation mark) 的特性。
43364371 在 NPLA1 规范求值算法(@7.8.2) 的 PTC 通过显式构造 TCO 动作以及在此基础上的操作压缩(@7.10.4) 实现。
4337-这对应 klisp 的 ktail_call 实现 Kernel 的默认求值算法(包括 [RnRK] 的 eval 应用子的底层的操作子);但和后者依赖 GC 不同,TCO 动作可对环境有所有权(@7.10.6) 。
4338-klisp 还使用 ktail_call 提供本机实现。NPLA1 也可使用类似的实现。
4339-其它更一般的情况下,在求值上下文(@4.4.8) 中隐含已构造 TCO 动作为前提,通过直接或间接调用 A1::ReduceOnce(@7.4.4) 提供 PTC 保证。
4340-这对应 klisp 的 ktail_eval ;但和后者不同,A1::ReduceOnce 调用确切地只对应不显式引入新的环境的操作。
43414372 可能引入新的环境的操作,如 [RnRK] 的 eval(对应 NPLA1 对象语言函数 eval 和 eval% 等,参见 @11.3.7 ),需要另行调用比 A1::ReduceOnce 更复杂的操作压缩。
43424373 和 Kernel 要求以外,因为维护资源(@7.10.5) 的需要,TCO 动作在函数合并的底层操作子合并前被构造,因此进入参数求值时在资源管理的意义上也在所在函数合并的同一个尾上下文(@4.4.8) 。
43434374 另见 TCO 实现(@7.11.5) 。
4344-
4345-@7.11.5 TCO 动作(@7.10.3) 实现和限制:
4375+**注释**
4376+PTC 实现对应 klisp 的 ktail_call 实现 Kernel 的默认求值算法(包括 [RnRK] 的 eval 应用子的底层的操作子);但和后者依赖 GC 不同,TCO 动作可对环境有所有权(@7.10.6) 。
4377+klisp 还使用 ktail_call 提供本机实现。NPLA1 也可使用类似的实现。
4378+其它更一般的情况下,在求值上下文(@4.4.8) 中隐含已构造 TCO 动作为前提,通过直接或间接调用 A1::ReduceOnce(@7.4.4) 提供 PTC 保证。
4379+这对应 klisp 的 ktail_eval ;但和后者不同,A1::ReduceOnce 调用确切地只对应不显式引入新的环境的操作。
4380+
4381+@7.11.A 资源回收限制:
4382+当前 TCO 操作压缩不保证回收(通过 #ignore 指定)被忽略外的动态环境(@4.6.1.2) 。
4383+注意 [RnRK] §3.3 仅保证的应用子调用是尾上下文(@4.4.8) ,使用任意环境作为动态环境的操作子调用时不需要满足 PTC 。
4384+这可能有误,因为造成应用子的底层合并子和不作为底层操作子的其它操作子不一致,并且和这里的操作压缩限制一样,实际无法总是保证具有动态环境的应用子在动态环境被用用时能满足的调用 PTC 。
4385+**注释**
4386+事实上,Kernel 语言的实际实现一般无法保证回收非 #ignore 的动态环境,即便动态环境只被用于尾调用中。
4387+上述无法 TCO 的情形在其它语言中因为可达性分析等可能具有实现缺陷也不会释放存储,如以下 Kernel 程序在 klisp 中实测不支持 PTC :
4388+($sequence ($define! f ($lambda (n) ((($vau (x y) e (eval ($sequence x y) e)) n (f n))))) (f 1))
4389+而当前实现中,对应上述 Kernel 程序的 NPLA1 程序支持 PTC :
4390+$sequence ($def! f ($lambda (n) ((($vau (x y) e (eval ($sequence x y) e)) n (f n))))) (f 1)
4391+以下 Kernel 程序和对应的 NPLA1 程序支持 PTC :
4392+($sequence ($define! $f ($vau () #ignore (($f)))) ($f))
4393+$sequence ($def! $f ($vau () #ignore (() $f))) (() $f)
4394+但替换动态环境不被忽略,则都不支持 PTC(对 NPLA1 ,因为 e 没有在尾上下文中被引用,而无法被压缩):
4395+($sequence ($define! $f ($vau () e (($f)))) ($f))
4396+$sequence ($def! $f ($vau () e (() $f))) (() $f)
4397+以上 Kernel 程序使用 klisp 和 SINK 中(后者需替换 #ignore 为 %ignore ),效果一致。
4398+
4399+@7.11.5 TCO 动作(@7.10.3) 实现和其它限制:
43464400 因为维护资源(@7.10.5) 的需要,NPLA1 规范求值算法(@7.8.2) 不处理 WHNF(@4.4.5.1) 以外的操作数且允许宿主类型的调用(@7.6.1.2) 处理 WHNF 的第一项。
43474401 当前在 TCO 动作中被分配的临时对象(@5.8.5) 的操作都针对作为 WHNF 的第一项的合并子(@4.5.3.2) ,其中合并子的相等关系由相等性(@8.4.5.5) 或不影响可观察行为的其它宿主实现提供的 == 操作确定。
43484402 由相等性(@8.4.5.5) ,捕获不同环境的 vau 合并子不相等;不论是否具有相等的外部表示(@1.2.4) 和来源,其右值不会被直接操作压缩(@7.10.4) 避免多次添加而被 TCO ;若其嵌套调用因为捕获不同的存在引用关系的环境,不支持其它形式的 TCO ;因此,不支持 PTC 。
4349-注意上述情形在其它语言中因为可达性分析等可能具有实现缺陷也不会释放存储,如 Kernel 程序 ($sequence ($define! f ($lambda (n) ((($vau (x y) e (eval ($sequence x y) e)) n (f n))))) (f 1)) 在 klisp 中实测不支持 PTC 。
4350-当前 TCO 操作压缩不支持回收(通过 #ignore )指定忽略外的动态环境(@4.6.1.2) 。这实际上较 [RnRK] 的保证弱。但 klisp 同样没有很好地支持此特性,如 Kernel 程序 ($sequence ($define! $f ($vau () #ignore (($f)))) ($f)) 在 klisp 中实测不支持 PTC 。
4351-(关于以上 klisp 的问题,参见 https://bitbucket.org/AndresNavarro/klisp/issues/12 。)
4352-但是当前实现中,对应的 NPLA1 程序支持 PTC :
4353-$sequence ($def! f ($lambda (n) ((($vau (x y) e (eval ($sequence x y) e)) n (f n))))) (f 1)
43544403 实现依赖 Environment::IsOrphan(@6.11.1.1) 等判断确保内存安全(@5.6.3) 。
43554404 忽略非平凡析构判断(假定所有对象都可平凡析构),允许移除可证明不被继续引用(@5.10) (如被总是新的环境隐藏)的变量。
43564405 被移除的对象生存期提前结束(@5.10) 。
43574406 除被隐藏的变量被单独移除外,若一个活动记录帧(环境)内存在任意不满足可证明幂等的操作的情形,整个帧的剩余部分都被保持存储(因为不支持对 NPL::TermReference(@6.8.3) 分别保存引用计数)。
43584407 当前实现并没有显式支持 evlis tail recursion(@5.10.3) ,但因为调用前切换环境时已提前进行了收集,所以以 TCO 动作为边界,保存的帧应与之等效。
43594408 尽管可能有更优的渐进复杂度,所需空间的大小仍取决 TCO 活动记录最终保留帧前分配对象和碎片所占空间大小之和的最大值;实现应该不依赖这项特性。
4360-回收使函数对象在表达式求值外完毕之前结束,这仍然符合 @5.10 的要求。
4409+回收使函数对象在表达式求值外完毕之前结束,这仍然符合尾上下文约定(@5.10) 的要求。
43614410 当前 NPL::LiftToReturn(@6.9.7.3) 的调用非嵌套调用安全(@6.1.3) 。在项的嵌套深度依赖调用深度时,不满足 PTC 。
4411+**注释**
4412+需要注意,在 WHNF 的第一项嵌套调用时,Kernel 不保证递归调用的 PTC ,因为这不是尾上下文:
4413+($sequence ($define! $f ($vau () #ignore (($f)))) ($f))
4414+($sequence ($define! f (wrap ($vau () #ignore ((f))))) (f))
4415+($sequence ($define! f ($lambda () ((f)))) (f))
4416+(关于以上 klisp 在没有支持 PTC 的情形的第一个例子的疑问,另见 https://bitbucket.org/AndresNavarro/klisp/issues/12 。)
4417+类似地,对应的 NPLA1 程序同样不保证 PTC :
4418+$sequence ($def! $f ($vau () #ignore (() $f))) (() $f)
4419+$sequence ($def! f (wrap ($vau () #ignore (() f)))) (() f)
4420+$sequence ($def! f ($lambda () (() f))) (() f)
4421+应用子递归调用对应的 Scheme 程序也类似:
4422+(begin (define f (lambda () ((f)))) ((f)))
4423+(begin (define f (lambda () (f))) (f))
43624424
43634425 @7.11.6 续延名称:
43644426 模块 NPL::NPLA1 提供特定可由函数 A1::QueryContinuationName(@7.8) 查询得到的续延名称。
@@ -4898,7 +4960,7 @@
48984960 <reference> :对象引用值。
48994961 <list> :列表。参见 @9.9.4 。
49004962 <lists> :元素都是列表的列表。
4901-<boolean> :布尔(boolean) 值,即取值为 #t 或 #f 的集合,是 NPLA 类型映射(@5.5) 指定的用于条件判断的单一值的类型。
4963+<boolean> :布尔值(@4.1),即取值为 #t 或 #f 的集合,是 NPLA 类型映射(@5.5) 指定的用于条件判断的单一值的类型。
49024964 推论:<boolean> 对应的宿主类型(@5.5) 是 bool 。
49034965 <test> :类似 <object> ,通常预期为 <boolean> ,作为条件。
49044966 和 Scheme 类似但和 Kenerl 不同,非 #t 的值在决定分支时视同 #f ,以允许在 <boolean> 外自然扩展的逻辑代数操作。
@@ -5228,13 +5290,17 @@
52285290 形式参数树的子节点绑定的副作用先序(@4.4.3) 枝节点的副作用。
52295291
52305292 @9.7.4 一般 TCO/PTC(@7.10) 保证和限制:
5231-参见一般实现策略(@7.10.1) 和部分实现限制(@7.11.5) 。
5232-当前实现的规约(如 A1::Reduce(@7.4.4) )直接递归规约子表达式支持的尾上下文(@4.4.8) 较少(详见 @9.7.4.1) ,和 Scheme 对大量特定的形式提供明确的尾上下文上的 PTC 保证不同。
5233-和 Kernel 类似,这是由于缺少针对特定的特殊形式(@5.2) 的特设规则。但因为程序实现(@9.1) 等限制,当前设计和实现支持的非调用的上下文(@9.7.4.3) 较 Kernel 少。
5234-虽然不保证在所有情形下支持 PTC ,当前的实现一般支持使用自由存储分配,以尽可能地避免宿主语言的未定义行为(@5.4) :
5293+NPLA1 使用 NPLA 的规则(@5.10.2) ,不保证在所有理论允许的情形下支持明确尾上下文以支持 PTC :
5294+调用位于尾上下文,当且仅当所有的对象都可被调整生存期而支持 PTC 。
5295+满足实现行为(@4.1.3) 要求的前提下,实现可支持比这里的要求更多的 TCO 和 PTC 尾上下文。
5296+**注释**
5297+当前实现一般支持使用自由存储分配,以尽可能地避免宿主语言的未定义行为(@5.4) :
52355298 其中,异步规约(@7.9) 实现使分配以环境(@6.11.1) 表示的活动记录失败时满足常规宿主资源分配要求(@5.4.1) 。
52365299 另见语法分析(@6.1.6) 和绑定支持 API(@7.7.4) 的类似的资源分配失败的约定。
5237-满足实现行为(@4.1.3) 要求的前提下,实现可能实际支持更多的 TCO 和 PTC 尾上下文。
5300+具体实现方式参见一般实现策略(@7.10.1) 和部分实现限制(@7.11.5) 。
5301+当前实现的规约(如 A1::Reduce(@7.4.4) )直接递归规约子表达式支持的尾上下文(@4.4.8) 较少(详见 @9.7.4.1) ,和 Scheme 对大量特定的形式提供明确的尾上下文上的 PTC 保证不同。
5302+和 Kernel 类似,这是由于缺少针对特定的特殊形式(@5.2) 的特设规则。
5303+因为程序实现(@9.1) 等限制,当前设计和实现支持的合并子调用以外的上下文(@9.7.4.3) 较 Kernel 也更少,但实际涵盖范围却可能更大(@7.11.5) 。
52385304
52395305 @9.7.4.1 支持 PTC 的尾调用尾上下文:
52405306 当允许忽略非平凡析构(@7.10.4) 时,可以在尾上下文求值中进行 TCO 并支持 PTC 。
@@ -5252,7 +5318,7 @@
52525318 名称解析可能是尾上下文。
52535319
52545320 @9.7.4.3 未绑定对象:
5255-按 @5.10 的约定,项上未被绑定到活动记录上的项中的对象生存期可提前结束。
5321+按尾上下文约定(@5.10) ,项上未被绑定到活动记录上的项中的对象生存期可提前结束。
52565322 实现 PTC 时被规约时替换结果的清理(@6.4.6) 若实现支持 TCO(@7.4) 且没有实现保存未绑定操作数引起这种情形。
52575323 当前通过参考实现环境(@10) 引入的合并子已经支持了保存操作数,但若互操作(@5.3) 没有保存操作数,则可能产生问题。
52585324 应注意合并子的参数绑定引用值(@7.7.3) 在同一个尾上下文求值引起清理导致悬空引用(@9.4.3.2) 破坏内存安全(@9.4) 。
@@ -6295,7 +6361,7 @@
62956361 未指定 eq? 的比较结果可允许实现复用存储右值的驻留(@9.8.4) 对象。
62966362 eql? 实际比较宿主值的相等。允许 eqv? 和 eql? 的不同可允许一对多的类型映射(@5.5.1) 下比较对象语言中的值的相等。(而多对一的类型映射 eql? 和 eqv? 可一致地比较。)
62976363 但是,当前实现中,大多数一对多映射的类型(如环境)都没有引起使 eql? 和 eqv? 不同的比较实现,因为不同宿主值类型的对象具有足够显著的差异,在大多数上下文不通过一些具有不可忽略开销的转换机制(如锁定环境弱引用转换为环境强引用),无法直接相互替换而保证行为差异可被忽略,因此逻辑上不适合定义为相等的。
6298-而基于性能等理由,等其它一对多映射的类型(特别是可能基于宿主类型的值的子集的,如数值类型(@6.14.1) 中的 <integer> )的值的比较也没有特别的处理,而引起 eqv? 和 eql? 的不同。
6364+而基于性能等理由,等其它一对多映射的类型(特别是可能基于宿主类型的值的子集的,如 NPLA 数值类型(@6.14.1) 中的 <integer> )的值的比较也没有特别的处理,而引起 eqv? 和 eql? 的不同。
62996365 这些类型可能需要其它针对特定类型的等价谓词(如 =?(@12.2) )进行相等性的比较。
63006366 **注释**
63016367 实现中,值数据成员的相等由 ValueObject 的 == 操作定义。这对应 C++ 意义上的对象相等。
Show on old repository browser