stupid python tricks

6 thoughts
last posted April 25, 2016, 8:24 a.m.

3 earlier thoughts

0

Stupid Python Tricks (mark III): "barely literate programming".

expand   = lambda node,d: ''.join(expand(x,d) if i%2 else x
             for i,x    in enumerate(d[node][:-1].split('@')))
findcode = lambda s: { rk[1:-1] : ''.join(rv[1:] for rv in rvs)
             for ls     in [[l+'\n' for l in s.split('\n') if l[:1] in '@>']]
             for js     in [[i for i,l in enumerate(ls) if l[0]=='@']+[None]]
             for i,j    in zip(js[:-1],js[1:]) 
             for rk,rvs in [(ls[i],ls[i+1:j])]}

print(':: :: ::\n'.join(
    expand(node, findcode(test))
        for node in ['k & r','ansi']
        for test in [r"""
this is a test of barely-literate programming.

:: :: ::

First, we try an old-timer program:

@k & r
>main(@formal names@)
>@formal declarations@
>{
>   printf(@greetings@);
>}
>

Not that we use them in this program (it is,
after all, a constant function, cf. the 'K'
combinator) but for nostalgia value, we have

@formal names
>argc, argv

@formal declarations
>int argc;
>char *argv[];

and, of course, we should specify the value
which the function takes at all arguments:

@greetings
>"Hello, world\n"

:: :: ::

Now, let's rewrite this in a more modern style:

@ansi
>@external declarations@
>
>int main(@inline formal declarations@)
>{
>   printf(@greetings@);
>   @more boilerplate...@
>}
>

You'll notice that we have an 'int' in there.
That's because once one has more than a few
K of memory to play with during a compile, it
turns out that silently assuming all params
are machine words isn't the best tradeoff.

Of course, now that we've declared that we're
returning an int, we'd probably better do so:

@more boilerplate...
>return 0;

We must declare the argument types as well
as the return types:
@inline formal declarations
>int argc, char **argv, char **envp

As in Pascal, the types are now specified in
with the argument names.  One might expect
that we'd need some additional bookkeeping
for printf() as well as main(), but luckily
(if one is not the preprocessor) this is a
matter of including the proper header file.

@external declarations
>#include <stdio.h>

:: :: ::

(to get fancier, one might try piping output
through "tcc -run", but it would probably be
better to fill in the code sketched here and
improve its robustness and input format)
"""]))

2 later thoughts