summaryrefslogtreecommitdiffstats
path: root/parser.c
Commit message (Collapse)AuthorAgeFilesLines
* cobj: rename poorly named default operation.Kaz Kylheku2017-05-151-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Renaming cobj_hash_op to cobj_eq_hash_op. This function is only appropriate to use with COBJ objects which use eq as their equal funtion. I've spotted one instance of an inappropriate use which have to be addressed by a different commit: the equal function is other than eq, but cobj_hash_op is used for the equal hash. * lib.h (cobj_hash_op): Declaration renamed to cobj_eq_hash_op. * hash.c (cobj_hash_op): Renamed to cobj_eq_hash_op. (hash_iter_ops): Refer to renamed cobj_hash_eq_op. * ffi.c (ffi_type_builtin_ops, ffi_type_struct_ops, ffi_type_ptr_ops, ffi-closure_ops, ffi_call_desc_ops): Likewise. * lib.c (cptr_ops): Likewise. * parser.c (parser_ops): Likewise. * rand.c (random_state_ops): Likewise. * regex.c (char_set_ops, regex_obj_ops): Likewise. * socket.c (dgram_strm_ops): Likewise. * stream.c (null_ops, stdio_ops, tail_ops, pipe_ops, dir_ops, string_in_ops, byte_in_ops, strlist_in_ops, string_out_ops, strlist_out_ops, cat_stream_ops, record_adapter_ops): Likewise. * struct.c (struct_type_ops): Likewise. * sysif.c (cptr_dl_ops): Likewise. * syslog.c (syslog_strm_ops): Likewise. * unwind.c (cont_ops): Likewise.
* listener: :p and :prompt commands.Kaz Kylheku2017-04-061-0/+8
| | | | | | | | | * parser.c (repl): Support :p and :prompt commands for printing the current prompt, which is useful in plain mode. * txr.1: Document the new commands under Interactive Listener. Also plain mode is documented again here, though it is described for -n/--noninteractive.
* Connect -n option to linenoise noninteractive mode.Kaz Kylheku2017-04-041-0/+3
| | | | | | | | | | * parser.c (repl): Set noninteractive mode from noninteractive option. * txr.c (help): Mention effect of -n upon listener. * txr.1: Documented effect of -n/--noninteractive on the listener.
* listener: completion sensitive for slots and methods.Kaz Kylheku2017-03-211-8/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When completing .prefix[TAB], .(prefix[TAB] or .[prefix[TAB], restrict identifiers to the appropriate namespace. The former will report only symbols from the relevant package which are struct slots; the latter further restricts it to those which are static slots defined as functions. * lib.c (symbol_visible): Static function becomes extern. * lib.h (symbol_visible): Declared. * parser.c (find_matching_syms): par parameter is renamed kind and can hold additional values 'S' (slots) and 'M' (methods). New get_slot_syms function is used to fetch the slots, as necessary, instead of the visible syms, if the kind is 'S' or 'M'. The same loop as before (with the minor change of recognizing 'S' and 'M' also) performs the prefix matching. (provide_completions): Recognize . .( and .[ prefix, calculating the kind argument of find_matching_syms in a new way. * struct.c (get_slot_syms): New function. * struct.h (get_slot_syms): Declared. * txr.1: Add some notes about this under the description of completion. The full rules are not given though; let the user discover.
* Rename badly named default_bool_argKaz Kylheku2017-03-171-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.h (default_bool_arg): Inline function renamed to default_null_arg. * eval.c (if_fun, pad, ginterate, giterate, range_star, range, constantp, macroexpand_1, macro_form_p, expand_with_free_refs, do_expand, eval_intrinsic, func_get_name, make_env_intrinsic): Follow rename. * arith.c (lognot): Likewise. * gc.c (gc_finalize): Likewise. * glob.c (glob_wrap): Likewise. * hash.c (group_reduce, gethash_n): Likewise. * lib.c (print, multi_sort, lazy_str, vector, iff, tok_str, split_str_keep, search_str, remove_if, val): Likewise. * match.c (match_fun): Likewise. * parser.c (lisp_parse_impl, regex_parse): Likewise. * rand.c (make_random_state): Likewise. * regex.c (read_until_match, search_regex, regex_compile): Likewise. * socket.c (sock_accept, sock_connect): Likewise. * stream.c (open_files_star, open_files, run, open_process, open_tail, get_string, record_adapter): Likewise. * struct.c (static_slot_ensure, static_slot_ens_rec, clear_struct, make_struct_type): Likewise. * sysif.c (exec_wrap, errno_wrap, cobj_ops_init): Likewise. * unwind.c (uw_capture_cont, uw_find_frames_impl): Likewise.
* Better way for releasing deferred warnings.Kaz Kylheku2017-02-101-1/+1
| | | | | | | | | | | | | | | | | | | | We should be re-throwing deferred warnings as ordinary warnings, not dumping them to a stream. * eval.c (eval_exception): Use uw_release_deferred_warnings instead of uw_dupm_deferred_warnings. (load): Likewise. * parser.c (read_eval_ret_last): Likewise. * txr.c (txr_main): Likewise. * unwind.c (uw_release_deferred_warnings): New function. * unwind.h (uw_release_deferred_warnings): Declared. * txr.1: Documented release-deferred-warnings and updated documentation for dump-deferred-warnings.
* Bump copyright year to 2017.Kaz Kylheku2017-01-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | * LICENSE, LICENSE-CYG, METALICENSE, 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, signal.c, signal.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, 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/getopts.tl, share/txr/stdlib/getput.tl, share/txr/stdlib/hash.tl, share/txr/stdlib/ifa.tl, share/txr/stdlib/package.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/tagbody.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: Add 2017 to all copyright headers and strings.
* Dump deferred warnings in eval_intrinsic.Kaz Kylheku2017-01-151-2/+9
| | | | | | | | | | | | * eval.c (eval_intrinsic): Dump deferred warnings after expansion, unless in the middle of a load. * parser.c (read_eval_ret_last): Bind *load-recursive* around all evaluations to t, then dump warnings if prior value of *load-recursive* is nil. Thus the repl's :read feature behaves like load. (repl_warning): We can now unconditionally defer deferrable warnings here now, whether or not in a load.
* Rebind *stderr* on entry into repl.Kaz Kylheku2017-01-151-0/+4
| | | | | * parser.c (repl): Create a new dynamic env and rebind *stderr* variable to the repl's output stream.
* Deferred warnings.Kaz Kylheku2017-01-131-3/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Warnings about undefined functions and variables are now deferred during loading, so forward references do not generate nuisance diagnostics. * eval.c (load_recursive_s): New symbol variable. (eval_defr_warn): New static function. (op_defvarl, op_defun): Purge any deferred warning about the given function or variable not being defined. (load): Rebind the sys:*load-recursive* special var to true around the load. After the load, dump deferred warnings if the prior binding of sys:*load-recursive* is false. Discard deferred warnings in the case of termination by a nonlocal control transfer. (do_expand): Treat unbound vars and functions as deferrable warnings, specially tagged for individual purging frkm the deferred list. (eval_init): Intern sys:*load-recursive* and initialize load_recursive_s variable. * eval.h (load_recursive_s): Declared. * parse.c (repl_warning): Accept variable arguments. Check whether we are loading and if so, defer deferrable (repl): Adjustment for altered signature of repl_warning. warnings. * txr.c (txr_main): dump deferred warnings after evaluating Lisp stream. * unwind.c (deferred_warnings): New static variable. (uw_throw): When a deferrable warning is caught, suppress the usual message and add it to the deferred_warnings list. (uw_defer_warning, uw_dump_deferred_warnings, uw_dump_deferred_warnings, uw_purge_deferred_warnings): New functions. (uw_late_init): gc-protect deferred_warnings. * unwind.h (uw_defer_warning, uw_dump_deferred_warnings, uw_dump_deferred_warnings, uw_purge_deferred_warnings): New functions declared.
* parser: fix problems at EOF involving #; syntax.Kaz Kylheku2016-12-061-10/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch addresses a problem whereby if a TXR Lisp file ends with an erased object notation such as #;(a b c), there is a syntax error. The strategy is to simplify the grammar so that a single yyparse primed with SECRET_ESCAPE_E or SECRET_ESCAPE_I will read either an object, or just one instance of the #; notation. If #;OBJ is read, then the parse tree is returned as the nao value. The caller knows that #;OBJ must have occurred because there are no errors and the parser isn't at EOF, yet there is no parse tree. Then in lisp_parse we can loop on this situation, and make adjustments elsewhere also. So that iread continues to work, we must separate the parser_eof condition from the lookahead token. Under iread, we were clearing the token in prime_parser_post, but that was having the side effect of making the parser look like it is in EOF. We now preserve the EOF indication in a flag, so we can manipulate the token. * parser.h (struct parser): new member, eof. * parser.c (parser_common_init): Initialize new eof flag in parser structure to zero. (prime_parser_post): Set the eof flag if the parser's most recent token is zero. (lisp_parse_impl): Call the parser repeatedly while there are no errors, and no EOF, yet no object has been produced. This indicates that a #; erasure has been processed. (read_eval_stream): Restructure the logic here for clarity. Do not break the loop if error_val was returned from the parser, but there are no errors, and the parser isn't at EOF. This is behavior is probably redundant with respect to the loop in lisp_parse_impl. (read_eval_ret_last): Bugfixes here. Pass an error indicating value down to lisp_parse, like in read_eval_stream and make the logic similar. (parser_eof): Just return an indication based no the eof flag. * parser.y (hash_semis_n_expr, hash_semis_i_expr, ignored_i_exprs, ignored_n_exprs): Grammar rules removed. (hash_semi_or_n_expr, hash_semi_or_i_expr): New grammar rules. (spec): Retarget SECRET_ESCAPE_E and SECRET_ESCAPE_I cases to new rules. (parse): Clear eof flag to zero.
* Expander warns about unbound variables.Kaz Kylheku2016-11-261-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* bugfix: reading hash literals with circ notation.Kaz Kylheku2016-11-231-1/+12
| | | | | | | | | | | | | | | | | | | The backpatching of literal hash objects containing circular notation labels is incorrect, because it directly mutates the hash keys, without regard for the fact that this alters their hash values. This change makes the test case #1=#H(() (#1# #1#)) work properly: a hash which contains itself as a key and corresponding value. When this object is constructed by the reader, we can do a gethash call on it, using itself as the key, and it emerges as the value. Before this fix, nil would be returned indicating that the key is not found, although it is listed in the table (corrupt hash). * parser.c (circ_backpatch): When traversing a hash, local list of the cells. Then clear the hash, iterate the list of old cells, and re-insert the key-value pairs.
* Completion of fallback list implementation.Kaz Kylheku2016-11-161-2/+28
| | | | | | | | | | | | | | | | | | | | | | | | * lib.c (find_symbol): New function. (symbol_present): Search the fallback list also to determine whether the symbol is visible. * lib.h (find_symbol): Declared. * parser.y (sym_helper): Implement a new behavior for qualified symbols. Interning new symbols is only allowed for packages that have an empty fallback list. * parser.c (get_visible_syms): New static function. (find_matching_syms): Use get_visible_syms to get the list of eligible symbols. This way the fallback list of the package is included if it is the current package. * share/txr/stdlib/package.tl (defpackage): Do not insert a default (:use usr) if there is no :usr clause. Since defpackage is very new, no need for backward compatibility; the amount of code depending on this is likely zero. * txr.1: Documented fallback list feature.
* Handle interpreted functions in circle printing.Kaz Kylheku2016-11-101-0/+7
| | | | | | | | | | | | | | | | | | | Interpreted functions print as #<interpreted fun: name args>, thus repeating some list structure in their notation. This means we must traverse them when populating the object hash during printing, and also when backpatching after parsing. Test case: evaluate and print (let ((s '(lambda (a b c) d))) (list s (eval s))) with *print-circle* enabled. * lib.c (populate_obj_hash): Handle FUN objects of functype FINTERP. * parser.c (circ_backpatch): Likewise.
* Implement *package* special var; package overhaul.Kaz Kylheku2016-11-081-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (load): Rebind *package* in the local dynamic environment already established for the sake of *load-path*. By doing this we cause *package* to be restored to its prior value, which allows the loaded file to alter it. Common Lisp works this way. (eval_init): Register *package* variable, with the user package as its default value. * lib.c (package_s): New symbol variable. (intern, rehome_sym): Default the package argument to the current package, not to user_package. (get_user_package, get_system_package, get_keyword_package): Functions removed. (get_current_package): New function. (obj_print_impl): Revise symbol printing. Keyword and uninterned symbols are printed with : and #: prefixes. The remainder are printed with a package prefix if their home package isn't the current package. * lib.h (keyword_package, user_package, system_package): These macros are just straight aliases for the global variables, not going through the lookup mechanism, which was pointless. (cur_package): New macro. (package_s): Declared. (get_current_package): Declared. * lisplib.c (lisplib_try_load): Establish a local dynamic environment, and bind the *package* variable to the user package which the library modules expect. * parser.c (find_matching_syms, provide_completions): Treat unqualified symbols in the current package rather than user package. * parser.y (sym_helper): Intern unqualified symbols in the current package, not user package. * txr.1: Document that the variables user-package, system-package and keyword-package should not be modified. Document the *package* special variable, and that intern and rehome-sym default their package argument to its value. (Here we get rid of wrong references to the undocumented variable *user-package*).
* New #; syntax for erasing following object.Kaz Kylheku2016-11-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * parser.c (parser_circ_ref): Don't generate the circular reference if circular suppression is in effect. * parser.h (struct parser): New member, circ_suppress. We use this for suppressing the generation of circular #n# references in erased objects. * parser.l (grammar): Scan #; producing HASH_SEMI token. * parser.y (HASH_SEMI): New token. (hash_semis_n_expr, hash_semis_i_expr, ignored_i_exprs, ignored_n_exprs): New nonterminals, needed for supporting the use of #; in front of top-level forms. (spec): Use hash_semis_n_expr and hash_semis_i_expr instead of n_expr and i_expr. (r_expr): Support object erasure within nested syntax. (yybadtoken): Handle H_SEMI token. (parse): Initialize new circ_suppress member of parser struct to zero. * txr.1: Documented. * genvim.txr (txr_ign_par, txr_ign_bkt, txr_ign_par_interior, txr_ign_bkt_interior): New regions for colorizing erased objects (partial support). (txr_list, txr_bracket, txr_mlist, txr_mbrackets): Include erased objects by including regions txr_ign_par and txr_ign_bkt. * txr.vim, tl.vim: Regenerated.
* repl: don't send error trace to *stderr*.Kaz Kylheku2016-10-211-1/+1
| | | | | | | * parser.c (repl): Pass out_stream rather than std_error to error_trace. I don't remember the original intent here. All it does is create strange puzzling behavior when an error occurs in the middle of a line of output that isn't flushed yet.
* Check call graph circularity in circ_backpatch.Kaz Kylheku2016-10-201-7/+13
| | | | | | | | | | | | | | | | | The circ_backpatch function could suffer runaway recursion, so we must add a cycle check. This could happen due to hitting cyclical objects when traversing structs. Structs have static slots that could contain cyclic objects, as well as construction logic which can generate slots that contain cycles and are not overridden by anything in the literal. * parser.c (circ_backpatch): Take struct circ_stack * argument; extend the circ_stack in recursive calls. Do circular check on entry. (parser_resolve_circ): Pass null pointer as the new stack argument to circ_backpatch.
* Adding notation for cycles and shared structure.Kaz Kylheku2016-10-181-1/+176
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit implements the parse-side support for handling a notation that exists in ANSI Common Lisp for specifying objects with cycles and shared substructure. * parser.h (struct parser): New members, circ_ref_hash and circ_count. (circref_s, parser_resolve_circ, parser_circ_def, parser_circ_ref): Declared. * parser.c (circref_s): New symbol variable. (parser_mark): Visit the new circ_ref_hash member of the parser structure. (parser_common_init): Initialize new members circ_ref_hash and circ_count of parser structure. (patch_ref, circ_backpatch): New static functions. (parser_resolve_circ, parser_circ_def, parser_circ_ref): New functions. (circref): New static function. (parse_init): Initialize circref_s as sys:circref symbol. Register sys:circref function. * parser.l (grammar): Scan #<num>= and #<num># notation as tokens, extracting their numeric value. * parser.y (HASH_N_EQUALS, HASH_N_HASH): New token types. (i_expr, n_expr): Adding phrases for hash-equalsign and hash-hash syntax. (yybadtoken): Handle new token types in switch. (parse_once): Call parser_resolve_circ after parsing to rewrite any remaining #<num># references in the structure to the objects they denote. (parse): Reset new struct parse members to initial state. Call parser_resolve_circ after parsing to rewrite any remaining #<num># references.
* Detect cycles in rlcp_tree.Kaz Kylheku2016-10-181-0/+10
| | | | | | | | | | | | | This will be required when the parser becomes capable of creating object graphs with cycles. * parser.c (parser_callgraph_circ_check): New function. * parser.h (struct circ_stack): New struct. (parser_callgraph_circ_check): Declared. * parser.y (rlcp_tree_rec): New static function. (rlcp_tree): Reduced to wrapper for rlcp_tree_rec.
* listener: put each result into linenoise.Kaz Kylheku2016-10-121-0/+1
| | | | | | | | * parser.c (repl): After each successful command that produces a value, not only print the value but also call lino_set_result to install its string representation into the linenoise object, so it is available for insertion via Ctrl-X Ctrl-P.
* Synchronize license comments with LICENSE.Kaz Kylheku2016-10-011-16/+17
| | | | | | | | | | | | | | | | | | | | * 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.
* Overhaul of self-load-path mechanism.Kaz Kylheku2016-09-261-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The self-load-path symbol macro is as of now deprecated. It simply expands to *load-path*. *load-path* is a new special variable which is dynamically bound to the path of a file being loaded. * eval.c (self_load_path_s): Global variable renamed to load_path_s. (sys_load): Bind *load-path* around processing of loaded file. (me_load): Expand (load x) simply to (sys:load x *load-path*). (set_get_symacro): Function removed. (reg_symacro): New static function. (eval_init): Initialize renamed load_path_s with interned symbol having the name *load-path*. Register the *load-path* special variable. Set up the sel-load-path symbol macro aliasing for *load-path*. * eval.h (self_load_path_s): Declaration renamed. * match.c (v_load): Bind *load-path* around loading or inclusion. * parser.c (load_rcfile): Bind *load-path* around loading of .txr_profile file. * txr.c (txr_main): Bind *load-path* instead of self-load-path symbol macro. * txr.1: Updated documentation for @(load) directive and load macro. Replaced documentation of self-load-path with *load-path*.
* Bugfix: -Dvar=val not seen in some Lisp code.Kaz Kylheku2016-09-231-3/+7
| | | | | | | | | | | | | | | | | | | TXR Lisp files run from the command line do not see -Dvar=val bindings, whereas -p expressions do. The REPL sees the bindings, but not code loaded from it using (load "file.tl") because they are lexical. Let's keep these bindings as local lexicals for -p and -e forms, but install them as global lexicals for the other situations. * parser.c (repl): Get rid of the local repl_env made from the bindings that are passed in. Instead, before starting the REPL, loop through the bindings and install them as global lexicals with reg_varl. * txr.c (txr_main): Before processing a Lisp file, install the bindings as global lexicals with reg_varl.
* Check for Cygnal when deciding where user home is.Kaz Kylheku2016-07-271-19/+9
| | | | | | | * parser.c (get_home_path): Do not try HOME first and then USERPROFILE. If running on Cygnal, use strictly USERPROFILE, and do not fall back on HOME. In all other situations, try the HOME variable only.
* Handle two possible home dir locations on Cygwin.Kaz Kylheku2016-06-271-1/+27
| | | | | | | | | | | | | | | | | Under the Cygwin port, if we are running in the Cygwin shell enviroment, there is a HOME variable which contains a POSIX path like /home/kaz. This path works fine and we use that. If we are not running in the Cygwin environment, but running as an application that uses the Cygwin DLL, then the HOME variable is still defined, but the path doesn't resolve. We must detect this, and fall back on the USERPROFILE environment variable, which holds something like C:\Users\kaz. * parser.c (get_home_path): New static function, defined separately for Cygwin and other platforms. (repl): Use get_home_path to determine home directory.
* Handle nonexistent HOME env var in repl.Kaz Kylheku2016-06-271-3/+3
| | | | | | | * parser.c (repl): If home is nil, don't try to extract UTF-8 string from histfile, which is also nil. Use the UTF-8 pointer for subsequent checks, since it is that pointer's use which is subject to those checks.
* Fix memory leak in parser object.Kaz Kylheku2016-06-071-0/+1
| | | | | * parser.c (parser_destroy): Don't just clean up the parser_t structure, free it.
* Implement listener variable for selection style.Kaz Kylheku2016-05-191-2/+5
| | | | | | | | | | | * parser.c (listener_sel_inclusive_p_s): New symbol variable. (repl): Install current value of *listener-sel-inclusive-p* variable into linenoise. (parse_init): Initialize the symbol variable and register the Lisp special variable. * txr.1: Documented special variable and selection mode semantics.
* New feature: self-load-path symbol macro.Kaz Kylheku2016-05-181-0/+4
| | | | | | | | | | | | | | | | | | | | | * eval.c (self_load_path_s): New symbol variable. (sys_load): Save, set-up and restore self-load-path around load. (set_get_symacro): New function. (eval_init): Register load function using sys_load_s instead of redundant intern. * eval.h (set_get_symacro): Declared. * match.c (v_load): Save, set-up and restore self-load-path macro. * parser.c (load_rcfile): Likewise. * txr.c (txr_main: Set up self-load-path when opening file. * txr.1: Documented self-load-path.
* Regex syntax errors trigger exception.Kaz Kylheku2016-04-211-1/+5
| | | | | * parser.c (regex_parse): Don't return nil if there were errors; throw a syntax-error exception.
* Close source files after parsing.Kaz Kylheku2016-04-151-1/+4
| | | | | | | | | | | | | * eval.c (sys_load): close stream in all cases. * match.c (v_load): Likewise. * parser.c (load_rcfile): Close stream in unwind block, if open. * txr.c (txr_main): Close stream after parsing in all cases. If stream is std_input, or a string stream, close_stream does nothing.
* Replace all stray C style casts with macros.Kaz Kylheku2016-03-291-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * gc.c (gc_report_copies): C style casts found in this function. * linenoise.c (strip_qual, convert, coerce): Copy and paste the macros here. (record_undo, compare_completions, lino_add_completion, history_search, ab_append, sync_data_to_buf, refresh_singleline, screen_rows, refresh_multiline, find_nearest_paren, paren_jump, yank_sel, edit_move_matching_paren, edit, lino_make, lino_copy, lino_hist_add, lino_hist_set_max_len): C style casts replaced. * mpi/mpi-types.h (MP_DIGIT_BIT, MP_DIGIT_MAX, MP_WORD_BIT, MP_WORD_MAX, RADIX): C style casts replaced. * mpi/mpi.c (convert, coerce): Copy and paste the macros here. (mp_init_size, mp_init_copy, mp_copy, mp_set_int, mp_div_d, mp_bit, mp_to_double, mp_to_signed_bin, mp_to_unsigned_bin, mp_to_unsigned_buf, mp_toradix_case, mp_grow, s_mp_set_bit, s_mp_mod_2d, s_mp_mul_2d, s_mp_div_2d, s_mp_mul_d, s_mp_mul, s_mp_sqr, s_mp_div, s_mp_2expt, s_mp_todigit): C style casts replaced. * mpi/mplogic (convert): Macro copy and pasted here. (mpl_num_set, mpl_num_clear): C style casts replaced. * parser.c (provide_completions): Likewise. * signal.c (small_sigfillset): Likewise. * stream.c (stdio_truncate, test_set_indent_mode, set_indent_mode): Likewise.
* Header file cleanup.Kaz Kylheku2016-01-221-3/+0
| | | | | | | * arith.c, cadr.c, debug.c, eval.c, filter.c, gencadr.txr, glob.c, hash.c, linenoise/linenoise.c, lisplib.c, match.c, parser.c, rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c, syslog.c, txr.c, unwind.c, utf8.c: Remove unncessary header files.
* Pastes produced using :read are now numbered.Kaz Kylheku2016-01-131-4/+6
| | | | | | | | * parser.c (read_eval_read_last): New argument: counter. Incorporate counter into name of stream. (repl): Pass prev_counter into read_eval_read_last so the paste inherits the line number of the :read command.
* New internal function scat: variable arg cat_str.Kaz Kylheku2016-01-101-3/+3
| | | | | | | | | | | | | | Avoids consing up list of strings. * lib.c (vscat): New static function. (scat): New function. (lazy_str): Use scat instead of cat_str. * lib.h (scat): Declared. * eval.c (format_field): Use scat instead of cat_str. * parser.c (open_txr_file, read_eval_stream): Likewise.
* Copyright year bump.Kaz Kylheku2015-12-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | * LICENSE, METALICENSE, 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, 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/cadr.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/struct.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, stream.c, stream.h, struct.c, struct.h, sysif.c, sysif.h, syslog.c, syslog.h, txr.1, txr.c, txr.h, unwind.c, unwind.h, utf8.c, utf8.h: Add 2016 copyright. * linenoise/LICENSE, linenoise/linenoise.c, linenoise/linenoise.h: Bump one principal author's copyright from 2014 to 2015. The code is based on a snapshot of 2015 upstream work.
* Fix regression in tab completion.Kaz Kylheku2015-12-301-1/+1
| | | | | | | | | | | Same issue as with Vim syntax highlighting. * eval.c (mboundp): Externalize static function. * eval.h (mboundp): Declared. * parser.c (find_matching_syms): Expand fboundp check to encompass mboundp and special_operator_p.
* Error reports trace through layers of macroexpansion.Kaz Kylheku2015-11-281-25/+2
| | | | | | | | | | | | | | | | | | | | * eval.c (error_trace): New function. Consolidates error reporting between unhandled exception handling in uw_throw, and the catcher in the repl. (op_defmacro, expand_macrolet): Propagate location info from body to wrapping block, and to the macro binding. In the latter function, also to the body that is wrapped by local macros. (do_expand, macroexpand_1): Propagate location info from macro expander to expansion, only taking it from the form if the macro doesn't supply it. * eval.h (error_trace): Declared. * parser.c (repl): Replace error reporting code with call to error_trace. * unwind.c (uw_throw): uw_throw: likewise.
* Report chain of macro-expansions in errors.Kaz Kylheku2015-11-251-3/+12
| | | | | | | | | | | | | | | * eval.c (origin_hash): New global variable. (lookup_origin): New function. (expand_macro): Enter original form into origin hash, keyed by new form. (eval_init): gc-protect and initialize origin_hash. * eval.h (lookup_origin): Declared. * parser.c (repl): Report chain of expansions from last_form_evaled. * unwind.c (uw_throw): Likewise.
* Implementing *print-base* and ~d format directive.Kaz Kylheku2015-11-141-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * debug.c (show_bindings): Use ~d for level, so as not to be influenced by *print-base*. (debug): Use ~d for line numbers. * lib.c (gensym): Use ~d conversion specifier for formatting gensym counter into symbol name. * match.c (LOG_MISMATCH, LOG_MATCH): Use ~d for line number references. (h_skip, h_coll, h_fun, h_chr, match_line_completely, v_skip, v_fuzz, v_gather, v_collect, v_output, v_filter, v_fun, v_assert, v_load, v_line, h_assert, open_data_source): Use ~d for line refs, number of iterations, errno values. * parser.c (repl): Use ~d for prompt line numbers, numbered variables and the expr-<n> string in error messages. * parser.l (yyerrorf, source_loc_str): Use ~d for line numbers. * stream.c (print_base_s): New symbol variable. (formatv): Implement *print-base*. (stdio_maybe_read_error, stdio_maybe_error, stdio_close, pipe_close, open_directory, open_file, open_fileno, open_tail, open_process, run, remove_path): Use ~d for errno values. (stream_init): Initialize print_base_s and register *print-base* special variable. sysif.c (mkdir_wrap, ensure_dir, getcwd_wrap, mknod_wrap, chmod_wrap, symlink_wrap, link_wrap, readlink_wrap, excec_wrap, stat_impl, pipe_wrap, poll_wrap, getgroups_wrap, setuid_wrap, seteuid_wrap, setgid_wrap): Use ~d for errno values and system function results. * txr.1: Documented *print-base* and ~d conversion specifier.
* New iread function.Kaz Kylheku2015-11-071-3/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The read function no longer works like it used to on an interactive terminal because of the support for .. and . syntax on a top-level expression. The iread function is provided which uses a modified syntax that doesn't support these operators on a top-level expression. The parser thus doesn't look one token ahead, and so iread can return immediately. * eval.c (eval_init): Register iread intrinsic function. * parser.c (prime_parser): Only push back the recently seen token when priming for a regular Lisp read. Handle the prime_interactive method by preparing a SECRET_ESCAPE_I token. (lisp_parse_impl): New static function, formed from previous lisp_parse. Takes a boolean argument indicating interactive mode. (prime_parser_post): New function. (lisp_parse): Now a wrapper for lisp_parse_impl which passes a nil to indicate noninteractive read. (iread): New function. * parser.h (enum prime_parser): New member, prime_interactive. (scrub_scanner, iread, prime_parser_post): Declared. * parser.l (prime_scanner): Handle the prime_interactive case the same way as prime_lisp. (scrub_scanner): New function. * parser.y (SECRET_ESCAPE_I): New token type. (i_expr): New nonterminal symbol. Like n_expr, but doesn't support dot or dotdot operators, except in nested subexpressions. (spec): Handle SECRET_ESCAPE_I by way of i_expr. (sym_helper): Before freeing the token lexeme, call scrub_scanner. If the token is registered as the scanner's most recently seen token, the scanner must forget that registration, because it is no longer valid. (parse): Call prime_parser_post. * txr.1: Documented iread.
* Fix *listener-hist-len* in ~/.txr_profile not working.Kaz Kylheku2015-10-271-3/+5
| | | | | | | | | | On startup, the history is trimmed to 100 lines regardless of the variable's value in the profile file. * parser.c (repl): Load the rc file first, then load the history file. Furthermore, call lino_hist_set_max_len between these operations with the latest value pulled from the *listener-hist-len* variable.
* Stop using C library setjmp/longjmp.Kaz Kylheku2015-10-251-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | TXR is moving to custom assembly-language routines. This is mainly motivated by a very dubious thing done in the GNU C Library setjmp and longjmp in the name of security. Evidently, glibc's setjmp "mangles" certain pointer values which are stored into the jmp_buf buffer. It's been that way since 2005, evidently. This means that, firstly, all along, the use of setjmp in gc.c to get registers into a buffer so they can be scanned has not actually worked properly. More importantly, this pointer mangling in setjmp and longjmp is very hostile to a stack copying implementation of delimited continuations. The reason is that continuations contain jmp_buf buffers, which get relocated in the process of capturing and reviving a continuation. Any pointers in a jmp_buf which point into the captured stack segment have to be fixed up to point into the relocated location. Mangled pointers make this difficult, requiring hacks which are specific to glibc and the machine architecture. We might as well implement a clean, well-behaved setjmp and longjmp. * Makefile (jmp.o): New object file. (dbg/%.o, opt/%.o): New rules for .S prerequisites. * args.c, arith.c, cadr.c, combi.c, cadr.c, combi.c, debug.c, eval.c, filter.c, glob.c, hash.c, lib.c, match.c, parser.c, rand.c, regex.c, signal.c, stream.c, struct.c, sysif.c, syslog.c, txr.c, unwind.c, utf8.c: Removed <setjmp.h> include. * gc.c: Switch to struct jmp and jmp_save, instead of jmp_buf and setjmp. * jmp.S: New source file. * signal.h (struct jmp): New struct type. (jmp_save, jmp_restore): New function declarations denoting assembly language routines in jmp.S. (extended_jmp_buf): Uses struct jmp instead of setjmp. (extended_setjmp): Use jmp_save instead of setjmp. (extended_longjmp): Use jmp_restore instead of longjmp.
* Bugfix: unterminated format argument list in repl code.Kaz Kylheku2015-10-181-1/+1
| | | | | * parser.c (repl): Missing nao terminator in format call which computes expression name.
* New way of handling exceptions without unwinding.Kaz Kylheku2015-10-141-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (handler_bind_s): New symbol variable. (op_handler_bind): New static function. (do_expand): Traverse handler-bind forms. (eval_init): Initialize handler_bind_s variable and register handler-bind operator. * lisplib.c (except_set_entries, except_instantiate): New functions. (lisplib_init): Register new functions in dl_table. * parser.c (intr_s): New symbol variable. (repl_intr): Throw exception of type intr, rather than error. This way we can interrupt accidental exception handling loops involving exceptions derived from error. (parse_init): Initialize intr_s. * share/txr/stdlib/except.tl: New file, defines handle macro. * unwind.c (uw_push_handler): New function. (invoke_handler): New static function. (uw_throw): Search loop looks for and processes handlers in addition to catches. * unwind.h (uw_frtype_t): New enum member, UW_HANDLE. (struct uw_catch): Move member visible so it is in the same position as in struct uw_handler. (struct uw_handler): New struct type. (union uw_frame): New member ha of type struct uw_handler. (uw_push_handler): Function declared. * txr.1: Added introductory paragraphs to Exception Handling section. Documented handler-bind and handle. Some minor errors corrected.
* Interactive listener: substring completion.Kaz Kylheku2015-10-031-1/+4
| | | | | | | * parser.c (find_matching_syms): Take advantage of the linenoise Ctrl-X Tab feature by providing substring matches. * txr.1: Documented Ctrl-X Tab.
* Treat .( and (( context in completion.Kaz Kylheku2015-09-271-1/+3
| | | | | | | | | * parser.c (provide_completions): Don't pass the context parenthesis to find_matching_syms in additional cases: when preceded by a dot, or another parenthesis. This causes completion situations such as (let ((var[TAB] and obj.(method[TAB] not to be wrongly restricted to the function space.
* Fix race in ~/.txr_profile security check.Kaz Kylheku2015-09-231-8/+8
| | | | | | | | * parser.c (load_rcfile): Apply the privacy test to the open stream, rather than the file name, thus guarding against the possibility that a verified file object is replaced by another one before it is opened.