Skip to content

Commit

Permalink
Phase2: Finish type checking and add three self defined test cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaredanwolfgang committed Dec 8, 2024
1 parent e4eaf2e commit fbf0138
Show file tree
Hide file tree
Showing 35 changed files with 615 additions and 585 deletions.
38 changes: 28 additions & 10 deletions src/analyser/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use thiserror::Error;
use std::fmt;
pub use SemanticError::*;

#[derive(Clone, Error, Debug)]
pub enum SemanticError {
Expand Down Expand Up @@ -34,36 +32,34 @@ pub enum SemanticError {
message: String,
line: usize,
},
#[error("[Semantic Error] Not Implemented Feature Error: {message:?}")]
#[error("[Semantic Error] Not Implemented Feature Error at line {line:?}: {message:?}")]
NotImplementedFeatureError{
message: String,
line: usize
},
#[error("System error: {0}")]
SystemError(String),

}

pub type Result<T, E = SemanticError> = core::result::Result<T, E>;

pub fn map_sys_err(e: std::io::Error) -> SemanticError {
SystemError(e.to_string())
}

pub struct SemanticErrorManager {
cnt: usize,
errors: Vec<SemanticError>,
line: usize,
}

impl SemanticErrorManager {
pub fn new() -> Self {
SemanticErrorManager {
cnt: 0,
errors: Vec::new(),
line: 0,
}
}

pub fn add_error(&mut self, error: SemanticError) {
pub fn add_error(&mut self, mut error: SemanticError) {
self.cnt += 1;
error.update_line(self.line);
self.errors.push(error);
}

Expand All @@ -74,4 +70,26 @@ impl SemanticErrorManager {
pub fn has_error(&self) -> bool {
!self.errors.is_empty()
}

pub fn update_line(&mut self) {
self.line += 1;
}

pub fn update_line_with_value(&mut self, value: usize) {
self.line = value;
}
}

impl SemanticError {
fn update_line(&mut self, line: usize) {
match self {
SemanticError::TypeError{line: ref mut l, ..} => *l = line,
SemanticError::ReferenceError{line: ref mut l, ..} => *l = line,
SemanticError::RedefinitionError{line: ref mut l, ..} => *l = line,
SemanticError::ImproperUsageError{line: ref mut l, ..} => *l = line,
SemanticError::ScopeError{line: ref mut l, ..} => *l = line,
SemanticError::NotImplementedFeatureError{line: ref mut l, ..} => *l = line,
_ => {}
}
}
}
6 changes: 1 addition & 5 deletions src/analyser/src/from.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
use std::borrow::Borrow;

use spl_ast::tree::{Value, Variable, CompExpr};
use crate::manager::SymbolManager;
use spl_ast::tree::Value;
use crate::symbol::*;
use crate::error::SemanticError;
use crate::typer::FuncRetType;

impl From<Value> for BasicType {
Expand Down
20 changes: 0 additions & 20 deletions src/analyser/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::symbol::*;
use crate::manager::SymbolManager;
use crate::error::{SemanticError, SemanticErrorManager};

impl<T> Symbol<T> {
pub fn new(id: i32, is_global: bool, identifier: String, symbol_type: T) -> Symbol<T>{
Expand Down Expand Up @@ -63,25 +62,6 @@ impl VarSymbol {
}
}

// From for FuncSymbol
impl FuncSymbol {
fn define(manager: &mut SymbolManager, identifier: String, return_type: BasicType, parameters: Vec<VarType>) -> FuncSymbol {
manager.new_func_symbol(identifier, (return_type, parameters), true)
}

fn get_return_type(&self) -> BasicType {
match &self.symbol_type {
(t, _) => t.clone(),
}
}

fn get_parameters(&self) -> Vec<VarType> {
match &self.symbol_type {
(_, p) => p.clone(),
}
}
}

impl PartialEq for VarType {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
Expand Down
53 changes: 10 additions & 43 deletions src/analyser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,65 +13,30 @@ pub mod manager;
mod tests {
use std::fs::File;
use std::io::Read;
use crate::symbol::{Symbol, VarType, BasicType, VarSymbol};
use spl_parser::parse;
use crate::table::ScopeTable;
use crate::stack::ScopeStack;
use crate::manager::SymbolManager;
use crate::walker::Walker;

fn parse_program(program: &str) -> ScopeStack {
let ast = parse(program).unwrap();
let manager = SymbolManager::default();
let mut walker = Walker::new(ast, manager);
walker.traverse();
walker.get_tables()
}

fn assert_analyze_from_file(file_path: &str, out_path: &str){
let mut src_content = String::new();
let mut src_file = File::open(file_path).expect("Unable to open file");
src_file.read_to_string(&mut src_content)
.expect("Unable to read file");

let mut out_content = String::new();
let mut out_file = File::open(out_path).expect("Unable to open file");
out_file.read_to_string(&mut out_content)
.expect("Unable to read file");
let expected = out_content.trim();

let ast = parse(&src_content).unwrap();
let manager = SymbolManager::default();
let mut walker = Walker::new(ast, manager);
let mut walker = Walker::new(file_path);

walker.traverse();
let table = walker.get_tables();
let _table = walker.get_tables();
let errors = walker.get_errors();
assert_eq!(
format!("{}", errors.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("\n")),
expected
);
}

fn test_scope_stack(){
let program = r#"
int main(){
int a = 0;
int b = 1;
if(a == 2){
int a = 1;
int b = 2;
}
}
"#;
let table = parse_program(program);
assert_eq!(format!("{}", table), "")
}

#[test]
fn test_phase2(){
for i in 1..15 {
if i == 6 || i == 10 || i == 13 {
for i in 1..16 {
if i == 6 {
continue;
}
let in_path = format!("../test/phase2/test_2_r{:0>2}.spl", i);
Expand All @@ -81,10 +46,12 @@ mod tests {
}

#[test]
fn test_specific(){
let in_path = "../test/phase2/test_2_r14.spl";
let out_path = "../test/phase2/test_2_r14.out";
assert_analyze_from_file(in_path, out_path);
fn test_self_defined(){
for i in 1..4 {
let in_path = format!("../test/phase2/self_def_s{:0>2}.spl", i);
let out_path = format!("../test/phase2/self_def_s{:0>2}.out", i);
assert_analyze_from_file(&in_path, &out_path);
}
}
}

Expand Down
5 changes: 0 additions & 5 deletions src/analyser/src/manager.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
use std::fmt::Display;

use crate::symbol::{FuncSymbol, Symbol, VarSymbol, FuncType, VarType};
use spl_ast::tree::Variable;
use spl_ast::tree::Function;
use crate::error::SemanticError;


#[derive(Default)]
Expand Down
3 changes: 1 addition & 2 deletions src/analyser/src/stack.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::table::ScopeTable;
use crate::symbol::{VarSymbol, FuncSymbol, VarType, StructType};
use std::process::id;
use crate::symbol::{VarSymbol, FuncSymbol, StructType};
use std::rc::Rc;
use std::cell::RefCell;
use crate::error::SemanticError;
Expand Down
Loading

0 comments on commit fbf0138

Please sign in to comment.