1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
implement Tr;

include "sys.m";
    sys: Sys;
    print, sprint: import sys;
include "draw.m";

Tr: module
{
    init: fn(ctxt: ref Draw->Context, argv: list of string);
};

MAXRUNE: con 16rFFFF;

init(nil: ref Draw->Context, nil: list of string)
{
    sys = load Sys Sys->PATH;

    print("%s\n", tr("qwertyuiop", "QWERTYUIOP", "typewriter"));
    print("%s\n", tr("a-z", "A-Z", "typewriter"));
    print("%s\n", tr("-a-z", "-A-X", "vw-xyz"));
    print("%s\n", tr("a-", "AZ", "plan-9"));
    print("%s\n", tr("a-e", "あ-お", "audio"));
}

tr(orig, subst, str: string): string
{
    tab := array[MAXRUNE] of int;
    for(i := 0; i < len tab; i++)
        tab[i] = 0;

    orig = expand(orig);
    subst = expand(subst);
    compile(tab, orig, subst);

    for(i = 0; i < len str; i++)
        if(tab[str[i]] != 0)
            str[i]= tab[str[i]];
    return str;
}

expand(s: string): string
{
    lastc := 0;
    r := "";
    for(i := 0; i < len s; i++){
        if(s[i] == '-' && lastc != 0 && i < len s-1){    # a-z
            for(c := lastc+1; c <= s[i+1]; c++)
                r += sprint("%c", c);
            i++;
        }else
            r += sprint("%c", s[i]);
        lastc = s[i];
    }
    return r;
}

compile(tab: array of int, orig, subst: string)
{
    n := len orig;
    if(n > len subst)
        n = len subst;
    for(i := 0; i < n; i++)
        tab[orig[i]] = subst[i];
}