Re: [Python-Dev] A minimal Python interpreter written in Python for experimenting with language changes

2018年2月06日 15:34:54 -0800

> Message-ID: <[email protected]>
> 
> 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
> 
>
_______________________________________________
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to