[Python-Dev] A minimal Python interpreter written in Python for experimenting with language changes
asrp
asrp at email.com
Tue Feb 6 18:32:19 EST 2018
> Message-ID: <20180206034013.GZ26553 at ando.pearwood.info>
>
> On Sat, Feb 03, 2018 at 11:45:15AM +0100, asrp wrote:
>
> > > Can you give an example of how you would do that? I don't mean the
> > > mechanism used, I mean how would a developer implement a new syntactic
> > > feature. Suppose I wanted to add a new clause to for...else, let's say:
> > >
> > > for ... :
> > > block
> > > otherwise:
> > > # runs only if the for-loop was empty
> > >
> > > How would do I do that?
> [...]
> > If you tell me a bit more about the intended behaviour of "otherwise",
> > I'd be happy to do an example with that clause.
>
>
> Here's a faked session showing the sort of thing I am referring to.
> (Note that this is just an example, not a proposal for a new language
> feature.)
>
> for x in [1, 2, 3]:
> print(x)
> otherwise:
> print("nothing there")
>
>
> prints 1, 2, 3.
>
> for x in []:
> print(x)
> otherwise:
> print("nothing there")
>
> prints "nothing there". In other words, the otherwise block runs if, and
> only if, the loop iterable is empty and the for block does NOT run.
>
> Can you do something like that?
>
Oh, I see. Yes, definitely. This time I'll change for_stmt in lib/simple_ast.py beforehand (but runtime reload also works).
def for_stmt(index_var, iterable, block, else_block, otherwise_block):
iterator = iter(evaluate(iterable))
try:
assignment(index_var, iterator.next())
except StopIteration:
evaluate(otherwise_block)
return
while_true:
__caller__['__continue__'] = __continue__
__caller__['__break__'] = __break__
evaluate(block)
try:
assignment(index_var, iterator.next())
except StopIteration:
evaluate(else_block)
return
Then start the interpreter
$ ipython -i test/python_repl.py
p>> simport simple_ast
p>> ^D
[...]
In [1]: grammar = python_grammar.full_definition + python_grammar.extra
In [2]: grammar += r"""
...: for_stmt = "for" {exprlist} "in" {testlist} ":" {suite} {((SAME_INDENT "else" ":" {suite}) | void=pass_stmt) ((SAME_INDENT "otherwise" ":" {suite}) | void=pass_stmt)}
...: """
In [3]: pyterp.parser = python.Interpreter(i3.parse("grammar", grammar))
In [4]: pyterp.repl()
p>> for x in [1, 2]:
... print(x)
... otherwise:
... print("Nothing there")
...
1
2
p>> for x in []:
... print(x)
... otherwise:
... print("Nothing there")
...
Nothing there
p>> for x in [1, 2]:
... print(x)
... else:
... print("Something there")
... otherwise:
... print("Nothing there")
...
1
2
Something there
I noticed since my last post that the else and otherwise blocks don't need to be named if they are positional in for_stmt. The grammar change here reflects that.
I've also posted an example with `until_stmt` and I talk a bit more about debugging changes made there.
http://blog.asrpo.com/adding_new_statement
(Nothing here is a proposed language change, just demos.)
asrp
>
>
> --
> Steve
>
>
More information about the Python-Dev
mailing list