Commit | Line | Data |
---|---|---|
dc2a07ab | 1 | #ifndef lint |
7edc52ec | 2 | static char sccsid[] = "@(#)parser5.c 3.6 %G%"; |
dc2a07ab EW |
3 | #endif |
4 | ||
5 | #include "parser.h" | |
0173496c | 6 | #include "var.h" |
dc2a07ab EW |
7 | |
8 | /* | |
9 | * unary $ + - ! ~ | |
10 | */ | |
11 | p_expr11(v, flag) | |
12 | register struct value *v; | |
13 | char flag; | |
14 | { | |
15 | int op; | |
16 | char *opname; | |
17 | ||
18 | switch (token) { | |
19 | case T_DOLLAR: | |
20 | opname = "$"; | |
21 | break; | |
22 | case T_PLUS: | |
23 | opname = "unary +"; | |
24 | break; | |
25 | case T_MINUS: | |
26 | opname = "unary -"; | |
27 | break; | |
28 | case T_NOT: | |
29 | opname = "!"; | |
30 | break; | |
31 | case T_COMP: | |
32 | opname = "~"; | |
33 | break; | |
34 | default: | |
35 | return p_expr12(v, flag); | |
36 | } | |
37 | op = token; | |
38 | (void) s_gettok(); | |
39 | if (p_expr11(v, flag) < 0) | |
40 | return -1; | |
41 | switch (v->v_type) { | |
42 | case V_NUM: | |
dc2a07ab EW |
43 | break; |
44 | case V_STR: | |
45 | switch (op) { | |
46 | case T_MINUS: | |
47 | case T_NOT: | |
48 | case T_COMP: | |
49 | p_error("Numeric value required for %s.", opname); | |
50 | str_free(v->v_str); | |
51 | v->v_type = V_ERR; | |
52 | return 0; | |
53 | } | |
54 | break; | |
55 | case V_ERR: | |
56 | return 0; | |
57 | } | |
58 | switch (op) { | |
59 | case T_DOLLAR: { | |
60 | struct var *r; | |
bb4a0c0b EW |
61 | if (v->v_type == V_NUM) { |
62 | v->v_num--; | |
c352fd33 | 63 | if (cx.x_type != X_BUF || cx.x_arg == 0 || |
bb4a0c0b EW |
64 | v->v_num < 0 || v->v_num >= cx.x_narg) { |
65 | p_error("%d: No such argument.", v->v_num); | |
66 | v->v_type = V_ERR; | |
67 | return 0; | |
68 | } | |
69 | if (flag) | |
70 | *v = cx.x_arg[v->v_num]; | |
71 | } else { | |
72 | if ((r = var_lookup(v->v_str)) == 0) { | |
73 | p_error("%s: Undefined variable.", v->v_str); | |
74 | str_free(v->v_str); | |
75 | v->v_type = V_ERR; | |
76 | return 0; | |
77 | } | |
dc2a07ab | 78 | str_free(v->v_str); |
bb4a0c0b EW |
79 | if (flag) |
80 | *v = r->r_val; | |
dc2a07ab | 81 | } |
bb4a0c0b EW |
82 | if (v->v_type == V_STR |
83 | && (v->v_str = str_cpy(v->v_str)) == 0) { | |
84 | p_memerror(); | |
85 | return -1; | |
dc2a07ab EW |
86 | } |
87 | break; | |
88 | } | |
89 | case T_MINUS: | |
90 | v->v_num = - v->v_num; | |
91 | break; | |
92 | case T_NOT: | |
93 | v->v_num = ! v->v_num; | |
94 | break; | |
95 | case T_COMP: | |
96 | v->v_num = ~ v->v_num; | |
97 | break; | |
98 | } | |
99 | return 0; | |
100 | } | |
101 | ||
102 | /* | |
103 | * string, number, ( expr ) | |
104 | * Plus function calls. | |
105 | * Also we map % into string. | |
106 | * | |
107 | * Always return v_type == V_ERR when flag == 0. | |
108 | */ | |
109 | p_expr12(v, flag) | |
110 | register struct value *v; | |
111 | char flag; | |
112 | { | |
113 | v->v_type = V_ERR; | |
dc2a07ab EW |
114 | switch (token) { |
115 | case T_MOD: | |
dc2a07ab EW |
116 | if (flag) { |
117 | v->v_type = V_STR; | |
118 | v->v_str = str_cpy("%"); | |
119 | } | |
120 | (void) s_gettok(); | |
121 | break; | |
122 | case T_NUM: | |
dc2a07ab EW |
123 | if (flag) { |
124 | v->v_type = V_NUM; | |
125 | v->v_num = token_num; | |
126 | } | |
127 | (void) s_gettok(); | |
128 | break; | |
129 | case T_STR: | |
dc2a07ab EW |
130 | if (flag) { |
131 | v->v_type = V_STR; | |
132 | v->v_str = token_str; | |
133 | } else | |
134 | str_free(token_str); | |
135 | (void) s_gettok(); | |
136 | break; | |
137 | case T_LP: | |
138 | (void) s_gettok(); | |
139 | if (p_expr(v, flag) < 0) { | |
140 | p_synerror(); | |
141 | return -1; | |
142 | } | |
143 | if (token != T_RP) { | |
144 | p_synerror(); | |
145 | val_free(*v); | |
146 | return -1; | |
147 | } | |
148 | (void) s_gettok(); | |
149 | break; | |
150 | default: | |
dc2a07ab EW |
151 | return -1; |
152 | } | |
153 | while (token == T_LP) { | |
154 | char *cmd; | |
155 | ||
156 | (void) s_gettok(); | |
bb4a0c0b EW |
157 | if (p_convstr(v) < 0) |
158 | return -1; | |
159 | cmd = v->v_type == V_STR ? v->v_str : 0; | |
dc2a07ab | 160 | if (p_function(cmd, v, flag) < 0) { |
f8e2d916 EW |
161 | if (cmd) |
162 | str_free(cmd); | |
dc2a07ab EW |
163 | return -1; |
164 | } | |
f8e2d916 EW |
165 | if (cmd) |
166 | str_free(cmd); | |
dc2a07ab EW |
167 | if (token != T_RP) { |
168 | p_synerror(); | |
169 | val_free(*v); | |
170 | return -1; | |
171 | } | |
172 | (void) s_gettok(); | |
173 | } | |
174 | return 0; | |
175 | } |