Skip to content

Commit

Permalink
Added ability to revert implicit type conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
loumadev committed Nov 29, 2023
1 parent 38371cd commit bb5ea0f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 16 deletions.
2 changes: 2 additions & 0 deletions include/compiler/parser/ASTNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ typedef struct LiteralExpressionASTNode {
enum ASTNodeType _type;
union TokenValue value;
struct ValueType type;
union TokenValue originalValue;
struct ValueType originalType;
} LiteralExpressionASTNode;

typedef struct InterpolationExpressionASTNode {
Expand Down
22 changes: 14 additions & 8 deletions src/compiler/analyser/Analyser.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,11 +933,17 @@ AnalyserResult Analyser_resolveExpressionType(Analyser *analyser, ExpressionASTN
LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)node;

// Can only retype int literals to double
if(prefferedType.type == TYPE_DOUBLE && literal->type.type == TYPE_INT) {
literal->value.floating = (double)literal->value.integer;
if(prefferedType.type == TYPE_DOUBLE && literal->originalType.type == TYPE_INT) {
literal->value.floating = (double)literal->originalValue.integer;
literal->type.type = TYPE_DOUBLE;
}

// Revert implicit type conversions
if(prefferedType.type == TYPE_INT && literal->originalType.type == TYPE_INT) {
literal->value = literal->originalValue;
literal->type = literal->originalType;
}

*outType = literal->type;
} break;

Expand Down Expand Up @@ -1326,21 +1332,21 @@ AnalyserResult Analyser_resolveExpressionType(Analyser *analyser, ExpressionASTN
binary->left->_type == NODE_LITERAL_EXPRESSION &&
leftType.type == TYPE_INT && rightType.type == TYPE_DOUBLE
) {
LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)binary->left;
// LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)binary->left;

literal->value.floating = (double)literal->value.integer;
literal->type.type = TYPE_DOUBLE;
// literal->value.floating = (double)literal->value.integer;
// literal->type.type = TYPE_DOUBLE;

binary->type.type = TYPE_DOUBLE;
} else if(
binary->operator != OPERATOR_DIV &&
binary->right->_type == NODE_LITERAL_EXPRESSION &&
leftType.type == TYPE_DOUBLE && rightType.type == TYPE_INT
) {
LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)binary->right;
// LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)binary->right;

literal->value.floating = (double)literal->value.integer;
literal->type.type = TYPE_DOUBLE;
// literal->value.floating = (double)literal->value.integer;
// literal->type.type = TYPE_DOUBLE;

binary->type.type = TYPE_DOUBLE;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/parser/ASTNodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ LiteralExpressionASTNode* new_LiteralExpressionASTNode(
prepare_node_of(LiteralExpressionASTNode, NODE_LITERAL_EXPRESSION)
node->type = type;
node->value = value;
node->originalType = type;
node->originalValue = value;
return node;
}

Expand Down
76 changes: 68 additions & 8 deletions test/compiler/analyser/Analyser.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3720,17 +3720,17 @@ DESCRIBE(return_reachability, "Return reachability analysis") {
}

DESCRIBE(type_conversion, "Implicit type conversion") {
// Lexer lexer;
// Lexer_constructor(&lexer);
Lexer lexer;
Lexer_constructor(&lexer);

// Parser parser;
// Parser_constructor(&parser, &lexer);
Parser parser;
Parser_constructor(&parser, &lexer);

// Analyser analyser;
// Analyser_constructor(&analyser);
Analyser analyser;
Analyser_constructor(&analyser);

// ParserResult parserResult;
// AnalyserResult analyserResult;
ParserResult parserResult;
AnalyserResult analyserResult;

// TEST_BEGIN("Conversion of literals inside a complex expression") {
// Lexer_setSource(
Expand All @@ -3743,6 +3743,66 @@ DESCRIBE(type_conversion, "Implicit type conversion") {
// analyserResult = Analyser_analyse(&analyser, (ProgramASTNode*)parserResult.node);
// EXPECT_TRUE(analyserResult.success);
// } TEST_END();

TEST_BEGIN("Conversion of literals inside a complex expression") {
Lexer_setSource(
&lexer,
"var a: Double = 5" LF
);
parserResult = Parser_parse(&parser);
EXPECT_TRUE(parserResult.success);

analyserResult = Analyser_analyse(&analyser, (ProgramASTNode*)parserResult.node);
EXPECT_TRUE(analyserResult.success);

EXPECT_STATEMENTS(parserResult.node, 1 + FUNCTIONS_COUNT);

VariableDeclaration *var = Analyser_getVariableByName(&analyser, "a", analyser.globalScope);
EXPECT_NOT_NULL(var);

LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)var->node->initializer;
EXPECT_NOT_NULL(literal);
EXPECT_TRUE(literal->_type == NODE_LITERAL_EXPRESSION);

EXPECT_TRUE(literal->type.type == TYPE_DOUBLE);
EXPECT_EQUAL_FLOAT(literal->value.floating, 5);
} TEST_END();

TEST_BEGIN("Conversion of literals inside a complex expression") {
Lexer_setSource(
&lexer,
"var a: Double = 5.5" LF
);
parserResult = Parser_parse(&parser);
EXPECT_TRUE(parserResult.success);

analyserResult = Analyser_analyse(&analyser, (ProgramASTNode*)parserResult.node);
EXPECT_TRUE(analyserResult.success);

EXPECT_STATEMENTS(parserResult.node, 1 + FUNCTIONS_COUNT);

VariableDeclaration *var = Analyser_getVariableByName(&analyser, "a", analyser.globalScope);
EXPECT_NOT_NULL(var);

LiteralExpressionASTNode *literal = (LiteralExpressionASTNode*)var->node->initializer;
EXPECT_NOT_NULL(literal);
EXPECT_TRUE(literal->_type == NODE_LITERAL_EXPRESSION);

EXPECT_TRUE(literal->type.type == TYPE_DOUBLE);
EXPECT_EQUAL_FLOAT(literal->value.floating, 5.5);
} TEST_END();

TEST_BEGIN("Conversion of literals inside a complex expression") {
Lexer_setSource(
&lexer,
"var a: Int = 5.5" LF
);
parserResult = Parser_parse(&parser);
EXPECT_TRUE(parserResult.success);

analyserResult = Analyser_analyse(&analyser, (ProgramASTNode*)parserResult.node);
EXPECT_FALSE(analyserResult.success);
} TEST_END();
}

DESCRIBE(str_interp_analysis, "String interpolation analysis") {
Expand Down

0 comments on commit bb5ea0f

Please sign in to comment.