Skip to content

Commit

Permalink
fix(type_checker): const assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
JaDogg committed Jun 24, 2023
1 parent 2f97522 commit c29f99c
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
16 changes: 10 additions & 6 deletions compiler/src/compiler/type_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,16 +733,20 @@ void type_checker::visit_assign_arr_expr(assign_arr_expr *obj) {
}
void type_checker::handle_assigns(token *oper, const ykobject &lhs,
const ykobject &rhs) {
// TODO you can assign a const to a value?
// Both are primitive but not equal? then it is a problem
if ((lhs.is_primitive_or_obj() && rhs.is_primitive_or_obj()) &&
*lhs.datatype_ != *rhs.datatype_) {
error(oper, "Cannot assign between 2 different data types.");
}
if (lhs.datatype_->is_const()) { error(oper, "Cannot assign to a constant"); }
if (rhs.is_a_function() && !slot_match(rhs, lhs.datatype_)) {
error(oper, "You can only assign a function to a Function[In[?],Out[?]]");
}
if ((lhs.is_primitive_or_obj() && rhs.is_primitive_or_obj())) {
auto rhs_dt = rhs.datatype_;
if (rhs_dt->is_const()) {
rhs_dt = rhs.datatype_->args_[0];
}
if (*lhs.datatype_ != *rhs_dt) {
error(oper, "Cannot assign between 2 different data types.");
}
}

token_type operator_type = oper->type_;
switch (operator_type) {
case token_type::AND_EQ:
Expand Down
6 changes: 6 additions & 0 deletions compiler/test_data/bug_fixes/assign_const.yaka
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def main() -> int:
A: Const[int] = 1
a: int = 2
a = A
b: int = A
return a + b
34 changes: 24 additions & 10 deletions compiler/tests/test_type_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@
using namespace yaksha;
#define TEST_FILE(A, E) \
do { \
yaksha::errors::error_capture.clear(); \
multifile_compiler mc{}; \
auto result = mc.compile(A); \
REQUIRE(result.failed_ == true); \
REQUIRE(!yaksha::errors::error_capture.empty()); \
REQUIRE(yaksha::errors::has_error(E)); \
} while (0)
#define TEST_FILE_OK(A) \
do { \
yaksha::errors::error_capture.clear(); \
multifile_compiler mc{}; \
auto result = mc.compile(A); \
REQUIRE(result.failed_ == false); \
REQUIRE(yaksha::errors::error_capture.empty()); \
} while (0)
#define TEST_SNIPPET(S, E) \
do { \
yaksha::errors::error_capture.clear(); \
multifile_compiler mc{}; \
std::string xa = "def main() -> int:\n"; \
xa += " "; \
Expand All @@ -26,6 +36,7 @@ using namespace yaksha;
} while (0)
#define TEST_SNIPPET_FULL(S, E) \
do { \
yaksha::errors::error_capture.clear(); \
multifile_compiler mc{}; \
std::string xa = (S); \
auto result = mc.compile(xa, true, "dummy.yaka", "../libs"); \
Expand Down Expand Up @@ -467,26 +478,29 @@ TEST_CASE("type checker: non existent element access") {
"Cannot find data type of LHS");
}
TEST_CASE("type checker: ccode statement used outside non native function") {
TEST_SNIPPET_FULL("def main() -> int:\n"
" ccode \"\"\"int a = 1;\"\"\"\n"
" return 0",
"Invalid use of ccode statement outside non native function");
TEST_SNIPPET_FULL(
"def main() -> int:\n"
" ccode \"\"\"int a = 1;\"\"\"\n"
" return 0",
"Invalid use of ccode statement outside non native function");
}
TEST_CASE(
"type checker: argument must be a string literal for binarydata()") {
TEST_CASE("type checker: argument must be a string literal for binarydata()") {
TEST_SNIPPET("a: Ptr[Const[u8]] = binarydata(1)",
"Argument to binarydata() must be a str literal");
}
TEST_CASE(
"type checker: only 1 argument is allowed for binarydata()") {
TEST_CASE("type checker: only 1 argument is allowed for binarydata()") {
TEST_SNIPPET("a: Ptr[Const[u8]] = binarydata(1, 2, 3)",
"binarydata() builtin expects 1 argument");
}
TEST_CASE("type checker: Redefining variables in a function different data types") {
TEST_CASE(
"type checker: Redefining variables in a function different data types") {
TEST_FILE("../test_data/bug_fixes/redefining_vars.yaka",
"Redefining a variable is not allowed");
}
TEST_CASE("type checker: Redefining variables in a function - params") {
TEST_FILE("../test_data/bug_fixes/redefining_vars_params.yaka",
"Redefining a variable is not allowed");
}
}
TEST_CASE("type checker: Const assignment should work as expected") {
TEST_FILE_OK("../test_data/bug_fixes/assign_const.yaka");
}

0 comments on commit c29f99c

Please sign in to comment.