<commit_before>use ast::Program;

use error::ErrorCode;
use error::ParseError;

use lexer::position::Position;

use parser::Parser;

struct TypeCheck {
    program: Program,
}

impl TypeCheck {
    pub fn new(prog: Program) -> TypeCheck {
        TypeCheck { program: prog }
    }

    pub fn check(&self) -> Result<(), ParseError> {
        self.check_main()
    }

    fn check_main(&self) -> Result<(), ParseError> {
        let fct = self.program.get_function("main");

        if fct.is_none() {
            return Err(ParseError {
                position: Position::new(1, 1),
                message: "main not found".to_string(),
                code: ErrorCode::MainDefinition
            })
        }

        let fct = fct.unwrap();

        if !fct.type_params.empty() || fct.params.len() > 0 ||
            !fct.return_type.is_unit() {
            return Err(ParseError {
                position: fct.position,
                message: "definition of main not correct".to_string(),
                code: ErrorCode::MainDefinition
            })
        }

        Ok(())
    }
}


#[test]
fn test_main_undefined() {
    let prog = Parser::from_str("fn foo() {}").parse().unwrap();
    assert!(TypeCheck::new(prog).check().is_err());
}

#[test]
fn test_main_definition_invalid() {
    let prog = Parser::from_str("fn main(x:int) {}").parse().unwrap();
    assert!(TypeCheck::new(prog).check().is_err());
}

#[test]
fn test_main() {
    let prog = Parser::from_str("fn main() {}").parse().unwrap();
    assert!(TypeCheck::new(prog).check().is_ok());
}
<commit_msg>use own function in tests for type checking<commit_after>use ast::Program;

use error::ErrorCode;
use error::ParseError;

use lexer::position::Position;

use parser::Parser;

struct TypeCheck {
    program: Program,
}

impl TypeCheck {
    pub fn new(prog: Program) -> TypeCheck {
        TypeCheck { program: prog }
    }

    pub fn check(&self) -> Result<(), ParseError> {
        self.check_main()
    }

    fn check_main(&self) -> Result<(), ParseError> {
        let fct = self.program.get_function("main");

        if fct.is_none() {
            return Err(ParseError {
                position: Position::new(1, 1),
                message: "main not found".to_string(),
                code: ErrorCode::MainDefinition
            })
        }

        let fct = fct.unwrap();

        if !fct.type_params.empty() || fct.params.len() > 0 ||
            !fct.return_type.is_unit() {
            return Err(ParseError {
                position: fct.position,
                message: "definition of main not correct".to_string(),
                code: ErrorCode::MainDefinition
            })
        }

        Ok(())
    }
}

#[cfg(test)]
fn ck(code: &'static str) -> Result<(), ParseError> {
    let prog = Parser::from_str(code).parse().unwrap();

    TypeCheck::new(prog).check()
}

#[test]
fn test_main_undefined() {
    assert!(ck("fn foo() {}").is_err());
}

#[test]
fn test_main_definition_invalid() {
    assert!(ck("fn main(x:int) {}").is_err());
}

#[test]
fn test_main() {
    assert!(ck("fn main() {}").is_ok());
}

{'fraction_non_alphanumeric': 0.16404494382022472, 'fraction_numerical': 0.0019261637239165329, 'mean_word_length': 2.3832790445168297, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6560340', 'n_tokens_mistral': 1007, 'n_tokens_neox': 977, 'n_words': 205}