Adding print-style function calls, and preproc plugins

Alex Martelli aleax at aleax.it
Fri Aug 31 09:07:09 EDT 2001


"Gerson Kurz" <gerson.kurz at t-online.de> wrote in message
news:3b8e6d04.14344968 at news.t-online.de...
    ...
> Well please remember what my original intent was: writing my own print
> function - er - statement. So, is "print = foo" a valid statement? No.

No, but only because print is a reserved word (a statement, not
a function).  So, the ambiguity still fully applies whenever
you're assigning to ANY identifier except the few reserved words.

Moreover: pleek = print is not ambiguous because it's illegal --
again, because print is a reserved word, NOT a function.  With
ANY non-reserved identifier, your "IMHO neat" syntax trick would
make it totally ambiguous.

> Is "print plikke" ambiguous? No. Is "print plikke()" ambiguous? No. So
> what is the problem? Just add the tiny little restriction that there
> is only one statement-like-function-call-per-instruction (separating
> by ; should work naturally) and you have a (IMHO neat) syntax trick.

Is that "only one" as in "ZERO are not allowed"?  Otherwise, most
obviously,
    pleek = plook
IS fully ambiguous -- is plook to be called, or is it just used and
a reference to it assigned to pleek?  It's not assignment only --
    pleek(plook)
suffers exactly the same ambiguity (again, the problem doesn't
arise with print *because print is a reserved word*).

> Maybe you're too much reminded of the way this works in Perl & VB.
> But please, my problem was that I had to modify print's behaviour, and
> couldn't do so, because by going from "print" to a function, you have
> to enclose the arguments in brackets.

Problems that can be solved by tools should be solved by tools,
rather than complicating the language in an attempt to work
around them.  For example, the following script, while a rough
first draft, might be a real beginning on solving your problem:

import tokenize, token

def statement_end(toktype, tokstr):
    return token.ISEOF(toktype) or \
        toktype==token.NEWLINE or \
        (toktype==token.OP and tokstr==';')

class dePrint:
    def __init__(self, changeto):
        self.changeto = changeto
        self.changes = []
        self.seenprint = 0
    def eat(self, toktype, tokstr, start, end, line):
        if tokstr == "print":
            lineno, startcol = start
            junk, endcol = end
            self.changes.append((lineno, startcol, endcol, self.changeto))
            self.seenprint = 1
        elif statement_end(toktype, tokstr) and self.seenprint:
            lineno, startcol = start
            junk, endcol = end
            if token.ISEOF(toktype): lineno -= 1
            self.changes.append((lineno, startcol, endcol, ')'+tokstr))
            self.seenprint = 0

def subst_print(changeto, readline):
    deprinter = dePrint(changeto)
    tokenize.tokenize(readline, deprinter.eat)
    return deprinter.changes

def tryone(string, outname='pippo'):
    import cStringIO
    asfile = cStringIO.StringIO(string)
    changes = subst_print(outname+'(', asfile.readline)
    asfile.seek(0)
    lines = asfile.readlines()
    print len(lines),"lines"
    for lineno, startcol, endcol, change in changes:
        print lineno, startcol, endcol, repr(change)
        line = lines[lineno-1]
        if startcol==endcol==0:
            line = line+change
        else:
            linestart = line[:startcol]
            lineend = line[endcol:]
            line = linestart+change+lineend
        lines[lineno-1] = line
    for line in lines:
        print line,
    print

There are "prettyprinting" worries (since the spaces
normally used after print remain, while one might want
to eliminate them) and more substantial ones (e.g.,
this does nothing about the trailing comma in a
print statement), but it's a start -- try the
"tryone" function on a few examples by running
this e.g. with python -i.  And this IS a rough, off-
the-cuff first attempt -- it's surely possible to do
much better by giving the problem the 20-30 minutes'
worth of thought and experiments it deserves.


Alex






More information about the Python-list mailing list