Skip to main content

yet another lexical preprocessor

Project description

 __    __    _____ _____
/\ \  /\ \  /\  _  \  _  \
\ \ \_\/  \_\/  \_\ \ \_\ \
 \ \__  /\____/\  __/\  __/
  \/_/\_\/___/\ \_\/\ \_\/
     \/_/      \/_/  \/_/

($($\y:u.\m.\...(m y($\C.\p.(r)e p)($\ro.(ce)s)))so r)
___         __________________________________
___ VERSION __________________________________

yup.py      1.0b4
            2016-11-08
python      2.7

___             ______________________________
___ WHAT IS IT? ______________________________

yupp is a lexical preprocessor which implements the macro language
with Lisp-like Polish notation syntax in fully parenthesized form.
yupp is intended to transform C programs before they are compiled.
It can also be useful for more general purposes, if you would like
to use the preprocessor with Python just install "yupp" package.

yupp allows to generate a readable, well-formatted text. Special
attention is paid to providing complete diagnostic information and
navigational capabilities.

Embedding of the preprocessor expressions into the source code occurs
by using an "application" form, e.g. ($e).

A small example with comments:

    https://github.com/in4lio/yupp/blob/master/doc/glance.md

___        ___________________________________
___ SYNTAX ___________________________________

Main syntactic categories of the macro language are: list, application
and lambda expression.

List is a sequence of expressions separated by blanks and enclosed
in parentheses.

<list> ::= '(' { <expression> } ')'

e.g. (0.5 "string" atom)

Application is an applying a function to arguments, it syntactically
differs from a list in presence of the dollar sign after the open
parenthesis.

<application> ::= '($' <function> { <argument> } ')'

($add 2 3)

Lambda is an anonymous function, it consists of a sequence of parameters
and a function body.

<lambda> ::= <param> { <param> } <expression>
<param>  ::= '\' <name> [ ':' <default> ] '.'

\p.($sub p 1)

Syntactic forms can be nested within each other but, as mentioned above,
only an application can be embedded into the source code directly.

The following examples show various syntactic constructs of the macro
language. Try them using yupp Web Console (http://yup-py.appspot.com/).

($! this is a comment, won't be saved in the generated text )

($! binding of the atom (identifier) with the value )

    ($set a 'A')

($! the atom binding with the list )

    ($set abc (a 'B' 'C' 'D' 'E'))

($! binding of the atom with the lambda is a function definition )

    ($set inc \val.($add val 1))

($! application of the number is subscripting )

    ($2 miss miss HIT miss)

HIT

($! getting the specific element of the list )

    ($0 abc)

'A'

($! application of the list is "for each" loop )

    ($(0 1 2) \i.($inc i))

123

($! embedding of one list into another – *list )

    ($set mark (5 4 *(3 2) 1))

($! infix expression on Python – { } )

    ($set four { 2 + 2 })

($! infix expression straight into the source code )

    foo = (${} sqrt(four) * 5.0);

foo = 10.0;

($! conditional expression – consequent ? condition | alternative )

    ($set fact \n.($ 1 ? { n == 0 } | { ($fact { n - 1 }) * n }))
    ($fact 10)

3628800

($! enclosing of the source code into the application )

    ($abc \ch.($code putchar(($ch));))

putchar('A'); putchar('B'); putchar('C'); putchar('D'); putchar('E');

($! the source code enclosing with square brackets – [ ] )

    ($mark \i.[($i), ])

5, 4, 3, 2, 1,

($! the function parameter with default value – \p:val. )

    ($set if \cond.\then:[].\else:[].($ then ? cond | else ))

($! the named argument )

    ($if { four != 4 } \else OK )

OK

($! the macro definition )

    ($macro GRADE ( PAIRS )
        ($set GRADE-name  ($ (($PAIRS)) \p.($0 p)))
        ($set GRADE-value ($ (($PAIRS)) \p.($1 p)))
        ($set each-GRADE  ($range ($len (($PAIRS)) )))
    )

($! the quote – (` ) )

    ($GRADE
        (`
            ( A 5 )
            ( B 4 )
            ( C 3 )
            ( D 2 )
            ( E 1 )
        )
    )

($! enclosing of the source code into the loop
    with reverse square brackets – ]<EOL> <EOL>[ )

    ($each-GRADE \i.]
        int ($i GRADE-name) = ($i GRADE-value);

    [ )

int A = 5;
int B = 4;
int C = 3;
int D = 2;
int E = 1;

($! the source code enclosing with double comma – ,, )

    ($import stdlib)
    ($hex ($BB,,11000000,,11111111,,11101110))

0xc0ffee

($! the string substitution )

    ($ "Give ($0) ($p)." \p ($0 mark) me )

"Give me 5."

($! the string evaluation – ($$ ) )

    ($ ($$'($($func) ($0) ($1))' \func (`mul) 5 5))

25

($! the iterator (modifier) – experimental!
    NOT applicable into a loop or conditional expression )

    ($set i 0)
    ($emit i inc) ($emit i inc) ($emit i dec) ($emit i)

0 1 2 1

($! the iterator (modifier) of the list )

    ($set l ($range 5 25 5))
    ($emit l) ($emit l) ($emit l) ($emit l)

5 10 15 20

($! the late bound parameter – \p.. &p )

    ($ \func.\val.($func val) \p.($q p) regular)
    ($ \p..\func.\val.($func val) ($q &p) late_bound)

"regular"
"late_bound"

($! the variable argument list – \... __va_args__ – experimental! )

    ($ \p1.\p2.\...($__va_args__) 1 2 v a _ a r g s)

va_args

    ($ \val.\...($ ($lazy __va_args__) \func.[($func val) ])
        9.0
        \n.($sqrt n)
        \n.{ 2 * n }
        \n.($pow n 2)
    )

3.0 18.0 81.0

($! getting names of parameters from the list – \(p). )

    ($set p (c d))
    ($ \(p).{ c - d } 100 500)
    ($set p (d c))
    ($ \(p).{ c - d } 100 500)

-400
400

Any functions from "string", "operator" and "math" modules of Python
Standard Library can be used in preprocessor expressions
(https://github.com/in4lio/yupp/blob/master/doc/builtin.md).

The special ($import ) form is provided to include macros and functions
from yupp Standard Library or other libraries
(https://github.com/in4lio/yupp/blob/master/lib/README.md).

___       ____________________________________
___ USAGE ____________________________________

yupp is written in Python, the main file is "yup.py". Source files
for preprocessing are passed to "yup.py" as command-line arguments.

To learn more about the preprocessor parameters, please get help on
the command-line interface:

    python yup.py -h

The files generated by the preprocessor are getting other extensions
that could come from the original, e.g. ".c" for ".yu-c".
In failing to translate the preprocessor expressions into a plain text
the evaluation result will be saved as ".ast" file.

___         __________________________________
___ EXAMPLE __________________________________

>cd yupp
>more "./eg/hello.yu-c"

    ($set greeting "Hello world!\n")

    ($set name   (  Co       F              Zu           ))
    ($set type   (  float    double         float        ))
    ($set val    (  { pi }   (`acos( -1 ))  { 355/113 }  ))
    ($set format (  "%.2f"   "%.10f"        "%.6f"       ))

    ($set each-Pi ($range ($len name)))

    #include <math.h>
    #include <stdio.h>

    void main( void )
    {
        ($each-Pi \i.]
            ($i type) ($i name) = ($i val);

        [ )
        printf( ($greeting) );

        ($each-Pi \i.]
            ($set n ($i name))
            printf( ($"($0) = ($1)\n" ($n) ($unq ($i format))), ($n) );

        [ )
    }

>python yup.py -q "./eg/hello.yu-c"

>more "./eg/hello.c"

    #include <math.h>
    #include <stdio.h>

    void main( void )
    {
        float Co = 3.14159265359;
        double F = acos( -1 );
        float Zu = 3.14159292035;

        printf( "Hello world!\n" );

        printf( "Co = %.2f\n", Co );
        printf( "F = %.10f\n", F );
        printf( "Zu = %.6f\n", Zu );

    }

Further examples:

    https://github.com/in4lio/yupp/tree/master/eg

___                ___________________________
___ PYTHON PACKAGE ___________________________

The easiest way to integrate the preprocessor into Python 2 - to install
the corresponding package:

    pip install yupp

You have to use "pip", and may need to specify "--pre" key to install
the beta version.

After that you will be able to apply macro expressions in the source
code on Python, starting the script with:

    # coding: yupp

Preprocessor options for all files in a directory can be specified into
".yuconfig" file, individual options for the file in "file.yuconfig".

Nothing prevents to translate other file types using the package:

    python -c "from yupp import pp; pp.translate( 'file.yu-c' )"

___              _____________________________
___ SUBLIME TEXT _____________________________

The folder "sublime_text" contains configuration files for comfortable
usage of the preprocessor in Sublime Text 2 editor. In addition there is
a plug-in for quick navigation between the generated text and its source.

___         __________________________________
___ TESTKIT __________________________________

yupp is currently in beta stage. The file called "test_yup.py" contains
a number of smoke tests.

The preprocessor still needs testing and optimization. Also you may run
into problems with completing of the eval-apply cycle when used recursion
or experimental features.

___     ______________________________________
___ WEB ______________________________________

o   The project on GitHub:
    https://github.com/in4lio/yupp/
    https://github.com/in4lio/yupp/wiki/

o   yupp Blog:
    http://yup-py.blogspot.com/

o   yupp Web Console:
    http://yup-py.appspot.com/

___          _________________________________
___ PROJECTS _________________________________

o   LEGO Mindstorms EV3 Debian C library:
    https://github.com/in4lio/ev3dev-c/

o   predict – an embedded application framework:
    https://github.com/in4lio/predict/

___     ______________________________________
___ GIT ______________________________________

Enter in the following on your command-line to clone yupp repository:

    git clone https://github.com/in4lio/yupp.git

___         __________________________________
___ CONTACT __________________________________

Please feel free to contact me at in4lio+yupp@gmail.com if you have
any questions about the preprocessor.

___         __________________________________
___ LICENSE __________________________________

Please see the file called "LICENSE".

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yupp-1.0b4.tar.gz (53.5 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page