jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<oprypin> codic12, almost nothing can be done without the stdlib
<oprypin> thats --prelude=empty
<FromGitter> <codic12> as long as you can do simple math, that's all I need for a kernel (though I'll implement a basic stdlib later); thanks!
<oprypin> well im not even sure that you can do simple math - thats the thing
<oprypin> yea your 1+2 program doesnt work already
<oprypin> though nothing that a little `fun __crystal_raise_overflow; end` cant fix
<oprypin> @codic12, take note of `1 &+ 2` & operations dont check for overflow
<oprypin> a program `1 &+ 2` does indeed build with `crystal build --prelude=empty hw.cr`
<FromGitter> <codic12> I see, thanks
<FromGitter> <codic12> `crystal build kernel.cr --cross-compile --target i386-elf --prelude=empty` produces both a binary and an .o file; I only need the latter. Can I tell it to only produce an object file?
<FromGitter> <Blacksmoke16> try `--no-codegren`
<FromGitter> <Blacksmoke16> nvm, that wouldnt produce anything
<oprypin> codic12, i think it's not true that it produces a binary.
<FromGitter> <codic12> I have both `kernel` and `kernel.o` in my current directory
<oprypin> codic12, well delete `kernel` and then you won't
<FromGitter> <codic12> That's true haha
<oprypin> no but crystlal also won't produce it
<FromGitter> <codic12> It does produce it
<oprypin> 🤔
<oprypin> not for me
<FromGitter> <codic12> Even prints out `cc hw.o -o hw -rdynamic ` when I compile
<oprypin> codic12, yea it only prints that
<FromGitter> <codic12> Makes a file for me
<FromGitter> <codic12> Well who cares, it works
<FromGitter> <codic12> Was just curious
renich has quit [Remote host closed the connection]
zorp has quit [Ping timeout: 256 seconds]
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 240 seconds]
<FromGitter> <codic12> I have this fairly simple C code for a basic kernel: https://hatebin.com/hbizmnwhik. I tried porting it to Crystal here: https://hatebin.com/bfvmmbfzca; this compiles, but just gives me a blinking cursor. Something's probably wrong with my logic
<FromGitter> <Blacksmoke16> You never call your main method?
<FromGitter> <Blacksmoke16> Don't actually need it either
<FromGitter> <codic12> No, the main method is called from some assembly code (unless Crystal mangles the names up, which could cause it)
<FromGitter> <codic12> Eg in rust I had to #[no_mangle]
<FromGitter> <codic12> if I `nm -gc` my .o file I do see a `main` symbol, along with a `__crystal_main`
<FromGitter> <codic12> Feel free to mention
<z64> @codic12 the "equivalent" to #[no_mangle] is `fun method(..)` instead of `def method(..)`
renich has joined #crystal-lang
renich has quit [Ping timeout: 256 seconds]
renich has joined #crystal-lang
sagax has quit [Remote host closed the connection]
sagax has joined #crystal-lang
zorp has joined #crystal-lang
nowhereFast has joined #crystal-lang
<nowhereFast> should https://play.crystal-lang.org/#/r/9psh work?
<jhass> no :)
<FromGitter> <stergiom> how about this? https://play.crystal-lang.org/#/r/9psj
<jhass> also intentional: https://play.crystal-lang.org/#/r/9psl
<FromGitter> <stergiom> it works as fine as a one-liner, or multiline with parens
<jhass> do binds to the left-most call, { to the right-most
<FromGitter> <stergiom> ah :)
bazaar has quit [Ping timeout: 260 seconds]
nowhereFast has left #crystal-lang [#crystal-lang]
zorp has quit [Ping timeout: 265 seconds]
renich has quit [Remote host closed the connection]
bazaar has joined #crystal-lang
duane has quit [Ping timeout: 256 seconds]
duane has joined #crystal-lang
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 244 seconds]
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo2 has joined #crystal-lang
<FromGitter> <Dan-Do> Could someone explain what the following error is?
<FromGitter> <Dan-Do> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f61f54fce5bbc7ffdcb1725]
<jhass> as it says, an actual compiler bug :)
<jhass> you would do us a great favor by trying to reduce your code to an as minimal example as possible
<jhass> (that still triggers this)
<FromGitter> <Dan-Do> let me try :)
<jhass> I usually start by trying to remove require's from the entry point, then inline them, then remove all dead (not called) code, and then it usually starts to get a bit more apparent where the issue is already
<jhass> (them = the remaining ones)
<FromGitter> <Dan-Do> Here it is: ⏎ ⏎ #copy & paste to test.cr ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f61f7d7ce5bbc7ffdcb1cf2]
<FromGitter> <Dan-Do> `crystal build ./test.cr`
<jhass> Great, I could reduce it a bit more: https://carc.in/#/r/9ptu
<jhass> for now you should be able to workaround this by just making this a struct and doing somehting like struct Foo; INSTANCE = Foo.new; and using Foo::INSTANCE instead
<jhass> Dan-Do: I think it's this one https://github.com/crystal-lang/crystal/issues/9568
<yxhuvud> I'm fairly certain it shouldn't compile too (as @-variables is not allowed in class methods). But the compiler should of course not crash.
<jhass> yeah, if you minimize it the wrong way it turns into a compilation error :)
<FromGitter> <Dan-Do> > *<jhass>* for now you should be able to workaround this by just making this a struct and doing somehting like struct Foo; INSTANCE = Foo.new; and using Foo::INSTANCE instead ⏎ ⏎ Actually it's the shard https://github.com/fukaoi/crystal-nodejs ⏎ I tried to add some methods and class variables ⏎ This module spans on many files. Do I need to change all? [https://git
<FromGitter> ... ter.im/crystal-lang/crystal?at=5f6200c5a9c2c8511e9b59d7]
<FromGitter> <Dan-Do> Sorry I am not an expert in crystal :(
<jhass> ah well, it's probably not meant to hold state :/
<jhass> you could try to see if using @@class_vars works for you
<jhass> or better yet if you can't find a way to not hold global state
<FromGitter> <Dan-Do> > *<jhass>* or better yet if you can't find a way to not hold global state ⏎ ⏎ Sadly, that's what I want :(
<jhass> another approach could be to extract all the functionality in the class and keep the old API intact by just delegating to an instance of it assigned to a constant
<jhass> with that last approach, the "global state" would just be the convenient API and users could even manually have multiple instances by using the class
<FromGitter> <Dan-Do> Can you give me a reduced code?
<FromGitter> <Dan-Do> Right now, it is: ⏎ ⏎ ```module Nodejs::Internal ⏎ extend self ⏎ def bar ⏎ end ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5f6202d45fde567ffa4eee23]
<jhass> this should roughly sketch what I'm thinking about
<FromGitter> <Dan-Do> That looks great! ⏎ BTW, what do you think the best structure that shard should be? I want to learn and understand more :)
<jhass> I don't know, I haven't really spent time looking at what it wants to do and thinking about it :)
<FromGitter> <Dan-Do> Okay, thanks.
<jhass> but yeah, probably go away from the very procedural code it is right now and think about an OO design, Crystal is an OO language after all :)
<FromGitter> <Dan-Do> Yeah, I will re-write the shard completely :) ⏎ not much files and codes
zorp has joined #crystal-lang
<riffraff169> more like a singleton?
<riffraff169> im having to rethink some of what im doing too...i mostly work in imperative languages, with some functional constructs thrown in...even the oo languages i use, i dont use many oo constructs as such....different way of thinking
<riffraff169> writing a sort of compiler, and when i would create a global struct to hold state, now i create an object...
<jhass> the big selling point of OO is that it allows you to group your state and the functionality that's depending on it close together, then compose the bigger task solution together from those units. Each composition should know less about how some unit even achieves what it does and what state it needs for that. If you're having some global state object passed around everywhere, you're pretty
<jhass> much defeating the point, yeah :)
<FromGitter> <Blacksmoke16> DI ftw 😉
<riffraff169> unfortunately, ive never written a compiler in an oo language, so my work has kind of stalled until i figure out some code architecture (in between life)
<riffraff169> im having to pass state around to, as mentioned...lexer passing lexemes to parser, which tokenizes and creates the list of tokens, which is then....more stuff...anyway
<FromGitter> <Dan-Do> :D
<riffraff169> its also been 15 years since i did any compiler design, so im rusty
<FromGitter> <Dan-Do> What is the proper way to interactive with cli process (created in crystal)?
<FromGitter> <Dan-Do> For example, when I run "node" in the terminal
<FromGitter> <Dan-Do> then it wait for the input
<FromGitter> <Dan-Do> ```> (enter command here)```
<jhass> if you know the input upfront, just pass is it in as the input: parameter
<jhass> otherwise you'll want the block form of Process.run
<FromGitter> <Dan-Do> I initialize the process as below: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f621a4ea9c2c8511e9ba674]
<jhass> that yields you an object which gives your access to IOs for stdin, stdout and stderr
<FromGitter> <Dan-Do> Then send the input command: ⏎ ⏎ ```@input_io << script.delete('\n').to_slice``` [https://gitter.im/crystal-lang/crystal?at=5f621a6b89b38d0921303fe6]
<FromGitter> <Dan-Do> what to do next to tell the process read input then execute it
<jhass> depends on what it's waiting for
<jhass> if a newline, send that and flush, if EOF, close the IO
<jhass> don't forget to #wait on your process to collect the dead childs
<jhass> (or use the block form which does that for you)
<FromGitter> <Dan-Do> It waits the "ENTER" key code, I already sent ⏎ ⏎ ```@input_io << "\n".to_slice``` [https://gitter.im/crystal-lang/crystal?at=5f621aeba9c2c8511e9ba850]
<jhass> then flush
<jhass> no need for the to_slice btw
<FromGitter> <Dan-Do> Oops :)
<FromGitter> <Dan-Do> ```@output_io.to_s # => ""```
<FromGitter> <Dan-Do> the output is empty
<jhass> not sure if `to_s` reads or just dumps the internal buffer
<jhass> I'd make sure to read using `gets` or so
<FromGitter> <Dan-Do> I used "gets_to_end" but still empty
<FromGitter> <Dan-Do> Is it correct that this line will tell process to execute? ⏎ ⏎ > It waits the "ENTER" key code, I already sent ⏎ > ``` ⏎ > @input_io << "\n" ... [https://gitter.im/crystal-lang/crystal?at=5f621d3aa857200e6d647bc8]
<FromGitter> <Blacksmoke16> have to rewind it?
<FromGitter> <Dan-Do> Already did "@node_process.wait"
<FromGitter> <Blacksmoke16> `@output_io.rewind`
<FromGitter> <Dan-Do> Rewind the output? It's empty at the start
<FromGitter> <Blacksmoke16> right, rewind it after the process has finished but before printing it?
<jhass> or just use the block form and stop messing around with IO::Memory's in favor of using the pipes directly :) One less moving part
<FromGitter> <Blacksmoke16> ^
<FromGitter> <Dan-Do> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f621e24ce5bbc7ffdcb847b]
<FromGitter> <Blacksmoke16> `pp! @output_io.gets_to_end`
<FromGitter> <Blacksmoke16> its already empty because it was consumed entirely in the last line
<jhass> well, #wait waits for the process to quit, do you expect that to happen actually?
<FromGitter> <j8r> p `@output_io.gets_to_end`
<jhass> also maybe it just dies with an error, don't forget to check the error output too
<FromGitter> <Dan-Do> > *<jhass>* well, #wait waits for the process to quit, do you expect that to happen actually? ⏎ ⏎ Nope, I will change the code
<FromGitter> <Dan-Do> > *<jhass>* well, #wait waits for the process to quit, do you expect that to happen actually? ⏎ ⏎ I think it will not quit because it's cli. Only with if I press CTRL+C
<FromGitter> <Dan-Do> Still empty output ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f62207089b38d092130528a]
<jhass> what about error?
<jhass> isn't gets_to_end waiting for EOF?
<jhass> which probably doesn't come while it's still running
<FromGitter> <Dan-Do> No error, just empty result
<jhass> with error I mean the stderr pipe of course
<FromGitter> <Dan-Do> > *<jhass>* isn't gets_to_end waiting for EOF? ⏎ ⏎ Nope, I just read the source ⏎ https://github.com/crystal-lang/crystal/blob/5999ae29b/src/io.cr#L533 [https://gitter.im/crystal-lang/crystal?at=5f6222b3a857200e6d648d0c]
<jhass> not sure but an empty slice might only be returned on EOF and the read call just block otherwise :)
<FromGitter> <Dan-Do> > *<jhass>* with error I mean the stderr pipe of course ⏎ ⏎ the same empty ⏎ @input_io << script.delete('\n') ⏎ @input_io << "\n" ... [https://gitter.im/crystal-lang/crystal?at=5f62231ff969413294ec832f]
<FromGitter> <Dan-Do> `@output_io.gets` return nil
<jhass> Dan-Do: using this https://p.jhass.eu/8v.txt I don't get any output until the input pipe is closed. I think node does some kind of pty detection and in fact not enter the REPL loop mode when spawned like this
<FromGitter> <Dan-Do> wow, it works!
<FromGitter> <Dan-Do> Does it mean that I cannot start node process like this?
<FromGitter> <Dan-Do> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f62287bf969413294ec91fa]
<jhass> In my example, you need to notice two things: First of all the output is not interleaved, first crystal, then node. Second, there's a three second delay between the crystal and the node output
<jhass> you can make that a 6 second delay by adding another sleep 3 right before the close
<jhass> these observations are what should generate the learnings from this example, namely that node does not seem to enter REPL mode unless it detects the other end to be a tty/pty
<FromGitter> <Dan-Do> Oh no, it's a web app. It cannot sleep any seconds
<jhass> you still didn't get it
<jhass> meanwhile I looked at node -h and noticed the -i flag. Modifying the example (https://p.jhass.eu/8w.txt) we get the behavior we expect from running in REPL mode
<FromGitter> <Dan-Do> I changed your code at this point:
<FromGitter> <Dan-Do> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f622f21ea62d70e65170441]
<FromGitter> <Dan-Do> Result:
<FromGitter> <Dan-Do> ```Sending first script ⏎ Sending second script ⏎ hi``` [https://gitter.im/crystal-lang/crystal?at=5f622f45ce5bbc7ffdcbb769]
<FromGitter> <Dan-Do> The result of second script is not printed
<FromGitter> <Dan-Do> Okay, I know, because I didn't use `console.log(homedir)`
<FromGitter> <Dan-Do> But then it's not REPL
<FromGitter> <Dan-Do> If you run
<FromGitter> <Dan-Do> ```node ⏎ > const homedir = require('os').homedir(); homedir;``` ⏎ ⏎ the result will be printed, don't need console.log [https://gitter.im/crystal-lang/crystal?at=5f623081df4af236f90fbebc]
<jhass> sounds like you didn't use the `-i` version
<FromGitter> <Dan-Do> Yeap, my bad.
<FromGitter> <Dan-Do> So how to transform your code to mine situation?
<FromGitter> <Dan-Do> There are differences between Process.new and Process.run
<jhass> .run is largely just new; yield; wait
<FromGitter> <Dan-Do> BTW, it's really magic about sleep. It does not sleep at all :)
<jhass> the sleep is there for demonstrative purposes, not functional ones
<jhass> the whole example was trying to demonstrate you something, not solve what you want to do any way
<jhass> and I have no clue what you're talking about, the sleep makes it indeed sleep for three seconds where you would expect
<FromGitter> <codic12> well if I do use `fun` instead of `def`, I can't use `String`; in C, since I had `char*`, I assume the equivalent would be `LibC::Char*`, but this is undefined (note that I'm building this with no prelude)
<jhass> UInt8* :)
<FromGitter> <codic12> For some reason that message doubled, thanks!
<FromGitter> <codic12> but UInt8 has no .chars method (for `while s.chars[index]`, and I can't do `while s[index]`)
<FromGitter> <codic12> oh i see
<jhass> yeah, it's just syntax sugar for Pointer(UInt8)
<jhass> all string handling is on String
<jhass> String.new(buffer), which won't work without prelude of course
<jhass> the compiler only defines the bare minimum, everything else is stdlib, even most Pointer methods
<FromGitter> <codic12> damn
<FromGitter> <codic12> so I can't iterate over a UInt8?
<FromGitter> <codic12> UInt8*, I mean
<jhass> well, with manual pointer arithmetic
<jhass> that should be compiler defined, I think
<jhass> tbh personally I don't see a benefit over C to prelude free Crystal :)
<jhass> other than the challenge perhaps
<oprypin> [18:12:29] <@codic12> so I can't iterate over a UInt8?
<oprypin> you can make a Slice with it if you know the size in advance, and iterate over that
<jhass> oprypin: they're meddling with no-prelude code
sorcus has quit [Ping timeout: 244 seconds]
sorcus has joined #crystal-lang
livcd has quit [Ping timeout: 256 seconds]
Nekka has joined #crystal-lang