Skip to content

Commit b87c09c

Browse files
committedJan 4, 2018
coverage-related changes
1 parent eef4718 commit b87c09c

File tree

10 files changed

+168
-103
lines changed

10 files changed

+168
-103
lines changed
 

‎example/escape-seq.c

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <stdio.h>
2+
3+
int main() {
4+
putchar('\\');
5+
putchar('\"');
6+
putchar('\'');
7+
putchar('\?');
8+
putchar('\a');
9+
putchar('\b');
10+
putchar('\t');
11+
putchar('\n');
12+
putchar('\f');
13+
putchar('\r');
14+
putchar('\v');
15+
putchar('\x17');
16+
putchar('\123');
17+
putchar('\0');
18+
}

‎example/funccall.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,19 @@ int add1(int n) {
55
return n + 1;
66
}
77

8+
// all qualifiers (for coverage)
9+
typedef int I;
10+
static I i1;
11+
I f1() { auto I i2; register I i3; return 0; }
12+
const I i4 = 1;
13+
volatile I i5;
14+
inline I f2() { I * restrict i6 = 0; return 0; }
15+
816
int main(int argc, char *argv[]) {
917
printf("add1(2) = %d%c", add1(2), 0xa);
10-
printf("hello world%s", "!!");
18+
printf("hello"
19+
" "
20+
"world%s",
21+
"!!");
1122
return 0;
1223
}

‎example/op.c

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,42 @@
22

33
int main() {
44
// TODO: this is for coverage. many other operators will be checked in the future.
5+
printf("%d\n", 1 + 2);
6+
printf("%d\n", 2 - 1);
7+
printf("%d\n", 2 * 3);
8+
printf("%d\n", 4 / 2);
9+
printf("%d\n", 4 % 3);
10+
printf("%d\n", 1 & 2);
11+
printf("%d\n", 1 | 2);
12+
printf("%d\n", 1 ^ 2);
513
printf("%d\n", 1 && 0);
14+
printf("%d\n", 1 || 0);
15+
printf("%d\n", 5 == 5);
16+
printf("%d\n", 1 != 1);
17+
printf("%d\n", 3 < 4);
18+
printf("%d\n", 3 > 4);
19+
printf("%d\n", 3 <= 4);
20+
printf("%d\n", 3 >= 4);
21+
printf("%d\n", 1 << 4);
22+
printf("%d\n", 16 >> 4);
23+
printf("%d\n", !0);
24+
printf("%d\n", ~123);
25+
printf("%d\n", +12);
26+
printf("%d\n", -34);
27+
int i = 0, *a = &i;
28+
printf("%d\n", ++i);
29+
printf("%d\n", --i);
30+
printf("%d\n", i++);
31+
printf("%d\n", i--);
32+
printf("%d\n", *a);
33+
i += 10;
34+
i -= 10;
35+
i *= 10;
36+
i /= 10;
37+
i %= 10;
38+
i <<= 10;
39+
i >>= 10;
40+
i &= 10;
41+
i |= 10;
642
return 0;
743
}

‎example/sizeof.c

+17-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@ struct S {
77
double f;
88
};
99

10+
union U {
11+
struct S s;
12+
char hello[6];
13+
};
14+
15+
enum { ZERO, ONE };
16+
1017
#define PRINT_SIZEOF(type) printf("sizeof(%s) = %d%c", #type, sizeof(type), 0xa)
1118

1219
int main() {
13-
char s[][8] = {"hello", "rucc", "world"};
14-
int i; double f;
20+
char str[][8] = {"hello", "rucc", "world"};
21+
int i; double f; struct S s; union U u;
1522
PRINT_SIZEOF( char );
1623
PRINT_SIZEOF( short );
1724
PRINT_SIZEOF( int );
@@ -21,11 +28,17 @@ int main() {
2128
PRINT_SIZEOF( double );
2229
PRINT_SIZEOF( int [5] );
2330
PRINT_SIZEOF( struct S );
31+
PRINT_SIZEOF( union U );
32+
PRINT_SIZEOF( u );
33+
PRINT_SIZEOF( s.f );
2434
PRINT_SIZEOF( "a" );
2535
PRINT_SIZEOF( 1 + 2 );
36+
PRINT_SIZEOF( 1.2 + 3.4 );
37+
PRINT_SIZEOF( 100000000000 + 200000000000 );
38+
PRINT_SIZEOF( ZERO + ONE );
2639
PRINT_SIZEOF( i + f );
27-
PRINT_SIZEOF( s );
28-
PRINT_SIZEOF( s + i );
40+
PRINT_SIZEOF( str );
41+
PRINT_SIZEOF( str + i );
2942
PRINT_SIZEOF( main );
3043
PRINT_SIZEOF( main + 8 );
3144
PRINT_SIZEOF( puts("hello") );

‎src/codegen.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub struct Codegen {
9696
context: LLVMContextRef,
9797
module: LLVMModuleRef,
9898
builder: LLVMBuilderRef,
99-
exec_engine: llvm::execution_engine::LLVMExecutionEngineRef,
99+
// exec_engine: llvm::execution_engine::LLVMExecutionEngineRef,
100100
global_varmap: HashMap<String, VarInfo>,
101101
local_varmap: Vec<HashMap<String, VarInfo>>,
102102
label_map: HashMap<String, LLVMBasicBlockRef>,
@@ -201,7 +201,7 @@ impl Codegen {
201201
context: context,
202202
module: module,
203203
builder: LLVMCreateBuilderInContext(context),
204-
exec_engine: ee,
204+
// exec_engine: ee,
205205
global_varmap: global_varmap,
206206
local_varmap: Vec::new(),
207207
label_map: HashMap::new(),

‎src/lexer.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,6 @@ impl Lexer {
283283
pub fn get_cur_line(&self) -> &usize {
284284
self.cur_line.back().unwrap()
285285
}
286-
pub fn get_mut_cur_line(&mut self) -> &mut usize {
287-
self.cur_line.back_mut().unwrap()
288-
}
289286
fn peek_get(&mut self) -> ParseR<char> {
290287
let peek = self.peek.back_mut().unwrap();
291288
let peek_pos = *self.peek_pos.back_mut().unwrap();
@@ -296,7 +293,7 @@ impl Lexer {
296293
}
297294
}
298295
fn peek_next(&mut self) -> ParseR<char> {
299-
let peek = self.peek.back_mut().unwrap();
296+
let peek = self.peek.back().unwrap();
300297
let peek_pos = self.peek_pos.back_mut().unwrap();
301298
if *peek_pos >= peek.len() {
302299
return Err(Error::EOF);
@@ -331,14 +328,6 @@ impl Lexer {
331328
let peek = try!(self.peek());
332329
Ok(peek.kind == TokenKind::Symbol(expect))
333330
}
334-
pub fn next_keyword_token_is(&mut self, expect: Keyword) -> ParseR<bool> {
335-
let peek = try!(self.get());
336-
let next = try!(self.get());
337-
let next_token_is_expected = next.kind == TokenKind::Keyword(expect);
338-
self.unget(next);
339-
self.unget(peek);
340-
Ok(next_token_is_expected)
341-
}
342331
pub fn next_symbol_token_is(&mut self, expect: Symbol) -> ParseR<bool> {
343332
let peek = try!(self.get());
344333
let next = try!(self.get());
@@ -563,7 +552,8 @@ impl Lexer {
563552
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' => {
564553
// if '0', check whether octal number \nnn or null \0
565554
if try!(self.peek_get()).is_numeric() {
566-
let mut oct = "0".to_string();
555+
let mut oct = "".to_string();
556+
oct.push(c);
567557
loop {
568558
let c = try!(self.peek_next());
569559
oct.push(c);

‎src/main.rs

+33-18
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,39 @@ fn main() {
3636
}
3737

3838
#[test]
39-
fn compile_examples() {
39+
fn compare_with_clang_output() {
40+
use std::fs;
41+
42+
let examples_paths = match fs::read_dir("example") {
43+
Ok(paths) => paths,
44+
Err(e) => panic!(format!("error: {:?}", e.kind())),
45+
};
46+
for path in examples_paths {
47+
let name = path.unwrap().path().to_str().unwrap().to_string();
48+
println!("testing {}...", name);
49+
50+
Command::new("./rucc.sh")
51+
.arg(name.to_string())
52+
.spawn()
53+
.expect("failed to run")
54+
.wait()
55+
.expect("failed to run");
56+
let output1 = Command::new("./a.out").output().expect("failed to run");
57+
Command::new("clang")
58+
.arg(name)
59+
.arg("-lm")
60+
.arg("-w")
61+
.spawn()
62+
.expect("failed to run")
63+
.wait()
64+
.expect("failed to run");
65+
let output2 = Command::new("./a.out").output().expect("failed to run");
66+
assert!(output1 == output2);
67+
}
68+
}
69+
70+
#[test]
71+
fn compile_all_examples() {
4072
use std::fs;
4173
use rucc::{codegen, lexer, parser};
4274
use std::process::Command;
@@ -71,22 +103,5 @@ fn compile_examples() {
71103
nodes.clear();
72104
}
73105
}
74-
75-
Command::new("./rucc.sh")
76-
.arg(name.to_string())
77-
.spawn()
78-
.expect("failed to run")
79-
.wait()
80-
.expect("failed to run");
81-
let output1 = Command::new("./a.out").output().expect("failed to run");
82-
Command::new("clang")
83-
.arg(name)
84-
.arg("-lm")
85-
.spawn()
86-
.expect("failed to run")
87-
.wait()
88-
.expect("failed to run");
89-
let output2 = Command::new("./a.out").output().expect("failed to run");
90-
assert!(output1 == output2);
91106
}
92107
}

‎src/node.rs

-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ pub enum CBinOps {
9292
pub enum CUnaryOps {
9393
LNot,
9494
BNot,
95-
Plus,
9695
Minus,
9796
// TODO: Inc and Dec is actually POSTFIX.
9897
Inc,
@@ -114,7 +113,6 @@ impl AST {
114113
ASTKind::TypeCast(ref e, _) => try!(e.eval()),
115114
ASTKind::UnaryOp(ref e, CUnaryOps::LNot) => (try!(e.eval()) == 0) as i64,
116115
ASTKind::UnaryOp(ref e, CUnaryOps::BNot) => !try!(e.eval()),
117-
ASTKind::UnaryOp(ref e, CUnaryOps::Plus) => try!(e.eval()),
118116
ASTKind::UnaryOp(ref e, CUnaryOps::Minus) => -try!(e.eval()),
119117
ASTKind::UnaryOp(ref e, CUnaryOps::Inc) => try!(e.eval()) + 1,
120118
ASTKind::UnaryOp(ref e, CUnaryOps::Dec) => try!(e.eval()) - 1,

‎src/parser.rs

+18-29
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use types::{Sign, StorageClass, Type};
66
use std::str;
77
use std::rc::Rc;
88
use std::io::{stderr, Write};
9-
use std::collections::{hash_map, HashMap, HashSet, VecDeque};
9+
use std::collections::{hash_map, HashMap, VecDeque};
1010

1111
// use CODEGEN;
1212

@@ -54,7 +54,7 @@ pub struct Parser<'a> {
5454
env: VecDeque<HashMap<String, AST>>,
5555
tags: VecDeque<HashMap<String, Type>>,
5656
// TODO: better implementation needed
57-
constexpr_func_map: HashSet<String>,
57+
// constexpr_func_map: HashSet<String>,
5858
}
5959

6060
macro_rules! matches {
@@ -94,7 +94,7 @@ impl<'a> Parser<'a> {
9494
err_counts: 0,
9595
env: env,
9696
tags: tags,
97-
constexpr_func_map: HashSet::new(),
97+
// constexpr_func_map: HashSet::new(),
9898
}
9999
}
100100
fn show_error(&mut self, msg: &str) {
@@ -1353,6 +1353,20 @@ impl<'a> Parser<'a> {
13531353
self.lexer.get_cur_pos(),
13541354
);
13551355
}
1356+
TokenKind::Symbol(Symbol::AssignXor) => {
1357+
lhs = assign(
1358+
lhs.clone(),
1359+
AST::new(
1360+
ASTKind::BinaryOp(
1361+
Rc::new(lhs),
1362+
Rc::new(try!(self.read_assign())),
1363+
node::CBinOps::Xor,
1364+
),
1365+
self.lexer.get_cur_pos(),
1366+
),
1367+
self.lexer.get_cur_pos(),
1368+
);
1369+
}
13561370
// TODO: implement more op
13571371
_ => {
13581372
self.lexer.unget(tok);
@@ -1587,12 +1601,7 @@ impl<'a> Parser<'a> {
15871601
self.lexer.get_cur_pos(),
15881602
))
15891603
}
1590-
TokenKind::Symbol(Symbol::Add) => {
1591-
return Ok(AST::new(
1592-
ASTKind::UnaryOp(Rc::new(try!(self.read_cast())), node::CUnaryOps::Plus),
1593-
self.lexer.get_cur_pos(),
1594-
))
1595-
}
1604+
TokenKind::Symbol(Symbol::Add) => return self.read_cast(),
15961605
TokenKind::Symbol(Symbol::Sub) => {
15971606
return Ok(AST::new(
15981607
ASTKind::UnaryOp(Rc::new(try!(self.read_cast())), node::CUnaryOps::Minus),
@@ -1790,25 +1799,6 @@ impl<'a> Parser<'a> {
17901799
))
17911800
}
17921801

1793-
fn read_const_array(&mut self) -> ParseR<AST> {
1794-
let mut elems = Vec::new();
1795-
loop {
1796-
elems.push(try!(self.read_assign()));
1797-
if try!(self.lexer.skip_symbol(Symbol::ClosingBrace)) {
1798-
break;
1799-
}
1800-
if !try!(self.lexer.skip_symbol(Symbol::Comma)) {
1801-
let peek = self.lexer.peek();
1802-
self.show_error_token(&try!(peek), "expected ','");
1803-
self.skip_until(Symbol::ClosingBrace);
1804-
return Err(Error::Something);
1805-
}
1806-
}
1807-
Ok(AST::new(
1808-
ASTKind::ConstArray(elems),
1809-
self.lexer.get_cur_pos(),
1810-
))
1811-
}
18121802
fn read_primary(&mut self) -> ParseR<AST> {
18131803
let tok = match self.lexer.get() {
18141804
Ok(tok) => tok,
@@ -1853,7 +1843,6 @@ impl<'a> Parser<'a> {
18531843
}
18541844
expr
18551845
}
1856-
Symbol::OpeningBrace => self.read_const_array(),
18571846
_ => {
18581847
self.show_error_token(
18591848
&tok,

0 commit comments

Comments
 (0)