Skip to content

Commit

Permalink
Implement local scope for if and while when constructing ASG (#105)
Browse files Browse the repository at this point in the history
Closes #103
  • Loading branch information
jlapeyre committed Feb 6, 2024
1 parent 6bdaf56 commit 1152f30
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
4 changes: 4 additions & 0 deletions crates/oq3_semantics/src/semantic_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ impl SemanticError {
self.node.text_range()
}

pub fn kind(&self) -> &SemanticErrorKind {
&self.error_kind
}

pub fn message(&self) -> String {
format!("{:?}", self.error_kind)
}
Expand Down
12 changes: 9 additions & 3 deletions crates/oq3_semantics/src/syntax_to_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,20 @@ fn from_stmt(stmt: synast::Stmt, context: &mut Context) -> Option<asg::Stmt> {
match stmt {
synast::Stmt::IfStmt(if_stmt) => {
let condition = from_expr(if_stmt.condition().unwrap(), context);
let then_branch = from_block_expr(if_stmt.then_branch().unwrap(), context);
let else_branch = if_stmt.else_branch().map(|ex| from_block_expr(ex, context));
with_scope!(context, ScopeType::Local,
let then_branch = from_block_expr(if_stmt.then_branch().unwrap(), context);
);
with_scope!(context, ScopeType::Local,
let else_branch = if_stmt.else_branch().map(|ex| from_block_expr(ex, context));
);
Some(asg::If::new(condition.unwrap(), then_branch, else_branch).to_stmt())
}

synast::Stmt::WhileStmt(while_stmt) => {
let condition = from_expr(while_stmt.condition().unwrap(), context);
let loop_body = from_block_expr(while_stmt.body().unwrap(), context);
with_scope!(context, ScopeType::Local,
let loop_body = from_block_expr(while_stmt.body().unwrap(), context);
);
Some(asg::While::new(condition.unwrap(), loop_body).to_stmt())
}

Expand Down
49 changes: 48 additions & 1 deletion crates/oq3_semantics/tests/from_string_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use oq3_semantics::asg;
use oq3_semantics::semantic_error::SemanticErrorList;
use oq3_semantics::semantic_error::{SemanticErrorKind, SemanticErrorList};
use oq3_semantics::symbols::{SymbolTable, SymbolType};
use oq3_semantics::syntax_to_semantics::parse_source_string;
use oq3_semantics::types::{ArrayDims, IsConst, Type};
Expand Down Expand Up @@ -117,6 +117,53 @@ while (false) {
assert_eq!(inner, vec![&1u128, &2u128]);
}

#[test]
fn test_from_string_while_stmt_scope() {
let code = r##"
while (false) {
int x = 1;
}
x = 2;
"##;
let (program, errors, _symbol_table) = parse_string(code);
assert!(matches!(
&errors[0].kind(),
SemanticErrorKind::UndefVarError
));
assert_eq!(errors.len(), 1);
assert_eq!(program.len(), 2);
}

#[test]
fn test_from_string_if_stmt_scope() {
let code = r##"
if (false) {
int x = 1;
}
x = 2;
"##;
let (program, errors, _symbol_table) = parse_string(code);
assert!(matches!(
&errors[0].kind(),
SemanticErrorKind::UndefVarError
));
assert_eq!(errors.len(), 1);
assert_eq!(program.len(), 2);
}

#[test]
fn test_from_string_if_stmt_scope_2() {
let code = r##"
if (false) {
int x = 1;
}
int x = 2;
"##;
let (program, errors, _symbol_table) = parse_string(code);
assert_eq!(errors.len(), 0);
assert_eq!(program.len(), 2);
}

#[test]
fn test_indexed_identifier() {
let code = r##"
Expand Down

0 comments on commit 1152f30

Please sign in to comment.