nakkaya / ferret

Ferret is a free software lisp implementation for real time embedded control systems.
https://ferret-lang.org
BSD 2-Clause "Simplified" License
1.08k stars 48 forks source link

More advanced string creation functions #21

Open drone29a opened 6 years ago

drone29a commented 6 years ago

I have a sort of odd use case for ferret where I'm using it to interop with some C++ code in order to generate FFI bindings. A part of this requires generating source code in a different language and having the ability to apply templates would be helpful. Having format or even str would be useful for this case.

I went ahead and hacked up a replacement for str that relies on the std::string class, but would be nice to have str and format in core. Happy to send a PR with my str, though not sure it handles all cases and, as I said, it requires std::string.

Thanks for ferret, it's kind of weird but I like it as a hacky way to get at C++. :)

nakkaya commented 6 years ago

Hi,

Currently string support is problematic. Most embedded targets lacks std::string, plain C strings are also problematic due to them using continuous memory, good for performance bad for memory fragmentation. My current plan is to keep rudimentary string support as is, since currently A Ferret string is just a sequence of numbers Ferret's sequence functions allows basic string operations on them and they are platform independent. And implement proper str functions as platform dependent modules still in core but they are opted in i.e require ferret.string that uses a std::string or ferret.arduino.string that uses String.

drone29a commented 6 years ago

The simple string type Ferret supports is just fine. My gripe is there's no way for me to create a new string in Ferret from runtime values without dipping into C++.

Imagine there's a Person struct with std::string first_name and std::string last_name members. As a simple example, I'd like to be able to represent a struct instance as a Ferret string like this: (defn Person->string [p] (str "first name: " (get-first-name p) " last name: " (get-last-name p))

It's completely possible I've missed the Ferret way to do this. But if not, the runtime generation of Ferret strings could be provided without changing how Ferret strings are represented. Right?

__ edit: Modified example so str only takes std::string or C-strings args.

nakkaya commented 6 years ago

I've modified new-string from a macro to a function so instead of,

(str "first name: " (get-first-name p) " last name: " (get-last-name p)

you can write new-string, it will concat all arguments and return a string,

(new-string "first name: " (get-first-name p) " last name: " (get-last-name p))

This also fixes the issue of once you use a lazy-sequence function on a string, it is no longer a string but a lazy-sequence this will convert it to a string. Does this fix works for your use case?

drone29a commented 6 years ago

Thanks! I didn’t get a chance to look at the code or try it today, but sounds like it’ll work.