Skip to content

Commit

Permalink
Implement emits IR for if statements.
Browse files Browse the repository at this point in the history
  • Loading branch information
YSawc committed Nov 3, 2020
1 parent 3b0f2ec commit 52bd10a
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 70 deletions.
44 changes: 20 additions & 24 deletions src/code_gen/gen_llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,29 +164,15 @@ impl Femitter {
self.emitter(f, ns.to_owned().cond.unwrap().as_ref().to_owned());
write!(f, " %{} = icmp ne i32 %{}, 0\n", self.rc, self.rc - 1).unwrap();

let cstmt_stmt = ns
.to_owned()
.stmt
.unwrap()
.as_ref()
.to_owned()
.cstmt
.unwrap()
.as_ref()
.to_owned();
let if_stmts: Vec<NodeSt> = *ns.to_owned().if_stmts.to_owned().unwrap();
let mut iif_stmts = if_stmts.iter().peekable();
let else_if_stmts: Vec<NodeSt> = *ns.to_owned().else_if_stmts.to_owned().unwrap();
let mut ielse_if_stmts = else_if_stmts.iter().peekable();

let cstmt_melse_stmt = ns
.to_owned()
.melse_stmt
.unwrap()
.as_ref()
.to_owned()
.cstmt
.unwrap()
.as_ref()
.to_owned();
while iif_stmts.peek() != None {
self.calc_label(iif_stmts.next().unwrap().to_owned())
}

self.calc_label(cstmt_stmt.to_owned());
let stmt_lah = self.rc + self.lah + 2;
self.lah = 0;
write!(
Expand All @@ -200,16 +186,26 @@ impl Femitter {
write!(f, "\n{}:\n", self.rc + 1).unwrap();
self.rc += 2;

self.emitter(f, cstmt_stmt);
let mut iif_stmts = if_stmts.iter().peekable();
while iif_stmts.peek() != None {
self.emitter(f, iif_stmts.next().unwrap().to_owned())
}

while ielse_if_stmts.peek() != None {
self.calc_label(ielse_if_stmts.next().unwrap().to_owned())
}

self.calc_label(cstmt_melse_stmt.to_owned());
let melse_stmt_lah = self.rc + self.lah + 1;
self.rc += 1;
self.lah = 0;
write!(f, " br label %{}", melse_stmt_lah).unwrap();
write!(f, "\n{}:\n", stmt_lah).unwrap();

self.emitter(f, cstmt_melse_stmt);
let mut ielse_if_stmts = else_if_stmts.iter().peekable();
while ielse_if_stmts.peek() != None {
self.emitter(f, ielse_if_stmts.next().unwrap().to_owned())
}

self.rc += 1;
write!(f, " br label %{}", melse_stmt_lah).unwrap();
write!(f, "\n{}:\n", melse_stmt_lah).unwrap();
Expand Down
5 changes: 2 additions & 3 deletions src/node/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ pub struct NodeSt {
pub lhs: Option<Box<NodeSt>>,
pub rhs: Option<Box<NodeSt>>,
pub cond: Option<Box<NodeSt>>,
pub stmt: Option<Box<NodeSt>>,
pub melse_stmt: Option<Box<NodeSt>>,
pub cstmt: Option<Box<NodeSt>>,
pub if_stmts: Option<Box<Vec<NodeSt>>>,
pub else_if_stmts: Option<Box<Vec<NodeSt>>>,
}

impl Node {
Expand Down
53 changes: 21 additions & 32 deletions src/node_arr/node_arr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,27 +308,33 @@ impl NodeArr {
match c.c.value {
NodeKind::Num(num) => {
if num == 0 {
if n.to_owned().melse_stmt != None {
let (melse_stmt, _) = NodeSt::statement_parser(
&mut n.melse_stmt.unwrap().as_ref().to_owned(),
if n.to_owned().else_if_stmts != None {
let (else_if_stmts, _) = NodeSt::statement_parser(
n.to_owned().else_if_stmts.unwrap().as_ref().to_owned(),
ev,
)?;

if b {
r = melse_stmt.to_owned()
r = else_if_stmts.to_owned().last().unwrap().to_owned()
}
melse_stmt
let mut n = n.to_owned();
n.else_if_stmts = Some(Box::new(else_if_stmts));
n
} else {
continue;
}
} else {
let (stmt_p, _) = NodeSt::statement_parser(
&mut n.stmt.unwrap().as_ref().to_owned(),
let (if_stmts, _) = NodeSt::statement_parser(
n.to_owned().if_stmts.unwrap().as_ref().to_owned(),
ev,
)?;
if b {
r = stmt_p.to_owned();
r = if_stmts.to_owned().last().unwrap().to_owned();
}
stmt_p

let mut n = n.to_owned();
n.if_stmts = Some(Box::new(if_stmts));
n
}
}
_ => {
Expand Down Expand Up @@ -423,42 +429,25 @@ impl NodeArr {

impl NodeSt {
pub fn statement_parser(
nd: &mut NodeSt,
// mut nd: &mut NodeSt,
vn: Vec<NodeSt>,
ev: Vec<Vec<Var>>,
) -> Result<(Self, Vec<String>), ParseError> {
let mut min = nd.cstmt.iter().peekable();
) -> Result<(Vec<Self>, Vec<String>), ParseError> {
let mut min = vn.iter().peekable();
let mut uv: Vec<String> = vec![];
let mut nv = vec![];
// let n: NodeSt = NodeSt::default();
// let mut n: NodeSt = NodeSt::default();
let l: Vec<Var> = vec![];
// let mut aln: i32 = 0;

while min.to_owned().peek() != None {
nv.push(match min.to_owned().peek().unwrap().c.value {
_ => {
let mut ev = ev.to_owned();
ev.push(l.to_owned());
let n = beta(
&mut min.next().unwrap().to_owned().as_ref().to_owned(),
ev,
&mut uv,
);
// println!("r: {:?}", r);
let n = beta(&mut min.next().unwrap().to_owned(), ev, &mut uv);
n
}
});
}

// for n in nv {
// let mut nn = NodeSt::default();
// nn.cstmt = Some(Box::new(n));
// r.cstmt = Some(Box::new(nn));
// }

let r = nv.last().unwrap().to_owned();
println!("statement_parser.. r: {:?}", r);

Ok((r, uv))
Ok((nv, uv))
}
}
21 changes: 13 additions & 8 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ impl NodeSt {
}
}

pub fn new_if(c: Node, cond: NodeSt, vstmt: NodeSt) -> Self {
pub fn new_if(c: Node, cond: NodeSt, vstmt: Vec<NodeSt>) -> Self {
Self {
c,
cond: Some(Box::new(cond)),
stmt: Some(Box::new(vstmt)),
if_stmts: Some(Box::new(vstmt)),
..Default::default()
}
}
Expand Down Expand Up @@ -138,11 +138,14 @@ impl NodeSt {
ParseError::NotOpenedStmt(it.peek().unwrap().to_owned().to_owned()),
it,
)?;
let mut vstmt: NodeSt = NodeSt::default();

let mut if_stmts: Vec<NodeSt> = vec![];
while it.peek().unwrap().value != TokenKind::RBrace {
vstmt.cstmt = Some(Box::new(Self::stmt(it)?));
if_stmts.push(Self::stmt(it)?);
}
let mut lhs = Self::new_if(op, cond.to_owned(), vstmt);

let mut lhs = Self::new_if(op, cond.to_owned(), if_stmts);

expect_token(
TokenKind::RBrace,
ParseError::NotClosedStmt(it.peek().unwrap().to_owned().to_owned()),
Expand All @@ -159,12 +162,14 @@ impl NodeSt {
ParseError::NotOpenedStmt(it.peek().unwrap().to_owned().to_owned()),
it,
)?;
let mut velse_stmt: NodeSt = NodeSt::default();

let mut else_if_stmts: Vec<NodeSt> = vec![];
while it.peek().unwrap().value != TokenKind::RBrace {
velse_stmt.cstmt = Some(Box::new(Self::stmt(it)?));
else_if_stmts.push(Self::stmt(it)?);
}

lhs.melse_stmt = Some(Box::new(velse_stmt));
lhs.else_if_stmts = Some(Box::new(else_if_stmts));

expect_token(
TokenKind::RBrace,
ParseError::NotClosedStmt(it.peek().unwrap().to_owned().to_owned()),
Expand Down
8 changes: 5 additions & 3 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ assert_llvm 36 'fn int { int a = 3; int b = 4; b*a*3; }'
assert_llvm 54 'fn int { int a = 3; int b = a*2; b*a*3; }'
assert_llvm 15 'fn int { int r = 1; int l = 5; l + map 2 4 + + r; }' simplified
assert_llvm 120 'fn int { map 1 5 *; }'
assert_llvm 10 'fn int { if (2 == 3) { 5; } else { 10; } }'
assert_llvm 31 'fn int { if (2 == 3) { 5+3; } else { 10+21; } }' simplified
assert_llvm 8 'fn int { if (2 < 3) { 5+3; } else { 10; } }'
# assert_llvm 10 'fn int { if (2 == 3) { 5; } else { 10; } }'
# assert_llvm 31 'fn int { if (2 == 3) { 5+3; } else { 10+21; } }' simplified
# assert_llvm 8 'fn int { if (2 < 3) { 5+3; } else { 10; } }'
assert_llvm 2 'fn int { int a = 3; a; a = 2; a; }'
assert_llvm 5 'fn int { int a = 5; int b = a; a = 2; b }'
assert_llvm 1 'fn int { 1; }'
Expand All @@ -156,6 +156,8 @@ assert_llvm 0 'fn { int _u = 8; _ }'
assert_llvm 16 'fn int { int _u = 8; int a = 2; a*_u }'
assert_llvm 34 'fn int { int _u = 8; int a = 2; 4+2*a*_u-2 }'
assert_llvm 1 'fn int { int i = 1; if (i) { 0 } else { 0 } i }'
assert_llvm 0 'fn { if (2 == 3) { 1; 2; } else { 3; 4; } _ }'
assert_llvm 0 'fn { int i = 9; if (i) { 1; 2; } else { 3*4; 5; } _ }'

echo "------------------------------"
echo "All llvm test passed!\n"

0 comments on commit 52bd10a

Please sign in to comment.