summaryrefslogtreecommitdiffstats
path: root/parser.c
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* repl: give details about source of error exception.Kaz Kylheku2015-09-231-0/+10
| | | | | * parser.c (repl): Print location info for exception based on last_form_evaled and last_form_expanded.
* Atom insert feature.Kaz Kylheku2015-09-181-0/+39
| | | | | | | | * parser.c (provide_atom): New static function. (repl): Register provide_atom with linenoise as atom callback. * txr.1: Documented.
* Set the tempfile suffix.Kaz Kylheku2015-09-181-0/+1
| | | | | * parser.c (repl): Configure the .tl suffix in the linenoise object.
* Improved ~/.txr_profile checks, with security.Kaz Kylheku2015-09-181-6/+15
| | | | | | | | | | * parser.c (load_rcfile): Use path-exists-p for the existence check. Since that doesn't throw, it's outside of the catch section. Use path-private-to-me-p to impose a security check on the profile file. If an error exception is caught, show the details. * txr.1: Added notes about security check.
* Change how error locations are reported in REPL.Kaz Kylheku2015-09-171-2/+2
| | | | | | | | | | | | | | Now that we have a multi-line mode, it no longer works that we use the command line number as the parse line number, so that an error from something that was parsed in command 42 comes out as "line:42". This commit changes to the format "expr-42:3": line 3 of expression 42. The expression number is fixed in the parse name, and the line number is derived from the line divisions in the entry itself. * parser.c (repl): Dynamically compute the parse name, such that it contains the command number. Then when parsing, just leave the parse to begin at line 1.
* Whitespace fix.Kaz Kylheku2015-09-171-1/+1
| | | | * parser.c (load_rcfile): Trailing whitespace after declaration.
* Listener configuration variables.Kaz Kylheku2015-09-171-0/+12
| | | | | | | | | | | | | | | | | | * linenoise/linenoise.c (lino_get_multiline): New function. * linenoise/linenoise.h (lino_get_multiline): Declared. * parser.c (listener_hist_len, listener_multi_line_p_s): New symbol global variables. (repl): Set linenoise history length and multi-line mode from the *listener-hist-len* and *listener-multi-line-p* variables on each call. Set the *listener-multi-line* variable from the lino_t object's current state after each linenoise call. (parse_init): Initialize new global variables and register them as special variables. * txr.1: Update sentence which says that history is fixed at 100 lines. Document listener configuration variables.
* Implement ~/.txr_profile mechanism.Kaz Kylheku2015-09-131-0/+34
| | | | | | | | | | | | * parser.c (load_rcfile): New function. (repl): Compute profile file name and try to load it before entering loop. * sysif.c (statp): Linkage becomes external. * sysif.h (statp): Declaration updated. * txr.1: Documented.
* Don't supply trivial completion which matches prefix.Kaz Kylheku2015-09-131-0/+3
| | | | | | | * parser.c (find_matching_syms): Don't add an entry into the history if it is a full match for the completion prefix, because in the UI in then looks as if nothing happened when Tab as pressed.
* Treat comment lines in repl, and plug memory leak.Kaz Kylheku2015-09-111-2/+14
| | | | | | | | | | * parser.c (repl): If we continue the loop due to detecting a blank line, we must free that line, since we are outside of the unwind block (and continue would violate that block if we were). If a line contains nothing but a comment, then enter that line into the history. * txr.1: Documented treatment of commented lines.
* New :read command in repl for direct stdin parse.Kaz Kylheku2015-09-111-1/+23
| | | | | | | | * parser.c (read_eval_ret_last): New function. (repl): Use read_eval_ret_last for :read command. * txr.1: Document :read in new section on direct read from the terminal.
* Better EOF check in read-eval stream function.Kaz Kylheku2015-09-111-1/+10
| | | | | | | | | | | | | | | | | | | | | This makes a difference if we read from a TTY. Without this fix, two Ctrl-D's have to be issued before the code registers EOF and returns. The trick is that we know, after calling the parser, whether it hit EOF, because we have the recent token. If its value is zero, that's the EOF token. We can bail out of the loop instead of calling the parser again which will require another EOF (because prime_parser will not push an EOF token!) * parser.h (parser_eof): Declared. * parser.c (read_eval_stream): After lisp_parse and eval, check for EOF with the parser_eof function, and bail if so. (parser_eof): New function.
* Quit if input form is :quit not its value.Kaz Kylheku2015-09-111-2/+2
| | | | | | | | * parser.c (repl): Subtle difference. Test form's syntax for equality to :quit, not its value. The REPL should not terminate if a form happens to calculate :quit as a value. * txr.1: Updated.
* Don't pass char to <ctype.h> function.Kaz Kylheku2015-09-101-2/+4
| | | | | | | * parser.c (provide_completions): Cast char argument to unsigned char in call to isalnum. The data comes from user input, which could be any byte. The char type may be signed (and usually is) and so may take on negative values.
* Completion doesn't iterate over all packages.Kaz Kylheku2015-09-101-10/+3
| | | | | | | | | | | When the completed symbol is unqualified, let's not complete across all packages, but just the user package. * parser.c (provide_completions): Substitute user_package if package is null, and call find_matching_syms once rather than iterating on all packages. Also, in this case, do not request symbol qualification.
* No completion on symbol in nonexistent package.Kaz Kylheku2015-09-101-0/+2
| | | | | * parser.c (provide_completions): If find_package returns nil, then just bail with no completions.
* C++: need conversions in return value from alloca.Kaz Kylheku2015-09-091-2/+2
| | | | | * parser.c (provide_completions): Use convert macro to cast void * return value of alloca to char *.
* C++: avoid the compl identifier.Kaz Kylheku2015-09-091-5/+5
| | | | | | | * parser.c (find_matching_syms): Rename the compl variable to comple, because compl is a standard C++ macro which provides an alternate name for the ~ operator.
* alloca needs to be declared.Kaz Kylheku2015-09-091-0/+1
| | | | * parser.c: #include ALLOCA_H.
* Refinement in linenoise eof/intr handling.Kaz Kylheku2015-09-081-3/+10
| | | | | | | | * parser.c (repl): Rather than breaking out of the loop when linenoise indicates lino_eof, break out of the loop for any error not equal to lino_intr. If the termination was due to other than lino_eof, print an error message.
* Bugfix: underrun on empty line tab completion.Kaz Kylheku2015-09-081-1/+4
| | | | | | | * parser.c (provide_completions): If strlen(data) is zero, the calculation of ptr places it at data - 1. Instead, let us calculate a zero value for ptr and then bail based on this.
* Load and save repl history.Kaz Kylheku2015-09-071-0/+14
| | | | | | | | | | * parser.c (repl): If a HOME environment variable exists, then load the .txr_history file from the user's home directory and save it when exiting. * sysif.c (getenv_wrap): Static function changed to extern. * sysif.h (getenv_wrap): Declared.
* Print exceptions with proper indenting.Kaz Kylheku2015-09-071-9/+7
| | | | | * parser.c (repl): Use format to print exception, and use ~! to ensure indentation.
* Better message for caught exceptions.Kaz Kylheku2015-09-071-1/+1
| | | | | * parser.c (repl): Use ** prefix on caught exception message. Clearly indicate that the second value is args.
* Store exception in repl variable.Kaz Kylheku2015-09-071-2/+3
| | | | | | | * parser.c (repl): If an exception is caught, don't store nil in the repl result variable and hash. Rather, store a cons cell holding the exception symbol and arguments.