Skip to content
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

Implement generator.throw() #156

Open
alanjds opened this issue Aug 18, 2018 · 3 comments
Open

Implement generator.throw() #156

alanjds opened this issue Aug 18, 2018 · 3 comments

Comments

@alanjds
Copy link
Owner

alanjds commented Aug 18, 2018

No description provided.

@alanjds
Copy link
Owner Author

alanjds commented Aug 18, 2018

Comment by m4ns0ur
Sunday Jul 23, 2017 at 19:43 GMT


@trotterdylan what is the best approach to test stmt and expr_visitor? could you give me a hint?

@alanjds
Copy link
Owner Author

alanjds commented Aug 18, 2018

Comment by m4ns0ur
Wednesday Jul 26, 2017 at 23:12 GMT


@trotterdylan generator cannot catch the thrown exception, I should check more.

@alanjds
Copy link
Owner Author

alanjds commented Aug 18, 2018

Comment by m4ns0ur
Thursday Aug 24, 2017 at 21:19 GMT


@trotterdylan sorry for the long delay.

so the problem is generator cannot catch the thrown exception.
here is the CPython code (in generator test):

def gen8():
  try:
    yield
  except ValueError as e:
    assert "foo" in str(e)
    yield
  else:
    raise AssertionError
g = gen8()
g.next()
g.throw(ValueError, 'foo')

and Grumpy generated code:

.
.
.
for ; πF.State() >= 0; πF.PopCheckpoint() {
	switch πF.State() {
	case 0:
	case 2: goto Label2
	case 3: goto Label3
	case 5: goto Label5
	default: panic("unexpected function state")
	}
	// line 2: try:
	πF.SetLineno(2)
	πF.PushCheckpoint(2)
	// line 3: yield
	πF.SetLineno(3)
	πF.PushCheckpoint(3)
	return πg.None, nil
Label3:
	if πThrown != nil {
		πE = πThrown
		πThrown = nil
		if πE != nil {
			continue
		}
	}
	πTemp001 = πSent
	πF.PopCheckpoint()
	if πTemp001, πE = πg.ResolveGlobal(πF, ßAssertionError); πE != nil {
		continue
	}
	// line 8: raise AssertionError
	πF.SetLineno(8)
	πE = πF.Raise(πTemp001, nil, nil)
	continue
	goto Label1
Label2:
	if πE == nil {
	  continue
	}
	πE = nil
	πTemp002, πTemp003 = πF.ExcInfo()
	if πTemp001, πE = πg.ResolveGlobal(πF, ßValueError); πE != nil {
		continue
	}
	if πTemp004, πE = πg.IsInstance(πF, πTemp002.ToObject(), πTemp001); πE != nil {
		continue
	}
	if πTemp004 {
		goto Label4
	}
	πE = πF.Raise(πTemp002.ToObject(), nil, πTemp003.ToObject())
	continue
	// line 4: except ValueError as e:
	πF.SetLineno(4)
Label4:
	µe = πTemp002.ToObject()
	// line 5: assert "foo" in str(e)
	πF.SetLineno(5)
	πTemp005 = πF.MakeArgs(1)
	if πE = πg.CheckLocal(πF, µe, "e"); πE != nil {
		continue
	}
	πTemp005[0] = µe
	if πTemp006, πE = πg.ResolveGlobal(πF, ßstr); πE != nil {
		continue
	}
	if πTemp007, πE = πTemp006.Call(πF, πTemp005, nil); πE != nil {
		continue
	}
	πF.FreeArgs(πTemp005)
	if πTemp004, πE = πg.Contains(πF, πTemp007, ßfoo.ToObject()); πE != nil {
		continue
	}
	πTemp001 = πg.GetBool(πTemp004).ToObject()
	if πE = πg.Assert(πF, πTemp001, nil); πE != nil {
		continue
	}
	// line 6: yield
	πF.SetLineno(6)
	πF.PushCheckpoint(5)
	return πg.None, nil
Label5:
	if πThrown != nil {
		πE = πThrown
		πThrown = nil
		if πE != nil {
			continue
		}
	}
	πTemp001 = πSent
	πF.RestoreExc(nil, nil)
	goto Label1
Label1:
}
.
.
.

it seems OK to me, do you see anything improper?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant