xref: /inferno-os/appl/cmd/mash/expr.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
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