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;
}
openSUSE Build Service is sponsored by