diff --git a/source/compiler/compiler/compiler.cpp b/source/compiler/compiler/compiler.cpp index d3aea9a2..5bc0ed75 100644 --- a/source/compiler/compiler/compiler.cpp +++ b/source/compiler/compiler/compiler.cpp @@ -37,7 +37,6 @@ namespace sigma { // backend // at this point we want to merge all frontend contexts into the backend context backend_context backend(frontend.syntax, m_description.target); - frontend.syntax.print_ast(); // run analysis on the generated AST TRY(type_checker::type_check(backend)); diff --git a/source/compiler/test/main.s b/source/compiler/test/main.s index f0227411..054ace5b 100644 --- a/source/compiler/test/main.s +++ b/source/compiler/test/main.s @@ -16,6 +16,6 @@ i32 main() { i32 a = 10; u64 b = 20; - bool res = a == b; + bool res = a && b; ret 0; } diff --git a/source/ir_translator/ir_translator.cpp b/source/ir_translator/ir_translator.cpp index 9830be08..b01639fc 100644 --- a/source/ir_translator/ir_translator.cpp +++ b/source/ir_translator/ir_translator.cpp @@ -37,6 +37,8 @@ namespace sigma { case ast::node_type::OPERATOR_NOT_EQUAL: case ast::node_type::OPERATOR_LESS_THAN: case ast::node_type::OPERATOR_EQUAL: return translate_binary_comparison_operator(ast_node); + case ast::node_type::OPERATOR_CONJUNCTION: + case ast::node_type::OPERATOR_DISJUNCTION: return translate_predicate_operator(ast_node); // statements case ast::node_type::RETURN: translate_return(ast_node); break; @@ -270,8 +272,6 @@ namespace sigma { // INTEGRAL_SIGNED || INTEGRAL_UNSIGNED const bool is_signed = expression.type == ast::comparison_expression::type::INTEGRAL_SIGNED; - std::cout << is_signed << '\n'; - switch (operator_node->type) { case ast::node_type::OPERATOR_GREATER_THAN_OR_EQUAL: return m_context.builder.create_cmp_ige(left, right, is_signed); case ast::node_type::OPERATOR_LESS_THAN_OR_EQUAL: return m_context.builder.create_cmp_ile(left, right, is_signed); @@ -283,7 +283,20 @@ namespace sigma { } } - return nullptr; + return nullptr; // unreachable + } + + auto ir_translator::translate_predicate_operator(handle operator_node) -> handle { + const handle left = translate_node(operator_node->children[0]); + const handle right = translate_node(operator_node->children[1]); + + switch(operator_node->type) { + case ast::node_type::OPERATOR_CONJUNCTION: return m_context.builder.create_and(left, right); + case ast::node_type::OPERATOR_DISJUNCTION: return m_context.builder.create_or(left, right); + default: PANIC("unexpected node type '{}' received", operator_node->type.to_string()); + } + + return nullptr; // unreachable } auto ir_translator::translate_cast(handle cast_node) -> handle { diff --git a/source/ir_translator/ir_translator.h b/source/ir_translator/ir_translator.h index 84d837ea..e2ab0527 100644 --- a/source/ir_translator/ir_translator.h +++ b/source/ir_translator/ir_translator.h @@ -28,6 +28,7 @@ namespace sigma { // expressions auto translate_binary_math_operator(handle operator_node) -> handle; auto translate_binary_comparison_operator(handle operator_node) -> handle; + auto translate_predicate_operator(handle operator_node) -> handle; // statements void translate_return(handle return_node); diff --git a/source/type_checker/type_checker.cpp b/source/type_checker/type_checker.cpp index b8a8afd8..7231a52f 100644 --- a/source/type_checker/type_checker.cpp +++ b/source/type_checker/type_checker.cpp @@ -45,6 +45,8 @@ namespace sigma { case ast::node_type::OPERATOR_NOT_EQUAL: case ast::node_type::OPERATOR_LESS_THAN: case ast::node_type::OPERATOR_EQUAL: return type_check_binary_comparison_operator(target); + case ast::node_type::OPERATOR_CONJUNCTION: + case ast::node_type::OPERATOR_DISJUNCTION: return type_check_predicate_operator(target); // statements case ast::node_type::RETURN: return type_check_return(target, expected); @@ -246,6 +248,14 @@ namespace sigma { return larger_type; } + auto type_checker::type_check_predicate_operator(ast_node binop) -> type_check_result { + // type check both operands + TRY(type_check_node(binop->children[0], binop, data_type::create_bool())); // left + TRY(type_check_node(binop->children[1], binop, data_type::create_bool())); // right + + return data_type::create_bool(); + } + auto type_checker::type_check_binary_comparison_operator(ast_node binop) -> type_check_result { // type check both operands TRY(const data_type left, type_check_node(binop->children[0], binop)); // left @@ -362,6 +372,8 @@ namespace sigma { return expression.type; } + + auto type_checker::type_check_character_literal(ast_node literal, ast_node parent, data_type expected) const -> type_check_result { auto& expression = literal->get(); TRY(expression.type, implicit_type_cast(expression.type, expected, parent, literal)); @@ -432,7 +444,7 @@ namespace sigma { target_type.to_string() ); - return original_type; + return target_type; } ASSERT(parent, "invalid parent detected"); diff --git a/source/type_checker/type_checker.h b/source/type_checker/type_checker.h index 10c608f5..cbd78691 100644 --- a/source/type_checker/type_checker.h +++ b/source/type_checker/type_checker.h @@ -46,6 +46,7 @@ namespace sigma { // expressions auto type_check_binary_math_operator(ast_node binop, data_type expected) -> type_check_result; auto type_check_binary_comparison_operator(ast_node binop) -> type_check_result; + auto type_check_predicate_operator(ast_node binop) -> type_check_result; // statements auto type_check_return(ast_node statement, data_type expected) -> type_check_result;