aboutsummaryrefslogtreecommitdiff
path: root/README.org
blob: 7abb54677eed0098e442665bb9450e5570097c39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
* Argot: A System For Grammar-Driven Macros

The ~argot~ system provides a macro-defining-macro called
~deflanguage~. The ~deflanguage~ macro accepts a context-free grammar,
augmented with parse handlers, and defines a macro whose body is
parsed and expanded according to that augmented grammar.

** A brief tour

In ~/examples/calc.lisp~ you see the following ~deflanguage~:

#+begin_src lisp

(deflanguage calc (:documentation "A calculator language")
  (<start>
   :match (:or
           (:seq <subexpr> (:eof))
           (:seq <value> (:eof))
           (:seq <unop> (:eof))
           (:seq <binop> (:eof)))
   :then car)
  (<expr>
   :match (:or <subexpr> <value> <unop> <binop>))
  (<subexpr>
   :match (:{} calc))
  (<value>
   :match (:item)
   :if numberp)
  (<binop>
   :match (:seq
            (:@ lhs <expr>)
            (:@ rhs (:+ (:seq (:or= + - / * ^ %) <expr>))))
   :then (expand-binop lhs rhs))
  (<unop>
   :match (:seq (:or= sin cos tan -) <expr>)))

#+end_src

This defines a cacluator language that you can use like so:

#+begin_src lisp

> (calc 1)
1
> (calc 1 + 2 + 3)
6
> (calc 1 + 2 * 3)
7
> (calc (1 + 2) * 3)
9
> (calc (1 + 2) * 3 + 1)
10
> (calc (1 + 2) * (3 + 1))
12
> (calc 2 ^ (2 * (1 + 1)))
16

#+end_src

The symbol ~calc~ also has a function docstring. If you are in slime,
you can evoke ~M-x slime-documentation~ with your cursor over the
~calc~ symbol and see this:

#+begin_src

Documentation for the symbol CALC:

Function:
 Arglist: (&BODY TOKENS)

 A calculator language

<START>         ::= (<SUBEXPR> ::EOF:: | <VALUE> ::EOF:: | <UNOP> ::EOF:: | <BINOP> ::EOF::)
<EXPR>          ::= (<SUBEXPR> | <VALUE> | <UNOP> | <BINOP>)
<SUBEXPR>       ::= {CALC}
<VALUE>         ::= ::TOKEN::
<BINOP>         ::= <EXPR> ('+' | '-' | '/' | '*' | '^' | '%') <EXPR>⁤+
<UNOP>          ::= ('SIN' | 'COS' | 'TAN' | '-') <EXPR>

KEY: 
::TOKEN::  Any ole token
::EOF::    Explicitly match the end of the input
{GRAMMAR}  Parse a sublist of tokens with GRAMMAR
(a|b|..)   One of the alternavites a b ...
PATTERN+   One or more PATTERN
PATTERN*   Zero or more PATTERN
<RULE>     A nonterminal symbol - naming a parse rule
[OPT]      Zero or one of OPT

#+end_src

** User Guide