Skip to content

Commit

Permalink
Impelement initialize variable.
Browse files Browse the repository at this point in the history
  • Loading branch information
YSawc committed Oct 10, 2020
1 parent 284a2d7 commit 3df3c89
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 40 deletions.
3 changes: 2 additions & 1 deletion src/error/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ impl Error {
| ParseError::NotClosedStmt(loc, ..)
| ParseError::OperatorAfterRetrun(loc, ..)
| ParseError::NotIdent(loc, ..)
| ParseError::NotAssign(loc, ..) => loc.loc.clone(),
| ParseError::NotAssign(loc, ..)
| ParseError::NotDefinitionVar(loc, ..) => loc.loc.clone(),
ParseError::Eof => Loc::new(input.len() as u8, input.len() as u8 + 1),
};
(e, loc)
Expand Down
5 changes: 5 additions & 0 deletions src/fmt/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ impl fmt::Display for ParseError {
ParseError::NotAssign(tok) => {
write!(f, "{}: Expected assign but got {}.", tok.loc, tok.value)
}
ParseError::NotDefinitionVar(tok) => write!(
f,
"{}: Expected definition var but not detected. Failed ident is {}",
tok.loc, tok.value
),
ParseError::Eof => write!(f, "Expected token, but not detected."),
}
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ pub mod parser;
pub mod simplified;
pub mod tests;
pub mod token;
pub mod var;
58 changes: 47 additions & 11 deletions src/node_arr/node_arr.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,77 @@
use super::super::node::node::*;
use super::super::parser::error::*;
use super::super::token::token::*;
use super::super::var::var::*;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NodeArr {
pub node_st_vec: Vec<NodeSt>,
pub ret_node_st: NodeSt,
pub l: Vec<Var>,
}

impl NodeArr {
pub fn find_l(s: String, vv: Vec<Var>) -> Option<Var> {
for v in vv {
if v.s == s {
return Some(v);
}
}
None
}
}

impl NodeArr {
pub fn new(v: Vec<NodeSt>) -> Self {
Self {
node_st_vec: v.to_owned(),
ret_node_st: v.to_owned().last().unwrap().to_owned(),
l: vec![],
}
}

pub fn w_parser(vt: Vec<Token>) -> Result<Self, ParseError> {
let mut vti = vt.iter().peekable();
let mut n = vec![];
let mut nv = vec![];
let mut l: Vec<Var> = vec![];

while vti.peek() != None {
n.push(match NodeSt::parser(&mut vti) {
Ok(n) => {
// println!("n: {:?}", n);
if n.c.value == NodeKind::Return && vti.peek() != None {
return Err(ParseError::OperatorAfterRetrun(
vti.next().unwrap().to_owned(),
));
nv.push(match NodeSt::parser(&mut vti) {
Ok(n) => match n.c.value {
NodeKind::Return => {
if vti.peek() != None {
return Err(ParseError::OperatorAfterRetrun(
vti.next().unwrap().to_owned(),
));
}
n
}
NodeKind::Assign => {
let s = match n.to_owned().lhs.unwrap().lhs.unwrap().c.value {
NodeKind::Ident(s) => s,
_ => unreachable!(),
};
let n = n.lhs.as_ref().unwrap().as_ref().to_owned();
let v = Var::new(s, n);
l.push(v);
continue;
}
n
}
NodeKind::Ident(s) => match Self::find_l(s, l.to_owned()) {
Some(v) => v.n,
None => {
return Err(ParseError::NotDefinitionVar(
vti.next().unwrap().to_owned(),
))
}
},
_ => n,
},
Err(e) => return Err(e),
});
}

let a = Self::new(n);
let mut a = Self::new(nv);
a.l = l;
Ok(a)
}
}
1 change: 1 addition & 0 deletions src/parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub enum ParseError {
OperatorAfterRetrun(Token),
NotIdent(Token),
NotAssign(Token),
NotDefinitionVar(Token),
// UnexpectedToken(Token),
// NotExpression(Token),
// UnclosedOpenParen(Token),
Expand Down
32 changes: 4 additions & 28 deletions src/tests/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,13 @@ fn evaluation_final_value_test() {

#[test]
fn parser_assign_test() {
let t = Token::tokenize("int a = 3;").unwrap();
let t = Token::tokenize("int a = 3; 1").unwrap();
let l = NodeArr::w_parser(t).unwrap().ret_node_st;
let e = {
NodeSt {
c: Annot {
value: NodeKind::Assign,
loc: Loc { f: 7, e: 8 },
},
lhs: Some(Box::new(NodeSt {
c: Annot {
value: NodeKind::Int,
loc: Loc { f: 0, e: 3 },
},
lhs: Some(Box::new(NodeSt {
c: Annot {
value: NodeKind::Ident("a".to_string()),
loc: Loc { f: 4, e: 6 },
},
lhs: None,
rhs: None,
})),
rhs: None,
})),
rhs: Some(Box::new(NodeSt {
c: Annot {
value: NodeKind::Num(3),
loc: Loc { f: 10, e: 11 },
},
lhs: None,
rhs: None,
})),
c: Node::number(1, Loc::new(14, 15)),
lhs: None,
rhs: None,
}
};
assert_eq!(e, l)
Expand Down
1 change: 1 addition & 0 deletions src/var/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod var;
20 changes: 20 additions & 0 deletions src/var/var.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use super::super::node::node::*;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Var {
pub s: String,
pub n: NodeSt,
}

impl Var {
pub fn new(s: String, n: NodeSt) -> Self {
Self { s, n }
}

pub fn default() -> Self {
Self {
s: String::new(),
n: NodeSt::default(),
}
}
}
2 changes: 2 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ assert 3 '(1*2>=3-(2*1))+2;' simplified
assert 4 '4'
assert 3 '2; 3'
assert 4 'return 4;'
assert 1 'int a = 3; 1;'
assert 2 'int a = 3; return 2;'

echo "------------------------------"
echo "All test passed!"

0 comments on commit 3df3c89

Please sign in to comment.