Example #1
0
/* add_expr
 * : mul_expr
 * | add_expr ADD mul_expr 
 * | add_expr SUB mul_expr 
 */
static void add_expr(ApexParser *parser) {
    mul_expr(parser);
    for (;;) {
        ApexAstNode *left, *right;
        ApexAstOpr opr;

        if (accept(parser, '+')) {
            opr =  '+';
        } else if (accept(parser, '-')) {
            opr = '-';
        } else {
            break;
        }
        left = apex_ast_pop(parser->ast);
        mul_expr(parser);
        right = apex_ast_pop(parser->ast);
        apex_ast_opr2(parser->ast, opr, left, right);
    }
}
Example #2
0
File: syntax.c Project: loiso/scalc
static void
add_expr(void)
{	
	switch(token.type) {
	case TOKEN_INTEGER:
	case TOKEN_LPARENTH:
		mul_expr();
		if (err == SYN_ERR) {
			goto out;
		}
		rest_add_expr();
		goto out;		
	default:
		err = SYN_ERR;
		goto out;
	}
out:
	return ;
}
Example #3
0
File: syntax.c Project: loiso/scalc
static void
rest_add_expr(void)
{
	number op1, op2;
	unsigned int tmp, rv, i;
		
	while (token.type == TOKEN_PLUS || token.type == TOKEN_MINUS) {
		tmp = token.type;
		
		get_next_token();
		mul_expr();
		if (err == SYN_ERR) {
			goto out;
		}
		
		rv = pop_item(&sp, &op2);
		if (rv != OK) {
			err = MEM_ERR;
			goto out;
		}
		
		rv = pop_item(&sp, &op1);
		if (rv != OK) {
			err = MEM_ERR;
			goto out;
		}
		
		if (op1.frac == op2.frac)
			goto main_part;
			
		if (op1.frac > op2.frac) {
			for (i = 0; i < (op1.frac - op2.frac); i++)
				rv = mpl_mul_dig(&op2.value, &op2.value, 10);
				if (rv != MPL_OK) {
					err = MEM_ERR;
					goto out;
				}
			op2.frac = op1.frac;
		} else {
			for (i = 0; i < (op2.frac - op1.frac); i++)
				rv = mpl_mul_dig(&op1.value, &op1.value, 10);
				if (rv != MPL_OK) {
					err = MEM_ERR;
					goto out;
				}
			op1.frac = op2.frac;
		}
main_part:
		if (tmp == TOKEN_PLUS) {
			rv = mpl_add(&op1.value, &op1.value, &op2.value);
			if (rv != MPL_OK) {
				err = MEM_ERR;
				goto out;
			}

		} else if (tmp == TOKEN_MINUS) {
			rv = mpl_sub(&op1.value, &op1.value, &op2.value);
			if (rv != MPL_OK) {
				err = MEM_ERR;
				goto out;
			}
		}
		rv = push_item(&sp, &op1);
		if (rv != OK) {
			err = MEM_ERR;
			goto out;
		}
		
		mpl_clear(&op2.value);
	}
	
	if (token.type != TOKEN_EOL && token.type != TOKEN_RPARENTH) {
		err = SYN_ERR;
		goto out;
	}
out:
	return ;
}
Example #4
0
File: expr.c Project: kybp/basic
void eval_expr(expr *in, expr *out, symtab *table)
{
    switch (in->type) {
    case NOTHING: break;
    case INTEGER: case REAL: case STRING:
        out->type = in->type;
        out->val  = in->val;
        return;
    case INT_VAR: {
        int n;
        if (lookup_int(in->val.string, table, &n)) {
            out->type = INTEGER;
            out->val.integer = n;
            return;
        } else {
            fprintf(stderr, "undefined integer variable '%s'\n",
                    in->val.string);
            exit(1);
        }
    } break;
    case REAL_VAR: {
        double d;
        if (lookup_real(in->val.string, table, &d)) {
            out->type = REAL;
            out->val.real = d;
            return;
        } else {
            fprintf(stderr, "undefined real variable '%s'\n",
                    in->val.string);
            exit(1);
        }
    } break;
    case STR_VAR: {
        char *s = (char *)malloc(MAX_LINE);
        if (lookup_str(in->val.string, table, &s)) {
            out->type = STRING;
            out->val.string = s;
            return;
        } else {
            fprintf(stderr, "undefined string variable '%s'\n",
                    in->val.string);
            exit(1);
        }
    } break;
    }

    switch (in->op) {
    case NOTHING:
        fprintf(stderr, "No operation for non-constant expression\n");
        exit(1);
    case ADD:
        add_expr(in, out, table);
        break;
    case SUB:
        sub_expr(in, out, table);
        break;
    case EXPT:
        pow_expr(in, out, table);
        break;
    case MUL:
        mul_expr(in, out, table);
        break;
    case DIV:
        div_expr(in, out, table);
        break;
    case LT:
        eval_expr(in->arg1, out->arg1, table);
        eval_expr(in->arg2, out->arg2, table);
        out->type = INTEGER;
        out->val.integer = compare(out->arg1, out->arg2, LT);
        break;
    case LE:
        eval_expr(in->arg1, out->arg1, table);
        eval_expr(in->arg2, out->arg2, table);
        out->type = INTEGER;
        out->val.integer = compare(out->arg1, out->arg2, LE);
        break;
    case EQ:
        eval_expr(in->arg1, out->arg1, table);
        eval_expr(in->arg2, out->arg2, table);
        out->type = INTEGER;
        out->val.integer = compare(out->arg1, out->arg2, EQ);
        break;
    case GE:
        eval_expr(in->arg1, out->arg1, table);
        eval_expr(in->arg2, out->arg2, table);
        out->type = INTEGER;
        out->val.integer = compare(out->arg1, out->arg2, GE);
        break;
    case GT:
        eval_expr(in->arg1, out->arg1, table);
        eval_expr(in->arg2, out->arg2, table);
        out->type = INTEGER;
        out->val.integer = compare(out->arg1, out->arg2, GT);
        break;
    case NE:
        eval_expr(in->arg1, out->arg1, table);
        eval_expr(in->arg2, out->arg2, table);
        out->type = INTEGER;
        out->val.integer = compare(out->arg1, out->arg2, NE);
        break;

    /* Numerical functions */
    case RAND: {
        expr arg;
        eval_expr(in->arg1, &arg, table);
        out->type = INTEGER;
        out->val.integer = rand() % arg.val.integer;
    } break;
    case SQRT: {
        expr arg;
        eval_expr(in->arg1, &arg, table);
        out->type = REAL;
        out->val.real = sqrt(arg.type == REAL ? arg.val.real :
                             (double)arg.val.integer);
    } break;

    /* Casting */
    case CEIL: {
        expr arg;
        eval_expr(in->arg1, &arg, table);
        out->type = INTEGER;
        out->val.integer = (int)ceil(arg.val.real);
    } break;
    case FLOOR: {
        expr arg;
        eval_expr(in->arg1, &arg, table);
        out->type = INTEGER;
        out->val.integer = (int)floor(arg.val.real);
    } break;
    case REAL_CAST: {
        expr arg;
        eval_expr(in->arg1, &arg, table);
        out->type = REAL;
        out->val.real = (double)arg.val.integer;
    } break;
    case ROUND: {
        expr arg;
        eval_expr(in->arg1, &arg, table);
        out->type = INTEGER;
        out->val.integer = (int)round(arg.val.real);
    } break;
    default:
        fprintf(stderr, "unrecognised operation\n");
        exit(1);
    }
}