1*37da2899SCharles.Forsyth# 2*37da2899SCharles.Forsyth# Expression evaluation. 3*37da2899SCharles.Forsyth# 4*37da2899SCharles.Forsyth 5*37da2899SCharles.Forsyth# 6*37da2899SCharles.Forsyth# Filename pattern matching. 7*37da2899SCharles.Forsyth# 8*37da2899SCharles.Forsythglob(e: ref Env, s: string): (string, list of string) 9*37da2899SCharles.Forsyth{ 10*37da2899SCharles.Forsyth if (filepat == nil) { 11*37da2899SCharles.Forsyth filepat = load Filepat Filepat->PATH; 12*37da2899SCharles.Forsyth if (filepat == nil) 13*37da2899SCharles.Forsyth e.couldnot("load", Filepat->PATH); 14*37da2899SCharles.Forsyth } 15*37da2899SCharles.Forsyth l := filepat->expand(s); 16*37da2899SCharles.Forsyth if (l != nil) 17*37da2899SCharles.Forsyth return (nil, l); 18*37da2899SCharles.Forsyth return (s, nil); 19*37da2899SCharles.Forsyth} 20*37da2899SCharles.Forsyth 21*37da2899SCharles.Forsyth# 22*37da2899SCharles.Forsyth# RE pattern matching. 23*37da2899SCharles.Forsyth# 24*37da2899SCharles.Forsythmatch(s1, s2: string): int 25*37da2899SCharles.Forsyth{ 26*37da2899SCharles.Forsyth (re, nil) := regex->compile(s2, 0); 27*37da2899SCharles.Forsyth return regex->execute(re, s1) != nil; 28*37da2899SCharles.Forsyth} 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth# 31*37da2899SCharles.Forsyth# RE match of two lists. Two non-singleton lists never match. 32*37da2899SCharles.Forsyth# 33*37da2899SCharles.Forsythmatch2(e: ref Env, s1: string, l1: list of string, s2: string, l2: list of string): int 34*37da2899SCharles.Forsyth{ 35*37da2899SCharles.Forsyth if (regex == nil) { 36*37da2899SCharles.Forsyth regex = load Regex Regex->PATH; 37*37da2899SCharles.Forsyth if (regex == nil) 38*37da2899SCharles.Forsyth e.couldnot("load", Regex->PATH); 39*37da2899SCharles.Forsyth } 40*37da2899SCharles.Forsyth if (s1 != nil) { 41*37da2899SCharles.Forsyth if (s2 != nil) 42*37da2899SCharles.Forsyth return match(s1, s2); 43*37da2899SCharles.Forsyth while (l2 != nil) { 44*37da2899SCharles.Forsyth if (match(s1, hd l2)) 45*37da2899SCharles.Forsyth return 1; 46*37da2899SCharles.Forsyth l2 = tl l2; 47*37da2899SCharles.Forsyth } 48*37da2899SCharles.Forsyth } else if (l1 != nil) { 49*37da2899SCharles.Forsyth if (s2 == nil) 50*37da2899SCharles.Forsyth return 0; 51*37da2899SCharles.Forsyth while (l1 != nil) { 52*37da2899SCharles.Forsyth if (match(hd l1, s2)) 53*37da2899SCharles.Forsyth return 1; 54*37da2899SCharles.Forsyth l1 = tl l1; 55*37da2899SCharles.Forsyth } 56*37da2899SCharles.Forsyth } else if (s2 != nil) 57*37da2899SCharles.Forsyth return match(nil, s2); 58*37da2899SCharles.Forsyth else if (l2 != nil) { 59*37da2899SCharles.Forsyth while (l2 != nil) { 60*37da2899SCharles.Forsyth if (match(nil, hd l2)) 61*37da2899SCharles.Forsyth return 1; 62*37da2899SCharles.Forsyth l2 = tl l2; 63*37da2899SCharles.Forsyth } 64*37da2899SCharles.Forsyth } else 65*37da2899SCharles.Forsyth return 1; 66*37da2899SCharles.Forsyth return 0; 67*37da2899SCharles.Forsyth} 68*37da2899SCharles.Forsyth 69*37da2899SCharles.Forsyth# 70*37da2899SCharles.Forsyth# Test list equality. Same length and identical members. 71*37da2899SCharles.Forsyth# 72*37da2899SCharles.Forsytheqlist(l1, l2: list of string): int 73*37da2899SCharles.Forsyth{ 74*37da2899SCharles.Forsyth while (l1 != nil && l2 != nil) { 75*37da2899SCharles.Forsyth if (hd l1 != hd l2) 76*37da2899SCharles.Forsyth return 0; 77*37da2899SCharles.Forsyth l1 = tl l1; 78*37da2899SCharles.Forsyth l2 = tl l2; 79*37da2899SCharles.Forsyth } 80*37da2899SCharles.Forsyth return l1 == nil && l2 == nil; 81*37da2899SCharles.Forsyth} 82*37da2899SCharles.Forsyth 83*37da2899SCharles.Forsyth# 84*37da2899SCharles.Forsyth# Equality operator. 85*37da2899SCharles.Forsyth# 86*37da2899SCharles.ForsythCmd.evaleq(c: self ref Cmd, e: ref Env): int 87*37da2899SCharles.Forsyth{ 88*37da2899SCharles.Forsyth (s1, l1, nil) := c.left.eeval2(e); 89*37da2899SCharles.Forsyth (s2, l2, nil) := c.right.eeval2(e); 90*37da2899SCharles.Forsyth if (s1 != nil) 91*37da2899SCharles.Forsyth return s1 == s2; 92*37da2899SCharles.Forsyth if (l1 != nil) 93*37da2899SCharles.Forsyth return eqlist(l1, l2); 94*37da2899SCharles.Forsyth return s2 == nil && l2 == nil; 95*37da2899SCharles.Forsyth} 96*37da2899SCharles.Forsyth 97*37da2899SCharles.Forsyth# 98*37da2899SCharles.Forsyth# Match operator. 99*37da2899SCharles.Forsyth# 100*37da2899SCharles.ForsythCmd.evalmatch(c: self ref Cmd, e: ref Env): int 101*37da2899SCharles.Forsyth{ 102*37da2899SCharles.Forsyth (s1, l1, nil) := c.left.eeval2(e); 103*37da2899SCharles.Forsyth (s2, l2, nil) := c.right.eeval2(e); 104*37da2899SCharles.Forsyth return match2(e, s1, l1, s2, l2); 105*37da2899SCharles.Forsyth} 106*37da2899SCharles.Forsyth 107*37da2899SCharles.Forsyth# 108*37da2899SCharles.Forsyth# Catenation operator. 109*37da2899SCharles.Forsyth# 110*37da2899SCharles.ForsythItem.caret(i: self ref Item, e: ref Env): (string, list of string, int) 111*37da2899SCharles.Forsyth{ 112*37da2899SCharles.Forsyth (s1, l1, x1) := i.left.ieval2(e); 113*37da2899SCharles.Forsyth (s2, l2, x2) := i.right.ieval2(e); 114*37da2899SCharles.Forsyth return caret(s1, l1, x1, s2, l2, x2); 115*37da2899SCharles.Forsyth} 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth# 118*37da2899SCharles.Forsyth# Caret of lists. A singleton distributes. Otherwise pairwise, padded with nils. 119*37da2899SCharles.Forsyth# 120*37da2899SCharles.Forsythcaret(s1: string, l1: list of string, x1: int, s2: string, l2: list of string, x2: int): (string, list of string, int) 121*37da2899SCharles.Forsyth{ 122*37da2899SCharles.Forsyth l: list of string; 123*37da2899SCharles.Forsyth if (s1 != nil) { 124*37da2899SCharles.Forsyth if (s2 != nil) 125*37da2899SCharles.Forsyth return (s1 + s2, nil, x1 | x2); 126*37da2899SCharles.Forsyth if (l2 == nil) 127*37da2899SCharles.Forsyth return (s1, nil, x1); 128*37da2899SCharles.Forsyth while (l2 != nil) { 129*37da2899SCharles.Forsyth l = (s1 + hd l2) :: l; 130*37da2899SCharles.Forsyth l2 = tl l2; 131*37da2899SCharles.Forsyth } 132*37da2899SCharles.Forsyth } else if (s2 != nil) { 133*37da2899SCharles.Forsyth if (l1 == nil) 134*37da2899SCharles.Forsyth return (s2, nil, x2); 135*37da2899SCharles.Forsyth while (l1 != nil) { 136*37da2899SCharles.Forsyth l = (hd l1 + s2) :: l; 137*37da2899SCharles.Forsyth l1 = tl l1; 138*37da2899SCharles.Forsyth } 139*37da2899SCharles.Forsyth } else if (l1 != nil) { 140*37da2899SCharles.Forsyth if (l2 == nil) 141*37da2899SCharles.Forsyth return (nil, l1, 0); 142*37da2899SCharles.Forsyth while (l1 != nil || l2 != nil) { 143*37da2899SCharles.Forsyth if (l1 != nil) { 144*37da2899SCharles.Forsyth s1 = hd l1; 145*37da2899SCharles.Forsyth l1 = tl l1; 146*37da2899SCharles.Forsyth } else 147*37da2899SCharles.Forsyth s1 = nil; 148*37da2899SCharles.Forsyth if (l2 != nil) { 149*37da2899SCharles.Forsyth s2 = hd l2; 150*37da2899SCharles.Forsyth l2 = tl l2; 151*37da2899SCharles.Forsyth } else 152*37da2899SCharles.Forsyth s2 = nil; 153*37da2899SCharles.Forsyth l = (s1 + s2) :: l; 154*37da2899SCharles.Forsyth } 155*37da2899SCharles.Forsyth } else if (l2 != nil) 156*37da2899SCharles.Forsyth return (nil, l2, 0); 157*37da2899SCharles.Forsyth return (nil, revstrs(l), 0); 158*37da2899SCharles.Forsyth} 159