File interp.c of Package interp
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define scan(x) while(isspace(**cp)) (*cp)++
int ass_exp(char**);
int cmp_exp(char**);
int alpha[32];
int *lvalue(char **cp)
{
if(isalpha(**cp)){
return alpha + (*(*cp)++ & 0x1f); // A..Z
}else if(**cp=='@'){
(*cp)++;
return (int*)cmp_exp(cp);
}else return 0;
}
int factor(char **cp)
{
int lop,*adr;
if(isdigit((**cp))) return strtol(*cp,cp,0);
adr = lvalue(cp);
if(adr) {
if(**cp !='[') return *adr;
(*cp)++;
adr += cmp_exp(cp);
if(*(*cp)++ == ']') return *adr;
}
scan(cp);
switch(*(*cp)++){
case '!': return !factor(cp);
case '~': return ~factor(cp);
case '-': return -factor(cp);
case '(':
lop = ass_exp(cp);
scan(cp);
if(*(*cp)++==')')
return lop;
}
printf("Error at factor %s ?\n",*cp);
return 0;
}
int mul_exp(char **cp)
{
int lop;
lop = factor(cp);
for(;;){
scan(cp);
switch(*(*cp)++){
case '*':lop*=factor(cp);continue;
case '%':lop%=factor(cp);continue;
case '/':lop/=factor(cp);continue;
case '&':lop&=factor(cp);continue;
case '^':lop^=factor(cp);continue;
case '<':
if(**cp != '<') break;
(*cp)++;
lop <<= factor(cp);continue;
break;
case '>':
if(**cp != '>') break;
(*cp)++;
lop >>= factor(cp);continue;
break;
}
(*cp)--;
break;
}
return lop;
}
int add_exp(char **cp)
{
int lop;
lop = mul_exp(cp);
for(;;){
scan(cp);
switch(*(*cp)++){
case '+':lop+=mul_exp(cp);continue;
case '-':lop-=mul_exp(cp);continue;
case '|':lop|=mul_exp(cp);continue;
}
(*cp)--;
break;
}
return lop;
}
int cmp_exp(char **cp)
{
int lop;
lop = add_exp(cp);
for(;;){
scan(cp);
switch(*(*cp)++){
case '<':
if(**cp != '=') {lop = lop < add_exp(cp);continue;}
(*cp)++;
lop = lop <= add_exp(cp);
continue;
case '>':
if(*(*cp) != '=') {lop = lop < add_exp(cp);continue;}
(*cp)++;
lop = lop >= add_exp(cp);
continue;
case '!':
if(**cp != '=') break;
(*cp)++;
lop = lop != add_exp(cp);
continue;
case '=':
if(**cp != '=') break;
(*cp)++;
lop = lop == add_exp(cp);
continue;
}
(*cp)--;
break;
}
return lop;
}
int ass_exp(char **cp)
{
int lop;
int *lv;
lv = lvalue(cp);
if(!lv) return cmp_exp(cp);
if(**cp=='='){
(*cp)++;
lop = *lv = cmp_exp(cp);
}else{
(*cp)--;
lop = cmp_exp(cp);
}
return lop;
}
int expr(char *cp)
{
int lop;
for(;;){
lop = ass_exp(&cp);
if(*cp =='?') {
cp++;
if(lop) return ass_exp(&cp);
else {
cp = strchr(cp,':');
if(cp){
cp++;
return ass_exp(&cp);
}
}
}
if(*cp !=',') break;
cp++;
}
// printf("-->%u '%s'\n",lop,cp);
return lop;
}
void test(char *t,int r)
{
int v;
v = expr(t);
printf(v==r?"ok %s=%d\n":"FAIL %s#%d =%d\n",t,v,r);
}
int main (int argc, const char * argv[]) {
// insert code here...
int i;
printf("Hello, World! %p\n",alpha);
test("1+2*3",7);
test("7+-2*3",1);
test("1<<6",64);
test("1==1",1);
test("(4-3)*(4+3)",7);
test("1024>>5",32);
test("7>=7",1);
test("a=12,b=13,c=19",19);
test("b*b-a*a",25);
test("@0x3060",25);
test("a[1]",13);
test("a[2]",19);
test("1?2:3",2);
test("0?2:3",3);
for(i=0;i<32;i++){
printf("%c=%-5d ",i+'@',alpha[i]);
if(i%8==7) printf("\n");
}
return 0;
}