Skip to content

Commit 5f5c509

Browse files
authored
fix(compiler): process arg declarations within cell scopes (#143)
1 parent ec15bcc commit 5f5c509

File tree

5 files changed

+103
-2
lines changed

5 files changed

+103
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Temporary Items
5757
# will have compiled files and executables
5858
debug/
5959
target/
60+
target
6061

6162
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6263
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

core/compiler/src/compile.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,12 +1116,38 @@ impl<'a> AstTransformer for VarIdTyPass<'a> {
11161116
kind: StaticErrorKind::RedeclarationOfBuiltin,
11171117
});
11181118
}
1119+
self.enter_scope(&input.scope);
1120+
// TODO: this code is mostly duplicated from `transform_scope`.
11191121
let args: Vec<_> = input
11201122
.args
11211123
.iter()
11221124
.map(|arg| self.transform_arg_decl(arg))
11231125
.collect();
1124-
let scope = self.transform_scope(&input.scope);
1126+
let scope_annotation = input
1127+
.scope
1128+
.scope_annotation
1129+
.as_ref()
1130+
.map(|ident| self.transform_ident(ident));
1131+
let stmts = input
1132+
.scope
1133+
.stmts
1134+
.iter()
1135+
.map(|stmt| self.transform_statement(stmt))
1136+
.collect_vec();
1137+
let tail = input
1138+
.scope
1139+
.tail
1140+
.as_ref()
1141+
.map(|stmt| self.transform_expr(stmt));
1142+
let metadata = self.dispatch_scope(&input.scope, &stmts, &tail);
1143+
let scope = Scope {
1144+
scope_annotation,
1145+
span: input.span,
1146+
stmts,
1147+
tail,
1148+
metadata,
1149+
};
1150+
self.exit_scope(&input.scope, &scope);
11251151
if let Some(tail) = scope.tail.as_ref() {
11261152
self.errors.push(StaticError {
11271153
span: self.span(tail.span()),

core/compiler/src/lib.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mod tests {
1212
use std::path::PathBuf;
1313

1414
use crate::{
15-
compile::{ExecErrorKind, SolvedValue},
15+
compile::{ExecErrorKind, SolvedValue, StaticErrorKind},
1616
gds::GdsMap,
1717
parse::parse_workspace_with_std,
1818
};
@@ -59,6 +59,8 @@ mod tests {
5959
const ARGON_ANY_TYPE: &str = concatcp!(EXAMPLES_DIR, "/any_type/lib.ar");
6060
const ARGON_SEQ_INDEX: &str = concatcp!(EXAMPLES_DIR, "/seq_index/lib.ar");
6161
const ARGON_SEQ_CONSTRUCTOR: &str = concatcp!(EXAMPLES_DIR, "/seq_constructor/lib.ar");
62+
const ARGON_FUNC_BAD_ARG_REUSE: &str = concatcp!(EXAMPLES_DIR, "/func_bad_arg_reuse/lib.ar");
63+
const ARGON_CELL_BAD_ARG_REUSE: &str = concatcp!(EXAMPLES_DIR, "/cell_bad_arg_reuse/lib.ar");
6264

6365
#[test]
6466
fn argon_scopes() {
@@ -781,4 +783,52 @@ mod tests {
781783
assert_relative_eq!(r.x1.0, 300., epsilon = EPSILON);
782784
assert_relative_eq!(r.y1.0, 500., epsilon = EPSILON);
783785
}
786+
787+
#[test]
788+
fn argon_func_bad_arg_reuse() {
789+
let o = parse_workspace_with_std(ARGON_FUNC_BAD_ARG_REUSE);
790+
assert!(o.static_errors().is_empty());
791+
let ast = o.ast();
792+
let cells = compile(
793+
&ast,
794+
CompileInput {
795+
cell: &["top"],
796+
args: Vec::new(),
797+
lyp_file: &PathBuf::from(BASIC_LYP),
798+
},
799+
);
800+
println!("{cells:#?}");
801+
802+
let errors = cells.unwrap_static_errors();
803+
assert!(
804+
errors
805+
.errors
806+
.iter()
807+
.any(|e| matches!(e.kind, StaticErrorKind::UndeclaredVar))
808+
);
809+
}
810+
811+
#[test]
812+
fn argon_cell_bad_arg_reuse() {
813+
let o = parse_workspace_with_std(ARGON_CELL_BAD_ARG_REUSE);
814+
assert!(o.static_errors().is_empty());
815+
let ast = o.ast();
816+
let cells = compile(
817+
&ast,
818+
CompileInput {
819+
cell: &["top"],
820+
args: Vec::new(),
821+
lyp_file: &PathBuf::from(BASIC_LYP),
822+
},
823+
);
824+
println!("{cells:#?}");
825+
826+
let errors = cells.unwrap_static_errors();
827+
assert!(
828+
errors
829+
.errors
830+
.iter()
831+
.any(|e| matches!(e.kind, StaticErrorKind::UndeclaredVar))
832+
);
833+
}
784834
}

examples/cell_bad_arg_reuse/lib.ar

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cell square(size: Float) {
2+
let shape = rect("met1", x0=0., y0=0., x1=size, y1=size);
3+
}
4+
5+
cell top() {
6+
let sq = inst(square(100.));
7+
let shape = rect("met2", x0=0., y0=0., x1=200., y1=size);
8+
}

examples/func_bad_arg_reuse/lib.ar

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fn double(argument: Float) -> Float {
2+
if argument > 0.0 {
3+
let argument = argument;
4+
} else {
5+
let argument = -argument;
6+
};
7+
2. * argument
8+
}
9+
10+
cell top() {
11+
let shape = rect("met1");
12+
eq(shape.x0, 0.);
13+
eq(shape.y0, 0.);
14+
eq(shape.x1, double(100.));
15+
eq(shape.y1, argument);
16+
}

0 commit comments

Comments
 (0)