summaryrefslogblamecommitdiff
path: root/src/user/app/kbasic/expr.c
blob: 3b8d5586ef707e06256c9403c49dc1a171089b73 (plain) (tree)
























































































































































                                                                                           
#include <stdlib.h>

#include "basic.h"

void level2(int*), level3(int*), level4(int*), level5(int*), level6(int*), primitive(int*);
void unary(char, int*), arith(char, int*, int*);

/* Entry point into parser. */
void get_exp(int *result)
{
	get_token();
	if(!*token) {
		serror(2);
		return;
	}
	level2(result);
	putback(); /* return last token read to input stream */
}

/*  Add or subtract two terms. */
void level2(int *result)
{
	register char  op; 
	int hold; 

	level3(result); 
	while((op = *token) == '+' || op == '-') {
		get_token(); 
		level3(&hold); 
		arith(op, result, &hold);
	}
}

/* Multiply or divide two factors. */
void level3(int *result)
{
	register char  op; 
	int hold;

	level4(result); 
	while((op = *token) == '*' || op == '/' || op == '%') {
		get_token(); 
		level4(&hold); 
		arith(op, result, &hold); 
	}
}

/* Process integer exponent. */
void level4(int *result)
{
	int hold; 

	level5(result); 
	if(*token== '^') {
		get_token(); 
		level4(&hold); 
		arith('^', result, &hold); 
	}
}

/* Is a unary + or -. */
void level5(int *result)
{
	register char  op; 

	op = 0; 
	if((token_type==DELIMITER) && (*token=='+' || *token=='-')) {
		op = *token; 
		get_token(); 
	}
	level6(result); 
	if(op)
		unary(op, result); 
}

/* Process parenthesized expression. */
void level6(int *result)
{
	if((*token == '(') && (token_type == DELIMITER)) {
		get_token(); 
		level2(result); 
		if(*token != ')')
			serror(1);
		get_token(); 
	}
	else
		primitive(result);
}

/* Find value of number or variable. */
void primitive(int *result)
{

	switch(token_type) {
		case VARIABLE:
			*result = *find_var(token);
			get_token(); 
			return; 
		case NUMBER:
			*result = atoi(token);
			get_token();
			return;
		case COMMAND:
			switch(tok) {
				case RND:
					*result = rand();
					get_token();
					return;
			}
		default:
			serror(0);
	}
}

/* Perform the specified arithmetic. */
void arith(char o, int *r, int *h)
{
	register int t, ex;

	switch(o) {
		case '-':
			*r = *r-*h; 
			break; 
		case '+':
			*r = *r+*h; 
			break; 
		case '*':  
			*r = *r * *h; 
			break; 
		case '/':
			*r = (*r)/(*h);
			break; 
		case '%':
			t = (*r)/(*h); 
			*r = *r-(t*(*h)); 
			break; 
		case '^':
			ex = *r; 
			if(*h==0) {
				*r = 1; 
				break; 
			}
			for(t=*h-1; t>0; --t) *r = (*r) * ex;
			break;       
	}
}

/* Reverse the sign. */
void unary(char o, int *r)
{
	if(o=='-') *r = -(*r);
}