summaryrefslogtreecommitdiffstats
path: root/share
Commit message (Collapse)AuthorAgeFilesLines
* Fix struct lit problem exposed by circular syntax.Kaz Kylheku2016-10-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The semantics of how struct literals come to life is poorly designed: namely, the slot-value pairs in the struct literal are used as the plist argument in a call to make-struct. This is wrong because the implied initializations are then clobbered by the structure type's :init and :postinit handlers, resulting in an object with slot values that don't match what is in the literal. When you add circular syntax to the mix, things get worse. Slots may be initialized with (sys:circ-ref ...) expressions corresponding to #<n># syntax. These expressions then get clobbered by the constructor actions before the circ_backpatch processes the syntax. * parser.y (struct): Use make_struct_lit rather than make_struct to instantiate struct object. * struct.tl (sys:struct-lit): Expand to a form which calls sys:make-struct-lit, rather than make-struct. * struct.c (struct_init): Register new make_struct_lit function as sys:make-struct-lit intrinsic. (make_struct_lit): New function. * struct.h (make_struct_lit): Declared. * tests/012/struct.tl: struct literal expansion test case updated. * txr.1: Updated documentation of struct literals. Added compat notes.
* Cycle detection in sys:cp-origin.Kaz Kylheku2016-10-191-9/+13
| | | | | | | | | | | | | | | Tree-walking code in the place expander runs into trouble if the expression contains cycles. Test case: (defparm a '(#1=(a . #1#))). * share/txr/stdlib/place.tl (sys:cp-origin): Take list of symbols as a single argument instead of trailing arguments. Support an optional argument that gives serves as a cycle-detecting stack. Bail if a cycle is detected. (call-udpate-expander, call-clobber-expander, call-delete-expander): Update sys:cp-origin calls to follow interface change.
* Bugfix: unable to assign to x.y.z place.Kaz Kylheku2016-10-151-4/+1
| | | | | | | | | | | | | | | | | | | This regression was caused by commit 957f80f "Bugfix: issue with expansion of place macros" on Sep 7, 2016. The commit itself is sound, but exposes a hidden problem in nearby code. * share/txr/stdlib/place.tl (sys:pl-expand): The conditions for terminating the loop and returning the expansion are too weak, due to the inclusion of an incorrect test. We must not bail when the expansion of a compound form is a compound form with the same symbol. This is because some macros behave that way, such as, oh: qref! The expansion of (qref a b c) is (qref (slot a 'b) 'c): another qref form. To fully expand, we must keep iterating until the returned form is eq to the input form. The original macroexpand (which was replaced by macroexpand-1 in 957f80f) hid this problem because macroexpand doesn't use this broken termination test.
* Version 154.txr-154Kaz Kylheku2016-10-151-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* Adding family slot to socket addresses.Kaz Kylheku2016-10-131-4/+8
| | | | | | | | | | | | | | | A static slot indicating the address family simplifies code which wants to map a socket address to its family. * lisplib.c (sock_instantiate): Call sock_load_init before loading socket.tl rather than after, because socket.tl now references variables defined inside sock_load_init. * share/txr/stdlib/socket.tl (sockaddr, sockaddr-in, sockaddr-in6, sockaddr-un): New static slot, family. * txr.1: Documented family slots.
* New accessor: hash-userdata.Kaz Kylheku2016-10-121-0/+12
| | | | | | | | | | | | | | The get-hash-userdata function is now deprecated in favor of hash-userdata, which is an accessor. * hash.c (hash_init): Register hash-userdata as a synonym for the same function as get-hash-userdata. * share/txr/stdlib/place.tl (hash-userdata): New defplace. * txr.1: Document new accessor, marking get-hash-userdata as a deprecated synonym. Replace references to get-hash-userdata with references to hash-userdata.
* Support curried args in method and meth.Kaz Kylheku2016-10-091-2/+2
| | | | | | | | | | | | | | | | | | | | | * share/txr/stdlib/struct.tl (meth): Take trailing arguments and pass them down to method, which now accepts them. * struct.c (struct_init): Register method intrinsic to the function method_args instead of the method function. (method_args_fun): New static function. (method_args): New function. Behaves like method function if args is empty, otherwise creates a function by means of method_args_fun. * struct.h (method_args_fun): Declared. * tests/012/oop.tl: New test case. * tests/012/oop.expected: Updated. * txr.1: Documented new features in method and meth, revising the documentation in the process.
* Support curried arguments in umethod and umeth.Kaz Kylheku2016-10-091-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | * share/txr/stdlib/struct.tl (umeth): accept variadic arguments. Evaluate them using the dwim brackets and pass to umethod. The (fun umethod) trick is used to refer to the umethod in the function namespace even if it is shadowed by a variable. * struct.c (struct_init): Update registration of umethod to reflect its new variadic argument signature. (umethod_args_fun): New static function. (umethod): Return a function based on umethod_fun, as before, if there are no variadic args. Otherwise, use umethod_args_fun which deals with them. * struct.h (umethod): Declaration updated. * tests/012/oop.tl: Modest testcase for umeth with curried argument. * tests/012/oop.expected: Updated. * txr.1: Updated documentation of umeth and umethod.
* Version 153.txr-153Kaz Kylheku2016-10-071-1/+1
| | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise.
* Version 152.txr-152Kaz Kylheku2016-10-041-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* New awk clauses :set and :set-file.Kaz Kylheku2016-10-041-0/+2
| | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-expander): Recognize :set and :set-file cases. * txr.1: Documented :set and :set-file, replacing some :begin uses with :set in the examples.
* Synchronize license comments with LICENSE.Kaz Kylheku2016-10-0117-272/+289
| | | | | | | | | | | | | | | | | | | | * Makefile, args.c, args.h, arith.c, arith.h, cadr.c, cadr.h, combi.c, combi.h, configure, debug.c, debug.h, eval.c, eval.h, filter.c, filter.h, ftw.c, ftw.h, gc.c, gc.h, glob.c, glob.h, hash.c, hash.h, jmp.S, lib.c, lib.h, lisplib.c, lisplib.h, match.c, match.h, parser.c, parser.h, parser.l, parser.y, rand.c, rand.h, regex.c, regex.h, share/txr/stdlib/awk.tl, share/txr/stdlib/build.tl, share/txr/stdlib/cadr.tl, share/txr/stdlib/conv.tl, share/txr/stdlib/except.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/path-test.tl, share/txr/stdlib/place.tl, share/txr/stdlib/socket.tl, share/txr/stdlib/struct.tl, share/txr/stdlib/termios.tl, share/txr/stdlib/txr-case.tl, share/txr/stdlib/type.tl, share/txr/stdlib/with-resources.tl, share/txr/stdlib/with-stream.tl, share/txr/stdlib/yield.tl, signal.c, signal.h, socket.c, socket.h, stream.c, stream.h, struct.c, struct.h, sysif.c, sysif.h, syslog.c, syslog.h, termios.c, termios.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Revert to verbatim 2-Clause BSD.
* Revision of static slot inheritance.Kaz Kylheku2016-09-301-7/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixing the broken static slot handling in TXR Lisp's "OOP structs" object system. Inherited static slots are now shared with the base type; only static slots explicitly defined in a derived type have a distinct global instance in that type. * share/txr/stdlib/struct.tl (sys:prune-nil-inits): Function removed. (sys:prune-missing-inits): New function. We now handle static slot forms with missing inits specially, not those with nil or missing inits. (defstruct): Translate a (word name) form to (word name) rather than (word name nil) if word is :static, because we need this nuance for non-shared static slots, so they can inherit the value from the base struct. For the purposes of generating the static init function, prune away all the static slot forms that do not have an initializer; we let those default. * struct.c (struct stslot): New struct for representing a static slot. (stslot_loc, stslot_place): New macros. (struct struct_type): Member eqmslot changes to a pointer to a struct stslot. The stslot dynamic array is no longer an array of val, but an array of stslot structs. (call_stinitfun_chain): The superclass chain of static init functions is now called only in compatibility mode. Otherwise only the type's own static init fun is called, which defclass uses to initialize just the new or repeated static slots. Inherited static slots are completely left alone; they do not require initialization. (static_slot_home_fixup): New static function; needed to fix some internal pointers within the static slot arrays if they are realloc'ed. (make_struct_type): Considerably revised to implement new scheme, while providing backward compatibility switching. New slots live in the struct stslot in which they are allocated. Inherited slots have home pointers to within the array in the base. (struct_type_mark): When walking the static slots, mark only the store cells of those which live in this array. Those that live elsewhere should have store cells that are nil; let's assert on it. (lookup_slot): Static slot lookup code has to retrieve slots in the new way, indirecting through the home pointer, which is hidden behind the stslot_loc macro. (lookup_static_slot_desc): New function, like lookup_static_slot, but returning a pointer to the struct stslot. Formed from the guts of lookup_static_slot. (lookup_static_slot): Gutted and turned into a wrappar around lookup_static_slot_desc. (static_slot_set): Simple change here: add cast because of the pointer type of eqmslot. (static_slot_home_fixup_rec): New static function. Fixes up the cached home in slot arrays in an entire type hierarchy rooted at a given type, which has to be done when its static slot has been reallocated, so all those inherited static slot pointers in the derived types are invalid. (static_slot_rewrite_rec): New static function: rewrites a particular inherited static slot in an inheritance hierarchy to point to a different slot. (static_slot_ens_rec): New static function: factored out recursive logic of static_slot_ensure. Substantially rewritten to handle new static slot scheme, plus support backward compatibility. There is a bug fixed here: if an instance slot is encountered in the no_error_p mode, it looks like we were dereferencing through an invalid ptr through the set(ptr, newval) line. (static_slot_ensure): A wrapper now for static_slot_ens_rec. (get_equal_method): Rework the logic related to the eqmslot member of the struct_type structure, in terms of it being a pointer now rather than an integer. The value -1 cast to a pointer serves the previous -1 sentinel value which indicates that it is confirmed (for the time being) that this type doesn't have an equal method. * txr.1: All documentation related to static slots updated, and compatibility notes added. * tests/012/oop.tl, tests/012/oop.expected: New files.
* Version 151.txr-151Kaz Kylheku2016-09-271-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* awk macro: code formatting.Kaz Kylheku2016-09-251-4/+4
| | | | | * share/txr/stdlib/awk.tl (awk): Fix indentation in two places.
* awk macro: proper fs semantics in paragraph mode.Kaz Kylheku2016-09-251-13/+27
| | | | | | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state): New slots: par-mode, par-mode-fs, par-mode-prev-fs. (sys:awk-state rec-to-f): In paragraph mode, detect that fs has changed since the last call. In that case, take the user's fs and add to it a newline match. If it is a regex, take the source, add the syntax and recompile the regex. If it's a string, build regex around it and compile. (sys:awk-state loop): Maintain the par-mode-t variable in the state structure as the rs value triggers transitions into or out of paragraph mode. * txr.1: Updated documentation for rs.
* awk macro: support paragraph mode.Kaz Kylheku2016-09-251-9/+22
| | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state loop): If the rs variable is nil, provide a record reader which reads paragraphs, like under Awk's paragraph mode when RS is blank. This does not support the requirement that newline is always a field separator, regardless of the value of FS. * txr.1: Documented paragraph mode.
* awk macro: loop uses closure to read records.Kaz Kylheku2016-09-251-23/+27
| | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state loop): Refactor code so that record-processing loop obtains a lambda which is called to extract a record. If rs and krs did not change, then the same lambda is obtained from a variable which caches it. The get-rec-reader local function thus encapsulates the whole record delimiting strategy as well as changes to the variables. With this structure, it will be relatively easy to add support for Awk's paragraph mode, which is notably missing in the implementation.
* awk macro: handle dynamic changes in rs variable.Kaz Kylheku2016-09-251-20/+28
| | | | | | | | * awk.tl (sys:awk-state loop): The loop now notices when rs or krs changes and switches to a new record-adapter or to the raw stream as necessary. * txr.1: Notes added about changes to rs and krs.
* awk macro: add orec variable.Kaz Kylheku2016-09-241-2/+4
| | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state): New slot, orig-rec. (sys:awk-state loop): Initialize orig-rec after reading each record. (sys:awk-let): Provide orec symbol macro. * txr.1: Document orec variable.
* awk macro: use range test logic for clause conditions.Kaz Kylheku2016-09-241-4/+5
| | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:range-test): Function renamed to sys:awk-test, since it's not just for ranges. (sys:awk-let): Uses of sys:range-test follow rename. sys:awk-test introduced into expansion of cond parts of cond-action clauses. * txr.1: Documented new behavior (conditions can produce a function or regex, which is implicitly invoked on rec).
* awk macro: exit if no cond-action clauses.Kaz Kylheku2016-09-241-12/+14
| | | | | | | | * share/txr/stdlib/awk.tl: If there are no cond-action clauses in the macro, do not generate the main record processing lambda, or the begin-file and end-file lambdas, and do not generate the call to the awk state object's loop method.
* awk macro: fconv conversions iz, xz, oz, bz and rz.Kaz Kylheku2016-09-241-1/+11
| | | | | | | * share/txr/stdlib/conv.tl (sys:conv-let): New flets iz, oz, xz, bz and rz. * txr.1: Documented under fconv.
* awk macro: support regexes better in ranges.Kaz Kylheku2016-09-231-4/+14
| | | | | | | | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-compile-time): New slot, rng-rec-temp. Specifies the name of a temporary variable which is scoped over the evaluation of ranges, and which caches a reference to the current record string. (sys:range-test): New function. (awk:let): Rename the original rng macrolet to sys:rng, and introduce rng as a wrapper around it which inserts the logic for calling the regex or function that might emerge from the evaluation of from-expr or to-expr. (awk): If ranges are present in the syntax, then bind the temporary variable which caches the record around the evaluations of the ranges. * txr.1: Document new special behavior of rng w.r.t functions and regexes. Add admonition against modifying rec and some other awk variables from range expressions.
* Use rlet in a few place macros for better code.Kaz Kylheku2016-09-211-3/+3
| | | | | | * share/txr/stdlib/place.tl (pset, push, pushnew): Use rlet for binding the assigned or pushed value to a temporary, so the temporary can disappear if the value is a constant.
* Fix broken sys:rslot place.Kaz Kylheku2016-09-211-4/+4
| | | | | | | | | | | | This is used in the awk macro. Breaking test case is an update modification of f, like (push 3 f); a broken call to sys:rslotset is generated with a too few arguments. * share/txr/stdlib/struct.tl (defplace sys:rslot): Fix name clash between gensym and parameter. Add the meth-slot-sym parameter into the sys:rslotset call where it is missing as a required parameter.
* awk macro: streamline field splitting.Kaz Kylheku2016-09-211-13/+7
| | | | | | | | | * share/txr/awk.tl (sys:awk-state rec-to-f): Check for empty record only in the fs case; it's not necessary when tokenizing with ft. Check (not self.kfs) first, since it's the common case. Handle default case (no fs or ft) using tok-str using the regex #/[^ \t\n]+/, which requires no trim-str and no empty record check.
* New library feature: imperative list building.Kaz Kylheku2016-09-201-0/+85
| | | | | | | | | | | * lisplib.c (build_set_entries, build_instantiate): New static functions. (dlt_register): Register dynamic loading of build.tl via the two new functions. * share/txr/stdlib/build.tl: New file. * txr.1: Documented everything.
* Version 150.txr-150Kaz Kylheku2016-09-181-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* New awk operator: fconv.Kaz Kylheku2016-09-182-1/+88
| | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-let): Add new symbol macro, fconv. * share/txr/stdlib/conv.tl: New file. * txr.1: Documented fconv.
* New awk variable: krs.Kaz Kylheku2016-09-171-3/+6
| | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state): New slot, krs. (sys:awk-state loop): Use record-adapter if krs is true, even if the default fs is in effect. Pass value of krs to record-adapter function. (sys:awk-let): Provide krs "awk variable" symbol macro. * txr.1: Documented krs. Clarified semantics of rs being those of both separation and termination.
* New awk variables: ft and kfs.Kaz Kylheku2016-09-161-5/+12
| | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state): New slots, ft and kfs. (sys:awk-state rec-to-f): Implement ft and kfs semantics. (sys:awk-let): Provide ft and kfs as "awk variable" via symbol macros. * txr.1: Documented ft and kfs.
* awk macro: don't bind *stdout* if :output missing.Kaz Kylheku2016-09-141-1/+2
| | | | | | | | * share/txr/stdlib/awk.tl (awk): Bind *stdout* only if awc.output is not nil; i.e. :output has been specified (with a non-nil argument). * txr.1: Revised :output documentation.
* New place-mutating macro: upd.Kaz Kylheku2016-09-141-0/+5
| | | | | | | | * lisplib.c (place_set_entries): Add upd to the auto-load list for place.tl. * share/txr/stdlib/place.tl (upd): New macro. * txr.1: Documented.
* Version 149.txr-149Kaz Kylheku2016-09-121-1/+1
| | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * share/txr/stdlib/ver.tl: Likewise. * txr.vim, tl.vim: Regenerated.
* awk macro: revise how implicit block works, and name.Kaz Kylheku2016-09-121-30/+36
| | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-expander): Check that :name designates a symbol, and that it isn't nil. (awk): Move the implicit block to the outermost scope so it encloses all of the clauses. Default to the name awk for the block, rather than nil. * txr.1: Document that the implicit awk block is called awk by default, and that nil is not allowed as a block name.
* awk macro: more Awk-like treatment of prn args.Kaz Kylheku2016-09-121-1/+6
| | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state prn): Use loop instead of simple interpolation, so that we we can individually interpolate each arg into a quasistring. This way if an arg is nil, it turns into nothing rather than the word "nil". * txr.1: Documented this behavior of prn.
* awk macro: fix: rebind *stdout* in broader scope.Kaz Kylheku2016-09-121-2/+2
| | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state loop): Do not bind *stdout* around the call to the main record-processing function. (awk): Re-bind *stdout* around all of the user code, just after the run-time awk state object is constructed. * txr.1: Correct the lies written about :output.
* awk macro: new local macros ff and mf.Kaz Kylheku2016-09-121-1/+7
| | | | | | | * share/txr/stdlib/awk.tl (sys:awk-let): New local macros. * txr.1: Documented.
* awk macro: don't use cat-str to update rec.Kaz Kylheku2016-09-111-1/+1
| | | | | | * share/txr/stdlib/awk.tl (sys:awk-state f-to-rec): Use quasiliteral to combine fields to reconstitute rec; cat-str works only with characters and strings.
* awk macro: field splitting more Awk-like.Kaz Kylheku2016-09-111-6/+14
| | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-state): Initialize fs to nil rather than the default regex. (sys:awk-state rec-to-f): If fs is nil then operate on a version of rec that is filtered through trim-str. Thus fs being nil is like the Awk special case when fs is a space. * txr.1: Description of fs updated.
* Replace some rlet and slet uses with alet.Kaz Kylheku2016-09-111-13/+15
| | | | | | | | | | | * share/txr/stdlib/place.tl (nthcdr): Fix a potentially wrong order of evaluation by using a temporary symbol for the list and using alet. If the list form could potentially modify the index, then we now avoid a bug here. (vecref, chr-str, ref, gethash, slot): Optimise the expansion of these two-expression places using alet. If both expressions are symbols, which is often the case, temporaries are avoided.
* New alet macro.Kaz Kylheku2016-09-111-0/+6
| | | | | | | | | * lisplib.c (place_set_entries): Add alet symbol to autoload list for place.tl. * share/txr/stdlib/place.tl (alet): New macro. * txr.1: Documented alet.
* rlet cleanup: replace safe with let or slet.Kaz Kylheku2016-09-112-70/+70
| | | | | | | | | | | | | * gencadr.txr: Use let instead of useless rlet that will just reduce to let. * share/txr/stdlib/cadr.tl: Regenerated. * share/txr/stdlib/place.tl (sys:var, car, cdr, errno): Replace rlet with slet where safe. (nthcdr): Replace useless let* with let. Replace one safe-looking rlet with slet. (dwim): Replace useless rlet with let.
* awk macro: don't use record stream if rs is "\n".Kaz Kylheku2016-09-111-6/+7
| | | | | | * share/txr/stdlib/awk.tl (sys:awk-state loop): Take input stream directly without a record adapter, if the record separator is the string "\n".
* awk macro: implement :begin-file and :end-file.Kaz Kylheku2016-09-101-32/+53
| | | | | | | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-compile-time): New slots, begin-file-actions and end-file-actions. (sys:awk-state loop): Take two additional functional arguments for the begin file and end file actions, and do the calls in the right places. unwind-protect triggers the end file function. (sys:awk-expander): Parse out :begin-file and :end-file actions. (awk): Generate lambdas for begin-file and end-file actions, if they are defined. Pass these to the loop method. The code is refactored here to do one big sys:awk-let around everything. * txr.1: Documented :begin-file and :end-file, revising the :begin and :end documentation in the process.
* awk macro: move expander values into compile-time struct.Kaz Kylheku2016-09-101-26/+25
| | | | | | | | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-compile-time): New slots: inputs, output, name, lets, begin-actions, end-actions, cond-actions. (sys:awk-expander): Use just one local variable, an awk compile time. Instead of the previous local variables, use the slots of this structure and return just that structure. Note that pattern-actions has been renamed cond-actions. This is per the terminology used in the newly-written documentation. (awk): Adjust to sys:awk-expander returning just the awk compile-time structure. No need to set up numerous locals; just refer to struct.
* awk macro: don't use zap.Kaz Kylheku2016-09-091-1/+1
| | | | | * share/txr/stdlib/awk.tl (sys:awk-state rec-to-f): Don't use zap macro when the return value is not used.
* awk macro: fix buggy range semantics.Kaz Kylheku2016-09-091-5/+9
| | | | | | | | | * share/txr/stdlib/awk.tl (sys:awk-let): The closing expression of an awk range only applies when the range is active. Refactor generated code with local flags to eliminate duplicating the end range expression. Avoid evaluating the start range expression if the range is already active.
* awk macro: better code for rng with placelet.Kaz Kylheku2016-09-091-1/+1
| | | | | | | * share/txr/stdlib/awk.tl (sys:awk-let): Use our wonderful placelet macro instead of symacrolet for binding the flag alias to the flag place. This removes the duplicate evaluations of the slot access.