git @ Cat's Eye Technologies Castile / master eg / assoc.castile
master

Tree @master (Download .tar.gz)

assoc.castile @masterraw · history · blame

/*
 * Implementation of an associative map in Castile.
 *
 * The map is implemented as an association list,
 * but this fact is hidden from clients, as only
 * the operations have access to the internals
 * of the struct.
 */

struct assoc {
  key: string;
  value: string;
  next: assoc|void;
} for (update, lookup, remove, render)

fun empty() {
  return null as assoc|void
}

fun update(k: string, v: string, a: assoc|void) {
  make assoc(key:k, value:v, next:a as assoc|void)
}

lookup : assoc|void, string -> string|void
fun lookup(a: assoc|void, k: string) {
  typecase a is void {
    return null as string|void
  }
  typecase a is assoc {
    if a.key == k {
      return a.value as string|void
    }
    return lookup(a.next, k)
  }
}

remove : assoc|void, string -> assoc|void
fun remove(a: assoc|void, k: string) {
  typecase a is void {
    return a as assoc|void
  }
  typecase a is assoc {
    if a.key == k {
      return remove(a.next, k)
    }
    return make assoc(key:a.key, value:a.value, next:remove(a.next, k)) as assoc|void
  }
}

render : assoc|void -> string
fun render(a: assoc|void) {
  typecase a is void {
    return ""
  }
  typecase a is assoc {
    return concat(a.value, concat(",", render(a.next)))
  }
}

fun main() {
  a = update("3", "third", empty());
  a = update("2", "second", a as assoc|void);
  a = update("1", "first", a as assoc|void);
  print(render(a as assoc|void))
  b = remove((a as assoc|void), "2");
  print(render(b))
  r = lookup(b, "2");
  typecase r is void { print("NOT FOUND"); }
  typecase r is string { print(r); }
}