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.0b5
2017-02-28
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 plugin for quick navigation between the generated text and its origin.
___ ______________________________________
___ VIM ______________________________________
Switching between the generated text and its origin in VIM editor:
https://github.com/in4lio/vim-yupp (under development)
___ __________________________________
___ 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
Release history Release notifications | RSS feed
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.0b5.tar.gz
(53.7 kB
view details)
File details
Details for the file yupp-1.0b5.tar.gz.
File metadata
- Download URL: yupp-1.0b5.tar.gz
- Upload date:
- Size: 53.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f195ef9ae81245e5dcb6bf4b676095a89879a688165296538fe8b2d7c97d3180
|
|
| MD5 |
123370562cc4ee2c75ba8aadceddce44
|
|
| BLAKE2b-256 |
70500aac7ea97e28b2b06ae4f71bfc8bf1fe2b7cfc4185fd400be23f8de8f6bb
|