Formatting: kill off "stealth whitespace"
[platform/upstream/nasm.git] / exprlib.c
1 /*
2  * exprlib.c
3  *
4  * Library routines to manipulate expression data types.
5  */
6
7 #include "nasm.h"
8
9 /*
10  * Return true if the argument is a simple scalar. (Or a far-
11  * absolute, which counts.)
12  */
13 int is_simple(expr * vect)
14 {
15     while (vect->type && !vect->value)
16         vect++;
17     if (!vect->type)
18         return 1;
19     if (vect->type != EXPR_SIMPLE)
20         return 0;
21     do {
22         vect++;
23     } while (vect->type && !vect->value);
24     if (vect->type && vect->type < EXPR_SEGBASE + SEG_ABS)
25         return 0;
26     return 1;
27 }
28
29 /*
30  * Return true if the argument is a simple scalar, _NOT_ a far-
31  * absolute.
32  */
33 int is_really_simple(expr * vect)
34 {
35     while (vect->type && !vect->value)
36         vect++;
37     if (!vect->type)
38         return 1;
39     if (vect->type != EXPR_SIMPLE)
40         return 0;
41     do {
42         vect++;
43     } while (vect->type && !vect->value);
44     if (vect->type)
45         return 0;
46     return 1;
47 }
48
49 /*
50  * Return true if the argument is relocatable (i.e. a simple
51  * scalar, plus at most one segment-base, plus possibly a WRT).
52  */
53 int is_reloc(expr * vect)
54 {
55     while (vect->type && !vect->value)  /* skip initial value-0 terms */
56         vect++;
57     if (!vect->type)            /* trivially return true if nothing */
58         return 1;               /* is present apart from value-0s */
59     if (vect->type < EXPR_SIMPLE)       /* false if a register is present */
60         return 0;
61     if (vect->type == EXPR_SIMPLE) {    /* skip over a pure number term... */
62         do {
63             vect++;
64         } while (vect->type && !vect->value);
65         if (!vect->type)        /* ...returning true if that's all */
66             return 1;
67     }
68     if (vect->type == EXPR_WRT) {       /* skip over a WRT term... */
69         do {
70             vect++;
71         } while (vect->type && !vect->value);
72         if (!vect->type)        /* ...returning true if that's all */
73             return 1;
74     }
75     if (vect->value != 0 && vect->value != 1)
76         return 0;               /* segment base multiplier non-unity */
77     do {                        /* skip over _one_ seg-base term... */
78         vect++;
79     } while (vect->type && !vect->value);
80     if (!vect->type)            /* ...returning true if that's all */
81         return 1;
82     return 0;                   /* And return false if there's more */
83 }
84
85 /*
86  * Return true if the argument contains an `unknown' part.
87  */
88 int is_unknown(expr * vect)
89 {
90     while (vect->type && vect->type < EXPR_UNKNOWN)
91         vect++;
92     return (vect->type == EXPR_UNKNOWN);
93 }
94
95 /*
96  * Return true if the argument contains nothing but an `unknown'
97  * part.
98  */
99 int is_just_unknown(expr * vect)
100 {
101     while (vect->type && !vect->value)
102         vect++;
103     return (vect->type == EXPR_UNKNOWN);
104 }
105
106 /*
107  * Return the scalar part of a relocatable vector. (Including
108  * simple scalar vectors - those qualify as relocatable.)
109  */
110 int64_t reloc_value(expr * vect)
111 {
112     while (vect->type && !vect->value)
113         vect++;
114     if (!vect->type)
115         return 0;
116     if (vect->type == EXPR_SIMPLE)
117         return vect->value;
118     else
119         return 0;
120 }
121
122 /*
123  * Return the segment number of a relocatable vector, or NO_SEG for
124  * simple scalars.
125  */
126 int32_t reloc_seg(expr * vect)
127 {
128     while (vect->type && (vect->type == EXPR_WRT || !vect->value))
129         vect++;
130     if (vect->type == EXPR_SIMPLE) {
131         do {
132             vect++;
133         } while (vect->type && (vect->type == EXPR_WRT || !vect->value));
134     }
135     if (!vect->type)
136         return NO_SEG;
137     else
138         return vect->type - EXPR_SEGBASE;
139 }
140
141 /*
142  * Return the WRT segment number of a relocatable vector, or NO_SEG
143  * if no WRT part is present.
144  */
145 int32_t reloc_wrt(expr * vect)
146 {
147     while (vect->type && vect->type < EXPR_WRT)
148         vect++;
149     if (vect->type == EXPR_WRT) {
150         return vect->value;
151     } else
152         return NO_SEG;
153 }