Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/ghaith/ruSTy into #17_par…
Browse files Browse the repository at this point in the history
…sing_comparisons
  • Loading branch information
riederm committed Dec 14, 2019
2 parents 17304c8 + 9e6fe4d commit 6ce38a4
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 6 deletions.
7 changes: 6 additions & 1 deletion src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ pub enum Statement {
},
BinaryExpression {
operator: Operator,
left: Box<Statement>,
right: Box<Statement>,
},
Assignment {
left: Box<Statement>,
right: Box<Statement>,
},
}
}

#[derive(Debug, PartialEq)]
Expand All @@ -44,4 +48,5 @@ pub enum Operator {
Division,
OperatorEqual,
OperatorNotEqual,
Modulo,
}
7 changes: 6 additions & 1 deletion src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub enum Token {
#[token = "<>"]
OperatorNotEqual,

#[token = "MOD"]
OperatorModulo,

#[regex = r"[0-9]+(\.(0-9)+)?"]
LiteralNumber,
}
Expand Down Expand Up @@ -130,14 +133,16 @@ mod tests {

#[test]
fn operator_test() {
let mut lexer = super::lex("+ - * /");
let mut lexer = super::lex("+ - * / MOD");
assert_eq!(lexer.token, super::Token::OperatorPlus);
lexer.advance();
assert_eq!(lexer.token, super::Token::OperatorMinus);
lexer.advance();
assert_eq!(lexer.token, super::Token::OperatorMultiplication);
lexer.advance();
assert_eq!(lexer.token, super::Token::OperatorDivision);
lexer.advance();
assert_eq!(lexer.token, super::Token::OperatorModulo);
}

#[test]
Expand Down
84 changes: 80 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ fn parse_multiplication_expression(lexer: &mut RustyLexer) -> Result<Statement,
let operator = match lexer.token {
OperatorMultiplication => Operator::Multiplication,
OperatorDivision => Operator::Division,
OperatorModulo => Operator::Modulo,
_ => return Ok(left),
};
lexer.advance();
Expand All @@ -182,11 +183,21 @@ fn parse_parenthesized_expression(lexer: &mut RustyLexer) -> Result<Statement, S
}

fn parse_unary_expression(lexer: &mut RustyLexer) -> Result<Statement, String> {
match lexer.token {
Identifier => parse_reference(lexer),
LiteralNumber => parse_literal_number(lexer),
_ => Err(unexpected_token(lexer)),
let current =
match lexer.token {
Identifier => parse_reference(lexer),
LiteralNumber => parse_literal_number(lexer),
_ => Err(unexpected_token(lexer)),
};

if current.is_ok() && lexer.token == KeywordAssignment {
lexer.advance();
return Ok(Statement::Assignment{
left: Box::new(current?),
right: Box::new(parse_primary_expression(lexer)?),
});
}
current
}

fn parse_reference(lexer: &mut RustyLexer) -> Result<Statement, String> {
Expand Down Expand Up @@ -547,6 +558,29 @@ mod tests {
assert_eq!(ast_string, expected_ast);
}

#[test]
fn module_expression_test() {
let lexer = lexer::lex("PROGRAM exp 5 MOD 2; END_PROGRAM");

let result = super::parse(lexer).unwrap();

let prg = &result.units[0];
let statement = &prg.statements[0];

let ast_string = format!("{:#?}", statement);
let expected_ast = r#"BinaryExpression {
operator: Modulo,
left: LiteralNumber {
value: "5",
},
right: LiteralNumber {
value: "2",
},
}"#;

assert_eq!(ast_string, expected_ast);
}

#[test]
fn parenthesized_term_ast_test() {
let lexer = lexer::lex("PROGRAM exp (1+2)*(3+4); END_PROGRAM");
Expand Down Expand Up @@ -579,4 +613,46 @@ mod tests {
}"#;
assert_eq!(ast_string, expected_ast);
}

#[test]
fn assignment_test() {
let lexer = lexer::lex("PROGRAM exp x := 3; x := 1 + 2; END_PROGRAM");
let result = super::parse(lexer).unwrap();

let prg = &result.units[0];
{
let statement = &prg.statements[0];
let ast_string = format!("{:#?}", statement);
let expected_ast = r#"Assignment {
left: Reference {
name: "x",
},
right: LiteralNumber {
value: "3",
},
}"#;
assert_eq!(ast_string, expected_ast);
}

{
let statement = &prg.statements[1];
let ast_string = format!("{:#?}", statement);
let expected_ast = r#"Assignment {
left: Reference {
name: "x",
},
right: BinaryExpression {
operator: Plus,
left: LiteralNumber {
value: "1",
},
right: LiteralNumber {
value: "2",
},
},
}"#;
assert_eq!(ast_string, expected_ast);
}
}

}

0 comments on commit 6ce38a4

Please sign in to comment.