Commit graph

1190 commits

Author SHA1 Message Date
Marius Gerbershagen
02ef05479c ext:run-program: support unicode characters for the process name, arguments and environment
The encoding is determined by ext:*default-external-format* as usual.
2023-02-26 17:03:09 +01:00
Daniel Kochmański
feff551c31 Merge branch 'inline-closure-global' into 'develop'
Fix compiler bug regarding inlining for global functions that are closures

See merge request embeddable-common-lisp/ecl!280
2023-02-14 21:05:19 +00:00
Daniel Kochmański
8ba1bb888a si_process_lambda_list: process all variables in an uniform manner
The comment mentioned that aux variables (the sixth value) are returned the
same way as requireds, optionals and keywords however factually that was not
the case - the number of variables was not the first element of the list. This
commit updates the function and all its callers.
2023-01-22 20:12:58 +01:00
Daniel Kochmański
b62cf6b7ed cmuutil: don't use setf to enable use in early macros
There was no real utility in using SETF there yet it made using collect macros
not possible in macros that are used to define ECL.
2023-01-22 20:12:58 +01:00
Tarn W. Burton
eeb91e8005 Avoid parsing parameters after colon or at sign 2023-01-06 11:27:22 -05:00
Marius Gerbershagen
fdcf5e7eff cmp: disable inlining for global functions that are closures
For functions already compiled and loaded, we simply check if the
definition is a closure. For functions defined in the same file, we
don't store their definition in the compiler environment but instead
use *global-funs*. The advantage is that this directly allows us to
determine whether a function is a closure or not and we don't have to
run the first compiler pass again each time we inline the function.

This commit also fixes some minor issues with the inline policy,
described in detail as follows:

1. The inline policy differed subtly between `proclaim` and `declaim`.
If a file like

(eval-when (:compile-toplevel)
  (proclaim '(inline f)))
(defun f ...)

was compiled (but not loaded), subsequent compilations would inline
`f` but for

(declaim (inline f))
(defun f ...)

the function `f` would only get inlined if the file was compiled _and_
loaded. We now use the latter approach for both cases. Thus, calling
`compile-file` without `load` has no side-effects regarding whether
functions are inlined or not.

2. We did not distinguish between functions which were declared inline
at a global versus local level such that e.g. in

(locally
    (declare (inline f))
  (defun f ...))

the function f would get inlined outside the scope of the `locally`
form. This is changed now such that local inline declarations only
apply to the scope in which they are made.

3. Inline declarations were made by expanding into statements like

(eval-when (:compile-toplevel)
  (c::declare-inline ...))

during the macroexpansion of `defun`. However this only works if the
`defun` appears at the toplevel and hence in code like

(declaim (inline f))
(let (...)
  (defun f ...))

the function `f` could not get inlined later on in the same file. This
is fixed now by calling the code which should run during compilation
directly when macro expanding defun.
2022-12-30 16:14:53 +01:00
Marius Gerbershagen
4d7ee7a301 fix typo introduced in commit de15a8542 2022-10-22 20:02:07 +02:00
Marius Gerbershagen
de15a85420 cosmetic: fix some compiler warnings 2022-10-22 19:58:24 +02:00
Marius Gerbershagen
482d09ed10 format.lsp: fix incorrect roundings for ~e directive
Due to rounding issues the exponent can be different than what we
guessed. For example in the following only one digit should appear
before the decimal point such that

(format nil "~,1e" 9.9) => 9.9e+0

is correct but

(format nil "~,1e" 9.9) => 10.0e+0

is incorrect, has to be 1.0e+1.
2022-09-24 21:04:43 +02:00
Marius Gerbershagen
0506ce34a3 format.lsp: fix format ~e with width argument
Fixes #632.
2022-09-18 16:33:00 +02:00
Marius Gerbershagen
d55d31df3b format: print 0 after decimal point with ~e for integer input
Example: (format t "~e" 1.0) used to print 1.e+0, now prints 1.0e+0

Code adapted from SBCL.
2022-09-03 19:38:51 +02:00
Daniel Kochmański
1ce4713804 floats: add operators to convert between floats and bits (integers)
The interface is in the system package (that is - not part of the official api).
2022-07-07 13:24:38 +02:00
Daniel Kochmański
ea92cba4ce defstruct: fix incorrect compatibility checks
Previously we've checked whether the new defstruct is compatible with the old
one like this:

(let ((old-desc (old-descriptions struct)))
  (when (and old-desc (null (compat old-desc new-desc)))
    (error "incompatible")))

This was to allow new definitions. This is incorrect, because allows first
defining a structure without slots and then adding some, like

(defstruct foo)
(defstruct foo xxx)

The new check verifies whether the structure is a structure and then compares
slot, so the verification is not inhibited when the first definition doesn't
have slots.

Moreover we now test for slot names being string= because:
a) initargs and functions ignore the package (so functions will be redefined)
b) we want to match gensymed slot names
This is compatible with what sbcl does.

On top of that check for duplicated names and signal an error if there are
such.
2022-02-05 15:03:22 +01:00
Daniel Kochmański
19112f0c95 Merge branch 'branch-cuts' into 'develop'
numbers: be consistent with branch cuts and signed zero

Closes #661

See merge request embeddable-common-lisp/ecl!266
2022-02-04 20:09:05 +00:00
Marius Gerbershagen
8f51683516 printer: don't pretty print stuff in _ecl_write_list
The pretty printer should handle this and we should not pretty print
objects if *pretty-print* is false.

Closes #673.
2022-01-31 21:05:27 +01:00
Marius Gerbershagen
8da3475b02 numbers: be consistent with branch cuts and signed zero
Let the sign of zero determine from which side branch cuts are
approached, no matter whether we use C99 complex numbers or not.

Disable the (acosh -∞) test. This test fails with the new code, but
was supposed to be commented out anyway. In general, we don't
guarantee anything about infinity if complex numbers are involved.

Closes #661.
2022-01-09 15:01:04 +01:00
Daniel Kochmański
de1b587d78 define-compiler-macro: fix the documentation expansion
Previously it set the documentation slot for the function - it should do
it for the compiler-macro. Fixes #658.
2021-11-06 09:34:25 +01:00
Marius Gerbershagen
5f65deea5b multithreading: implement optional timeout for mp:get-lock 2021-08-29 17:25:21 +02:00
Marius Gerbershagen
579a8d4380 run-program: simplify with-process-lock
We already have a race condition between mp:get-lock and
mp:holding-lock-p, there is no point in trying to make sure the lock
is released at all costs during an interrupt.
2021-08-29 17:23:19 +02:00
Marius Gerbershagen
0f737b6ba6 multithreading: implement mutexes and condition variables using OS primitives
Replace slow homegrown mutex implementation by standard OS functions.

We try our best to be interrupt safe, however a completely safe
implementation is impossible (unless one completely removes the ability
to interrupt a thread waiting on a mutex). There is always a window
after the OS specific function has returned, but before we can set
the owner, in which interrupts will see an inconsistent state of the
mutex with regards to owner and count.

Condition variables are now based on OS functions as well. Timed
waiting on condition variables has also been implemented.
2021-08-29 17:23:19 +02:00
Marius Gerbershagen
ff8cf4d3c1 pathnames: handle unicode characters
On Unix, pathnames are converted into the default encoding specified
by ext:*default-external-format* and back. On Windows, the operating
system already gives us utf16 encoded pathnames, so we use those.

ecl_namestring with ECL_NAMESTRING_FORCE_BASE_STRING encodes with the
specified encoding. Decoding is handled individually in the filesystem
functions.

Includes a minor refactor of list_directory, changing the
PARSE_DIRECTORY_ENTRY macro into an inline function.

Closes #609, #549.
2021-08-19 14:00:28 +02:00
Marius Gerbershagen
548309e165 cmdline options: also set ext::*default-external-format* when --encoding is given 2021-08-19 13:51:55 +02:00
Daniel Kochmański
e68e682784 Merge branch 'add-ed-hooks' into 'develop'
Add ed hooks

See merge request embeddable-common-lisp/ecl!253
2021-07-01 16:17:45 +00:00
Tarn W. Burton
c0e56f23af Add ed hooks 2021-07-01 11:15:05 -04:00
Tarn W. Burton
3d09bebe62 Add CDR 6 feature keyword 2021-07-01 07:44:14 -04:00
Marius Gerbershagen
0638932696 run-program: remove redundant finalizer for windows handles
We have already registered a finalizer for the external process object
which calls external-process-wait. This in turn calls si::waitpid
which closes the handle once the process has exited.
2021-06-12 21:26:47 +02:00
Marius Gerbershagen
6f3f52d4f0 destructuring-bind: signal program-error instead of an ordinary error
Make the ansi-test suite happy.
2021-03-03 22:14:28 +01:00
Marius Gerbershagen
f5c2416ea1 prog1: fix return values for the case of a single form with multiple values
prog1 returns only the first value.

Closes #617.
2021-02-15 21:14:44 +01:00
Marius Gerbershagen
210012375d define-setf-expander: fix lambda-list handling
define-setf-expander takes a macro lambda-list. Previously, we handled
the &environment part of this list manually, but &body, &whole
parameters and destructuring did not work.

To fix this, we use sys::expand-defmacro in define-setf-expander. This
necessitates a change in the arguments of the setf-methods stored by
do-define-setf-function: we now pass the whole form (including the
name of the access-function) in the first argument and the environment
in the second argument, like in an ordinary macro function.

Fixes #627.
2021-02-13 19:31:50 +01:00
Marius Gerbershagen
5cd97358af 21.2.1 release 2021-01-30 19:27:41 +01:00
Marius Gerbershagen
1effa6a160 predlib.lsp: fix type comparisons involving gray streams
Due to gray:fundamental-stream being treated as a built-in type,
subclass relationships were not checked (see added test case).
Fixes #614.
2020-11-06 20:35:22 +01:00
Daniel Kochmański
8e2d78a4b2 loop: destructuring: replace MAPCAR with a DO* loop
Simple MAPCAR must be replaced by a slightly more complicated DO, because the
list may not be a proper list. I want to dedicate this ballad to myself.

    This is a tale of a sorry quest
    To master pure code at the T guru's behest
    I enrolled in a class that appealing did seem
    For it promised to teach fine things like T3 and Scheme

    The first day went fine; we learned of cells
    And symbols and lists and functions as well
    Lisp I had mastered and excited was I
    For to master T3 my hackstincts did cry

    I sailed through the first week with no problems at all
    And I even said "closure" instead of "function call"
    Then said the master that ready were we
    To start real hacking instead of simple theory

    Will you, said he, write me a function please
    That in lists would associate values with keys
    I went home and turned on my trusty Apollo
    And wrote a function whose definition follows:

        (cdr (assq key a-list))

    A one-liner I thought, fool that I was
    Just two simple calls without a COND clause
    But when I tried this function to run
    CDR didn't think that NIL was much fun

    So I tried again like the good King of yore
    And of code I easily generated some more:

        (cond ((assq key a-list) => cdr))

    It got longer but purer, and it wasn't too bad
    But then COND ran out and that was quite sad

    Well, that isn't hard to fix, I was told
    Just write some more code, my son, be bold
    Being young, not even a moment did I pause
    I stifled my instincts and added a clause

        (cond ((assq key a-list) => cdr)
              (else nil))

    Sometimes this worked and sometimes it broke
    I debugged and prayed and even had a stroke
    Many a guru tried valiantly to help
    But undefined datums their efforts did squelch.

    I returneth once more to the great sage of T
    For no way out of the dilemma I could see
    He said it was easy -- more lines must I fill
    with code, for FALSE was no longer NIL.

        (let ((val (assq key a-list)))
           (cond (val (cdr val))
                 (else nil)))

    You'd think by now I might be nearing the end
    Of my ballad which seems bad things to portend
    You'd think that we could all go home scot-free
    But COND eschewed VAL; it wanted #T

    So I went back to the master and appealed once again
    I said, pardon me, but now I'm really insane
    He said, no you're not really going out of your head
    Instead of just VAL, you must use NOT NULL instead

        (let ((val (assq key a-list)))
           (cond ((not (null? val)) (cdr val))
                 (else nil)))

    My song is over and I'm going home to bed
    With this ineffable feeling that I've been misled
    And just in case my point you have missed
    Somehow I preferred (CDR (ASSQ KEY A-LIST))

                -- Ashwin Ram,
                   "A Short Ballad Dedicated to Program Growth"
2020-08-17 20:18:31 +02:00
Daniel Kochmański
809b9de86f loop: destructuring: allow values shorter than variables
We achieve that by adding &optional to every sublist. Fixes #605.
2020-08-14 16:43:00 +02:00
Eric Timmons
bbbc655931 process: Propagate EOFs to child process on virtual input streams
When piping streams to child processes, if the virtual input stream returns an
EOF, close the pipe to the child.
2020-07-16 15:41:32 -04:00
Daniel Kochmański
f9db80dcbf cmp: for LAMBDA use an associated function-block-name
That makes lambda with a declaration si:function-block-name behave
consistently with ext:lambda-block (and in eval-macros
ext:lambda-block expands to have this declaration too to behave in
turn consistently with how the compiler treats ext:lambda-block).
2020-06-15 12:34:10 +02:00
Marius Gerbershagen
9c9f07c4ce mislib.lsp: fix argument type if long-long is not available 2020-06-12 20:50:02 +02:00
Karsten Poeck
5bfe616bd0 Fix declariotion for complex for variable 2020-05-06 21:46:56 +02:00
Marius Gerbershagen
c6b4296bb8 cosmetic: fix some compiler warnings 2020-04-29 20:35:37 +02:00
Daniel Kochmański
f152a3000d Merge branch 'fix-576' into develop 2020-04-24 11:50:13 +02:00
Moritz Petersen
660b1bec69 Always close stream in with-output-to-string & cosmetic changes
Fix #576, Related to !197, 72560efa5a

with-output-to-string is required to close the output stream that it provides
for the extent of the body forms [1]. The current definition does not do that.

This change wraps the body forms in unwind-protect clauses to ensure the stream
is always closed on exit. Because declarations cannot appear at the beginning of
progn forms, any potential declarations are extracted from the body forms and
moved to the beginning of the surrounding let form's body.

element-type is no longer bound to a gensym, but evaluated inside the let body.

The uppercased names are downcased for a more coherent appearance.

[1]: http://www.lispworks.com/documentation/HyperSpec/Body/m_w_out_.htm
2020-04-24 11:42:23 +02:00
Daniel Kochmański
eea597de34 20.4.24 release
Announcement proposal. When this is merged to the develop branch, then
we should make a PR against master and merge. Then we shall publish
tarballs and the announcement on the website.
2020-04-21 11:24:02 +02:00
Daniel Kochmański
1fe88da7f1 Merge branch 'close-with-input-from-string-stream' into 'develop'
Always close stream in with-input-from-string

See merge request embeddable-common-lisp/ecl!197
2020-04-18 15:59:26 +00:00
Moritz Petersen
72560efa5a Always close stream in with-input-from-string & Cosmetic changes
The Common Lisp Standard defines that with-input-from-string always closes the
input stream that it creates. But with the current definition it would only be
closed in the case of an index variable being provided.

This change wraps the code for both cases (index given or not) in a unified
unwind-protect form, updates the index if present, and always closes the
stream. It also unifies the processing of declarations.

Downcase code & fix indentation:

Set the uppercased code in lower case to harmonise appearance and increase
readability. Differentiated indentation for the first forms in unwind-protect
and multiple-value-prog1 helps to understand their special meaning.
2020-04-18 17:44:41 +02:00
Daniel Kochmański
2b5b2374b6 util: add binding macros from alexandria for convenience
if-let, when-let, when-let* are well known utilities and we have
plenty of places where we could use these idioms.
2020-03-26 13:42:37 +01:00
Marius Gerbershagen
f776bd8615 fix daylight savings time detection for win64 2020-03-07 22:26:43 +01:00
Daniel Kochmański
471f3f8312 function-lambda-list: bytecmp: always use the annotation
I think that the old method is a relic from the past when bytecodes
had a different representation. bytecompiled functions also have
proper annotations so there is no need to attempt to disassemble their
lambda lists manually. Closes #561.
2020-02-11 17:06:51 +01:00
Marius Gerbershagen
b85d628955 run-program: fix handling of nil argument to :if-output-exists, :if-input-does-not-exist
According to the documentation, we were supposed to return nil, but
instead we signaled a bogus error like

 :INPUT argument to RUN-PROGRAM does not have a file handle:
 #<output stream "/dev/null" 0x5645a22a5280>
2020-02-07 21:38:30 +01:00
Marius Gerbershagen
10c4f6e6d6 ffi: fix bogus error when using load-foreign-library with bytecmp
As it modifies the linker flags, the do-load-foreign-library function
only works with the C compiler.
2020-01-27 20:58:21 +01:00
Marius Gerbershagen
00934b358b format: don't signal an error if ~T and ~<...~> are mixed
Only ~:T is forbidden inside ~<...~> or in conjunction with
~<...~:;...~>.
Fixes #540.
2019-12-20 13:37:25 +01:00
Daniel Kochmański
7dbde99b7c ffi: defcallback: unify behavior of dffi and compiled versions
- normalize return-type from NIL to :void, ARRAY and '* in interpreted
  dffi implementation -- it is already normalized in sffi

- remove invalid path where argument type was not a valid elementary
  FFI type

  when it was not c1-defcallback pushed result of add-object to
  arg-type-constants and tried to pass the data as opaque
  pointers. That said it could never work, because:

  1. add-object could return a string (i.e for known symbols expanding
     to ECL_SYM) and they were fed as elementary FFI type leading to
     errors during compilation by C compiler (invalid enum type)

  2. when ecl_make_foreign_data was called to pass opaque objects a
     function FFI:SIZE-OF-FOREIGN-TYPE was called which resulted in
     error (because return type is not a valid elementary FFI type
     what this code path was meant to be)

Moreover we validate both return type and argument types during the
first compiler to fail as early as possible (previously only argument
types were validated early).

- some cosmetic fixes like indentation or redundant PROGN
2019-12-16 10:20:42 +01:00