YSTest: NPLA1Internals.cpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

NPLA1Internals.cpp
浏览该文件的文档.
1 /*
2 © 2018-2020 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "NPL/YModules.h"
29 #include "NPLA1Internals.h" // for NPL::Deref, Environment, shared_ptr,
30 // std::make_move_iterator, NPL::AsTermNode;
31
32 using namespace YSLib;
33
34 namespace NPL
35 {
36
37 namespace A1
38 {
39
40 inline namespace Internals
41 {
42
43 #if NPL_Impl_NPLA1_Enable_Thunked
44 # if NPL_Impl_NPLA1_Enable_TCO
45 ReductionStatus
46 TCOAction::operator()(ContextNode& ctx) const
47 {
48 YAssert(ystdex::ref_eq<>()(EnvGuard.func.Context.get(), ctx),
49 "Invalid context found.");
50
51 // NOTE: Lifting is optional, but is shall be performed before release
52 // of guards. See also $2018-02 @ %Documentation::Workflow.
53 const auto res(HandleResultRequests(TermRef, ctx));
54
55 // NOTE: The order here is significant. The environment in the guards
56 // should be hold until lifting is completed.
57 {
58 const auto egd(std::move(EnvGuard));
59 }
60 while(!xgds.empty())
61 xgds.pop_back();
62 // NOTE: This should be after the guards to ensure there is no term
63 // references the environment.
64 while(!RecordList.empty())
65 {
66 // NOTE: The order is significant, as %FrameRecord destruction now
67 // is unspecified, and temporary objects have dependencies on
68 // environments.
69 auto& front(RecordList.front());
70
71 get<ActiveCombiner>(front) = {};
72 RecordList.pop_front();
73 }
74 return res;
75 }
76
77
78 TCOAction&
79 EnsureTCOAction(ContextNode& ctx, TermNode& term)
80 {
81 auto p_act(AccessTCOAction(ctx));
82
83 if(!p_act)
84 {
85 SetupTailTCOAction(ctx, term, {});
86 p_act = AccessTCOAction(ctx);
87 }
88 return NPL::Deref(p_act);
89 }
90
91
92 void
93 RecordCompressor::Compress()
94 {
95 // NOTE: This is need to keep the root as external reference.
96 const auto p_root(NPL::Nonnull(RootPtr.lock()));
97
98 // NOTE: Trace.
99 for(auto& pr : Universe)
100 {
101 auto& e(pr.first.get());
102
103 Traverse(e, e.Parent, [this](const shared_ptr<Environment>& p_dst){
104 auto& count(Universe.at(NPL::Deref(p_dst)));
105
106 YAssert(count > 0, "Invalid count found in trace record.");
107 --count;
108 return false;
109 });
110 }
111 for(auto i(Universe.cbegin()); i != Universe.cend(); )
112 if(i->second > 0)
113 {
114 // TODO: Blocked. Use ISO C++17 container node API for efficient
115 // implementation.
116 NewlyReachable.insert(i->first);
117 i = Universe.erase(i);
118 }
119 else
120 ++i;
121 for(ReferenceSet rs; !NewlyReachable.empty();
122 NewlyReachable = std::move(rs))
123 {
124 for(const auto& e : NewlyReachable)
125 Traverse(e, e.get().Parent,
126 [&](const shared_ptr<Environment>& p_dst) ynothrowv{
127 auto& dst(NPL::Deref(p_dst));
128
129 rs.insert(dst);
130 Universe.erase(dst);
131 return false;
132 });
133 Reachable.insert(std::make_move_iterator(NewlyReachable.begin()),
134 std::make_move_iterator(NewlyReachable.end()));
135 for(auto i(rs.cbegin()); i != rs.cend(); )
136 if(ystdex::exists(Reachable, *i))
137 i = rs.erase(i);
138 else
139 ++i;
140 }
141
142 // XXX: Need full support of PTC by direct DFS traverse?
143 ReferenceSet accessed;
144
145 ystdex::retry_on_cond(ystdex::id<>(), [&]() -> bool{
146 bool collected = {};
147
148 Traverse(*p_root, p_root->Parent,
149 [&](const shared_ptr<Environment>& p_dst, Environment& src,
150 ValueObject& parent) -> bool{
151 auto& dst(NPL::Deref(p_dst));
152
153 if(accessed.insert(src).second)
154 {
155 if(!ystdex::exists(Universe, ystdex::ref(dst)))
156 return true;
157 // NOTE: Variable %parent can be a single parent in a list
158 // of parent environments not equal to %src.Parent.
159 // XXX: The envionment would be finally collected after the last
160 // reference is destroyed. The order of destruction of
161 // environments is unspecified but determined by the parentage.
162 parent = dst.Parent;
163 collected = true;
164 }
165 return {};
166 });
167 return collected;
168 });
169 }
170 # endif
171 #endif
172
173
174 EnvironmentReference
175 FetchTailEnvironmentReference(const TermReference& ref, ContextNode& ctx)
176 {
177 auto r_env(ref.GetEnvironmentReference());
178
179 // NOTE: Unsafe term reference is enforced to be safe with current
180 // environment as the holder.
181 return
182 r_env.GetAnchorPtr() ? r_env : EnvironmentReference(ctx.GetRecordPtr());
183 }
184
185 ReductionStatus
186 ReduceForCombinerRef(TermNode& term, ContextNode& ctx,
187 const TermReference& ref, const ContextHandler& h, size_t n)
188 {
189 const auto& r_env(FetchTailEnvironmentReference(ref, ctx));
190 const auto a(term.get_allocator());
191 auto p_sub(YSLib::allocate_shared<TermNode>(a, NPL::AsTermNode(a,
192 ContextHandler(FormContextHandler(RefContextHandler(h, r_env), n)))));
193 auto& sub(NPL::Deref(p_sub));
194 TermNode tm(std::allocator_arg, a, {NPL::AsTermNode(a, std::move(p_sub))},
195 std::allocator_arg, a, TermReference(sub, r_env));
196
197 term.SetContent(std::move(tm));
198 return ReductionStatus::Retained;
199 }
200
201 } // inline namespace Internals;
202
203 } // namesapce A1;
204
205 } // namespace NPL;
206
ystdex::fseq::front
identity< _type > front(empty_base< _type, _types... >)
Definition: variadic.hpp:74
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:112
NPL::TermReference
项引用。
Definition: NPLA.h:1068
platform::Nonnull
YB_PURE _type && Nonnull(_type &&p) ynothrowv
断言并返回非空参数。
Definition: Debug.h:518
NPL::Environment
环境。
Definition: NPLA.h:2004
ystdex::retry_on_cond
invoke_result_t< _fCallable, _tParams... > retry_on_cond(_fCond cond, _fCallable &&f, _tParams &&... args)
循环重复调用：代替直接使用 do-while 语句以避免过多引入作用域外的变量。
Definition: functional.hpp:554
NPL::A1::Internals::term
_fCurrent TermNode &decltype(cur(term, ctx)) term
Definition: NPLA1Internals.h:593
NPL::A1::Internals::ReduceForCombinerRef
ReductionStatus ReduceForCombinerRef(TermNode &term, ContextNode &ctx, const TermReference &ref, const ContextHandler &h, size_t n)
Definition: NPLA1Internals.cpp:186
NPL::A1::ContextHandler
YSLib::GHEvent< ReductionStatus(TermNode &, ContextNode &)> ContextHandler
上下文处理器类型。
Definition: NPLA1.h:72
TermRef
lref< const TermNode > TermRef
Definition: NPLA1Forms.cpp:262
NPLA1Internals.h
NPLA1 内部接口。
NPL::tm
tm
Definition: NPLA.h:1941
YModules.h
NPL 库模块配置文件。
YSLib::YAssert
YAssert(!(v< Deref(a)), "Value less than lower bound found.")
YSLib::ValueObject
值类型对象类。
Definition: YObject.h:1068
YSLib::Drawing::src
src
Definition: YGDI.h:442
NPL::EnvironmentReference
环境引用计数检查支持。
Definition: NPLA.h:986
YSLib::GHEvent< ReductionStatus(TermNode &, ContextNode &)>
YSLib::i
return i
Definition: YCoreUtilities.h:177
ystdex::exists
bool exists(const _tCon &con, const _tKey &key)
判断指定的容器中存在指定的键。
Definition: container.hpp:462
NPL::A1::Internals::FetchTailEnvironmentReference
EnvironmentReference FetchTailEnvironmentReference(const TermReference &ref, ContextNode &ctx)
Definition: NPLA1Internals.cpp:175
NPL
Definition: NPL/Configuration.h:35
ystdex::ref_eq
引用等价关系仿函数。
Definition: functor.hpp:450
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:46
NPL::ContextNode
上下文节点。
Definition: NPLA.h:2385
platform::Deref
YB_PURE yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:547
NPL::A1::FormContextHandler
形式上下文处理器。
Definition: NPLA1.h:919
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
ystdex::id
恒等仿函数。
Definition: functor.hpp:94
NPL::AsTermNode
typename _tParams YB_ATTR_nodiscard YB_PURE ystdex::enable_if_t< ystdex::not_< ystdex::cond_or_t< ystdex::bool_<(sizeof...(_tParams) >=1)>, ystdex::false_, std::is_convertible, ystdex::decay_t< _tParams >..., TermNode::allocator_type > >::value, TermNode > AsTermNode(_tParams &&... args)
Definition: SContext.h:601
ystdex::ref
void ref(const _type &&)=delete
NPL::ReductionStatus
ReductionStatus
规约状态：某个项上的一遍规约可能的中间结果。
Definition: NPLA.h:1520
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:168