-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
StringStream & more stdlib modules support for JS/NimScript #14095
Conversation
reason: it allows writing portable code in between releases even if switching branches/versions/commits. |
|
Some notes: It's possible to only support I can either implement Streams would have benefited from a kind of Supporting |
IMO we should pick whatever solution will maximize the amount of code that works on all backends c,vm,js (with same semantics) and code reuse (as few backend-specific tweaks as possible).
seems like a totally reasonable requirement, we shouldn't restrict to the minimal common features amongst -d:nimbrowser and -d:nodejs. we can simply add a runtime check if needed, eg
in #13451 I've added nodejs support for CT failure vs RT failureThis is a subtle point: failing at runtime (eg missing requirements) instead of disable code at CT will simplify a lot of code (less backend-specific branching, more availability across backends), because the runtime failure happens in only a few key places, whereas disabling code at CT is "viral" and affects all the callers, regardless whether runtime code will actually use that feature, eg: I want this code to work with var cond = someRuntimeCondition()
if cond:
var s = newFileStream("foo.txt")
fun(s)
else:
var s = newStringStream("bar")
fun(s) This in turns make code that calls this work without being disabled at compile time just because some not-taken-branch would fail.
i don't understand;
that makes sense to me (as long as it doesn't break code?) |
I'm talking about the generic
That makes sense. You were right about it being out of scope though I'm not going to implement it in this PR, I don't have many good ideas on it.
It would, I'm just complaining that it doesn't exist already. I've rolled back the integer/bool overloads, a library that performs string -> ArrayBuffer -> integer would be much more elegant. |
oh ya, I'm not suggesting implementing it in this PR, I'm just saying to simply remove import streams
var cond = someRuntimeCondition()
if cond: echo newFileStream("foo.txt").readAll # fails at RT if goes here, and in future will work for -d:nodejs
else: echo newStringStream("bar").readAll # works if goes here I tried that modification from your PR and it did work; when changing runtime condition to false, it gives an easy-to-understand errmsg:
benefit: no "viral" propagation of CT disabled code, so that more code works so long it's not attempting to open a newFileStream, which is unlikely to occur by accident; less backend-specific branching via
I see; yes, |
Oh, that's good about fs.
If I understand correctly then I should reenable Also, do I change the version checks or can that be done by someone else after the merge? |
sorry which one for example? like # in newFileStream:
when defined(js):
# TODO for future work: support nodejs via `fs` builtin module
doAssert false, "js not yet supported; context: " & filename
else:
var f: File
if open(f, filename, mode, bufSize): result = newFileStream(f)
sorry, I need more context to understand (3am here..) |
Sorry for keeping you up. I meant StringStream procs, if they get a pointer that isn't try:
cast[ptr string](buffer)[][0..<result] = s.data[s.pos..<s.pos+result]
except:
raise newException(ValueError, "reading to buffer pointer failed, did you use a non-string pointer?", getCurrentException()) For context about the versioning:
Should I do any one of these things (replace with >= (1, 3, 2) or increment version) or can they be done after the PR? |
leave it like you did for now, we can always change later if ppl agree |
sorry can you give me a simple complete example I can run on top of your PR to see what you mean exactly? (ideally one where calling stream apis would end up with a pointer that is a ptr string, and one where it won't) because right now this works in your pr: when true:
import streams
var s2 = newStringStream("abc")
doAssert s2.readAll == "abc"
s2.write("def") |
import streams
var s = newStringStream("abcd")
var i: int
discard s.readData(addr i, sizeof i) # this is what read[T](Stream, var T) does
echo i You get |
I cannot merge this, you used |
sadly, |
It's ok, #14099 had to get merged first anyway |
@hlaaftana i have some more feedback, please hold on before any merge :) also, can you please rebase + force push instead of merge? otherwise really hard to follow your commits ; that's what i do in all my PR's ; any conflicts are almost always easy to fix and when they're not i squash what needs to be squashed before rebase (assuming you already know all this stuff but just in case: |
|
The new code in cstrutils is just copy pasted from strutils (can be reused right now, just I understand that |
Ormin caused the test failures on azure but builds.sr.ht complains about the pegs test, most likely an unrelated CI issue. Should be good regardless |
the failure is because you haven't rebased against devel so my fix #14134 wasn't picked up; if you |
Could've sworn I rebased it before. Fine now. |
Merge? |
@hlaaftana amazing job! this is 1 big step closer to the goal of making all of stdlib available for all targets |
…#14095) * StringStream & more stdlib modules support for JS/NimScript * change back pegs test in line with nim-lang#14134
Closes #12417, closes #11066, closes #4247
streams.StringStream
now compiles for JavaScript, the implementation was already there it was only enabled for compile time for some reason (though it only implemented readDataStr and not read/peek/writeData). StringStreams in JS have the limitation that any bufferpointer
s used are cast toptr string
for the lack of a better option (except maybe a conditionalvar openarray[char]
parameter but that would be very ugly), any pointer incompatible withptr string
will not work. JS now compilesparsecsv
,parsecfg
,parsesql
,xmlparser
,htmlparser
,ropes
and there is new support forcstrutils
.typeinfo
was broken on JS because of commit ca4b971#diff-f3396a3284b9ca3e52aff3aeef171a09,jssys
only importedsystem/indexerrors
whereas it was included in system on C/C++. It is included now injssys
.lexbase
andstreams
now compile on NimScript, they would have worked before but they just didn't compile correctly. NimScript now compiles:parsecsv
,parsecfg
,parsesql
,xmlparser
,htmlparser
,ropes
,json
,parsejson
,strtabs
unidecode
has never not worked in NimScript, both in compiling and the module being functional, but it was specifically mentioned in the NimScript docs that it didn't, so I added it to the changelog.marshal
now mentions JS and NimScript instead of just the new runtime when it's imported on the wrong backend. #11066 mentionsmarshal
in JS, but should be closed since it's specifically talking about newStringStream. There is another issue, #5667, about the pointer-to-int cast in marshal in JS, but this is irrelevant, marshal imports typeinfo which doesn't compile on JS.