tdenniston / bish

Bish is a language that compiles to Bash. It's designed to give shell scripting a more comfortable and modern feel.
MIT License
1.48k stars 36 forks source link

Add shebang capability #14

Closed noahmorrison closed 9 years ago

noahmorrison commented 9 years ago

This pull request adds a new flag (-r) that can be used to directly execute a bish file

Either add -r before the filename

$ bish -r examples/fib.bish

or add

#!/bin/bish -r

to the top of the file

This would close #7 (Unless @reklis wanted a full REPL, but I don't think that was the intent)

tdenniston commented 9 years ago

This is great, thanks for doing this. There seems to be an issue though. I tried running it on this fib program:

def fib(n) {
  if (n < 2) {
    return 1;
  }
  return fib(n-1) + fib(n-2);
}
fib(15);

By saying ./bish -r fib.bish. And I get the following bash error: bash: line 7: syntax error: unexpected end of file. When I run ./bish fib.bish | bash I don't see that error. Could you look into that before I merge this?

Additionally, I get a compiler warning (clang) with your changes:

src/bish.cpp:83:14: warning: using the result of an assignment as a condition
      without parentheses [-Wparentheses]
    while (n = is.readsome(buf, sizeof(buf))) {

What you meant is perfectly clear, but to silence the warning could you just add parens around that assignment?

noahmorrison commented 9 years ago

I'm not getting this EOF error anymore... could you try adding

fwrite(buf, 1, n, stdout);

at line 84 (right below while ((n = is.readsome(...))) and tell me the output?

I'm getting

#!/bin/bash
# Autogenerated script, compiled from the Bish language.
# Bish version 0.1
# Please see https://github.com/tdenniston/bish for more information about Bish.

function bish_fib () {
    if [[ $1 -lt 2 ]]; then
        echo 1; exit;
    fi;
    echo $(($(bish_fib $(($1 - 1))) + $(bish_fib $(($1 - 2))))); exit;
}

function bish_main () {
    bish_fib 15;
}

bish_main;
987

987 being what it outputs after all that

tdenniston commented 9 years ago

Here is what I get when I replace printing to bash with printing to stdout:

$ ./bish -r fib.bish
#!/bin/bash
# Autogenerated script, compiled from the Bish language.
# Bish version 0.1
# Please see https://github.com/tdenniston/bish for more information about Bish.

function bish_fib () {$

It seems like readsome is not reading the entire contents. Since the input does not need to be read asynchronously, perhaps the solution is to use read instead? Something like this that allows batched read/write:

while (is.good()) {
    is.read(buf, sizeof(buf));
    fwrite(buf, 1, is.gcount(), bash);
}

If this works also on your system, go ahead and update the PR and I think it's ready for merging.

noahmorrison commented 9 years ago

I didn't realize that readsome was async... I thought the only difference was that it returned the amount of data it read. It was prettier too, but oh well, hope this works!

tdenniston commented 9 years ago

Hmm. I might prefer the while as opposed to the do-while. Couldn't it be possible that the stream is not "good" before the first iteration? In that case there would be an exception thrown. With the while form, we wouldn't try to use a "bad" stream.

noahmorrison commented 9 years ago

is.gcount() would be 0 if the stream was bad, no? Then fwrite wouldn't try to write anything. Passing run_on_bash an empty std::stringstream works fine, but I don't know how to make a bad stream for testing.

tdenniston commented 9 years ago

All right, thanks for doing this!

noahmorrison commented 9 years ago

No problem! Glad I could help :)