summaryrefslogtreecommitdiffstats
path: root/tests/011
Commit message (Collapse)AuthorAgeFilesLines
* matcher: bugfix: @nil isn't trivial.Kaz Kylheku2021-01-291-0/+1
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (non-triv-pat-p): Extend sys:var match so (sys:var nil) is identified as trivial. * tests/011/patmatch.tl: Add broken test case fixed by this. This doesn't show up when @nil is used as the only match. It also doesn't show up if @nil is used in a vector or list in a mixture with other operators, because those other ones identify the overall list pattern as non-trivial. None of the occurrences of @nil in the existing test suite, like (@nil @nil @x) tickle the bug.
* matcher: restructuring to fix new broken case.Kaz Kylheku2021-01-281-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This one test case requires restructuring. The handling for the @(or ...) operator is now very different. To support @(or ...), there is now a new variant of the match-guard object called guard disjunction, which contains multiple match-guard chains. Furthermore, the separation between both guard-chain lists and compiled-match having a test expression and variables is being obliterated. For now, what we do is in a :postinit handler on compiled-match, we immediately convert the test-expr, vars and var-exprs slots into a match-guard object, which is placed into the guard-chain, and then we clear these slots. They are now vestigial only and will be removed. * tests/011/patmatch.tl: New test case which shows that (@(or foo bar) ...) does not short immediately short circuit to a failure when the corresponding element is neither foo nor bar. Matching proceeds to the right, wasting cycles and possibly causing errors. * share/txr/stdlib/match.tl (*match-var*): Move to top, above structs. There are some methods which refer to this variable now for throwing internal errors. (guard-disjunction): New object that is compatible with a match-guard, and placed into guard-lists as if it were a match-guard. This handles the bifurcation logic of an OR match. (compiled-match): New :postinit handler converts local vars, var-exprs and test-expr into a match-guard placed into the chain, and then clears these values. The compilation of code is done purely from the guard-chain. (compiled-match get-vars): This method is now complicated due to the guard-disjunction objects, and so uses a helper function called get-guard-values. (compiled-match get-var-exprs): New method accompanying get-vars to get the accompanying init expressions. (compiled-match wrap-guards): Two changes are going on here. One is that the funccion takes on more of the responsibility which was previously carried out by the callers. The callers were interpolating the test-expr and vars from a compiled-match into a piece of code, which was then passed to wrap-guards. Hence the naming: the job was just to wrap some guards. Now, wrap-guards is called just with the body forms, and does all of the work. Secondly, wrap-guards is complicated due to the handling of the guard-disjunction items. Also, there is some case handling to generate better code; we avoid generating an empty (let () ...) and (alet () ...). (compiled-match add-guard-pre, compiled-match add-guards-pre, compiled-match add-guards-post): New methods for adding guards after construction. These interfaces replace hacks of pushing new variables, tweaking the test-expr, or explicitly pushing guards onto the list. (get-guard-values): New function for iterating over a guard-chain, including match-guard and guard-disjunction items, retrieving a particular list-valued slot from each one using the fun argument, and returning a list of all those lists catenated together. (compile-struct-match, compile-vec-match, compile-range-match): Eliminate test-expr, replacing it with the harmless t. (compile-op-match): We don't try to extend the test-expr of the compiled var. Rather we add our guard expressin using the add-guard-pre interface. (compile-dwim-predicate-match): Likewise, and also, we do not calculate the test-expr for the output compiled-match from the constituent match test-exprs. We ignore those and just set the test-expr pat-match.obj-var. The constituent test-exprs have been converted to guard-chain items already, so there is no point in referring to them. (compile-predicate-match): Use add-guard-pre method to add guard instead of pushing it on list. (compile-cons-structure): Eliminate test-expr being calculated from constituent test-exprs, and just stub it out to t. (compile-require-match): Use add-guards-post to push match-guard onto compiled child mach, instead of tweaking its test-expr. (compile-let-match): Oblierate calculation of test-expr from child test-exprs, replacing with t stub. (compile-loop-match): Call wrap-guards in the new way, without generating assignments or test-expr. (compile-parallel-match): This method is removed; there are now separate compile-or-match and compile-and-match methods. (compile-or-match): New method: compiles consitituent expressions, and converts them into multiple guard-chains for a guard-disjunction object. Then wrap-guards will finish the job of emitting the or logic out of those chains. (compile-and-match): This shares some common logic with compile-or-match, but is substantially simpler. Pattern matching is implicitly AND-based: in a pattern, all the sub-patterns have to match. So there isn't much to do beyond just evaluating all the patterns against the same object. They can all be thrown into one combined flat guard chain. (compile-not-match): Adjust to new wrap-guards interface. Nothing left to do here but pass the expression t to it. (copmile-hash-mach): The post-constructon manipulations of the child compiled matches are done with the appropriate add-guards-pre. The test-expr is eliminated, replaced with t. (compile-match): Wire or and and to the new separate methods compile-or-match and compile-and-match. (when-match, if-match, match-case): Simplified due to when-match interface change. The macros depend on a lot less implementation detail now: they bind the required vars and generate the code.
* mather: new bad (@(predicate) @(all ...)) test case.Kaz Kylheku2021-01-271-0/+2
| | | | | * tests/011/patmatch.tl: Predicates must also be tested earlier, as guard conditions.
* matcher: new broken test case: bad order of checks.Kaz Kylheku2021-01-271-0/+2
| | | | | | | * tests/011/patmatch.tl: Even though bar mismatches foo, the second element @(all) is processed and tries to collect the list. This results in an error due to the list being improper.
* matcher: add failing @(or @(and ...)) test.Kaz Kylheku2021-01-271-0/+2
| | | | | | * tests/011/patmatch.tl: It looks like there is still a problem with scoping. An inner x is assigned the correct value, leaving the outer x nil.
* matcher: add failing @(all (@or ...)) test.Kaz Kylheku2021-01-271-0/+3
| | | | | The matcher has a bug: the loop patterns are not collecting the variables from enclosed parallel patterns.
* matcher: allow pat/var argument: @[expr var pat]Kaz Kylheku2021-01-261-0/+8
| | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-dwim-predicate-match): Drop redundant bindable check of sym, since compile-var-match checks this. Support third argument which gives a pattern or variable which captures the value from the predicate function, which might be interesting (not just true/false). * tests/011/patmatch.tl: New tests. * txr.1: Documented.
* doc: add back discussion about (rcons ...) pattern.Kaz Kylheku2021-01-241-0/+3
| | | | | | | * txr.1: Add anote that a pattern a..b matches rcons syntax, and add examples. * tests/011/patmatch.tl: new examples from doc added as tests.
* matcher: rescind support for @(rcons ...) patterns.Kaz Kylheku2021-01-241-0/+9
| | | | | | | | | | | | | | | | | | | | | There is no longer any way to write a @(rcons ...) pattern using the range syntax, so there is no point in supporting that operator. The silly syntax @@a..@b which previously worked was actually due to a mistaken requirement in the parser. * share/txr/stdlib/match.tl (compile-range-match): Function moved closer to compile-atom-match, below compile-vec-match. The argument is now a range object containing patterns, so we pull it apart with from and to. (compile-atom-match): Pass range directly to compile-range-match; no need to construct (rcons ...) syntax. * tests/011/patmatch.tl: Add range tests from documentation and a few others. * txr.1: References to @(rcons ...) pattern scrubbed. One wrong #R pattern example corrected.
* matcher: add optimized special case to hash pattern.Kaz Kylheku2021-01-221-0/+3
| | | | | | | | | | | | | | | | | | This change causes a key-value pattern like (@a @b) to be treated specially when @a already has a binding from a previous pattern. In this case, it behaves like the trivial key case: the value of @a is looked up to try to find a single value. If @a is not bound, then the exhaustive search takes place, using equal equality. * share/txr/stdlib/match.tl (compile-hash-match): Implement special case. (var-pat-p): New function. * tests/011/patmatch.tl: Existing test case now changes value. New test case added. * txr.1: Documented.
* matcher: document hash and some fixes.Kaz Kylheku2021-01-221-0/+3
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-hash-match): Follow rename of is-pattern function to non-triv-pat-p. (is-pattern): Renamed to non-triv-pat-p, to follow terminology in the reference manual. A bug is fixed here: we must recognize cons patterns with operators and variables in the dotted position as non-trivial. * tests/011/patmatch.tl: New hash test case, from doc. * txr.1: Documented hash pattern operator.
* matcher: existing variables in @(all) now backref.Kaz Kylheku2021-01-221-0/+4
| | | | | | | | | | | | | | | | | | This commit fixes the inadequacy that all variables occurring in a pattern under @(all ...) or @(coll ...) are blindly collated into lists, ignoring the fact that they may be previously bound variables that must back-reference and not be colleced into lists (just like in the TXR Pattern language!) * share/txr/stdlib/match.tl (compile-loop-match): Calculate the subset of variables in the pattern that have been freshly bound. Only generate the collection gensyms for those variables and only collect and nreverse those variables. * tests/011/patmatch.tl: Some test cases that backreference into an @(all). * txr.1: Documented.
* matcher: new @(coll) operator.Kaz Kylheku2021-01-211-0/+4
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-loop-match): Implement coll semantics. coll fails if it collects nothing, which uses common logic with all*. We just have to move the flipping of the loop-iterated-var into the match, and not do it unconditionally for every iteration. (compile-match): Hook in the coll operator. * tests/011/patmatch.tl: Test case copied from doc example. * txr.1: Documented.
* matcher: more test cases.Kaz Kylheku2021-01-211-0/+29
| | | | | | * tests/011/patmatch.tl: Add test case matching with two structures in circular relationship, and a loop around match case for various cases involving backreference.
* matcher: matcher: fix broken @(let @a @(some @a)).Kaz Kylheku2021-01-211-0/+2
| | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-parallel-match): Just like what was done in compile-loop-match in the prior commit, we fix the situation here. guard1's guard-expr, in which the matching logic actually happens, becomes the main test-expr. Thus guard1 disappears and guard0 is renamed to the one and only guard. * tests/011/patmatch.tl: Added test case which is fixed by this.
* matcher: fix broken @(let @a @(some @a)) test case.Kaz Kylheku2021-01-211-0/+2
| | | | | | | | | | | | | | | | | | | | | This is caused by the way the loop match compiler moves the matching logic into a guard, which causes a re-ordering of the variable assignments which interferes with backreferencing when @(some) is embedded into a @(let), and probably other situations. The issues is that the backreferencing equal tests can be reordered to occur before the assignment which sets the intial value of the backreferenced variable: cart before the horse kind of thing. * share/txr/stdlib/match.tl (compile-loop-match): Do not add the submatch into the guard sequence. Thus guard1's vars and var-exprs, move into into the main compiled-match, and guard1's guard-expr moves into guard0. Thus guard1 disappears, guard0 becomes guard. * tests/011/patmatch.tl: New test case that is also fixed, and which was not fixed by a different approach to the problem that I scrapped.
* matcher: add failing circular backreferencing test.Kaz Kylheku2021-01-211-0/+4
| | | | | | * tests/011/patmatch.tl: New test showing breakage whereby a variable inside the @(some ...) operator is not able to unify against a surrounding let variable.
* matcher: add another broken test case.Kaz Kylheku2021-01-191-0/+2
| | | | | * tests/011/patmatch.tl: Breaking test case added. The @(some) pattern match has the same vars misalignment problem.
* matcher: add failing test case.Kaz Kylheku2021-01-191-0/+2
| | | | | | * tests/011/patmatch.tl: New weirdly failing test case. The @(and @a @b) is important; if that term is replaced by a simple @a, then the correct datum is bound to c.
* doc: document when-match, if-match and match-case.Kaz Kylheku2021-01-181-0/+14
| | | | | | * tests/011/patmatch.tl: Add match-case test. * txr.1: Document when-match, if-match and match-case.
* matcher: add tests from documentation.Kaz Kylheku2021-01-182-0/+68
| | | | | | * tests/011/patmatch.tl: New file. * tests/011/patmatch.expected: Likewise.
* The code expander becomes a public API.Kaz Kylheku2018-11-021-1/+1
| | | | | | | | | | | | | | | | | | | | | | | The functions sys:expand, sys:expand* and sys:expand-with-free-refs are now in the usr package and documented for public use. * eval.c (eval_init): Move registrations of the symbools expand, expand* and expand-with-free-refs from the system package to the user package. * share/txr/stdlib/awk.tl (sys:awk-mac-let, awk): Uses of sys:expand drop the sys: prefix. * share/txr/stdlib/op.tl (sys:op-alpha-rename): Likewise. * share/txr/stdlib/place.tl (call-upudate-expander, call-clobber-expander, call-delete-expander, sys:placelet-1): Likewise. * tests/011/macros-2.txr, tests/012/struct.tl: Likewise. * txr.1: Documented expand, expand* and expand-with-free-refs.
* printer: improve object formatting.Kaz Kylheku2018-04-051-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There is an issue with the printer in that it produces output whereby objects continue on the same line after a multi-line object, e.g: (foo (foobly bar xyzzy quux) (oops same line)) rather than: (foo (foobly bar xyzzy quux) (oops same line)) There is a simple fix for this: set a flag to force a line break on the next width-check operation whenever an object has been broken into multiple lines. width-check can return a Boolean indication whether it generated a line break, and so aggregate object printing routines can tell whether their object has been broken into lines, and set the flag. * stream.h (struct strm_base): New member, force_break. (force_break): Declared. * stream.c (strm_base_init): Extent initializer to cover force_break flag. (put_string, put_char): Clear the force_break flag whenever we hit column zero. (width_check): If indent mode is on, and force_break is true, generate a break. Clear force_break. (force_break): New function. (stream_init): Register force-break intrinsic. * buf.c (buf_print): Set the force break flag if the buffer was broken into multiple lines. * hash.c (hash_print_op): Set the force break flag if the hash was broken into multiple lines. * lib.c (obj_print_impl): Same logic for lists. * struct.c (struct_inst_print): Same logic for structs. * tests/009/json.expected, tests/011/macros-2.expected, tests/012/struct.tl, tests/017/glob-zarray.expected: Update expected textual output to reflect new formatting.
* eval: remove hack of macro deffers evaled on expansion.Kaz Kylheku2018-03-253-21/+24
| | | | | | | | | | | | | | | | | | * eval.c (do_expand): When a defmacro or defsymacro form is traversed, do not evaluate it, except in backward compatibility mode. Unfortunately, this breaks some code. * tests/011/macros-1.txr: A defmacro form has to be wrapped in macro-time. * tests/011/macros-2.txr: Likewise. * tests/011/mandel.txr: Likewise. * tests/012/man-or-boy.tl (defun-cbn): This macro generates a progn which which expects that a defmacro form will come into effect for the subsequent lambda in the same form. We must wrap it in macro-time to make this happen now.
* macros: expand declined form in outer env.Kaz Kylheku2017-11-242-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch implements a new requirement which clarifies what happens when a macro declines to expand a form. To decline expanding a form means to return the original form (same object) without returning it. The expander detects this situation with an eq comparison on the input and output. The current behavior is that no further attempts are made to expand the form. This is problematic for various reasons. In code which is expanded more than once, this can lead to the expansion being different between the expansion passes. In the first pass, a local macro M might decline to expand a form. In the second pass, the local macro definition no longer exists, and the form does get expanded by a global macro M. This kind of instability introduces a flaw into complex macros which expand their argument material more than once. The new requirement is that if a macro definition declines to expand a macro, then a search takes place through the outer lexical scopes, and global scope, for the innermost macro definition which will expand the form. The search tries every macro in turn, stopping if a macro is found which doesn't decline the expansion, or after passing the global scope. * eval.c (expand_macro): Implement new searching behavior. * txr.1: Documented the expansion declining mechanism under defmacro and macrolet. * tests/011/macros-3.tl: New file. * tests/011/macros-3.expected: New file.
* bugfix: dynamic env handling in parallel bindingKaz Kylheku2016-12-231-0/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In the parallel binding (let ((x s) (s 0) (y s)) ...), both x and y must bind to the prior value of s, not to the new value 0. We have the bug that if s is a special variable, the initialization of y sees the new dynamic environment which contains the new value, so x gets the previous, y gets new. This commit fixes it. * eval.c (reparent_env): New static function. (bindings_helper): Separate logic into two loops, for sequential and parallel binding, so we don't have to repeatedly test this condition in the loop body, and can think separately about each case and streamline it. Nothing new happens under sequential binding; the behavior that is wrong for parallel binding is right for sequential. Under parallel binding, what we do is reset the dynamic environment to the original one prior to each evaluation of an initform. Then if the evaluation changes to a new dynamic environment (a special variable is being bound), we notice this and hook the new environment into a local stack, changing it parent pointer. At the end, we install this stack as the new dynamic env. Thus each init form is evaluated in the original dynamic env. * tests/011/special-1.tl: New tests added.
* Use with-out-string-stream macro in test.Kaz Kylheku2016-12-231-5/+1
| | | | | * tests/011/special-1.tl (with-output-to-string): macro removed; with-out-string-stream used.
* Convert special-1 test from txr to tl.Kaz Kylheku2016-12-232-10/+9
| | | | | * tests/011/special-1.txr: Renamed to tests/011/special-1.tl and @(do ...) removed.
* Refactoring internals of for/each operators.Kaz Kylheku2016-12-181-9/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | NOTE: The socket test cases do not pass under this commit: this is expected. The for and each family of operators will now be macros which expand to let/let* binding construct wrapping a lower level special operator. This is in preparation for a change to how special variable binding is implemented. This change reduces the number of special forms which bind variables. There is a single low-level operator for for loops called sys:for-op. Its syntax is a lot like the C89 for loop: (sys:for-op init-forms test step-forms body). The init-forms do not bind anything; it is just forms. There is a sys:each operator for implementing each, each*, append-each and all those operators. Its syntax is (sys:each-op type-sym optional-vars . body). The type-sym is one of each, append-each or collect-each. If optional-vars is nil, then the operator looks at the immediate lexical environment, and assumes all the bindings there are the each iteration variables and it works with those bindings, like its predecessor did. Otherwise optional-vars is a list of symbols: the operator walks the list and resolves each element to a binding. This is used in two situations: when some of the variables are special (dynamically scoped) or when the variables are bound sequentially with let* and are thus scattered in multiple levels of environment. * eval.c (for_op_s, each_op_s): New symbol variables. (get_bindings): New static function. (op_each): Now implements sys:each-op. (op_for): Now implements sys:for-op. (get_var_syms): New static function. (me_each, me_for): New static functions. (do_expand): Do not expand the each operator family under the same rule. New case handling sys:each-op is introduced due to the different syntax. The for case restructured to handle for_op_s. (eval_init): Intern sys:each-op and sys:for-op symbols. Register the corresponding operators. Move registrations of the public symbols each, each*, for, for* and all the other each variants to be macros. * tests/011/macros-2.expected: Updated with different macro expansion which is now produced for a while loop.
* Expander warns about unbound variables.Kaz Kylheku2016-11-261-7/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (eval_exception): New static function. (eval_error): Reduced to wrapper around eval_exception. (eval_warn): New function. (me_op): Bind the rest symbol in a shadowing env to suppress watnings about unbound rest. (do_expand): Throw a warning when a bindable symbol is traversed that has no binding. (expand): Don't install atoms as last_form_expanded. * lib.c (warning_s, restart_s, continue_s): New symbol variables. (obj_init): Initialize new symbol variables. * lib.h (warning_s, restart_s, continue_s): Declared. * lisplib.c (except_set_entries): New entries for ignwarn and macro-time-ignwarn. * parser.c (repl_warning): New static function. (repl): Use repl_warning function as a handler for warning exceptions: to print their message and then continue by throwing a continue exception. * parser.y (warning_continue): New static function. (parse_once): Use warning_continue to ignore warnings. In other words, we suppress warnings from Lisp that is mixed into TXR pattern language code, because this produces too many false positives. * share/txr/stdlib/except.tl (ignwarn, macro-time-ignwarn): New macros. * share/txr/stdlib/place.tl (call-update-expander, call-clobber-expander, call-delete-expander): Ignore warnings around calls to sys:expand, because of some gensym-related false positives (we expand code into which we inserted some gensyms, without having inserted the constructs which bind them. * tests/011/macros-2.txr: Suppress unbound variable warnings from a test case. * tests/012/ifa.tl: Bind unbound x y variables in one test case. * tests/012/struct.tl: Suppress unbound variable warnings in some test cases. * uwind.c (uw_throw): If a warning is unhandled, then print its message with a "warning" prefix and then throw a continue exception. (uw_register_subtype): Eliminate the check for sub already being a subtype of sup. This allows us to officially register new types against t. (uw_late_init): Register continue exception type as a subtype of the restart type. Formally register warning type. * txr.1: Documented ignwarn.
* Use *load-path* in load/include directive.Kaz Kylheku2016-09-261-1/+1
| | | | | | | | | | | | | | * match.c (v_load): Obtain parent load path from *load-path* variable, rather than from source location info associated with the directive. This changes the semantics of when a @(load ...) occurs in code included via @(include ...). That @(load ...) is processed in the *load-path* context of the parent, rather than the include. * tests/011/txr-case.txr: Load txr-case.txr from the standard library, rather than include it. Otherwise txr-case.txr looks for txr-case.tl in tests/011.
* Multi-line, indented printing of structure.Kaz Kylheku2015-07-311-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (op_error): New static function. (macro_form_p, fboundp): Static to external. (special_operator_p): New function. (eval_init): Register macrolet and symacrolet to op_error. These are recognized and processed by expand, but we want them in the op table so they are reported by special_operator_p. * eval.h (fboundp, macro_form_p, special_operator_p): Declared. * hash.c (print_key_val): Break long lines on spaces between pairs with stream_width_check. (hash_print_op): Implement split and indented printing. * lib.c (obj_print_impl): New static function, resulting from a merge of obj_print and obj_pprint. Fixes some wrong-way recursion bugs: obj_pprint recursed into obj_print in some places. Adds support for multi-line printing of vectors and lists, with indentation using the new interfaces in streams. * stream.c (strm_base_init): Update initializer. (put_indent, indent_mode_put_string): New static functions. (put_string): Use indent_mode_put_string in either of the two indent modes. (put_char): Implement indent mode. (get_indent_mode, test_set_indent_mode, set_indent_mode, get_indent, set_indent, inc_indent, width_check): New functions. * stream.h (enum indent_mode): New. (struct strm_base): indent_on member becomes indent_mode. New members data_width and code_width. (get_indent_mode, test_set_indent_mode, set_indent_mode, get_indent, set_indent, inc_indent, width_check): Declared. * tests/009/json.expected: Updated. * tests/010/seq.expected: Likewise. * tests/011/macros-2.expected: Likewise.
* Crack down on redefinitions of built-ins.Kaz Kylheku2015-05-082-12/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (builtin, eval_initing): New global variable. (op_defun, op_defmacro): During initialization, record functions and macros in builtin hash. (builtin_reject_test): New static function. (expand_macrolet): Perform builtin reject test for fbind, lbind, and macrolet. (regfun, reg_mac): Add symbol to builtin hash. (eval_init): GC-protect new hash table variable and initialize it. Set eval_initing to true over eval initialization. The flip function is renamed fo flipargs. (eval_compat_fixup): New function, for dealing with the operator/function conflict over flip. * eval.h (eval_compat_fixup): Declared. * lib.c (compat_fixup): Call eval_compat_fixup. * tests/011/macros-2.txr: This test was defining a macro called while which is now illegal. Renamed to whilst. * tests/011/macros-2.expected: Regenerated. * txr.1: Function flip renamed to flipargs and documented in Compatibility section.
* New macro-based framework for assignment places.Kaz Kylheku2015-05-062-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The operators set, inc, dec, pop and others are now macros which generate code, rather than built-in special forms that use "C magic". Moreover, new such macros are easy to write, and several new ones are already available. Moreover, new kinds of assignable places are easy to create. * place.tl: New file. * lisplib.c, lisplib.h: New files. * Makefile (OBJS): New target, lisplib.o. (GEN_HDRS): New variable. (LISP_TO_C_STRING): New recipe macro, with rule. (clean): Remove generated headers named in $(GEN_HDRS). * eval.c (dec_s, push_s, pop_s, flip_s, del_s): Variables removed. (setq_s): New variable. (lookup_var, lokup_sym_lisp_1, lookup_var_l, lookup_fun, lookup_mac, lookup_symac, lookup_symac_lisp1): Trigger the delayed loading of libraries for undefined global symbols, and re-try the lookup. (op_modplace, dwim_loc, force_l): Static functions removed. (op_setq): New static function. (eval_init): Initialize setq_s; remove initializations of removed variables; remove registrations for op_modplace; add registration for sys:setq, sys:rplaca, sys:rplacd, sys:dwim-set and sys:dwim-del intrinsics. Call lisplib_init to initialize the dynamic library loading module. * lib.c (sys_rplaca, sys_rplacd): New functions, differing in return value from rplaca and rplacd. (ref, refset): Handle hash table. (dwim_set, dwim_del): New functions. * lib.h (sys_rplaca, sys_rplacd, dwim_set, dwim_del): Declared. * genvim.txr: Include place.tl in scan. * tests/010/seq.txr: The del operator test case no longer throws at run-time but at macro-expansion time, so the test case is simply removed. * tests/010/seq.expected: Updated output. * tests/011/macros-2.txr: Reset *gensym-counter* to zero, because the textual output of the test case includes gensyms, whose numberings fluctuate with the content of the new Lisp library material. * tests/011/macros-2.expected: Updated output.
* * tests/011/macros-1.txr: Add test for lexical functionKaz Kylheku2015-02-072-0/+7
| | | | | | shadowing symbol macro. * tests/011/macros-1.expected: Updated.
* * share/txr/stdlib/txr-case.txr: New file.Kaz Kylheku2014-10-212-0/+13
| | | | | | | | | | | | * txr.1: Document txr-if, txr-when and txr-case. * genvim.txr: Added new macro names. * tests/011/txr-case.expected: New file. * tests/011/txr-case.txr: New file. * txr.vim: Regenerated.
* * tests/011/macros-2.txr: Added test for labels shadowing macro,Kaz Kylheku2014-07-102-2/+14
| | | | | | | | and let shadowing symacro. * tests/011/macros-2.expected: Regenerated * txr.vim: Regenerated.
* * parser.l: Allowing ^ to be a quote character, and adjusting definitionKaz Kylheku2014-03-033-7/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | of identifiers to rule this out from being the first character of a symbol which has no prefix. Recognize the ^ character as a token in the NESTED state. * lib.c (obj_print, obj_pprint): Render sys:qquote as ^. * parser.y (choose_quote): Function removed. (n_expr): Recognize '^' as quasiquote. Removed all the "smart quote" hacks that try to make quote behave as quote or quasiquote, or try to cancel out unquotes and quotes. * tests/009/json.txr: Fixed to ^ quasiquote. * tests/010/reghash.txr: Likewise. * tests/011/macros-2.txr: Likewise. * tests/011/mandel.txr: Likewise. * tests/011/special-1.txr: Likewise. * txr.1: Updated docs. * genvim.txr: Revamped definitions for txr_ident and txl_ident so that unqualified identifiers cannot start with # or ^, but ones with @ or : in front can start with these characters. * txr.vim: Regenerated.
* * tests/011/special-1.txr: Add some coverage for evaluationKaz Kylheku2014-03-011-1/+2
| | | | | | of a re-bound special under the Lisp-1 evaluation of the [ ] notation. This test case would have failed three commits back.
* * tests/011/mandel.expected: New file.Kaz Kylheku2014-02-282-0/+123
| | | | * tests/011/mandel.txr: New file.
* Change in the design of how special variables work, to fix the brokenKaz Kylheku2014-02-282-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | re-binding. C code now has to go through the dynamic environment lookup to access things like *random-state*, or *stdout*. As part of this, I'm moving some intrinsic variable and function initializations out of eval.c and into their respective modules. Macros are are used to make global variables look like ordinary C variables. This is very similar to the errno trick in POSIX threads implementations. * eval.c (looup_var, lookup_var_l): Restructured to eliminate silly goto, the cobjp handling is gone. (reg_fun, reg_var): Internal function becomes external. reg_var registers a simple cons cell binding now, without any C pointer tricks to real C global variables. (c_var_mark): Static function removed. (c_var_ops): Static struct removed. (eval_init): Numerous initializations for streams, syslog, rand, signals and others moved to their respective modules. The new symbol variables user_package_s, keyword_package_s and system_package_s are interned here, and the variables are created in a special way. * eval.h (reg_var, reg_fun): Declared. * gc.c (prot1): Added assert that the loc pointer isn't null. This happened, and blew up during garbage collection. * lib.c (system_package, keyword_package, user_package): Variables removed these become macros. (system_package_var, keyword_package_var, user_package_var): New global variables. (system_package_s, keyword_package_s, user_package_s): New symbol globals. (get_user_package, get_system_package, get_keyword_package): New functions. (obj_init): Protect new variables. Initialization order of modules tweaked: the modules sig_init, stream_init, and rand_init are moved after eval_init because they register variables. * lib.h (keyword_package, system_pckage, user_package): Variables turned into macros. (system_package_var, keyword_package_var, user_package_var): Declared. (system_package_s, keyword_package_s, user_package_s): Declared. (get_user_package, get_system_package, get_keyword_package): Declared. * rand.c (struct random_state): Renamed to struct rand_state to avoid clash with new random_state macro. (random_state): Global variable removed. (random_state_s): New symbol global. (make_state, rand32, make_random_state, random_fixnum, random): Follow rename of struct random_state.
* About time for some new regression tests.Kaz Kylheku2014-02-286-0/+74
* tests/011/macros-1.expected: New file. * tests/011/macros-1.txr: New file. * tests/011/macros-2.expected: New file. * tests/011/macros-2.txr: New file. * tests/011/special-1.expected: New file. * tests/011/special-1.txr: New file.