コード例 #1
0
ファイル: expr.c プロジェクト: doniexun/ucc-c-compiler
static expr *parse_primary(void)
{
	switch(tok_cur){
		case tok_ident: tok_next(); return expr_ident();
		case tok_num:   tok_next(); return expr_num(tok_cur_num);
		case tok_lparen:
		{
			expr *e;
			tok_next();
			e = parse();
			if(tok_cur != tok_rparen)
				CPP_DIE("close paren expected");
			tok_next();
			return e;
		}

		case tok_not:
		case tok_bnot:
		case tok_minus:
		{
			const e_op op = tok_cur;
			tok_next();
			return expr_new_uop(op, parse_primary());
		}

		default:
			break;
	}

	{
		char s[2];
		*s = tok_cur, s[1] = '\0';
		CPP_DIE("expression expected (got %s)", tok_cur == tok_eof ? "eof" : s);
	}
}
コード例 #2
0
ファイル: preproc.c プロジェクト: bobrippling/ucc-c-compiler
void preproc_push(FILE *f, const char *fname, int is_sysh)
{
	if(file_stack_idx >= 0)
		file_stack[file_stack_idx].line_no = current_line; /* save state */


	file_stack_idx++;
	if(file_stack_idx == countof(file_stack))
		CPP_DIE("too many includes");

#ifdef DO_CHDIR
	char *wd;

	curwdfd = open(".", O_RDONLY);
	if(curwdfd == -1)
		ppdie(p, "open(\".\"): %s", strerror(errno));

	/* make sure everything is relative to the file */
	wd = udirname(p->fname);
	if(chdir(wd))
		ppdie(p, "chdir(\"%s\"): %s (for %s)", wd, strerror(errno), p->fname);
	free(wd);
#endif


	/* setup new state */
	set_current_fname(fname);

	file_stack[file_stack_idx].file    = f;
	file_stack[file_stack_idx].fname   = ustrdup(fname);
	file_stack[file_stack_idx].line_no = current_line = 1;
	file_stack[file_stack_idx].is_sysh = is_sysh;

	preproc_emit_line_info_top(LINEINFO_START_OF_FILE);
}
コード例 #3
0
ファイル: preproc.c プロジェクト: bobrippling/ucc-c-compiler
void preprocess(void)
{
	char *line;
	int eof = 0;

	preproc_push(stdin, current_fname, /*sysh:*/0);

	while(!eof && (line = splice_lines(&eof))){
		debug_push_line(line);

		if(option_digraphs)
			line = expand_digraphs(line);

		line = strip_comment(line);
		switch(strip_in_block){
			case NOT_IN_BLOCK:
			case IN_BLOCK_BEGIN:
			case IN_BLOCK_END:
				line = filter_macros(line);
			case IN_BLOCK_FULL: /* no thanks */
				break;
		}

		debug_pop_line();

		if(line){
			if(!no_output)
				puts(line);
			free(line);
		}
	}

	switch(strip_in_block){
		case NOT_IN_BLOCK:
		case IN_BLOCK_END:
			break;
		case IN_BLOCK_BEGIN:
		case IN_BLOCK_FULL:
			CPP_DIE("no terminating block comment");
	}

	parse_end_validate();
}
コード例 #4
0
ファイル: expr.c プロジェクト: doniexun/ucc-c-compiler
static expr *parse_rhs(expr *lhs, int priority)
{
	for(;;){
    int this_pri, next_pri;
		e_op op;
		expr *rhs;

		op = tok_cur;
		if(!is_op(op))
			return lhs; /* eof, rparen and colon covered here */

		this_pri = PRECEDENCE(op);
    if(this_pri > priority)
      return lhs;

		/* eat the op */
		tok_next();

		/* special case for ternary */
		if(op == tok_question){
			expr *if_t = parse();

			if(tok_cur != tok_colon)
				CPP_DIE("colon expected for ternary-? operator");
			tok_next();

			rhs = parse();

			lhs = expr_new_top(lhs, if_t, rhs);
		}else{
			rhs = parse_primary();

			/* now on the next op, or eof (in which case, precedence returns -1 */
			next_pri = PRECEDENCE(tok_cur);
			if(next_pri < this_pri) {
				/* next is tighter, give it our rhs as its lhs */
				rhs = parse_rhs(rhs, next_pri);
			}

			lhs = expr_op(op, lhs, rhs);
		}
  }
}
コード例 #5
0
ファイル: expr.c プロジェクト: doniexun/ucc-c-compiler
expr *expr_parse(char *str)
{
	expr *e;

	expr_init();

	debug_push_line(str);

	tok_begin(str);
	tok_next();

	e = parse();

	if(tok_cur != tok_eof)
		CPP_DIE("'%s' at end of expression", tok_last());

	debug_pop_line();

	return e;
}
コード例 #6
0
ファイル: expr.c プロジェクト: doniexun/ucc-c-compiler
/* eval */
expr_n expr_eval(expr *e_, int *had_ident)
{
	const expr ke = *e_;
	free(e_);

	switch(ke.type){
		case E_IDENT:
			*had_ident = 1;
			return 0; /* identifiers are zero */
		case E_NUM:
			return ke.bits.num;
		case E_UOP:
		{
			expr_n n = expr_eval(ke.bits.uop.e, had_ident);
			switch(ke.bits.op.op){
#define UNARY(ch, o) case ch: return o n
				UNARY('-', -);
				UNARY('!', !);
				UNARY('~', ~);
				default:
				break;
			}
			ICE("bad op");
		}
		case E_OP:
		{
			expr_n nums[2];

			nums[0] = expr_eval(ke.bits.op.lhs, had_ident);
			nums[1] = expr_eval(ke.bits.op.rhs, had_ident);

			switch(ke.bits.op.op){
				case '*':
				case '/':
					if(nums[1] == 0)
						CPP_DIE("%s by zero",
								ke.bits.op.op == '/' ? "division" : "modulo");
				default:
					break;
			}

			switch(ke.bits.op.op){
#define OP(ty, op) case tok_ ## ty: return nums[0] op nums[1]
				OP(divide, /);
				OP(modulus, %);
				OP(multiply, *);
				OP(plus, +);
				OP(minus, -);
				OP(xor, ^);
				OP(or, |);
				OP(and, &);
				OP(orsc, ||);
				OP(andsc, &&);
				OP(shiftl, <<);
				OP(shiftr, >>);
				OP(eq, ==);
				OP(ne, !=);
				OP(le, <=);
				OP(lt, <);
				OP(ge, >=);
				OP(gt, >);
#undef OP

				default:
					break;
			}
			ICE("bad op");
		}
		case E_TOP:
		{
			expr_n a, b, c;
			/* must evaluate all - free the expressions */
			a = expr_eval(ke.bits.top.e, had_ident);
			b = expr_eval(ke.bits.top.if_true, had_ident);
			c = expr_eval(ke.bits.top.if_false, had_ident);
			return a ? b : c;
		}
	}

	ICE("bad expr type");
}