summaryrefslogtreecommitdiffstats
path: root/parser.c
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* Reset flex scanner if exception thrown during read.Kaz Kylheku2015-09-061-1/+22
| | | | | | | | | | | | | | We must tear down and rebuild the Flex scanner, otherwise it is left in a bad state causing it to abort. * parser.c (parser_cleanup): After destroying scanner, null out the pointer. (parser_reset): Destroy the Flex scanner, and instantiate a new one in its place. (lisp_parse): Set up an unwind catch which will reset the parser if it was aborted by an exception. * parser.h (parser_reset): Declared.
* Repl will print something for syntax error exceptions.Kaz Kylheku2015-09-061-1/+1
| | | | | | * parser.c (repl): Print a simple fixed message when a syntax error exception is caught, just so the fact is noted.
* Allow evaluation from repl to be interrupted.Kaz Kylheku2015-09-061-0/+7
| | | | | | | | | | | * eval.c (do_eval): Check for pending signals. * parser.c (repl_intr): New static function. (repl): Set up signal handler for SIGINT around REPL. * signal.h (sig_deferred): declared. (sig_check_fast): New inline function/macro. A bit of a rearrangement here.
* Distinguish interrupt indication from linenoise.Kaz Kylheku2015-09-061-2/+6
| | | | | | * parser.c (repl): If linenoise returns a null pointer, but the last error is lino_eof, print "** intr" message and continue; do not quit.
* Distinguish exceptions from results in repl.Kaz Kylheku2015-09-061-0/+1
| | | | | * parser.c (repl): Print "** " sequence in front of exception.
* Erroneous lines must go into history also.Kaz Kylheku2015-09-061-4/+8
| | | | | | * parser.c (repl): If an exception is thrown, we record a nil value for the line backreference variable, and add the line to history.
* repl suppresses syntax error exceptionsKaz Kylheku2015-09-061-1/+3
| | | | | | | | | * parser.c (repl): If an expression is caught of type syntax-error, then just suppress it. It is not informative in this situation because the syntax error diagnostics have appeared on the tty. A syntax error exceptions is thrown out of the reader so that program logic doesn't ignore errors.
* Parenthesis sensitivity for completion.Kaz Kylheku2015-09-061-4/+23
| | | | | | | | | | | | | * eval.c (boundp): Static function becomes extern. * eval.h (boundp): Declared. * parser.c (find_matching_syms): New par parameter lets function determine whether previous character is a an open parenthesis or brace, based on which the set of possible completions is restricted. (provide_completions): Calculate the par parameter and pass to find_matching_syms.
* linenoise completion for txr symbolsKaz Kylheku2015-09-051-0/+114
| | | | | | | | | | | | | | | Implement basic tab completion. * lib.c (package_alist, package_name, package_symbols): New functions. * lib.h (package_alist, package_name, package_symbols): Declared. * parser.c (find_matching_syms, provide_completions): New static functions. (repl): Register provide_completions as completion callback with linenoise.