package main
import (
- "fmt";
- "io";
- "os";
+ "fmt"
+ "io"
+ "os"
)
///--------------------------------------------------------------------------
/// Utilities.
-var prog = os.Args[0];
+var prog = os.Args[0]
func bail(msg string) {
- fmt.Fprintf(os.Stderr, "%s: %s\n", prog, msg);
- os.Exit(1);
+ fmt.Fprintf(os.Stderr, "%s: %s\n", prog, msg)
+ os.Exit(1)
}
///--------------------------------------------------------------------------
type Iterable interface {
// Simply put the items to the channel CH one at a time.
- Iterate(ch chan<- any);
+ Iterate(ch chan<- any)
}
// An iterator.
-type Iterator <-chan any;
+type Iterator <-chan any
// Returns an iterator for a given iterable thing.
func MakeIterator(it Iterable) Iterator {
- ch := make(chan any);
+ ch := make(chan any)
go func () {
- it.Iterate(ch);
- close(ch);
- } ();
- return ch;
+ it.Iterate(ch)
+ close(ch)
+ } ()
+ return ch
}
// Returns the next item from an iterator IT. If there is indeed an item
// available, return it and true; otherwise return nil and false.
func (it Iterator) Next() (any, bool) {
- item, anyp := <-it;
- return item, anyp;
+ item, anyp := <-it
+ return item, anyp
}
// Answer whether the iterators return the same items in the same order.
// Equality is determined using `=='. Maybe we'll do better some day.
func SameIterators(ia, ib Iterator) bool {
for {
- a, any_a := ia.Next();
- b, any_b := ib.Next();
+ a, any_a := ia.Next()
+ b, any_b := ib.Next()
if !any_a { return !any_b }
if a != b { break }
}
- return false;
+ return false
}
///--------------------------------------------------------------------------
// Just a simple binary tree.
type Node struct {
- data byte;
- left, right *Node;
+ data byte
+ left, right *Node
}
// Iteration is easy. Note that recursion is fine here: this is just a
// simple function.
func (n *Node) Iterate(ch chan<- any) {
if n == nil { return }
- n.left.Iterate(ch);
- ch <- n.data;
- n.right.Iterate(ch);
+ n.left.Iterate(ch)
+ ch <- n.data
+ n.right.Iterate(ch)
}
// Parse a tree from a textual description. The syntax is simple:
// where the ambiguity is resolved by declaring that a `(' is a tree if we're
// expecting a tree.
func ParseTree(s string) *Node {
- var parse func(int) (*Node, int);
- n := len(s);
- i := 0;
+ var parse func(int) (*Node, int)
+ n := len(s)
+ i := 0
parse = func(i int) (*Node, int) {
if i < n && s[i] == '(' {
- left, i := parse(i + 1);
+ left, i := parse(i + 1)
if i >= n { bail("no data") }
- data := s[i];
- right, i := parse(i + 1);
+ data := s[i]
+ right, i := parse(i + 1)
if i >= n || s[i] != ')' { bail("missing )") }
- return &Node { data, left, right }, i + 1;
+ return &Node { data, left, right }, i + 1
}
- return nil, i;
- };
- t, i := parse(0);
+ return nil, i
+ }
+ t, i := parse(0)
if i < n { bail("trailing junk") }
- return t;
+ return t
}
///--------------------------------------------------------------------------
func main() {
switch len(os.Args) {
case 2:
- t := ParseTree(os.Args[1]);
- i := MakeIterator(t);
+ t := ParseTree(os.Args[1])
+ i := MakeIterator(t)
for {
- item, winp := i.Next();
+ item, winp := i.Next()
if !winp { break }
- fmt.Printf("%c", item);
+ fmt.Printf("%c", item)
}
- fmt.Printf("\n");
+ fmt.Printf("\n")
case 3:
- ia := MakeIterator(ParseTree(os.Args[1]));
- ib := MakeIterator(ParseTree(os.Args[2]));
+ ia := MakeIterator(ParseTree(os.Args[1]))
+ ib := MakeIterator(ParseTree(os.Args[2]))
if SameIterators(ia, ib) {
- io.WriteString(os.Stdout, "match\n");
+ io.WriteString(os.Stdout, "match\n")
} else {
- io.WriteString(os.Stdout, "no match\n");
+ io.WriteString(os.Stdout, "no match\n")
}
default:
- bail("bad args");
+ bail("bad args")
}
}