-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
reader.lisp: First try at parsing C numeric literals #7
reader.lisp: First try at parsing C numeric literals #7
Conversation
Thank you very much. I hadn't thought of implementing C numeric literals until I saw your PR. |
Thank you for the fast reply! Apparently I missed testing with single-digit literals, for starters, and didn't try your tests against the new code. I will push a new commit later today - sorry for the inconvenience. What do you think about the general appearance of the code? Am I going about it the right way? |
Hi again, just letting you know I've pushed a new commit - test results are same as before now: "Success: 168 tests, 1265 checks." |
I should mention the motive for this (and future) pull requests - hopefully it's compatible with your goals for this project: I need to implement quite a few network protocols whose authoritative definition is mostly in C header files. Toward that end I'm writing a SWIG XML parser in CL, as other CL tools I've tried don't match this usage pattern. SWIG does a bit of constant folding, but not enough. With this pull request, I've managed to import most #defines from a test C header file, and can move on to implementing enum and struct handling. It is my hope to eventually create a native CL system that imports C header files without depending on external tools, with the help of with-c-syntax . |
I was surprised to see your purpose. My purpose was just for fun... For example, looking at Duff's Device C code in Lisp and laughing at it. I will cooperate you if this code is useful for something. I review your commits; give me some time. But I still need to hear what you're going to do. e.g. CFFI-grovel (https://common-lisp.net/project/cffi/manual/html_node/The-Groveller.html) is just for the purpose. Current And, SWIG itself has a support for Common Lisp. I would like to know why these tools were not working for you. |
I knew you'd be surprised, I too got scared of the possibility of someone actually using it in the way presented in the README. :-) Feel free to take your time reading the following, or not at all; I've already overcome my first block by writing this patch. TL;DR: cl-autowrap is unfortunately not working for me; I need a lightweight and more native replacement I can hack on, and with-c-syntax seems like it could play a part in it. Here is some more background to what I'm doing - please keep in mind while reading it that for now I only want to implement as much code as is needed to get to the point of actually implementing protocols - not create complete implementations of anything described. I first tried using cl-autowrap, which didn't work for me for two reasons:
After realizing 2. above I didn't try its fork, claw, either. There is a chance Vacietis has a usable parser, but I was too afraid to go near that, seeing how many failed before me. Regarding SWIG, Common Lisp (along with a few more languages) support was dropped in version 4.0, and I'd prefer to implement the integration in CL, instead of a mix of C/C++ and SWIG templates. I am aware of C struct alignment intricacies, and CFFI-Grovel is indeed the tool I intend to use for the next steps! However, as I need to generate (and maintain) grovel wrappers for many C header files from various C projects, some of which are moving targets, I have to automate the process to the extent it is possible. Let's call the system I'm writing cffi-grovel-generator for this discussion. So, my thought process is:
While implementing the above, I may find out that the SWIG XML -> Grovel template process is enough for my purposes, in which case I'll have no use for with-c-syntax for the moment. if OTOH I find out that SWIG cannot work in an architecture-independent way, as I've read on Reddit, I'll expedite my efforts on getting with-c-syntax to work as a configurable C/CPP parser. Practically speaking, the whole thing will have many similarities with cl-autowrap, but it will use SWIG XML/with-c-syntax instead of Clang as the "frontend", GCC instead of Clang as the "backend", and the guts will be written in CL instead of C++. Wrt with-c-syntax, it may have been written for fun, but it's already parsing a decent subset of C nevertheless. ;-) In every case, with-c-syntax will always be able to be used to write CL in C syntax for fun (or for scaring babies). |
I understand a bit now. I've been writing the cffi-grovel files by hand if required. I've only done this for small libraries, so hand-writing was sufficient, but I understand that it's hard when there are a lot of them. I did some digging and found the following Reddit thread. The context is same? I haven't yet figured out how with-c-syntax will be used, but if you think there is a possibility that this fun library can be used, by all means use it. I may also use the cffi-grovel-generator.
I didn't know that.. It feels sad.
To put First point. The current with-c-syntax only supports the C90 grammar. This is not a problem if you are only parsing header files as you say, because headers should only contain declarations. However, the header may contain Second point. I think CPP is tough. Since Common Lisp has If we do implement CPP, I think we need to make some compromises..
😁 |
@@ -250,6 +250,71 @@ This is bound by '#{' read macro to the `*readtable*' at that time.") | |||
(read-slash-comment stream char | |||
#'read-single-or-equal-symbol)) | |||
|
|||
(eval-when (:compile-toplevel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think +acceptable-numeric-characters+
may be referred not only in compile-time. I prefer to use (:compile-toplevel :load-toplevel :execute)
here.
(eval-when (:compile-toplevel) | |
(eval-when (:compile-toplevel :load-toplevel :execute) |
src/reader.lisp
Outdated
(defconstant +acceptable-numeric-characters+ | ||
'(( 2 . (#\0 #\1)) | ||
( 8 . (#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7)) | ||
(10 . (#\- #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\.)) | ||
(16 . (#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\A #\B #\C #\D #\E #\F #\a #\b #\c #\d #\e #\f))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend to use (alexandria:define-constant ... :test 'equal)
to define a list constant, to suppress redefinition errors.
I use it here:
https://github.com/y2q-actionman/with-c-syntax/blob/master/src/with-c-syntax.lisp#L244-L281
(16 . (#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\A #\B #\C #\D #\E #\F #\a #\b #\c #\d #\e #\f))))) | ||
|
||
(defun read-bare-number (&optional (base 10) (stream *standard-input*) (c0 nil)) | ||
(let ((string (make-array '(0) :element-type 'character :adjustable t)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make it work in my environment (SBCL 2.1.3 on MacOSX), :fill-pointer 0
is required.
(let ((string (make-array '(0) :element-type 'character :adjustable t)) | |
(let ((string (make-array '(0) :element-type 'character :adjustable t :fill-pointer 0)) |
((member c acceptable-characters) (vector-push-extend (read-char stream) string)) | ||
(t nil))) ; Finish processing if any other character | ||
(if floatp | ||
(let ((*readtable* named-readtables::*standard-readtable*)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think with-standard-io-syntax
is usable for here, because It resets *readtable*
and *read-base*
to 10.
(let ((*readtable* named-readtables::*standard-readtable*)) | |
(with-standard-io-syntax |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I confirmed this commit fixed existing tests. thank you
I finally added numeric literals. Thank you. |
Hello and thank you for your work!
This is a first, buggy, try at parsing C numeric literals, would love if you could review and comment on it!