CREXX icon indicating copy to clipboard operation
CREXX copied to clipboard

Rexx ‘return’ statement is not able to return a string

Open rvjansen opened this issue 3 years ago • 8 comments

Attempts to make it return a string fail; I can do ‘return ?’ , it parses ok, but I don’t know what that means.

rvjansen avatar Feb 15 '22 12:02 rvjansen

This works

/* rexx */
options levelb

say "result =" blah(1)
return 0

blah: procedure = .string
arg a = int
return "Rene"

However this does not - it seems the parser can't handle a function with no arguments ... which is an issue for sure!

/* rexx */
options levelb

say "result =" blah()
return 0

blah: procedure = .string

return "Rene"

adesutherland avatar Feb 15 '22 12:02 adesutherland

maybe factor in https://github.com/adesutherland/CREXX/discussions/264 because using an exposed variable from main() also needs to be possible without an ARG

rvjansen avatar Mar 02 '22 12:03 rvjansen

I think this should be fixed in develop now

adesutherland avatar Jun 12 '22 14:06 adesutherland

/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'

still gives:

Error @ 6:8 - #31.1, "\'string\'"
1 error(s) in source file

while return 0 works without problem.

rvjansen avatar Jul 22 '22 21:07 rvjansen

in addition to the previous: it seems that return 0 (or another number) is still mandatory; sources won't compile without it. Code that runs off the end should implicitly return 0 or ""; this is awkward with running script-like things compatibly in netrexx, because in netrexx(Java), a main(args=String[]) cannot return anything, so for my compatible mini-scripts this would be good.

rvjansen avatar Sep 25 '22 12:09 rvjansen

The issue is that

/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'

is "syntax candy" (by which I mean "is converted to for the convenience of developers") for

/* test empty say */
options levelb

main: procedure = .int
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'

So you could always use

/* test empty say */
options levelb

main: procedure = .string
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'

or better for you

/* test empty say */
options levelb

main: procedure
say "now follows an empty say:"
say
say "this was an empty say:"

So that's the problem. We have some options

  1. Do nothing - you just have to add the "main: procedure"
  2. Make the syntax candy assume no return value. i.e. add "main: procedure" without the ".int". I chose ".int" because that is what main() from the OS expects but for the syntax candy perhaps no return code is more natural?
  3. Remove the syntax candy - as it's confusing!?
  4. Make the syntax candy smarter - if there is no return statement use "main: procedure", no return value (0 implied), otherwise use "main: procedure = .int". Note that main() must return an .int, in general OS's don't support a string return from main()

What do you think?

PS It should be noted that arguments into main are STILL not implemented!

adesutherland avatar Sep 25 '22 13:09 adesutherland

my vote is for (2) in the short term and (4) in the long run Java cannot return from main - my primary use case (I admit that frankly) is NetRexx compatible scripts so I can go native if needed.

rvjansen avatar Sep 25 '22 13:09 rvjansen

I had forgotten that java main was type void!

adesutherland avatar Sep 25 '22 17:09 adesutherland

ok

/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return '123'

returns 123

/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"

return 0

And

/* test empty say */
options levelb
say "now follows an empty say:"
say
say "this was an empty say:"
return 'string'

Causes a conversion error - which seems reasonable.

So I am marking as resolved :-)

adesutherland avatar Jun 18 '25 19:06 adesutherland

'normally' - on Classic Rexx - what is returned with a return statement goes into the RESULT variable (when called from an exec) and what is returned to the OS comes from EXIT n, to TSO or as a batch step return code and I think in our case, to the calling shell process. But if we cannot compile, we cannot return. Because what is 'returned' in Rexx is mostly strings, we should maybe change the default of the generated syntax candy to .string and leave the conversion error for if we try to EXIT with a string?

rvjansen avatar Jun 25 '25 14:06 rvjansen

I think that is what we do

options levelb
say "hi"
return '100'

returns 100 to the os

adesutherland avatar Jun 25 '25 15:06 adesutherland

@rvjansen given that we DO return a rc if the return value can be converted to an integer (or raise a signal if not) - can we also close this issue?

adesutherland avatar Jun 26 '25 16:06 adesutherland

I still think EXIT should be in charge of returning returncodes and ‘return’ should be able to return a string in RESULT when called by another module - even when it is generated by syntactic sugar. A string containing a number then still could be deposited in RESULT when needed.

rvjansen avatar Jun 26 '25 19:06 rvjansen

But if that is awkward we could document the difference and leave it like this.

rvjansen avatar Jun 26 '25 19:06 rvjansen

Oh - I can set the RESULT environment variable. I just was not understanding the requirement!

adesutherland avatar Jun 26 '25 19:06 adesutherland

In classic rexx it is possible to have a program file hang around in a directory or concatenation and call that from another program or use it by itself - with the complication that it cannot start with a PROCEDURE statement in that case, but is treated as a procedure anyway. In level b we must have an exposed function to call and it would be odd to use an exported main() for that (if that is at all possible). So I am closing this one, but still wondering what is needed for level C which is supposed to be compatible with classic. In this case the generated main should be an exposed version of the filename and probably returning a string. But that is for later.

rvjansen avatar Jun 30 '25 20:06 rvjansen