OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [Tools/] [as09/] [eval.c] - Blame information for rev 142

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 83 davidgb
/*
2
 *      eval --- evaluate expression
3
 *
4
 *      an expression is constructed like this:
5
 *
6
 *      expr ::=  expr + term |
7
 *                expr - term ;
8
 *                expr * term ;
9
 *                expr / term ;
10
 *                expr | term ;
11
 *                expr & term ;
12
 *                expr % term ;
13
 *                expr ^ term ;
14
 *
15
 *      term ::=  symbol |
16
 *                * |
17
 *                constant ;
18
 *
19
 *      symbol ::=  string of alphanumerics with non-initial digit
20
 *
21
 *      constant ::= hex constant |
22
 *                   binary constant |
23
 *                   octal constant |
24
 *                   decimal constant |
25
 *                   ascii constant;
26
 *
27
 *      hex constant ::= '$' {hex digits};
28
 *
29
 *      octal constant ::= '@' {octal digits};
30
 *
31
 *      binary constant ::= '%' { 1 | 0 };
32
 *
33
 *      decimal constant ::= {decimal digits};
34
 *
35
 *      ascii constant ::= ''' any printing char;
36
 *
37
 */
38
eval()
39
{
40
        int     left,right;     /* left and right terms for expression */
41
        char    o;              /* operator character */
42
 
43
#ifdef DEBUG
44
        printf("Evaluating %s\n",Optr);
45
#endif
46
        Force_byte = NO;
47
        Force_word = NO;
48
        if(*Optr=='<'){
49
                Force_byte++;
50
                Optr++;
51
                }
52
        else if(*Optr=='>'){
53
                Force_word++;
54
                Optr++;
55
                }
56
        left = get_term();         /* pickup first part of expression */
57
 
58
        while( is_op(*Optr)){
59
                o = *Optr++; /* pickup connector and skip */
60
                right = get_term();     /* pickup current rightmost side */
61
                switch(o){
62
                        case '+': left += right; break;
63
                        case '-': left -= right; break;
64
                        case '*': left *= right; break;
65
                        case '/': left /= right; break;
66
                        case '|': left |= right; break;
67
                        case '&': left &= right; break;
68
                        case '%': left %= right; break;
69
                        case '^': left = left^right; break;
70
                        }
71
                }
72
 
73
        Result= left;
74
#ifdef DEBUG
75
        printf("Result=%x\n",Result);
76
        printf("Force_byte=%d  Force_word=%d\n",Force_byte,Force_word);
77
#endif
78
        return(YES);
79
}
80
 
81
/*
82
 *      is_op --- is character an expression operator?
83
 */
84
is_op(c)
85
char c;
86
{
87
        if( any(c,"+-*/&%|^"))
88
                return(YES);
89
        return(NO);
90
}
91
 
92
 
93
/*
94
 *      get_term --- evaluate a single item in an expression
95
 */
96
get_term()
97
{
98
        char    hold[MAXBUF];
99
        char    *tmp;
100
        int     val = 0;        /* local value being built */
101
        int     minus;          /* unary minus flag */
102
        struct nlist *pointer;
103
        struct link *pnt,*bpnt;
104
 
105
        if( *Optr == '-' ){
106
                Optr++;
107
                minus =YES;
108
                }
109
        else
110
                minus = NO;
111
 
112
        while( *Optr == '#' ) Optr++;
113
 
114
        /* look at rest of expression */
115
 
116
        if(*Optr=='%'){ /* binary constant */
117
                Optr++;
118
                while( any(*Optr,"01"))
119
                        val = (val * 2) + ( (*Optr++)-'0');
120
                }
121
        else if(*Optr=='@'){ /* octal constant */
122
                Optr++;
123
                while( any(*Optr,"01234567"))
124
                        val = (val * 8) + ((*Optr++)-'0');
125
                }
126
        else if(*Optr=='$'){ /* hex constant */
127
                Optr++;
128
                while( any(*Optr,"0123456789abcdefABCDEF"))
129
                        if( *Optr > '9' )
130
                                val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
131
                        else
132
                                val = (val * 16) + ((*Optr++)-'0');
133
                }
134
        else if( any(*Optr,"0123456789")){ /* decimal constant */
135
                while(*Optr >= '0' && *Optr <= '9')
136
                        val = (val * 10) + ( (*Optr++)-'0');
137
                }
138
        else if(*Optr=='*'){    /* current location counter */
139
                Optr++;
140
                val = Old_pc;
141
                }
142
        else if(*Optr=='\''){   /* character literal */
143
                Optr++;
144
                if(*Optr == EOS)
145
                        val = 0;
146
                else
147
                        val = *Optr++;
148
                }
149
        else if( alpha(*Optr) ){ /* a symbol */
150
                tmp = hold;     /* collect symbol name */
151
                while(alphan(*Optr))
152
                        *tmp++ = *Optr++;
153
                *tmp = EOS;
154
                pointer = lookup(hold);
155
                  if (pointer != NULL)
156
                   {
157
                   if (Pass == 2)
158
                    {
159
                       pnt = pointer->L_list;
160
                        bpnt = NULL;
161
                        while (pnt != NULL)
162
                         {
163
                           bpnt = pnt;
164
                           pnt = pnt->next;
165
                         }
166
                        pnt = (struct link *) alloc(sizeof(struct link));
167
                      if (bpnt == NULL)
168
                       pointer->L_list = pnt;
169
                      else bpnt->next = pnt;
170
                     pnt->L_num = Line_num;
171
                    pnt->next = NULL;
172
                    }
173
                       val = Last_sym;
174
                   }
175
                else{
176
                        if(Pass==1){    /* forward ref here */
177
                                fwdmark();
178
                                if( !Force_byte )
179
                                        Force_word++;
180
                                val = 0;
181
                                }
182
                        else    /* added ver TER_2.0  2 Jul 89 */
183 142 davidgb
                                printf("Symbol '%s' undefined Pass 2",hold);
184 83 davidgb
                        }
185
                if(Pass==2 && Line_num==F_ref && Cfn==Ffn){
186
                        if( !Force_byte  )
187
                                Force_word++;
188
                        fwdnext();
189
                        }
190
                }
191
        else
192
                /* none of the above */
193
                val = 0;
194
 
195
        if(minus)
196
                return(-val);
197
        else
198
                return(val);
199
}

powered by: WebSVN 2.1.0

© copyright 1999-2022 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.