From 18 Jan, 2021 0:00 UTC: All services will be temporary unavailable for maintenance
  • R/O
  • SSH

YSLib: Commit

The YSLib project - main repository


Commit MetaInfo

Revisiond1f3d524f742f086e693c526456aa036606413f9 (tree)
Time2021-01-09 05:33:56
AuthorFrankHB <frankhb1989@gmai...>
CommiterFrankHB

Log Message

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

Change Summary

Incremental Difference

diff -r a285f6f132e8 -r d1f3d524f742 3rdparty/freetype/builds/build-ds.sh
--- a/3rdparty/freetype/builds/build-ds.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/3rdparty/freetype/builds/build-ds.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,7 +1,7 @@
1-rm -fr ../objs/ds/
2-mkdir ../objs/ds
3-cp -r ./ds/modules.cfg ../objs/ds/
4-cd ds
5-make -j -f buildlib.mk
6-cd ..
1+#!/usr/bin/env sh
2+# (C) 2014, 2020-2021 FrankHB.
3+# FreeType2 build script for platform DS.
74
5+rm -fr ../objs/ds/ && mkdir -p ../objs/ds \
6+&& cp -r ./ds/modules.cfg ../objs/ds/ && (cd ds && make -j -f buildlib.mk)
7+
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-BuildApp.txt
--- a/Tools/Scripts/SHBuild-BuildApp.txt Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-BuildApp.txt Sat Jan 09 04:33:56 2021 +0800
@@ -1,4 +1,4 @@
1-"#", "(C) 2014-2018, 2020 FrankHB.",
1+"#", "(C) 2014-2018, 2020-2021 FrankHB.",
22 "NPLA1 script for building YSLib applications using SHBuild.";
33
44 $import! std.strings ++ string-empty? string<-,
@@ -15,11 +15,11 @@
1515 $env-de!
1616 $redef!
1717 SHBuild_CheckCXX
18- SHBuild_Extend_CallVariables
1918 SHBuild_GetPlatformStrings
2019 SHBuild_Platform_Detect
2120 build-with-conf-opt
2221 cons-cmd
22+ ld-ext-noadjust_
2323 ld-ext-adjust_win32_subsystem_
2424 putss
2525 rmatch?
@@ -36,9 +36,6 @@
3636 $def! (host-arch host-os) () SHBuild_GetPlatformStrings;
3737 $assert-nonempty host-arch,
3838 $assert-nonempty host-os;
39-"NOTE", "See %SHBuild-YSLib-build.txt";
40-$def! host-platform_ SHBuild_Platform_Detect host-os host-arch;
41-$env-de! SHBuild_YSLib_Platform host-platform_;
4239
4340 $def! SR_Prefix_ SHBuild_DirectoryOf_ (SHBuild_DirectoryOf_ SR_Share_NPLA1_);
4441 $def! SR_Bin_ ++ SR_Prefix_ "/bin";
@@ -150,11 +147,6 @@
150147 safeenv-set "LIBS" (SHBuild_TrimOptions_
151148 (cons-cmd LIBS "-Wl,-dn" SHBuild_YSLib_LibNames))
152149 );
153- "XXX", "Workaround for MinGW32 release static builds.",
154- "See $2020-10 @ doc/Workflow.txt.";
155- $defl! fix-flags (flags)
156- $if ($and? (win32? host-os) (eqv? host-arch "i686")
157- (not? dynamic)) (++ flags " -fno-lto") flags;
158150 "NOTE", "Configuration (except variable echo) done.";
159151 $def! SHBuild_BuildDir safeenv-get "SHBuild_BuildDir";
160152 "NOTE", "Different to %SHBuild-YSLib-build.txt, relative paths are",
@@ -165,13 +157,16 @@
165157 $env-de! SHBuild ++ SR_Bin_ "/SHBuild";
166158 $assert-nonempty SHBuild;
167159 build-with-conf-opt (++ SHBuild_BuildDir "." SHBuild_Conf) host-os debug
168- dynamic "" #t
169- ld-ext-adjust_win32_subsystem_ ($lambda (#ignore CXXFLAGS SHBOPT .)
160+ dynamic "" #t ($if debug ld-ext-noadjust_
161+ ld-ext-adjust_win32_subsystem_) ($lambda (#ignore CXXFLAGS SHBOPT .)
170162 (
171163 "TODO", "Support precompiled headers?";
172- () SHBuild_Extend_CallVariables;
164+ "XXX", "'-fno-lto' is the workaround for MinGW32 release static",
165+ " builds. See $2020-10 @ doc/Workflow.txt.";
173166 system-check (++ SHBuild " " (apply cons-cmd (append SHBOPT_BASE
174- (list SHBOPT) (list (fix-flags CXXFLAGS))
167+ (list SHBOPT) (list CXXFLAGS) ($if ($and? (eqv?
168+ (SHBuild_Platform_Detect host-os host-arch) "MinGW32")
169+ (not? dynamic)) (list "-fno-lto") ())
175170 (list SHBuild_YSLib_Flags))))
176171 )
177172 )
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-YSLib-build.txt
--- a/Tools/Scripts/SHBuild-YSLib-build.txt Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-YSLib-build.txt Sat Jan 09 04:33:56 2021 +0800
@@ -1,4 +1,4 @@
1-"#", "(C) 2014-2020 FrankHB.",
1+"#", "(C) 2014-2021 FrankHB.",
22 "NPLA1 script for building YSLib using SHBuild.";
33
44 $import! std.strings ++ string->symbol string-empty?,
@@ -16,7 +16,6 @@
1616 SHBuild_2m
1717 SHBuild_CheckCXX
1818 SHBuild_EchoVar_N
19- SHBuild_Extend_CallVariables
2019 SHBuild_GetPlatformStrings
2120 SHBuild_GetSystemPrefix
2221 SHBuild_Platform_Detect
@@ -24,7 +23,6 @@
2423 cons-cmd
2524 get_env_SHB_
2625 ld-ext-noadjust_
27- rmatch?
2826 safeenv-empty?
2927 safeenv-get
3028 safeenv-restore
@@ -33,6 +31,7 @@
3331 system-or-puts
3432 system-quote-m_
3533 putss
34+ use-ubsan?
3635 win32?
3736 ) load ($let () ++ (env-get "SHBuild_ToolDir") "/SHBuild-YSLib-common.txt");
3837
@@ -157,8 +156,7 @@
157156 $def! inc-pch ()
158157 );
159158 $def! DFLAG_B_YB $if dynamic "-DYB_BUILD_DLL" "";
160- () SHBuild_Extend_CallVariables;
161- $def! base_LDFLAGS env-get "LDFLAGS";
159+ $if dynamic ($def! base_LDFLAGS env-get "LDFLAGS");
162160 "NOTE", "The prefix 'lib' is explicit, see %InstLibD.";
163161 $defl! build-lib (lib-name inc-pch .opts)
164162 $let ((dname ++ (dnameof lib-name)))
@@ -191,32 +189,29 @@
191189 $def! mingw64g
192190 $and? use-g++ (eqv? host-platform_ "MinGW64");
193191 "XXX", "See $2020-12 @ doc/Workflow.txt.";
194- $defl! use-asan? (opt) rmatch? opt
195- "-f(address-sanitizer|sanitize=[a-z,]*address)";
196- $def! linuxgrd-asan $and? use-g++ (not? debug) dynamic
197- (eqv? host-platform_ "Linux")
198- ($or? (use-asan? SHBuild_CXXFLAGS)
199- (use-asan? (safeenv-get "SHBuild_LDFLAGS")));
200- $defl! fix-flags-add ()
201- (
192+ $def! SHBuild_LDFLAGS safeenv-get "SHBuild_LDFLAGS";
193+ $defl! add-fix-flags ()
202194 $cond
203195 (mingw64g $if dynamic
204196 "-Og -g -fno-var-tracking-assignments"
205197 "-O1 -g -fno-var-tracking-assignments")
206- (linuxgrd-asan "-fno-var-tracking-assignments")
198+ (($and? use-g++ (not? debug) dynamic
199+ (eqv? host-platform_ "Linux")
200+ ($or? (use-ubsan? SHBuild_CXXFLAGS)
201+ (use-ubsan? SHBuild_LDFLAGS)))
202+ "-fdisable-tree-einline -fno-lto")
207203 (mingw32r "-fno-lto")
208- (#t "")
209- );
210- $defl! fix-flags-add-w ()
204+ (#t "");
205+ $defl! add-fix-flags-w ()
211206 (
212- $def! extra () fix-flags-add;
213- $unless (string-empty? extra) (puts (++
207+ $def! extra () add-fix-flags;
208+ $unless (string-empty? extra) (putss
214209 "WARNING: Additional option are prepended to work"
215- " around the YFramework build: '" extra "'."));
210+ " around the YFramework build: '" extra "'.");
216211 extra
217212 );
218213 build-lib "YFramework" ($if mingw64g () inc-pch)
219- (() fix-flags-add-w) ($if dynamic "-DYB_DLL" "")
214+ (() add-fix-flags-w) ($if dynamic "-DYB_DLL" "")
220215 ($if dynamic "-DYF_BUILD_DLL" "") "-DFREEIMAGE_LIB"
221216 (SHBuild_TrimOptions_ (++ INCLUDES_YFramework " "
222217 CFLAGS_freetype_other))
@@ -330,8 +325,7 @@
330325 safeenv-restore "LIBS";
331326 safeenv-set "LIBS" (SHBuild_TrimOptions_ (cons-cmd (safeenv-get "LIBS") "-L"
332327 (system-quote-m_ SR_Lib_) "-lYFramework -lYBase"));
333-$def! INCLUDES_ ++ (safeenv-get "INCLUDES") " -I"
334- (system-quote-m_ SR_Include_);
328+$def! INCLUDES_ ++ (safeenv-get "INCLUDES") " -I" (system-quote-m_ SR_Include_);
335329
336330 $let ((target-name "stage 2 SHBuild"))
337331 (
@@ -340,14 +334,10 @@
340334 putss "Building " target-name " ...";
341335 $assert-absolute-path src-dir;
342336 "XXX", "Extra options for SHBOPT are always empty now.";
343- build-with-conf-opt SR_SHBuild_ host-os #f #t "" #t
344- ld-ext-noadjust_ ($lambda (CXX CXXFLAGS SHBOPT LIBPFX)
345- (
346- () SHBuild_Extend_CallVariables;
347- system-check (apply cons-cmd (append (list e_S1_SHBuild_ src-dir
348- SHBOPT) extra-opts (list CXXFLAGS INCLUDES_)))
349- )
350- );
337+ build-with-conf-opt SR_SHBuild_ host-os #f #t "" #t ld-ext-noadjust_
338+ ($lambda (CXX CXXFLAGS SHBOPT LIBPFX)
339+ system-check (apply cons-cmd (append (list e_S1_SHBuild_
340+ src-dir SHBOPT) extra-opts (list CXXFLAGS INCLUDES_))));
351341 putss "Finished building " target-name "."
352342 );
353343 putss "Installing " target-name " ...";
@@ -376,13 +366,10 @@
376366 " these tools, while 'SHBuild_ToolDir' is expected more portable.";
377367 build-with-conf-opt SR_SHBuild_ host-os #f #t "" #t
378368 ld-ext-noadjust_ ($lambda (CXX CXXFLAGS SHBOPT LIBPFX)
379- for-each-ltr ($lambda (name) (
380- () SHBuild_Extend_CallVariables;
381- system-check (apply cons-cmd (append (list e_S2_SHBuild_
382- (++ SHBuild_BaseDir "/../" name) SHBOPT) extra-opts
383- (list CXXFLAGS INCLUDES_)))
384- )) tools-list
385- );
369+ for-each-ltr ($lambda (name)
370+ system-check (apply cons-cmd (append
371+ (list e_S2_SHBuild_ (++ SHBuild_BaseDir "/../" name) SHBOPT)
372+ extra-opts (list CXXFLAGS INCLUDES_)))) tools-list);
386373 puts "Installing other development tools ...";
387374 $import! env_SHB_ InstHardLinkExe;
388375 for-each-ltr ($lambda (name) (
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-YSLib-common.txt
--- a/Tools/Scripts/SHBuild-YSLib-common.txt Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-YSLib-common.txt Sat Jan 09 04:33:56 2021 +0800
@@ -1,4 +1,4 @@
1-"#", "(C) 2014-2020 FrankHB.",
1+"#", "(C) 2014-2021 FrankHB.",
22 "NPLA1 script as common library.";
33
44 "XXX", "'SHBuild_2*' depend on 'cygpath' optionally.";
@@ -17,13 +17,14 @@
1717 "NOTE", "Prelude:", "Unsafe functions not friendly to environment stability",
1818 " or dangerous to environments except 'move!', 'assign!' and",
1919 " 'lock-current-environment' are poisoned.";
20-$provide/d! (assign%! assign@! copy-environment lock-environment
21- $defrec! $setrec! make-standard-environment) mods
20+$provide! (assign%! assign@! copy-environment lock-environment
21+ $defrec! $setrec! make-standard-environment)
2222 (
2323 $def! fns (unwrap list) move! assign%! assign@! copy-environment
2424 lock-environment $defrec! $setrec!;
25- $defl/e! raise-error mods (&fn) SHBuild_RaiseError_
26- (++ "ERROR: Use of unsafe function '" fn "' is not allowed.");
25+ $defl/e! raise-error (make-environment env_SHBuild_ std.strings) (&fn)
26+ SHBuild_RaiseError_
27+ (++ "ERROR: Use of unsafe function '" fn "' is not allowed.");
2728 $defl! poison-fn (&fn &env)
2829 eval (list $defl/e! fn (() make-standard-environment)
2930 (string->symbol ".") raise-error (symbol->string fn)) env;
@@ -45,21 +46,20 @@
4546 (eval (list $set! env var vexpr) env);
4647
4748 "NOTE", "Saving environments at first to avoid being overriden unexpectedly.";
48-$provide/d! (safeenv-get safeenv-set ss-verbose-puts) ext-env
49+$provide! (safeenv-get safeenv-set ss-verbose-puts)
4950 (
5051 $import! std.system env-empty?;
5152
5253 "NOTE", "Nonempty environment variable 'SS_*' would enable specifically.",
5354 "See user documentation Tools/Scripts.zh-CN.md.";
54- $def! SS_DebugEnv not? (env-empty? "SS_DebugEnv"),
55- $def! SS_Verbose not? (env-empty? "SS_Verbose");
56- $def! mods $bindings/p->environment
55+ $def! mods $let ((ss_DebugEnv not? (env-empty? "SS_DebugEnv")))
56+ $bindings/p->environment
5757 (std.environments std.strings std.system std.io)
5858 (emap () make-environment)
59- (SS_DebugEnv SS_DebugEnv)
60- (SS_Verbose SS_Verbose)
61- (log-set $if SS_DebugEnv
62- ($lambda/e ext-env (name value)
59+ (SS_DebugEnv ss_DebugEnv)
60+ (SS_Verbose not? (env-empty? "SS_Verbose"))
61+ (log-set $if ss_DebugEnv
62+ ($lambda/e (make-environment env_SHBuild_ std.io) (name value)
6363 (puts "SS_DebugEnv: "; SHBuild_EchoVar name value))
6464 ($lambda .));
6565
@@ -240,12 +240,22 @@
240240
241241 $defl! SHBuild_Extend_CallVariables ()
242242 (
243- $env-de! SHBuild_LDFLAGS "";
244- $unless (string-empty? SHBuild_LDFLAGS)
245- (safeenv-set "LDFLAGS" (++ SHBuild_LDFLAGS " " (env-get "LDFLAGS")));
246- $env-de! SHBuild_LIBS "";
247- $unless (string-empty? SHBuild_LIBS)
248- (safeenv-set "LIBS" (++ SHBuild_LIBS " " (env-get "LIBS")));
243+ $defv! $prepend (svar var) d
244+ (
245+ eval (list $env-de! svar "") d;
246+ $def! sval eval svar d;
247+ $unless (string-empty? sval)
248+ (
249+ $let* ((varn symbol->string var) (val env-get (eval varn d)))
250+ (
251+ safeenv-set varn (++ sval " " val);
252+ ss-verbose-puts (++ "Prepended " (symbol->string svar) " '" sval
253+ "' to the original " varn " '" val "'.")
254+ )
255+ )
256+ );
257+ $prepend SHBuild_LDFLAGS LDFLAGS;
258+ $prepend SHBuild_LIBS LIBS
249259 );
250260
251261 $defl! SHBuild_ar_ok_ (ar)
@@ -318,6 +328,15 @@
318328 (cons-cmd C_CXXFLAGS_GC LDFLAGS_GC)) (list C_CXXFLAGS_GC LDFLAGS_GC)
319329 (list "" "")
320330 );
331+$defl! use-fsanitize? (name opt)
332+ rmatch? opt (++ ".*-fsanitize=[a-z,]*" name ".*");
333+$defl! use-san? (opt)
334+ use-fsanitize? "(address|thread|memory|undefined|leak)" opt;
335+$defl! use-asan? (opt) use-fsanitize? "address" opt;
336+$defl! use-tsan? (opt) use-fsanitize? "thread" opt;
337+$defl! use-msan? (opt) use-fsanitize? "memory" opt;
338+$defl! use-ubsan? (opt) use-fsanitize? "undefined" opt;
339+$defl! use-lsan? (opt) use-fsanitize? "leak" opt;
321340
322341 $defl! build-with-conf-opt (outdir host-os debug dynamic shbopt-ext app
323342 do-ld-ext do-build)
@@ -431,8 +450,9 @@
431450 (force prom_C_CXXFLAGS_PIC) (force prom_C_CXXFLAGS_COMMON)
432451 (force prom_CXXFLAGS_WARNING) (force prom_CXXFLAGS_IMPL_COMMON)
433452 (force prom_C_CXXFLAGS_COMMON_IMPL_) (force prom_CXXFLAGS_OPT_DBG);
434- $redef! CFLAGS SHBuild_TrimOptions_ CFLAGS,
435- $redef! CXXFLAGS SHBuild_TrimOptions_ CXXFLAGS;
453+ $def! SHBuild_CXXFLAGS safeenv-get "SHBuild_CXXFLAGS";
454+ $def! has-asan-opt $or? (use-asan? CFLAGS) (use-asan? CXXFLAGS)
455+ (use-asan? SHBuild_CXXFLAGS);
436456 SHB_SetupPlatformVars_ (() get-current-environment) host-os;
437457 $if use-ld
438458 (
@@ -477,14 +497,44 @@
477497 ($if app (cons-cmd ($if dynamic (force prom_LIBS_RPATH) "")
478498 (do-ld-ext host-os)) ($if dynamic
479499 (cons-cmd (force prom_LDFLAGS_DYN)) "-Wl,--dn")));
500+ $unless has-asan-opt ($redef! has-asan-opt use-asan? LDFLAGS);
501+ "XXX", "Assume %LD has same style to %CXX when sanitizers are used";
502+ $if ($and? (eqv? SHBuild_CXX_Style_ "Clang++")
503+ ($or? (use-san? CFLAGS) (use-san? CXXFLAGS)
504+ (use-san? SHBuild_CXXFLAGS)))
505+ (
506+ "NOTE", "This reverts '-Wl,--no-undefined' or '-Wl,-z,defs'.",
507+ " See https://sourceware.org/binutils/docs/ld/Options.html.",
508+ " This is required to use MSan,",
509+ " see https://clang.llvm.org/docs/MemorySanitizer.html.";
510+ $redef! LDFLAGS (++ LDFLAGS " -Wl,-z,undefs");
511+ ss-verbose-puts
512+ "NOTE: LDFLAGS has been adjusted for Clang++ with sanitizers."
513+ );
480514 safeenv-set "LDFLAGS" LDFLAGS
481515 );
516+ $if has-asan-opt
517+ (
518+ $def! fixed " -U_FORTIFY_SOURCE -fno-omit-frame-pointer -fno-common";
519+ $redef! CFLAGS (++ CFLAGS fixed),
520+ $redef! CXXFLAGS (++ CXXFLAGS fixed);
521+ ss-verbose-puts "NOTE: CFLAGS and CXXFLAGS have been adjusted for ASan."
522+ );
523+ $redef! CFLAGS SHBuild_TrimOptions_ CFLAGS,
524+ $redef! CXXFLAGS SHBuild_TrimOptions_ CXXFLAGS;
482525 $def! SHBOPT get-SHBOPT_ outdir shbopt-ext use-ld;
483526 $defl! echo-var (var) SHBuild_EchoVar var (value-of var);
484527 "XXX", "The values of following variables may be overriden in 'do-build'.";
485528 "TODO", "Print actual values being used in 'do-build' as possible.";
486529 echo-var "CXXFLAGS";
487- $if use-ld (echo-var "LDFLAGS");
530+ $if use-ld
531+ (
532+ () SHBuild_Extend_CallVariables;
533+ $redef! LDFLAGS (env-get "LDFLAGS");
534+ echo-var "LDFLAGS";
535+ $redef! LIBS (env-get "LIBS");
536+ echo-var "LIBS"
537+ );
488538 echo-var "SHBOPT";
489539 do-build CXX CXXFLAGS SHBOPT LIBPFX
490540 );
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-YSLib.sh
--- a/Tools/Scripts/SHBuild-YSLib.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-YSLib.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,6 +1,33 @@
11 #!/usr/bin/env bash
2-# (C) 2014-2017 FrankHB.
3-# Reserved script for YSLib building.
2+# (C) 2014-2021 FrankHB.
3+# Shared stage 1 script for YSLib building.
44
5-echo "This file is now reserved."
5+[[ "$INC_SHBuild_YSLib" == '' ]] && INC_SHBuild_YSLib=1 || return 0
66
7+: "${SHBuild_ToolDir:=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)}"
8+: "${YSLib_BaseDir:="$SHBuild_ToolDir/../.."}"
9+YSLib_BaseDir=$(cd "$YSLib_BaseDir"; pwd)
10+
11+: "${SHBuild_PCH_stdinc_h:=stdinc.h}"
12+
13+# shellcheck source=./SHBuild-common-options.sh
14+. "$SHBuild_ToolDir/SHBuild-common-options.sh"
15+
16+# XXX: %INCLUDE_PCH and %INCLUDES are internal.
17+# shellcheck disable=2034
18+INCLUDE_PCH="$YSLib_BaseDir/YBase/include/stdinc.h"
19+# shellcheck disable=2034
20+INCLUDES="-I$YSLib_BaseDir/YFramework/include \
21+-I$YSLib_BaseDir/YFramework/Android/include \
22+-I$YSLib_BaseDir/YFramework/DS/include \
23+-I$YSLib_BaseDir/YFramework/Win32/include \
24+-I$YSLib_BaseDir/3rdparty/include \
25+-I$YSLib_BaseDir/3rdparty/freetype/include \
26+-I$YSLib_BaseDir/YBase/include \
27+"
28+
29+SHBuild_S1_InitializePCH()
30+{
31+ SHBuild_CheckPCH "$INCLUDE_PCH" "$SHBuild_PCH_stdinc_h"
32+}
33+
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-bootstrap.sh
--- a/Tools/Scripts/SHBuild-bootstrap.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-bootstrap.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,18 +1,18 @@
11 #!/usr/bin/env bash
2-# (C) 2014-2020 FrankHB.
2+# (C) 2014-2021 FrankHB.
33 # Common source script: bootstrap configuration.
44
55 set -e
6+
67 : "${SHBuild_ToolDir:=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)}"
7-# shellcheck source=./SHBuild-common.sh
8-. "$SHBuild_ToolDir/SHBuild-common.sh" # for SHBuild_Puts, SHBuild_PrepareBuild,
9-# SHBuild_EchoVar_N.
8+# shellcheck source=./SHBuild-YSLib.sh
9+. "$SHBuild_ToolDir/SHBuild-YSLib.sh" # for SHBuild_Puts, SHBuild_EchoVar_N,
10+# YSLib_BaseDir, SHBuild_GetBuildName, CXX, CXXFLAGS, LDFLAGS, INCLUDES, LIBS,
11+# SHBuild_Host_OS;
12+
1013 SHBuild_Puts "Bootstrap beginned."
11-SHBuild_PrepareBuild
1214 : "${SHBuild_BaseDir:="$SHBuild_ToolDir/../SHBuild"}"
13-: "${YSLib_BaseDir:="$SHBuild_ToolDir/../.."}"
1415 SHBuild_BaseDir=$(cd "$SHBuild_BaseDir"; pwd)
15-YSLib_BaseDir=$(cd "$YSLib_BaseDir"; pwd)
1616
1717 SHBuild_EchoVar_N 'SHBuild.BaseDir'
1818 SHBuild_EchoVar_N 'SHBuild.ToolDir'
@@ -21,24 +21,6 @@
2121
2222 SHBuild_Puts "Configuring ..."
2323
24-# shellcheck source=./SHBuild-common-toolchain.sh
25-. "$SHBuild_ToolDir/SHBuild-common-toolchain.sh"
26-# shellcheck source=./SHBuild-common-options.sh
27-. "$SHBuild_ToolDir/SHBuild-common-options.sh"
28-
29-# XXX: %INCLUDE_PCH and %INCLUDES are internal.
30-# shellcheck disable=2034
31-INCLUDE_PCH="$YSLib_BaseDir/YBase/include/stdinc.h"
32-# shellcheck disable=2034
33-INCLUDES="-I$YSLib_BaseDir/YFramework/include \
34--I$YSLib_BaseDir/YFramework/Android/include \
35--I$YSLib_BaseDir/YFramework/DS/include \
36--I$YSLib_BaseDir/YFramework/Win32/include \
37--I$YSLib_BaseDir/3rdparty/include \
38--I$YSLib_BaseDir/3rdparty/freetype/include \
39--I$YSLib_BaseDir/YBase/include \
40-"
41-
4224 # Coordinated at build 882.
4325 LIBS="$YSLib_BaseDir/YBase/source/ystdex/base.cpp \
4426 $YSLib_BaseDir/YBase/source/ystdex/exception.cpp \
@@ -86,6 +68,8 @@
8668 export CXXFLAGS
8769 export LDFLAGS
8870
71+# XXX: %SHBuild_Host_Arch and %SHBuild_Host_OS shall be ready after the
72+# inclusion of %SHBuild-YSLib.sh.
8973 : "${SHBuild_BuildDir:="$SHBuild_ToolDir/../../build/$(SHBuild_GetBuildName)"}"
9074
9175 SHBuild_EchoVar_N 'SHBuild.BuildDir'
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-build.sh
--- a/Tools/Scripts/SHBuild-build.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-build.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,10 +1,10 @@
11 #!/usr/bin/env bash
2-# (C) 2014-2018, 2020 FrankHB.
2+# (C) 2014-2018, 2020-2021 FrankHB.
33 # Build script for SHBuild.
44
55 set -e
6+
67 : "${SHBuild_ToolDir:=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)}"
7-: "${SHBuild_BaseDir:="$SHBuild_ToolDir/../SHBuild"}"
88 # XXX: Some options for stage 1 SHBuild are fixed. Provide more separated
99 # options in future?
1010 # XXX: Following variables are internal.
@@ -27,10 +27,10 @@
2727 # shellcheck disable=2034
2828 LDFLAGS_IMPL_OPT=' '
2929 # shellcheck source=./SHBuild-bootstrap.sh
30-. "$SHBuild_ToolDir/SHBuild-bootstrap.sh"
30+. "$SHBuild_ToolDir/SHBuild-bootstrap.sh" # for SHBuild_Pushd, SHBuild_BaseDir,
31+# SHBuild_Puts, CXXFLAGS, LDFLAGS, INCLUDES, LIBS, SHBuild_Popd.
3132
3233 : "${SHBuild_Output:=SHBuild}"
33-: "${SHBuild_PCH_stdinc_h:=stdinc.h}"
3434
3535 SHBuild_Pushd .
3636 cd "$SHBuild_BaseDir"
@@ -40,8 +40,10 @@
4040 # Precompiled header is not used here because it does not work well with
4141 # external %CXXFLAGS_OPT_DBG. It is also not used frequently like in stage 2.
4242 # Even it is needed, it should be better separated with the stage 2 option.
43-# When needed, uncomment the following command.
44-# SHBuild_CheckPCH "$INCLUDE_PCH" "$SHBuild_PCH_stdinc_h"
43+# When needed, uncomment the following command (where
44+# %SHBuild_S1_InitializePCH is from %SHBuild_ToolDir/SHBuild-bootstrap.sh),
45+# to provide %SHBuild_IncPCH.
46+# SHBuild_S1_InitializePCH
4547
4648 # Note '-fwhole-program' should not be used because there
4749 # do exist multiple translation units when linking with YSLib source,
@@ -49,7 +51,7 @@
4951 # linkage which had been optimized away.
5052 # XXX: %SHBuild_Verbose_ is external.
5153 # shellcheck disable=2154
52-if [[ "$SHBuild_Verbose_" != "" ]]; then
54+if [[ "$SHBuild_Verbose_" != '' ]]; then
5355 # XXX: Value of several variables may contain whitespaces.
5456 # shellcheck disable=2086
5557 SHBuild_Puts "$CXX" Main.cpp -o"$SHBuild_Output" $CXXFLAGS $LDFLAGS \
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-self-host-DLL.sh
--- a/Tools/Scripts/SHBuild-self-host-DLL.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-self-host-DLL.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,10 +1,10 @@
11 #!/usr/bin/env bash
2-# (C) 2014-2016, 2020 FrankHB.
2+# (C) 2014-2016, 2020-2021 FrankHB.
33 # Test script for self-hosting SHBuild.
44
55 set -e
6+
67 : "${SHBuild_ToolDir:=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)}"
7-: "${SHBuild_BaseDir:="$SHBuild_ToolDir/../SHBuild"}"
88 # shellcheck source=./SHBuild-bootstrap.sh
99 . "$SHBuild_ToolDir/SHBuild-bootstrap.sh"
1010
diff -r a285f6f132e8 -r d1f3d524f742 Tools/Scripts/SHBuild-self-host.sh
--- a/Tools/Scripts/SHBuild-self-host.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/Scripts/SHBuild-self-host.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,10 +1,10 @@
11 #!/usr/bin/env bash
2-# (C) 2014-2016, 2020 FrankHB.
2+# (C) 2014-2016, 2020-2021 FrankHB.
33 # Test script for self-hosting SHBuild.
44
55 set -e
6+
67 : "${SHBuild_ToolDir:=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)}"
7-: "${SHBuild_BaseDir:="$SHBuild_ToolDir/../SHBuild"}"
88 # shellcheck source=./SHBuild-bootstrap.sh
99 . "$SHBuild_ToolDir/SHBuild-bootstrap.sh"
1010
diff -r a285f6f132e8 -r d1f3d524f742 Tools/install-sysroot.sh
--- a/Tools/install-sysroot.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/Tools/install-sysroot.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,13 +1,14 @@
11 #!/usr/bin/env bash
2-# (C) 2014-2018, 2020 FrankHB.
2+# (C) 2014-2018, 2020-2021 FrankHB.
33 # SHBuild installation script.
44
55 set -e
6+
67 : "${SHBuild_ToolDir:=$(cd "$(dirname "${BASH_SOURCE[0]}")/Scripts"; pwd)}"
78 # XXX: Use 'shell -x -P SCRIPTDIR'.
89 # shellcheck source=./Scripts/SHBuild-common.sh
9-. "$SHBuild_ToolDir/SHBuild-common.sh" # for SHBuild_Puts,
10-# SHBuild_PrepareBuild, SHBuild_GetBuildName;
10+. "$SHBuild_ToolDir/SHBuild-common.sh" # for SHBuild_Puts, SHBuild_PrepareBuild,
11+# SHBuild_GetBuildName;
1112
1213 # NOTE: Some variables are configurable. If not set or set to empty, the
1314 # variables can be later set by the scripts being called. Variable specific to
@@ -30,15 +31,14 @@
3031 : "${SHBuild_SysRoot:="$YSLib_BaseDir/sysroot"}"
3132 YSLib_BaseDir=$(cd "$YSLib_BaseDir"; pwd)
3233 export YSLib_BaseDir
34+# NOTE: This is necessary before the call to %SHBuild_GetBuildName.
3335 SHBuild_PrepareBuild
3436 # NOTE: The default value is same to %SHBuild_BuildDir in
35-# %SHBuild-YSLib-bootstrap.sh. The directory will be created if not existed by
37+# %SHBuild-bootstrap.sh. The directory will be created if not existed by
3638 # the following stage 1 process or by %SHBuild-YSLib-build.txt.
3739 : "${SHBuild_BuildDir:="$YSLib_BaseDir/build/$(SHBuild_GetBuildName)"}"
3840 export SHBuild_BuildDir
3941 SHBuild_Puts "Build directory is \"$SHBuild_BuildDir\"."
40-# shellcheck source=./Scripts/SHBuild-common-toolchain.sh
41-. "$SHBuild_ToolDir/SHBuild-common-toolchain.sh"
4242 if [[ -z ${SHBuild_UseRelease+x} ]]; then
4343 SHBuild_UseRelease=true
4444 fi
diff -r a285f6f132e8 -r d1f3d524f742 YFramework/include/NPL/NPLA1Forms.h
--- a/YFramework/include/NPL/NPLA1Forms.h Thu Dec 24 12:58:49 2020 +0800
+++ b/YFramework/include/NPL/NPLA1Forms.h Sat Jan 09 04:33:56 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2016-2020 FrankHB.
2+ © 2016-2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1.h
1212 \ingroup NPL
1313 \brief NPLA1 语法形式。
14-\version r7731
14+\version r7741
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2020-02-15 11:19:21 +0800
1919 \par 修改时间:
20- 2020-11-22 01:29 +0800
20+ 2021-01-08 19:22 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -898,14 +898,16 @@
898898 //! \pre 间接断言:第一参数指定的项是枝节点。
899899 //@{
900900 /*!
901-\brief 创建以参数指定的环境列表作为父环境的新环境。
901+\brief 创建空环境。
902902 \exception NPLException 异常中立:由 Environment 的构造函数抛出。
903903 \sa Environment::CheckParent
904904 \sa EnvironmentList
905905 \since build 798
906906 \todo 使用专用的异常类型。
907907
908-取以指定的参数初始化新创建的父环境。
908+取以参数指定父环境的空环境。
909+可选地通过参数指定的一个或多个环境作为父环境。
910+当且仅当参数指定超过一个环境时,使用环境列表。
909911
910912 参考调用文法:
911913 <pre>make-environment \<environment>...</pre>
@@ -973,7 +975,7 @@
973975 剩余表达式视为求值结果,直接绑定到 \c \<definiend> 。
974976
975977 参考调用文法:
976-<pre>$deflazy! \<definiend> \<expressions></pre>
978+<pre>$deflazy! \<definiend> \<body></pre>
977979 */
978980 YF_API ReductionStatus
979981 DefineLazy(TermNode&, ContextNode&);
@@ -984,7 +986,7 @@
984986 剩余表达式视为一个表达式在上下文决定的当前环境进行求值后绑定到 \c \<definiend> 。
985987
986988 参考调用文法:
987-<pre>$def! \<definiend> \<expressions></pre>
989+<pre>$def! \<definiend> \<body></pre>
988990 */
989991 YF_API ReductionStatus
990992 DefineWithNoRecursion(TermNode&, ContextNode&);
@@ -1000,7 +1002,7 @@
10001002 循环引用以此引入的名称可能抛出 InvalidReference 异常。
10011003
10021004 参考调用文法:
1003-<pre>$defrec! \<definiend> \<expressions></pre>
1005+<pre>$defrec! \<definiend> \<body></pre>
10041006 */
10051007 YF_API ReductionStatus
10061008 DefineWithRecursion(TermNode&, ContextNode&);
@@ -1014,7 +1016,7 @@
10141016 同 DefineWithNoRecursion ,但由规约第一参数子项的结果显式地确定被修改的环境。
10151017
10161018 参考调用文法:
1017-<pre>$set! \<environment> \<formals> \<expressions></pre>
1019+<pre>$set! \<environment> \<formals> \<body></pre>
10181020 */
10191021 YF_API ReductionStatus
10201022 SetWithNoRecursion(TermNode&, ContextNode&);
@@ -1025,7 +1027,7 @@
10251027 同 DefineWithRecursion ,但由规约第一参数子项的结果显式地确定被修改的环境。
10261028
10271029 参考调用文法:
1028-<pre>$setrec! \<environment> \<formals> \<expressions></pre>
1030+<pre>$setrec! \<environment> \<formals> \<body></pre>
10291031 */
10301032 YF_API ReductionStatus
10311033 SetWithRecursion(TermNode&, ContextNode&);
diff -r a285f6f132e8 -r d1f3d524f742 YFramework/source/NPL/Dependency.cpp
--- a/YFramework/source/NPL/Dependency.cpp Thu Dec 24 12:58:49 2020 +0800
+++ b/YFramework/source/NPL/Dependency.cpp Sat Jan 09 04:33:56 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2015-2020 FrankHB.
2+ © 2015-2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file Dependency.cpp
1212 \ingroup NPL
1313 \brief 依赖管理。
14-\version r3888
14+\version r3938
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 623
1717 \par 创建时间:
1818 2015-08-09 22:14:45 +0800
1919 \par 修改时间:
20- 2020-11-30 21:07 +0800
20+ 2021-01-09 04:02 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -35,8 +35,8 @@
3535 // LiftOtherOrCopy, NPL::IsMovable, LiftTermOrCopy, ResolveTerm,
3636 // LiftTermValueOrCopy, MoveResolved, ResolveIdentifier, ystdex::plus,
3737 // std::placeholders, NPL::ResolveRegular, ystdex::tolower,
38-// ystdex::swap_dependent, LiftTermRef, LiftTerm, NPL::Deref,
39-// YSLib::IO::StreamPut, YSLib::IO::omode_convb, YSLib::uremove,
38+// FetchEnvironmentVariable, ystdex::swap_dependent, LiftTermRef, LiftTerm,
39+// NPL::Deref, YSLib::IO::StreamPut, YSLib::IO::omode_convb, YSLib::uremove,
4040 // ystdex::throw_error;
4141 #include YFM_NPL_NPLA1Forms // for NPL::Forms functions;
4242 #include YFM_YSLib_Service_FileSystem // for YSLib::IO::Path;
@@ -282,10 +282,10 @@
282282 DoMoveOrTransfer(void(&f)(TermNode&, TermNode&, bool), TermNode& term)
283283 {
284284 return Forms::CallResolvedUnary(
285- [&](TermNode& tm, ResolvedTermReferencePtr p_ref){
285+ [&](TermNode& nd, ResolvedTermReferencePtr p_ref){
286286 // NOTE: Force move. No %IsMovable check is needed.
287287 // XXX: Term tags are currently not respected in prvalues.
288- f(term, tm, !p_ref || p_ref->IsModifiable());
288+ f(term, nd, !p_ref || p_ref->IsModifiable());
289289 // NOTE: Term tags are not copied.
290290 return ReductionStatus::Retained;
291291 }, term);
@@ -622,7 +622,7 @@
622622 RegisterStrict(renv, "list", ReduceBranchToListValue);
623623 RegisterStrict(renv, "list%", ReduceBranchToList);
624624 // NOTE: Lazy form '$deflazy!' is the basic operation, which may bind
625- // parameter as unevaluated operands.
625+ // parameter as unevaluated operands.
626626 RegisterForm(renv, "$deflazy!", DefineLazy);
627627 RegisterForm(renv, "$set!", SetWithNoRecursion);
628628 RegisterForm(renv, "$setrec!", SetWithRecursion);
@@ -920,18 +920,17 @@
920920 $defl%! assv (&x &alist) $cond ((null? alist) ())
921921 ((eqv? x (first& (first& alist))) first alist)
922922 (#t assv (forward! x) (rest% alist));
923+ $defw! derive-current-environment (.&envs) d
924+ apply make-environment (append envs (list d)) d;
925+ $defv! $as-environment (.&body) d
926+ eval (list $let () (list $sequence (move! body)
927+ (list () lock-current-environment))) d;
923928 $defv%! $let (&bindings .&body) d
924929 eval% (list*% () (list*% $lambda (map1 firstv bindings)
925930 (list (move! body))) (map1 list-rest% bindings)) d;
926931 $defv%! $let% (&bindings .&body) d
927932 eval% (list*% () (list*% $lambda% (map1 firstv bindings)
928933 (list (move! body))) (map1 list-rest% bindings)) d;
929- $defv%! $let/d (&bindings &ef .&body) d
930- eval% (list*% () (list% wrap (list*% $vau (map1 firstv bindings)
931- ef (list (move! body)))) (map1 list-rest% bindings)) d;
932- $defv%! $let/d% (&bindings &ef .&body) d
933- eval% (list*% () (list% wrap (list*% $vau% (map1 firstv bindings)
934- ef (list (move! body)))) (map1 list-rest% bindings)) d;
935934 $defv%! $let/e (&e &bindings .&body) d
936935 eval% (list*% () (list*% $lambda/e e (map1 firstv bindings)
937936 (list (move! body))) (map1 list-rest% bindings)) d;
@@ -939,11 +938,11 @@
939938 eval% (list*% () (list*% $lambda/e% e (map1 firstv bindings)
940939 (list (move! body))) (map1 list-rest% bindings)) d;
941940 $defv%! $let* (&bindings .&body) d
942- eval% ($if (null? bindings) (list*% $let bindings (move! body))
941+ eval% ($if (null? bindings) (list*% $let () (move! body))
943942 (list% $let (list% (firstv bindings))
944943 (list*% $let* (rest% bindings) (move! body)))) d;
945944 $defv%! $let*% (&bindings .&body) d
946- eval% ($if (null? bindings) (list*% $let* bindings (move! body))
945+ eval% ($if (null? bindings) (list*% $let* () (move! body))
947946 (list% $let% (list (first bindings))
948947 (list*% $let*% (rest% bindings) (move! body)))) d;
949948 $defv%! $letrec (&bindings .&body) d
@@ -959,18 +958,14 @@
959958 (list*% () list (map1 rest% bindings))) d)
960959 res;
961960 $defv! $bindings->environment (.&bindings) d
962- eval (list*% $bindings/p->environment
963- (list (() make-standard-environment)) bindings) d;
964- $defv! $provide! (&symbols .&body) d
965- $sequence (eval% (list% $def! symbols (list $let () $sequence
961+ eval (list*% $bindings/p->environment () bindings) d;
962+ $defv! $provide/let! (&symbols &bindings .&body) d
963+ $sequence (eval% (list% $def! symbols (list $let bindings $sequence
966964 (list% ($vau% (&e) d $set! e res (lock-environment d))
967965 (() get-current-environment)) (move! body)
968966 (list* () list symbols))) d) res;
969- $defv! $provide/d! (&symbols &ef .&body) d
970- $sequence (eval% (list% $def! symbols (list $let/d () ef $sequence
971- (list% ($vau% (&e) d $set! e res (lock-environment d))
972- (() get-current-environment)) (move! body)
973- (list* () list symbols))) d) res;
967+ $defv! $provide! (&symbols .&body) d
968+ eval (list*% $provide/let! (forward! symbols) () (move! body)) d;
974969 $defv! $import! (&e .&symbols) d
975970 eval% (list $set! d symbols (list* () list symbols)) (eval e d);
976971 $defl! nonfoldable? (&l)
@@ -1059,15 +1054,10 @@
10591054 // NOTE: Call of 'set-first%!' does not check cyclic references. This is
10601055 // kept safe since it can occur only with NPLA1 undefined behavior.
10611056 context.Perform(R"NPL(
1062- $def! __ $provide! (promise? memoize $lazy $lazy/e force)
1063- (
1064- $def! (encapsulate promise? decapsulate) () make-encapsulation-type,
1065- $defl%! memoize (&x) encapsulate (list (list% (forward! x) ())),
1066- $defv%! $lazy (.&expr) d encapsulate (list (list expr d)),
1067- $defv%! $lazy/e (&e .&expr) d
1068- encapsulate (list (list expr (check-environment (eval e d)))),
1069- $defl%! force (&x)
1070- $if (promise? x) (force-promise (decapsulate x)) (forward! x),
1057+ $provide/let! (promise? memoize $lazy $lazy/e force)
1058+ ((mods $as-environment (
1059+ $def! (encapsulate% promise? decapsulate)
1060+ () make-encapsulation-type;
10711061 $defl%! force-promise (&x) $let ((((&o &env)) x))
10721062 $if (null? env) (forward! o)
10731063 (
@@ -1081,6 +1071,18 @@
10811071 list% (assign! o y) (assign@! e ()))
10821072 (forward! y))
10831073 )
1074+ )))
1075+ (
1076+ $import! mods promise?;
1077+ $defl/e%! memoize mods (&x)
1078+ encapsulate% (list (list% (forward! x) ())),
1079+ $defv/e%! $lazy mods (.&body) d
1080+ encapsulate% (list (list (move! body) d)),
1081+ $defv/e%! $lazy/e mods (&e .&body) d
1082+ encapsulate%
1083+ (list (list (move! body) (check-environment (eval e d)))),
1084+ $defl/e%! force mods (&x)
1085+ $if (promise? x) (force-promise (decapsulate x)) (forward! x)
10841086 );
10851087 )NPL");
10861088 }
@@ -1439,7 +1441,8 @@
14391441
14401442 str = pfx + std::move(str) + sfx;
14411443 // TODO: Check file access with read-write permissions using
1442- // %YSLib::uopen. This requires the exposure of the open flags.
1444+ // %YSLib::uopen. This requires the exposure of the open flags in
1445+ // YSLib since NPL does not use %YCLib::NativeAPI.
14431446 // XXX: This is like %YSLib::ufexists, but UTF-8 support is not
14441447 // needed.
14451448 if(ystdex::fexists(str.c_str(), true))
diff -r a285f6f132e8 -r d1f3d524f742 YFramework/source/NPL/NPLA1Forms.cpp
--- a/YFramework/source/NPL/NPLA1Forms.cpp Thu Dec 24 12:58:49 2020 +0800
+++ b/YFramework/source/NPL/NPLA1Forms.cpp Sat Jan 09 04:33:56 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2016-2020 FrankHB.
2+ © 2016-2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file NPLA1Forms.cpp
1212 \ingroup NPL
1313 \brief NPLA1 语法形式。
14-\version r19632
14+\version r19640
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 882
1717 \par 创建时间:
1818 2014-02-15 11:19:51 +0800
1919 \par 修改时间:
20- 2020-11-22 12:51 +0800
20+ 2021-01-08 19:20 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -391,7 +391,7 @@
391391 DoDefineSet(TermNode& term, size_t n, _func f) -> decltype(f())
392392 {
393393 Retain(term);
394- if(term.size() > n)
394+ if(term.size() >= n)
395395 return f();
396396 ThrowInsufficientTermsErrorFor(term,
397397 InvalidSyntax("Invalid syntax found in definition."));
@@ -603,7 +603,7 @@
603603 // XXX: See %RelayForEvalOrDirect.
604604 #if NPL_Impl_NPLA1_Enable_Thunked
605605 // TODO: Blocked. Use C++14 lambda initializers to simplify the
606- // implementation.
606+ // implementation.
607607 return A1::RelayCurrentNext(term, ctx, yforward(next), MakeMoveGuard(gd));
608608 #else
609609 yunused(gd);
@@ -1484,7 +1484,7 @@
14841484 YB_NORETURN ReductionStatus
14851485 ThrowForWrappingFailure(const ystdex::type_info& tp)
14861486 {
1487- throw TypeError(ystdex::sfmt("Wrapping failed with type '%s'.", tp.name()));
1487+ throw TypeError(ystdex::sfmt("Wrapping failed with type '%s'.", tp.name()));
14881488 }
14891489
14901490 ReductionStatus
@@ -1644,7 +1644,7 @@
16441644 if(r)
16451645 EqualSubterm(r, act, first1, first2, last1);
16461646 };
1647- ystdex::update_thunk(act, [&, first1, first2, last1]{
1647+ ystdex::update_thunk(act, [&]{
16481648 if(r)
16491649 EqualSubterm(r, act, x.begin(), y.begin(), x.end());
16501650 });
@@ -1742,7 +1742,7 @@
17421742 }
17431743 return ReductionStatus::Retained;
17441744 }, [&]{
1745- LiftTerm(term, tm);
1745+ LiftTerm(term, tm);
17461746 return ReductionStatus::Retained;
17471747 });
17481748 }
@@ -1941,7 +1941,7 @@
19411941 while(++j != nd.end())
19421942 {
19431943 auto& tm(*j);
1944-
1944+
19451945 if(IsReferenceTerm(tm))
19461946 ncon.emplace_back(tm);
19471947 else
@@ -2023,7 +2023,7 @@
20232023 std::move(nterm)}, a)}, a))));
20242024
20252025 RelaySwitched(ctx, A1::NameTypedReducerHandler([&, d]() YB_FLATTEN{
2026- return ReduceCallSubsequent(*term.begin(), ctx, d,
2026+ return ReduceCallSubsequent(*term.begin(), ctx, d,
20272027 A1::NameTypedReducerHandler([&]() YB_FLATTEN{
20282028 auto i_term(term.begin());
20292029
@@ -2052,7 +2052,7 @@
20522052 rterm.GetContainerRef().emplace_back();
20532053 RelaySwitched(ctx, A1::NameTypedReducerHandler([&]{
20542054 LiftOther(term, rterm);
2055- return ctx.LastStatus;
2055+ return ctx.LastStatus;
20562056 }, "eval-lift-sum"));
20572057 }
20582058
@@ -2151,6 +2151,7 @@
21512151 }, static_cast<const TermNode&(&)(const TermNode&)>(ReferenceTerm));
21522152 }
21532153
2154+
21542155 ReductionStatus
21552156 If(TermNode& term, ContextNode& ctx)
21562157 {
diff -r a285f6f132e8 -r d1f3d524f742 doc/ChangeLog.V0.9.txt
--- a/doc/ChangeLog.V0.9.txt Thu Dec 24 12:58:49 2020 +0800
+++ b/doc/ChangeLog.V0.9.txt Sat Jan 09 04:33:56 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2020 FrankHB.
2+ © 2020-2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file ChangeLog.V0.9.txt
1212 \ingroup Documentation
1313 \brief 版本更新历史记录 - V0.9 。
14-\version r1787
14+\version r1983
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 800
1717 \par 创建时间:
1818 2020-10-12 17:19:23 +0800
1919 \par 修改时间:
20- 2020-12-24 12:09 +0800
20+ 2021-01-09 04:08 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -31,6 +31,199 @@
3131 // Scope: [b900, $now];
3232
3333 $now
34+ / %Tools $=
35+ (
36+ / %Scripts $=
37+ (
38+ / @ "%SHBuild-YSLib.sh" $=
39+ (
40+ - "'echo' command to print reserved information";
41+ + "%(INCLUDES, INCLUDE)",
42+ + "%YSLib_BaseDir initialization",
43+ (
44+ + "overridable variable %SHBuild_PCH_stdinc_h";
45+ + "function %SHBuild_S1_InitializePCH"
46+ )
47+ ),
48+ / DLDI "simplified quotes" @ "%SHBuild_Verbose_ check"
49+ @ "%SHBuild-build.sh",
50+ - DLDI "%SHBuild_BaseDir" @ "%(SHBuild-build.sh, SHBuild-self-host.sh, \
51+ SHBuild-self-host-DLL.sh)",
52+ // This is set in %SHBuild-bootstrap.sh.
53+ / DLDI @ "%SHBuild-bootstrap.sh" $=
54+ (
55+ - "'.' command for %SHBuild-common-toolchain.sh"
56+ @ "%SHBuild-bootstrap.sh",
57+ / "reordered and simplified source inclusion commands"
58+ ),
59+ / @ "%SHBuild-YSLib-common.txt" $=
60+ (
61+ (
62+ + "applicative 'use-fsanitize?'";
63+ (
64+ + "applicative 'use-asan?'";
65+ // This only support options like '-fsanitize=address' but \
66+ not '-faddress-sanitize'. The latter is nonsense to \
67+ G++ and current Clang++. See also See $2020-12 \
68+ @ %Documentation::Workflow.
69+ + ' -U_FORTIFY_SOURCE -fno-omit-frame-pointer -fno-common'
70+ @ "build flags %(CFLAGS, CXXFLAGS) for detected sanitizer \
71+ builds",
72+ )
73+ (
74+ + "applicative 'use-san?';
75+ + "postfix %LDFLAGS with '-Wl,-z,undefs' for Clang++ when \
76+ santizers are used"
77+ ),
78+ + "applicatives ('use-san?', 'use-tsan?', 'use-msan?',
79+ 'use-ubsan?', 'use-lsan?')"
80+ ),
81+ + "output for needed setting on %SS_Verbose"
82+ @ "applivative %SHBuild_Extend_CallVariables",
83+ / @ "applicative 'build-with-conf-opt'"
84+ (
85+ + "%SHBuild_Extend_CallVariables call" @ "final settings"
86+ $dep_to "SHBuild library variables extension",
87+ + "%LIBS echo when %LD is used after %LDFLLAGS echo"
88+ ),
89+ / DLDI "simplified static environment" @ "applicatives \
90+ ('safeenv-get', 'safeenv-set', 'ss-verbose-puts')",
91+ / DLDI "poisoned unsafe functions and safe environment \
92+ functions" ^ ('$provide!', 'make-environment')
93+ ~ '$provide/d!' $dep_to "removal of calls to '$provide/d!'"
94+ ),
95+ (
96+ / $forced "callbacks for 'build-with-conf-opt'"
97+ $dep_from "SHBuild library variables extension"
98+ $effective @ "%(SHBuild-YSLib-build.txt, SHBuild-BuildApp.txt")
99+ $= (- "redundant %SHBuild_Extend_CallVariables call");
100+ * $comp "accumulated %(LDFLAGS, LIBS) more than once"
101+ @ "development tool builds" @ "%SHBuild-YSLib-build.txt"
102+ $since b906
103+ ),
104+ / @ "%SHBuild-YSLib-build.txt" $=
105+ (
106+ * "wrong pattern for sanitizer detection" $since b906
107+ $= (/ $impl ^ $dep_from ('use-ubsan?'
108+ @ "%SHBuild-YSLib-common.txt")),
109+ // The address sanitizer pattern was already wrong. \
110+ And actually the undefined behavior santizer is \
111+ offending.
112+ * "%LDFLAGS pollution caused by %SHBuild_LDFLAGS extension \
113+ when %LDFLAGS is unused" @ "library build" $since b906
114+ // This is needed fixing even if the call of \
115+ %SHBuild_Extend_CallVariables is removed, for base \
116+ %LDFLAGS used by %Win32 at least.
117+ ),
118+ / @ "%SHBuild-BuildApp.txt" $=
119+ (
120+ * "wrongly adjustedd linker option with '-mwindows' for %debug \
121+ builds" $since b900
122+ - $re_add(b838) DLDI "variable %SHBuild_YSLib_Platform",
123+ * "platform-specific flags fix" $since b900
124+ // The platform detection now uses %MSYSTEM when \
125+ specified, which is consistent to \
126+ %SHBuild-YSLib-build.txt.
127+ )
128+ ),
129+ - DLI "redundant inclusion of %Tools/SHBuild-common-toolchain.sh"
130+ @ "%install-sysroot.sh"
131+ // See $2020-12 @ %Documentation::Workflow.
132+ ),
133+ / "stage 1 build scripts" $=
134+ (
135+ / "simplified scripts with %YSLib_BaseDir initialization and \
136+ %SHBuild-common-options.sh inclusion" ^ $dep_from ("%(INCLUDE_PCH, \
137+ INCLUDES, YSLib_BaseDir)" @ "%SHBuild-YSLib.sh" @ %Tools.Scripts)
138+ $effective @ ("%SHBuild-bootstrap.sh" @ %Tools.Scripts,
139+ "%test.sh" @ %Test),
140+ (
141+ / "simplified scripts with stage 1 PCH options avaiable"
142+ ^ $dep_from ("%SHBuild_S1_InitializePCH"
143+ @ "%SHBuild-YSLib.sh" @ %Tools.Scripts) $effective
144+ @ ("%SHBuild-YSLib.sh" @ %Tools.Scripts, "%test.sh" @ %Test)
145+ ~ "%SHBuild_CheckPCH";
146+ + $comp "overridable %SHBuild_PCH_stdinc_h" @ "%test.sh" @ %Test
147+ ),
148+ - DLI "duplicate initialization of build environment variables"
149+ $effective @ ("%test.sh" @ %Test, "%SHBuild-bootstrap.sh"
150+ @ %Tools.Scripts)
151+ // See $2020-12 @ %Documentation::Workflow.
152+ ),
153+ / $dev "unchecked shell scripts" $effective
154+ @ ("%3rdparty/freetype/builds/build-ds.sh",
155+ "%doxygen-cjk.sh" @ %Documentation) $=
156+ (
157+ // See $2020-12 @ %Documentation::Workflow.
158+ + "normalized shebang with 'env'",
159+ + "copyright notice",
160+ + "description",
161+ / "optimized to eliminate ShellCheck issues"
162+ ),
163+ / "%doxygen-cjk.sh" @ %Documentation $=
164+ (
165+ / "supported working directory other than 'doc'",
166+ / DLDI ^ "%SHBuild_Pushd, SHBuild_Popd",
167+ * "wrong 'sed' command argument" $since b380
168+ ),
169+ * $comp "missing console window" @ "default %debug configurations"
170+ @ "platform %Win32" @ %YSTest $since b903
171+ $dep_from ("%SHBuild-BuildApp.txt" @ %Tools.Scripts),
172+ / %YFramework.NPL $=
173+ (
174+ / %NPLA1Forms $=
175+ (
176+ / DLDI "simplified" @ "%operator==" @ "encapsulation constructed \
177+ from function %MakeEncapsulationType",
178+ // To eliminate Clang++ warning: [-Wunused-lambda-capture].
179+ / "allowed empty body" @ "functions %(DefineLazy, \
180+ DefineWithNoRecursion, DefineWithRecursion, \
181+ SetWithNoRecursion, SetWithNoRecursion)"
182+ ),
183+ / %Dependency $=
184+ (
185+ / @ "function %LoadGroundContext" $=
186+ (
187+ / DLDI "simplified operatives ('$let*', '$let*%')"
188+ - "operative '$let/d%'",
189+ // See $2020-01 @ %Documentation::Workflow.
190+ (
191+ / "operative '$provide/d!'" -> '$provide/let!'
192+ $dep_from "removal of calls to '$provide/let!'";
193+ - "operative '$let/d'",
194+ // Ditto.
195+ / DLDI "simplified operative '$provide!'" ^ '$provide/d!'
196+ ),
197+ * "wrong parent environment constructed"
198+ @ "operative '$bindings->environment'" $since b839,
199+ // See $2020-01 @ %Documentation::Workflow.
200+ $= (/ $impl !^ 'make-standard-environment'),
201+ + "applicative 'derive-current-environment'",
202+ + "operative '$as-environment'"
203+ ),
204+ / DLI @ "function %LoadModule_std_promises" $=
205+ (
206+ / $design "enforced sigil at the end of name of internal \
207+ encapsulation applicative",
208+ // To be consistent to 'box%'.
209+ / $design "parameter name 'expr'"
210+ @ "operatives ('$lazy', '$lazy/e')" -> 'body',
211+ // To be consistent to %NPL.Documentation changes.
212+ / "optimized expression parameter"
213+ @ "operatives ('$lazy', '$lazy/e')"
214+ @ "function %LoadModule_std_promises" ^ 'move!',
215+ / "providing symbols"
216+ ^ $dep_from (('$provide/let!', '$as-environment')
217+ @ "%LoadGroundContext") ~ ('$provide!', '__')
218+ )
219+ )
220+ ),
221+ * DD "wrong parameter types" @ ("applicative %memoize",
222+ "operatives ('$lazy', '$lazy/e') %memoize") @ "promises module"
223+ @ %Documentation.NPL $since b856
224+),
225+
226+b906
34227 (
35228 / %YFramework $=
36229 (
@@ -115,7 +308,7 @@
115308 + "warning to indicate additional flags fix is used",
116309 + "detection of address sanitizer and the workaround for \
117310 building performance with dynamic YFramework build by \
118- G++"@ "platform %Linux"
311+ G++" @ "platform %Linux"
119312 )
120313 ),
121314 * "missing check slashes in the 1st argument before call to \
@@ -1781,8 +1974,8 @@
17811974 ^ ("%GenerateProjects.sh" @ %Tools.Scripts),
17821975 / $doc "%Doxyfile" $=
17831976 (
1784- / $deploy "updated version";
1785- / DLDI "saved with some new default configurations"
1977+ / $deploy "updated %PROJECT_NUMBER";
1978+ ^ $re_ex(b627) "Doxygen 1.8.18" ~ "Doxygen 1.8.10"
17861979 )
17871980 );
17881981
diff -r a285f6f132e8 -r d1f3d524f742 doc/NPL.txt
--- a/doc/NPL.txt Thu Dec 24 12:58:49 2020 +0800
+++ b/doc/NPL.txt Sat Jan 09 04:33:56 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2012-2020 FrankHB.
2+ © 2012-2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file NPL.txt
1212 \ingroup Documentation
1313 \brief NPL 规范和实现规格说明。
14-\version r17543
14+\version r17674
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 304
1717 \par 创建时间:
1818 2012-04-25 10:34:20 +0800
1919 \par 修改时间:
20- 2020-12-23 21:12 +0800
20+ 2021-01-08 21:21 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -477,6 +477,7 @@
477477 解释(interpretation) :通过直接执行(@2.1.1.1) 表现行为的具体语言实现的形式。
478478 源语言(source language) :翻译的输入的语言。
479479 目标语言(destination language) :翻译的输入的语言。
480+源程序(source program) :形式为作为翻译的输入的(以源语言编码的)程序。
480481 计算复杂度(computational complexity) :某个形式化计算模型中以有限的正整数作为模型决定的规模(metric) 作为参数的渐进(asymptotic) 性质确定的度量,一般包括描述步骤规模的时间(time) 和描述存储规模的空间(space) 复杂度。
481482 复杂度(complexity) :以程序的规模作为参数的关于程序的直接执行的计算复杂度,一般包括描述步骤规模的时间(time) 和描述存储规模的空间(space) 复杂度。
482483 元语言(metalanguage) :描述其它语言的语言。
@@ -577,6 +578,7 @@
577578 字符(character) :组成语言代码的最小实体。
578579 基本翻译单元(basic transation unit) :任意连续字符的有限序列(可以是空序列)。
579580 翻译单元(translation unit) :基本翻译单元的集合,之间满足由派生实现定义的规则。
581+程序(@2.3.2) 以翻译单元或具体操作指定的以翻译单元进行翻译(@2.3.2) 得到的其它变换形式表示。
580582
581583 @3.2 字符集和字符串:
582584 字符集(character set) :对一个实现而言不变的字符的有限集合。
@@ -1298,7 +1300,7 @@
12981300 C ::= [] | Ce | vC
12991301 其中 e 是被求值表达式,v 是作为范式(@4.4.3) 的值。
13001302 通过附加适当的求值规则保证对象语言中的表达式总是可唯一地被分解为这种表示,抽象的求值上下文可直接实现对象语言的求值。但语义描述和实现的基准都以抽象机(@2.6) 替代,因为:
1301-抽象机语义允许不依赖源程序的表示和构造(如特定的表达式的文法);
1303+抽象机语义允许不依赖源程序(@2.3.2) 的表示和构造(如特定的表达式的文法);
13021304 这种分解一般要求遍历对象语言的源程序而难以具有较好的可实现性质,如复杂度(@2.3.2) ;
13031305 为满足良好的可实现性质,需描述实现中可能具有的离散状态与只和其中个别状态关联的局部的求值规则时,这种分解通常会渐进演化为某种抽象机的表示。
13041306
@@ -3258,7 +3260,7 @@
32583260 A1::TransformNode 变换 NPLA1 节点 S 表达式抽象语法树为 NPLA1 语义结构。
32593261 通过 ValueNode 变换实现解释,参数指定映射例程,结果为变换的序列语义结构。
32603262 复合表达式中的经过节点到字符串的映射例程被解释为序列语义结构的名称,余下的项一一映射为子节点。
3261-A1::LoadNode 加载 NPLA1 翻译单元(另见 @5.3.2.3 )。
3263+A1::LoadNode 加载(load) NPLA1 翻译单元(另见 @5.3.2.3 )。
32623264
32633265 @7.5.2 中缀变换:
32643266 NPLA1 提供符合特定谓词指定的过滤条件的中缀分隔项替换为特定名称表达式(@4.5.1) 指定的前缀操作形式的列表。
@@ -4092,7 +4094,7 @@
40924094
40934095 @8.4.4.2 环境创建和访问操作:
40944096 Forms 提供以下函数实现对象语言中的环境创建和访问:
4095-Forms::MakeEnvironment 创建以参数指定的环境列表(@5.4.3) 作为父环境的新环境。
4097+Forms::MakeEnvironment 创建空环境(@4.6.1.1) 。
40964098 Forms::GetCurrentEnvironment 取当前环境(@5.4.4) 的引用。取得的宿主值类型为 NPL::EnvironmentReference 。
40974099 Forms::LockCurrentEnvironment 锁定当前环境的引用。取得的宿主值类型为 shared_ptr<Environment> 。
40984100 Forms::ValueOf
@@ -4119,7 +4121,7 @@
41194121
41204122 @8.4.5.1 捕获:
41214123 环境中的变量被隐含地捕获。
4122-捕获通过调用时设置在初始化保存的父环境(@5.4.3) 指针实现。
4124+捕获通过调用时设置在初始化保存的父环境指针实现。
41234125 因为实际指称的确定发生应用中对表达式副本的求值时的名称查找(@4.3.3) ,所以这是延迟到应用的按名称捕获(capture by name) 。这也在引入抽象时实现递归指称。
41244126 由于使用 NPL::EnvironmentReference 值保证有效性,无效的父环境访问会出错,但行为仍可预测;详见 @8.4.5.2 。
41254127 被 A1::EvaluateIdentifier(@7.6.4) 求值的变量按引用捕获。
@@ -4133,7 +4135,7 @@
41334135 作为过程实现的求值结构(evaluation structure)(对应表达式中可能被求值的函数体(@4.5.2) );
41344136 决定是否在调用后提升返回结果(@8.4.5.4) 的标记。
41354137 这些数据都是可被共享的。复制 vau 抽象的处理器对象共享这些数据。
4136-其中,作为父环境(@5.4.3) 的静态环境以 NPL::EnvironmentReference 弱引用值保存,并附加 shared_ptr 实例以可选被 vau 抽象所有;其它数据都以 shared_ptr 的值保存,被 vau 抽象所有。
4138+其中,作为父环境的静态环境以 NPL::EnvironmentReference 弱引用值保存,并附加 shared_ptr 实例以可选被 vau 抽象所有;其它数据都以 shared_ptr 的值保存,被 vau 抽象所有。
41374139 这允许调用(@8.4.5.4) 引用父环境时对之前确定的绑定(如捕获(@8.4.5.1) 时) 进行生存期检查,发现循环引用(@5.2) 等引起未定义行为的错误(@7.6.5) 。注意在对象语言中出错时未定义行为,不应依赖此行为。
41384140 除可选的静态环境 shared_ptr 实例,所有指针数据在 vau 抽象对象的生存期内都保持非空。
41394141 形式参数树(@7.7.3) 作为数据成员同 vau 抽象对象被项或环境所有,可能被不同值类别的表达式标识,但它作为表达式和子表达式时不被直接求值,且子表达式中的符号被复制而不是以间接值引用(@5.7.4.2) ,因此是纯右值(@5.7.3) 。
@@ -4235,13 +4237,13 @@
42354237 函数 Forms::LoadModule_std_io 提供输入/输出操作(@11.4) ;
42364238 函数 Forms::LoadModule_std_system 提供系统操作(@11.5) ;
42374239 函数 Forms::LoadModule_SHBuild 提供其它一些供 SHBuild 间接调用的操作(@12.1.1) 。
4238-函数 Forms::LoadStandardContext 调用 Forms::LoadGroundContext 并加载标准库模块(另见 @11 )。
4240+函数 Forms::LoadStandardContext 调用 Forms::LoadGroundContext 并加载基础上下文中提供的库模块(@10.1) ;另见 @11 。
42394241
42404242 @9 NPLA1 对象语言规则和一般实现导引:
42414243 以下实现中的 C++ 名称和项目模块命名空间的使用同 @7 。
42424244
42434245 @9.1 程序实现:
4244-程序是语言的派生。实现程序即在语言的基础上指定派生规则。
4246+程序(@2.3.2) 是语言的派生。实现程序即在语言的基础上指定派生规则。
42454247 实现外的程序是用户程序(user program) 。
42464248 以 NPLA1 程序或另行指定的其它形式实现的可复用程序被归类为库(@1.4.4.4) 。
42474249 不论是 NPLA1 的实现还是用户程序,都可能使用库。
@@ -4299,11 +4301,11 @@
42994301 <expression> :待求值的表达式。
43004302 <expressions> :形式为 <expression>... 的待求值形式。
43014303 求值时,<expressions> 被作为单一表达式(即视为 (<expression>...) ),代替 <expression> 可避免语法中要求过多的括号及 eval(@10.5.6) 等求值形式中显式构造列表的需要。
4302-<binding> :绑定列表,形式为 <symbol> <expressions> ,用于指定被求值的表达式和绑定参数的符号。
4304+<binding> :绑定列表,形式为 <symbol> <body> ,用于指定被求值的表达式和绑定参数的符号。
43034305 和 Kernel 不同,<symbol> 后不要求是整个 <expression> 。
43044306 <bindings> :元素为 <binding> 的列表,形式为 (<binding>...) 。
4305-<body> :出现在元素的末尾 <expressions>? 形式,用于函数体(@8.4.5) 等替换求值的目标。
4306-<expression-sequence> :同 <body> 但蕴含顺序求值。
4307+<body> :出现在元素的末尾 <expressions>? 形式,可用于函数体(@8.4.5) 等替换求值的目标。
4308+<expression-sequence> :同 <body> 但蕴含顺序求值子项。
43074309 求值 <expression-sequence> 的结果被定义为求值其最后一个子表达式(若存在)的结果,或当不存在子表达式时为未指定值(@7.2.2)。
43084310 <consequent> :同 <expression> ,仅用于 <test> 求值为 #t 时。
43094311 <alternate> :同 <expression> ,仅用于 <test> 求值不为 #t 时。
@@ -4325,17 +4327,19 @@
43254327 和 [RnRK] 的理由不同,允许布尔代数以外扩展的比较判断在此不认为是易错的,而是有意的设计(by design) 。这避免预设地假定类型的名义语用作用(“角色(role)” ),也避免限定语言和派生语言的类型全集(@4.6.2.4) 。
43264328 <combiner> :合并子。
43274329 <applicative> :应用子(@4.5.3.2) 。
4328-<predicate> :谓词,是应用操作数的求值结果的值为 <bool> 的 <applicative> 。通常实现为纯求值(@4.4.2) 。
4330+<predicate> :谓词,是应用操作数的求值结果的值为 <test> 的 <applicative> 。通常实现结果为 <bool> 的纯求值(@4.4.2) 。
43294331 <environment> :一等环境(@9.6.2) 。
43304332 <string> :字符串,宿主值类型为 string(@5.6.1) 。
43314333 字符串(包括字符串字面量求值的结果)以 string 类型表示,编码和表示要求同 YFramework 默认约定([Documentation::YFramework @@3.3.1]) 。
43324334
43334335 @9.2.2.4 文法形式补充约定:
4336+和 [RnRK] 不同,NPLA1 的符号可包含字面量。除非另行指定,以 <symbols> 指定的值被作为 <definiend> 或 <formals> 使用时不应引起错误,即不应包含 #ignore 以外的字面量。注意 <symbols> 在被其它上下文使用时仍可能引起错误。
43344337 和 [RnRK] 不同,<definiend> 和 <formals> 不要求重复符号检查。另见 @7.7.3 。
43354338 [RnRK] 和 [Shu10] 都没有显式区分 <definiend> 和 <formals> ,两者在上下文中实质可互换,差别仅在 [RnRS] 中的 define 形式中定义的位置可具有和 <formals> 不兼容的扩展形式。
43364339 本文档补充约定,使用 <formals> 的情形包括合并子基本操作(@10.5.7) 和可通过这些操作派生的操作在对应位置的操作数。
43374340 针对这个假设,派生实现可进行附加的语义检查。在 NPLA1 的当前实现(特别地,使用 @7.7.4 的 API )中,没有这样的检查。
43384341 这实质等价使用 [Shu09] 中的记法,即 <formals> 用于除和 [Shu09] 的 $define! 类似外的所有操作(包括 $set! 和 $let 等,而不论是否对应 <body> )。这些上下文中总是隐含了上述的可派生实现的要求。
4342+和 [RnRK] 不同,<body> 不蕴含顺序求值子项。
43394343
43404344 @9.3 对象语言语法:
43414345 基于 NPLA 基本语法约定参见 @5.2 。
@@ -4383,7 +4387,7 @@
43834387 和实现进行(通常无法保证内存安全的)互操作;
43844388 绑定列表(@9.2.2.1) 传递引用(@7.7.3) 且传递的引用值被求值(@5.7.4.1) 使用时,被引用的对象不在生存期内;
43854389 调用可能返回引用值的合并子(通常通过 @8.4.5.4 实现),且返回值(@4.5.3.1) 对应的对象不在生存期内(另见 @10.4.1 );
4386-使用其它不保证内存安全的操作(可由 NPLA1 参考环境提供,参见 @10.1.2 )引入的不具有内存安全保证的间接值访问实体。
4390+使用其它不保证内存安全的操作(可由 NPLA1 参考环境提供,参见 @10.1.4 )引入的不具有内存安全保证的间接值访问实体。
43874391 绑定到形式参数的右值(@5.5.1) 保存在过程调用的局部环境(@8.4.5) 中,因此退出函数体(@8.4.5) 求值(局部环境被释放后)返回其引用总是无法满足安全保证;
43884392 绑定到列表形式参数上的实际参数列表总是右值;
43894393 对返回值中涉及到的安全保证机制,参见 @9.6.1.4 。
@@ -4401,7 +4405,9 @@
44014405
44024406 @9.4.3.1 错误(@2.5.2) :
44034407 NPLA1 中的错误是按接口的约定不符合预期的正常条件(如不被正常处理的操作数类型(@9.4.3.4) )引起的诊断。
4404-求值特定的表达式可引起(@2.5.2) 错误,包括语法错误(@7.8.2) 和其它的语义错误。
4408+求值特定的表达式可引起(@2.5.2) 错误,包括在求值算法(@9.4.1) 中直接引起的语法错误(@7.8.2) 和其它的语义错误。
4409+以 @9.2 的形式约定的操作中,除类型检查(@9.4.3.4.1) 外,参数绑定(@8.4.5.3) 失败是语法错误。
4410+总是依赖程序运行时确定的合并子的具体实际参数的值引起的语法错误是动态语法错误;其它语法错误是静态语法错误。静态语法错误可能通过语法分析从源代码决定。
44054411 其它错误包括求值特定的函数应用(@9.4.3) ,由具体操作指定(参见 @10.4.1 )。
44064412 程序可通过引发(raise) 错误对象(error object) 指定引起诊断。
44074413 除非另行指定,NPLA1 的错误对象不需要是 NPLA1 支持的对象,而可以仅在宿主实现中可见。
@@ -4415,7 +4421,7 @@
44154421 引发错误对象(@9.4.3.1) 可能通过抛出异常实现。被抛出的宿主语言异常对象是错误对象。被抛出的异常类型可具有被显式指定的 public 基类,这些基类应无歧义以允许宿主语言捕获。
44164422 若存在依赖错误(@9.4.3.1) 且引发被依赖的错误对象使用抛出异常实现,使用宿主语言标准库的嵌套异常(nested error) 机制实现依赖错误。
44174423 除非由宿主环境(@2.7.1) (包括 @9.4.3.3 中指定的情形)、对 TermNode(@5.4.2) 的操作内部实现或另行指定的来源,被抛出的异常对象的类型总是 NPL::NPLException(@6.3) 或其 public 派生类。
4418-若语法错误(@7.8.2) 使用抛出异常实现,则异常对象的类型是 NPL::InvalidSyntax(@6.3) 或其 public 派生类。
4424+若语法错误(@9.4.3.1) 使用抛出异常实现,则异常对象的类型是 NPL::InvalidSyntax(@6.3) 或以其作为无歧义 public 基类的类。
44194425 除显式指定的情形,抛出的具体异常类型未指定。通常实现可根据接口的含义使用 @6.3 中最合适的异常。
44204426
44214427 @9.4.3.3 运行时(@2.4.1) 错误条件(@2.5.2) :
@@ -4564,10 +4570,12 @@
45644570 特定的表达式维护可修改性(@9.4.5.1) 。这类似宿主语言的 const 类型限定,但只适合左值(@5.5.1) 且仅使用隐式类型。
45654571
45664572 @9.5.2 绑定构造(binding construct) :
4567-部分函数合并的求值用于表示在环境(@9.6.2) 中引入绑定,其调用指定绑定操作(@7.7.3) 。这样的表达式是绑定构造。
4573+部分函数合并的求值用于表示在环境(@9.6.2) 中引入绑定,其调用指定绑定操作(@7.7.3) 。具有这样的语法构造的表达式是绑定构造。
45684574 绑定构造包含形式参数树(@7.7.3) ,通过绑定规则(@7.7.3) 引入绑定。绑定在符号上的值引入变量(@4.1) 。另见 @5.5.2 。
4569-对绑定项的处理和 [RnRK] 的不同参见 @9.2.2.4 。
45704575 按 @5.2 的要求以及 @7.7.3.1 的约定,操作数树(@7.7.3) 的子节点初始化被绑定的形式参数树的对应子节点。
4576+一些绑定构造使用 <binding>(@9.5.2) 提供在一个表达式多次出现的形式参数树和操作数树。
4577+和 [RnRK] 不同,各种绑定构造可使用 <body>(@9.5.2) 提供操作数。
4578+对绑定项的处理和 [RnRK] 的其它不同参见 @9.2.2.4 。
45714579 另见 @7.7.4 的 API 。
45724580
45734581 @9.5.2.1 强递归绑定:
@@ -4644,15 +4652,20 @@
46444652
46454653 @9.6.2 环境:
46464654 和 Kernel 类似,NPLA1 支持一等环境(first-class environment) 。
4655+语言实现可提供非一等环境。总是不能被对象语言作为一等对象的环境是隐藏环境(hidden environment) 。
4656+一般地,隐藏环境是某一个(非隐藏的)一等环境的直接或间接父环境(而能通过求值等间接操作被访问)。
46474657 和 Kernel 类似,NPLA1 的一等环境可包含一个或多个父环境(@5.4.3) ,其重定向(@4.3.3) 使用 DFS 形式的默认重定向算法(@5.4.3) 。
4648-新环境(fresh environment) 是新创建的环境。除非另行指定,新环境是不存在能引起程序行为改变的父环境的空环境(@4.6.1.1) 。
4658+新环境(fresh environment) 是新创建的环境。除非另行指定,新环境是不存在能引起程序行为改变的父环境的空环境(@4.6.1.1) 。()
46494659 和 Kernel 不同,环境绑定(@4.1) 的抽象不依赖对象语言中表达的引用的概念,允许直接关联一个没有引用的值。另见 @4.2.3 和 @5.4.3 。
4650-和 Kernel 不同,环境绑定对被绑定的对象具有所有权(@5.4.3) 。除非另行指定(参见 @10.1.2 ),这种直接所有权是独占的。
4660+和 Kernel 不同,环境绑定对被绑定的对象具有所有权(@5.4.3) 。除非另行指定(参见 @10.1.4 ),这种直接所有权是独占的。
46514661 和 Kernel 不同,环境对象符合默认的等价比较规则(@9.4.5.3) ,不提供不同等价谓词的结果一致性。
46524662 和 Kernel 不同,环境中的绑定的对象可以在引入后通过对象的引用(@9.6.1) 被修改(@9.4.5.1) 。
4653-但环境在特定情形仍保证稳定性(stability) ,即总是可假定绑定维持一定意义的等价性。违反环境稳定性引起未定义行为(@9.4) 。
4654-当前约定稳定性包括隐藏环境(hidden environment) 的绑定有效稳定性(@9.6.2.2) 和值稳定性(@9.6.2.3) ,其中隐藏环境指不能被对象语言作为一等对象的环境。
4655-一般地,隐藏环境是某一个(非隐藏的)一等环境的直接或间接父环境(而能通过求值等间接操作被访问)。
4663+但环境在特定情形仍保证稳定性(stability) ,即总是可假定绑定维持一定意义的等价性,而可确保其中同名实体的同一性。在这些特定的情形中,违反环境稳定性引起未定义行为(@9.4) 。
4664+当前要求确保的稳定性包括:
4665+隐藏环境的绑定有效稳定性(@9.6.2.2) 和值稳定性(@9.6.2.3) ;
4666+从构造时即明确要求稳定的一等环境(参见 @10.1.1 )。
4667+一般地,环境的稳定性要求构造环境时不能依赖非特定的动态环境(作为被名称解析访问的父环境),因为这些环境的绑定可能具有在构造模块之后确定的绑定,而不能确保模块中的名称具有可预知的含义。
4668+环境的稳定性简化分析程序的推理过程,也在许多上下文中允许程序更易被优化。
46564669 和 Kernel 不同,环境(@10.5.6) 和合并子操作(@10.5.7) 及基于这些操作的一些派生操作(@10.6) 的操作数树(@7.7.3) 构造不检查其中的非列表项是否都为符号或 #ignore ;匹配时不检查符号重复;若形式参数中的符号重复,则绑定的目标未指定。
46574670 此外,NPLA1 提供单独的递归绑定符号的机制,且明确支持在操作数中同时递归绑定之前未被绑定的多个符号(@9.5.2.1) 。
46584671 环境对应多个宿主值类型(@6.9.3) 。
@@ -4690,7 +4703,7 @@
46904703
46914704 @9.6.2.4 冻结(freeze) 操作:
46924705 环境可被冻结。冻结后的环境中取得的绑定和引用值不可修改。
4693-特定的环境修改要求环境不在没有冻结状态以确保不变量,要求类型检查(@9.4.3.4.1) 。检查失败则引起类型错误。
4706+特定的环境修改要求环境不在没有冻结状态以确保不变量,要求类型检查(@9.4.3.4.1) 。检查失败则引起类型错误(@9.4.3.4.1) 。
46944707 冻结一个已被冻结的环境没有作用。
46954708 注意冻结的环境中仍可添加、移除绑定或重绑定(@9.6.2.2) 。
46964709 NPLA1 隐藏环境是冻结的。当前 NPLA1 不提供在已有环境撤销冻结的方法。
@@ -4802,7 +4815,7 @@
48024815
48034816 @9.9.1 可提供以引用标记字符结尾版本的操作:
48044817 为满足适用性(@1.4.5.2) ,同时考虑维护内存安全、避免误用和允许使用引用避免复制,这些操作需显式使用以 % 或 & 结尾的函数名称以得到特别关注。
4805-对以求值 <body> 作为尾上下文的操作(@9.4.8.1),以 % 结尾表示 <body> 所在的函数返回时不要求返回非引用值(@9.6.1.4) ,尽管这些操作不返回引用值。
4818+对以求值 <body> 作为尾上下文(@4.4.7) 的操作(@9.4.8.1),以 % 结尾表示 <body> 所在的函数返回时不要求返回非引用值(@9.6.1.4) ,尽管这些操作不返回引用值。
48064819 对其它提供不同引用标记字符的多个版本的操作:
48074820 以 % 结尾表示函数可使用不进行左值到右值转换(@5.5.5) 的折叠(@5.6.3.2) 的引用值参数,或可返回折叠的引用值;
48084821 以 & 结尾表示函数使用不进行左值到右值转换的折叠的引用值参数,或返回折叠的引用值;
@@ -4869,13 +4882,27 @@
48694882 除此之外,派生实现可指定对操作提供对应的非常规函数(@9.7.4) 。
48704883 这些操作中的大部分具有特定的名称。这些名称符合 @9.9 的约定;其分类详见 @10.4 。
48714884 其它操作不具有特定名称,可由上述操作间接地提供,如蕴含在某些操作涉及的函数值(@4.5.3) 中。
4872-同 [RnRK] ,以绑定提供的语言特性被分组归类为模块(@1.4.6.4) ,可通过 @8.5 实现。
4873-同 @8.1 ,特性分为基本的和派生的。前者在设计上不分解为更小的其它特性的组合;后者可由 NPLA1 源代码实现。
4874-区分基本和派生的特性在设计上类似 [RnRK] 中的基本和库特性。注意和 [RnRK] 的库特性不同(而更接近宿主语言),NPLA1 的库特性是以接口而非对象语言实现的角度定义的。
4875-因不预期通过派生实现,基本操作总是通过本机实现提供。
4876-要求通过基础环境直接或间接提供的库(@9.1) 总称标准库(standard library) 。
4885+
4886+@10.1.1 模块:
4887+同 [RnRK] ,以绑定提供的语言特性被分组归类为模块(@1.4.6.4) 。
4888+模块的源(source) 提供特性的实现,可以是本机实现或者 NPLA1 程序。
4889+模块的源可以是实现内建的,或位于实现环境提供的外部资源(如文件系统)。
4890+因为模块以绑定的集合的形式提供,需被包含在可访问的环境,或包含环境作为子对象的其它对象中。
4891+从模块的源得到提供一个模块的所有绑定集合的环境对象的过程称为模块的加载(loading) 。
4892+模块加载可能失败。失败的模块加载引起错误(@9.4.3.1) 。
4893+根环境加载的失败不被直接依赖这些环境的 NPLA1 用户程序处理(而视为实现初始化的运行时错误)。
4894+一般地,模块和加载模块得到的环境对象没有直接对应关系:一个模块的绑定可以由一个或多个环境提供,一个已被加载的环境可能提供零个或多个程序可见的模块。但除非另行指定,一个模块的绑定不在超过一个的不相交的环境(之间没有直接或间接父环境关系)中提供。
4895+程序可通过加载外部模块来源取得模块。除非另行指定,这种模块以一个一等环境对象(可包含作为环境的直接或间接子对象)中的绑定提供。
4896+同 [RnRK] 的 get-module 的约定,提供模块绑定的环境依赖已知来源的绑定而确保稳定(@9.6.2) 。
4897+
4898+@10.1.2 特性分类:
4899+同 @8.1 ,特性分为基本的和派生的。前者在设计上不分解为更小的其它特性的组合,通常需要本机实现;后者可由可移植的 NPLA1 源代码实现。
4900+实现加载本文档要求的模块的本机 API 入口参见 @8.5 。
4901+区分基本和派生的特性在设计上类似 [RnRK] 中的基本和库特性。
4902+注意和 [RnRK] 的库特性不同(而更接近宿主语言),NPLA1 的库特性是以 NPLA1 程序使用的接口而非实现的角度定义的,不总是使用对象语言实现,外延更广。
4903+本文档中要求的通过基础环境直接或间接提供的库(@9.1) 总称标准库(standard library) 。
48774904 标准库的接口随语言规范在参考实现环境(@10) 和参考实现扩展环境(@11) 约定。
4878-核心库(core library) 是提供直接绑定在基础环境中的保证可派生实现的接口的标准库模块。
4905+核心库(core library) 是提供直接绑定在基础环境中的、保证可派生实现的接口的标准库模块。
48794906 在参考实现环境中的不同标准库模块的绑定都可在基础环境访问;
48804907 在参考实现扩展环境中的标准库模块以其它环境(通常作为基础环境的子对象提供)中的绑定和基础环境隔离。
48814908 派生实现可以库的形式提供语言扩展或其它功能特性,扩充标准库。
@@ -4888,12 +4915,12 @@
48884915 @10.5 提供在基础上下文(@8.5.2) 初始化的根环境基本(primitive) 接口,作为单独的模块。
48894916 @10.6 起的各节提供其余要求 NPLA1 实现直接支持的各个模块的操作。
48904917
4891-@10.1.1 限制:
4918+@10.1.3 限制:
48924919 为避免依赖逻辑上复杂的形式,一些操作当前被核心功能排除。例如,依赖一阶算术的操作、其硬件加速形式的 ISA 表示的整数操作及依赖这些操作实现的数值塔(numerical tower) 被整体忽略。
48934920 上述忽略的操作可由派生实现补充(如以类似 @10.6 的形式),在派生根环境后按需进行 AOT(ahead-of-time) 优化(如 Kernel 的 $let-safe! 中包含的内容,其中引用基础环境的符号不再可变),然后组成类似基础环境。
48944921 派生实现不依赖非真合并子(@9.6.4) ,因此其中不使用分隔符(@9.4) ,也不需要实现在初始化时支持中缀变换(@7.5.2) 。
48954922
4896-@10.1.2 不安全(unsafe) 操作:
4923+@10.1.4 不安全(unsafe) 操作:
48974924 除非另行指定,以下操作是不安全操作:
48984925 以下不具有内存安全保证(@9.4.2) 的操作:
48994926 使用 @9.9 约定命名的带有后缀的操作;
@@ -4901,8 +4928,8 @@
49014928 引入其它间接值的操作;
49024929 引入引用现有环境(@9.6.2) 的 shared_ptr<Environment> 宿主值而可能通过循环引用等引起未定义行为(@9.6.1.1) 的操作;
49034930 引入共享持有者的值数据成员(@5.4.2) 而可能通过循环引用等引起未定义行为操作。
4904-第一类不安全操作和引用值的使用(特别是保留引用值(@9.6.1.5) )相关,具体规则参见 @10.1.2.1 、@10.4.1 和 @10.4.2 。
4905-其中,可引起扩展 NPLA 未定义行为(@9.4) 的操作包括以下可能破坏环境稳定性(@9.6.2) 的第一类不安全操作(@10.1.2.1) :
4931+第一类不安全操作和引用值的使用(特别是保留引用值(@9.6.1.5) )相关,具体规则参见 @10.1.4.1 、@10.4.1 和 @10.4.2 。
4932+其中,可引起扩展 NPLA 未定义行为(@9.4) 的操作包括以下可能破坏环境稳定性(@9.6.2) 的第一类不安全操作(@10.1.4.1) :
49064933 赋值操作(@10.4.1.3) ;
49074934 move!(@10.5.4) 。
49084935 第二类不安全操作可能通过非引用的操作引入循环引用破坏环境的资源所有权,其中的基本操作在 @10.5.6 提供,对应的函数名如下:
@@ -4918,7 +4945,7 @@
49184945 第三类不安全操作的强递归绑定过程中引用共享对象(参见 $defrec!(@10.5.6) )的中间值。
49194946 NPLA1 参考实现环境中,仅有第三类不安全操作的实现内部可能引入引用持有者;参见 @9.4.2 。
49204947
4921-@10.1.2.1 第一类不安全操作的子类:
4948+@10.1.4.1 第一类不安全操作的子类:
49224949 第一类不安全操作按被保留的引用值的来源分为以下两个子类:
49234950 直接保留引用值操作:接受引用值参数并直接保留引用值;
49244951 间接保留引用值操作:可涉及不同的环境,参数在这些环境中被求值得到引用值。
@@ -4930,7 +4957,7 @@
49304957 可能间接保留引用值的操作:可涉及不同的环境,结果和副作用由实际参数(需要时经过隐含的左值到右值转换)在这些环境中被求值后确定。
49314958 通过引用进行的修改(@9.4.5.1) 操作可因破坏环境稳定性(@9.6.2) 而引起未定义行为(不一定违反内存安全)。
49324959
4933-@10.1.2.2 安全性附加证明:
4960+@10.1.4.2 安全性附加证明:
49344961 一些不安全操作是否蕴含未定义行为可能依赖具体调用使用的操作数。
49354962 若能证明特定的前提保证任意的调用实例中的操作数满足附加的安全假设,则这些不安全操作的调用仍可保证安全。
49364963 NPLA1 附加调用安全包括少量的第一类不安全操作的调用。派生实现可定义其它调用提供更强的保证。
@@ -4939,12 +4966,13 @@
49394966
49404967 @10.2 实体实现(@2.3.1.2) 约定:
49414968 本节约定对 NPLA1 参考实现内部有效,不作用在用户程序。
4969+因不预期通过派生实现,当前实现中,基本操作总是通过本机实现(@5.2.1) 提供。(这不被接口设计(@10.1) 严格要求。)
49424970 类似 [RnRK] ,派生操作可通过基本操作及派生操作实现。
49434971 除非另行指定,NPLA1 参考实现环境作为公开接口提供的变量在根环境中绑定。
49444972 除非是语义蕴含的操作结果或另行指定,所有作为函数值的操作(@10.1) 的结果(@4.1) 是未指定值(@7.2.2) 。另见 @9.9 。
49454973 未指定值可等于 #inert(@9.3.1) 或其它值,但满足忽略值时不引起可观察行为(@4.1.3) 的改变(这排除了引入 volatile 类型或非平凡析构的宿主值)。
49464974 若操作(@10.1) 在 Kernel 或 klisp 中存在结果为 #inert 的对应的操作,且未指定作为函数值的结果,则返回等于 #inert 的右值。
4947-除非另行指定,空环境没有父环境。
4975+除非显式指定,空环境没有父环境。
49484976 约定的接口通过绑定在根环境中的名称提供,参见以下各节。
49494977 这些名称可能是本机实现(@5.2.1) ,即直接调用 NPLA 或 NPLA1 API(参见 @6 、@7 和 @8 )绑定定义;也可能是非本机的派生的(derive) 实现,即通过在当前的基础上求值特定的对象语言代码引入(其实现最终依赖本机实现)。
49504978 变量的绑定(@4.1) 的引入是否由本机实现未指定。
@@ -4955,9 +4983,9 @@
49554983 作为 @7.1.2 的扩展,函数的非本机也实现允许假定纯右值(@5.5.1) 的项不包含不被 @7.1.2 约定直接使用的标签。
49564984
49574985 @10.2.1 函数实现使用约定:
4958-名称使用 $def 起始的函数用于在当前环境(@5.4.4) 引入绑定。
4986+名称使用 $def 起始的函数用于在当前环境引入绑定。
49594987 需引入绑定时,优先使用 @10.6.2 中的函数;当使用这些函数并不能简化实现时,使用 $def!(@10.5.6) 。
4960-其中优先使用函数名中没有 % 的函数,仅当语义要求时,使用 %! 结尾的函数,以减少不安全操作(@10.1.2) 并明确函数值是否可能只是非引用值(此时两者效果应一致)。
4988+其中优先使用函数名中没有 % 的函数,仅当语义要求时,使用 %! 结尾的函数,以减少不安全操作(@10.1.4) 并明确函数值是否可能只是非引用值(此时两者效果应一致)。
49614989 这对应宿主实现中,使用 auto 而不是 auto&& 作为返回值;但宿主语言中返回非引用类型的表达式两者含义不同。
49624990 尽管设计时没有参照,使用函数结尾的引用标记字符和其它一些语言的类似特性的使用惯例也一致,如 PHP 的 function & 语法:
49634991 https://www.php.net/references.return
@@ -4979,13 +5007,13 @@
49795007 一些函数区分引用值的使用,以引用标记字符结尾提供不同的版本。
49805008 可能存在的结尾的引用标记字符用于强调无法总是保证内存安全(@9.4.2) 的危险操作(@1.4.5.2) ,参见 @9.9.1 。
49815009 不带有引用标记字符结尾的操作通过避免保留引用值(@9.6.1.5) 提供一定的内存安全保证,而带有引用标记字符结尾的操作较容易引起注意。这符合易预测性(@1.4.5.2.1) 。
4982-带有引用标记字符结尾的不安全操作属于第一类不安全操作(@10.1.2) 。
5010+带有引用标记字符结尾的不安全操作属于第一类不安全操作(@10.1.4) 。
49835011 第一类不安全操作实际不满足内存安全的一个主要的必要非充分条件是操作保留引用值,且引用值在被引用对象的生存期外被使用。
49845012 这主要包括直接使用标识符求值为引用值的情形:因为标识符求值(@9.4.1) 后指称左值引用值(@7.8.2) 。
49855013 保留引用值操作的内存安全(@9.4.2) 依赖所有被保留的引用值在之后的使用中都满足内存安全。
49865014 若保留引用值操作不返回引用值,则返回的值等价经过返回值转换(@9.6.1.4) 。
49875015 一般仅在明确需要引用时,使用以引用标记字符结尾的版本的函数(特别是环境可能作为参数被使用时)。
4988-本节约定的函数提供的操作属于 @10.1.2.1 定义的可能直接保留引用值的操作和可能间接保留引用值的操作之一。
5016+本节约定的函数提供的操作属于 @10.1.4.1 定义的可能直接保留引用值的操作和可能间接保留引用值的操作之一。
49895017 可能直接保留引用值的操作中,不带有引用标记字符的操作转发参数(@10.4.2.3) 。
49905018 可能直接保留引用值的操作包括容器构造器或访问器(@9.8.5) ,以及可能使对象中包含引用值的修改操作(@9.4.5.1) 。
49915019 (引入非容器对象的操作另见 @10.4.1.4 。)
@@ -5053,10 +5081,10 @@
50535081 一些函数命名不提供结尾 % 或 & ,函数值是否保留引用值通过本节内的分类确定,符合 @9.9.2 。
50545082 本节内部分操作涉及参数转发(@9.8.2) 和函数值转发(@9.8.4) 。
50555083 本节约定的涉及参数转发或函数值转发的函数不提供引用标记字符(@9.9.1) ,但已在 @10.4.1 中的除外。
5056-尽管可能因为对左值进行求值而使用引用,不使用 @10.4.1.4 中的第一类不安全操作(@10.1.2) 仍能保证这些引用不逃逸(@7.1.4) 。
5084+尽管可能因为对左值进行求值而使用引用,不使用 @10.4.1.4 中的第一类不安全操作(@10.1.4) 仍能保证这些引用不逃逸(@7.1.4) 。
50575085 通常使用 forward(@10.6.1) 转发实现上述保证(@9.8.2) 。
50585086 部分操作的内存安全性和 @10.4.1 类似,也是第一类不安全操作,但仅在引用值参数被保留且在之后体现。
5059-和 @10.1.2.1 类似,包括直接保留引用值和间接保留引用值的不同情形。
5087+和 @10.1.4.1 类似,包括直接保留引用值和间接保留引用值的不同情形。
50605088 除 @10.4.2.1 和其它节的操作不相交,以下分类对操作的参数和函数值分别约定,可能相交。
50615089
50625090 @10.4.2.1 可直接返回引用值的操作:
@@ -5089,7 +5117,7 @@
50895117 类似列表构造器,这些函数可在结果中保留引用值。
50905118
50915119 @10.4.2.3 直接参数转发操作:
5092-部分不带有引用标记字符的直接参数转发操作是可能直接保留引用值的操作(@10.1.2.1) 。
5120+部分不带有引用标记字符的直接参数转发操作是可能直接保留引用值的操作(@10.1.4.1) 。
50935121 函数名不使用引用标记字符,和 @10.4.1.1 的函数名使用引用标记字符不一致:
50945122 本节约定的函数和 @10.4.1.1 中函数名中带有 % 结尾的函数同属参数转发操作,但后者同时有不带有引用标记字符的版本;
50955123 本节不约定和 @10.4.1.1 中函数名中不带有引用标记字符结尾的函数对应的操作。
@@ -5128,12 +5156,12 @@
51285156 使用 make-encapsulation-type(@10.5.9) 返回的访问器合并子。
51295157
51305158 @10.4.2.5 间接保留引用值的操作:
5131-部分不带有引用标记字符的操作是可能间接保留引用值的操作(@10.1.2.1) 。
5159+部分不带有引用标记字符的操作是可能间接保留引用值的操作(@10.1.4.1) 。
51325160 由类型为合并子的参数(而非 <body> 或 <expressions> )决定是否保留引用值同时对其它参数进行转发的操作有:
51335161 apply(@10.6.1)
51345162 由特定的参数在特定环境中的求值的结果决定是否保留引用值的操作有核心库函数(@10.6.2) :
51355163 $provide!
5136-$provide/d!
5164+$provide/let!
51375165
51385166 @10.4.3 引用值构造:
51395167 当前构造子对象引用(@5.6.3.5) 的操作有:
@@ -5143,8 +5171,8 @@
51435171 @10.5 根环境基本接口(@10.1) :
51445172 和 [RnRK] 不同,为简化设计,NPLA1 不提供可选(optional) 的合并子,而通过预定义对象(@10.3) 的形式提供可选的模块(@11) 。
51455173 根环境基本接口是除了这些模块的以变量绑定形式提供的不要求可派生实现的接口,被绑定对象(@5.4.3) 包括预定义对象(@10.3) 和在基础上下文(@8.5.2) 的根环境中初始化的基础基本操作(grounded primitive operations) 的实现。
5146-派生实现可以通过提供不公开不安全操作(@10.1.2) 的根环境,但不符合此处的规格要求(@2.3.1.2) 。
5147-若派生实现不提供第三类不安全操作(@10.1.2) ,可以简化部分 @10.5.4 中与之关联的操作的实现。
5174+派生实现可以通过提供不公开不安全操作(@10.1.4) 的根环境,但不符合此处的规格要求(@2.3.1.2) 。
5175+若派生实现不提供第三类不安全操作(@10.1.4) ,可以简化部分 @10.5.4 中与之关联的操作的实现。
51485176 部分可选的 Kernel 合并子被直接提供。
51495177 和 Kernel 不同,一些函数显式地操作引用值(@5.5.4) ,包括未折叠的引用值(@5.5.4) 。
51505178 和 Kernel 不同,求值算法不直接处理对象的引用值(@6.5.3.3) 。
@@ -5231,7 +5259,7 @@
52315259 unique? <object> :判断操作数是否为唯一引用(@5.4.2.2) 。
52325260 deshare <object> :取指定对象取消共享的值。
52335261 同 idv(@10.6.1) ,但显式提升操作数中具有共享持有者的值数据成员(@5.4.2) ,且不转移宿主值。
5234-因为提供第三类不安全操作(@10.1.2) ,这个区别是必要的。否则,使用 idv 替代应不影响可观察行为(@4.1.3) 。
5262+因为提供第三类不安全操作(@10.1.4) ,这个区别是必要的。否则,使用 idv 替代应不影响可观察行为(@4.1.3) 。
52355263 和通常的求值规约消除引用值(如 @7.7.2.1 )不同,以 NPL::LiftTermRef(@6.6.2) 和确保创建值副本的 NPL::SetContentWith(@6.2.1) 实现。
52365264 expire <object> :取指定对象的消亡值(@5.5.1) 。
52375265 同 id(@10.6.1) ,但当参数是引用值时,结果是和参数引用相同对象的唯一引用。
@@ -5283,7 +5311,7 @@
52835311 和 $resolve-identifier 类似,但直接取被绑定的对象并从环境中转移。
52845312 若环境被冻,则复制绑定的对象所在的项;否则,直接转移对象的项(@5.5.3) 。
52855313 一般应仅用于被绑定的对象不需要再被使用时。
5286-() copy-environment :递归复制当前环境(@5.4.4) 。当前忽略父环境中的环境列表(@5.4.3) 。
5314+() copy-environment :递归复制当前环境。当前忽略父环境中的环境列表(@5.4.3) 。
52875315 结果为新创建的环境,具有宿主值类型 shared_ptr<Environment> 。
52885316 使用类似 @5.4.3 的 DFS 搜索操作数的父环境和绑定的对象,若非环境则直接复制值,否则创建环境并递归使用 DFS 复制值。
52895317 当前只支持复制具有 shared_ptr<Environment> 和 EnvrionmentReference 的宿主值的环境,其它对象直接视为非环境对象。
@@ -5298,20 +5326,20 @@
52985326 结果为新创建的环境,是环境强引用,具有宿主值类型 shared_ptr<Environment> 。
52995327 weaken-environment <environment> :使用环境强引用创建环境弱引用。
53005328 检查操作数的宿主值类型(@6.9.1) 是 shared_ptr<Environment> ,结果的宿主类型 NPL::EnvironmentReference 。因为 NPLA1 需要精确控制所有权而不依赖 GC(@5.2) ,这可用于派生实现某些操作(如 $sequence(@10.6.1) 必要的)。
5301-$def! <definiend> <expressions> :修改当前环境中的绑定。
5329+$def! <definiend> <body> :修改当前环境中的绑定。
53025330 类似 Kernel 的 $define! ,但满足 @9.5.2 的约定。
5303-和 Kernel 的 $define! 不同,$def! 和 $defrec! 在求值 <expressions> 后,进行类型检查(@9.6.2.4) ,确保环境没有被冻结后添加绑定。
5304-和 Kernel 类似,对在 <expressions> 中某些未被直接求值的子表达式(如 $lambda(@10.5.7) 的 <body>),因为其中的求值依赖 $def! 表达式求值后的环境,在之后仍可以实现递归。
5331+和 Kernel 的 $define! 不同,$def! 和 $defrec! 在求值 <body> 后,进行类型检查(@9.6.2.4) ,确保环境没有被冻结后添加绑定。
5332+和 Kernel 类似,对在 <body> 中某些未被直接求值的子表达式(如 $lambda(@10.5.7) 的 <body>),因为其中的求值依赖 $def! 表达式求值后的环境,在之后仍可以实现递归。
53055333 由于递归调用依赖环境中的绑定,修改以上定义引入的绑定后可影响被递归函数的调用。
53065334 对 <definiend> 中已存在的标识符的绑定,保证直接替换对象的值,对象的引用不失效(@9.6.2.2) 。
5307-$defrec! <definiend> <expressions> :修改绑定,同 $def! ,但在绑定时针对 <definiend> 指定的操作数树(@7.7.4) 中的绑定名称有附加的处理以支持直接递归。
5335+$defrec! <definiend> <body> :修改绑定,同 $def! ,但在绑定时针对 <definiend> 指定的操作数树(@7.7.4) 中的绑定名称有附加的处理以支持直接递归。
53085336 除和 $def! 相同过程的常规绑定(求值 <expression> 和绑定符号)外,支持强递归绑定(@9.5.2.1) ,其操作数树的附加处理分为两阶段;每个阶段深度优先遍历 <definiend> 指定的操作数树,对每个符号进行附加处理:
53095337 在常规绑定前,每个遍历的待绑定符号在目标环境(被定义影响的环境)中预先进行绑定,保证指称一个对默认对象的弱引用,其中默认对象具有调用总是抛出异常的 A1::ContextHandler 类型(@7.2.1) 的值;和这个弱引用的共享的强引用被临时另行保存。
53105338 在常规绑定后,再次遍历操作数树,对每个 A1::ContextHandler 的值,替换之前在环境中保存的共享定义为默认对象的共享强引用,最后释放先前临时保存的默认对象的强引用。
53115339 调用默认对象时,若默认对象的强引用存在,抛出默认对象内置的异常;否则,抛出由对象实现提供的引用不存在的异常。和 vau 抽象对环境的检查(@9.6.2.1) 类似,后者在对象语言中已引起未定义行为,不应被依赖。
5312-常规绑定后转移未被 <expressions> 求值影响的绑定中的默认对象的所有权到环境中,但不影响绑定目标在对象语言中指称的值。
5313-在环境中未被 <expressions> 求值替换的绑定,在 $defrec! 求值仍指称默认对象(而不会是持有合并子的宿主类型(@7.6.1.1) 的值),若被作为合并子调用,则显示存在循环递归调用。
5314-和 $def! 不同,常规绑定后的操作使 <expressions> 不在尾上下文求值;而因为保证操作数树中的名称已存在默认定义,求值 $defrec! 的 <expressions> 前时可使用绑定。
5340+常规绑定后转移未被 <body> 求值影响的绑定中的默认对象的所有权到环境中,但不影响绑定目标在对象语言中指称的值。
5341+在环境中未被 <body> 求值替换的绑定,在 $defrec! 求值仍指称默认对象(而不会是持有合并子的宿主类型(@7.6.1.1) 的值),若被作为合并子调用,则显示存在循环递归调用。
5342+和 $def! 不同,常规绑定后的操作使 <body> 不在尾上下文求值;而因为保证操作数树中的名称已存在默认定义,求值 $defrec! 的 <body> 前时可使用绑定。
53155343 这允许递归定义的名称在绑定完成前指称对象。例如,当环境中未绑定变量 a 和 b 时:
53165344 求值表达式 $def! (a b) list b ($lambda () 1) 因为被求值的 b 未被绑定引起错误(@9.4.3.1) ;
53175345 求值表达式 $defrec! (a b) list b ($lambda () 1) 不需要 a 或 b 已被绑定(即便 b 并不在 $lambda 的 <body> 中),求值后 a 为默认对象;
@@ -5325,7 +5353,7 @@
53255353 和 Scheme 及 Kernel 不同,<body> 可以是多个项,而不在派生另外的版本支持顺序求值。
53265354 引入合并子的操作子不求值 <body> ,后者在被调用时替换操作数以后被求值。这允许安全地使用 $def! 而不需要 $defrec! 进行递归绑定(@10.5.6) 。
53275355 创建合并子时对参数指定的求值环境 <environment> 进行类型检查(@9.4.3.4.1) 外,还进行内部的检查确保宿主值非空。
5328-检查失败的错误(@9.4.3.1) 是(可能依赖(@9.4.3.1) 类型错误(@9.4.3.4.1) 的)语法错误(@7.8.2) 。
5356+检查失败的错误(@9.4.3.1) 是(可能依赖(@9.4.3.1) 类型错误(@9.4.3.4.1) 的)语法错误(@9.4.3.1) 。
53295357 $vau/e <environment> <formals> <eformal> <body> :创建指定静态环境的 vau 抽象(@4.5.2.3) 。
53305358 创建的对象是操作子(@7.6.1.1) 。
53315359 和 Kernel 不同,因为支持保存环境的所有权,$vau/e 被设计为比 $vau 更基本的操作。
@@ -5362,17 +5390,18 @@
53625390 NPL_Impl_NPLA1_Native_EnvironmentPrimitives
53635391 NPL_Impl_NPLA1_Use_Id_Vau
53645392 NPL_Impl_NPLA1_Use_LockEnvironment
5365-不直接使用本机实现的替代实现仅供参考,可能引入和本机实现不同的未指定行为,且可能有和核心特性实现相关的限制,如:
5366-可使用不同的类型检查顺序(@9.4.3.4.1) ,多次失败的类型检查可能引发不同的诊断(@9.4.3) ;
5393+不直接使用本机实现的替代实现仅供参考,可能引入和本机实现不同的未指定行为,且可能有和核心特性实现相关的限制:
5394+由合并子调用的参数绑定(@8.4.5.3) 引起(@9.4.3.1) 的静态语法错误(@9.4.3.1) 可能具有不同的诊断(@9.4.3) ;
5395+类型检查(@9.4.3.4.1) 可具有不同的顺序,多次失败的类型检查引起的类型错误可能具有不同的诊断;
53675396 使用 TCO 实现 PTC(@9.4.8) ,可能具有不同的支持(@9.4.8.1) 和实现(如 @7.10.8 );
5368-@10.2 的一些未指定行为,特别地,包括续延名称(@7.11.6) 的差异。
5397+@10.2 约定的关于一般操作实现的一些未指定行为,特别地,包括续延名称(@7.11.6) 的差异。
53695398 注意和 [RnRK] 合并子的派生完全省略错误处理而允许不同的诊断不同,NPLA1 中的操作的替代实现的没有被以上例外或操作自身的语义指定的其它行为(如诊断(@9.4.3) )仍应和本机实现保持一致。
53705399
53715400 @10.6.1 基本派生操作:
53725401 引入合并子的操作子对 <body> 的约定同 @10.5.7 。
53735402 因为互相依赖,一些操作实现为派生操作时,不能用于直接派生特定一些其它操作。
53745403 和 $vau/e 或 $vau/e%(@10.5.7) 不同,不指定静态环境的合并子构造器隐含总是使用环境弱引用(@5.4.3) 形式的静态环境,以避免过于容易引入循环引用(@9.6.1.1) 。另见 @5.4.3 。
5375-() get-current-environment :取当前环境(@5.4.4) :取当前环境的环境弱引用。
5404+() get-current-environment :取当前环境:取当前环境的环境弱引用。
53765405 结果具有宿主值类型 NPL::EnvironmentReference 。派生需要非派生实现的 vau/e 。
53775406 () lock-current-environment :锁定当前环境:取当前环境的环境强引用。
53785407 结果具有宿主值类型 shared_ptr<Environment> 。
@@ -5388,13 +5417,13 @@
53885417 idv <object> :同 id ,但结果为返回值转换(@5.7.4.4) 后的值。
53895418 list <object>... :创建列表(类型为 <list> )对象。
53905419 list% <object>... :同 list ,但每个参数都不隐含左值到右值转换,在结果保留引用值。
5391-$deflazy! <definiend> <expressions> :修改绑定。
5420+$deflazy! <definiend> <body> :修改绑定。
53925421 同 $def! ,但不求值参数;在添加绑定前仍对冻结环境进行检查(@10.5.6) 。
5393-$set! <environment> <formals> <expressions> :修改指定环境的变量绑定。
5394-在当前环境求值 <environment> 和 <expressions> ,再以后者的求值结果修改前者的求值结果指定的环境中的绑定。绑定效果同使用 $def!(@10.5.6) 。
5395-类似 Kernel 的 $set! 。注意 <expressions> 的形式不同。允许的递归操作参见 $def! 。
5422+$set! <environment> <formals> <body> :修改指定环境的变量绑定。
5423+在当前环境求值 <environment> 和 <body> ,再以后者的求值结果修改前者的求值结果指定的环境中的绑定。绑定效果同使用 $def!(@10.5.6) 。
5424+类似 Kernel 的 $set! 。注意 <body> 的形式不同。允许的递归操作参见 $def! 。
53965425 和 Kernel 不同而和 NPLA1 的 $def! 等类似,在修改绑定前对冻结环境进行检查。
5397-$setrec! <environment> <formals> <expressions> :修改指定环境的绑定,绑定效果同使用 $defrec!(@10.5.6) 。
5426+$setrec! <environment> <formals> <body> :修改指定环境的绑定,绑定效果同使用 $defrec!(@10.5.6) 。
53985427 同 $set! ,但允许不同的递归操作,参见 $defrec! 。
53995428 $lambda <formals> <body> :创建 λ 抽象(@4.5.2.2) 。
54005429 和创建 vau 抽象类似,但创建的是调用时对操作数的元素求值一次的应用子(@7.6.1.1) ,且忽略动态环境。
@@ -5507,7 +5536,7 @@
55075536 rest& <list> :同 rest ,但在返回的列表值中的元素是引用值,且首先调用 check-list-reference 检查参数是列表引用,对右值的抛出异常。
55085537 rest% <list> :同 rest ,但在返回的列表值中的元素可能是传递的引用值。
55095538 () make-standard-environment 创建标准环境:创建没有其它绑定的环境。
5510-当前环境作为根环境(@10) 作为新创建环境的唯一父环境。类似 Kernel 的 make-standard-kernel-environment 。
5539+根环境是新创建环境的唯一父环境。类似 Kernel 的 make-standard-kernel-environment 。
55115540 box <object> 装箱:构造箱(类型为 <box> 的对象)。
55125541 box% <object> 同 box ,但参数不隐含左值到右值转换,在结果保留引用值。
55135542 box? <object> 判断是否为 <box> 类型的对象。
@@ -5527,14 +5556,16 @@
55275556 否则,值为空列表。
55285557 类似 Kernel 的 assoc ,但使用 eqv? 而不是 equal? ,且转发参数。
55295558 和 Scheme 的 assv 类似,但失败的值不返回 #f ,尽管和 Kernel 相同而和 Scheme 不同,<test> 支持非布尔类型的值(@10.5.3) 。
5530-$let <bindings> <body> :局部绑定求值。
5559+derive-current-environment <environment>... :创建当前环境的派生环境。
5560+创建参数指定的环境和当前环境作为父环境的空环境。
5561+$as-environment <body> :求值表达式构造环境。
5562+创建以动态环境为父环境的空环境,并在其中求值参数指定的表达式。
5563+结果是创建的环境强引用。
5564+$let <bindings> <body> :局部绑定求值:创建以当前环境为父环境的空环境,在其中添加 <bindings> 指定的变量绑定,再求值 <body> 。
55315565 类似 Kernel 的同名操作,但返回非引用值(@9.6.1.4) 。
5566+创建的环境同合并子的局部环境(@8.4.5) 。
55325567 $let% <bindings> <body> :同 $let ,但保留引用值。
55335568 当前派生使用 $lambda% 而不是 $lambda 实现。
5534-$let/d <bindings> <eformal> <body> :同 $let ,但在 <body> 的求值前引入绑定到动态环境的变量 <eformal> 。
5535-若 <eformal> 为 #ignore ,作用同 $let 。
5536-$let/d% <bindings> <eformal> <body> :同 $let/d% ,但保留引用值。
5537-若 <eformal> 为 #ignore ,作用同 $let% 。
55385569 $let/e <environment> <bindings> <body> :指定静态环境并局部绑定求值。
55395570 类似 Kernel 的 $let-redirect ,但使用 $lambda/e 而不是 eval 和 $lambda 实现,并返回非引用值。
55405571 这允许传递引用值并保证环境的宿主值类型(包含所有权)被正确传递作为求值的父环境,而无需支持扩展 <environment> 为右值时其中的环境临时对象的生存期。
@@ -5549,20 +5580,21 @@
55495580 和 $let 及 $let* 不同,操作保证使用同一环境,因此可配合 lock-current-environment 传递具有所有权的环境。
55505581 $letrec% <bindings> <body> :同 $letrec ,但保留引用值。
55515582 注意以上 $let 等函数的 <body> 形式和 Kernel 不同。
5552-$bindings/p->environment (<environment>...) <binding>... :转换绑定列表为以指定的环境列表为父环境的环境。
5553-类似 Kernel 的 $binding->environment ,但指定父环境具有适当的所有权。
5583+$bindings/p->environment (<environment>...) <binding>... :转换绑定列表为以指定的环境列表中的环境为父环境的具有这些绑定的环境。
5584+类似 Kernel 的 $binding->environment ,但指定父环境,且具有适当的所有权。
55545585 使用 make-environment 而不是 $let/e 等绑定构造实现。
5555-$bindings->environment <binding>... :转换绑定列表为以标准环境为父环境的环境。
5586+$bindings->environment <binding>... :转换绑定列表为没有父环境的具有这些绑定的环境。
55565587 类似 Kernel 的同名操作,但因为要求对内部父环境环境所有权,使用 $binding/p->environment 而不是 $let/e 等绑定构造实现。
5557-$provide! <symbols> <body> :求值第二参数并在当前环境绑定结果到第一参数指定的符号。
5558-结果是对这些绑定具有所有权的环境。
5559-类似 Kernel 的同名操作,但返回创建的局部环境(@8.4.5) 的强引用。
5588+$provide/let! <symbols> <bindings> <body> :在当前环境中提供绑定:蕴含 $let <bindings> <body> ,在求值 <body> 后以结果作为操作数绑定到 <symbols> 的符号。
5589+<symbols> 应能被作为 <defindend> 使用。
5590+结果是对这些绑定具有所有权的环境强引用。
55605591 绑定后的符号可通过作为 vau 抽象的父环境(@9.6.2.1) 等形式依赖这个环境,因此用户需适当保存返回值使其生存期(@9.6.2.1) 覆盖在被使用的绑定符号指称的对象生存期。
5561-$provide/d! <symbols> <eformal> <body> :同 $provide! ,但在 <body> 的求值前引入绑定到动态环境的变量 <eformal> 。
5562-若 <eformal> 为 #ignore ,作用同 $provide! 。
5592+$provide! <symbols> <body> :在当前环境中提供绑定:同 $provide/let! 但不指定单独的 <bindings> 。
5593+作用同 <bindings> 为空列表的 $provide/let! 。
5594+类似 Kernel 的同名操作,但结果是创建的环境的强引用。
55635595 $import! <environment> <symbols> :从第一参数指定的环境导入第二参数指定的符号。
55645596 类似 Kernel 的同名操作。
5565-nonfoldable? <list> :判断参数是否不可被继续折叠映射:存在空表。
5597+nonfoldable? <list> :判断参数是否不可被继续折叠映射:存在空列表。
55665598 输入类似 Kernel map 操作可接受的列表参数或空列表。若输入是空列表,结果为 #f 。
55675599 list-extract <list> <applicative> :以指定应用子在指定列表中选取并合并内容为新的列表。
55685600 对参数列表 (&l &extr) ,结果同求值 accr l null? () ($lambda% (&l) forward-list-first% expire extr l) rest% cons% 。
@@ -5580,9 +5612,9 @@
55805612 类似 Kernel 的 for-each 但支持空的 <list> 且保证顺序。
55815613
55825614 @11 NPLA1 参考实现扩展环境:
5583-和 @10.5 和 @10.6 类似,NPLA1 以根环境的形式提供其它一些模块的操作。
5615+和 @10.5 和 @10.6 类似,NPLA1 以根环境的形式提供其它一些模块(@10.1) 的操作。
55845616 因为可移植性和模块化等原因,这些操作不直接引入基础上下文(@8.5.2) 的根环境中。
5585-这允许实现使用特殊的环境子类型延迟加载(当前 NPLA1 没有提供支持)。
5617+这允许实现使用特殊的环境子类型延迟加载(@10.1.1)(当前 NPLA1 没有提供支持)。
55865618 这也允许作为实现的用户程序可选地支持这些操作。作为被加载的模块的环境的名称由具体用户程序决定。
55875619 修改(@9.4.5.1) 这些环境的程序行为未定义。
55885620 默认加载使用 . 分隔标识符得到的符号作为名称,类似 CHICKEN Scheme 的转换 R7RS 的标准模块名(参见 http://wiki.call-cc.org/eggref/4/r7rs#import )。
@@ -5612,9 +5644,9 @@
56125644 <promise> :求值代理:表示可被求值的封装结果。
56135645 除 $laze/e 外,同 [RnRK] 的 promises 模块,但当前不支持 PTC(@9.4.8) 。
56145646 promise? <object> :判断是否为 <promise> 类型的对象。
5615-memoize <expressions> :记忆化求值。
5616-$lazy <expressions> :创建 promise 对象,延迟求值。
5617-$lazy/e <environment> <expressions> :同 $lazy ,但以指定环境替代动态环境。
5647+memoize <object> :记忆化求值。
5648+$lazy <body> :创建 promise 对象,延迟求值。
5649+$lazy/e <environment> <body> :同 $lazy ,但以指定环境替代动态环境。
56185650 force <promise> :立即求值指定的 promise 对象。
56195651
56205652 @11.3 字符串:
@@ -5637,12 +5669,15 @@
56375669 puts <string> :输出字符串(视为 NTCTS(@5.11.1) )和换行并刷新缓冲。
56385670 实现使用 REPLContext::GetOutputStreamRef(@7.8.1) 。
56395671 在使用前,一般应初始化 REPLContext::OutputStreamPtr(@7.8.1) 指向特定的 std::ostream 对象;否则,总是失败引发错误。
5640-load <string> :加载参数指定的翻译单元。
5641-当前实现中的参数为文件系统路径。
5672+load <string> :加载参数指定的翻译单元作为源的模块(@10.1.1) 。
5673+加载时创建新环境(@9.6.2) ,以此为当前环境读取翻译单元后求值,以求值后的这个环境对象作为调用的结果。
5674+当前实现中,参数为文件系统路径。
56425675 被加载的翻译单元视为对象的外部表示(@4.1.1) ,经读取翻译为 NPLA1 对象。
5643-类似 klisp 的同名操作,但不使用 find-required-filename 机制,直接以宿主的运行环境为基准使用路径。
5676+类似 klisp 的同名操作。类似地,不使用 klisp 的 find-required-filename 机制,直接以宿主的运行环境为基准使用路径。
56445677 和 klisp 不同,在尾上下文中求值被加载后读取的对象,并以其求值结果作为表达式的求值结果。
5645-([Shu09] 缺少 load 的详细描述而仅有标题。)
5678+[Shu09] 缺少 load 的详细描述而仅有标题。
5679+注意 http://klisp.org/docs/Ports.html#Ports 的 load 描述中求值环境有误,按 [Shu09] 一致的描述和实际实现,应为使用当前环境,而非同 [Shu09] 的 get-module 的使用创建的环境(即新环境(@9.6.2) )。
5680+和 [R7RS] 不同,load 不支持指定环境,而总是使用当前环境。类似 Kernel ,当前环境可通过不同机制改变,而不需由 load 提供特设的支持。
56465681
56475682 @11.5 系统:
56485683 通过初始化基础上下文后调用 Forms::LoadModule_std_system(@8.5.2) 初始化,默认加载为根环境下的 std.system 环境。
@@ -5697,7 +5732,7 @@
56975732
56985733 @12.1 NPL::Dependency 派生操作:
56995734 SHBuild 实现环境由 NPL::Dependency 提供初始的派生操作。
5700-在基础上下文(@8.5.2) 上,SHBuild 实现环境通过切换新环境并调用 Forms::LoadModule_SHBuild(@8.5.2) 初始化。
5735+在基础上下文(@8.5.2) 上,SHBuild 实现环境通过切换新环境(@9.6.2) 并调用 Forms::LoadModule_SHBuild(@8.5.2) 初始化。
57015736 SHBuild 的基础环境(@10) 的子环境中提供对象引用 env_SHBuild_ ,其中包含这些接口。
57025737 部分 SHBuild 互操作接口在 YFramework 的 NPLA1 实现中提供,参见 @11.6 。
57035738 此外,NPLA1 在默认实现的 SHBuild_BaseTerminalHook_(@12.1.1) 的实现被覆盖,以使 SHBuild_EchoVar(@12.1.1) 等和 SHBuild 的其它输出兼容。
@@ -5708,7 +5743,7 @@
57085743
57095744 @12.2.1 环境变量缓存:
57105745 脚本缓存环境变量并在访问缓存时可能按外部环境的要求以未指定的方式跟踪环境变量的访问操作。缓存的环境变量的值在第一次访问时确定。
5711-对环境变量的直接访问是使用系统模块(@11.5) 的 env-get、 env-set 和 env-empty? 的访问,忽略缓存的环境变量。直接设置环境变量不更新缓存的值。
5746+对环境变量的直接访问是使用系统模块(@11.5) 的 env-get、env-set 和 env-empty? 的访问,忽略缓存的环境变量。直接设置环境变量不更新缓存的值。
57125747 除非另行指定,访问环境变量使用缓存的环境变量。
57135748 带缓存环境变量的访问接口如下:
57145749 safeenv-get <string> :同 env-get ,但使用缓存。
diff -r a285f6f132e8 -r d1f3d524f742 doc/Workflow.txt
--- a/doc/Workflow.txt Thu Dec 24 12:58:49 2020 +0800
+++ b/doc/Workflow.txt Sat Jan 09 04:33:56 2021 +0800
@@ -1,5 +1,5 @@
11 /*
2- © 2013-2020 FrankHB.
2+ © 2013-2021 FrankHB.
33
44 This file is part of the YSLib project, and may only be used,
55 modified, and distributed under the terms of the YSLib project
@@ -11,13 +11,13 @@
1111 /*! \file Workflow.txt
1212 \ingroup Documentation
1313 \brief 工作流汇总报告。
14-\version r4006
14+\version r4086
1515 \author FrankHB <frankhb1989@gmail.com>
1616 \since build 433
1717 \par 创建时间:
1818 2013-07-31 01:27:41 +0800
1919 \par 修改时间:
20- 2020-12-15 06:00 +0800
20+ 2021-01-08 00:38 +0800
2121 \par 文本编码:
2222 UTF-8
2323 \par 模块名称:
@@ -3994,19 +3994,93 @@
39943994 These include 'SHBuild_BuildApp' and 'SHBuild_BuildPrefix'.
39953995 Now 'SHBuild_BuildDir' is used for all cases (including stage 1).
39963996
3997-$2020-11:
3997+$2020-12:
39983998
39993999 report.impl:
4000-The YSLib builds are revised.
4000+The YSLib build scripts are revised and enhanced.
40014001 'SHBuild-common-options.sh' is simplified by the removal of stage 2 configurations.
40024002 They are still available in %SHBuild-YSLib-common.txt.
40034003 Unused stage 2 configurations are removed.
40044004 Now all NPLA1 build scripts accept 'SHBuild_LDFLAGS' and 'SHBuild_LIBS'.
4005- The library building process in the build script 'SHBuild-YSLib-build.txt' has improved the workarounds.
4006- There is now a warning to indicate the fix of flags is used.
4007- It now detects sanitizers used with Linux G++.
4008- As a workaround for performance, dynamic builds with address sanitizer adds '-fno-var-tracking-assignments'.
4009- It still typically takes more than half an hour, though.
4005+ The build script 'SHBuild-YSLib-common.txt' now detects sanitizers used with Linux Clang++ or G++.
4006+ Supported sanitizers are: ASan (AddressSanitizer), TSan (ThreadSanitizer), MSan (MemorySanitizer), UBSan (UndefinedBehaviorSanitizer) and LSan (LeakSanitizer).
4007+ See https://clang.llvm.org/docs/ and https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html for available options.
4008+ Note G++ has no support of MSan (MemorySanitizer) at current. It requires Clang.
4009+ See also https://gcc.gnu.org/legacy-ml/gcc/2014-10/msg00006.html.
4010+ The sanitizer flags are scanned directly by string pattern matching.
4011+ As usual, the order of options are not assumed. Options to disable sanitizers are not recognized.
4012+ Multiple sanitizer names delimited by ',' for '-fsanitize=' option are supported.
4013+ Not all of them can be used together by design, though. See also https://github.com/google/sanitizers/issues/1039.
4014+ The flags with the old syntax are not supported, as they are not recognized by current versions of Clang++ and G++.
4015+ See https://reviews.llvm.org/rL204330.
4016+ For better effects of the ASan, '-U_FORTIFY_SOURCE -fno-omit-frame-pointer -fno-common' is also added to the compiler option.
4017+ See also https://github.com/google/sanitizers/wiki/AddressSanitizer#faq.
4018+ The support is in the build process. At runtime it would still fail due to bugs in the environment.
4019+ ASan has false positive of ODR uses.
4020+ LSan is known not working at current for stage 2 SHBuild.
4021+ The library building process in the build script 'SHBuild-YSLib-build.txt' has improved the compiler options configuration.
4022+ There is now a warning to indicate some fixes of flags is used.
4023+ As a workaround for performance, libYFramework dynamic builds with sanitizers adds more flags as the workaround.
4024+ The configuration without such flags fix would cause extremely slow compilation for the dynamic release library.
4025+ It also requires a lot of memory. For example, compilation with '-fsanitize=address,undefined' by 'cc1plus' could stops on G++ 10.2.0 tree-ree (Redundant Extension Elimination) pass with a memory allocation failure.
4026+ The real issue is not in the '-O3' path, it also hangs on '-O1' (but not '-O0'), when the address sanitize is used.
4027+ Since tree-ree is disabled in '-O1' (inspected by a call like 'echo "" | g++ -fdump-passes -c -x c++ -'), it should have been gone wrong earlier.
4028+ The '-Q' option shows the problem is in ipa-opt_local_passes.
4029+ G++ 10.2 would crash with segfault on '-fsanitize=undefined -fno-lto' in compiling 'NPLA1Forms.cpp' after several minutes.
4030+ This seems https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97554 and would be fixed in GCC 10.3.
4031+ It is eventually worked around by adding options specific to 'cc1plus'.
4032+ By adding '-fdisable-ipa-opt_local_passes', or more specific '-fdisable-einline', it works.
4033+ Note there is a bug with '-fdump-passes -fdisable-tree-einline': https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82955. This seems work for current Arch Linux's G++.
4034+ This also includes '-fno-lto' to disable LTO for various sanitizers, to prevent long time spent in 'lto1' invocation during linking.
4035+ This should be mostly specific to 'NPLA1Forms.cpp' like the issue in $2020-09 report.impl, although '-fno-var-tracking-assignments' makes no big differences.
4036+ With LTO, the whole compilation still typically takes more than half an hour for other compilation units, though.
4037+ The common stage 1 (shell) build scripts logic is now handled in the script 'Tools/Scripts/SHBuild-YSLib.sh', which was reserved previously.
4038+ This script initializes the common stage 1 build environment by including 'Tools/Scripts/SHBuild-common-toolchain.sh' and providing additional common interface like stage 1 'INCLUDE' variable.
4039+ The stage 1 SHBuild bootstrapping script 'Tools/Scripts/SHBuild-bootstrap.sh' includes this script and it is included by other stage 1 build scripts.
4040+ The test script (now assumely stage 1 only), i.e. 'Test/test.sh', also includes this script.
4041+ Source inclusions and build environment initialization have been cleanup.
4042+ The initialization is for 'SHBuild_Env_*' and 'SHBuild_Host_*' variables, now performed by the call of shell function 'SHBuild_PrepareBuild' provided by 'Tools/Scripts/SHBuild-common.sh'.
4043+ In stage 1, this is mostly done in 'Tools/SHBuild-common-toolchain.sh' since build 904.
4044+ Originally, it was performed by function 'SHBuild_CheckUName' since build 897.
4045+ This is duplicate by clashing with earlier calls in other places (all call 'SHBuild_PrepareBuild' currently):
4046+ In 'Test/test.sh', this was originally done by function 'SHBuild_CheckHostPlatform' since build 740.
4047+ In stage 1 bootstrapping including 'Tools/Scripts/SHBuild-bootstrap.sh' and 'Tools/install-sysroot.sh', this was originally done by 'SHBuild_CheckUName' since build 562.
4048+ The duplication is resolved in different ways.
4049+ The script 'Tools/install-sysroot.sh' now removes the redundant inclusion of 'Tools/Scripts/SHBuild-common-toolchain.sh'.
4050+ This is appropriate since both the builds of stage 1 and stage 2 can handle the toolchain detection in the called script, either by including 'Tools/Scripts/SHBuild-common-toolchain.sh' (stage 1) or using NPLA1 configuration routines (stage 2).
4051+ Other scripts just remove the redundant call of 'SHBuild_PrepareBuild'.
4052+ Now all other scripts use the inclusion from 'Tools/Scripts/SHBuild-bootstrap.sh', which in turn includes the new common piece of code in 'Tools/Scripts/SHBuild-YSLib.sh'.
4053+ Note this is not directly needed in 'Test/test.sh' as neither 'SHBuild_Env_*' nor 'SHBuild_Host_*' variables are explicitly used.
4054+ This is also not needed in non-stage 1 build scripts, but there are no duplicated initializations and it can be required in future (e.g. cross compilation). Thus, no changes are for non-stage 1 scripts.
4055+The remained scripts '3rdparty/freetype/builds/build-ds.sh' and 'doc/doxygen-cjk.sh' are revised and checked by ShellCheck according to the requirements on https://frankhb.github.io/YSLib-book/Development.zh-CN.html.
4056+
4057+$2021-01:
4058+
4059+report.impl:
4060+NPLA1 interface for local bindings and modules are revised.
4061+ The operative '$provide/d!', '$let/d' and '$let/d%' are removed.
4062+ The dynamic environment denoted by the environment formal parameter is generally discouraged, because the dynamic environment may have other bindings initialized later, and relying on such bindings is often error-prone, esp. for long bodies.
4063+ Using of the statically derived environments (e.g. the standard enviornment) instead as the static environment of the exported functions in the body is generally more encouraged.
4064+ If the dynamic environment is needed indeed, it can be easily worked around.
4065+ Since the environment is local to the binding clauses and the bound expressions in the clauses will be always evaluated, it is easy to specify the dynamic environment in the bindings clause.
4066+ For example, a '() get-current-environment' should generally be enough.
4067+ This is different to operative constructors like '$vau'.
4068+ Dynamic environment is necessary to operatives in general, even though the caveats on the use of the dynamic environments still apply.
4069+ It is not optional for all such operative constructors.
4070+ There should be some place to get the binding of the dynamic environment in some operative contructors.
4071+ Operatives cannot rely on the dynamic environment available from the evaluation by the operative calls.
4072+ That is, operand like '() get-current-environment' cannot be in the parameter tree, because it will remain unevaluated if the operative is not wrapped.
4073+ Obviously it cannot be in the body, either.
4074+ There is no other room for such an operand to go, so the environment formal parameter is eventually needed.
4075+ Mapping between modules and environments for loaded modules has been clearified.
4076+ There is no guarantee of one-to-one mapping, even though it often is the case.
4077+ The stability of the environments for loaded modules is now explicitly required.
4078+ This is in alignment to the applicative 'get-module' in [RnRK],
4079+ The stability in 'get-module' is get by a fresh environment made by 'make-kernel-standard-environment' as the parent.
4080+ This is also similar to '$let-safe' in [RnRK], though '$let-safe' is not specific to module interface.
4081+ A bug of wrong parent environment used in the constructed environment is fixed in the core library operative '$bindings->environment'.
4082+ The operative now correctly used the fresh environment without parents instead.
4083+ This is also consistent to the environments vs. modules definitions (requires a standard environment for the latter ones).
40104084
40114085 ////
40124086
diff -r a285f6f132e8 -r d1f3d524f742 doc/doxygen-cjk.sh
--- a/doc/doxygen-cjk.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/doc/doxygen-cjk.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,15 +1,32 @@
1-#!/bin/bash
2-doxygen -w latex header.tex0 footer.tex0 stylesheet.tex0 ../Doxyfile
3-cat header.tex0 | awk '{print;}
4- /\\usepackage{doxygen}/{print("\\usepackage{CJK}")} /\\begin{document}/{print("\\begin{CJK}{UTF8}{gbsn}")}' > header.tex
5-sed -ie "s/YSTest/Reference Manual/" header.tex
6-cat footer.tex0 | awk '{print;}/\\printindex/{print("\\end{CJK}")}' > footer.tex
1+#!/usr/bin/env bash
2+# (C) 2013, 2021 FrankHB.
3+# Doxygen script for LaTeX with CJK contents (expermental, untested).
4+# Requires: Doxygen. LaTeX enabled in Doxyfile. External LaTeX packages.
5+# Arch Linux packages texlive-most texlive-lang should work.
6+
7+set -e
8+
9+: "${SHBuild_ToolDir:=\
10+$(cd "$(dirname "${BASH_SOURCE[0]}")/../Tools/Scripts"; pwd)}"
11+: "${YSLib_BaseDir:="$SHBuild_ToolDir/../.."}"
12+YSLib_BaseDir=$(cd "$YSLib_BaseDir"; pwd)
13+YSLib_DocDir=$(cd "$YSLib_BaseDir/doc"; pwd)
14+
15+# shellcheck source=../Tools/Scripts/SHBuild-common.sh
16+. "$SHBuild_ToolDir/SHBuild-common.sh" # for SHBuild_Pushd, SHBuild_Popd,
17+
18+(cd "$YSLib_BaseDir" && doxygen -w latex "$YSLib_DocDir/header.tex0" \
19+"$YSLib_DocDir/footer.tex0" "$YSLib_DocDir/stylesheet.tex0" Doxyfile)
20+
21+SHBuild_Pushd "$YSLib_DocDir"
22+< header.tex0 awk '{print;}
23+/\\usepackage{doxygen}/{print("\\usepackage{CJK}")} /\\begin{document}/{print("\\begin{CJK}{UTF8}{gbsn}")}' \
24+> header.tex
25+sed -ie "s/Your title here/YSTest Reference Manual/" header.tex
26+< footer.tex0 awk '{print;}/\\printindex/{print("\\end{CJK}")}' > footer.tex
727 rm stylesheet.tex0
8-pushd ..
9-doxygen Doxyfile
10-popd
11-pushd latex
12-make
13-popd
28+(cd "$YSLib_BaseDir" && doxygen Doxyfile)
29+(cd latex && make)
1430 rm header.tex* footer.tex*
31+SHBuild_Popd
1532
diff -r a285f6f132e8 -r d1f3d524f742 test/test.sh
--- a/test/test.sh Thu Dec 24 12:58:49 2020 +0800
+++ b/test/test.sh Sat Jan 09 04:33:56 2021 +0800
@@ -1,13 +1,12 @@
11 #!/usr/bin/env bash
2-# (C) 2014-2017, 2020 FrankHB.
2+# (C) 2014-2017, 2020-2021 FrankHB.
33 # Script for testing.
44 # Requires: G++/Clang++, Tools/Scripts, YBase source.
55
66 set -e
7+
78 : "${SHBuild_ToolDir:=\
89 $(cd "$(dirname "${BASH_SOURCE[0]}")/../Tools/Scripts"; pwd)}"
9-: "${YSLib_BaseDir:="$SHBuild_ToolDir/../.."}"
10-YSLib_BaseDir=$(cd "$YSLib_BaseDir"; pwd)
1110
1211 # XXX: Following variables are internal.
1312 # shellcheck disable=2034
@@ -15,32 +14,22 @@
1514 # shellcheck disable=2034
1615 SHBuild_Debug=debug
1716
18-# shellcheck source=../Tools/Scripts/SHBuild-common-options.sh
19-. "$SHBuild_ToolDir/SHBuild-common-options.sh" # for SHBuild_PrepareBuild,
20-# SHBuild_GetBuildName, SHBuild_Pushd, SHBuild_Popd, SHBuild_CheckPCH,
21-# SHBuild_Puts and build options.
22-
23-INCLUDE_PCH="$YSLib_BaseDir/YBase/include/stdinc.h"
24-INCLUDES="-I$YSLib_BaseDir/YFramework/include \
25--I$YSLib_BaseDir/YFramework/Android/include \
26--I$YSLib_BaseDir/YFramework/DS/include \
27--I$YSLib_BaseDir/YFramework/Win32/include \
28--I$YSLib_BaseDir/3rdparty/include \
29--I$YSLib_BaseDir/YBase/include \
30-"
17+# shellcheck source=../Tools/Scripts/SHBuild-YSLib.sh
18+. "$SHBuild_ToolDir/SHBuild-YSLib.sh" # for YSLib_BaseDir, SHBuild_GetBuildName,
19+# SHBuild_Pushd, SHBuild_S1_InitializePCH, CXXFLAGS, LDFLAGS, INCLUDES,
20+# SHBuild_Popd;
3121
3222 LIBS="$YSLib_BaseDir/YBase/source/ystdex/cassert.cpp \
3323 $YSLib_BaseDir/YBase/source/ystdex/cstdio.cpp \
3424 $YSLib_BaseDir/YBase/source/ytest/test.cpp \
3525 "
3626
37-SHBuild_PrepareBuild
3827 TestDir="$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)"
3928 Test_BuildDir="$YSLib_BaseDir/build/$(SHBuild_GetBuildName)/.test"
4029 mkdir -p "$Test_BuildDir"
4130 SHBuild_Pushd "$Test_BuildDir"
4231
43-SHBuild_CheckPCH "$INCLUDE_PCH" "stdinc.h"
32+SHBuild_S1_InitializePCH # for SHBuild_IncPCH.
4433
4534 # XXX: Value of several variables may contain whitespaces.
4635 # shellcheck disable=2086,2154
Show on old repository browser