fubark / cyber

Fast and concurrent scripting.
https://cyberscript.dev
MIT License
1.21k stars 43 forks source link

Recover #3

Closed zachcp closed 1 year ago

zachcp commented 1 year ago

Hi @fubark,

This looks like a really promising scripting language. I was looking to kick the tires and I ran into an issue using recover where the doc example trips an error. In my particular case, I was trying to write a little function that will allow me to step through stdin line by line without triggering a panic and recover seemed designed for this purpose - although if theres an alternative, I would love to know.

--- this recover example which is verbatim form the docs trips  parse error
func kaboom():
    recover err:
        if err == #danger:
            print 'recovered from #danger'
    panic(#danger)

kaboom()  

---
--- results in the following
ParseError: Expected term expr. Parsed recover_k.
recover.cy:2:5:
    recover err:

My example:

-- I would like to wrap readLine so I don't encounter a panic when the stream runs out
hasline = true
for hasline:
    a = readLine()
    print a

-- ./cyber testparse.cy < filetoparse.txt
fubark commented 1 year ago

Hello @zachcp, I just fixed coreReadLine in 0c59964b1f64ed70e5cd99263897da0db4591fad to return a error(#EndOfStream) value when EOF is encountered. recover hasn't been implemented yet as the design hasn't been finalized. This issue can remain open as reminder to complete recover. I also wouldn't recommend using try right now outside of writing tests. Here's how you might handle the error:

for:
    line = readLine()
    if line == error(#EndOfStream):
        print 'end of stream'
        break
    else:
        print line`
zachcp commented 1 year ago

Awesome! Thank you.

matu3ba commented 1 year ago

Will this also work for use cases like this:

def runTest(da: dalib.Talib) -> int:
    st = da.expectEq(list(ta.storage_msg[0].keys())[0], "1")
    # This line feels very superfluous, but I need stack trace (without crashing) + dump program state
    if st != 0: da.failTestDumpState(st); return 1 
    st = ta.expectEq(list(ta.storage_msg[0].keys())[1], "2")
    if st != 0: da.failTestDumpState(st); return 1 # again feeling superfluous (2x time code size)
    # ...
    def failTestDumpState(self: object, status: int):
        print("FAIL with status:", status)
        traceback.print_stack() # printStackTrace
        self.dumpState()
        print("last_setEvState:", self.timeline_msg[self.dump_timeline_msg_last])
        print("Messages still in Queue:")
        while self.queue_msg.empty() == False:
            msg= self.queue_msg.get(block=False)
            writeQueueMsg(msg)
da = dalib.Dalib()
da.init()
st = runTest(da)
sys.exit(st)

?

If @fubark provides sufficient pointers on how libstd works, then I can start with libstd xml and json/dictionary functionality I dearly miss in python or is super clunky. This should also provide better insights into performance of realistic applications.

fubark commented 1 year ago

Yes, you should be able to recover the stack trace for the implementation of recover. The current goal for libstd is to keep it small, and allow libs to be easily imported from the web... So one would do import json 'https://libs.com/json.cy'. But we could also keep an official set of modules in this repo. They would just be library modules that expose the interface with bindLib. There are a couple of things that needs to be done first though... one is user modules which I'm working on now. @matu3ba

fubark commented 1 year ago

recover is no longer part of the language since Cyber has moved to a try/catch mechanism. Please open a new issue if anyone has trouble using it. Learn more about error handling here: https://fubark.github.io/cyber/docs/toc/errors/