Browse Source

add README

Getty Ritter 2 years ago
parent
commit
b1f1f71d02
1 changed files with 91 additions and 0 deletions
  1. 91 0
      README.md

+ 91 - 0
README.md

@@ -0,0 +1,91 @@
+**Matzo** is my first attempt at a language designed for creating random text fragments, now reimplemented in Rust.
+
+(The earlier versions were Haskell and JavaScript, and both have bit-rotted rather badly: I'm hoping that this version is both cleaner—on account of my writing it a decade later—and also that this version is easier to modify and will be more resilient to bit-rot.)
+
+## Matzo basics
+
+There are two basic kinds of statements: assignment and printing. Assignment is usually done with `:=`. All statements are terminated with a semicolon (although the REPL will usually tolerate you leaving it off.)
+
+```
+greeting := "hello";
+```
+
+Printing statements are written with `puts`.
+
+```
+puts greeting; (* prints "hello" *)
+```
+
+The two most common operations are catenation and choice. Catenation is indicated by simply putting expressions next to each other:
+
+```
+puts "Hello" " " "world!";
+```
+
+Choice is indicated by putting vertical bars between various choices.
+
+```
+puts "Hello!" | "Hey!" | "Yo!";
+```
+
+Catenation binds more tightly than choice, but parentheses can explicitly group operations.
+
+```
+puts ("Bonjour" | "Buenos dias") ", world!";
+```
+
+Choices can also be weighted by using a number and `:`. In the following example, there's a 1/6 chance of getting `"tails"`, and a 5/6 chance of getting `"heads"`:
+
+```
+puts 5: "heads" | "tails";
+```
+
+Since it's quite common to want to choose from some basic string literals, there's a special case for that: the `::=` operator allows you to list zero or more space-separated identifiers, and then it will treat them as strings and choose between them with equal weight.
+
+```
+suits ::= hearts diamonds clubs spades;
+(* this is equivalent to writing
+   suits := "hearts" | "diamonds" | "clubs" | "spades";
+*)
+```
+
+Importantly, definitions in Matzo are _lazy_: if something is defined as a choice between alternatives, then every use of that thing has a chance of choosing a different alternative.
+
+```
+letter ::= a b;
+(* this might print any of aa, ab, ba, bb *)
+puts letter letter;
+```
+
+Matzo also allows you to _fix_ definitions, which will evaluate them once and use that version for every subsequent reference. There are two ways of doing this: one is to prefix the assignment with the `fix` keyword:
+
+```
+fix letter ::= a b;
+(* this can only print aa or bb *)
+puts letter letter;
+```
+
+The other is to use `fix` as a standalone statement, which modifies a definition in-scope by fixing it.
+
+```
+letter ::= a b;
+puts letter letter; (* aa, ab, ba, or bb *)
+fix letter;
+puts letter letter; (* aa or bb *)
+```
+
+## Fancier Matzo
+
+- Data types (atoms, tuples)
+- Functions
+- Pattern-matching
+
+## Implementation notes
+
+## Todo
+
+- [ ] Pattern matching
+- [ ] Closures
+- [ ] Expand the stdlib
+- [ ] Switch to packed expr representation for easier sharing
+- [ ] Think about how to express GC