Check if functions are declared twice
This commit is contained in:
parent
af0eb6414a
commit
e1a0afba36
@ -23,8 +23,9 @@
|
||||
- [x] Parse function call parameters
|
||||
- [x] Codegen function call parameters
|
||||
- [x] Parse function declaration arguments (Type id)
|
||||
- [ ] Begin work on semantic analysis
|
||||
- [ ] Symbol table
|
||||
- [x] Begin work on semantic analysis
|
||||
- [x] Minimal symbol table
|
||||
- [x] Check duplicate function declarations
|
||||
- [ ] Typecheck bindings
|
||||
- [ ] Typecheck functions
|
||||
- [ ] Transform simple THP expression into PHP statements
|
||||
|
@ -116,11 +116,7 @@ fn get_line_number(chars: &Vec<char>, target_pos: usize) -> usize {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
error_handling::MistiError,
|
||||
lexic::get_tokens,
|
||||
syntax::construct_ast,
|
||||
};
|
||||
use crate::{error_handling::MistiError, lexic::get_tokens, syntax::construct_ast};
|
||||
|
||||
fn _get_error_data(input: String) -> (Vec<char>, MistiError) {
|
||||
let tokens = get_tokens(&input).unwrap();
|
||||
|
@ -62,7 +62,16 @@ fn build_ast(input: &String, tokens: Vec<Token>) -> String {
|
||||
let ast = syntax::construct_ast(&tokens);
|
||||
|
||||
match ast {
|
||||
Ok(ast) => codegen::codegen(&ast),
|
||||
Ok(ast) => {
|
||||
match crate::semantic::check_semantics(&ast) {
|
||||
Ok(_) => {}
|
||||
Err(reason) => {
|
||||
panic!("{}", reason)
|
||||
}
|
||||
};
|
||||
|
||||
codegen::codegen(&ast)
|
||||
}
|
||||
Err(reason) => {
|
||||
let chars: Vec<char> = input.chars().into_iter().collect();
|
||||
panic!("{}", reason.get_error_str(&chars))
|
||||
|
@ -30,6 +30,15 @@ fn build_ast(input: &String, tokens: Vec<Token>) {
|
||||
|
||||
match ast {
|
||||
Ok(ast) => {
|
||||
let res1 = crate::semantic::check_semantics(&ast);
|
||||
match res1 {
|
||||
Ok(_) => {}
|
||||
Err(reason) => {
|
||||
eprintln!("{}", reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let js_code = codegen::codegen(&ast);
|
||||
println!("{}", js_code)
|
||||
}
|
||||
|
39
src/semantic/impls.rs
Normal file
39
src/semantic/impls.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use crate::syntax::ast::{ModuleAST, TopLevelDeclaration};
|
||||
|
||||
use super::symbol_table::SymbolTable;
|
||||
|
||||
pub trait SemanticCheck {
|
||||
fn check_semantics(&self, scope: &SymbolTable) -> Result<(), String>;
|
||||
}
|
||||
|
||||
impl SemanticCheck for ModuleAST {
|
||||
fn check_semantics(&self, scope: &SymbolTable) -> Result<(), String> {
|
||||
for declaration in &self.declarations {
|
||||
declaration.check_semantics(scope)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SemanticCheck for TopLevelDeclaration {
|
||||
fn check_semantics(&self, scope: &SymbolTable) -> Result<(), String> {
|
||||
match self {
|
||||
TopLevelDeclaration::Binding(_) => Err("Binding not implemented".into()),
|
||||
TopLevelDeclaration::FunctionDeclaration(function) => {
|
||||
let function_name = function.identifier.as_ref().clone();
|
||||
|
||||
if scope.test(&function_name) {
|
||||
return Err(format!("Function {} already defined", function_name));
|
||||
}
|
||||
|
||||
scope.insert(
|
||||
function_name,
|
||||
super::symbol_table::SymbolEntry::Function(vec![], "Unit".into()),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,23 @@
|
||||
use crate::syntax::ast::ModuleAST;
|
||||
|
||||
mod impls;
|
||||
mod symbol_table;
|
||||
|
||||
use impls::SemanticCheck;
|
||||
|
||||
// What to do?
|
||||
// 1. Create a mutable symbol table
|
||||
// 2. Walk the AST
|
||||
// 3. Add the symbols declared to the symbol table, annotating them with their type
|
||||
// 4. Check if the symbols used are declared
|
||||
|
||||
pub fn check_semantics(ast: &ModuleAST) -> Result<(), String> {
|
||||
// For now there's only support for a single file
|
||||
let global_scope = symbol_table::SymbolTable::new();
|
||||
|
||||
ast.check_semantics(&global_scope)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::symbol_table::{SymbolEntry, SymbolTable};
|
||||
|
Loading…
Reference in New Issue
Block a user