401 lines
54 KiB
HTML
401 lines
54 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||
|
<title>CLiki: Infix</title>
|
||
|
<link rel="alternate" type="application/atom+xml" title="ATOM feed of edits to current article"
|
||
|
href="https://www.cliki.net/site/feed/article.atom?title=Infix">
|
||
|
<link rel="stylesheet" href="static/css/style.css">
|
||
|
<link rel="stylesheet" href="static/css/colorize.css">
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<span class="hidden">CLiki - Infix</span>
|
||
|
<div id="content"><div id="content-area"><div id="article-title">Infix</div><div id="article">The infix notation for arithmetic in Common Lisp.<p><ul>
|
||
|
<li>
|
||
|
<a href="polisher.html" class="internal">polisher</a> -
|
||
|
<a href="Infix.html" class="category">Infix</a> notation to <a href="s-exp syntax.html" class="internal">S-expression</a> (Polish notation) translator for Common Lisp
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="ugly-tiny-infix-macro.html" class="internal">ugly-tiny-infix-macro</a> -
|
||
|
This is a powerful lisp macro for the purpose of writing your expressions in <a href="infix.html" class="category">infix</a> notation while not losing out on lisp's power
|
||
|
</li>
|
||
|
</ul> <p><h2>Infix reader-macro by Mark Kantrowitz.</h2><p>Available from the <a href="CMU AI Repository.html" class="internal">CMU AI Repository</a>: <a href="http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/infix.cl">infix.cl</a>.<p>The Changelog from the <a href="cclan.html" class="internal">cclan</a> version reads<p><pre>
|
||
|
2005-06-06:
|
||
|
* infix.cl: bind *read-suppress* in infix-reader to support the
|
||
|
use of infix notation when *read-suppress* is true.
|
||
|
|
||
|
Christophe Rhodes <csr21@cam.ac.uk>
|
||
|
|
||
|
2002-03-04:
|
||
|
* infix.cl: moved definition of infix-error macro to before its
|
||
|
first use.
|
||
|
|
||
|
Christophe Rhodes <csr21@cam.ac.uk>.
|
||
|
</pre><p>This is not the most volatile piece of software.<p>Incidentally, it's probably <a href="non-free.html" class="internal">non-free</a> — there's a non-commercial clause in the <a href="license.html" class="internal">license</a>.<p>There is also a <a href="Debian package.html" class="category">Debian package</a>.<p>Note: Users may want to consider <a href="readable.html" class="internal">readable</a> instead, which is <a href="MIT.html" class="internal">MIT</a>-licensed and has support for an infix notation.<p>Another package by Alan Manuel Gloria can be found <a href="http://web.archive.org/web/20100102215454/http://plaza.ufl.edu/lavigne/resources/index.html">here</a>, but it's buggy on expressions like <p><div class="code"><span class="nonparen"><span class="paren1">(<span class="nonparen">nfx 55 <a href="https://www.cliki.net/site/HyperSpec/Body/any_-.html" class="symbol">-</a> 3 <a href="https://www.cliki.net/site/HyperSpec/Body/any_st.html" class="symbol">*</a> 4 <a href="https://www.cliki.net/site/HyperSpec/Body/any_pl.html" class="symbol">+</a> 2000000</span>)</span></span></div><p>(giving -1999957 instead of the correct result 2000043. There seems to be a problem with different operators of the same precedence. <p>Here's a corrected version of the macro implementation:<p><div class="code"><span class="nonparen"><span class="comment">;; infix.lisp
|
||
|
</span><span class="comment">;; by AmkG
|
||
|
</span>
|
||
|
<span class="comment">;; Title : Infix notation macro
|
||
|
</span><span class="comment">;; Filename : infix.lisp
|
||
|
</span><span class="comment">;; Written by : Alan Manuel K. Gloria <almkglor@gmail.com>
|
||
|
</span><span class="comment">;; Corrected by : Bruno Daniel <bruno.daniel@gmx.net>
|
||
|
</span>
|
||
|
<span class="comment">;; Copyright status:
|
||
|
</span><span class="comment">;; Err. I don't care? Okay, I do care. To be honest, I'll just
|
||
|
</span><span class="comment">;; be plain happy if somebody ELSE uses this. Drop me a line,
|
||
|
</span><span class="comment">;; or something. Or don't. I built this for my own amusement,
|
||
|
</span><span class="comment">;; so if anyone else is amused too, well, drop me a line!
|
||
|
</span>
|
||
|
<span class="comment">;; tested on:
|
||
|
</span><span class="comment">;; clisp
|
||
|
</span><span class="comment">;; gcl
|
||
|
</span><span class="comment">;; sbcl
|
||
|
</span><span class="comment">;; ecl
|
||
|
</span>
|
||
|
<span class="comment">;; infix notation:
|
||
|
</span><span class="comment">;; Lisp has traditionally used prefix notation for all formulae: in this
|
||
|
</span><span class="comment">;; notation, the operation to be performed is specified before the
|
||
|
</span><span class="comment">;; operands it is to be performed on. This simple notation gives a
|
||
|
</span><span class="comment">;; consistent, regular syntax which greatly facilitates
|
||
|
</span><span class="comment">;; metaprogramming.
|
||
|
</span>
|
||
|
<span class="comment">;; However, one weakness of prefix notation is that some simple
|
||
|
</span><span class="comment">;; algebraic/arithmetic operations do not and cannot follow the
|
||
|
</span><span class="comment">;; traditional syntax taught to us during elementary - that is, the
|
||
|
</span><span class="comment">;; notation we are used to in arithmetic is not prefix, but infix
|
||
|
</span><span class="comment">;; notation:
|
||
|
</span><span class="comment">;; 1 + 2 - 4 * 5
|
||
|
</span><span class="comment">;; In Lisp this would be:
|
||
|
</span><span class="comment">;; (- (+ 1 2) (* 4 5)))
|
||
|
</span><span class="comment">;; Despite the inherent advantages of prefix notation, sometimes
|
||
|
</span><span class="comment">;; it's just much easier to write mathematical formulae a little more
|
||
|
</span><span class="comment">;; like the way we actually write them on paper.
|
||
|
</span>
|
||
|
<span class="comment">;; This file contains a macro, 'nfx, which allows for such an infix
|
||
|
</span><span class="comment">;; notation. There are limitations: you need to put a LOT of spaces
|
||
|
</span><span class="comment">;; in the formula:
|
||
|
</span><span class="comment">;; (nfx 1+2-3) ;would confuse the Lisp parser
|
||
|
</span><span class="comment">;; (nfx 1 + 2 - 3) ;would be understood
|
||
|
</span>
|
||
|
<span class="comment">;; You can't use certain symbols as variable names:
|
||
|
</span><span class="comment">;; (setf + 42)
|
||
|
</span><span class="comment">;; (nfx (max + 3)) ; would look awfully like +(max,3), not max(+,3)
|
||
|
</span>
|
||
|
<span class="comment">;; ...but you can embed prefix notation in it!
|
||
|
</span><span class="comment">;; (nfx 1 + (- x 100)) ;it's valid!
|
||
|
</span><span class="comment">;; (nfx 1 + (- x (3 * 3))) ;it's ALSO valid!
|
||
|
</span><span class="comment">;; (nfx 1 + (- x 3 * 3)) ;err... this can give you unexpected behavior
|
||
|
</span>
|
||
|
<span class="comment">;; ...also, you can define your own infix symbols using definfix:
|
||
|
</span><span class="comment">;; (definfix my-infix-symbol
|
||
|
</span><span class="comment">;; :precedence 40
|
||
|
</span><span class="comment">;; :function-name +)
|
||
|
</span><span class="comment">;; (nfx 1 my-infix-symbol 2)
|
||
|
</span><span class="comment">;; => 3
|
||
|
</span>
|
||
|
<span class="comment">;; send any feedback, bugreports, bugfixes, and cute girls to:
|
||
|
</span><span class="comment">;; almkglor@gmail.com
|
||
|
</span>
|
||
|
<span class="comment">;; This file defines a macro of the form (nfx ...) whose
|
||
|
</span><span class="comment">;; parameters are a stream of LISP "tokens" (either symbols,
|
||
|
</span><span class="comment">;; constants, or lists). The stream of tokens is interpreted
|
||
|
</span><span class="comment">;; in infix notation. The macro then expands to the prefix
|
||
|
</span><span class="comment">;; form equivalent to the infix form
|
||
|
</span><span class="comment">;; Ex.
|
||
|
</span><span class="comment">;; (macroexpand-1 '(nfx foo = 32))
|
||
|
</span><span class="comment">;; => (setf foo 32)
|
||
|
</span><span class="comment">;; (macroexpand-1 '(nfx bar == (3 + foo) * quux ))
|
||
|
</span><span class="comment">;; => (equal bar (* (+ 3 foo) quux))
|
||
|
</span>
|
||
|
<span class="comment">;; NOTE: detection of function calls
|
||
|
</span><span class="comment">;; function call forms should be supported:
|
||
|
</span><span class="comment">;; (macroexpand-1 '(nfx foo = (max (bar + 32) quux niaw) ))
|
||
|
</span><span class="comment">;; => (setf foo (max (+ bar 32) quux niaw))
|
||
|
</span><span class="comment">;; (macroexpand-1 '(nfx (cdr foo) = (cons (qux + 1) nil)))
|
||
|
</span><span class="comment">;; => (setf (cdr foo) (cons (+ qux 1) nil))
|
||
|
</span>
|
||
|
<span class="comment">;; If any infix notation is in a function call within an
|
||
|
</span><span class="comment">;; nfx form, it should be within a parentheses:
|
||
|
</span><span class="comment">;; (macroexpand-1 '(nfx (max (bar + foo) (quux + quuux)) ))
|
||
|
</span><span class="comment">;; => (max (+ bar foo) (+ quux quuux))
|
||
|
</span><span class="comment">;; (macroexpand-1 '(nfx (max bar + foo quux + quuux) ))
|
||
|
</span><span class="comment">;; => (max bar + foo quux + quuux)
|
||
|
</span>
|
||
|
<span class="comment">;; function calls are detected in the following manner:
|
||
|
</span><span class="comment">;; if nfx detects a list in the input stream,
|
||
|
</span><span class="comment">;; if the second item is not a registered infix,
|
||
|
</span><span class="comment">;; function call, for each element recurse and replace the element
|
||
|
</span><span class="comment">;; not a function call, recurse on the list as a new stream
|
||
|
</span>
|
||
|
<span class="comment">;; this allows us to use prefix operators (such as -) as-is:
|
||
|
</span><span class="comment">;; (macroexpand-1 '(nfx (- bar) == (/ (foo + 1)) ))
|
||
|
</span><span class="comment">;; => (equal (- bar) (/ (+ foo 1)))
|
||
|
</span>
|
||
|
|
||
|
<span class="comment">;; (nfx-operator-base <action> ...)
|
||
|
</span><span class="comment">;; Handles the operator database
|
||
|
</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_letcm_letst.html" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">nfx-data <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_make-hash-table.html" class="symbol">make-hash-table</a> <span class="keyword">:test</span> '<a href="https://www.cliki.net/site/HyperSpec/Body/fun_eq.html" class="symbol">eq</a></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defun.html" class="symbol"><i><span class="symbol">defun</span></i></a> nfx-operator-base <span class="paren3">(<span class="nonparen">action &rest params</span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_fletcm_scm_macrolet.html" class="symbol"><i><span class="symbol">labels</span></i></a>
|
||
|
<span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen">getval <span class="paren6">(<span class="nonparen">sym</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_gethash.html" class="symbol">gethash</a> sym nfx-data</span>)</span> </span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">add <span class="paren6">(<span class="nonparen">params</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_gethash.html" class="symbol">gethash</a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> params</span>)</span> nfx-data</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_apply.html" class="symbol">apply</a> #'<a href="https://www.cliki.net/site/HyperSpec/Body/any_vector.html" class="symbol">vector</a> params</span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_casecm_ccasecm_ecase.html" class="symbol">case</a> action
|
||
|
<span class="paren5">(<span class="nonparen"><span class="keyword">:get</span> <span class="paren6">(<span class="nonparen">getval <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> params</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen"><span class="keyword">:add</span> <span class="paren6">(<span class="nonparen">add params</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
|
||
|
|
||
|
<span class="comment">;;; the nfx macro
|
||
|
</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defun.html" class="symbol"><i><span class="symbol">defun</span></i></a> nfx-impl <span class="paren2">(<span class="nonparen">s</span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_letcm_letst.html" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren3">(<span class="nonparen">opstack
|
||
|
curop tmp
|
||
|
<span class="paren4">(<span class="nonparen">bldg <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_fletcm_scm_macrolet.html" class="symbol"><i><span class="symbol">labels</span></i></a>
|
||
|
<span class="paren4">(<span class="nonparen"> <span class="comment">;; tconc = a cons with pointers to the head and the last element of
|
||
|
</span> <span class="comment">;; a list. This function appends an element to such a tconc.
|
||
|
</span> <span class="paren5">(<span class="nonparen">tconc-append <span class="paren6">(<span class="nonparen">l v</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> l</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cdr</a> l</span>)</span> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cddr</a> l</span>)</span> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> v <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> l</span>)</span> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cdr</a> l</span>)</span> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> v <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span> </span>)</span></span>)</span>
|
||
|
<span class="comment">;; top-of-stack query
|
||
|
</span> <span class="paren5">(<span class="nonparen">top-opstack <span class="paren6">(<span class="nonparen"></span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">caaar</a> opstack</span>)</span></span>)</span>
|
||
|
<span class="comment">;; handles any sub-lists
|
||
|
</span> <span class="paren5">(<span class="nonparen">enlist <span class="paren6">(<span class="nonparen">l</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">when</a> l
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_cond.html" class="symbol"><i><span class="symbol">cond</span></i></a> <span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen">getop <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cadr</a> l</span>)</span></span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> 'nfx l</span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_mapccm_ma_istcm_mapcon.html" class="symbol">mapcar</a> #'<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren5">(<span class="nonparen">o</span>)</span> <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_listp.html" class="symbol">listp</a> o</span>)</span> <span class="paren6">(<span class="nonparen">enlist o</span>)</span> o</span>)</span></span>)</span>
|
||
|
l</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="comment">;; pushes an operation onto the stack - used when the currently
|
||
|
</span> <span class="comment">;; being built operation is of lower precedence than the
|
||
|
</span> <span class="comment">;; operation being considered
|
||
|
</span> <span class="paren5">(<span class="nonparen">push-oper <span class="paren6">(<span class="nonparen"></span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_push.html" class="symbol">push</a> bldg opstack</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> bldg <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="comment">;; pops off an operation from the stack,
|
||
|
</span> <span class="comment">;; - used before collapsing the call
|
||
|
</span> <span class="paren5">(<span class="nonparen">pop-oper <span class="paren6">(<span class="nonparen"></span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_letcm_letst.html" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren1">(<span class="nonparen"><span class="paren2">(<span class="nonparen">top <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_pop.html" class="symbol">pop</a> opstack</span>)</span></span>)</span> </span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen">tconc-append top <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> bldg</span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> bldg top</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="comment">;; sub-expression handling code
|
||
|
</span> <span class="paren5">(<span class="nonparen">expr <span class="paren6">(<span class="nonparen">o</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_listp.html" class="symbol">listp</a> o</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen">enlist o</span>)</span>
|
||
|
o</span>)</span></span>)</span>
|
||
|
<span class="comment">;; determine if the specified operation has precedence over the
|
||
|
</span> <span class="comment">;; operation currently being built
|
||
|
</span> <span class="paren5">(<span class="nonparen">precedes? <span class="paren6">(<span class="nonparen">op1 op2 associativity</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_or.html" class="symbol">or</a> <span class="paren1">(<span class="nonparen">< <span class="paren2">(<span class="nonparen">precedence op1</span>)</span> <span class="paren2">(<span class="nonparen">precedence op2</span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_and.html" class="symbol">and</a> <span class="paren2">(<span class="nonparen">= <span class="paren3">(<span class="nonparen">precedence op1</span>)</span> <span class="paren3">(<span class="nonparen">precedence op2</span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_eq.html" class="symbol">eq</a> <span class="paren3">(<span class="nonparen">associativity op1</span>)</span> associativity</span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="comment">;; funges bldg: collapses fungible operations into one form
|
||
|
</span> <span class="paren5">(<span class="nonparen">fungebldg <span class="paren6">(<span class="nonparen">bldg</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_mapccm_ma_istcm_mapcon.html" class="symbol">mapcan</a>
|
||
|
#'<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren2">(<span class="nonparen">o</span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_cond.html" class="symbol"><i><span class="symbol">cond</span></i></a> <span class="paren3">(<span class="nonparen"><span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_listp.html" class="symbol">listp</a> o</span>)</span>
|
||
|
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> o <span class="paren5">(<span class="nonparen">fungebldg o</span>)</span></span>)</span>
|
||
|
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_cond.html" class="symbol"><i><span class="symbol">cond</span></i></a> <span class="paren5">(<span class="nonparen"><span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_and.html" class="symbol">and</a> <span class="paren1">(<span class="nonparen">fungible <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> bldg</span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_eq.html" class="symbol">eq</a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> o</span>)</span> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> bldg</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cdr</a> o</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> o <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> o <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
bldg</span>)</span></span>)</span>
|
||
|
<span class="comment">;; fixes bldg: changes operation objects to their functions
|
||
|
</span> <span class="paren5">(<span class="nonparen">fixbldg <span class="paren6">(<span class="nonparen">bldg</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">when</a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_vectorp.html" class="symbol">vectorp</a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> bldg</span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> bldg</span>)</span> <span class="paren2">(<span class="nonparen">function-name <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> bldg</span>)</span></span>)</span></span>)</span> </span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_mapccm_ma_istcm_mapcon.html" class="symbol">mapc</a>
|
||
|
#'<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren2">(<span class="nonparen">o</span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">when</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_listp.html" class="symbol">listp</a> o</span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen">fixbldg o</span>)</span> </span>)</span></span>)</span>
|
||
|
bldg </span>)</span></span>)</span>
|
||
|
<span class="comment">;; error-handling function
|
||
|
</span> <span class="paren5">(<span class="nonparen">err <span class="paren6">(<span class="nonparen">l</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_error.html" class="symbol">error</a> <span class="string">"improper nfx expression:~%~s"</span> l</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">print-expr-list <span class="paren6">(<span class="nonparen">l</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="string">"("</span></span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_loop.html" class="symbol"><i><span class="symbol">loop</span></i></a> <span class="keyword">:for</span> x in l
|
||
|
<span class="keyword">:for</span> i from 0 <span class="keyword">:do</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">when</a> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_minuspcm_plusp.html" class="symbol">plusp</a> i</span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="string">" "</span></span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_cond.html" class="symbol"><i><span class="symbol">cond</span></i></a> <span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_vectorp.html" class="symbol">vectorp</a> x</span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="string">"~s"</span> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_aref.html" class="symbol">aref</a> x 0</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_listp.html" class="symbol">listp</a> x</span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen">print-expr-list x</span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="string">"~s"</span> x</span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_format.html" class="symbol">format</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <span class="string">")"</span></span>)</span></span>)</span>
|
||
|
<span class="comment">;; (print-tconc (tc)
|
||
|
</span> <span class="comment">;; (print-expr-list (car tc))
|
||
|
</span> <span class="comment">;; (format t "~%"))
|
||
|
</span> <span class="comment">;; accessor functions
|
||
|
</span> <span class="paren5">(<span class="nonparen">precedence <span class="paren6">(<span class="nonparen">op</span>)</span> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> op <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_aref.html" class="symbol">aref</a> op 1</span>)</span> 99999</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">associativity <span class="paren6">(<span class="nonparen">op</span>)</span> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_aref.html" class="symbol">aref</a> op 2</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">function-name <span class="paren6">(<span class="nonparen">op</span>)</span> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_aref.html" class="symbol">aref</a> op 3</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">fungible <span class="paren6">(<span class="nonparen">op</span>)</span> <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">when</a> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_vectorp.html" class="symbol">vectorp</a> op</span>)</span> <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_aref.html" class="symbol">aref</a> op 4</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="comment">;; get the data for a (presumed) infix operator
|
||
|
</span> <span class="paren5">(<span class="nonparen">getop <span class="paren6">(<span class="nonparen">op</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen">nfx-operator-base <span class="keyword">:get</span> op</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_casecm_ccasecm_ecase.html" class="symbol">case</a> <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_length.html" class="symbol">length</a> s</span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">1 <span class="paren6">(<span class="nonparen">expr <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> s</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">2 <span class="paren6">(<span class="nonparen">err s</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_docm_dost.html" class="symbol">do</a> <span class="paren1">(<span class="nonparen"> <span class="comment">;; variable and step list
|
||
|
</span> <span class="paren2">(<span class="nonparen">oL s <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cddr</a> oL</span>)</span></span>)</span> </span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"> <span class="comment">;; termination condition
|
||
|
</span> <span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_null.html" class="symbol">null</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cddr</a> oL</span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen">tconc-append bldg <span class="paren3">(<span class="nonparen">expr <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> oL</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_whencm_unless.html" class="symbol">when</a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cdr</a> oL</span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen">err oL</span>)</span> </span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_loop.html" class="symbol"><i><span class="symbol">loop</span></i></a> <span class="keyword">:while</span> opstack <span class="keyword">:do</span>
|
||
|
<span class="paren3">(<span class="nonparen">pop-oper</span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen">fixbldg <span class="paren3">(<span class="nonparen">fungebldg <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">caar</a> bldg</span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> curop <span class="paren2">(<span class="nonparen">getop <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">cadr</a> oL</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_cond.html" class="symbol"><i><span class="symbol">cond</span></i></a> <span class="paren2">(<span class="nonparen">curop
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_cond.html" class="symbol"><i><span class="symbol">cond</span></i></a> <span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen">precedes? curop <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">caar</a> bldg</span>)</span> <span class="keyword">:right</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">push-oper</span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">tconc-append bldg curop</span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">tconc-append bldg <span class="paren6">(<span class="nonparen">expr <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> oL</span>)</span></span>)</span></span>)</span> </span>)</span>
|
||
|
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a>
|
||
|
<span class="paren5">(<span class="nonparen">tconc-append bldg <span class="paren6">(<span class="nonparen">expr <span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> oL</span>)</span></span>)</span></span>)</span>
|
||
|
<span class="comment">;; collapse while the stacktop is precedent over the
|
||
|
</span> <span class="comment">;; current op
|
||
|
</span> <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_loop.html" class="symbol"><i><span class="symbol">loop</span></i></a> <span class="keyword">:while</span> <span class="paren6">(<span class="nonparen">precedes? <span class="paren1">(<span class="nonparen">top-opstack</span>)</span> curop <span class="keyword">:left</span></span>)</span> <span class="keyword">:do</span>
|
||
|
<span class="paren6">(<span class="nonparen">pop-oper</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> tmp <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/acc_carcm_cdr_darcm_cddddr.html" class="symbol">car</a> bldg</span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_setf.html" class="symbol">setf</a> bldg <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_cons.html" class="symbol">cons</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span></span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">tconc-append bldg curop</span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen">tconc-append bldg tmp</span>)</span> </span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a>
|
||
|
<span class="paren3">(<span class="nonparen">err oL</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
|
||
|
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmacro.html" class="symbol"><i><span class="symbol">defmacro</span></i></a> nfx <span class="paren2">(<span class="nonparen">&rest s</span>)</span>
|
||
|
<span class="paren2">(<span class="nonparen">nfx-impl s</span>)</span></span>)</span>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<span class="comment">;; (definfix <operator>
|
||
|
</span><span class="comment">;; :precedence <integer>
|
||
|
</span><span class="comment">;; [:associativity <:left | :right>]
|
||
|
</span><span class="comment">;; [:function-name <actual function>]
|
||
|
</span><span class="comment">;; [:fungible <t | nil>])
|
||
|
</span><span class="comment">;; - defines an infix operator with the symbol <operator>,
|
||
|
</span><span class="comment">;; with a precedence of <integer>. The smaller the precedence
|
||
|
</span><span class="comment">;; number, the more precedence it has: * and / have smaller
|
||
|
</span><span class="comment">;; precedence number than + and -.
|
||
|
</span><span class="comment">;; - associativity defaults to :left, which means that if two
|
||
|
</span><span class="comment">;; operators of the same precedence are encountered, the first
|
||
|
</span><span class="comment">;; one resolves first: 1 x 2 x 3 becomes ((1 x 2) x 3). This
|
||
|
</span><span class="comment">;; is appropriate for most maths. :right associativity means
|
||
|
</span><span class="comment">;; that 1 x 2 x 3 becomes (1 x (2 x 3)). This is appropriate
|
||
|
</span><span class="comment">;; for assignment. IMPORTANT: operators with the same
|
||
|
</span><span class="comment">;; precedence must have the same associativities!
|
||
|
</span><span class="comment">;; - function-name defaults to the same symbol as the operator.
|
||
|
</span><span class="comment">;; For example, the function-name of = is setf.
|
||
|
</span><span class="comment">;; - fungible means that if the same operator is encountered
|
||
|
</span><span class="comment">;; several times, then all inputs are funged into one function
|
||
|
</span><span class="comment">;; call. For example, 1 + 2 + 3 becomes (+ 1 2 3), 1 < 2 < 3
|
||
|
</span><span class="comment">;; becomes (< 1 2 3). This is not true for assignment:
|
||
|
</span><span class="comment">;; x = y = z should become (setf x (setf y z)), not (setf x y z)
|
||
|
</span><span class="comment">;; - fungible defaults to t because I noticed that nearly every
|
||
|
</span><span class="comment">;; single darned operator was fungible. Except assignment.
|
||
|
</span><span class="comment">;; Saved some dozen lines of code too.
|
||
|
</span>
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/mac_defmacro.html" class="symbol"><i><span class="symbol">defmacro</span></i></a> <i><span class="symbol">definfix</span></i> <span class="paren2">(<span class="nonparen">operator
|
||
|
&key precedence <span class="paren3">(<span class="nonparen">associativity <span class="keyword">:left</span></span>)</span>
|
||
|
function-name <span class="paren3">(<span class="nonparen">fungible <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a></span>)</span></span>)</span>
|
||
|
`<span class="paren2">(<span class="nonparen">nfx-operator-base <span class="keyword">:add</span> ',operator
|
||
|
,precedence ,associativity
|
||
|
',<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> function-name function-name operator </span>)</span>
|
||
|
,fungible</span>)</span></span>)</span>
|
||
|
|
||
|
<span class="comment">;; Predefined operators
|
||
|
</span><span class="comment">;; Note: precedences are divisibles of 10, in case you
|
||
|
</span><span class="comment">;; want to insert precedence levels between levels.
|
||
|
</span>
|
||
|
<span class="comment">;; since we expect infix notation only (not infix-postfix),
|
||
|
</span><span class="comment">;; our array accessor is a single infix @
|
||
|
</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> @ <span class="keyword">:precedence</span> 10 <span class="keyword">:function-name</span> <a href="https://www.cliki.net/site/HyperSpec/Body/acc_aref.html" class="symbol">aref</a></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> <a href="https://www.cliki.net/site/HyperSpec/Body/var_stcm_ststcm_ststst.html" class="symbol">**</a> <span class="keyword">:precedence</span> 20 <span class="keyword">:function-name</span> <a href="https://www.cliki.net/site/HyperSpec/Body/fun_expcm_expt.html" class="symbol">expt</a></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> <a href="https://www.cliki.net/site/HyperSpec/Body/any_st.html" class="symbol">*</a> <span class="keyword">:precedence</span> 30</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> / <span class="keyword">:precedence</span> 29</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> % <span class="keyword">:precedence</span> 28 <span class="keyword">:function-name</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_mod.html" class="symbol">mod</a></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> <a href="https://www.cliki.net/site/HyperSpec/Body/any_pl.html" class="symbol">+</a> <span class="keyword">:precedence</span> 40</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> <a href="https://www.cliki.net/site/HyperSpec/Body/any_-.html" class="symbol">-</a> <span class="keyword">:precedence</span> 40</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> <= <span class="keyword">:precedence</span> 60</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> < <span class="keyword">:precedence</span> 60</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> >= <span class="keyword">:precedence</span> 60</span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> > <span class="keyword">:precedence</span> 60</span>)</span>
|
||
|
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> = <span class="keyword">:precedence</span> 70 <span class="keyword">:fungible</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> /= <span class="keyword">:precedence</span> 70</span>)</span>
|
||
|
|
||
|
<span class="comment">;; 80-100 should be for the bitwise operators (&, |, ^),
|
||
|
</span><span class="comment">;; once I figure out how CL handles bitops.
|
||
|
</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> && <span class="keyword">:precedence</span> 110 <span class="keyword">:function-name</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_and.html" class="symbol">and</a></span>)</span>
|
||
|
<span class="paren1">(<span class="nonparen"><i><span class="symbol">definfix</span></i> || <span class="keyword">:precedence</span> 120 <span class="keyword">:function-name</span> <a href="https://www.cliki.net/site/HyperSpec/Body/any_or.html" class="symbol">or</a></span>)</span>
|
||
|
|
||
|
|
||
|
<span class="paren1">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_set-dispa_ro-character.html" class="symbol">set-dispatch-macro-character</a>
|
||
|
<span class="character">#\#</span> <span class="character">#\n</span>
|
||
|
#'<span class="paren2">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_lambda.html" class="symbol"><i><span class="symbol">lambda</span></i></a> <span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a> c1 c2</span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/sym_declare.html" class="symbol">declare</a> <span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/dec_ignorecm_ignorable.html" class="symbol">ignorable</a> c1 c2</span>)</span></span>)</span>
|
||
|
<span class="paren3">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_letcm_letst.html" class="symbol"><i><span class="symbol">let</span></i></a> <span class="paren4">(<span class="nonparen"><span class="paren5">(<span class="nonparen">rd <span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_readcm_re_g-whitespace.html" class="symbol">read</a> <a href="https://www.cliki.net/site/HyperSpec/Body/syscla_stream.html" class="symbol">stream</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_nil.html" class="symbol">nil</a> <a href="https://www.cliki.net/site/HyperSpec/Body/any_t.html" class="symbol">t</a></span>)</span></span>)</span></span>)</span>
|
||
|
<span class="paren4">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_if.html" class="symbol"><i><span class="symbol">if</span></i></a> <span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_listp.html" class="symbol">listp</a> rd</span>)</span>
|
||
|
`<span class="paren5">(<span class="nonparen">nfx ,@rd</span>)</span>
|
||
|
<span class="paren5">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/speope_progn.html" class="symbol"><i><span class="symbol">progn</span></i></a>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_writecm_p_rintcm_princ.html" class="symbol">print</a> 'invalid-#n-usage</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/fun_writecm_p_rintcm_princ.html" class="symbol">print</a> rd</span>)</span>
|
||
|
<span class="paren6">(<span class="nonparen"><a href="https://www.cliki.net/site/HyperSpec/Body/any_error.html" class="symbol">error</a> '<a href="https://www.cliki.net/site/HyperSpec/Body/any_error.html" class="symbol">error</a></span>)</span> </span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
|
||
|
|
||
|
|
||
|
<span class="comment">;; (nfx 55 - 3 * 4 + 2000000) used to give -1999957
|
||
|
</span><span class="comment">;; instead of the correct result 2000043. This is now corrected. -- Bruno Daniel</span></span></div><p>The program is in the <a href="public domain.html" class="category">public domain</a>.<p><hr>
|
||
|
<a href="macro example.html" class="category">macro example</a></div></div>
|
||
|
<div id="footer" class="buttonbar"><ul><li><a href="Infix.html">Current version</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/history?article=Infix">History</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/backlinks?article=Infix">Backlinks</a></li><li><a href="https://www.cliki.net/site/edit-article?title=Infix&from-revision=3801186274">Edit</a></li><li><a href="https://www.cliki.net/site/edit-article?create=t">Create</a></li></ul></div>
|
||
|
</div>
|
||
|
<div id="header-buttons" class="buttonbar">
|
||
|
<ul>
|
||
|
<li><a href="https://www.cliki.net/">Home</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/recent-changes">Recent Changes</a></li>
|
||
|
<li><a href="CLiki.html">About</a></li>
|
||
|
<li><a href="Text Formatting.html">Text Formatting</a></li>
|
||
|
<li><a href="https://www.cliki.net/site/tools">Tools</a></li>
|
||
|
</ul>
|
||
|
<div id="search">
|
||
|
<form action="https://www.cliki.net/site/search">
|
||
|
<label for="search_query" class="hidden">Search CLiki</label>
|
||
|
<input type="text" name="query" id="search_query" value="" />
|
||
|
<input type="submit" value="search" />
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="pageheader">
|
||
|
<div id="header">
|
||
|
<span id="logo">CLiki</span>
|
||
|
<span id="slogan">the common lisp wiki</span>
|
||
|
<div id="login"><form method="post" action="https://www.cliki.net/site/login">
|
||
|
<label for="login_name" class="hidden">Account name</label>
|
||
|
<input type="text" name="name" id="login_name" class="login_input" />
|
||
|
<label for= "login_password" class="hidden">Password</label>
|
||
|
<input type="password" name="password" id="login_password" class="login_input" />
|
||
|
<input type="submit" name="login" value="login" id="login_submit" /><br />
|
||
|
<div id="register"><a href="https://www.cliki.net/site/register">register</a></div>
|
||
|
<input type="submit" name="reset-pw" value="reset password" id="reset_pw" />
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</body></html>
|