...
 
Commits (2)
use crate::ast::Program;
use crate::ast::Expr;
use crate::ast::Expr_;
use crate::ast::Program;
fn check_main(program: &Program) -> bool {
let mut has_main = false;
for expression in &program.stmts {
match &expression.node {
Expr_::Func {
......@@ -12,18 +12,61 @@ fn check_main(program: &Program) -> bool {
expr: _,
} => {
if identifier == "main" {
has_main = true
return true;
}
}
_ => {}
}
}
has_main
false
}
fn detect_collision(scope: &mut Vec<String>, identifier: &String) {
println!("identifier: {:?}", identifier);
match scope.iter().find(|&x| x == identifier) {
Some(_) => panic!(
"Error: identifier \"{}\" already declared. Aborting compilation.",
identifier
),
None => {}
}
scope.push(identifier.to_string());
}
fn identifiers_collision(program: &Vec<Expr>, mut scope: Vec<String>) {
for expression in program {
match &expression.node {
// if we encounter a function declaration /////////////////////////
Expr_::Func {
ident: identifier,
t: _,
args: _,
expr: func_expr,
} => {
detect_collision(&mut scope, &identifier);
let new_scope = scope.clone();
identifiers_collision(&func_expr, new_scope);
}
// if we encounter a variable declaration /////////////////////////
Expr_::Assign {
ident: identifier,
t: _,
expr: _,
} => {
detect_collision(&mut scope, &identifier);
}
_ => {}
}
}
eprintln!("available identifiers in current scope: {:?}", scope);
}
pub fn check_grammar(program: &Program) -> bool {
pub fn check_grammar(program: &Program) {
if !check_main(&program) {
panic!("No main function detected. Compilation aborted.");
}
true
let identifiers_scopes: Vec<String> = Vec::new();
identifiers_collision(&program.stmts, identifiers_scopes); // check for identifier collision
}
a: int = 10;
# Pseudo-python test file
def main() -> int {
a : float = .45;
......