コード例 #1
0
ファイル: syntree.c プロジェクト: doniexun/compiler-40
/* 式を表示 */
void pr_expr(FILE * fp, expr_t e)
{
  switch (e->kind) {
  case expr_kind_int_literal:
  case expr_kind_id:
    fprintf(fp, "%s", e->u.s);
    break;
  case expr_kind_paren:
    fprintf(fp, "(");
    pr_expr(fp, e->u.p);
    fprintf(fp, ")");
    break;
  case expr_kind_app:
    if (e->u.a.o == op_kind_fun) {
      fprintf(fp, "%s", e->u.a.f);
      fprintf(fp, "(");
      pr_expr_list_comma(fp, e->u.a.args);
      fprintf(fp, ")");
    } else if (un_op_to_str(e->u.a.o)) {
      fprintf(fp, "%s ", un_op_to_str(e->u.a.o));
      pr_expr(fp, expr_list_get(e->u.a.args, 0));
    } else if (bin_op_to_str(e->u.a.o)) {
      pr_expr(fp, expr_list_get(e->u.a.args, 0));
      fprintf(fp, " %s ", bin_op_to_str(e->u.a.o));
      pr_expr(fp, expr_list_get(e->u.a.args, 1));
    } else {
      assert(0);
    }
    break;
  default:
    assert(0);
  }
}
コード例 #2
0
ファイル: syntree.c プロジェクト: doniexun/compiler-40
/* 文を表示 */
void pr_stmt(FILE * fp, stmt_t s)
{
  switch (s->kind) {
  case stmt_kind_empty:
    fprintf(fp, ";\n");
    break;
  case stmt_kind_continue:
    fprintf(fp, "continue;\n");
    break;
  case stmt_kind_break:
    fprintf(fp, "break;\n");
    break;
  case stmt_kind_return:
    fprintf(fp, "return ");
    pr_expr(fp, s->u.e);
    fprintf(fp, ";\n");
    break;
  case stmt_kind_expr:
    pr_expr(fp, s->u.e);
    fprintf(fp, ";\n");
    break;
  case stmt_kind_compound:
    fprintf(fp, "{\n");
    pr_var_decl_list_semicolon(fp, s->u.c.decls);
    pr_stmt_list(fp, s->u.c.body);
    fprintf(fp, "}\n");
    break;
  case stmt_kind_if:
    fprintf(fp, "if (");
    pr_expr(fp, s->u.i.e);
    fprintf(fp, ") ");
    pr_stmt(fp, s->u.i.th);
    if (s->u.i.el) {
      fprintf(fp, " else ");
      pr_stmt(fp, s->u.i.el);
    }
    break;
  case stmt_kind_while:
    fprintf(fp, "while(");
    pr_expr(fp, s->u.w.e);
    fprintf(fp, ") ");
    pr_stmt(fp, s->u.w.body);
    break;
  default:
    assert(0);
  }
}
コード例 #3
0
ファイル: syntree.c プロジェクト: doniexun/compiler-40
/* 式のリストを , で区切りながら表示 */
void pr_expr_list_comma(FILE * fp, expr_list_t es)
{
  int n = expr_list_sz(es);
  int i;
  for (i = 0; i < n; i++) {
    if (i > 0) fprintf(fp, ", ");
    expr_t e = expr_list_get(es, i);
    pr_expr(fp, e);
  }
}
コード例 #4
0
ファイル: syntax.c プロジェクト: loiso/scalc
static void
mul_expr(void)
{
	switch(token.type) {		
	case TOKEN_INTEGER:
	case TOKEN_LPARENTH:
		pr_expr();
		if (err == SYN_ERR) {
			goto out;
		}
		rest_mul_expr();
		goto out;
	default:
		err = SYN_ERR;
		goto out;
	}
out:
	return ;
}
コード例 #5
0
ファイル: syntax.c プロジェクト: loiso/scalc
static void
rest_mul_expr(void)
{
	int tmp, rv, i;
	number op1, op2;
		
	while(token.type == TOKEN_ASTERISK || token.type == TOKEN_SLASH) {	
		tmp = token.type;
		get_next_token();
		
		pr_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 (tmp == TOKEN_ASTERISK) {
			rv = mpl_mul(&op1.value, &op1.value, &op2.value);
			if (rv != MPL_OK) {
				err = MEM_ERR; 
				goto out;
			}
			
			op1.frac += op2.frac;

		} else if (tmp == TOKEN_SLASH) {
			if (op1.frac == 0 && op2.frac == 0)
				goto main_part;
				
			op1.frac -= op2.frac;
			for (i = 0; i < PRECISION; i++) {
				rv = mpl_mul_dig(&op1.value, &op1.value, 10);
				if (rv != MPL_OK) {
					err = MEM_ERR;
					goto out;
				}
				op1.frac++;
			}
main_part:			
			rv = mpl_div(&op1.value, NULL, &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_PLUS && token.type != TOKEN_MINUS &&
	    token.type != TOKEN_RPARENTH && token.type != TOKEN_EOL) {
			err = SYN_ERR;
			goto out;
	}
	
out:
	return ;
}