(** Some example programs in the Matzo language
 *
 * It is important to note that, in the Matzo language, the value of a
 * variable is generally not a single value, but one of a set of values.
 * Every time a variable is used, an element is drawn from this set;
 * so the following program can print 1, 2, 3, 10, 20, or 30. *)

x := 1 | 2 | 3;
f := { n => x } 
   | { n => n * 10 };
puts f(x);


(* The Aquan language program *)

(* The ::= operator is for the common case that we want to select from a
 * whole bunch of literal characters or words. It is referred to as the
 * 'literal assignment operator'. *)
vowel ::= a e i o u;
consonant ::= p t k w h m n l;

(* The := operator sets the value on the left to be 
syll := vowel | consonant vowel
      | vowel "'" | consonant vowel "'";
word := syll syll (6 @ syll);


(* Fixing a value *)

(* The built-in pseudo-function `choose` allows you to force a value
 * to stay the same. *)

n := 1 | 2;
m := n; fix m;
(* The following could print either "1,2", "2,1" "1,1" or "2,2" *)
puts "{n},{n}"
(* The following can only print "1,1" or "2,2" *)
puts "{m},{m}"


(* A random person description *)

(* Identifiers that begin with capitals are symbols. Symbols can be
 * compared and matched against. It is not allowed to use an identifier
 * that begins with a capital as a variable. *)

pronoun := 
  { Male => "he"
  ; Female => "she"
  };
person :=
  { Male => "man"
  ; Female => "woman"
  };

gender := Male | Female;
fix gender;
hair ::= long short;
hair_color ::= brown black blonde red white;
eye_color ::= blue black brown green;
mood ::= happy sad angry;

puts "This {person.gender} has {hair}, {hair_color} hair and "
     "{eye_color} eyes; {pronoun.gender} appears to be "
     "quite {mood}.";


