Infix ===== Topics ------ 1. Introduction 2. License 3. Usage 4. Testing 5. Installing A. Credits B. Bug reports C. Resources 1. Introduction --------------- This package is a distribution of libraries for R6RS Scheme implementations; it provides the INFIX macro which converts the traditional infix notation for expressions to the equivalent Scheme's prefix notation. The library has no dependencies; the implementation itself is a single, definitive, kill'em all DEFINE-SYNTAX form with the addition of a few auxiliary syntaxes. The library attempts to support Guile, Larceny, Mosh, Petite Chez, Racket, Sagittarius, Vicare and Ypsilon. 2. License ---------- Copyright (c) 2010, 2012 Marco Maggi <marco.maggi-ipsu@poste.it> Copyright (c) 2008 Derick Eddington Copyright (c) 2005-2008 Dominique Boucher Copyright (C) 2000 The Free Software Foundation. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. 3. Usage -------- To use the library just import (infix infix) and use the INFIX macro: it expands to a prefix expression to be evaluated at runtime, in the lexical context of the macro use; as a special case "(infix)" is equivalent to "(values)". The macro allows us to evaluate forms like: (let ((a 1) (b 2) (c 3)) (infix cos (a) * tan (b) / c) ==> (/ (* (cos a) (tan b)) c) (infix (cos (a) * tan (b) / c)) ==> (/ (* (cos a) (tan b)) c) (infix a ? b : c) ==> (if a b c) #f) Some interpretation rules: * Any Scheme value can be element of the input form. * The following infix operators are supported; in order of descending precedence from top to bottom, operators on the same line have equal precedence: bitwise-arithmetic-shift-left bitwise-arithmetic-shift-right bitwise-not bitwise-and bitwise-ior bitwise-xor incr! decr! (unary +) (unary -) expt mod mod0 * / div div0 + - < > <= >= = eq? eqv? equal? not and or xor remember that the Scheme comparison operators are meant to return a boolean value, rather than a number object. * All the operators are left-associative with the exception of EXPT which is right-associative and of the unary +, -, incr!, decr!, not and bitwise-not which are non-associative: ;; left-associative (infix 10 - 5 - 3) ==> (- (- 10 5) 3) (infix 10 - 5 - 3) ==> (- 10 5 3) (infix 10 / 5 / 3) ==> (/ (/ 10 5) 3) (infix 10 / 5 / 3) ==> (/ 10 5 3) ;; right-associative (infix 10 expt 5 expt 3) ==> (expt 10 (expt 5 3)) * The following operators for fixnums are supported with the same precedence of the corresponding generic operators: fx+ fx- fx* fxdiv fxdiv0 fxmod fxmod0 fx<? fx>? fx<=? fx>=? fx=? fxand fxior fxxor fxnot fxarithmetic-shift-left fxarithmetic-shift-right All the operators are left-associative with the exception of FXNOT which is non-associative: (infix 10 fx- 5 fx- 3) ==> (fx- (fx- 10 5) 3) (infix 10 fxdiv 5 fxdiv 3) ==> (fxdiv (fxdiv 10 5) 3) * The following operators for flonums are supported with the same precedence of the corresponding generic operators: fl+ fl- fl* fl/ flexpt fl<? fl>? fl<=? fl>=? fl=? All the operators are left-associative with the exception of FLEXPT which is right-associative: ;; left-associative (infix 10. fl- 5. fl- 3.) ==> (fl- (fl- 10. 5.) 3.)) (infix 10. fl- 5. fl- 3.) ==> (fl- 10. 5. 3.)) (infix 10. fl/ 5. fl/ 3.) ==> (fl/ (fl/ 10. 5.) 3.)) (infix 10. fl/ 5. fl/ 3.) ==> (fl/ 10. 5. 3.)) ;; right-associative (infix 10 expt 5 expt 3) ==> (expt 10 (expt 5 3)) (infix 10. flexpt 5. flexpt 3.) ==> (flexpt 10. (flexpt 5. 3.)) * INCR! and DECR! are unary operators that can be applied to expressions both in prefix and suffix positions. When applied in prefix position to an identifier, INCR! expands to: (infix incr! ?id) ==> (begin (set! ?id (+ ?id 1)) ?id) and DECR! expands to: (infix decr! ?id) ==> (begin (set! ?id (- ?id 1)) ?id) When applied in suffix position to an identifier, INCR! expands to: (infix ?id incr!) ==> (let ((v ?id)) (set! ?id (+ ?id 1)) v) and DECR! expands to: (infix ?id decr!) ==> (let ((v ?id)) (set! ?id (- ?id 1)) v) When applied to a non-identifier expression, both in prefix and suffix position, INCR! expands to: (infix incr! ?expr) ==> (+ ?expr 1) (infix ?expr incr!) ==> (+ ?expr 1) and DECR! expands to: (infix decr! ?expr) ==> (- ?expr 1) (infix ?expr decr!) ==> (- ?expr 1) * The if-then-else statement involves the special symbols "?" and ":" which should be free identifiers. This statement has the least precedence of all. * Identifiers which are not operators are interpreted as variable references; if an identifier is followed by a list, it is a function call. * Function calls with one or more arguments require the arguments to be grouped in a list; there is no special separator in the list of arguments. (define (fun a b c) (+ a b c)) (infix fun (1 2 3)) ==> (fun 1 2 3) Notice that grouping the function arguments in a list is a requirement of the infix expression grammar. * Numbers and all the other values are just put there as operands. * As a special exception: the binding BEGIN from (rnrs) is recognised in the input form and allows us to nest prefix-notation expressions. (infix (begin (+ 1 2))) => 3 (infix (begin (let ((a 3)) (/ a 4)))) => 3/4 (let ((a 3)) (infix (begin (/ a 4)))) => 3/4 (let ((a 1) (b 2) (c 3)) (infix (1 + a ? (begin (+ 2 b)) : 3 + c - 4)) ==> (if (+ 1 a) (begin (+ 2 b)) (- (+ 3 c) 4)) #f) * The following binding aliases are exported by the library: and -> && or -> !! xor -> ^^ not -> ~~ mod -> % bitwise-and -> & bitwise-ior -> ! bitwise-xor -> ^ bitwise-not -> ~ bitwise-arithmetic-shift-left -> << bitwise-arithmetic-shift-right -> >> fxand -> fx& fxior -> fx! fxxor -> fx^ fxnot -> fx~ fxarithmetic-shift-left -> fx<< fxarithmetic-shift-right -> fx>> 4. Testing ---------- The included Makefile provides a "test" rule which attempts to run tests with all the supported Scheme implementations. In detail the following rules are defined: gtest - Run tests with Guile ltest - Run tests with Larceny mtest - Run tests with Mosh ptest - Run tests with Petite Chez rtest - Run tests with Racket stest - Run tests with Sagittarius vtest - Run tests with Vicare ytest - Run tests with Ypsilon 5. Installing ------------- There is no "install" rule in the Makefile, sorry. We have to install the library by hand with commands like the following: cd <top of infix tree> prefix=/usr/local datarootdir=$prefix/share datadir=$datarootdir schemedir=$datadir/scheme infixdir=$schemedir/infix install -d $infixdir install infix/infix.sls $infixdir A. Credits ---------- The library is the work of Marco Maggi, the code is derived from the Nausicaa/Scheme distribution of libraries. The only way to regenerate the parser table is to build it in Nausicaa/Scheme and copy it into the library here. The parser table and the general concept of the package is a rework of Guile-Arith by Ian Grant. The parser driver is from the Lalr-scm package by Dominique Boucher, the parser table is also generated using Lalr-scm. The implementation of XOR is by Derick Eddington. B. Bug reports -------------- Bug reports are appreciated, send them by email to Marco Maggi <marco.maggi-ipsu@poste.it> or use the project's Issue tracker: <http://github.com/marcomaggi/infix/issues> C. Resources ------------ The last revision of this package can be downloaded from: <http://github.com/marcomaggi/infix/downloads> <http://github.com/marcomaggi/infix/> The R6RS documents are available at: <http://www.r6rs.org> Guile Scheme can be downloaded from: <http://www.gnu.org/software/guile/guile.html> Larceny Scheme can be downloaded from: <http://www.ccs.neu.edu/home/will/Larceny/> <https://trac.ccs.neu.edu/trac/larceny/> Mosh Scheme can be downloaded from: <http://code.google.com/p/mosh-scheme/> Petite Chez Scheme can be downloaded from: <http://www.scheme.com/> Racket can be downloaded from: <http://racket-lang.org/> Sagittarius Scheme can be downloaded from: <http://code.google.com/p/sagittarius-scheme/> Ypsilon Scheme can be downloaded from: <http://code.google.com/p/ypsilon/> Vicare Scheme can be downloaded from: <http://github.com/marcomaggi/vicare/downloads> <http://github.com/marcomaggi/vicare/> the home page of the Nausicaa project is at: <http://marcomaggi.github.com/nausicaa.html> the latest version of the Nausicaa packages can be downloaded from: <http://github.com/marcomaggi/nausicaa-scheme/> ### end of file # Local Variables: # mode: text # fill-column: 72 # paragraph-start: "*" # End: