summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* doc: opip, flow: note about no-argument case.Kaz Kylheku2022-10-171-0/+20
| | | | | | | * txr.1: It's a developer surprise that (flow x) returns nil rather than x; which is due to the documented behavior of chain, when it has no arguments. Let's add cautionary notes.
* Version 283.txr-283Kaz Kylheku2022-10-167-799/+885
| | | | | | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. Also mention that separator commas in integer tokens are new in 283 and have a different interpretation in older versions. * txr.vim, tl.vim: Regenerated. * protsym.c: Regenerated.
* args: don't use C99 flexible array member.Kaz Kylheku2022-10-151-6/+2
| | | | | | | | | | | | | | | The reason is that args_decl_list places struct args inside a larger struct, where it is followed by another member. A struct with a flexible array being other than the last member of another struct is a GNU extension, which generates warnings on newer GCC versions. * args.h (struct args): Define arg as array of [1] rather than [FLEX_ARRAY]. (ARGS_ABS_MIN): Unconditionally define as 1. (args_decl_list): Subtract 1 from N because we get one element from struct args. This macro should have subtracted the FLEX_ARRAY value.
* args: don't use alloca for const size cases.Kaz Kylheku2022-10-1511-38/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * args.h (args_decl_list): This macro now handles only constant values of N. It declares an anonyous container struct type which juxtaposes the struc args header with exactly N values. This is simply defined as a local variable without alloca. (args_decl_constsize): Like args_decl, but requiring a constant N; implemented via args_decl_list. (args_decl_list_dyn): New name for the old args_decl_list which calls alloca. No places in the code depend on this at all, except the definition of args_decl. (args_decl): Retargeted to args_decl_list_dyn. There is some inconsistency in the macro naming in that args_decl_constsize depends on args_decl_list, and args_decl depends on arg_decl_list_dyn. This was done to minimize diffs. Most direct uses of args_decl_list have a constant size, but a large number of args_decl uses do not have a constant size. * eval.c (op_catch): Use args_decl_constsize. * ffi.c (ffi_struct_in, ffi_struct_get, union_out): Likewise. * ftw.c (ftw_callback): Likewise. * lib.c (funcall, funcall1, funcall2, funcall3, funcall4, uniq, relate): Likewise. * socket.c (sockaddr_in_unpack, sockaddr_in6_unpack, sockaddr_un_unpack): Likewise. * stream.c (formatv): Likewise. * struct.c (struct_from_plist, struct_from_args, make_struct_lit): Likewise. * sysif.c (termios_unpack): Likewise. * time.c (broken_time_struct): Likewise.
* funcall: consolidate VM fun handling.Kaz Kylheku2022-10-141-34/+80
| | | | | | | * lib.c (funcall, funcall1, funcall2, funcall3, funcall4): Handle FVM case separately, regardless of the f.variadic flag. If the VM function is variadic, the call can still use the special cases.
* funcall: handle optargs in funcall helpers.Kaz Kylheku2022-10-141-8/+85
| | | | | | * lib.c (funcall, funcall1, funcall2, funcall3, funcall4): Handle some situations when the function is a built-in with optional args.
* funcall: don't route to generic_fun on optargs.Kaz Kylheku2022-10-141-5/+15
| | | | | | | | | | | | | | * lib.c (funcall, funcall1, funcall2, funcall3, funcall4): Do not go through the generic_funcall slow path just because the target function has optional arguments. It's possible that the call is supplying all of the required arguments. Let's try it like that and then if it doesn't work and there are optionals, check again and go the generic_funcall route. This might not be an overall improvement by itself, if we end up going to generic_funcall in more cases than not. However, this change paves the way for more changes: handling some cases of optargs in these helpers.
* New function: macroexpand-struct-clause.Kaz Kylheku2022-10-134-1/+57
| | | | | | | | | | | * stdlib/struct.tl (macroexpand-struct-clause): New function. * autoload.c (struct_set_entries): Autoload struct module on macroexpand-struct-clause. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: macroexpand-match.Kaz Kylheku2022-10-134-0/+57
| | | | | | | | | | | * stdlib/match.tl (macroexpand-match): New function. * autoload.c (match_set_entries): Autoload match module on macroexpand-match. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: macroexpand-place.Kaz Kylheku2022-10-134-8/+87
| | | | | | | | | | | | | | | * stdlib/place.tl (sys:pl-expand): Function renamed to macroexpand-place; env parameter becomes optional. (macroexpand-1-place): New function. (place-form-p, call-update-expander, call-clobber-expander, call-delete-expander): Follow rename. * autoload.c (place_set_entries): Register symbols macroexpand-place and macroexpand-1-place for autoload. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: macroexpand-params.Kaz Kylheku2022-10-135-1/+76
| | | | | | | | | | | | | | | * stdlib/pmac.tl (macroexpand-params): New function, implemented using newly exposed sys:expand-param-macro. * autoload.c (pmac_set_entries): Trigger pmac.tl autload on macroexpand-params symbol. * eval.c (eval_init): Register existing expand_param_macro function as sys:expand-param-macro. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* doc: revise lambda examples.Kaz Kylheku2022-10-121-12/+49
| | | | | | | * txr.1: Fix formatting issue with .IP headings; add more examples showing (. arg) notation, use of : argument for requesting defaulting, and demonstration of presence-indicating variables.
* structs: optional init-exprs now useful in :delegateKaz Kylheku2022-10-113-13/+53
| | | | | | | | | | | | * stdlib/struct.tl (:delegate): Handle the two-element form of the optional parameter, which specifies the usual initializing expression for the default value. This is just passed through as-is to the generated method. Diagnose if the three-element form occurs. * tests/012/oop.tl: Some new tests. * txr.1: Documented.
* json: support standard-style formatting.Kaz Kylheku2022-10-115-36/+127
| | | | | | | | | | | | | | | | | | | | * stream.c (standard_k, print_json_format_s): New symbol variables. (stream_init): New variables initialized. * stream.h (enum json_fmt): New enum. (standard_k, print_json_format_s): Declared. * lib.c (out_json_rec): Take enum json_fmt param, and pass it recursively. Printing for vector and dictionaries reacts to argument value. (out_json, put_json): Examine value of special var *print-json-format* and calculate enum json_fmt value from this. Pass to out_json_rec. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* streams: new function inc-indent-abs.Kaz Kylheku2022-10-114-4/+30
| | | | | | | | | | | * stream.c (inc_indent_abs): New function. (stream_init): inc-init-abs intrinsic registered. * stream.h (inc_indent_abs): Declared. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* put-json: restore indent on unwinding.Kaz Kylheku2022-10-111-1/+7
| | | | | | | | | | | | | | | | | | The following situation is observed in the listener. 1> (put-json #H(() (a 1))) {** print: invalid object a in JSON ** during evaluation at expr-1:1 of form (put-json #H(() (a 1))) 1> 1> An indent established in the aborted JSON print job has been left in the stream. * lib.c (put_json): Save the indent value also, not only the mode. Restore the indent mode and value on unwinding, not just on a normal exit from out_json_rec, similiarly to what obj_print does.
* New quip: future-proof.Kaz Kylheku2022-10-101-0/+1
| | | | * stdlib/quips.tl (%quips%): New entry.
* strings: revert caching of hash value.Kaz Kylheku2022-10-083-34/+4
| | | | | | | | | | | | | | | Research indicates that this is something useful in languages that abuse strings for implementing symbols. We have interned symbols. * lib.h (struct string): Remove hash member. * lib.c (string_own, string, string_utf8, mkustring, string_extend, replace_str, chr_str_set): Remove all initializations and updates of the removed hash member. * hash.c (equal_hash): Do not cache string hash value.
* doc: revise text under :mass-delegate.Kaz Kylheku2022-10-061-3/+5
| | | | * txr.1: Revise text, fixing a grammar error.
* hash: bugfix: don't trim seed to 32 bits.Kaz Kylheku2022-10-061-3/+2
| | | | | | | | | | | | | | This relates to the November 2021 commit 9108e9f8f4434fb29200b08a4b576df47c407c01: hash: 64 bit string and buffer hashing and seeds. In the hash constructor, a 32 bit cast was left behind, needlessly reducing the seed value to 32 bits on 64 bit platforms. * hash.c (do_make_hash): Don't convert the ucnum value to u32_t; just store it.
* doc: hash-eql and hash-equal return fixnum.Kaz Kylheku2022-10-061-0/+7
| | | | | | * txr.1: Document that hash-eql and hash-equal return a value in the range fixnum-min to fixnum-max.
* strings: take advantage of malloc_usable_sizeKaz Kylheku2022-10-065-16/+109
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On platforms which have the malloc_usable_size function, we don't have to store the allocated size of an object; malloc provides us the allocated size (which may be larger than we requested). Here we take advantage of this for strings. And since we don't have to store the string allocated size any more, we use that field for something else: storing the hash code (for seed zero). This can speed up some hashing operations. * configure (have_malloc_usable_size): New variable. Configure test for have_malloc_usable size. We have to try several header files, too. We set the configure variable HAVE_MALLOC_USABLE_SIZE, and possibly HAVE_MALLOC_H or HAVE_MALLOC_NP_H. * lib.h (struct string): If HAVE_MALLOC_USABLE_SIZE is true, we define a member called hash insetad of alloc. Also, we change alloc to cnum. * lib.c: Include <malloc_np.h> if HAVE_MALLOC_NP_H is defined. (string_own, string, string_utf8, mkstring, mkustring, init_str, string_extend, string_finish, string_set_code, string_get_code, length_str, replace_str, chr_str_set): Fix code for both cases. On platforms with malloc_usable_size, we have the allocated size from malloc, so we don't have to retrieve it from the object or store it. Any operations which mutate the string must reset the hash field to zero; zero means "hash has not been calculated". * hash.c (equal_hash): Just retrive a string's hash value, if it is nonzero, otherwise calculate, cache it and return it. * gc.c (mark_obj): The alloc member of struct string is a machine integer now; no need to mark it.
* doc: fix three broken syntax continuation lines.Kaz Kylheku2022-10-061-3/+3
| | | | | | | * txr.1: Syntax markup for file-get-buf, :mass-delegate and file-open options contains an extra space. This causes the syntax not to be correctly processed for the HTML version. nroff-based man page rendering and pdf are fine.
* Syntax: allow separator commas in numeric tokens.Kaz Kylheku2022-10-055-3646/+4220
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * parser.l (remove_char): New static function. (DIGSEP, XDIGSEP, NUMSEP, FLOSEP, XNUMSEP, ONUMSEP, BNUMSEP, ONUM, BNUM): New named lex patterns. (FLODOT): Use DIGSEP instead of DIG. (ONUM): Use ODIG instead of [0-7]. (BNUM): Use BDIG instead of [0-1]. (grammar): New rule for producing NUMBER from decimal token with commas based on BNUMSEP instead of BNUM. This is a copy and paste so that the BNUM rule doesn't deal with the comma removal, not to slow it down. For the octal, binary and hex, we just switch to BNUMSEP, ONUMSEP and XNUMSEP, so they all go through one case. Floating point numbers are also handled with a copy pasted case using FLOSEP. * tests/012/syntax.tl: New test cases. * txr.1: Documented. * genvim.txr (alpha-noe, digsep, hexsep, octsep, binsep): New variables. (txr_pnum, txr_xnum, txr_onum, txr_bnum, txr_num): Integrate separating commas. Some bugs fixed in txr_num, some simplifications, better txr_badnum pattern. * lex.yy.c.shipped: Updated.
* define-struct-clause: add tests.Kaz Kylheku2022-10-051-0/+65
| | | | * tets/012/oop-dsc.tl: New file.
* defstruct: consolidate finalizers into one lambda.Kaz Kylheku2022-10-051-6/+12
| | | | | | | | * stdlib/struct.tl (defstruct): Don't generate a separate finalizer registration for each :fini or :postfini; roll them into a single lambda in the correct order. Their object argument turns into a let block around each piece of code to bind that argument, like had been done for :init and :postinit.
* defstruct: refactor elimination of empty :init/:fini.Kaz Kylheku2022-10-051-18/+18
| | | | | | | | * stdlib/struct.tl (defstruct): When an :init, :fini, :postinit or :postfini has an empty body, do not push it onto its corresponding list. Then later we don't have to check for empty items when generating the code; we know only non-empty items are on the lists.
* define-struct-clause: reject :postfiniKaz Kylheku2022-10-042-3/+4
| | | | | | | * stdlib/struct.tl (define-struct-clause): Disallow the :postfini keyword as clause name. * txr.1: Documented.
* oop: allow multiple :init, :fini, etc.Kaz Kylheku2022-10-044-55/+87
| | | | | | | | | | | | | | | | | | | | | | The motivation is that struct clause macros defined using define-struct-clause may want to introduce their own initializers and finalizers for the specific stuff they add to the struct. The uniqueness restrictions on these initializing and finalizing clauses makes it impossible to use two clause macros which both want to inject a definition of the same initializer or finalizer type. * stdlib/struct.tl (defstruct): Don't enforce that there be at most one clause in the category of :init, :postinit, :fini or :postini. Multiple are allowed. They all execute left-to-right except for :fini. * tests/012/fini.tl: New tests. * tests/012/fini.expected: Updated. * txr.1: Documented.
* New: %fun% mechanism for current function name.Kaz Kylheku2022-10-036-18/+176
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * eval.c (pct_fun_s): New symbol variable, holding the usr:%fun% symbol. (fun_macro_env): New static function. (do_expand): For defun and defmacro, use fun_macro_env to establish an environment binding the %fun% symbol macro, and expand everything in that environment. (eval_init): Intern the %fun% symbol, initializing pct_fun_s, and also register a global symbol macro in that name so that we can freely use %fun% everywhere without worrying that the code will blow up. E.g. a logging macro can use it to get the function name, but still be useful in a top-level form outside of a named function. * stdlib/struct.tl (sys:meth-lambda): New macro. (defstruct, defmeth): Use sys:meth-lambda as a replacement for lambda to set up the %fun% symbol macro. In the :init case which doesn't use a lambda, an open-coded symacrolet does the job. * tests/019/pct-fun.tl: New file. * tests/019/pct-fun.expected: Likewise. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New method: str-addr.Kaz Kylheku2022-10-035-1/+140
| | | | | | | | | | | | | | | | | | | | | * socket.c (sock_set_entries): Intern str-addr symbol. There is no autoload on this because the struct types of which this is a method don't exist if the socket module has not been loaded. * stdlib/socket.tl ((sockaddr-in str-addr), (sockaddr-in6 str-addr), (sockaddr-un str-addr)): New methods. * tests/014/str-addr.tl: New file. This provides coverage not just for the str-addr method, but the hitherto untested address to text functions. This is why the bug was found, that was addressed in the previous commit. The test case which produces "8000::1" was actually producing "800:1". * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* str-in6addr: bugfix: trailing zero in hex problem.Kaz Kylheku2022-10-031-2/+4
| | | | | | | | | | | * stdlib/socket.c (sys:in6addr-condensed-text): The regular expression used in calculating zr is incorrect; the zero in it can match the trailing zero of a nonzero quad, when the intent is only to match zero quads. Hack: we represent zero quads by the character Z and use that for the matching and removal of the longest range of zero quads. Then we filter the Z back to 0.
* New sockaddr-str function.Kaz Kylheku2022-10-025-0/+146
| | | | | | | | | | | | | | | | This function "intelligently" constructs an address object of the right type from a string. * socket.c (sock_set_entries): Autoload socket.tl on sockaddr-str function being accessed. * stdlib/socket.tl (sockaddr-str): New function. * tests/014/sockaddr-str.tl: New file. * txr.1: Documented. * stdlib.doc-syms.tl: Updated.
* doc: equot: replace awkward word.Kaz Kylheku2022-09-291-2/+2
| | | | | * txr.1: describe equote as occuping a semantic midpoint between full and quoting, rather than being "mongrel".
* New :postfini feature in defstruct.Kaz Kylheku2022-09-274-7/+106
| | | | | | | | | | | | | | | | | | | | | | | | The :postfini clause registers a finalizer that runs in the ordinary order: after previously registered ones. This has the effect of allowing a derived structure to run clean-up actions after those of inherited structures. Either order can be useful because the dependencies between base and derived can go in either direction. It's a huge mistake in C++ that it supports only derived-first destructor invocation order. * stdlib/struct.tl (defstruct): Recognize and translate :postfini clause. It's exactly like :fini but omits the t parameter in the finalize call, registering in the natural order. * tests/012/fini.tl (derived): Add :postfini handler. * tests/012/fini.expected: Updated to reflect the messages coming from the postfini handler, which are happening in the correct order. * txr.1: Documented.
* ffi: fix accidental reference to a uint type.Kaz Kylheku2022-09-201-1/+1
| | | | | | * ffi.c (make_ffi_type_struct): Change uint to unsigned. This is a typo, but a uint type is coming from somewhere. I discovered this in an environment where there is no uint.
* configure: bogus line preventing errors being shown.Kaz Kylheku2022-09-201-1/+0
| | | | | | | * configure: when the compiler is not found to be sane, we used to print the errors. But in a 2014 commit, the stray line "conftest && true" was left behind, whose termination status is false, and which thus causes an exit.
* configure: add missing "$@" to early reconfigure.Kaz Kylheku2022-09-191-1/+1
| | | | | | | | | * configure: the reconfigure script is generated twice; once before going through the configuration, with a notice indicating configuration did not complete, and then again after configuration. The first instance is missing the "$@" argument, preventing ./reconfigure being used with arguments after an interrupted configure run.
* android: pointer tagging countermeasure.Kaz Kylheku2022-09-172-0/+22
| | | | | | | | | | | | | | | | | | | | We strip Android's pointer tag from our heap pointer while we own it, then put it back at free time. * configure (android_target): New variable. Set this to y in the test where we detect Android. When setting CONFIG_NAN_BOXING, also set CONFIG_NAN_BOXING_STRIP_TAG if on Android. * gc.c (struct heap): New member, tag. (more): When tag stripping is enabled, clear the top 16 bits of the pointer coming from malloc, and keep those bits in heap->tag. This gets rid of Android's tag. (sweep): When releasing a heap block with free, we must put the tag back into the pointer, from heap->tag.
* Version 282.txr-282Kaz Kylheku2022-09-166-1073/+1109
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated.
* nan-boxing: make default on 64 bit.Kaz Kylheku2022-09-161-2/+1
| | | | | * configure: automatically select NaN boxing on 64 bit platforms.
* nan-boxing: warning fix for gcc 12.Kaz Kylheku2022-09-161-0/+2
| | | | | | | | | | gcc 12.2.0, targetting RISC-V, emitted a warning for the c_f function that the &u expression uses an uninitialized u, even though u is declared with an initializer. Code builds otherwise and tests pass. * lib.h (c_f): Also suppress and re-enable the -Wuninitialized option.
* doc: notes about boxing of numbers.Kaz Kylheku2022-09-161-0/+38
| | | | | | | * txr.1: In the Numbers section, talk about fixnum and bignum, and the boxed/unboxed terminology, as well as the possibility that floating-point may be unboxed, and how to detect that.
* nan-boxing: build on older gcc.Kaz Kylheku2022-09-162-14/+16
| | | | | | | | | | | | Older GCC 4.x versions do not support diagnostic pragmas in functions and don't have push pragmas for diagnostics. * arith.c (flo): Put the diagnostic disabling pragma stuff outside of the function. Instead saving and restoring the status with push and pop, we just disable the aliasing warning and re-instate it as a warning. * lib.h (c_f): Likewise.
* seq-iter: bugfix: floating-point ranges.Kaz Kylheku2022-09-152-24/+71
| | | | | | | | | | | | | | | | | | | | | | * lib.c (seq_iter_get_range_bignum): Static function renamed to seq_iter_get_range_number because it in fact generalizes to numbers. (seq_iter_peek_range_bignum): Renamed to seq_iter_peek_range_number. (seq_iter_get_rev_range_bignum): Renamed to seq_iter_get_rev_range_number. (seq_iter_peek_rev_range_bignum): Renamed to seq_iter_peek_rev_range_number. (si_range_bignum_ops): Renamed to si_range_number_ops. (si_rev_range_bignum_ops): Renamed to si_rev_range_number_ops. (seq_iter_init_with_info): Handle ranges where the from value is floating-point. Also, if the from-value is bignum that fits into cnum range, we now try to handle that as a cnum range. * tests/012/iter.tl: New tests.
* compiler: bug: bad basic-block merge across end insn.Kaz Kylheku2022-09-154-6/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The bad situation reproduced as a miscompilation of some prof forms at *opt-level* 5 or above. The basic idea is that there is a situation like this prof t2 ... profiled code here producing value in t8 mov t2 t8 end t2 end t2 The code block produces a value in t8, which is copied into t2, and executes the end instruction. This instruction does not fall through to the next one but passes control back to the prof instruction. The prof instruction then stores the result value, which came from t2, back into the t2 register and resumes the program at the end t2. The first bad thing that happens is that the end instructions get merged together into one basic block. The optimizer then treats them without regard for the prof instruction, as if they were a linear sequence. It looks like the register move mov t2 t8 is wasteful and so it eliminates it, rewriting the end instruction to: end t8 end t8 Of course, the second instruction is now wrong because prof is still producing the result in t2. To fix this without changing the instruction set, I'm introducing another pseudo-op that represents end, called xend. This is similar to jend, except that jend is regarded as an unconditional branch whereas xend isn't. The special thing about xend is that a basic block in which it occcurs is marked as non-joinable. It will not be joined with the following basic block. * stdlib/asm.tl (xend): New alias opcode for end. * stdlib/compiler.tl (comp-prof): Use xend to end prof fragment, rather than plain end. * stdlib/optimize.tl (basic-block): New slot, nojoin. If true, block cannot be joined with next one. (basic-blocks jump-ops): Add xend to list of jump ops, so that a basic block will terminate on xend. (basic-blocks link-graph): Set the nojoin flag on a basic block which contains (and thus ends with) xend. (basic-blocks local-liveness): Add xend to the case in def-ref that handles end. (basic-blocks (peephole, join-blocks)): Refuse to join blocks marked nojoin. * tests/019/comp-bugs.tl: New file with miscompiled test case that was returning 42 instead of (42 0 0 0) as a result of the wrong register's value being returned.
* compiler: bug: scoping of lambda optionals.Kaz Kylheku2022-09-152-17/+20
| | | | | | | | | | | | | | | | | | | | | | The scoping is not behind handled correctly for optional variables. The init-forms are being evaluated in a scope in which all the variables are already visible, instead of sequentially. Thus, for instance, variable rebinding doesn't work, as in (lambda (: (x x)) ...). When the argument is missing, x ends up with the value : because the expression refers to the new x, rather than the outer x. * stdlib/compiler.tl (compiler comp-lambda-impl): Perform the compilation of the init-forms earlier. Use the same new trick that is used for let*: the target for the code fragment is a locaton obtained from get-loc, which is then attached to a variable afterward. The spec-sub helper is extended with a loc parameter to help with this case. * tests/012/lambda.tl: New test case that fails without this fix.
* build: remove .tlo.tmp file before compiling.Kaz Kylheku2022-09-151-0/+1
| | | | | | | | | * Makefile (COMPILE_TL): Before we invoke txr --compile, let's make sure there isn't a .tmp file left over by a previous failed compile job. Otherwise --compile will consider that to be an up-to-date compiled file due to its newer timestamp relative to the .tl file, and we end up renaming that to .tlo.
* compiler: eliminate rename-var hack.Kaz Kylheku2022-09-151-13/+6
| | | | | | | | | | | | | | | * stdlib/compiler.tl (env rename-var): Method removed. (compiler comp-let): Instead of initially creating a let* variable as a gensym, and then renaming it after compiling the init expression, we now just obtain the location not bound to a variable, use the location when compiling the init form, and bind the location to a variable right after. This is cleaner since the only thing we are mutating now is the environment, and we are not wastefully allocating a gensym. The real motivation is that this is building up to a bugfix in compiling optional variables in lambda: stay tuned!
* compiler: unbundle v-reg allocation from env extensionKaz Kylheku2022-09-151-6/+10
| | | | | | | | | | | | * stdlib/compiler.tl (env get-loc): New method for allocating v-reg, split out of extend-var and extend-var*. Now there is a check for the v-cntr overflow. (env (extend-var, extend-var*)): Taken an optional loc parameter, so the caller can optionally allocate a v-reg location using get-loc, and then specify that location when creating a variable. If the argument is omitted, use get-loc.