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