Skip to content

Commit

Permalink
fixed everything
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Jan 15, 2025
1 parent e9c10ee commit 9df460e
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 100 deletions.
127 changes: 38 additions & 89 deletions compiler/typecheck/step3_function_and_method_bodies.jou
Original file line number Diff line number Diff line change
Expand Up @@ -869,108 +869,57 @@ def typecheck_expression(ft: FileTypes*, expr: AstExpression*) -> None:
case AstExpressionKind.GetClassField:
if expr->class_field.uses_arrow_operator:
temptype = typecheck_expression_not_void(ft, expr->class_field.instance)
match temptype->kind:
case TypeKind.Class:
snprintf(
msg, sizeof(msg),
"left side of '.' operator must be a pointer to an instance of a class, not %s (try . instead of ->)",
temptype->name)
fail(expr->location, msg)
case TypeKind.Pointer:
if temptype->value_type->kind != TypeKind.Class:
snprintf(
msg, sizeof(msg),
"left side of the '->' operator must be a pointer to an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
case _:
snprintf(
msg, sizeof(msg),
"left side of the '->' operator must be a pointer to an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
# if temptype->kind == TypeKind.Class and strlen(msg) + 50 < sizeof(msg):
# strcat(msg, " (try . instead of ->)")
if temptype->kind != TypeKind.Pointer or temptype->value_type->kind != TypeKind.Class:
snprintf(
msg, sizeof(msg),
"left side of '->' operator must be a pointer to an instance of a class, not %s",
temptype->name)
if temptype->kind == TypeKind.Class and strlen(msg) + 50 < sizeof(msg):
strcat(msg, " (try . instead of ->)")
fail(expr->location, msg)
result = typecheck_class_field(temptype->value_type, expr->class_field.field_name, expr->location)->type
else:
temptype = typecheck_expression_not_void(ft, expr->class_field.instance)
match temptype->kind:
case TypeKind.Class:
pass
case TypeKind.Pointer:
if temptype->value_type->kind == TypeKind.Class:
snprintf(
msg, sizeof(msg),
"left side of '.' operator must be an instance of a class, not %s (try -> instead of .)",
temptype->name)
fail(expr->location, msg)
else:
snprintf(
msg, sizeof(msg),
"left side of the '.' operator must be an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
case _:
snprintf(
msg, sizeof(msg),
"left side of the '.' operator must be an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
# if (
# temptype->kind == TypeKind.Pointer
# and temptype->value_type->kind == TypeKind.Class
# and strlen(msg) + 50 < sizeof(msg)
# ):
# strcat(msg, " (try -> instead of .)")
if temptype->kind != TypeKind.Class:
snprintf(
msg, sizeof(msg),
"left side of '.' operator must be an instance of a class, not %s",
temptype->name)
if (
temptype->kind == TypeKind.Pointer
and temptype->value_type->kind == TypeKind.Class
and strlen(msg) + 50 < sizeof(msg)
):
strcat(msg, " (try -> instead of .)")
fail(expr->location, msg)
result = typecheck_class_field(temptype, expr->class_field.field_name, expr->location)->type

case AstExpressionKind.Call:
if expr->call.method_call_self == NULL:
result = typecheck_function_or_method_call(ft, &expr->call, NULL, expr->location)
elif expr->call.uses_arrow_operator:
temptype = typecheck_expression_not_void(ft, expr->call.method_call_self)
match temptype->kind:
case TypeKind.Pointer:
if temptype->value_type->kind != TypeKind.Class:
snprintf(msg, sizeof(msg),
"left side of the '->' operator must be a pointer to an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
case TypeKind.Class:
snprintf(msg, sizeof(msg),
"left side of '.' operator must be a pointer to an instance of a class, not %s (try . instead of ->)",
temptype->name)
fail(expr->location, msg)
case _:
snprintf(msg, sizeof(msg),
"left side of the '->' operator must be a pointer to an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
# if temptype->kind == TypeKind.Class and strlen(msg) + 50 < sizeof(msg):
# strcat(msg, " (try . instead of ->)")
# fail(expr->location, msg)
if temptype->kind != TypeKind.Pointer or temptype->value_type->kind != TypeKind.Class:
snprintf(msg, sizeof(msg),
"left side of '->' operator must be a pointer to an instance of a class, not %s",
temptype->name)
if temptype->kind == TypeKind.Class and strlen(msg) + 50 < sizeof(msg):
strcat(msg, " (try . instead of ->)")
fail(expr->location, msg)
result = typecheck_function_or_method_call(ft, &expr->call, temptype->value_type, expr->location)
else:
temptype = typecheck_expression_not_void(ft, expr->call.method_call_self)
match temptype->kind:
case TypeKind.Pointer:
if temptype->value_type->kind == TypeKind.Class:
snprintf(msg, sizeof(msg),
"left side of the '.' operator must be an instance of a class, not %s (try -> instead of .)",
temptype->name)
fail(expr->location, msg)
else:
snprintf(msg, sizeof(msg),
"left side of the '.' operator must be an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
case TypeKind.Class:
pass
case _:
snprintf(msg, sizeof(msg),
"left side of the '.' operator must be an instance of a class, not %s",
temptype->name)
fail(expr->location, msg)
if temptype->kind != TypeKind.Class:
snprintf(msg, sizeof(msg),
"left side of '.' operator must be an instance of a class, not %s",
temptype->name)
if (
temptype->kind == TypeKind.Pointer
and temptype->value_type->kind == TypeKind.Class
and strlen(msg) + 50 < sizeof(msg)
):
strcat(msg, " (try -> instead of .)")
fail(expr->location, msg)

result = typecheck_function_or_method_call(ft, &expr->call, temptype, expr->location)

Expand Down
2 changes: 1 addition & 1 deletion tests/wrong_type/arrow_instead_of_dot.jou
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ class Foo:

def blah() -> None:
f = Foo{}
f->n++ # Error: left side of '.' operator must be a pointer to an instance of a class, not Foo (try . instead of ->)
f->n++ # Error: left side of '->' operator must be a pointer to an instance of a class, not Foo (try . instead of ->)
2 changes: 1 addition & 1 deletion tests/wrong_type/arrow_instead_of_dot_call.jou
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ class Foo:

def blah() -> None:
f = Foo{}
f->do_stuff() # Error: left side of '.' operator must be a pointer to an instance of a class, not Foo (try . instead of ->)
f->do_stuff() # Error: left side of '->' operator must be a pointer to an instance of a class, not Foo (try . instead of ->)
2 changes: 1 addition & 1 deletion tests/wrong_type/arrow_operator_int.jou
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
def foo() -> None:
num = 1
x = num->lol # Error: left side of the '->' operator must be a pointer to an instance of a class, not int
x = num->lol # Error: left side of '->' operator must be a pointer to an instance of a class, not int
2 changes: 1 addition & 1 deletion tests/wrong_type/arrow_operator_int_call.jou
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
def foo() -> None:
num = 1
x = num->lol() # Error: left side of the '->' operator must be a pointer to an instance of a class, not int
x = num->lol() # Error: left side of '->' operator must be a pointer to an instance of a class, not int
2 changes: 1 addition & 1 deletion tests/wrong_type/arrow_operator_intptr.jou
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def foo() -> None:
num = 1
pointer = &num
x = pointer->lol # Error: left side of the '->' operator must be a pointer to an instance of a class, not int*
x = pointer->lol # Error: left side of '->' operator must be a pointer to an instance of a class, not int*
2 changes: 1 addition & 1 deletion tests/wrong_type/arrow_operator_intptr_call.jou
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def foo() -> None:
num = 1
pointer = &num
x = pointer->lol() # Error: left side of the '->' operator must be a pointer to an instance of a class, not int*
x = pointer->lol() # Error: left side of '->' operator must be a pointer to an instance of a class, not int*
2 changes: 1 addition & 1 deletion tests/wrong_type/dot_instead_of_arrow_call.jou
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ class Foo:


def blah(ptr: Foo*) -> None:
ptr.foo() # Error: left side of the '.' operator must be an instance of a class, not Foo* (try -> instead of .)
ptr.foo() # Error: left side of '.' operator must be an instance of a class, not Foo* (try -> instead of .)
2 changes: 1 addition & 1 deletion tests/wrong_type/dot_operator_int.jou
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
def foo() -> None:
x = 123
y = x.lolwat # Error: left side of the '.' operator must be an instance of a class, not int
y = x.lolwat # Error: left side of '.' operator must be an instance of a class, not int
2 changes: 1 addition & 1 deletion tests/wrong_type/dot_operator_int_call.jou
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
def foo() -> None:
x = 123
y = x.lolwat() # Error: left side of the '.' operator must be an instance of a class, not int
y = x.lolwat() # Error: left side of '.' operator must be an instance of a class, not int
2 changes: 1 addition & 1 deletion tests/wrong_type/dot_operator_intptr.jou
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def foo() -> None:
x = 123
y = &x
z = y.lolwat # Error: left side of the '.' operator must be an instance of a class, not int*
z = y.lolwat # Error: left side of '.' operator must be an instance of a class, not int*
2 changes: 1 addition & 1 deletion tests/wrong_type/dot_operator_intptr_call.jou
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def foo() -> None:
x = 123
y = &x
z = y.lolwat() # Error: left side of the '.' operator must be an instance of a class, not int*
z = y.lolwat() # Error: left side of '.' operator must be an instance of a class, not int*

0 comments on commit 9df460e

Please sign in to comment.