Boolean operators
This commit is contained in:
@@ -22,6 +22,11 @@ binary_test :: ()
|
|||||||
bit_or :: 1 | 4
|
bit_or :: 1 | 4
|
||||||
bit_xor :: 8 ^ 7
|
bit_xor :: 8 ^ 7
|
||||||
|
|
||||||
|
boolean_equals :: true == false
|
||||||
|
boolean_var: Bool = boolean_equals
|
||||||
|
|
||||||
|
bvar2 := int_val > 1
|
||||||
|
bvar3 := int_val < 1
|
||||||
|
|
||||||
|
|
||||||
basic_type_assignment :: ()
|
basic_type_assignment :: ()
|
||||||
|
|||||||
100
typecheck.cpp
100
typecheck.cpp
@@ -95,7 +95,28 @@ value_get_float(Value value){
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
function Value
|
function Value
|
||||||
eval_binary(Token *pos, Token_Kind op, Value a, Value b){
|
eval_binary(Token *pos, Token_Kind op, Value a, Value b){
|
||||||
if(!(is_numeric(a.type) && is_numeric(b.type))) parsing_error(pos, "Constant application of binary %s on values of type %s is not allowed", token_kind_string(op).str, docname(a.type));
|
if(!(is_numeric(a.type) && is_numeric(b.type))) parsing_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", token_kind_string(op).str, docname(a.type), docname(a.type));
|
||||||
|
|
||||||
|
// @warning: this bool path returns early, always should return untyped bool
|
||||||
|
if(is_bool(a.type) || is_bool(b.type)){
|
||||||
|
if(!is_bool(a.type)) parsing_error(pos, "Type mismatch in binary operation %s - left: %s right: %s", token_kind_string(op).str, docname(a.type), docname(b.type));
|
||||||
|
if(!is_bool(b.type)) parsing_error(pos, "Type mismatch in binary operation %s - left: %s right: %s", token_kind_string(op).str, docname(a.type), docname(b.type));
|
||||||
|
|
||||||
|
Value result;
|
||||||
|
result.type = untyped_bool;
|
||||||
|
switch(op){
|
||||||
|
case TK_And: result.bool_val = a.bool_val && b.bool_val; break;
|
||||||
|
case TK_Or: result.bool_val = a.bool_val || b.bool_val; break;
|
||||||
|
case TK_GreaterThen: result.bool_val = a.bool_val > b.bool_val; break;
|
||||||
|
case TK_GreaterThenOrEqual: result.bool_val = a.bool_val >= b.bool_val; break;
|
||||||
|
case TK_LesserThen: result.bool_val = a.bool_val < b.bool_val; break;
|
||||||
|
case TK_LesserThenOrEqual: result.bool_val = a.bool_val <= b.bool_val; break;
|
||||||
|
case TK_Equals: result.bool_val = a.bool_val == b.bool_val; break;
|
||||||
|
case TK_NotEquals: result.bool_val = a.bool_val != b.bool_val; break;
|
||||||
|
invalid_default_case;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Ast_Resolved_Type *final_type = 0;
|
Ast_Resolved_Type *final_type = 0;
|
||||||
Value before_conversion;
|
Value before_conversion;
|
||||||
@@ -123,7 +144,53 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b){
|
|||||||
F64 right_float = value_get_float(b);
|
F64 right_float = value_get_float(b);
|
||||||
// @WARNING: When introducing big ints & | ^ will be problematic
|
// @WARNING: When introducing big ints & | ^ will be problematic
|
||||||
|
|
||||||
|
Value c;
|
||||||
|
c.type = untyped_bool;
|
||||||
switch(op){
|
switch(op){
|
||||||
|
|
||||||
|
// @note: These return early, they don't need type evaluation
|
||||||
|
// always should return untyped bool
|
||||||
|
case TK_And: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int && right_int;
|
||||||
|
else c.bool_val = left_float && right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
case TK_Or: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int || right_int;
|
||||||
|
else c.bool_val = left_float || right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
case TK_GreaterThen: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int > right_int;
|
||||||
|
else c.bool_val = left_float > right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
case TK_GreaterThenOrEqual: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int >= right_int;
|
||||||
|
else c.bool_val = left_float >= right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
case TK_LesserThen: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int < right_int;
|
||||||
|
else c.bool_val = left_float < right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
case TK_LesserThenOrEqual: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int <= right_int;
|
||||||
|
else c.bool_val = left_float <= right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
case TK_Equals: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int == right_int;
|
||||||
|
else c.bool_val = left_float == right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
case TK_NotEquals: {
|
||||||
|
if(final_type == untyped_int) c.bool_val = left_int != right_int;
|
||||||
|
else c.bool_val = left_float != right_float;
|
||||||
|
return c;
|
||||||
|
}break;
|
||||||
|
|
||||||
case TK_Add: {
|
case TK_Add: {
|
||||||
left_int = left_int + right_int;
|
left_int = left_int + right_int;
|
||||||
left_float = left_float + right_float;
|
left_float = left_float + right_float;
|
||||||
@@ -156,7 +223,7 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b){
|
|||||||
left_int = left_int ^ right_int;
|
left_int = left_int ^ right_int;
|
||||||
if(before_conversion.type == untyped_float) parsing_error(pos, "%s cant be performed on [Untyped_Float]", token_kind_string(op).str);
|
if(before_conversion.type == untyped_float) parsing_error(pos, "%s cant be performed on [Untyped_Float]", token_kind_string(op).str);
|
||||||
} break;
|
} break;
|
||||||
invalid_default_case;
|
default: parsing_error(pos, "Binary operation %s is not allowed on types: left: %s right: %s", token_kind_string(op).str, docname(a.type), docname(b.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(before_conversion.type == untyped_float){
|
if(before_conversion.type == untyped_float){
|
||||||
@@ -711,35 +778,6 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
else if(token_is_compare(node->op)){
|
|
||||||
Operand left = resolve_expr(node->left);
|
|
||||||
Operand right = resolve_expr(node->right);
|
|
||||||
|
|
||||||
if(left.is_const && right.is_const){
|
|
||||||
if(result.type == type_int){
|
|
||||||
switch(node->op){
|
|
||||||
case TK_GreaterThen : result.bool_val = left.int_val > right.int_val; break;
|
|
||||||
case TK_GreaterThenOrEqual: result.bool_val = left.int_val >= right.int_val; break;
|
|
||||||
case TK_LesserThen : result.bool_val = left.int_val < right.int_val; break;
|
|
||||||
case TK_LesserThenOrEqual : result.bool_val = left.int_val <= right.int_val; break;
|
|
||||||
case TK_Equals : result.bool_val = left.int_val == right.int_val; break;
|
|
||||||
case TK_NotEquals : result.bool_val = left.int_val != right.int_val; break;
|
|
||||||
invalid_default_case;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else parsing_error(node->pos, "Arithmetic on type [%s] is not supported", type_names[result.type->kind]);
|
|
||||||
}
|
|
||||||
else if(left.type != right.type) {
|
|
||||||
parsing_error(node->pos, "Type mismatch in binary operation %s - left: %s right: %s", token_kind_string(node->op).str, docname(left.type), docname(right.type));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
result = operand_rvalue(left.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
else{
|
else{
|
||||||
Operand left = resolve_expr(node->left);
|
Operand left = resolve_expr(node->left);
|
||||||
|
|||||||
Reference in New Issue
Block a user