diff options
author | colin <colin@cicadas.surf> | 2023-08-03 06:39:48 -0700 |
---|---|---|
committer | colin <colin@cicadas.surf> | 2023-08-03 06:39:48 -0700 |
commit | 7dcb51ab0ec2dadd3728a3872a56cb64c1e0c23a (patch) | |
tree | 9788c3191ce2d29b694fd7cbd4d30d9b4502ab67 /README.org | |
parent | b0213128f7c0cde618c0c3ca958c6b79f2de4b72 (diff) |
Add initial readme
Diffstat (limited to 'README.org')
-rw-r--r-- | README.org | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/README.org b/README.org new file mode 100644 index 0000000..7abb546 --- /dev/null +++ b/README.org @@ -0,0 +1,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 + |