• R/O
  • SSH

YSLib: Commit

The YSLib project - main repository


Commit MetaInfo

Revision5acfef6648155e9dc1be4915c65196a42a926ee4 (tree)
Time2022-09-14 05:23:05
AuthorFrankHB <frankhb1989@gmai...>
CommiterFrankHB

Log Message

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

Change Summary

Incremental Difference

diff -r 05c8e54ed1bb -r 5acfef664815 Tools/SHBuild/Main.cpp
--- a/Tools/SHBuild/Main.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/Tools/SHBuild/Main.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Main.cpp
1212 \ingroup MaintenanceTools
1313 \brief 宿主构建工具:递归查找源文件并编译和静态链接。
14-\version r4509
14+\version r4580
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 473
1717 \par 创建时间:
1818 2014-02-06 14:33:55 +0800
1919 \par 修改时间:
20- 2022-07-11 18:05 +0800
20+ 2022-09-14 03:06 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -39,7 +39,8 @@
3939 // ystdex::exists_substr, YSLib::uspawn, YSLib::ifstream,
4040 // IO::FetchNativeDynamicModuleExtension, YSLib::uremove,
4141 // YSLib::CommandArguments, YSLib::istringstream, EXIT_FAILURE, EXIT_SUCCESS;
42-#include YFM_YSLib_Core_YEvent // for YSLib::function, ystdex::bind1,
42+#include <ystdex/function.hpp> // for ystdex::unchecked_function;
43+#include YFM_YSLib_Core_YEvent // for ystdex::bind1, YSLib::function,
4344 // trivial_swap;
4445 #include YFM_YSLib_Service_FileSystem // for namespace YSLib::IO, IO::Path,
4546 // YSLib::Deployment;
@@ -49,7 +50,8 @@
4950 #include YFM_YSLib_Service_YTimer // for namespace std::chrono;
5051 #include <ystdex/mixin.hpp> // for ystdex::wrap_mixin_t;
5152 #include YFM_NPL_Dependency // for NPL::DepsEventType, NPL::Deliteralize,
52-// NPL::pmr::memory_resource, NPL, A1, Forms, TraceException, TraceBacktrace,
53+// NPL::pmr::memory_resource, NPL, A1, Forms, LoadStandardContext,
54+// LoadModule_SHBuild, TraceException, TraceBacktrace,
5355 // NPL::DecomposeMakefileDepList, NPL::FilterMakefileDependencies,
5456 // NPL::pmr::pool_resource;
5557 #include <ystdex/concurrency.h> // for std::mutex, std::lock_guard,
@@ -78,12 +80,13 @@
7880 using YSLib::RecordLevel;
7981 using YSLib::Notice;
8082 using YSLib::FetchStaticRef;
83+using YSLib::Logger;
8184 using YSLib::string;
8285 using YSLib::set;
8386 using YSLib::map;
8487 using YSLib::vector;
85-using YSLib::Logger;
86-using YSLib::function;
88+//! \since build 955
89+using ystdex::unchecked_function;
8790 using YSLib::Warning;
8891 using YSLib::to_std_string;
8992 using YSLib::string_view;
@@ -92,6 +95,7 @@
9295 namespace IO = YSLib::IO;
9396 using YSLib::Debug;
9497 using YSLib::Informative;
98+using YSLib::function;
9599 using IO::Path;
96100 using YSLib::String;
97101 using YSLib::FilterExceptions;
@@ -207,12 +211,12 @@
207211 // cannot use custom PMR allocators.
208212 //! \since build 928
209213 std::vector<const char*> option_details;
210- //! \since build 852
211- function<bool(const string&)> filter;
214+ //! \since build 955
215+ unchecked_function<bool(const string&)> filter;
212216
213- //! \since build 852
217+ //! \since build 955
214218 Option(const char* pfx, const char* n, const char* opt_arg,
215- function<void(string&&)> parse,
219+ unchecked_function<void(string&&)> parse,
216220 std::initializer_list<const char*> il)
217221 : prefix(pfx), name(n), option_arg(opt_arg), option_details(il),
218222 filter(ystdex::bind1(ystdex::filter_prefix<string, string,
@@ -255,9 +259,10 @@
255259 {"-xcmd,", "command", "COMMAND", [](string&& val) ynothrow{
256260 RequestedCommand = std::move(val);
257261 }, {"Specify the name of a command to run.", "If this option is set, all"
258- " other parameters not recognized as options are treated as arguments"
259- " of the command. Currently the following COMMAND name and arguments"
260- " combinations are supported:",
262+ " other following parameters not recognized as options are treated as"
263+ " arguments of the command. An option of empty COMMAND is ignored.",
264+ " Currently the"
265+ " following COMMAND name and arguments combinations are supported:",
261266 " EnsureDirectory PATH",
262267 " Make PATH available as a directory, as 'mkdir -p PATH'.",
263268 " InstallFile DST SRC",
@@ -278,7 +283,7 @@
278283 " UNIT.",
279284 " RunNPLFile SRC [ARGS...]",
280285 " Read and execute NPLA1 translation unit specified by file path"
281- " SRC with optional arguments ARGS.", OPT_des_mul}},
286+ " SRC with optional arguments ARGS.", OPT_des_last}},
282287 {"-xd,", "output directory path", "DIR_PATH", [](string&& val){
283288 string raw(NPL::Deliteralize(val));
284289
@@ -378,9 +383,7 @@
378383 }, 0x3UL, {"The target action mode.",
379384 "Value '1' represents call of AR for the final target, and '2' is LD."
380385 " Other value is reserved and to be ignored."
381- " Default value is '1'.",
382- "If this option occurs more than once, only the last one is"
383- " effective."}},
386+ " Default value is '1'.", OPT_des_last}},
384387 {"-xn,", "Target name", "OBJ_NAME", [](string&& val){
385388 PrintInfo("Target name is switched to " + Quote(val) + '.');
386389 TargetName = std::move(val);
@@ -468,34 +471,32 @@
468471 using namespace NPL;
469472 using namespace A1;
470473 using namespace Forms;
471- REPLContext context{rsrc};
472- TermNode term{context.Allocator};
474+ GlobalState global{rsrc};
475+ TermNode term{global.Allocator};
473476 #if SHBuild_UseBacktrace
474- ContextNode::ReducerSequence backtrace{context.Allocator};
477+ ContextNode::ReducerSequence backtrace{global.Allocator};
475478 #endif
479+ ContextState cs(global);
476480
477481 #if SHBuild_UseSourceInfo
478- context.UseSourceLocation = true;
482+ global.UseSourceLocation = true;
479483 #endif
480484 // NOTE: Set the filter level to avoid uninterested NPLA messages. This is
481485 // intended at least in the stage 1.
482- context.Root.Trace.FilterLevel = Logger::Level::Informative;
483- LoadStandardContext(context);
484- context.OutputStreamPtr = make_observer(&std::cout);
485-
486- auto& rctx(context.Root);
487-
488- InvokeIn(rctx, [&]{
489- context.Root.GetRecordRef().DefineChecked("env_SHBuild_",
490- GetModuleFor(rctx, [&]{
491- LoadModule_SHBuild(context);
486+ cs.Trace.FilterLevel = Logger::Level::Informative;
487+ LoadStandardContext(cs);
488+ global.OutputStreamPtr = make_observer(&std::cout);
489+ // NOTE: The ground environment is saved during the call to %InvokeIn.
490+ InvokeIn(cs, [&]{
491+ cs.GetRecordRef().DefineChecked("env_SHBuild_", GetModuleFor(cs, [&]{
492+ LoadModule_SHBuild(cs);
492493 // XXX: Overriding.
493- rctx.GetRecordRef().Define("SHBuild_BaseTerminalHook_",
494+ cs.GetRecordRef().Define("SHBuild_BaseTerminalHook_",
494495 ValueObject(function<void(const string&, const string&)>(
495496 [&](const string& n, const string& val){
496497 using namespace YSLib::Consoles;
497498 using IO::StreamPut;
498- auto& os(context.GetOutputStreamRef());
499+ auto& os(global.GetOutputStreamRef());
499500 Terminal te;
500501
501502 {
@@ -512,10 +513,10 @@
512513 os.put('"') << std::endl;
513514 })));
514515 }));
515- context.ShareCurrentSource(name);
516+ cs.ShareCurrentSource(name);
516517 try
517518 {
518- context.Root.Rewrite(NPL::ToReducer(context.Allocator, trivial_swap,
519+ cs.Rewrite(NPL::ToReducer(global.Allocator, trivial_swap,
519520 [&](ContextNode& ctx){
520521 ctx.SaveExceptionHandler();
521522 // TODO: Blocked. Use C++14 lambda initializers to simplify the
@@ -542,8 +543,8 @@
542543 LastLogGroup = LogGroup::General;
543544 TraceException(e, trace);
544545 trace.TraceFormat(Notice, "Location: %s.",
545- context.CurrentSource
546- ? context.CurrentSource->c_str() : "<unknown>");
546+ cs.CurrentSource ? cs.CurrentSource->c_str()
547+ : "<unknown>");
547548 #if SHBuild_UseBacktrace
548549 TraceBacktrace(backtrace, trace);
549550 #endif
@@ -555,7 +556,8 @@
555556 " (see the backtrace for details).");
556557 }
557558 }, ctx.GetCurrent().cbegin());
558- term = context.ReadFrom(is);
559+ term = global.ReadFrom(is, cs);
560+ global.Preprocess(term);
559561 // XXX: Is it necessary to change the text color here?
560562 return A1::ReduceOnce(term, ctx);
561563 }));
@@ -1240,8 +1242,8 @@
12401242 if(!OutputDir.empty())
12411243 bctx.OutputDir = std::move(OutputDir);
12421244 // NOTE: Remained command line arguments are moved as options
1243- // saved in the build context options. SRCPATH is expected as
1244- // the 1st build context option, following by the options in
1245+ // saved in the build global options. SRCPATH is expected as
1246+ // the 1st build global option, following by the options in
12451247 // interface specification.
12461248 yunseq(bctx.IgnoredDirs = std::move(IgnoredDirs),
12471249 bctx.Options = std::move(args), bctx.Mode = Mode);
@@ -1260,17 +1262,17 @@
12601262
12611263 StreamPut(os, sfmt("Usage: \"%s\" [OPTIONS ...] SRCPATH"
12621264 " [OPTIONS ... [-- [ARGS...]]]\n or:"
1263- " \"%s\" [OPTIONS ... [-- [[SRCPATH] ARGS ...]]]\n"
1265+ " \"%s\" [OPTIONS ... [-- [[SRCPATH] ARGS ...]]]\n\n"
12641266 "\tThis program is a tool to build the source tree, with some"
12651267 " additional functionalities. If there are no command"
12661268 " arguments, this help message is shown. Otherwise, the program"
12671269 " will try working in a specific execution mode based on"
1268- " the specific command arguments.\n"
1270+ " the specific command arguments.\n\n"
12691271 "\tThere are two execution modes, building mode and command"
12701272 " requesting mode, exclusively. In building mode, building"
12711273 " backends (commands for compiling) are called. The latter is"
12721274 " only enabled when there are some options beginned with"
1273- " '-xcmd,', see below for details.\n"
1275+ " '-xcmd,', see below for details.\n\n"
12741276 "\tThe execution of the program may entail nested instances of"
12751277 " execution initiated by the command being executed. Such"
12761278 " instances can be grouped by sessions. Each session shares the"
@@ -1278,9 +1280,9 @@
12781280 " epoch, which determines the base time point used in the"
12791281 " logging messages. The initial instance and any non-nested"
12801282 " instances have their epochs independently to other instances."
1281- "\n"
1282- "The session epoch for each instance is currently configured by"
1283- " an environment variable (see below). If its value is"
1283+ "\n\n"
1284+ "\tThe session epoch for each instance is currently configured"
1285+ " by an environment variable (see below). If its value is"
12841286 " '0', the instance is the initial one and it will maintain"
12851287 " the value for their nested instance by replace the value"
12861288 " before calling the commands for the nested instances. The"
@@ -1289,9 +1291,10 @@
12891291 " maintained value is guraranteed not empty. So, set it to '0'"
12901292 " or empty, or unset the variable before the execution of this"
12911293 " program, to ensure it independent to other instances (i.e. in"
1292- " a different session).\n"
1293- "\tThere are no checks on the values. Any behaviors depending"
1294- " on the locale-specific values are unspecified.\n"
1294+ " a different session).\n\n"
1295+ "\tThere are no checks on the values unless otherwise"
1296+ " specified. Any behaviors depending on the locale-specific"
1297+ " values are unspecified.\n\n"
12951298 "\tCurrently accepted environment variable settings are:\n\n",
12961299 prog.c_str(), prog.c_str()).c_str());
12971300 for(const auto& env : DeEnvs)
@@ -1312,22 +1315,28 @@
13121315 " names specified by '-xid,' option (see below) will also be"
13131316 " ignored.\n\n"
13141317 "OPTIONS ...\nOPTIONS ... -- [[SRCPATH] ARGS ...]\n"
1315- "\tThe options and arguments for the tool execution. After"
1316- " '--', options parsing is turned off and every remained"
1317- " command line argument (if any) is interpreted as an argument,"
1318- " except that in building mode, the 1st command line argument"
1319- " after '--' (if any) is treated as SRCPATH when there is no"
1320- " SRCPATH before '--'.\n"
1321- "\tRecognized options are handled in this program, and the"
1322- " remained arguments will either be the arguments to the"
1323- " command specified in the options in command requesting mode,"
1324- " or as options come after values of the environment variable"
1318+ "\tThe options and arguments for the tool execution. Options"
1319+ " parsing in this program regonizes options from command line"
1320+ " arguments. After '--', options parsing is turned off and"
1321+ " every remained command line argument (if any) is interpreted"
1322+ " as an argument, except that in building mode, the 1st command"
1323+ " line argument after '--' (if any) is treated as SRCPATH when"
1324+ " there is no recognized SRCPATH before '--'.\n"
1325+ "\tFor recognized options having a fixed prefix, if the"
1326+ " following substring in the option is empty, the whole option"
1327+ " is ignored. Otherwise, it is then handled in some"
1328+ " option-specific manner, which may or may not support multiple"
1329+ " instances of the option.\n"
1330+ "\tThe remained command line arguments not recognized as"
1331+ " options will either be the arguments to the command specified"
1332+ " in the options in command requesting mode, or as options"
1333+ " coming after values of the environment variable"
13251334 " SHBuild_CFLAGS or SHBuild_CXXFLAGS and a single space"
13261335 " character when CC or CXX is called in building mode,"
13271336 " respectively. In building mode, all command line arguments"
1328- " except SRCPATH and the recoginzed options as well as the"
1337+ " except SRCPATH and the recoginzed options, as well as the"
13291338 " (prefixed) values specified by the environment variables"
1330- " SHBuild_CFLAGS or SHBuild_CXXFLAGS will be sent to the"
1339+ " SHBuild_CFLAGS or SHBuild_CXXFLAGS, will be sent to the"
13311340 " building backends.\n"
13321341 "\tThe recognized options are:\n\n");
13331342 for(const auto& opt : OptionsTable)
diff -r 05c8e54ed1bb -r 5acfef664815 YBase/source/ystdex/memory_resource.cpp
--- a/YBase/source/ystdex/memory_resource.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YBase/source/ystdex/memory_resource.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file memory_resource.cpp
1212 \ingroup YStandardEx
1313 \brief 存储资源。
14-\version r1841
14+\version r1844
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 842
1717 \par 创建时间:
1818 2018-10-27 19:30:12 +0800
1919 \par 修改时间:
20- 2022-06-27 03:57 +0800
20+ 2022-09-05 22:07 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -857,14 +857,14 @@
857857 // https://bugs.llvm.org/show_bug.cgi?id=43638. The support in LLVM
858858 // IR has been changed since LLVM 14 (see
859859 // https://releases.llvm.org/14.0.0/docs/ReleaseNotes.html#changes-to-the-llvm-ir),
860- // but just keep it the assumption conservative.
861-#if YB_IMPL_CLANGPP
860+ // but just keep the assumption conservative.
861+#if YB_IMPL_CLANGPP >= 100000
862862 YB_Diag_Push
863863 YB_Diag_Ignore(builtin-assume-aligned-alignment)
864864 #endif
865865 yunused(upstream_rsrc->allocate(size_t(-1) >> 1,
866866 ~(size_t(-1) >> 1)));
867-#if YB_IMPL_CLANGPP
867+#if YB_IMPL_CLANGPP >= 100000
868868 YB_Diag_Pop
869869 #endif
870870 yassume(false);
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/Helper/Environment.h
--- a/YFramework/include/Helper/Environment.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/Helper/Environment.h Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Environment.h
1212 \ingroup Helper
1313 \brief 环境。
14-\version r1146
14+\version r1160
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 521
1717 \par 创建时间:
1818 2013-02-08 01:28:03 +0800
1919 \par 修改时间:
20- 2022-09-05 08:41 +0800
20+ 2022-09-13 06:37 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -46,7 +46,7 @@
4646 # define YF_Helper_Environment_NPL_UseSourceInfo false
4747 #endif
4848 #include YFM_YSLib_Core_YShellDefinition // for ostringstream;
49-#include YFM_NPL_NPLA1 // for NPL::A1::REPLContext, NPL::TermNode,
49+#include YFM_NPL_NPLA1 // for NPL::A1::GlobalState, NPL::TermNode,
5050 // NPL::ContextNode, NPL::A1::InvokeIn, NPL::Environment,
5151 // NPL::A1::EnvironmentGuard, NPL::ToReducer, NPL::A1::ReduceOnce;
5252
@@ -76,6 +76,7 @@
7676 /*!
7777 \brief 应用程序环境。
7878 \warning 非线程安全。
79+\warning 初始化后不检查成员使用的分配器相等性。
7980 \since build 378
8081
8182 应用程序实例使用的环境。
@@ -92,12 +93,15 @@
9293 //! \since build 954
9394 //@{
9495 ostringstream DefaultOutputStream;
95- NPL::A1::REPLContext Context;
96- NPL::TermNode Term{Context.Allocator};
96+ //! \since build 955
97+ NPL::A1::GlobalState Global;
98+ //! \since build 955
99+ NPL::A1::ContextState Main{Global};
100+ NPL::TermNode Term{Global.Allocator};
97101
98102 private:
99103 # if YF_Helper_Environment_NPL_UseBacktrace
100- NPL::ContextNode::ReducerSequence backtrace{Context.Allocator};
104+ NPL::ContextNode::ReducerSequence backtrace{Global.Allocator};
101105 # endif
102106 //@}
103107
@@ -129,7 +133,7 @@
129133 {
130134 // NOTE: The ground environment is saved during the call to
131135 // %NPL::A1::InvokeIn.
132- NPL::A1::InvokeIn(Context.Root, [&]{
136+ NPL::A1::InvokeIn(Main, [&]{
133137 RewriteNPLA1(f);
134138 });
135139 }
@@ -141,11 +145,11 @@
141145 void
142146 ExecuteNPLA1(_func f, shared_ptr<NPL::Environment> p_env)
143147 {
144- YAssert(p_env != Context.Root.GetRecordPtr(),
148+ YAssert(p_env != Main.GetRecordPtr(),
145149 "Invalid environment found.");
146150
147- NPL::A1::EnvironmentGuard gd(Context.Root,
148- Context.Root.SwitchEnvironmentUnchecked(std::move(p_env)));
151+ NPL::A1::EnvironmentGuard gd(Main,
152+ Main.SwitchEnvironmentUnchecked(std::move(p_env)));
149153
150154 RewriteNPLA1(f);
151155 }
@@ -158,10 +162,11 @@
158162 void
159163 RewriteNPLA1(_func f)
160164 {
161- Context.Root.Rewrite(NPL::ToReducer(Context.Allocator, trivial_swap,
165+ Main.Rewrite(NPL::ToReducer(Global.Allocator, trivial_swap,
162166 [&](NPL::ContextNode& ctx){
163167 PrepareExecution(ctx);
164168 f(Term);
169+ Global.Preprocess(Term);
165170 return NPL::A1::ReduceOnce(Term, ctx);
166171 }));
167172 }
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/NPL/Configuration.h
--- a/YFramework/include/NPL/Configuration.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/NPL/Configuration.h Wed Sep 14 04:23:05 2022 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2012-2016, 2019-2021 FrankHB.
2+ © 2012-2016, 2019-2022 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 Configuration.h
1212 \ingroup NPL
1313 \brief 配置设置。
14-\version r407
14+\version r445
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 334
1717 \par 创建时间:
1818 2012-08-27 15:15:08 +0800
1919 \par 修改时间:
20- 2021-12-29 01:20 +0800
20+ 2022-09-10 02:11 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -29,8 +29,8 @@
2929 #define NPL_INC_Configuration_h_
3030
3131 #include "YModules.h"
32-#include YFM_NPL_NPLA1 // for ValueNode, NoContainer,
33-// ystdex::exclude_self_params_t;
32+#include YFM_NPL_NPLA1 // for YSLib::default_allocator, byte, ValueNode,
33+// NoContainer, ystdex::exclude_self_params_t;
3434
3535 namespace NPL
3636 {
@@ -42,17 +42,10 @@
4242 /*!
4343 \brief 加载 NPLA1 翻译单元。
4444 \throw LoggedEvent 警告:被加载配置中的实体转换失败。
45-\since build 665
45+\since build 955
4646 */
47-template<typename _type, typename... _tParams>
48-YB_ATTR_nodiscard ValueNode
49-LoadNode(_type&& tree, _tParams&&... args)
50-{
51- TryRet(A1::TransformNode(std::forward<TermNode>(tree), yforward(args)...))
52- CatchThrow(bad_any_cast& e, LoggedEvent(YSLib::sfmt(
53- "Bad NPLA1 tree found: cast failed from [%s] to [%s] .", e.from(),
54- e.to()), YSLib::Warning))
55-}
47+YF_API YB_ATTR_nodiscard ValueNode
48+LoadNode(const TermNode&);
5649
5750 } // namespace A1;
5851
@@ -64,27 +57,44 @@
6457 */
6558 class YF_API Configuration
6659 {
60+public:
61+ //! \since build 955
62+ using allocator_type = YSLib::default_allocator<yimpl(byte)>;
63+
6764 private:
6865 ValueNode root;
6966
7067 public:
68+ //! \brief 无参数构造:默认构造。
7169 DefDeCtor(Configuration)
70+ /*!
71+ \brief 构造:使用分配器。
72+ \since build 955
73+ */
74+ Configuration(allocator_type a)
75+ : root(a)
76+ {}
7277 //! \since build 376
73- //@{
7478 Configuration(const ValueNode& node)
7579 : root(node)
7680 {}
81+ //! \since build 376
7782 Configuration(ValueNode&& node)
7883 : root(std::move(node))
7984 {}
80- //@}
8185 //! \since build 848
8286 template<typename... _tParams, yimpl(typename
8387 = ystdex::exclude_self_params_t<Configuration, _tParams...>)>
84- explicit
88+ explicit inline
8589 Configuration(_tParams&&... args)
8690 : root(NoContainer, yforward(args)...)
8791 {}
92+ //! \since build 955
93+ template<typename... _tParams>
94+ explicit inline
95+ Configuration(std::allocator_arg_t, allocator_type a, _tParams&&... args)
96+ : root(std::allocator_arg, a, NoContainer, yforward(args)...)
97+ {}
8898 DefDeCopyMoveCtorAssignment(Configuration)
8999
90100 DefGetter(const ynothrow, const ValueNode&, Root, root)
@@ -105,6 +115,11 @@
105115 \since build 341
106116 */
107117 DefGetter(ynothrow, ValueNode&&, NodeRRef, std::move(root))
118+
119+ //! \since build 955
120+ YB_ATTR_nodiscard YB_PURE
121+ PDefH(allocator_type, get_allocator, ) const ynothrow
122+ ImplRet(root.get_allocator())
108123 };
109124
110125 /*!
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/NPL/Dependency.h
--- a/YFramework/include/NPL/Dependency.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/NPL/Dependency.h Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Dependency.h
1212 \ingroup NPL
1313 \brief 依赖管理。
14-\version r617
14+\version r640
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 623
1717 \par 创建时间:
1818 2015-08-09 22:12:37 +0800
1919 \par 修改时间:
20- 2022-09-05 08:50 +0800
20+ 2022-09-14 01:32 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -29,7 +29,7 @@
2929 #define NPL_INC_Dependency_h_
3030
3131 #include "YModules.h"
32-#include YFM_NPL_NPLA1 // for string, vector, REPLContext, YSLib::unique_ptr;
32+#include YFM_NPL_NPLA1 // for string, vector, GlobalState, YSLib::unique_ptr;
3333 #include <istream> // for std::istream;
3434 #include <ystdex/scope_guard.hpp> // for ystdex::guard;
3535
@@ -79,11 +79,11 @@
7979 YB_ATTR_nodiscard YF_API YB_NONNULL(1) YSLib::unique_ptr<std::istream>
8080 OpenFile(const char*);
8181
82-//! \since build 899
82+//! \since build 955
8383 //@{
8484 //! \brief 打开指定路径的文件作为 NPL 输入流并在上下文设置源代码名称。
8585 YB_ATTR_nodiscard YF_API YSLib::unique_ptr<std::istream>
86-OpenUnique(REPLContext&, string);
86+OpenUnique(ContextState&, string);
8787
8888
8989 /*!
@@ -94,7 +94,7 @@
9494 \sa TryLoadSource
9595 */
9696 YB_NONNULL(2) YF_API void
97-PreloadExternal(REPLContext&, const char*);
97+PreloadExternal(ContextState&, const char*);
9898
9999 //! \note 以参数指定的项的第一个子项作为 string 类型的名称指定翻译单元。
100100 //@{
@@ -105,7 +105,7 @@
105105 \sa OpenUnique
106106 */
107107 YF_API ReductionStatus
108-ReduceToLoadExternal(TermNode&, ContextNode&, REPLContext&);
108+ReduceToLoadExternal(TermNode&, ContextNode&);
109109
110110 /*!
111111 \brief 异步规约加载外部翻译单元。
@@ -113,7 +113,7 @@
113113 \sa ReduceToLoadExternal
114114 */
115115 YF_API ReductionStatus
116-RelayToLoadExternal(ContextNode&, TermNode&, REPLContext&);
116+RelayToLoadExternal(ContextNode&, TermNode&);
117117 //@}
118118 //@}
119119
@@ -122,7 +122,7 @@
122122
123123 /*!
124124 \note 支持的具体语法形式参考 Documentation::NPL 。
125-\since build 839
125+\since build 955
126126 */
127127 //@{
128128 /*!
@@ -135,7 +135,7 @@
135135 当前派生实现:求值合并子调用前已加载字符串模块或等价方式初始化为模块 std.strings 。
136136 */
137137 YF_API void
138-LoadGroundContext(REPLContext&);
138+LoadGroundContext(ContextState&);
139139
140140 /*!
141141 \pre 已加载基础 NPLA1 上下文或等价方式初始化。
@@ -146,30 +146,27 @@
146146 //@{
147147 /*!
148148 \brief 加载续延模块。
149-\since build 943
150149
151150 加载一等续延和相关操作。
152151 */
153152 YF_API void
154-LoadModule_std_continuations(REPLContext&);
153+LoadModule_std_continuations(ContextState&);
155154
156155 /*!
157156 \brief 加载代理求值模块。
158-\since build 856
159157
160158 加载 promise 类型和延迟求值等操作。
161159 */
162160 YF_API void
163-LoadModule_std_promises(REPLContext&);
161+LoadModule_std_promises(ContextState&);
164162
165163 /*!
166164 \brief 加载数学功能模块。
167-\since build 930
168165
169166 加载数学功能相关操作。
170167 */
171168 YF_API void
172-LoadModule_std_math(REPLContext&);
169+LoadModule_std_math(ContextState&);
173170
174171 /*!
175172 \brief 加载字符串模块。
@@ -177,7 +174,7 @@
177174 加载字符串库操作。
178175 */
179176 YF_API void
180-LoadModule_std_strings(REPLContext&);
177+LoadModule_std_strings(ContextState&);
181178
182179 /*!
183180 \pre 当前派生实现:已加载和初始化依赖的模块,在当前环境可访问的指定的模块名称。
@@ -188,14 +185,13 @@
188185 \brief 加载输入/输出模块。
189186 \pre 断言:第二参数非空。
190187 \note 第二参数指定基础环境。
191-\since build 942
192188
193189 加载输入/输出库操作。
194190 派生实现依赖模块:
195191 字符串模块 std.strings 。
196192 */
197193 YF_API void
198-LoadModule_std_io(REPLContext&, const shared_ptr<Environment>&);
194+LoadModule_std_io(ContextState&, const shared_ptr<Environment>&);
199195
200196 /*!
201197 \brief 加载系统模块。
@@ -206,13 +202,12 @@
206202 字符串模块 std.strings 。
207203 */
208204 YF_API void
209-LoadModule_std_system(REPLContext&);
205+LoadModule_std_system(ContextState&);
210206
211207 /*!
212208 \brief 加载模块管理模块。
213209 \pre 断言:第二参数非空。
214210 \note 第二参数指定基础环境。
215-\since build 942
216211
217212 加载模块管理操作。
218213 派生实现依赖模块:
@@ -222,7 +217,7 @@
222217 系统模块 std.system 。
223218 */
224219 YF_API void
225-LoadModule_std_modules(REPLContext&, const shared_ptr<Environment>&);
220+LoadModule_std_modules(ContextState&, const shared_ptr<Environment>&);
226221 //@}
227222
228223 /*!
@@ -232,7 +227,7 @@
232227 用于内部使用。加载的环境的具体内容未指定。
233228 */
234229 YF_API void
235-LoadModule_SHBuild(REPLContext&);
230+LoadModule_SHBuild(ContextState&);
236231 //@}
237232 //@}
238233
@@ -245,7 +240,7 @@
245240 \sa LoadModule_std_promises
246241 \sa LoadModule_std_strings
247242 \sa LoadModule_std_system
248-\since build 898
243+\since build 955
249244
250245 调用 LoadGroundContext 并加载标准库模块。
251246 加载的标准库模块名称符合 NPLA1 参考实现扩展环境约定。
@@ -253,7 +248,7 @@
253248 加载的标准库模块被冻结。
254249 */
255250 YF_API void
256-LoadStandardContext(REPLContext&);
251+LoadStandardContext(ContextState&);
257252
258253 } // namespace Forms;
259254
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/NPL/NPLA1.h
--- a/YFramework/include/NPL/NPLA1.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/NPL/NPLA1.h Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1.h
1212 \ingroup NPL
1313 \brief NPLA1 公共接口。
14-\version r9803
14+\version r10005
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 472
1717 \par 创建时间:
1818 2014-02-02 17:58:24 +0800
1919 \par 修改时间:
20- 2022-09-05 10:51 +0800
20+ 2022-09-14 02:53 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -32,8 +32,8 @@
3232 #include YFM_NPL_NPLA // for NPLATag, TermNode, ContextNode,
3333 // ystdex::equality_comparable, std::declval, ystdex::exclude_self_t,
3434 // trivial_swap_t, trivial_swap, ystdex::ref_eq, string_view,
35-// CombineReductionResult, pmr::memory_resource, make_observer, TNIter,
36-// LiftOtherValue, ValueNode, NPL::Deref, NPL::AsTermNode,
35+// CombineReductionResult, SourceName, make_observer, YSLib::allocate_shared,
36+// TNIter, LiftOtherValue, ValueNode, NPL::Deref, NPL::AsTermNode,
3737 // std::make_move_iterator, std::next, ystdex::retry_on_cond, std::find_if,
3838 // ystdex::exclude_self_params_t, YSLib::AreEqualHeld, ystdex::or_,
3939 // std::is_constructible, ystdex::decay_t, ystdex::expanded_caller,
@@ -43,9 +43,8 @@
4343 // CountPrefix, ArityMismatch, TermTags, RegularizeTerm, ystdex::invoke,
4444 // AssignParent, TokenValue, function, Environment, ParseResultOf, ByteParser,
4545 // SourcedByteParser, type_info, type_id, SourceInformation, std::bind,
46-// std::placeholders::_1, std::integral_constant, SourceName, NPL::tuple,
47-// NPL::get, NPL::forward_as_tuple, ReaderState, YSLib::allocate_shared,
48-// ystdex::is_bitwise_swappable;
46+// std::placeholders::_1, std::integral_constant, pmr::memory_resource,
47+// ReaderState, ystdex::is_bitwise_swappable;
4948 #include YFM_YSLib_Core_YEvent // for YSLib::GHEvent, YSLib::GCombinerInvoker,
5049 // YSLib::GDefaultLastValueInvoker;
5150 #include <ystdex/algorithm.hpp> // for ystdex::fast_any_of, ystdex::split;
@@ -299,6 +298,9 @@
299298 //@}
300299
301300
301+//! \since build 955
302+class GlobalState;
303+
302304 /*!
303305 \brief NPLA1 上下文状态。
304306 \note 扩展 ContextNode 。
@@ -310,13 +312,7 @@
310312 class YF_API ContextState : public ContextNode
311313 {
312314 public:
313- // XXX: Allocators are not used here for performance.
314- //! \brief 叶遍。
315- EvaluationPasses EvaluateLeaf{};
316- //! \brief 列表遍。
317- EvaluationPasses EvaluateList{};
318- //! \brief 字面量遍。
319- LiteralPasses EvaluateLiteral{};
315+ lref<const GlobalState> Global;
320316 //! \brief 守卫遍。
321317 GuardPasses Guard{};
322318 /*!
@@ -347,12 +343,17 @@
347343 \since build 948
348344 */
349345 mutable ValueObject OperatorName{};
346+ /*!
347+ \brief 当前源代码名称。
348+ \since build 955
349+ */
350+ SourceName CurrentSource{};
350351
351352 /*!
352- \brief 构造:使用指定的存储资源。
353- \since build 845
353+ \brief 构造:使用指定的全局状态引用。
354+ \since build 955
354355 */
355- ContextState(pmr::memory_resource&);
356+ ContextState(const GlobalState&);
356357 //! \brief 复制构造:复制下一项的指针以外的子对象。
357358 ContextState(const ContextState&);
358359 //! \brief 转移构造:转移基类子对象和下一项的指针,并复制其余子对象。
@@ -431,8 +432,8 @@
431432 \note 默认不需要重规约。这可被求值遍改变。
432433 \note 可被求值遍调用以实现递归求值。
433434 \warning 若不满足上下文状态类型要求,行为未定义。
434- \sa EvaluateLeaf
435- \sa EvaluateList
435+ \sa GlobalState::EvaluateLeaf
436+ \sa GlobalState::EvaluateList
436437 \sa ReduceOnce
437438 \sa ValueToken
438439 \since build 878
@@ -445,9 +446,9 @@
445446 在已进入异步规约时,则在上下文最后一次规约状态设置为
446447 ReductionStatus::Retrying 时,不继续设置异步求值遍而跳过剩余的求值遍。
447448 对应不同的节点次级结构分类,一次迭代按以下顺序选择以下分支之一,按需规约子项:
448- 对枝节点调用 EvaluateList 求值;
449+ 对枝节点调用 Global 的 EvaluateList 求值;
449450 对空节点或值数据成员为 ValueToken 类型的值的叶节点不进行操作;
450- 对其它叶节点调用 EvaluateList 求值。
451+ 对其它叶节点调用 Global 的 EvaluateList 求值。
451452 支持重规约。异步重规约由 ContextNode 支持。
452453 此处约定的迭代中对节点的具体结构分类默认也适用于其它 NPLA1 实现 API ;
453454 例外情况应单独指定明确的顺序。
@@ -495,6 +496,18 @@
495496 RewriteTermGuarded(TermNode&);
496497 //@}
497498
499+ /*!
500+ \brief 设置当前源代码名称为参数指定初始化的新分配的共享名称。
501+ \since build 955
502+ */
503+ template<typename... _tParams>
504+ void
505+ ShareCurrentSource(_tParams&&... args)
506+ {
507+ CurrentSource = YSLib::allocate_shared<string>(get_allocator(),
508+ yforward(args)...);
509+ }
510+
498511 //! \since build 948
499512 //@{
500513 /*!
@@ -523,9 +536,7 @@
523536 friend PDefH(void, swap, ContextState& x, ContextState& y) ynothrow
524537 ImplExpr(swap(static_cast<ContextNode&>(x), static_cast<ContextNode&>(
525538 y)), swap(x.combining_term_ptr, y.combining_term_ptr),
526- swap(x.next_term_ptr, y.next_term_ptr), swap(x.EvaluateLeaf,
527- y.EvaluateLeaf), swap(x.EvaluateList, y.EvaluateList),
528- swap(x.EvaluateLiteral, y.EvaluateLiteral), swap(x.Guard, y.Guard))
539+ swap(x.next_term_ptr, y.next_term_ptr), swap(x.Guard, y.Guard))
529540 };
530541
531542
@@ -883,8 +894,8 @@
883894 第三参数表示记号在源代码中的位置。
884895 */
885896 YF_API void
886-ParseLeafWithSourceInformation(TermNode&, string_view,
887- const shared_ptr<string>&, const SourceLocation&);
897+ParseLeafWithSourceInformation(TermNode&, string_view, const SourceName&,
898+ const SourceLocation&);
888899 //@}
889900
890901
@@ -1429,7 +1440,7 @@
14291440 \pre 第二参数引用的对象是 NPLA1 上下文状态或 public 继承的派生类。
14301441 \return 求值标识符的结果或 ReductionStatus::Retained 。
14311442 \sa CategorizeLexeme
1432-\sa ContextNode::EvaluateLiteral
1443+\sa GlobalState::EvaluateLiteral
14331444 \sa DeliteralizeUnchecked
14341445 \sa EvaluateIdentifier
14351446 \since build 736
@@ -1547,20 +1558,24 @@
15471558 NPL::SwitchToFreshEnvironment(ctx, yforward(args)...));
15481559 }
15491560
1550-//! \since build 942
1551-//@{
1552-//! \brief 加载代码调用。
1561+/*!
1562+\brief 加载代码调用。
1563+\since build 955
1564+*/
15531565 template<typename _fCallable, typename... _tParams>
1554-void
1566+auto
15551567 InvokeIn(ContextNode& ctx, _fCallable&& f, _tParams&&... args)
1568+ -> decltype(ystdex::invoke(yforward(f), yforward(args)...))
15561569 {
15571570 ValueObject parent(ctx.WeakenRecord());
15581571 auto gd(GuardFreshEnvironment(ctx));
15591572
15601573 AssignParent(ctx, std::move(parent));
1561- ystdex::invoke(yforward(f), yforward(args)...);
1574+ return ystdex::invoke(yforward(f), yforward(args)...);
15621575 }
15631576
1577+//! \since build 942
1578+//@{
15641579 /*!
15651580 \brief 加载代码作为模块。
15661581 \return 作为环境模块的环境对象强引用。
@@ -1804,7 +1819,7 @@
18041819 \sa ReduceFirst
18051820 \sa ReduceHeadEmptyList
18061821 \sa ReduceLeafToken
1807-\since build 842
1822+\since build 955
18081823
18091824 设置默认解释的求值遍到第一参数指定的上下文的列表求值遍和叶求值遍中。
18101825 列表求值遍等效第二参数后依次添加 ReduceFirst 、ReduceHeadEmptyList 和
@@ -1812,7 +1827,7 @@
18121827 叶求值遍设置为 ReduceLeafToken 。
18131828 */
18141829 YF_API void
1815-SetupDefaultInterpretation(ContextState&, EvaluationPasses);
1830+SetupDefaultInterpretation(GlobalState&, EvaluationPasses);
18161831
18171832 /*!
18181833 \brief 设置参数指定的上下文为尾上下文。
@@ -1837,8 +1852,9 @@
18371852 // XXX: Use %function instead of %ystdex::unchecked_function is no less
18381853 // efficient.
18391854 //! \brief 泛型标记器:分析解析结果元素转换为可能包含记号的节点。
1840-template<typename _fParse>
1841-using GTokenizer = function<TermNode(const GParsedValue<_fParse>&)>;
1855+template<typename _fParse, typename... _tParams>
1856+using GTokenizer
1857+ = function<TermNode(const GParsedValue<_fParse>&, _tParams...)>;
18421858 //@}
18431859
18441860 /*!
@@ -1848,7 +1864,7 @@
18481864 using Tokenizer = GTokenizer<ByteParser>;
18491865
18501866 //! \brief 标记器:分析带有源代码位置信息的词素转换为可能包含记号的节点。
1851-using SourcedTokenizer = GTokenizer<SourcedByteParser>;
1867+using SourcedTokenizer = GTokenizer<SourcedByteParser, ContextState&>;
18521868
18531869
18541870 //! \ingroup NPLDiagnostics
@@ -2014,7 +2030,7 @@
20142030 //! \brief 环境守卫类型。
20152031 template<class _tGuard>
20162032 using GKeptGuardAction = decltype(std::bind(KeepGuard<_tGuard>,
2017- std::declval<_tGuard&>(), std::placeholders::_1));
2033+ std::declval<_tGuard&&>(), std::placeholders::_1));
20182034
20192035 /*!
20202036 \brief 转移保持环境守卫。
@@ -2039,15 +2055,19 @@
20392055
20402056
20412057 /*
2042-\brief REPL 上下文。
2058+\brief 全局状态。
20432059 \warning 非虚析构。
2044-\since build 740
2060+\warning 初始化后不检查成员使用的分配器相等性。
2061+\since build 955
20452062
2046-REPL 表示读取-求值-输出循环。
2063+提供各个上下文共享的实现 REPL(读取-求值-输出循环)的数据和可变状态。
20472064 每个循环包括一次翻译。
2048-这只是一个基本的可扩展实现。功能通过操作数据成员控制。
2065+这只是一个基本的可扩展实现。
2066+部分功能可通过操作数据成员控制,但一般在初始化后不改变非可变状态,
2067+ 因此通常使用 const GlobalState& 访问,且不提供全局状态锁。
2068+一般仅需锁定派生实现中的可能共享操可变状态。
20492069 */
2050-class YF_API REPLContext
2070+class YF_API GlobalState
20512071 {
20522072 public:
20532073 //! \since build 891
@@ -2072,21 +2092,23 @@
20722092 \brief 加载器。
20732093 \since build 899
20742094
2075- 接受 REPL 上下文、规约上下文和指定名称,转换翻译单元内容为待求值节点的例程。
2095+ 接受上下文状态和指定名称,转换翻译单元内容为待求值节点的例程。
20762096 */
2077- using Loader = function<TermNode(REPLContext&, ContextNode&, string)>;
2097+ using Loader = function<TermNode(ContextState&, string)>;
20782098
20792099 private:
2100+ //! \since build 891
20802101 struct LeafConverter final
20812102 {
2082- const REPLContext& Context;
2103+ //! \since build 955
2104+ ContextState& Context;
20832105
20842106 YB_ATTR_nodiscard
20852107 PDefHOp(TermNode, (), const GParsedValue<ByteParser>& val) const
2086- ImplRet(Context.ConvertLeaf(val))
2108+ ImplRet(Context.Global.get().ConvertLeaf(val))
20872109 YB_ATTR_nodiscard PDefHOp(TermNode, (),
20882110 const GParsedValue<SourcedByteParser>& val) const
2089- ImplRet(Context.ConvertLeafSourced(val))
2111+ ImplRet(Context.Global.get().ConvertLeafSourced(val, Context))
20902112 };
20912113
20922114 public:
@@ -2095,11 +2117,12 @@
20952117 \since build 845
20962118 */
20972119 TermNode::allocator_type Allocator;
2098- /*!
2099- \brief 上下文根节点。
2100- \since build 842
2101- */
2102- ContextState Root;
2120+ //! \brief 叶遍。
2121+ EvaluationPasses EvaluateLeaf{Allocator};
2122+ //! \brief 列表遍。
2123+ EvaluationPasses EvaluateList{Allocator};
2124+ //! \brief 字面量遍。
2125+ LiteralPasses EvaluateLiteral{Allocator};
21032126 /*!
21042127 \brief 预处理例程:每次翻译时预先处理调用的公共例程。
21052128 \sa Prepare
@@ -2125,8 +2148,6 @@
21252148 */
21262149 SourcedTokenizer ConvertLeafSourced;
21272150 //@}
2128- //! \brief 当前源代码名称。
2129- SourceName CurrentSource{};
21302151 /*!
21312152 \brief 默认启用源代码位置。
21322153 \sa Perform
@@ -2154,16 +2175,12 @@
21542175 */
21552176 //@{
21562177 /*!
2157- \brief 构造:使用默认的解释、指定的存储资源和默认的叶节点词素转换器。
2178+ \brief 构造:使用默认解释、指定的存储资源和默认的叶节点词素转换器。
21582179 \sa ParseLeaf
2159- \since build 879
21602180 */
2161- REPLContext(pmr::memory_resource& = NPL::Deref(pmr::new_delete_resource()));
2162- /*!
2163- \brief 构造:使用默认的解释、指定的存储资源和叶节点词素转换器。
2164- \since build 891
2165- */
2166- REPLContext(Tokenizer, SourcedTokenizer,
2181+ GlobalState(pmr::memory_resource& = NPL::Deref(pmr::new_delete_resource()));
2182+ //! \brief 构造:使用默认解释、指定的存储资源和叶节点词素转换器。
2183+ GlobalState(Tokenizer, SourcedTokenizer,
21672184 pmr::memory_resource& = NPL::Deref(pmr::new_delete_resource()));
21682185 //@}
21692186
@@ -2181,142 +2198,75 @@
21812198 \brief 取输出流引用。
21822199 \throw ystdex::unsupported 不支持的输出流:流指针为空。
21832200 \sa OutputStreamPtr
2201+ \since build 901
21842202 */
21852203 YB_ATTR_nodiscard YB_PURE std::ostream&
21862204 GetOutputStreamRef() const;
21872205
21882206 /*!
21892207 \brief 默认加载。
2190- \since build 899
21912208
21922209 以参数作为文件名读取内容并转换。
21932210 不处理文件名。
21942211 若被平台支持,使用相对路径文件名指定的文件位置可能和当前工作目录相关。
21952212 */
21962213 YB_ATTR_nodiscard static TermNode
2197- DefaultLoad(REPLContext&, ContextNode&, string);
2214+ DefaultLoad(ContextState&, string);
21982215
2199-private:
2200- //! \since build 891
2201- template<typename _tParam>
2202- YB_ATTR_nodiscard inline ContextNode&
2203- FetchContextParameter(_tParam&&)
2204- {
2205- return Root;
2206- }
2207- //! \since build 899
2208- template<typename... _tParams>
2209- YB_ATTR_nodiscard inline ContextNode&
2210- FetchContextParameter(NPL::tuple<_tParams..., ContextNode&> args)
2211- {
2212- return NPL::get<sizeof...(_tParams)>(args);
2213- }
2214-
2215-public:
22162216 /*!
2217+ \brief 执行:从指定参数指定的来源读取并翻译源代码,并返回处理结果。
22172218 \exception std::invalid_argument 异常中立:由 ReadFrom 抛出。
2219+ \sa Preprocess
22182220 \sa ReadFrom
22192221 \sa Reduce
2220- \since build 891
22212222 */
2222- //@{
2223- //! \brief 加载:从指定参数指定的来源读取并翻译源代码。
2224- //@{
2225- template<typename... _tParams>
2226- inline void
2227- LoadFrom(_tParams&&... args)
2228- {
2229- auto term(ReadFrom(yforward(args)...));
2230-
2231- Reduce(term,
2232- FetchContextParameter(NPL::forward_as_tuple(yforward(args)...)));
2233- }
2234- //@}
2235-
2236- //! \brief 执行循环:从指定参数指定的来源读取并翻译源代码,并返回处理结果。
22372223 template<typename... _tParams>
22382224 // XXX: No %YB_ATTR_nodiscard.
22392225 inline TermNode
2240- Perform(_tParams&&... args)
2226+ Perform(ContextState& cs, _tParams&&... args) const
22412227 {
2242- auto term(ReadFrom(yforward(args)...));
2228+ auto term(ReadFrom(yforward(args)..., cs));
22432229
2244- Reduce(term,
2245- FetchContextParameter(NPL::forward_as_tuple(yforward(args)...)));
2230+ Preprocess(term);
2231+ Reduce(term, cs);
22462232 return term;
22472233 }
2248- //@}
22492234
22502235 /*!
2251- \brief 准备规约项:分析输入并标记记号节点和预处理。
2252- \return 预处理后的项。
2253- \sa Preprocess
2254- \since build 890
2255-
2256- 按需分析并调用预处理例程。
2257- 词素的处理由分析完成,不需单独调用 TokenizeTerm 转换。
2258- */
2259- //@{
2260- YB_ATTR_nodiscard PDefH(TermNode, Prepare, TermNode&& term) const
2261- ImplRet(Preprocess(term), std::move(term))
2262- /*!
2236+ \brief 准备规约项:分析输入并标记记号节点。
22632237 \return 从参数输入读取的准备的项。
22642238 \sa SContext::Analyze
2239+
2240+ 按需分析。
2241+ 词素的处理由分析完成,不需单独调用 TokenizeTerm 转换。
2242+ 之后可能需另行调用预处理例程。
22652243 */
22662244 template<typename... _tParams>
22672245 YB_ATTR_nodiscard TermNode
2268- Prepare(_tParams&&... args) const
2246+ Prepare(ContextState& cs, _tParams&&... args) const
22692247 {
2270- return Prepare(SContext::Analyze(std::allocator_arg, Allocator,
2271- LeafConverter{*this}, yforward(args)...));
2248+ return SContext::Analyze(std::allocator_arg, Allocator,
2249+ LeafConverter{cs}, yforward(args)...);
22722250 }
2273- //@}
22742251
22752252 /*!
22762253 \brief 读取:从指定参数指定的来源输入源代码并准备规约项。
22772254 \return 从参数输入读取的准备的项。
22782255 \sa Prepare
2279- \since build 891
2256+ \since build 955
22802257 */
22812258 //@{
22822259 template<class _type>
22832260 YB_ATTR_nodiscard inline TermNode
2284- ReadFrom(_type&& input)
2261+ ReadFrom(_type&& input, ContextState& cs) const
22852262 {
2286- return ReadFrom(yforward(input), Root);
2287- }
2288- //! \since bulid 899
2289- template<class _type>
2290- YB_ATTR_nodiscard inline TermNode
2291- ReadFrom(_type&& input, ReaderState& rs)
2292- {
2293- return ReadFrom(yforward(input), rs, Root);
2263+ return ReadFrom(LoadOptionTag<>(), yforward(input), cs);
22942264 }
22952265 template<class _type>
22962266 YB_ATTR_nodiscard inline TermNode
2297- ReadFrom(_type&& input, ContextNode& ctx) const
2298- {
2299- return ReadFrom(LoadOptionTag<>(), yforward(input), ctx);
2300- }
2301- //! \since build 899
2302- template<class _type>
2303- YB_ATTR_nodiscard inline TermNode
2304- ReadFrom(_type&& input, ReaderState& rs, ContextNode& ctx) const
2267+ ReadFrom(_type&& input, ReaderState& rs, ContextState& cs) const
23052268 {
2306- return ReadFrom(LoadOptionTag<>(), yforward(input), rs, ctx);
2307- }
2308- template<LoadOption _vOpt, class _type>
2309- YB_ATTR_nodiscard inline TermNode
2310- ReadFrom(LoadOptionTag<_vOpt> opt, _type&& input)
2311- {
2312- return ReadFrom(opt, yforward(input), Root);
2313- }
2314- //! \since build 899
2315- template<LoadOption _vOpt, class _type>
2316- YB_ATTR_nodiscard inline TermNode
2317- ReadFrom(LoadOptionTag<_vOpt> opt, _type&& input, ReaderState& rs)
2318- {
2319- return ReadFrom(opt, yforward(input), rs, Root);
2269+ return ReadFrom(LoadOptionTag<>(), yforward(input), rs, cs);
23202270 }
23212271 /*!
23222272 \throw std::invalid_argument 流状态错误或缓冲区不存在。
@@ -2337,65 +2287,59 @@
23372287 throw std::invalid_argument("Invalid stream found.");
23382288 }
23392289 YB_ATTR_nodiscard TermNode
2340- ReadFrom(LoadOptionTag<>, std::streambuf&, ContextNode&) const;
2341- //! \since build 899
2290+ ReadFrom(LoadOptionTag<>, std::streambuf&, ContextState&) const;
23422291 YB_ATTR_nodiscard TermNode
2343- ReadFrom(LoadOptionTag<>, std::streambuf&, ReaderState&, ContextNode&)
2292+ ReadFrom(LoadOptionTag<>, std::streambuf&, ReaderState&, ContextState&)
23442293 const;
23452294 YB_ATTR_nodiscard TermNode
2346- ReadFrom(LoadOptionTag<WithSourceLocation>, std::streambuf&, ContextNode&)
2295+ ReadFrom(LoadOptionTag<WithSourceLocation>, std::streambuf&, ContextState&)
23472296 const;
2348- //! \since build 899
23492297 YB_ATTR_nodiscard TermNode
23502298 ReadFrom(LoadOptionTag<WithSourceLocation>, std::streambuf&, ReaderState&,
2351- ContextNode&) const;
2299+ ContextState&) const;
23522300 YB_ATTR_nodiscard TermNode
2353- ReadFrom(LoadOptionTag<NoSourceInformation>, std::streambuf&, ContextNode&)
2301+ ReadFrom(LoadOptionTag<NoSourceInformation>, std::streambuf&, ContextState&)
23542302 const;
2355- //! \since build 899
23562303 YB_ATTR_nodiscard TermNode
23572304 ReadFrom(LoadOptionTag<NoSourceInformation>, std::streambuf&, ReaderState&,
2358- ContextNode&) const;
2305+ ContextState&) const;
23592306 //! \pre 断言:字符串的数据指针非空。
23602307 //@{
23612308 YB_ATTR_nodiscard TermNode
2362- ReadFrom(LoadOptionTag<>, string_view, ContextNode&) const;
2309+ ReadFrom(LoadOptionTag<>, string_view, ContextState&) const;
23632310 YB_ATTR_nodiscard TermNode
2364- ReadFrom(LoadOptionTag<WithSourceLocation>, string_view, ContextNode&)
2311+ ReadFrom(LoadOptionTag<WithSourceLocation>, string_view, ContextState&)
23652312 const;
23662313 YB_ATTR_nodiscard TermNode
2367- ReadFrom(LoadOptionTag<NoSourceInformation>, string_view, ContextNode&)
2314+ ReadFrom(LoadOptionTag<NoSourceInformation>, string_view, ContextState&)
23682315 const;
23692316 //@}
23702317 //@}
2318+};
23712319
2372- /*!
2373- \brief 设置当前源代码名称为参数指定初始化的新分配的共享名称。
2374- \since build 899
2375- */
2376- template<typename... _tParams>
2377- void
2378- ShareCurrentSource(_tParams&&... args)
2379- {
2380- CurrentSource
2381- = YSLib::allocate_shared<string>(Allocator, yforward(args)...);
2382- }
2383-};
2320+//! \since build 955
2321+template<typename... _tParams>
2322+// XXX: No %YB_ATTR_nodiscard.
2323+inline TermNode
2324+Perform(ContextState& cs, _tParams&&... args)
2325+{
2326+ return cs.Global.get().Perform(cs, yforward(args)...);
2327+}
23842328
23852329 /*!
23862330 \brief 尝试加载源代码。
23872331 \exception NPLException 嵌套异常:加载失败。
23882332 \note 第二参数表示来源,仅用于诊断消息。
2389-\note 不使用可能自定义的 REPLContext::Load 。
2390-\relates REPLContext
2391-\sa REPLContext::LoadFrom
2392-\since build 838
2333+\note 不使用可能自定义的 GlobalState::Load 。
2334+\relates GlobalState
2335+\sa GlobalState::LoadFrom
2336+\since build 955
23932337 */
23942338 template<typename... _tParams>
23952339 YB_NONNULL(2) void
2396-TryLoadSource(REPLContext& context, const char* name, _tParams&&... args)
2340+TryLoadSource(ContextState& cs, const char* name, _tParams&&... args)
23972341 {
2398- TryExpr(context.LoadFrom(yforward(args)...))
2342+ TryExpr(A1::Perform(cs, yforward(args)...))
23992343 CatchExpr(..., std::throw_with_nested(NPLException(
24002344 ystdex::sfmt("Failed loading external unit '%s'.", name))));
24012345 }
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/NPL/NPLA1Forms.h
--- a/YFramework/include/NPL/NPLA1Forms.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/NPL/NPLA1Forms.h Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Forms.h
1212 \ingroup NPL
1313 \brief NPLA1 语法形式。
14-\version r8876
14+\version r8880
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2020-02-15 11:19:21 +0800
1919 \par 修改时间:
20- 2022-08-22 03:07 +0800
20+ 2022-09-12 02:53 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -1117,18 +1117,16 @@
11171117 EvalStringRef(TermNode&, ContextNode&);
11181118
11191119 /*!
1120-\brief 在参数指定的 REPL 环境中规约字符串表示的翻译单元以求值。
1120+\brief 在当前环境中规约字符串表示的翻译单元以求值。
11211121 \exception LoggedEvent 翻译单元为空串。
11221122 \return ReductionStatus::Retained 。
11231123 \sa Reduce
11241124
1125-提供创建 REPL 新实例并求值的便利接口。
1126-
11271125 参考调用文法:
1128-<pre>eval-unit \<string> \<object></pre>
1126+<pre>eval-unit \<string></pre>
11291127 */
11301128 YF_API ReductionStatus
1131-EvalUnit(TermNode&);
1129+EvalUnit(TermNode&, ContextNode&);
11321130 //@}
11331131
11341132 /*!
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/YSLib/Core/ValueNode.h
--- a/YFramework/include/YSLib/Core/ValueNode.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/YSLib/Core/ValueNode.h Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file ValueNode.h
1212 \ingroup Core
1313 \brief 值类型节点。
14-\version r4285
14+\version r4291
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 338
1717 \par 创建时间:
1818 2012-08-03 23:03:44 +0800
1919 \par 修改时间:
20- 2022-03-10 20:09 +0800
20+ 2022-09-09 00:08 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -241,7 +241,7 @@
241241 */
242242 //@{
243243 ValueNode(const Container& con)
244- : container(con)
244+ : ValueNode(con, con.get_allocator())
245245 {}
246246 ValueNode(const Container& con, allocator_type a)
247247 : container(con, a)
@@ -279,7 +279,8 @@
279279 template<typename _tString, typename... _tParams,
280280 yimpl(typename = enable_value_constructible_t<_tParams...>)>
281281 ValueNode(const Container& con, _tString&& str, _tParams&&... args)
282- : name(yforward(str)), container(con), Value(yforward(args)...)
282+ : ValueNode(std::allocator_arg, con.get_allocator(), con, yforward(str),
283+ yforward(args)...)
283284 {}
284285 template<typename _tString, typename... _tParams,
285286 yimpl(typename = enable_value_constructible_t<_tParams...>)>
@@ -295,8 +296,7 @@
295296 inline
296297 ValueNode(std::allocator_arg_t, allocator_type a, const Container& con,
297298 _tString&& str, _tParams&&... args)
298- : name(yforward(str)), container(con, a),
299- Value(yforward(args)...)
299+ : name(yforward(str)), container(con, a), Value(yforward(args)...)
300300 {}
301301 template<typename _tString, typename... _tParams,
302302 yimpl(typename = enable_value_constructible_t<_tParams...>)>
@@ -345,7 +345,7 @@
345345 {}
346346 //@}
347347 /*!
348- \brief 复制构造:使用参数和参数指定的分配器。
348+ \brief 复制构造:使用参数和参数的分配器。
349349 \since build 879
350350 */
351351 ValueNode(const ValueNode& nd)
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/YSLib/Core/YCoreUtilities.h
--- a/YFramework/include/YSLib/Core/YCoreUtilities.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/YSLib/Core/YCoreUtilities.h Wed Sep 14 04:23:05 2022 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2010-2021 FrankHB.
2+ © 2010-2022 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 YCoreUtilities.h
1212 \ingroup Core
1313 \brief 核心实用模块。
14-\version r2629
14+\version r2653
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 539
1717 \par 创建时间:
1818 2010-05-23 06:10:59 +0800
1919 \par 修改时间:
20- 2021-05-18 02:01 +0800
20+ 2022-09-06 12:36 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -29,8 +29,9 @@
2929 #define YSL_INC_Core_YCoreUtilities_h_ 1
3030
3131 #include "YModules.h"
32-#include YFM_YSLib_Core_YException // for LoggedEvent, string, function,
33-// string_view;
32+#include YFM_YSLib_Core_YException // for LoggedEvent, string, string_view,
33+// std::string, std::exception, size_t, ExtractException, FatalError,
34+// to_std_string, make_string_view, function;
3435 #include <ystdex/algorithm.hpp> // for ystdex::clamp;
3536
3637 namespace YSLib
@@ -305,7 +306,7 @@
305306 // TODO: Add and use safe %common_arithmetic_type interface instead?
306307 // TODO: Add direct integer rank comparison?
307308 using common_t = typename ystdex::common_int_type<_tDst, _type>::type;
308-
309+
309310 if((std::is_signed<common_t>() && std::is_unsigned<_tDst>()
310311 && ystdex::integer_width<common_t>() <= ystdex::integer_width<_tDst>())
311312 || !(common_t(std::numeric_limits<common_t>::max()) < common_t(val)))
@@ -371,10 +372,26 @@
371372 \brief 执行关键动作。
372373 \throw FatalError 调用失败。
373374 \note 第二参数表示调用签名;后两个参数用于抛出异常。
374-\since build 899
375+\since build 955
375376 */
376-YF_API void
377-PerformKeyAction(function<void()>, const char*, const char*, string_view);
377+template<typename _func>
378+void
379+PerformKeyAction(_func f, const char* sig, const char* t, string_view sv)
380+{
381+ std::string res;
382+
383+ try
384+ {
385+ f();
386+ return;
387+ }
388+ CatchExpr(std::exception& e, ExtractException(
389+ [&](const std::string & str, size_t level){
390+ res += std::string(level, ' ') + "ERROR: " + str + '\n';
391+ }, e))
392+ CatchExpr(..., res += std::string("Unknown exception @ ") + sig + ".\n")
393+ throw FatalError(t, make_string_view(to_std_string(sv) + res));
394+}
378395
379396
380397 /*!
@@ -401,7 +418,7 @@
401418 //! \since build 919
402419 //@{
403420 DefDeCtor(ArgumentsVector)
404- ArgumentsVector(vector<string>::allocator_type a)
421+ ArgumentsVector(CommandArguments::VectorType::allocator_type a)
405422 : Arguments(a)
406423 {}
407424 DefDeCopyMoveCtorAssignment(ArgumentsVector)
@@ -434,6 +451,7 @@
434451 /*!
435452 \brief 锁定默认命令行参数对象。
436453 \return 静态对象的非空锁定指针。
454+\note 使用默认分配器而不支持指定分配器,以避免静态对象析构时超出分配器的生存期。
437455 \relates ArgumentsVector
438456 \since build 839
439457 */
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/include/YSLib/Core/YObject.h
--- a/YFramework/include/YSLib/Core/YObject.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/include/YSLib/Core/YObject.h Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file YObject.h
1212 \ingroup Core
1313 \brief 平台无关的基础对象。
14-\version r6971
14+\version r6977
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 561
1717 \par 创建时间:
1818 2009-11-16 20:06:58 +0800
1919 \par 修改时间:
20- 2022-08-31 12:40 +0800
20+ 2022-09-13 03:33 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -31,7 +31,7 @@
3131 #include "YModules.h"
3232 #include YFM_YSLib_Core_YShellDefinition // for std::is_base_of,
3333 // std::allocator_arg_t, std::allocator_arg, std::is_constructible,
34-// std::addressof, YSLib::forward_as_tuple;
34+// std::addressof, YSLib::forward_as_tuple, ystdex::remove_cv_t;
3535 #include <ystdex/typeindex.h> // for ystdex::type_id, ystdex::type_info,
3636 // ystdex::type_index;
3737 #include <ystdex/any.h> // for ystdex::any, ystdex::any_ops,
@@ -156,7 +156,7 @@
156156 \brief 创建不具有所有权的间接持有者。
157157 \warning 应适当维护所有权避免未定义行为。
158158
159- 派生实现应保证持有对应的 lref<T> 类型的值引用当前持有的 T 类型的值。
159+ 派生实现应保证持有对应的 \c lref<T> 类型的值引用当前持有的 \c T 类型的值。
160160 */
161161 Indirect,
162162 /*!
@@ -1053,10 +1053,11 @@
10531053 return
10541054 HolderOperations<RefHolder<_type>>::CreateInPlace(ystdex::ref(obj));
10551055 case Copy:
1056- return HolderOperations<ValueHolder<_type>>::CreateInPlace(obj);
1056+ return HolderOperations<
1057+ ValueHolder<ystdex::remove_cv_t<_type>>>::CreateInPlace(obj);
10571058 case Move:
1058- return
1059- HolderOperations<ValueHolder<_type>>::CreateInPlace(std::move(obj));
1059+ return HolderOperations<ValueHolder<
1060+ ystdex::remove_cv_t<_type>>>::CreateInPlace(std::move(obj));
10601061 default:
10611062 ystdex::throw_invalid_construction();
10621063 }
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/Helper/Environment.cpp
--- a/YFramework/source/Helper/Environment.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/Helper/Environment.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Environment.cpp
1212 \ingroup Helper
1313 \brief 环境。
14-\version r1995
14+\version r2001
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 379
1717 \par 创建时间:
1818 2013-02-08 01:27:29 +0800
1919 \par 修改时间:
20- 2022-09-05 12:33 +0800
20+ 2022-09-14 01:34 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -60,7 +60,7 @@
6060
6161 Environment::Environment(Application& app)
6262 : Root(app.get_allocator()), DefaultOutputStream(string(
63- app.get_allocator())), Context(*app.get_allocator().resource())
63+ app.get_allocator())), Global(*app.get_allocator().resource())
6464 {
6565 #if !YF_Hosted
6666 // NOTE: This only effects freestanding implementations now, which may need
@@ -143,16 +143,16 @@
143143 // XXX: This should not fail.
144144 PerformKeyAction([&]{
145145 # if YF_Helper_Environment_NPL_UseSourceInfo
146- Context.UseSourceLocation = true;
146+ Global.UseSourceLocation = true;
147147 # endif
148- Context.OutputStreamPtr = NPL::make_observer(&
148+ Global.OutputStreamPtr = NPL::make_observer(&
149149 # if YF_Helper_Environment_UseStdout
150150 std::cout
151151 # else
152152 DefaultOutputStream
153153 # endif
154154 );
155- NPL::A1::Forms::LoadStandardContext(Context);
155+ NPL::A1::Forms::LoadStandardContext(Main);
156156 }, yfsig, " NPLA1 Failure ",
157157 " An unexpected error occurs \n"
158158 " during the initializaiton.\n");
@@ -202,8 +202,8 @@
202202 auto& trace(ctx.Trace);
203203
204204 TraceException(e, trace);
205- trace.TraceFormat(Notice, "Location: %s.", Context.CurrentSource
206- ? Context.CurrentSource->c_str() : "<unknown>");
205+ trace.TraceFormat(Notice, "Location: %s.", Main.CurrentSource
206+ ? Main.CurrentSource->c_str() : "<unknown>");
207207 # if YF_Helper_Environment_NPL_UseBacktrace
208208 A1::TraceBacktrace(backtrace, trace);
209209 // NOTE: As %Tools.SHBuild.Main.
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/NPL/Configuration.cpp
--- a/YFramework/source/NPL/Configuration.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/NPL/Configuration.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2012-2016, 2020-2021 FrankHB.
2+ © 2012-2016, 2020-2022 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 Configuration.cpp
1212 \ingroup NPL
1313 \brief 配置设置。
14-\version r962
14+\version r981
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 334
1717 \par 创建时间:
1818 2012-08-27 15:15:06 +0800
1919 \par 修改时间:
20- 2021-06-25 12:29 +0800
20+ 2022-09-10 02:11 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -27,13 +27,28 @@
2727
2828 #include "NPL/YModules.h"
2929 #include YFM_NPL_Configuration // for PrintNode, LiteralizeEscapeNodeLiteral;
30-#include YFM_NPL_SContext // for SContext::Analyze;
30+#include YFM_NPL_SContext // for Session, SContext::Analyze;
3131 #include <iterator> // for std::istreambuf_iterator;
32-#include <ystdex/ios.hpp> // for ystdex::rethrow_badstate;
32+#include <ystdex/ios.hpp> // for ystdex::rethrow_badstate,
33+// std::ios_base::failbit;
3334
3435 namespace NPL
3536 {
3637
38+namespace A1
39+{
40+
41+ValueNode
42+LoadNode(const TermNode& tree)
43+{
44+ TryRet(A1::TransformNode(tree))
45+ CatchThrow(bad_any_cast& e, LoggedEvent(YSLib::sfmt(
46+ "Bad NPLA1 tree found: cast failed from [%s] to [%s] .", e.from(),
47+ e.to()), YSLib::Warning))
48+}
49+
50+} // namespace A1;
51+
3752 std::ostream&
3853 operator<<(std::ostream& os, const Configuration& conf)
3954 {
@@ -46,11 +61,11 @@
4661 {
4762 using sb_it_t = std::istreambuf_iterator<char>;
4863 // TODO: Validate for S-expression?
49- // TODO: Use allocator?
50- Session sess{};
64+ const auto a(conf.get_allocator());
65+ Session sess(a);
5166
52- TryExpr(conf.root = A1::LoadNode(
53- SContext::Analyze(sess, sess.Process(sb_it_t(is), sb_it_t{}))))
67+ TryExpr(conf.root = A1::LoadNode(SContext::Analyze(std::allocator_arg, a,
68+ sess, sess.Process(sb_it_t(is), sb_it_t{}))))
5469 CatchExpr(..., ystdex::rethrow_badstate(is, std::ios_base::failbit))
5570 return is;
5671 }
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/NPL/Dependency.cpp
--- a/YFramework/source/NPL/Dependency.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/NPL/Dependency.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Dependency.cpp
1212 \ingroup NPL
1313 \brief 依赖管理。
14-\version r7189
14+\version r7359
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 623
1717 \par 创建时间:
1818 2015-08-09 22:14:45 +0800
1919 \par 修改时间:
20- 2022-09-04 23:03 +0800
20+ 2022-09-14 01:45 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -28,7 +28,7 @@
2828 #include "NPL/YModules.h"
2929 #include YFM_NPL_Dependency // for set, string, UnescapeContext, string_view,
3030 // ystdex::isspace, std::istream, YSLib::unique_ptr, std::throw_with_nested,
31-// std::invalid_argument, ystdex::sfmt, YSLib::share_move, REPLContext,
31+// std::invalid_argument, ystdex::sfmt, YSLib::share_move, GlobalState,
3232 // RelaySwitched, trivial_swap, std::bind, SourceName, RetainN,
3333 // NPL::ResolveRegular, NPL::Deref, A1::NameTypedReducerHandler, std::ref,
3434 // Forms::CallResolvedUnary, EnsureValueTags, ResolvedTermReferencePtr,
@@ -39,19 +39,20 @@
3939 // ThrowValueCategoryError, ValueToken, ResolveTerm, TokenValue,
4040 // CheckVariadicArity, A1::AsForm, ystdex::bind1, std::placeholders,
4141 // NPL::CollectTokens, Strict, LiftOtherOrCopy, IsEmpty,
42-// ComposeReferencedTermOp, IsBranch, IsReferenceTerm, IsBoundLValueTerm,
43-// IsUncollapsedTerm, IsUniqueTerm, IsModifiableTerm, IsTemporaryTerm,
44-// LiftTermRef, NPL::SetContentWith, Environment::EnsureValid,
45-// LiftTermValueOrCopy, ResolveIdentifier, NPLException, ReduceToReferenceList,
42+// ComposeReferencedTermOp, IsBranch, IsTypedRegular, ReferenceTerm,
43+// IsReferenceTerm, IsBoundLValueTerm, IsUniqueTerm, IsModifiableTerm,
44+// IsTemporaryTerm, IsUncollapsedTerm, LiftTermRef, NPL::SetContentWith,
45+// LiftTermValueOrCopy, ResolveName, ResolveIdentifier,
46+// Environment::EnsureValid, NPLException, ReduceToReferenceList,
4647 // MoveCollapsed, NPL::IsMovable, LiftTermOrCopy, IsBranchedList,
47-// AccessFirstSubterm, ThrowInsufficientTermsError, AssertValueTags, Retain,
48-// RemoveHead, ClearCombiningTags, EmplaceCallResultOrReturn, NPL::AsTermNode,
49-// ReferenceTerm, ResolveName, ystdex::fast_any_of, Ensigil, YSLib::ufexists,
50-// YSLib::to_std_string, EmplaceCallResultOrReturn, TryAccessTerm,
51-// ystdex::plus, ystdex::tolower, YSLib::OwnershipTag, YSLib::IO::StreamPut,
52-// YSLib::FetchEnvironmentVariable, YSLib::SetEnvironmentVariable, NPL::tuple,
53-// YSLib::IO::UniqueFile, YSLib::uremove, YSLib::allocate_shared,
54-// ReduceReturnUnspecified, ystdex::throw_error;
48+// AccessFirstSubterm, ThrowInsufficientTermsError, Retain, NPL::AsTermNode,
49+// ystdex::fast_any_of, A1::Perform, Ensigil, YSLib::ufexists,
50+// YSLib::to_std_string, AssertValueTags, ClearCombiningTags,
51+// EmplaceCallResultOrReturn, RemoveHead, TryAccessTerm, ystdex::plus,
52+// ystdex::tolower, ReduceReturnUnspecified, YSLib::IO::StreamPut,
53+// YSLib::OwnershipTag, YSLib::FetchEnvironmentVariable,
54+// YSLib::SetEnvironmentVariable, YSLib::uremove, YSLib::allocate_shared,
55+// NPL::tuple, YSLib::IO::UniqueFile, ystdex::throw_error;
5556 #include <ystdex/container.hpp> // for ystdex::exists, ystdex::search_map,
5657 // ystdex::emplace_hint_in_place;
5758 #include YFM_NPL_NPLA1Forms // for EncapsulateValue, Encapsulate, Encapsulated,
@@ -208,55 +209,62 @@
208209 }
209210
210211 YSLib::unique_ptr<std::istream>
211-OpenUnique(REPLContext& context, string filename)
212+OpenUnique(ContextState& cs, string filename)
212213 {
213214 auto p_is(A1::OpenFile(filename.c_str()));
214215
215- // NOTE: Swap guard for %Context.CurrentSource is not used. It is up to the
216+ // NOTE: Swap guard for %cs.CurrentSource is not used. It is up to the
216217 // caller to support PTC or not.
217- context.CurrentSource = YSLib::share_move(filename);
218+ cs.CurrentSource = YSLib::share_move(filename);
218219 return p_is;
219220 }
220221
221222
222223 void
223-PreloadExternal(REPLContext& context, const char* filename)
224+PreloadExternal(ContextState& cs, const char* filename)
224225 {
225- TryLoadSource(context, filename,
226- *OpenUnique(context, string(filename, context.Allocator)));
226+ const auto& global(cs.Global.get());
227+
228+ TryLoadSource(cs, filename,
229+ *OpenUnique(cs, string(filename, global.Allocator)));
227230 }
228231
229232 //! \since build 923
230233 namespace
231234 {
232235
236+//! \since build 955
233237 ReductionStatus
234-ReduceToLoadFile(TermNode& term, ContextNode& ctx, REPLContext& context,
235- string filename)
238+ReduceToLoadFile(TermNode& term, ContextNode& ctx, string filename)
236239 {
240+ auto& cs(ContextState::Access(ctx));
241+ const auto& global(cs.Global.get());
242+
237243 // NOTE: This is explicitly not same to klisp. This is also friendly to PTC.
238244 // XXX: Same to %A1::ReduceOnce, without setup the next term.
239245 #if NPL_Impl_NPLA1_Enable_Thunked
240246 # if NPL_Impl_NPLA1_Enable_TCO
241- RefTCOAction(ctx).SaveTailSourceName(context.CurrentSource,
242- std::move(context.CurrentSource));
247+ RefTCOAction(ctx).SaveTailSourceName(cs.CurrentSource,
248+ std::move(cs.CurrentSource));
243249 # else
244250 RelaySwitched(ctx, trivial_swap,
245251 A1::NameTypedReducerHandler(std::bind([&](SourceName& saved_src){
246- context.CurrentSource = std::move(saved_src);
252+ cs.CurrentSource = std::move(saved_src);
247253 return ctx.LastStatus;
248- }, std::move(context.CurrentSource)), "restore-source-name"));
254+ }, std::move(cs.CurrentSource)), "restore-source-name"));
249255 # endif
250- term = context.Load(context, ctx, std::move(filename));
256+ term = global.Load(cs, std::move(filename));
257+ global.Preprocess(term);
251258 return ContextState::Access(ctx).ReduceOnce.Handler(term, ctx);
252259 #else
253- auto saved_src(std::move(context.CurrentSource));
260+ auto saved_src(std::move(cs.CurrentSource));
254261
255- term = context.Load(context, ctx, std::move(filename));
262+ term = global.Load(cs, std::move(filename));
263+ global.Prerpocess(term);
256264
257265 const auto res(ContextState::Access(ctx).ReduceOnce.Handler(term, ctx));
258266
259- context.CurrentSource = std::move(saved_src);
267+ cs.CurrentSource = std::move(saved_src);
260268 return res;
261269 #endif
262270 }
@@ -264,20 +272,19 @@
264272 } // unnamed namespace;
265273
266274 ReductionStatus
267-ReduceToLoadExternal(TermNode& term, ContextNode& ctx, REPLContext& context)
275+ReduceToLoadExternal(TermNode& term, ContextNode& ctx)
268276 {
269277 RetainN(term);
270- return ReduceToLoadFile(term, ctx, context, string(
271- NPL::ResolveRegular<const string>(NPL::Deref(std::next(term.begin()))),
272- term.get_allocator()));
278+ return ReduceToLoadFile(term, ctx, string(NPL::ResolveRegular<const string>(
279+ NPL::Deref(std::next(term.begin()))), term.get_allocator()));
273280 }
274281
275282 ReductionStatus
276-RelayToLoadExternal(ContextNode& ctx, TermNode& term, REPLContext& context)
283+RelayToLoadExternal(ContextNode& ctx, TermNode& term)
277284 {
278285 return RelaySwitched(ctx, trivial_swap,
279286 A1::NameTypedReducerHandler(std::bind(ReduceToLoadExternal,
280- std::ref(term), std::ref(ctx), std::ref(context)), "load-external"));
287+ std::ref(term), std::ref(ctx)), "load-external"));
281288 }
282289
283290 namespace Forms
@@ -494,29 +501,29 @@
494501 Reduce(term, ctx);
495502 # if false
496503 // NOTE: Usage:
497- AddDefineFunction(rctx, "$defv!", {"&$f", "&formals", "&ef"},
504+ AddDefineFunction(ctx, "$defv!", {"&$f", "&formals", "&ef"},
498505 {"$f", "$vau", "formals", "ef"});
499- AddDefineFunction(rctx, "$defv%!", {"&$f", "&formals", "&ef"},
506+ AddDefineFunction(ctx, "$defv%!", {"&$f", "&formals", "&ef"},
500507 {"$f", "$vau%", "formals", "ef"});
501- AddDefineFunction(rctx, "$defv/e!", {"&$f", "&p", "&formals", "&ef"},
508+ AddDefineFunction(ctx, "$defv/e!", {"&$f", "&p", "&formals", "&ef"},
502509 {"$f", "$vau/e", "p", "formals", "ef"});
503- AddDefineFunction(rctx, "$defv/e%!", {"&$f", "&p", "&formals", "&ef"},
510+ AddDefineFunction(ctx, "$defv/e%!", {"&$f", "&p", "&formals", "&ef"},
504511 {"$f", "$vau/e%", "p", "formals", "ef"});
505- AddDefineFunction(rctx, "$defw!", {"&f", "&formals", "&ef"},
512+ AddDefineFunction(ctx, "$defw!", {"&f", "&formals", "&ef"},
506513 {"f", "$wvau", "formals", "ef"});
507- AddDefineFunction(rctx, "$defw%!", {"&f", "&formals", "&ef"},
514+ AddDefineFunction(ctx, "$defw%!", {"&f", "&formals", "&ef"},
508515 {"f", "$wvau%", "formals", "ef"});
509- AddDefineFunction(rctx, "$defw/e!", {"&f", "&p", "&formals", "&ef"},
516+ AddDefineFunction(ctx, "$defw/e!", {"&f", "&p", "&formals", "&ef"},
510517 {"f", "$wvau/e", "p", "formals", "ef"});
511- AddDefineFunction(rctx, "$defw/e%!", {"&f", "&p", "&formals", "&ef"},
518+ AddDefineFunction(ctx, "$defw/e%!", {"&f", "&p", "&formals", "&ef"},
512519 {"f", "$wvau/e%", "p", "formals", "ef"});
513- AddDefineFunction(rctx, "$defl!", {"&f", "&formals"},
520+ AddDefineFunction(ctx, "$defl!", {"&f", "&formals"},
514521 {"f", "$lambda", "formals"});
515- AddDefineFunction(rctx, "$defl%!", {"&f", "&formals"},
522+ AddDefineFunction(ctx, "$defl%!", {"&f", "&formals"},
516523 {"f", "$lambda%", "formals"});
517- AddDefineFunction(rctx, "$defl/e!", {"&f", "&p", "&formals"},
524+ AddDefineFunction(ctx, "$defl/e!", {"&f", "&p", "&formals"},
518525 {"f", "$lambda/e", "p", "formals"});
519- AddDefineFunction(rctx, "$defl/e%!", {"&f", "&p", "&formals"},
526+ AddDefineFunction(ctx, "$defl/e%!", {"&f", "&p", "&formals"},
520527 {"f", "$lambda/e%", "p", "formals"});
521528 # endif
522529 }
@@ -582,6 +589,10 @@
582589 RegisterUnary(ctx, "branchv?", IsBranch);
583590 RegisterUnary(ctx, "pair?", ComposeReferencedTermOp(IsPair));
584591 RegisterUnary(ctx, "pairv?", IsPair);
592+ RegisterUnary(ctx, "symbol?",
593+ [] YB_LAMBDA_ANNOTATE((const TermNode& x), ynothrow, pure){
594+ return IsTypedRegular<TokenValue>(ReferenceTerm(x));
595+ });
585596 RegisterUnary(ctx, "reference?", IsReferenceTerm);
586597 RegisterUnary(ctx, "unique?", IsUniqueTerm);
587598 RegisterUnary(ctx, "modifiable?", IsModifiableTerm);
@@ -620,9 +631,6 @@
620631 void
621632 LoadLists(ContextNode& ctx)
622633 {
623- // NOTE: Though NPLA does not use cons pairs, corresponding primitives are
624- // still necessary.
625- // NOTE: Since NPL has no con pairs, it only added head to existed list.
626634 RegisterStrict(ctx, "cons", Cons);
627635 RegisterStrict(ctx, "cons%", ConsRef);
628636 // NOTE: Like '$set-cdr!' in Kernel, with no references.
@@ -751,12 +759,12 @@
751759 namespace Derived
752760 {
753761
754-//! \since build 909
762+//! \since build 955
763+//@{
755764 void
756-LoadBasicDerived(REPLContext& context)
765+LoadBasicDerived(ContextState& cs)
757766 {
758- auto& rctx(context.Root);
759- auto& renv(rctx.GetRecordRef());
767+ auto& renv(cs.GetRecordRef());
760768
761769 // NOTE: Some combiners are provided here as host primitives for
762770 // more efficiency and less dependencies.
@@ -942,7 +950,7 @@
942950 ystdex::bind1([](TermNode& term, const EnvironmentReference& ce){
943951 RetainN(term, 0);
944952 term.SetValue(CreateEnvironmentWithParent(term.get_allocator(), ce));
945- }, context.Root.WeakenRecord()));
953+ }, cs.WeakenRecord()));
946954 RegisterStrict(renv, "derive-current-environment",
947955 [] YB_LAMBDA_ANNOTATE((TermNode& term, ContextNode& ctx), , flatten){
948956 Retain(term);
@@ -958,7 +966,7 @@
958966 Retain(term);
959967 term.emplace(NPL::AsTermNode(term.get_allocator(), ce));
960968 return MakeEnvironment(term);
961- }, context.Root.WeakenRecord()));
969+ }, cs.WeakenRecord()));
962970 RegisterForm(renv, "$as-environment", AsEnvironment);
963971 RegisterForm(renv, "$bindings/p->environment",
964972 BindingsWithParentToEnvironment);
@@ -981,7 +989,7 @@
981989 RegisterStrict(renv, "assq", Assq);
982990 RegisterStrict(renv, "assv", Assv);
983991 {
984- const auto a(context.Allocator);
992+ const auto a(cs.get_allocator());
985993 // NOTE: As %MakeEncapsulationType.
986994 shared_ptr<void> p_type(new yimpl(byte));
987995
@@ -991,8 +999,8 @@
991999 renv.Define("unbox", A1::MakeForm(a, Decapsulate(p_type), Strict));
9921000 }
9931001 #else
994- context.ShareCurrentSource("<root:basic-derived>");
995- context.Perform(
1002+ cs.ShareCurrentSource("<root:basic-derived>");
1003+ A1::Perform(cs,
9961004 # if NPL_Impl_NPLA1_Native_EnvironmentPrimitives
9971005 R"NPL(
9981006 $def! forward! wrap
@@ -1037,8 +1045,8 @@
10371045 );
10381046 RegisterForm(renv, "$lambda", Lambda);
10391047 RegisterForm(renv, "$lambda%", LambdaRef);
1040- context.ShareCurrentSource("<root:basic-derived-1>");
1041- context.Perform(R"NPL(
1048+ cs.ShareCurrentSource("<root:basic-derived-1>");
1049+ A1::Perform(cs, R"NPL(
10421050 $def! id $lambda% (%x) $move-resolved! x;
10431051 $def! idv $lambda% (x) $move-resolved! x;
10441052 $def! list $lambda (.x) move! x;
@@ -1389,12 +1397,11 @@
13891397 #endif
13901398 }
13911399
1392-//! \since build 909
13931400 void
1394-LoadStandardDerived(REPLContext& context)
1401+LoadStandardDerived(ContextState& cs)
13951402 {
13961403 #if NPL_Impl_NPLA1_Native_Forms
1397- auto& renv(context.Root.GetRecordRef());
1404+ auto& renv(cs.GetRecordRef());
13981405
13991406 RegisterUnary<Strict, const TokenValue>(renv, "ensigil", Ensigil);
14001407 RegisterForm(renv, "$binds1?", [](TermNode& term, ContextNode& ctx){
@@ -1417,8 +1424,8 @@
14171424 // derivations available later in the bodies. Otherwise, they are not
14181425 // relied on. To avoid cyclic dependencies, the derivation of %ensigl
14191426 // further avoids specific core functions.
1420- context.ShareCurrentSource("<root:standard-derived>");
1421- context.Perform(R"NPL(
1427+ cs.ShareCurrentSource("<root:standard-derived>");
1428+ A1::Perform(cs, R"NPL(
14221429 $def! ensigil $lambda (&s)
14231430 $let/e (derive-current-environment std.strings) ()
14241431 $let ((&str symbol->string s))
@@ -1431,13 +1438,11 @@
14311438 #endif
14321439 }
14331440
1434-//! \since build 839
1435-//@{
14361441 void
1437-LoadCore(REPLContext& context)
1442+LoadCore(ContextState& cs)
14381443 {
1439- context.ShareCurrentSource("<root:core>");
1440- context.Perform(R"NPL(
1444+ cs.ShareCurrentSource("<root:core>");
1445+ A1::Perform(cs, R"NPL(
14411446 $defw%! map-reverse (&appv .&ls) d
14421447 accl (forward! (check-list-reference ls)) nonfoldable? () list-extract-first
14431448 list-extract-rest%
@@ -1447,26 +1452,25 @@
14471452 }
14481453
14491454 void
1450-Load(REPLContext& context)
1455+Load(ContextState& cs)
14511456 {
1452- LoadBasicDerived(context);
1453- LoadStandardDerived(context);
1454- LoadCore(context);
1457+ LoadBasicDerived(cs);
1458+ LoadStandardDerived(cs);
1459+ LoadCore(cs);
14551460 }
14561461 //@}
14571462
14581463 } // namespace Derived;
14591464
1460-//! \since build 839
1465+//! \since build 955
14611466 void
1462-Load(REPLContext& context)
1467+Load(ContextState& cs)
14631468 {
1464- auto& rctx(context.Root);
1465- auto& renv(rctx.GetRecordRef());
1469+ auto& renv(cs.GetRecordRef());
14661470
14671471 // LoadObjects(renv);
1468- Primitive::Load(rctx);
1469- Derived::Load(context);
1472+ Primitive::Load(cs);
1473+ Derived::Load(cs);
14701474 // NOTE: Prevent the ground environment from modification.
14711475 renv.Frozen = true;
14721476 }
@@ -1722,22 +1726,21 @@
17221726 //@}
17231727
17241728
1725-//! \since build 942
1729+//! \since build 955
17261730 template<typename _func>
17271731 ReductionStatus
1728-ReduceToLoadGuarded(TermNode& term, ContextNode& ctx, REPLContext& context,
1732+ReduceToLoadGuarded(TermNode& term, ContextNode& ctx,
17291733 shared_ptr<Environment> p_env, _func reduce)
17301734 {
17311735 # if NPL_Impl_NPLA1_Enable_Thunked
17321736 return A1::RelayCurrentNext(ctx, term, trivial_swap, std::bind(
1733- std::move(reduce), std::ref(term), std::ref(ctx), std::ref(context)),
1737+ std::move(reduce), std::ref(term), std::ref(ctx)),
17341738 trivial_swap, MoveKeptGuard(EnvironmentGuard(ctx,
17351739 ctx.SwitchEnvironmentUnchecked(std::move(p_env)))));
17361740 # else
1737- const EnvironmentGuard gd(ctx,
1738- ctx.SwitchEnvironmentUnchecked(p_env));
1741+ const EnvironmentGuard gd(ctx, ctx.SwitchEnvironmentUnchecked(p_env));
17391742
1740- return reduce(term, ctx, context);
1743+ return reduce(term, ctx);
17411744 # endif
17421745 }
17431746 #endif
@@ -1760,17 +1763,17 @@
17601763 } // unnamed namespace;
17611764
17621765 void
1763-LoadGroundContext(REPLContext& context)
1766+LoadGroundContext(ContextState& cs)
17641767 {
1765- // NOTE: Dynamic separator handling is lifted to %REPLContext::Preprocess.
1768+ // NOTE: Dynamic separator handling is lifted to %GlobalState::Preprocess.
17661769 // See $2020-02 @ %Documentation::Workflow.
1767- Ground::Load(context);
1770+ Ground::Load(cs);
17681771 }
17691772
17701773 void
1771-LoadModule_std_continuations(REPLContext& context)
1774+LoadModule_std_continuations(ContextState& cs)
17721775 {
1773- auto& renv(context.Root.GetRecordRef());
1776+ auto& renv(cs.GetRecordRef());
17741777
17751778 RegisterStrict(renv, "call/1cc", Call1CC);
17761779 RegisterStrict(renv, "continuation->applicative",
@@ -1778,8 +1781,8 @@
17781781 #if NPL_Impl_NPLA1_Native_Forms
17791782 RegisterStrict(renv, "apply-continuation", ApplyContinuation);
17801783 #else
1781- context.ShareCurrentSource("<lib:std.continuations>");
1782- context.Perform(R"NPL(
1784+ cs.ShareCurrentSource("<lib:std.continuations>");
1785+ A1::Perform(cs, R"NPL(
17831786 $defl! apply-continuation (&k &arg)
17841787 apply (continuation->applicative (forward! k)) (forward! arg);
17851788 )NPL");
@@ -1787,10 +1790,10 @@
17871790 }
17881791
17891792 void
1790-LoadModule_std_promises(REPLContext& context)
1793+LoadModule_std_promises(ContextState& cs)
17911794 {
17921795 #if NPL_Impl_NPLA1_Native_Forms
1793- auto& renv(context.Root.GetRecordRef());
1796+ auto& renv(cs.GetRecordRef());
17941797
17951798 RegisterUnary(renv, "promise?",
17961799 [] YB_LAMBDA_ANNOTATE((const TermNode& x), ynothrow, pure){
@@ -1825,7 +1828,7 @@
18251828 }, term);
18261829 });
18271830 #else
1828- context.ShareCurrentSource("<lib:std.promises>");
1831+ cs.ShareCurrentSource("<lib:std.promises>");
18291832 // NOTE: The call to 'set-first%!' does not check cyclic references. This is
18301833 // kept safe since it can occur only with NPLA1 undefined behavior.
18311834 // XXX: The internal construct uses lists instead of pairs as [RnRK] even
@@ -1833,7 +1836,7 @@
18331836 // value introduced by trailing sequence has unspecified behavior in the
18341837 // object language (and it will not change the shared referent in the
18351838 // current implementation)..
1836- context.Perform(R"NPL(
1839+ A1::Perform(cs, R"NPL(
18371840 $provide/let! (promise? memoize $lazy $lazy% $lazy/d $lazy/d% force)
18381841 ((mods $as-environment (
18391842 $def! (encapsulate% promise? decapsulate) () make-encapsulation-type;
@@ -1877,9 +1880,9 @@
18771880 }
18781881
18791882 void
1880-LoadModule_std_math(REPLContext& context)
1883+LoadModule_std_math(ContextState& cs)
18811884 {
1882- auto& renv(context.Root.GetRecordRef());
1885+ auto& renv(cs.GetRecordRef());
18831886
18841887 RegisterUnary(renv, "number?", trivial_swap,
18851888 ComposeReferencedTermOp(ystdex::bind1(LeafPred(), IsNumberValue)));
@@ -1946,10 +1949,14 @@
19461949 }
19471950
19481951 void
1949-LoadModule_std_strings(REPLContext& context)
1952+LoadModule_std_strings(ContextState& cs)
19501953 {
1951- auto& renv(context.Root.GetRecordRef());
1954+ auto& renv(cs.GetRecordRef());
19521955
1956+ RegisterUnary(renv, "string?",
1957+ [] YB_LAMBDA_ANNOTATE((const TermNode& x), ynothrow, pure){
1958+ return IsTypedRegular<string>(ReferenceTerm(x));
1959+ });
19531960 RegisterStrict(renv, "++", trivial_swap,
19541961 std::bind(CallBinaryFold<string, ystdex::plus<>>,
19551962 ystdex::plus<>(), string(), std::placeholders::_1));
@@ -1957,8 +1964,8 @@
19571964 [](const string& str) ynothrow{
19581965 return str.empty();
19591966 });
1960- RegisterBinary<Strict, ResolvedArg<>, ResolvedArg<>>(renv,
1961- "string<-", [](ResolvedArg<>&& x, ResolvedArg<>&& y){
1967+ RegisterBinary<Strict, ResolvedArg<>, ResolvedArg<>>(renv, "string<-",
1968+ [](ResolvedArg<>&& x, ResolvedArg<>&& y){
19621969 if(x.IsModifiable())
19631970 {
19641971 auto& str_x(AccessRegular<string>(x.get(), x.second));
@@ -2040,12 +2047,12 @@
20402047 }
20412048
20422049 void
2043-LoadModule_std_io(REPLContext& context,
2050+LoadModule_std_io(ContextState& cs,
20442051 const shared_ptr<Environment>& p_ground)
20452052 {
20462053 YAssertNonnull(p_ground);
20472054
2048- auto& renv(context.Root.GetRecordRef());
2055+ auto& renv(cs.GetRecordRef());
20492056
20502057 RegisterUnary<Strict, const string>(renv, "readable-file?",
20512058 [](const string& str) ynothrow{
@@ -2055,21 +2062,24 @@
20552062 [](const string& str) ynothrow{
20562063 return YSLib::ufexists(str.c_str(), true);
20572064 });
2058- RegisterStrict(renv, "newline", trivial_swap, [&](TermNode& term){
2065+ RegisterStrict(renv, "newline", trivial_swap,
2066+ [&](TermNode& term, ContextNode& ctx){
20592067 RetainN(term, 0);
2060- if(auto& os{context.GetOutputStreamRef()})
2068+ if(auto&
2069+ os{ContextState::Access(ctx).Global.get().GetOutputStreamRef()})
20612070 os << std::endl;
20622071 return ReduceReturnUnspecified(term);
20632072 });
20642073 RegisterUnary<Strict, const string>(renv, "put", trivial_swap,
2065- [&](const string& str){
2066- YSLib::IO::StreamPut(context.GetOutputStreamRef(), str.c_str());
2074+ [&](const string& str, ContextNode& ctx){
2075+ YSLib::IO::StreamPut(ContextState::Access(ctx).Global.get()
2076+ .GetOutputStreamRef(), str.c_str());
20672077 return ValueToken::Unspecified;
20682078 });
20692079 #if NPL_Impl_NPLA1_Native_Forms
20702080 RegisterUnary<Strict, const string>(renv, "puts", trivial_swap,
2071- [&](const string& str){
2072- auto& os(context.GetOutputStreamRef());
2081+ [&](const string& str, ContextNode& ctx){
2082+ auto& os(ContextState::Access(ctx).Global.get().GetOutputStreamRef());
20732083
20742084 YSLib::IO::StreamPut(os, str.c_str());
20752085 if(os)
@@ -2077,18 +2087,15 @@
20772087 return ValueToken::Unspecified;
20782088 });
20792089 #else
2080- context.ShareCurrentSource("<lib:std.io>");
2081- context.Perform(R"NPL(
2090+ cs.ShareCurrentSource("<lib:std.io>");
2091+ A1::Perform(cs, R"NPL(
20822092 $defl! puts (&s) $sequence (put s) (() newline);
20832093 )NPL");
20842094 #endif
2085- RegisterStrict(renv, "load", trivial_swap,
2086- [&](TermNode& term, ContextNode& ctx){
2087- // NOTE: Since %load disallows additional barrier of catching the inner
2088- // exceptions and the reset of the source name, %TryLoadSource or
2089- // %PreloadExternal is not applicable here.
2090- return ReduceToLoadExternal(term, ctx, context);
2091- });
2095+ // NOTE: Since %load disallows additional barrier of catching the inner
2096+ // exceptions and the reset of the source name, %TryLoadSource or
2097+ // %PreloadExternal is not applicable here.
2098+ RegisterStrict(renv, "load", ReduceToLoadExternal);
20922099 #if NPL_Impl_NPLA1_Native_Forms
20932100 RegisterStrict(renv, "get-module", trivial_swap,
20942101 ystdex::bind1([&](TermNode& term, ContextNode& ctx,
@@ -2123,10 +2130,10 @@
21232130 term.SetValue(std::move(p_res));
21242131 return ReductionStatus::Clean;
21252132 }, p_env), "get-module-return"));
2126- return ReduceToLoadGuarded(term, ctx, context, std::move(p_env),
2133+ return ReduceToLoadGuarded(term, ctx, std::move(p_env),
21272134 ReduceToLoadExternal);
21282135 # else
2129- ReduceToLoadGuarded(term, ctx, context, std::move(p_env),
2136+ ReduceToLoadGuarded(term, ctx, std::move(p_env),
21302137 ReduceToLoadExternal);
21312138 term.SetValue(std::move(p_env));
21322139 return ReductionStatus::Clean;
@@ -2138,8 +2145,8 @@
21382145 }, std::placeholders::_2, EnvironmentReference(p_ground)));
21392146 #else
21402147 yunused(p_ground);
2141- context.ShareCurrentSource("<lib:std.io-1>");
2142- context.Perform(R"NPL(
2148+ cs.ShareCurrentSource("<lib:std.io-1>");
2149+ A1::Perform(cs, R"NPL(
21432150 $defl! get-module (&filename .&opt)
21442151 $let ((env $if (null? opt) (() make-standard-environment)
21452152 ($let (((&e .&eopt) opt)) $if (null? eopt)
@@ -2152,14 +2159,15 @@
21522159 }
21532160
21542161 void
2155-LoadModule_std_system(REPLContext& context)
2162+LoadModule_std_system(ContextState& cs)
21562163 {
2157- auto& renv(context.Root.GetRecordRef());
2164+ auto& renv(cs.GetRecordRef());
21582165
21592166 RegisterStrict(renv, "get-current-repl", trivial_swap,
2160- [&](TermNode& term){
2167+ [&](TermNode& term, ContextNode& ctx){
21612168 RetainN(term, 0);
2162- term.Value.assign(context, YSLib::OwnershipTag<>());
2169+ term.Value.assign(ContextState::Access(ctx).Global.get(),
2170+ YSLib::OwnershipTag<>());
21632171 });
21642172 RegisterStrict(renv, "eval-string", EvalString);
21652173 RegisterStrict(renv, "eval-string%", EvalStringRef);
@@ -2186,8 +2194,8 @@
21862194 [](const string& var, const string& val){
21872195 YSLib::SetEnvironmentVariable(var.c_str(), val.c_str());
21882196 });
2189- context.ShareCurrentSource("<lib:std.system>");
2190- context.Perform(R"NPL(
2197+ cs.ShareCurrentSource("<lib:std.system>");
2198+ A1::Perform(cs, R"NPL(
21912199 $defl/e! env-empty? (derive-current-environment std.strings) (&n)
21922200 string-empty? (env-get n);
21932201 )NPL");
@@ -2217,15 +2225,15 @@
22172225 }
22182226
22192227 void
2220-LoadModule_std_modules(REPLContext& context,
2228+LoadModule_std_modules(ContextState& cs,
22212229 const shared_ptr<Environment>& p_ground)
22222230 {
22232231 YAssertNonnull(p_ground);
2232+
22242233 #if NPL_Impl_NPLA1_Native_Forms
2225-
22262234 using namespace std::placeholders;
22272235 using YSLib::to_std_string;
2228- auto& renv(context.Root.GetRecordRef());
2236+ auto& renv(cs.GetRecordRef());
22292237 const auto a(renv.Bindings.get_allocator());
22302238 const auto p_registry(YSLib::allocate_shared<YSLib::map<string,
22312239 pair<TermNode, shared_ptr<Environment>>>>(a));
@@ -2357,12 +2365,12 @@
23572365 return A1::RelayCurrentNext(ctx, term, trivial_swap,
23582366 ystdex::bind1([&](TermNode& t, ContextNode& c,
23592367 string& fname, shared_ptr<Environment>& p_env){
2360- return ReduceToLoadGuarded(t, c, context, std::move(p_env),
2361- ystdex::bind1([&](TermNode& t_0, ContextNode& c_0,
2362- REPLContext& rc, string& fname_0){
2368+ return ReduceToLoadGuarded(t, c, std::move(p_env),
2369+ ystdex::bind1(
2370+ [&](TermNode& t_0, ContextNode& c_0, string& fname_0){
23632371 return
2364- ReduceToLoadFile(t_0, c_0, rc, std::move(fname_0));
2365- }, _2, _3, std::move(fname)));
2372+ ReduceToLoadFile(t_0, c_0, std::move(fname_0));
2373+ }, _2, std::move(fname)));
23662374 }, _2, std::move(filename), val.second),
23672375 A1::NameTypedReducerHandler([&, reduce_to_res]{
23682376 MoveCollapsed(val.first, term);
@@ -2448,16 +2456,17 @@
24482456 }
24492457
24502458 void
2451-LoadModule_SHBuild(REPLContext& context)
2459+LoadModule_SHBuild(ContextState& cs)
24522460 {
24532461 using namespace YSLib;
2454- auto& renv(context.Root.GetRecordRef());
2462+ auto& renv(cs.GetRecordRef());
2463+ const auto& global(cs.Global.get());
24552464
24562465 // NOTE: SHBuild builtins.
24572466 renv.DefineChecked("SHBuild_BaseTerminalHook_",
24582467 ValueObject(function<void(const string&, const string&)>(
24592468 [&](const string& n, const string& val) ynothrow{
2460- auto& os(context.GetOutputStreamRef());
2469+ auto& os(global.GetOutputStreamRef());
24612470
24622471 IO::StreamPut(os,
24632472 YSLib::sfmt("%s = \"%s\"", n.c_str(), val.c_str()).c_str());
@@ -2665,31 +2674,29 @@
26652674 }
26662675
26672676 void
2668-LoadStandardContext(REPLContext& context)
2677+LoadStandardContext(ContextState& cs)
26692678 {
2670- LoadGroundContext(context);
2679+ LoadGroundContext(cs);
26712680
26722681 const auto pfx("std.");
2673- string mod(pfx, context.Allocator);
2674- auto& rctx(context.Root);
2682+ string mod(pfx, cs.get_allocator());
26752683 const auto load_std_module(
2676- [&](string_view module_name, void(&load_module)(REPLContext&)){
2677- // XXX: Using %context.Allocator or %std::string are both a bit less
2684+ [&](string_view module_name, void(&load_module)(ContextState&)){
2685+ // XXX: Using allocator of the state or %std::string are both a bit less
26782686 // efficient.
26792687 mod += module_name;
2680- LoadModuleChecked(rctx, mod, load_module, context);
2688+ LoadModuleChecked(cs, mod, load_module, cs);
26812689 mod.resize(ystdex::string_length(pfx));
26822690 });
2683- const auto p_ground(rctx.ShareRecord());
2691+ const auto p_ground(cs.ShareRecord());
26842692
26852693 load_std_module("continuations", LoadModule_std_continuations),
26862694 load_std_module("promises", LoadModule_std_promises);
26872695 load_std_module("math", LoadModule_std_math),
26882696 load_std_module("strings", LoadModule_std_strings);
2689- LoadModuleChecked(rctx, "std.io", LoadModule_std_io, context, p_ground);
2697+ LoadModuleChecked(cs, "std.io", LoadModule_std_io, cs, p_ground);
26902698 load_std_module("system", LoadModule_std_system);
2691- LoadModuleChecked(rctx, "std.modules", LoadModule_std_modules, context,
2692- p_ground);
2699+ LoadModuleChecked(cs, "std.modules", LoadModule_std_modules, cs, p_ground);
26932700 }
26942701
26952702 } // namespace Forms;
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/NPL/NPLA1.cpp
--- a/YFramework/source/NPL/NPLA1.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/NPL/NPLA1.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1.cpp
1212 \ingroup NPL
1313 \brief NPLA1 公共接口。
14-\version r23847
14+\version r23927
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 472
1717 \par 创建时间:
1818 2014-02-02 18:02:47 +0800
1919 \par 修改时间:
20- 2022-08-25 12:06 +0800
20+ 2022-09-14 02:53 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -1575,8 +1575,9 @@
15751575 }
15761576
15771577
1578-ContextState::ContextState(pmr::memory_resource& rsrc)
1579- : ContextNode(rsrc)
1578+ContextState::ContextState(const GlobalState& g)
1579+ : ContextNode(*g.Allocator.resource()),
1580+ Global(g)
15801581 {
15811582 // NOTE: The guard object shall be fresh on the calls for reentrancy.
15821583 // XXX: The empty type is specialized enough without %trivial_swap.
@@ -1586,19 +1587,15 @@
15861587 in_place_type<ReductionGuard>, ctx);
15871588 });
15881589 }
1589-ContextState::ContextState(const ContextState& ctx)
1590- : ContextNode(ctx),
1591- EvaluateLeaf(ctx.EvaluateLeaf), EvaluateList(ctx.EvaluateList),
1592- EvaluateLiteral(ctx.EvaluateLiteral), Guard(ctx.Guard),
1593- ReduceOnce(ctx.ReduceOnce)
1590+ContextState::ContextState(const ContextState& cs)
1591+ : ContextNode(cs),
1592+ Global(cs.Global), Guard(cs.Guard), ReduceOnce(cs.ReduceOnce)
15941593 {}
1595-ContextState::ContextState(ContextState&& ctx)
1596- : ContextNode(std::move(ctx)),
1597- EvaluateLeaf(ctx.EvaluateLeaf), EvaluateList(ctx.EvaluateList),
1598- EvaluateLiteral(ctx.EvaluateLiteral), Guard(ctx.Guard),
1599- ReduceOnce(ctx.ReduceOnce)
1594+ContextState::ContextState(ContextState&& cs)
1595+ : ContextNode(std::move(cs)),
1596+ Global(cs.Global), Guard(cs.Guard), ReduceOnce(cs.ReduceOnce)
16001597 {
1601- swap(next_term_ptr, ctx.next_term_ptr);
1598+ swap(next_term_ptr, cs.next_term_ptr);
16021599 }
16031600 ContextState::ImplDeDtor(ContextState)
16041601
@@ -1621,13 +1618,14 @@
16211618 // here. More specific handling can be implemented by context handlers or
16221619 // replacement of %ContextState::DefaultReduceOnce.
16231620 auto& cs(ContextState::Access(ctx));
1621+ auto& global(cs.Global.get());
16241622
16251623 if(IsCombiningTerm(term))
16261624 {
16271625 YAssert(term.size() != 0, "Invalid term found.");
16281626 // NOTE: List with single element shall be reduced as the element.
16291627 if(!IsSingleElementList(term))
1630- return DoAdministratives(cs.EvaluateList, term, ctx);
1628+ return DoAdministratives(global.EvaluateList, term, ctx);
16311629
16321630 // XXX: This may be slightly more efficient, and more importantly,
16331631 // respecting to the nested call safety on %ReduceOnce for the thunked
@@ -1649,7 +1647,7 @@
16491647 else if(!IsTyped<ValueToken>(term))
16501648 // NOTE: The reduction relies on proper handling of reduction status and
16511649 // proper tail action for the thunked implementations.
1652- return DoAdministratives(cs.EvaluateLeaf, term, ctx);
1650+ return DoAdministratives(global.EvaluateLeaf, term, ctx);
16531651 return ReductionStatus::Retained;
16541652 }
16551653
@@ -2009,7 +2007,7 @@
20092007
20102008 void
20112009 ParseLeafWithSourceInformation(TermNode& term, string_view id,
2012- const shared_ptr<string>& name, const SourceLocation& src_loc)
2010+ const SourceName& name, const SourceLocation& src_loc)
20132011 {
20142012 // NOTE: Most are same to %ParseLeaf, except for additional source
20152013 // information mixed into the values of %TokenValue.
@@ -2306,6 +2304,7 @@
23062304 EvaluateLeafToken(TermNode& term, ContextNode& ctx, string_view id)
23072305 {
23082306 auto& cs(ContextState::Access(ctx));
2307+ auto& global(cs.Global.get());
23092308
23102309 YAssertNonnull(id.data());
23112310 // NOTE: Only string node of identifier is tested.
@@ -2313,10 +2312,11 @@
23132312 // results from the analysis result of %ParseLeaf. If necessary, there can
23142313 // be inserted some additional cleanup to remove empty tokens, returning
23152314 // %ReductionStatus::Partial. Separators should have been handled in
2316- // appropriate preprocessing passes like %REPLContext::Preprocess.
2315+ // appropriate preprocessing passes like %GlobalState::Preprocess.
23172316 // XXX: Asynchronous reduction is currently not supported.
2318- return cs.EvaluateLiteral.empty() || CheckReducible(cs.EvaluateLiteral(term,
2319- cs, id)) ? EvaluateIdentifier(term, cs, id) : ReductionStatus::Retained;
2317+ return global.EvaluateLiteral.empty()
2318+ || CheckReducible(global.EvaluateLiteral(term, cs, id))
2319+ ? EvaluateIdentifier(term, cs, id) : ReductionStatus::Retained;
23202320 }
23212321
23222322 ReductionStatus
@@ -2550,10 +2550,10 @@
25502550
25512551
25522552 void
2553-SetupDefaultInterpretation(ContextState& cs, EvaluationPasses passes)
2553+SetupDefaultInterpretation(GlobalState& global, EvaluationPasses passes)
25542554 {
25552555 using Pass = EvaluationPasses::HandlerType;
2556- const auto a(cs.get_allocator());
2556+ const auto a(global.Allocator);
25572557
25582558 // XXX: Empty types and functions after decayed are specialized enough
25592559 // without %trivial_swap.
@@ -2601,9 +2601,9 @@
26012601 // implementation, assumed by TCO action.
26022602 passes += Pass(std::allocator_arg, a, ReduceCombined);
26032603 #endif
2604- cs.EvaluateList = std::move(passes);
2604+ global.EvaluateList = std::move(passes);
26052605 // NOTE: This implies the %RegularizeTerm call when necessary.
2606- cs.EvaluateLeaf = Pass(std::allocator_arg, a, ReduceLeafToken);
2606+ global.EvaluateLeaf = Pass(std::allocator_arg, a, ReduceLeafToken);
26072607 }
26082608
26092609 void
@@ -2746,40 +2746,42 @@
27462746 }
27472747
27482748
2749-REPLContext::REPLContext(pmr::memory_resource& rsrc)
2750- : REPLContext([this](const GParsedValue<ByteParser>& str){
2749+GlobalState::GlobalState(pmr::memory_resource& rsrc)
2750+ : GlobalState([this](const GParsedValue<ByteParser>& str){
27512751 TermNode term(Allocator);
27522752 const auto id(YSLib::make_string_view(str));
27532753
27542754 if(!id.empty())
27552755 ParseLeaf(term, id);
27562756 return term;
2757- }, [this](const GParsedValue<SourcedByteParser>& val){
2757+ }, [this](const GParsedValue<SourcedByteParser>& val,
2758+ const ContextState& cs){
27582759 TermNode term(Allocator);
27592760 const auto id(YSLib::make_string_view(val.second));
27602761
27612762 if(!id.empty())
2762- ParseLeafWithSourceInformation(term, id, CurrentSource, val.first);
2763+ ParseLeafWithSourceInformation(term, id, cs.CurrentSource,
2764+ val.first);
27632765 return term;
27642766 }, rsrc)
27652767 {}
2766-REPLContext::REPLContext(Tokenizer leaf_conv,
2768+GlobalState::GlobalState(Tokenizer leaf_conv,
27672769 SourcedTokenizer sourced_leaf_conv, pmr::memory_resource& rsrc)
2768- : Allocator(&rsrc), Root(rsrc), Preprocess(SeparatorPass(Allocator)),
2770+ : Allocator(&rsrc), Preprocess(SeparatorPass(Allocator)),
27692771 ConvertLeaf(std::move(leaf_conv)),
27702772 ConvertLeafSourced(std::move(sourced_leaf_conv))
27712773 {
2772- SetupDefaultInterpretation(Root, EvaluationPasses(Allocator));
2774+ SetupDefaultInterpretation(*this, EvaluationPasses(Allocator));
27732775 }
27742776
27752777 bool
2776-REPLContext::IsAsynchronous() const ynothrow
2778+GlobalState::IsAsynchronous() const ynothrow
27772779 {
27782780 return NPL_Impl_NPLA1_Enable_Thunked;
27792781 }
27802782
27812783 std::ostream&
2782-REPLContext::GetOutputStreamRef() const
2784+GlobalState::GetOutputStreamRef() const
27832785 {
27842786 if(OutputStreamPtr)
27852787 return *OutputStreamPtr;
@@ -2787,119 +2789,119 @@
27872789 }
27882790
27892791 TermNode
2790-REPLContext::DefaultLoad(REPLContext& context, ContextNode& ctx,
2791- string filename)
2792+GlobalState::DefaultLoad(ContextState& cs, string filename)
27922793 {
2793- return context.ReadFrom(*A1::OpenUnique(context, std::move(filename)), ctx);
2794+ return
2795+ cs.Global.get().ReadFrom(*A1::OpenUnique(cs, std::move(filename)), cs);
27942796 }
27952797
27962798 TermNode
2797-REPLContext::ReadFrom(LoadOptionTag<>, std::streambuf& buf, ContextNode& ctx)
2799+GlobalState::ReadFrom(LoadOptionTag<>, std::streambuf& buf, ContextState& cs)
27982800 const
27992801 {
28002802 using s_it_t = std::istreambuf_iterator<char>;
2801- Session sess(ctx.get_allocator());
2802-
2803- if(UseSourceLocation)
2804- {
2805- SourcedByteParser parse(sess.Lexer, sess.get_allocator());
2806-
2807- return Prepare(sess,
2808- sess.Process(s_it_t(&buf), s_it_t(), ystdex::ref(parse)));
2809- }
2810- return Prepare(sess, sess.Process(s_it_t(&buf), s_it_t()));
2811-}
2812-TermNode
2813-REPLContext::ReadFrom(LoadOptionTag<>, std::streambuf& buf, ReaderState& rs,
2814- ContextNode& ctx) const
2815-{
2816- using s_it_t = std::istreambuf_iterator<char>;
2817- Session sess(ctx.get_allocator());
2803+ Session sess(cs.get_allocator());
28182804
28192805 if(UseSourceLocation)
28202806 {
28212807 SourcedByteParser parse(sess.Lexer, sess.get_allocator());
28222808
2823- return Prepare(sess, sess.ProcessOne(rs, s_it_t(&buf), s_it_t(),
2824- ystdex::ref(parse)).first);
2809+ return Prepare(cs, sess,
2810+ sess.Process(s_it_t(&buf), s_it_t(), ystdex::ref(parse)));
28252811 }
2826- return Prepare(sess, sess.ProcessOne(rs, s_it_t(&buf), s_it_t()).first);
2812+ return Prepare(cs, sess, sess.Process(s_it_t(&buf), s_it_t()));
28272813 }
28282814 TermNode
2829-REPLContext::ReadFrom(LoadOptionTag<WithSourceLocation>, std::streambuf& buf,
2830- ContextNode& ctx) const
2831-{
2832- using s_it_t = std::istreambuf_iterator<char>;
2833- Session sess(ctx.get_allocator());
2834- SourcedByteParser parse(sess.Lexer, sess.get_allocator());
2835-
2836- return
2837- Prepare(sess, sess.Process(s_it_t(&buf), s_it_t(), ystdex::ref(parse)));
2838-}
2839-TermNode
2840-REPLContext::ReadFrom(LoadOptionTag<WithSourceLocation>, std::streambuf& buf,
2841- ReaderState& rs, ContextNode& ctx) const
2815+GlobalState::ReadFrom(LoadOptionTag<>, std::streambuf& buf, ReaderState& rs,
2816+ ContextState& cs) const
28422817 {
28432818 using s_it_t = std::istreambuf_iterator<char>;
2844- Session sess(ctx.get_allocator());
2845- SourcedByteParser parse(sess.Lexer, sess.get_allocator());
2846-
2847- return Prepare(sess,
2848- sess.ProcessOne(rs, s_it_t(&buf), s_it_t(), ystdex::ref(parse)).first);
2849-}
2850-TermNode
2851-REPLContext::ReadFrom(LoadOptionTag<NoSourceInformation>, std::streambuf& buf,
2852- ContextNode& ctx) const
2853-{
2854- using s_it_t = std::istreambuf_iterator<char>;
2855- Session sess(ctx.get_allocator());
2856-
2857- return Prepare(sess, sess.Process(s_it_t(&buf), s_it_t()));
2858-}
2859-TermNode
2860-REPLContext::ReadFrom(LoadOptionTag<NoSourceInformation>, std::streambuf& buf,
2861- ReaderState& rs, ContextNode& ctx) const
2862-{
2863- using s_it_t = std::istreambuf_iterator<char>;
2864- Session sess(ctx.get_allocator());
2865-
2866- return Prepare(sess, sess.ProcessOne(rs, s_it_t(&buf), s_it_t()).first);
2867-}
2868-TermNode
2869-REPLContext::ReadFrom(LoadOptionTag<>, string_view unit, ContextNode& ctx) const
2870-{
2871- YAssertNonnull(unit.data());
2872-
2873- Session sess(ctx.get_allocator());
2819+ Session sess(cs.get_allocator());
28742820
28752821 if(UseSourceLocation)
28762822 {
28772823 SourcedByteParser parse(sess.Lexer, sess.get_allocator());
28782824
2879- return Prepare(sess, sess.Process(unit, ystdex::ref(parse)));
2825+ return Prepare(cs, sess, sess.ProcessOne(rs, s_it_t(&buf), s_it_t(),
2826+ ystdex::ref(parse)).first);
28802827 }
2881- return Prepare(sess, sess.Process(unit));
2828+ return Prepare(cs, sess, sess.ProcessOne(rs, s_it_t(&buf), s_it_t()).first);
28822829 }
28832830 TermNode
2884-REPLContext::ReadFrom(LoadOptionTag<WithSourceLocation>, string_view unit,
2885- ContextNode& ctx) const
2831+GlobalState::ReadFrom(LoadOptionTag<WithSourceLocation>, std::streambuf& buf,
2832+ ContextState& cs) const
2833+{
2834+ using s_it_t = std::istreambuf_iterator<char>;
2835+ Session sess(cs.get_allocator());
2836+ SourcedByteParser parse(sess.Lexer, sess.get_allocator());
2837+
2838+ return Prepare(cs, sess,
2839+ sess.Process(s_it_t(&buf), s_it_t(), ystdex::ref(parse)));
2840+}
2841+TermNode
2842+GlobalState::ReadFrom(LoadOptionTag<WithSourceLocation>, std::streambuf& buf,
2843+ ReaderState& rs, ContextState& cs) const
2844+{
2845+ using s_it_t = std::istreambuf_iterator<char>;
2846+ Session sess(cs.get_allocator());
2847+ SourcedByteParser parse(sess.Lexer, sess.get_allocator());
2848+
2849+ return Prepare(cs, sess,
2850+ sess.ProcessOne(rs, s_it_t(&buf), s_it_t(), ystdex::ref(parse)).first);
2851+}
2852+TermNode
2853+GlobalState::ReadFrom(LoadOptionTag<NoSourceInformation>, std::streambuf& buf,
2854+ ContextState& cs) const
2855+{
2856+ using s_it_t = std::istreambuf_iterator<char>;
2857+ Session sess(cs.get_allocator());
2858+
2859+ return Prepare(cs, sess, sess.Process(s_it_t(&buf), s_it_t()));
2860+}
2861+TermNode
2862+GlobalState::ReadFrom(LoadOptionTag<NoSourceInformation>, std::streambuf& buf,
2863+ ReaderState& rs, ContextState& cs) const
2864+{
2865+ using s_it_t = std::istreambuf_iterator<char>;
2866+ Session sess(cs.get_allocator());
2867+
2868+ return Prepare(cs, sess, sess.ProcessOne(rs, s_it_t(&buf), s_it_t()).first);
2869+}
2870+TermNode
2871+GlobalState::ReadFrom(LoadOptionTag<>, string_view unit, ContextState& cs) const
28862872 {
28872873 YAssertNonnull(unit.data());
28882874
2889- Session sess(ctx.get_allocator());
2890- SourcedByteParser parse(sess.Lexer, sess.get_allocator());
2875+ Session sess(cs.get_allocator());
28912876
2892- return Prepare(sess, sess.Process(unit, ystdex::ref(parse)));
2877+ if(UseSourceLocation)
2878+ {
2879+ SourcedByteParser parse(sess.Lexer, sess.get_allocator());
2880+
2881+ return Prepare(cs, sess, sess.Process(unit, ystdex::ref(parse)));
2882+ }
2883+ return Prepare(cs, sess, sess.Process(unit));
28932884 }
28942885 TermNode
2895-REPLContext::ReadFrom(LoadOptionTag<NoSourceInformation>, string_view unit,
2896- ContextNode& ctx) const
2886+GlobalState::ReadFrom(LoadOptionTag<WithSourceLocation>, string_view unit,
2887+ ContextState& cs) const
28972888 {
28982889 YAssertNonnull(unit.data());
28992890
2900- Session sess(ctx.get_allocator());
2891+ Session sess(cs.get_allocator());
2892+ SourcedByteParser parse(sess.Lexer, sess.get_allocator());
29012893
2902- return Prepare(sess, sess.Process(unit));
2894+ return Prepare(cs, sess, sess.Process(unit, ystdex::ref(parse)));
2895+}
2896+TermNode
2897+GlobalState::ReadFrom(LoadOptionTag<NoSourceInformation>, string_view unit,
2898+ ContextState& cs) const
2899+{
2900+ YAssertNonnull(unit.data());
2901+
2902+ Session sess(cs.get_allocator());
2903+
2904+ return Prepare(cs, sess, sess.Process(unit));
29032905 }
29042906
29052907 } // namesapce A1;
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/NPL/NPLA1Forms.cpp
--- a/YFramework/source/NPL/NPLA1Forms.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/NPL/NPLA1Forms.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Forms.cpp
1212 \ingroup NPL
1313 \brief NPLA1 语法形式。
14-\version r28289
14+\version r28294
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2014-02-15 11:19:51 +0800
1919 \par 修改时间:
20- 2022-09-05 08:54 +0800
20+ 2022-09-13 02:31 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -4170,11 +4170,10 @@
41704170 }
41714171
41724172 ReductionStatus
4173-EvalUnit(TermNode& term)
4174-{
4175- CallBinaryAs<const string, REPLContext>(
4176- [&](const string& unit, REPLContext& rctx){
4177- term.SetContent(rctx.Perform(unit));
4173+EvalUnit(TermNode& term, ContextNode& ctx)
4174+{
4175+ CallUnaryAs<const string>([&](const string& unit){
4176+ term.SetContent(A1::Perform(ContextState::Access(ctx), unit));
41784177 }, term);
41794178 return ReductionStatus::Retained;
41804179 }
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/NPL/NPLA1Internals.cpp
--- a/YFramework/source/NPL/NPLA1Internals.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/NPL/NPLA1Internals.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Internals.cpp
1212 \ingroup NPL
1313 \brief NPLA1 内部接口。
14-\version r20655
14+\version r20663
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 473
1717 \par 创建时间:
1818 2020-02-15 13:20:08 +0800
1919 \par 修改时间:
20- 2022-08-18 07:51 +0800
20+ 2022-09-05 22:12 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 非公开模块名称:
@@ -142,19 +142,18 @@
142142 // represent an uncollapsed reference value, there is no need to call
143143 // %RegularizeTerm if the lift is not needed. However, this is not
144144 // easily provable, so leave it as-is.
145+ // XXX: When %req_lift_result is 0, this is only needed on a real call
146+ // from the evaluation is reentered. However, whether here is the
147+ // reentrant call is not easily provable.
148+ RegularizeTerm(GetTermRef(), ctx.LastStatus);
145149 if(req_lift_result != 0)
146150 {
147- RegularizeTerm(GetTermRef(), ctx.LastStatus);
148151 for(; req_lift_result != 0; --req_lift_result)
149152 LiftToReturn(GetTermRef());
150153 return ReductionStatus::Retained;
151154 }
152- // XXX: This is only needed on a real call from the evaluation is
153- // reentered. However, whether here is the reentrant call is not easily
154- // provable.
155155 // TODO: Anything necessary to prepare for invocation of first-class
156156 // continuations?
157- RegularizeTerm(GetTermRef(), ctx.LastStatus);
158157 return ctx.LastStatus;
159158 }());
160159
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/NPL/NPLA1Internals.h
--- a/YFramework/source/NPL/NPLA1Internals.h Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/NPL/NPLA1Internals.h Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Internals.h
1212 \ingroup NPL
1313 \brief NPLA1 内部接口。
14-\version r22506
14+\version r22522
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2020-02-15 13:20:08 +0800
1919 \par 修改时间:
20- 2022-08-18 07:51 +0800
20+ 2022-09-08 12:34 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 非公开模块名称:
@@ -360,8 +360,6 @@
360360 // components of %FrameRecord is unspecified.
361361 // XXX: Different to %ContextNode::ReducerSequence::clear, this is a bit
362362 // more efficient.
363- auto i(before_begin());
364-
365363 while(!empty())
366364 // NOTE: The order of destruction of the members in each frame is
367365 // implied by %FrameRecord.
@@ -400,10 +398,10 @@
400398 };
401399
402400 /*!
403- \brief 帧记录。
404- \note 成员顺序和 RecordFrameIndex 中的项对应。
401+ \brief 附加信息记录。
402+ \note 成员顺序和 ExtraInfoIndex 中的项对应。
405403 \note 成员析构的顺序是未指定的。
406- \sa RecordFrameIndex
404+ \sa ExtraInfoIndex
407405 */
408406 using ExtraInfo = tuple<ystdex::guard<SourceNameRecoverer>,
409407 ystdex::optional<ystdex::guard<OneShotChecker>>>;
@@ -428,6 +426,8 @@
428426 /*!
429427 \brief 可选的附加信息。
430428 \since build 947
429+
430+ 保存不是每个 TCO 动作都需被使用的信息,避免频繁创建的性能开销。
431431 */
432432 mutable ystdex::optional<ExtraInfo> opt_extra_info{};
433433
@@ -1438,10 +1438,11 @@
14381438 #if NPL_NPLA_CheckEnvironmentReferenceCount
14391439 //! \since build 876
14401440 EnvironmentReference environment_ref;
1441-#else
1441+#elif YB_IMPL_GNUCPP < 120000
14421442 // XXX: The anchor pointer here is for more efficient native code generation
1443- // (at least with x86_64-pc-linux G++ 9.2), though there are still more
1444- // than necessary memory allocations should have been better avoided.
1443+ // (at least with x86_64-pc-linux G++ 9.2, but not G++ 12.1), though there
1444+ // are still more than necessary memory allocations should have been better
1445+ // avoided.
14451446 AnchorPtr anchor_ptr;
14461447 #endif
14471448
@@ -1453,8 +1454,10 @@
14531454 const EnvironmentReference& env_ref) ynothrow
14541455 #if NPL_NPLA_CheckEnvironmentReferenceCount
14551456 : environment_ref(env_ref), HandlerRef(h)
1457+#elif YB_IMPL_GNUCPP < 120000
1458+ : anchor_ptr(env_ref.GetAnchorPtr()), HandlerRef(h)
14561459 #else
1457- : anchor_ptr(env_ref.GetAnchorPtr()), HandlerRef(h)
1460+ : HandlerRef((yunused(env_ref), h))
14581461 #endif
14591462 {}
14601463 DefDeCopyMoveCtorAssignment(RefContextHandler)
@@ -1477,10 +1480,13 @@
14771480 friend DefSwap(ynothrow, RefContextHandler,
14781481 (std::swap(_x.environment_ref, _y.environment_ref),
14791482 std::swap(_x.HandlerRef, _y.HandlerRef)))
1480-# else
1483+# elif YB_IMPL_GNUCPP < 120000
14811484 friend DefSwap(ynothrow, RefContextHandler,
14821485 (std::swap(_x.anchor_ptr, _y.anchor_ptr),
14831486 std::swap(_x.HandlerRef, _y.HandlerRef)))
1487+# else
1488+ friend DefSwap(ynothrow, RefContextHandler,
1489+ (std::swap(_x.HandlerRef, _y.HandlerRef)))
14841490 # endif
14851491 #endif
14861492 };
diff -r 05c8e54ed1bb -r 5acfef664815 YFramework/source/YSLib/Core/YCoreUtilities.cpp
--- a/YFramework/source/YSLib/Core/YCoreUtilities.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YFramework/source/YSLib/Core/YCoreUtilities.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2014-2015, 2017-2018, 2020 FrankHB.
2+ © 2014-2015, 2017-2018, 2020, 2022 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 YCoreUtilities.cpp
1212 \ingroup Core
1313 \brief 核心实用模块。
14-\version r167
14+\version r187
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 539
1717 \par 创建时间:
1818 2014-10-01 08:52:17 +0800
1919 \par 修改时间:
20- 2020-12-12 10:09 +0800
20+ 2022-09-05 22:12 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -26,8 +26,8 @@
2626
2727
2828 #include "YSLib/Core/YModules.h"
29-#include YFM_YSLib_Core_YCoreUtilities // for std::exception, ExtractException,
30-// FatalError, upopen, upclose, ExtractAndTrace;
29+#include YFM_YSLib_Core_YCoreUtilities // for FatalError, upopen, upclose,
30+// ExtractAndTrace;
3131 #include <random> // for std::random_device, std::mt19937,
3232 // std::uniform_int_distribution;
3333 #include <cstdlib> // for std::getenv;
@@ -36,26 +36,6 @@
3636 namespace YSLib
3737 {
3838
39-void
40-PerformKeyAction(function<void()> f, const char* sig,
41- const char* t, string_view sv)
42-{
43- string res;
44-
45- try
46- {
47- f();
48- return;
49- }
50- CatchExpr(std::exception& e, ExtractException(
51- [&](const string& str, size_t level){
52- res += string(level, ' ') + "ERROR: " + str + '\n';
53- }, e))
54- CatchExpr(..., res += string("Unknown exception @ ") + sig + ".\n")
55- throw FatalError(t, string(sv) + res);
56-}
57-
58-
5939 string
6040 RandomizeTemplatedString(string str, char mask, string_view tmpl)
6141 {
diff -r 05c8e54ed1bb -r 5acfef664815 YSTest/source/Shells.cpp
--- a/YSTest/source/Shells.cpp Mon Sep 05 21:43:00 2022 +0800
+++ b/YSTest/source/Shells.cpp Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file Shells.cpp
1212 \ingroup YReader
1313 \brief Shell 框架逻辑。
14-\version r6555
14+\version r6556
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since 早于 build 132
1717 \par 创建时间:
1818 2010-03-06 21:38:16 +0800
1919 \par 修改时间:
20- 2022-09-05 00:51 +0800
20+ 2022-09-14 03:06 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -172,7 +172,7 @@
172172 using namespace NPL;
173173
174174 TryExpr(env.ExecuteNPLA1([&](TermNode& term){
175- term = env.Context.ReadFrom(is);
175+ term = env.Global.ReadFrom(is, env.Main);
176176 }))
177177 // NOTE: Like %A1::TryLoadSource, but not in the inner reduction.
178178 CatchExpr(..., std::throw_with_nested(
diff -r 05c8e54ed1bb -r 5acfef664815 doc/ChangeLog.V0.9.txt
--- a/doc/ChangeLog.V0.9.txt Mon Sep 05 21:43:00 2022 +0800
+++ b/doc/ChangeLog.V0.9.txt Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file ChangeLog.V0.9.txt
1212 \ingroup Documentation
1313 \brief 版本更新历史记录 - V0.9 。
14-\version r11302
14+\version r11547
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 800
1717 \par 创建时间:
1818 2020-10-12 17:19:23 +0800
1919 \par 修改时间:
20- 2022-09-05 21:41 +0800
20+ 2022-09-14 04:19 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -32,6 +32,247 @@
3232
3333 $now
3434 (
35+ * "missing refinement on Clang++ version" @ "#pragma directive"
36+ @ "member function %monotonic_buffer_resource::do_allocate"
37+ @ %YBase.YStandardEx.MemoryResource $since b948,
38+ $= (/ $impl '#if YB_IMPL_CLANGPP' -> '#if YB_IMPL_CLANGPP >= 100000'),
39+ // To eliminate Clang++ warning [-Wunknown-warning-option], or error \
40+ with [-Werror,-Wunknown-warning-option].
41+ * $re_add(b953) DD "wrong description of the result type" @ "applicatives \
42+ ('rest&', %restv)" @ %Documentation.NPL $since b951,
43+ / %YFramework $=
44+ (
45+ / %YSLib.Core $=
46+ (
47+ / %YCoreUtilities $=
48+ (
49+ / DLDI "constructor#2" @ "class %ArgumentsVector"
50+ ^ "%CommandArguments::VectorType::allocator_type"
51+ ~ "%vector<string>::allocator_type"
52+ / "function %PerformKeyAction" @ %YCoreUtilities
53+ -> "function template" $=
54+ (
55+ ^ "template argument" ~ "%function",
56+ ^ "%std::string" ~ "%string"
57+ * $comp "unexpected implicit dependency on \
58+ %pmr::get_default_resource"
59+ // This would cause it not usable during \
60+ initialization of namespace scope variables, which \
61+ was undocumented.
62+ )
63+ ),
64+ * $re_add(b879) "missing using allocator for container copy"
65+ @ "all constructors \
66+ with 'const Container&' parameter" @ "class %ValueNode"
67+ @ %ValueNode $since b844,
68+ // The allocator would not be propagated implicitly (not \
69+ affected by the constructor transitions from b844 to \
70+ b845, which were all inconsist to the copy assignment). \
71+ Now it also behaves as the copy constrctor of %ValueNode \
72+ and %TermNode. This change effects a call sites in a \
73+ compatible way.
74+ * "missing removal of cv-qualifiers for %ValueHolder argument"
75+ @ "static function template %CreateHolder"
76+ @ "interface %IValueHolder" @ %YObject $since b761
77+ // This would make creation of cv-qualified %RefHolder \
78+ ill-formed.
79+ ),
80+ / %NPL $=
81+ (
82+ / %NPLA1Internals $=
83+ (
84+ * $doc $impl "wrong internal %ExtraInfo comments"
85+ @ "class %TCOAction" $since b947,
86+ / DLI "simplified member function %TCOAction::operator()",
87+ * DLDI "redundant unused iterator variable" @ "function %clear"
88+ @ "class template %FrameRecordList" $since b946,
89+ // To eliminate Clang++ warning: [-Wunused variable].
90+ - DLI "anchor" @ !'YB_IMPL_GNUCPP < 120000'
91+ @ "class %RefContextHandler"
92+ ),
93+ / %NPLA1 $=
94+ (
95+ * "mismatched argument type" @ "%GKeptGuardAction"
96+ $since b942
97+ $= (/ $impl ^ 'std::declval<_tGuard&&>'
98+ ~ 'std::declval<_tGuard&>'),
99+ / "allowed return non-void type"
100+ @ "function template %InvokeIn",
101+ / DLI "simplified 3rd parameter type"
102+ @ "function %ParseLeafWithSourceInformation"
103+ ^ "%SourceName",
104+ / "supported trailing parameter pack"
105+ @ "alias template %GTokenizer",
106+ / "class %REPLContext" -> "class %GlobalState" $=
107+ (
108+ - "function template %LoadFrom";
109+ // All instances should use %Perform instead.
110+ / "split preprocessing out of term prepration" $=
111+ (
112+ - "nested call" @ "function template %Prepare#2";
113+ - "function template %Prepare#1",
114+ - $comp "preprocessing" @ ("all overloads %ReadFrom",
115+ "static function %DefaultLoad";
116+ "data member %Load"),
117+ // Preprocessing is now optional and it should be \
118+ called externally if needed.
119+ / $forced DLDI "called %Preprocess"
120+ @ "function template %Perform"
121+ ),
122+ (
123+ + 'mutable' @ "data member %CurrentSource";
124+ + 'const' @ "all member function and function templates \
125+ not modifying objects except %Root"
126+ ),
127+ (
128+ + "explicit 1st parameter 'ContextNode&' type"
129+ @ "function templates %(Perform, Prepare)";
130+ // The change to %Prepare passes the context in the session.
131+ - "use of %Root" @ "members";
132+ // This includes %ReadFrom overloads without trailing \
133+ 'ContextNode&' parameter but implying %Root in the \
134+ implementation.
135+ - "data member %Root",
136+ (
137+ / "all 9 functions and 2 function templates with trailing \
138+ context parameter" ^ 'ContextState&' ~ 'ContextNode&';
139+ / $forced DLDI "simplified function template %Perform",
140+ / $forced DLI "simplified static function %DefaultLoad"
141+ )
142+ ),
143+ / @ "parameter list"
144+ @ ("alias %Loader", "static function %DefaultLoad") $=
145+ (
146+ / "type of parameter 'ContextNode&'" -> 'ContextState&',
147+ // This is needed for the source information \
148+ change of %CurrentSource, see below.
149+ - "1st parameter"
150+ ),
151+ (
152+ / "added additional source parameter" @ "%SourcedTokenizer"
153+ $dep_from "%GTokenizer",
154+ / ("data member %CurrentSource", "function template \
155+ %ShareCurrentSource") >> "class %ContextState";
156+ // So there is no need of 'mutable' and protection \
157+ (like the global interpreter lock) against \
158+ concurrent accesses via 'const GlobalState&', \
159+ which allows concurrent loading on different \
160+ %ContextState instances.
161+ / $forced DLDI "constructor" $dep_from "%CurrentSource"
162+ )
163+ ),
164+ (
165+ + "class name declaration %GlobalState";
166+ / @ "class %ContextState" $=
167+ (
168+ + "data member %Global";
169+ + "parameter type" @ "constructor#1"
170+ -> 'const GlobalState&' ~ 'pmr::memory_resource&',
171+ / $forced DLI "constructors" $dep_from "%REPLContext"
172+ )
173+ ),
174+ / $forced "1st parameter type 'REPLContext&'"
175+ @ "function template %TryLoadSource"
176+ -> 'const GlobalState&' $dep_from "%REPLContext",
177+ + "function template %Perform"
178+ $dep_from ("%Perform" @ "GlobalState"),
179+ / "data members %(EvaluationPasses, EvaluateLeaf, \
180+ EvaluateLiteral)" @ "class %ContextState"
181+ >> "class %GlobalState" $dep_to "pass lifting";
182+ // The guard pass which has no context parameter is not \
183+ moved.
184+ / $forced "simplified constructors and friend function %swap"
185+ @ "class %ContextState" $dep_from "pass lifting",
186+ / $forced "1st parameter type 'ContextState&'"
187+ @ "function %SetupDefaultInterpretation"
188+ -> 'GlobalState&' $dep_from ("class %REPLContext",
189+ "pass lifting")
190+ // This is required by both %GlobalState constructor and \
191+ the passes lifted to the global state.
192+ ),
193+ / %Configuration $=
194+ (
195+ + "allocator support" @ "class %Configuration" $=
196+ (
197+ + "alias %allocator_type";
198+ + "constructor with allocator parameter",
199+ + "constructor template with allocator parameter and \
200+ parameter pack",
201+ + "function %get_allocator"
202+ ),
203+ / DLI "supported allocator" @ "function operator>>"
204+ ^ $dep_from "%Configuration::get_allocator",
205+ / "function template %LoadNode" -> "function"
206+ ),
207+ / $forced "function %Forms::EvalUnit used context instead of \
208+ 2nd argument from the object language" @ %NPLA1Forms
209+ $dep_from ("%REPLContext" @ %NPLA1) $=
210+ (
211+ + "2nd parameter of 'ContextNode&' type";
212+ / $impl ^ $dep_from ("%A1::Perform" @ %NPLA1)
213+ ),
214+ / %Dependency $=
215+ (
216+ / $forced DLDI
217+ "functions %(ReduceToLoadExternal, RelayToLoadExternal)"
218+ $dep_from ("%REPLContext::Load" @ %NPLA1),
219+ + "applicative 'symbol?'" @ "function %LoadGroundContext",
220+ + "applicative 'string?'" @ "function %LoadModule_std_strings",
221+ / "1st parameter type 'REPLContext&'" -> 'const GlobalState&'
222+ / $forced (("functions %OpenUnique"; "function %PreloadExternal"
223+ $dep_from ("%TryLoadSource" @ %NPLA1)),
224+ "function whose name have prefix 'Load'"
225+ $dep_from ("%REPLContext" @ %NPLA1))
226+ / $= ($impl ^ $dep_from ("%A1::Perform" @ %NPLA1))
227+ )
228+ ),
229+ / @ "class %Environment" @ %Helper.Environment $=
230+ (
231+ / $forced DLDI "constructor"
232+ $dep_from ("%LoadStandardContext" @ %NPL.Dependency),
233+ (
234+ / "data member %Context" => "%Global";
235+ + "data member %Main";
236+ / "context" ^ "%Main" ~ "%Global.Root"
237+ )
238+ )
239+ ),
240+ * $comp "building failure" @ "platform %Android" $since b942
241+ $dep_from %(YBase.YStandardEx.MemoryResource,
242+ "%GKeptGuardAction" @ YFramework.NPL.NPLA1),
243+ / %Tools.SHBuild.Main $=
244+ (
245+ / @ "help message" $=
246+ (
247+ * "incorrect effect for multiple instances"
248+ @ "descriptions for the '-xcmd,' option" $since b659,
249+ / @ "common descriptions" $=
250+ (
251+ * "missing indent before the paragraph of the session epoch"
252+ $since b905
253+ + "newlines between paragraphs"
254+ ),
255+ * "missing specifying the empty string after ',' for \
256+ descriptions of OPTIONS" $since b659,
257+ / DLDI
258+ "simplified descriptions for the '-xmode,' option" ^ "macro"
259+ ),
260+ / DLI "optional table" ^ "%ystdex::unchecked_function" ~ "%function",
261+ / $forced DLI "function %RunNPLFromStream" $dep_from
262+ ("%(LoadStandardContext, LoadModule_SHBuild)"
263+ @ %YFramework.NPL.Dependency)
264+ ),
265+ / $forced DLDI "called %Preprocess function from the global state instance"
266+ $effective @ ("all 2 function templates %ExecuteNPLA1"
267+ @ "class %Environment" @ %YFramework.Helper.Environment,
268+ "function %RunNPLFromStream" @ %Tools.SHBuild.Main)
269+ $dep_from ("%REPLContext" @ %YFramework.NPL.NPLA1),
270+ / $forced DLI "function %TestNPL" @ %YReader.Shells
271+ $dep_from %YFramework.Helper.Environment
272+),
273+
274+b954
275+(
35276 / %YFramework $=
36277 (
37278 / %YSLib.Core $=
@@ -47,14 +288,14 @@
47288 + "allocator support" @ "class %MessageQueue" @ %YMessage $=
48289 (
49290 + 'using BaseType::get_allocator;';
50- + "constructor with 1 allocator parameter",
291+ + "constructor with allocator parameter",
51292 + 'using BaseType::get_allocator;'
52293 ),
53294 + "allocator support" @ "class %Application" @ %YApplication $=
54295 (
55296 + "alias %allocator_type";
56- + "constructor with 1 allocator parameter" ^ $dep_from
57- ("constructor %MessageQueue with 1 allocator parameter"
297+ + "constructor with allocator parameter" ^ $dep_from
298+ ("constructor %MessageQueue with allocator parameter"
58299 @ %YMessage),
59300 + "function %get_allocator"
60301 ^ $dep_from ("%MessageQueue::get_allocator @ "%YMessage)
@@ -1323,7 +1564,7 @@
13231564 (
13241565 - DLDI "'NPL::' prefix" @ "calls to %NPL::make_observer",
13251566 // As %NPL changes in b947, but with a different reason: the name \
1326- is introced by a using directive.
1567+ is introduced by a using directive.
13271568 + "message after linking finished"
13281569 @ "member function %BuildContext::Build"
13291570 )
@@ -5482,7 +5723,7 @@
54825723 + DLI 'YB_UNLIKELY' @ "'--' handling",
54835724 / $re_add(b926) DLDI "all 'yconstexpr const'" @ "namespace scope"
54845725 -> 'yconstexpr_inline const',
5485- / DLI "function %RunNPLStream" ^ "any_ops::trivial_swap_t",
5726+ / DLI "function %RunNPLFromStream" ^ "any_ops::trivial_swap_t",
54865727 * DLDI "PMR container" @ "option table" $since b861,
54875728 // This is safe only when the allocator lives longer. This is the \
54885729 current case, so it is only a bug of the implementation. \
diff -r 05c8e54ed1bb -r 5acfef664815 doc/NPL.txt
--- a/doc/NPL.txt Mon Sep 05 21:43:00 2022 +0800
+++ b/doc/NPL.txt Wed Sep 14 04:23:05 2022 +0800
@@ -11,13 +11,13 @@
1111 /*! \file NPL.txt
1212 \ingroup Documentation
1313 \brief NPL 规范和实现规格说明。
14-\version r29667
14+\version r29695
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 304
1717 \par 创建时间:
1818 2012-04-25 10:34:20 +0800
1919 \par 修改时间:
20- 2022-09-05 08:39 +0800
20+ 2022-09-14 01:23 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -2013,12 +2013,13 @@
20132013
20142014 @5.5.1 广义列表:
20152015 列表(list) 是元素(element) 的序列(sequence) 。
2016-NPLA 中,列表的元素是一等对象(@4.1) 。真列表(proper list) 是有限个列表元素构成的列表。
2016+真列表(proper list) 是有限个列表元素构成的列表。
20172017 空列表(empty list) 是不含有元素的列表。
20182018 每个真列表和有限个有序对(pair) 的嵌套组合表示同构。每个有序对具有两个元素。
20192019 有序对的第二个元素是列表时,则有序对是(非空的)真列表。否则,有序对是非真列表(improper list) 。
2020-NPLA 对象不支持自引用和循环数据结构(@4.2.4) ,因此非真列表是无环(acyclic) 的,不包含环(cycle) 。
2021-NPLA 广义列表是真列表或无环非真列表。
2020+NPLA 广义列表(generalized list) 是真列表或非真列表。
2021+广义列表的元素是一等对象(@4.1) ,是广义列表对象的子对象(@4.2.4.1) 。
2022+NPLA 对象不支持自引用和循环数据结构(@4.2.4) ,因此作为广义列表的非真列表是无环(acyclic) 的,不包含环(cycle) 。
20222023 取得嵌套的有序对的广义列表的同构表示分解(decompose) 这个广义列表。广义列表分解后若得到有序对,可继续被分解。经有限次分解后,广义列表不再可取得不同的同构表示,即被完全分解。
20232024 广义列表的元素是其完全分解后得到的元素,且当广义列表是真列表时,最后一个(空列表)元素。
20242025 广义列表对元素具有所有权。同一个广义列表的不同元素之间不具有所有权,生存期不相交。
@@ -4318,7 +4319,7 @@
43184319 除非另行指定,对 NPLA1 实现选项的宏的要求和约定同 NPLA 实现选项(@6.1.2) 。
43194320 和 NPLA 不同,这些选项主要用于提供参考实现,不应被直接作为公开接口;通常情形不需要更改。
43204321 特定的 API 可间接依赖这些特性,以便派生实现提供不同的优化实现,包括:
4321- A1::REPLContext::IsAsynchronous(@7.8.1)
4322+ A1::GlobalState::IsAsynchronous(@7.8.1)
43224323 部分 NPLA 安全保证(@6.1.4) 依赖:
43234324 特定的实现选项支持(如 NPL_Impl_NPLA1_Enable_ThunkedSeparatorPass(@7.9.2) ),当没有启用时可能不满足。
43244325 被调用的互操作(@5.3) 实现支持相应的安全保证。
@@ -4548,14 +4549,15 @@
45484549 @7.4.3 NPLA1 上下文状态:
45494550 类 ContextState 是 ContextNode 的 public 派生类,其对象表示 NPLA1 上下文状态,包含 NPLA 上下文的状态(@6.11.3) 。
45504551 A1::ContextState 包含作为之后的异步求值规约动作(@6.12.1) 使用的当前项(@6.10) 的下一求值项。
4551-NPLA1 上下文状态提供以下的供迭代的公共遍:
4552+NPLA1 上下文状态可访问以下的供迭代的公共遍:
45524553 守卫遍(guard pass) ,类型是一个 GuardPasses(@7.4.1.3) ,用于提供调试回调等。
45534554 叶遍(leaf pass) ,类型是一个 EvaluationPasses(@7.4.1.2) ,用于实现叶节点(@6.2.1) 对应表达式的求值。
45544555 列表遍(list pass) ,类型是一个 EvaluationPasses ,用于实现列表节点对应表达式的求值。
45554556 字面量遍(literal pass) ,类型是附加 string_view 参数的 EvaluationPasses ,用于在叶遍的处理器内部调用,处理不同类型的扩展字面量(@5.2) 。
45564557 尽管 NPLA 已约定字面量的词法构成(@5.2) ,仍使用字面量遍而不是固定的扩展字面量处理逻辑以便派生实现决定具体字面量的关于不同字面量和不同语义的处理方式,同时能保证实现逻辑的局域性。
45574558 A1::ContextState 提供以下公开 API :
4558-数据成员 EvaluateLeaf 、EvaluateList 、EvaluateLiteral 和 Guard 是上下文提供的公共遍,分别为叶遍、列表遍和守卫遍。
4559+数据成员 Global 指定全局状态(@7.8) 的引用,包含共享的公共求值遍。
4560+数据成员 Guard 是上下文提供的公共遍守卫遍。
45594561 数据成员 ReduceOnce
45604562 成员函数 RewriteGuarded 和 ContextNode::Rewrite 类似,但首先调用成员 Guard 动作。
45614563 成员函数 Access 通过指定的 ContextNode 对象中访问对应的 ContextState 引用。
@@ -5113,23 +5115,24 @@
51135115 别名模板 A1::GTokenizer 提供标记器,即和解析器的解析结果类型中的元素类型为参数的转换为 TermNode 的例程。对应解析器类型提供以下实例:
51145116 类型 A1::Tokenizer
51155117 类型 A1::SourcedTokenizer
5116-类 A1::REPLContext 可直接作为 REPL 原型。
5117-A1::REPLContext 以 ContextNode::EvaluateList(@6.11.3.1) 为第二参数调用 A1::SetupDefaultInterpretation 初始化,之后默认解释配置 ContextNode 具有以下能在 A1::ReduceOnce(@7.4.4) 运行的规约算法:
5118-A1::REPLContext 使用 @7.5.3 的 API 实现标记器。
5118+类 A1::GlobalState 提供全局状态,可直接作为 REPL 原型。
5119+其中,数据成员 EvaluateLeaf 、EvaluateList 、EvaluateLiteral 是全局公共遍(@7.4.3) ,分别为叶遍、列表遍和字面量求值遍。
5120+A1::GlobalState 以 ContextNode::EvaluateList(@6.11.3.1) 为第二参数调用 A1::SetupDefaultInterpretation 初始化,之后默认解释配置 ContextNode 具有以下能在 A1::ReduceOnce(@7.4.4) 运行的规约算法:
5121+A1::GlobalState 使用 @7.5.3 的 API 实现标记器。
51195122 若项是具有一个子项的列表节点,则规约为这个子项;
51205123 若项是具有多个子项的列表节点,依次调用 NPL::ReduceHeadEmptyList(@6.10.7.1) 、A1::ReduceFirst(@7.4.6) 和 A1::ReduceCombined(@7.6.4.2) 规约列表项;
51215124 否则调用 A1::ReduceLeafToken(@7.6.4) 规约叶节点。
5122-A1::REPLContext(@7.8.1)
5125+A1::GlobalState(@7.8.1)
51235126 函数模板 A1::TryLoadSource
51245127
5125-@7.8.1 类 A1::REPLContext :
5126-A1::REPLContext REPL 是上下文对象类。
5127-类 A1::REPLContext 还提供以下 API :
5128+@7.8.1 类 A1::GlobalState :
5129+A1::GlobalState REPL 是上下文对象类。
5130+类 A1::GlobalState 还提供以下 API :
51285131 数据成员 Preprocess 是内部保存的求值表达式一次预处理的处理器。这在 NPLA1 规范求值算法(@7.8.2) 前生效,不处理子表达式。
51295132 成员函数 IsAsynchronous 判断是否启用异步规约实现(@7.9.2) 。
51305133
51315134 @7.8.2 NPLA1 规范(canonical) 求值算法:
5132-A1::REPLContext(@7.8.1) 配置的主规约函数实现的(@7.4.4) 具体求值算法(@4.4.1) 称为 NPLA1 规范求值算法。
5135+A1::GlobalState(@7.8.1) 配置的主规约函数实现的(@7.4.4) 具体求值算法(@4.4.1) 称为 NPLA1 规范求值算法。
51335136 NPLA1 规范求值算法和 [RnRK] 中定义的 Kernel 求值算法(以及 [Shu10] 中定义的 vau 演算(@1.4) )类似,差异为:
51345137 求值算法不直接约定取得 WHNF(@4.4.5.1) 以外的子项是否被求值,而由被调用的第一个子项的处理器 A1::FormContextHandler::operator() (@7.6.1.2) 决定;
51355138 求值符号同 A1::EvaluateIdentifier(@7.6.4) ,包含对引用值的区分;
@@ -5184,7 +5187,7 @@
51845187 和 klisp 不同,NPLA1 允许使用 . 作为变量名,但在特定的上下文不被求值时符号 . 可被特别处理,如变量绑定匹配(@7.7.3.3) 时忽略以 . 为符号的忽略绑定。
51855188 和 klisp 不同,NPLA1 允许使用 ++ 等全以 + 或 - 组成的字符序列构成标识符。
51865189 以 # 、+ 或 - 起始的不能构成标识符的词素是 NPLA 扩展字面量(@5.2.3.2) 。
5187-一些求值算法的性质在实现上由 NPLA1 间接值使用规则(@7.1.3) 、A1::EvaluateIdentifier(@7.6.4) 和 A1::REPLContext 配置的求值遍保证。
5190+一些求值算法的性质在实现上由 NPLA1 间接值使用规则(@7.1.3) 、A1::EvaluateIdentifier(@7.6.4) 和 A1::GlobalState 配置的求值遍保证。
51885191
51895192 @7.9 异步规约支持:
51905193 异步规约(@6.12) 支持基于异步规约动作(@6.12.1) 实现。
@@ -6109,7 +6112,7 @@
61096112 load-external :A1::RelayToLoadExternal(@8.5.2) 加载外部翻译单元。
61106113 match-ptree-recursive :支持延迟递归绑定( Forms::DefineWithRecursion 和 Forms::SetWithRecursion(@8.4.4.3) )。
61116114 provide-let-return :Forms::ProvideLet(@8.4.9) 返回环境。
6112-restore-source-name :非 TCO 的 A1::ReduceToLoadExternal 和 A1::RelayToLoadExternal(@8.5.1) 及 Forms::LoadModule_std_modules(@8.5.2) 在加载模块求值后恢复 REPLContext(@7.8) 中保存的源代码名称。
6115+restore-source-name :非 TCO 的 A1::ReduceToLoadExternal 和 A1::RelayToLoadExternal(@8.5.1) 及 Forms::LoadModule_std_modules(@8.5.2) 在加载模块求值后恢复 GlobalState(@7.8) 中保存的源代码名称。
61136116 require-return :异步规约的 LoadModule_std_module 实现 require 加载翻译单元后设置和返回结果。
61146117 sequence-return :非 TCO 的 A1::ReduceOrdered(@7.4.6) 实现中设置规约合并最后的返回结果。
61156118 **注释**
@@ -7992,12 +7995,13 @@
79927995 null? <object> :判断操作数是否为空列表。
79937996 nullv? <object> :判断操作数是否为空列表纯右值。
79947997 同 null? ,但不支持引用值。
7995-branch? <object> :判断操作数是否具有枝节点表示。
7998+branch? <object> :判断操作数是否具有枝节点(@6.2.1) 表示。
79967999 branchv? <object> :判断操作数是否为具有枝节点表示的纯右值。
79978000 同 branch? ,但不支持引用值。
79988001 pair? <object> :<pair> 的类型谓词(@10.7.2.1) 。
79998002 pairv? <object> :判断操作数是否为有序对纯右值。
80008003 同 pair? ,但不支持引用值。
8004+symbol? <object> : <symbol> 的类型谓词。
80018005 reference? <object> :判断操作数是否为引用值。
80028006 unique? <object> :判断操作数是否为唯一引用(@6.2.2) 。
80038007 modifiable? <object> :判断操作数是否为可修改对象或可修改对象的引用值。
@@ -8320,11 +8324,11 @@
83208324 firstv <pair> :同 first ,但结果总是返回值转换后的值。
83218325 rest% <pair> :取有序对的第一个元素以外的元素值经过转发的值构成的有序对。
83228326 若结果构成子有序对(@9.9.4.1) ,可能引入子有序对引用(@9.9.4.1) 。
8323-rest& <pair> :取有序对的第一个元素以外的元素值的引用值构成的列表的子对象引用(@11.2.4) 。
8324-首先调用 check-pair-reference 检查参数是列表引用,对右值引发错误。
8327+rest& <pair> :取有序对的第一个元素以外的元素值的引用值构成的有序对的子对象引用(@11.2.4) 。
8328+首先调用 check-pair-reference 检查参数是有序对引用,对右值引发错误。
83258329 若结果构成子有序对,引入子有序对引用。
8326-restv <pair> :取有序对的第一个元素以外的元素值构成的列表。
8327-结果是列表对象。
8330+restv <pair> :取有序对的第一个元素以外的元素值构成的有序对。
8331+结果是有序对对象。
83288332 set-first! <pair> <object> :修改有序对的第一个元素。
83298333 和 [RnRK] 的 set-car! 类似,但可派生,检查列表是左值,且不保留引用值。
83308334 set-first@! <pair> <object> :同 set-first%! ,但保留未折叠的引用值。
@@ -8841,6 +8845,7 @@
88418845 std::regex_constants::match_default ;
88428846 std::regex_constants::format_default 。
88438847 操作:
8848+string? <object> :<string> 的类型谓词(@10.7.2.1) 。
88448849 ++ <string>... :字符串串接。
88458850 string-empty? <string> :判断字符串是否为空。
88468851 string<- <string1> <string2> :字符串赋值(@9.8.3.1) 。
@@ -8887,8 +8892,8 @@
88878892 因为当前不提供取得求值构造的读取(read) 等函数,不要求 load 具有非本机的派生实现。并且,取得求值构造可能有其它方式,如从二进制映像映射(map) 到内部表示等替代,这些实现通常不应被要求为总是具有本机派生实现而降低实现质量。
88888893 **注释**
88898894 关于 newline 、put 和 puts :
8890-实现使用 REPLContext::GetOutputStreamRef(@7.8.1) 。
8891-在使用前,一般应初始化 REPLContext::OutputStreamPtr(@7.8.1) 指向特定的 std::ostream 对象;否则,总是失败,引起错误(@9.5.1) 。
8895+实现使用 GlobalState::GetOutputStreamRef(@7.8.1) 。
8896+在使用前,一般应初始化 GlobalState::OutputStreamPtr(@7.8.1) 指向特定的 std::ostream 对象;否则,总是失败,引起错误(@9.5.1) 。
88928897 关于 load 和 get-module :
88938898 参数一般指定视为外部翻译单元的文件名。
88948899 http://klisp.org/docs/Ports.html#Ports 的 load 描述中求值环境有误:
Show on old repository browser