TranscryptOrg / Transcrypt

Python 3.9 to JavaScript compiler - Lean, fast, open!
https://www.transcrypt.org
Apache License 2.0
2.86k stars 215 forks source link

with __pragma__(...): #552

Open kiwi0fruit opened 6 years ago

kiwi0fruit commented 6 years ago

It would be nice to have in addition to in-line comment pragmas the new more explicit pragma via with construction. It switches to pragma needed then switches back to the global value:

with __pragma__(...):
    do()
more()
happy-monk commented 6 years ago

Do you mind if I try to implement this?

JdeH commented 6 years ago

@happy-monk

It would be a nice addition if it doesn't complicate the compiler too much. You're welcome to give it a try. I've marked it 'under construction' for now.

Kind regards Jacques

happy-monk commented 5 years ago

The with __pragma__ now works in most cases, but with a couple of issues.

First of all, if you try to nest pragmas of the same kind, you will see rather confusing results. For example:

with __pragma__('opov'):
    a = b + c
    with __pragma__('opov'):
        x = y + z
    d = e + f

a = b + c and x = y + z will be affected by 'opov', but d = e + f will not.

This is because with __pragma__ is implemented now by appending/prepending __pragma__('xxx') and __pragma__('noxxx') to the context code. So the nested with will always disable its effect instead of restoring the previous state.

The same applies to the single-line activation variety of pragmas, because it's implemented in the same way.

Of course, this is not kind of thing you should see in final/production/etc. code, but it surely will confuse people and get in the way of experimentation with code.

To solve this some architectural solution is needed. There are several way to handle this, but, I think, the easiest way would be to implement some kind of stack for translator flags and utilise it for with handling and single-line activation. The __pragma__(push) and __pragma__(pop) could also be realised for use with non-context pragmas.

JdeH commented 5 years ago

I agree that this behavior may be confusing if you encounter it while experimenting. Still I think that the with __pragma__ variant is quite useful. The situation reminds me to C/C++ #ifdef #endif macro's that also "cannot count", if I remember well, but still are quite useful. The same limitation holds for nested comments in many languages. So I'd like to include it in the upcoming release, but will pay attention to its limitations in the documentation.

One probably simple way to lift this limitation for most pragma's would be to use a counter rather than a boolean to maintain their status. But currently I do not oversee all consequences (which may be none). It may result in some pragma's being nestable and others not, which may be even more confusing, not sure...

By the way, I don't think I properly understand what you mean by the __pragma__(push) and __pragma__(pop) syntax. Would this be a way to handle nested pragma's? What exactly would be pushed and popped? And how would this pragma deal with nested activation of itself?