Skip to content

Commit

Permalink
methödss
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Jan 10, 2025
1 parent 6b69d52 commit 1042b14
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 120 deletions.
50 changes: 25 additions & 25 deletions compiler/build_cf_graph.jou
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def build_bool_to_int_conversion(
location: Location,
t: Type*,
) -> LocalVariable*:
assert is_integer_type(t)
assert t->is_integer_type()
result: LocalVariable* = add_local_var(st, t)

set1 = add_block(st)
Expand All @@ -167,39 +167,39 @@ def build_cast(
if obj->type == to:
return obj

if is_pointer_type(obj->type) and is_pointer_type(to):
if obj->type->is_pointer_type() and to->is_pointer_type():
result = add_local_var(st, to)
add_unary_op(st, location, CfInstructionKind::PtrCast, obj, result)
return result

if is_number_type(obj->type) and is_number_type(to):
if obj->type->is_number_type() and to->is_number_type():
result = add_local_var(st, to)
add_unary_op(st, location, CfInstructionKind::NumCast, obj, result)
return result

if is_number_type(obj->type) and obj->type->size_in_bits == 64 and is_pointer_type(to):
if obj->type->is_number_type() and obj->type->size_in_bits == 64 and to->is_pointer_type():
result = add_local_var(st, to)
add_unary_op(st, location, CfInstructionKind::Int64ToPtr, obj, result)
return result

if is_integer_type(obj->type) or to->kind == TypeKind::Enum:
if obj->type->is_integer_type() or to->kind == TypeKind::Enum:
i32var = add_local_var(st, intType)
result = add_local_var(st, to)
add_unary_op(st, location, CfInstructionKind::NumCast, obj, i32var)
add_unary_op(st, location, CfInstructionKind::Int32ToEnum, i32var, result)
return result

if obj->type->kind == TypeKind::Enum and is_integer_type(to):
if obj->type->kind == TypeKind::Enum and to->is_integer_type():
i32var = add_local_var(st, intType)
result = add_local_var(st, to)
add_unary_op(st, location, CfInstructionKind::EnumToInt32, obj, i32var)
add_unary_op(st, location, CfInstructionKind::NumCast, i32var, result)
return result

if obj->type == boolType and is_integer_type(to):
if obj->type == boolType and to->is_integer_type():
return build_bool_to_int_conversion(st, obj, location, to)

if is_pointer_type(obj->type) and is_integer_type(to) and to->size_in_bits == 64:
if obj->type->is_pointer_type() and to->is_integer_type() and to->size_in_bits == 64:
result = add_local_var(st, to)
add_unary_op(st, location, CfInstructionKind::PtrToInt64, obj, result)
return result
Expand Down Expand Up @@ -248,8 +248,8 @@ def build_binop(
result_type: Type*,
) -> LocalVariable*:
got_bools = lhs->type == boolType and rhs->type == boolType
got_numbers = is_number_type(lhs->type) and is_number_type(rhs->type)
got_pointers = is_pointer_type(lhs->type) and is_pointer_type(rhs->type)
got_numbers = lhs->type->is_number_type() and rhs->type->is_number_type()
got_pointers = lhs->type->is_pointer_type() and rhs->type->is_pointer_type()
assert got_bools or got_numbers or got_pointers

negate = False
Expand Down Expand Up @@ -316,7 +316,7 @@ def build_class_field_pointer(

for f = class_type->classdata.fields; f < &class_type->classdata.fields[class_type->classdata.nfields]; f++:
if strcmp(f->name, fieldname) == 0:
result = add_local_var(st, get_pointer_type(f->type))
result = add_local_var(st, f->type->pointer())

ins = CfInstruction{
location = location,
Expand All @@ -340,7 +340,7 @@ def build_class_field(
fieldname: byte*,
location: Location,
) -> LocalVariable*:
ptr = add_local_var(st, get_pointer_type(instance->type))
ptr = add_local_var(st, instance->type->pointer())
add_unary_op(st, location, CfInstructionKind::AddressOfLocalVar, instance, ptr)
field_ptr = build_class_field_pointer(st, ptr, fieldname, location)
field = add_local_var(st, field_ptr->type->value_type)
Expand All @@ -366,7 +366,7 @@ def build_increment_or_decrement(
assert addr->type->kind == TypeKind::Pointer
t = addr->type->value_type

if not is_integer_type(t) and not is_pointer_type(t):
if not t->is_integer_type() and not t->is_pointer_type():
msg: byte[500]
if diff == 1:
snprintf(msg, sizeof(msg), "cannot increment a value of type %s", t->name)
Expand All @@ -376,14 +376,14 @@ def build_increment_or_decrement(

old_value = add_local_var(st, t)
new_value = add_local_var(st, t)
if is_integer_type(t):
if t->is_integer_type():
diffvar = add_local_var(st, t)
else:
diffvar = add_local_var(st, intType)

add_constant(st, location, int_constant(diffvar->type, diff), diffvar)
add_unary_op(st, location, CfInstructionKind::PtrLoad, addr, old_value)
if is_number_type(t):
if t->is_number_type():
add_binary_op(st, location, CfInstructionKind::NumAdd, old_value, diffvar, new_value)
else:
add_binary_op(st, location, CfInstructionKind::PtrAddInt, old_value, diffvar, new_value)
Expand Down Expand Up @@ -464,7 +464,7 @@ def build_and_or(

def build_address_of_expression(st: State*, address_of_what: AstExpression*) -> LocalVariable*:
if address_of_what->kind == AstExpressionKind::GetVariable:
ptrtype = get_pointer_type(get_expr_types(st, address_of_what)->type)
ptrtype = get_expr_types(st, address_of_what)->type->pointer()
addr = add_local_var(st, ptrtype)

local_var = find_local_var_cf(st, address_of_what->varname)
Expand All @@ -483,7 +483,7 @@ def build_address_of_expression(st: State*, address_of_what: AstExpression*) ->
return addr

if address_of_what->kind == AstExpressionKind::Self:
ptrtype = get_pointer_type(get_expr_types(st, address_of_what)->type)
ptrtype = get_expr_types(st, address_of_what)->type->pointer()
addr = add_local_var(st, ptrtype)

local_var = find_local_var_cf(st, "self")
Expand Down Expand Up @@ -512,7 +512,7 @@ def build_address_of_expression(st: State*, address_of_what: AstExpression*) ->
assert ptr->type->kind == TypeKind::Pointer

index = build_expression(st, &address_of_what->operands[1])
assert is_integer_type(index->type)
assert index->type->is_integer_type()

result = add_local_var(st, ptr->type)
add_binary_op(st, address_of_what->location, CfInstructionKind::PtrAddInt, ptr, index, result)
Expand Down Expand Up @@ -556,9 +556,9 @@ def build_function_or_method_call(
}

if call->method_call_self != NULL:
if is_pointer_type(sig->argtypes[0]) and not call->uses_arrow_operator:
if sig->argtypes[0]->is_pointer_type() and not call->uses_arrow_operator:
ins.add_operand(build_address_of_expression(st, call->method_call_self))
elif (not is_pointer_type(sig->argtypes[0])) and call->uses_arrow_operator:
elif (not sig->argtypes[0]->is_pointer_type()) and call->uses_arrow_operator:
self_ptr = build_expression(st, call->method_call_self)
assert self_ptr->type->kind == TypeKind::Pointer

Expand Down Expand Up @@ -586,7 +586,7 @@ def build_function_or_method_call(

def build_instantiation(st: State*, type: Type*, inst: AstInstantiation*, location: Location) -> LocalVariable*:
instance = add_local_var(st, type)
instanceptr = add_local_var(st, get_pointer_type(type))
instanceptr = add_local_var(st, type->pointer())

add_unary_op(st, location, CfInstructionKind::AddressOfLocalVar, instance, instanceptr)
add_unary_op(st, location, CfInstructionKind::PtrMemsetToZero, instanceptr, NULL)
Expand All @@ -603,9 +603,9 @@ def build_array(st: State*, type: Type*, items: AstExpression*, location: Locati
assert type->kind == TypeKind::Array

arr = add_local_var(st, type)
arrptr = add_local_var(st, get_pointer_type(type))
arrptr = add_local_var(st, type->pointer())
add_unary_op(st, location, CfInstructionKind::AddressOfLocalVar, arr, arrptr)
first_item_ptr = add_local_var(st, get_pointer_type(type->array.item_type))
first_item_ptr = add_local_var(st, type->array.item_type->pointer())
add_unary_op(st, location, CfInstructionKind::PtrCast, arrptr, first_item_ptr)

for i = 0; i < type->array.len; i++:
Expand Down Expand Up @@ -896,8 +896,8 @@ def build_assert(st: State*, assert_location: Location, assertion: AstAssertion*
strcpy(argnames[2], "lineno")

argtypes: Type** = malloc(3 * sizeof(argtypes[0]))
argtypes[0] = get_pointer_type(byteType)
argtypes[1] = get_pointer_type(byteType)
argtypes[0] = byteType->pointer()
argtypes[1] = byteType->pointer()
argtypes[2] = intType

ins = CfInstruction{
Expand Down
3 changes: 2 additions & 1 deletion compiler/structs.jou
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def copy_constant(c: Constant) -> Constant:
return c

def int_constant(type: Type*, value: long) -> Constant:
assert is_integer_type(type)
assert type->is_integer_type()
return Constant{
kind = ConstantKind::Integer,
integer = IntegerConstant{
Expand All @@ -68,6 +68,7 @@ def int_constant(type: Type*, value: long) -> Constant:
}
}


class Signature:
name: byte[100] # Function or method name. For methods it does not include the name of the class.
nargs: int
Expand Down
40 changes: 20 additions & 20 deletions compiler/typecheck.jou
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,14 @@ def type_from_ast(ft: FileTypes*, asttype: AstType*) -> Type*:
if asttype->kind == AstTypeKind::Pointer:
if asttype->value_type->is_void():
return voidPtrType
return get_pointer_type(type_from_ast(ft, asttype->value_type))
return type_from_ast(ft, asttype->value_type)->pointer()

if asttype->kind == AstTypeKind::Array:
tmp = type_from_ast(ft, asttype->value_type)
len = evaluate_array_length(asttype->array.length)
if len <= 0:
fail(asttype->array.length->location, "array length must be positive")
return get_array_type(tmp, len)
return tmp->array_type(len)

assert False

Expand Down Expand Up @@ -228,11 +228,11 @@ def handle_signature(ft: FileTypes*, astsig: AstSignature*, self_class: Type*) -
and astsig->args[i].type.name[0] == '\0'
):
# just "self" without a type after it --> default to "self: Foo*" in class Foo
argtype = get_pointer_type(self_class)
argtype = self_class->pointer()
else:
argtype = type_from_ast(ft, &astsig->args[i].type)

if strcmp(sig.argnames[i], "self") == 0 and argtype != self_class and argtype != get_pointer_type(self_class):
if strcmp(sig.argnames[i], "self") == 0 and argtype != self_class and argtype != self_class->pointer():
snprintf(msg, sizeof(msg), "type of self must be %s* (default) or %s", self_class->name, self_class->name)
fail(astsig->args[i].type.location, msg)

Expand All @@ -255,7 +255,7 @@ def handle_signature(ft: FileTypes*, astsig: AstSignature*, self_class: Type*) -
and not (
sig.nargs == 2
and sig.argtypes[0] == intType
and sig.argtypes[1] == get_pointer_type(get_pointer_type(byteType))
and sig.argtypes[1] == byteType->pointer()->pointer()
)
):
fail(
Expand Down Expand Up @@ -614,7 +614,7 @@ def do_implicit_cast(

if (
types->expr->kind == AstExpressionKind::String
and from == get_pointer_type(byteType)
and from == byteType->pointer()
and to->kind == TypeKind::Array
and to->array.item_type == byteType
):
Expand All @@ -629,7 +629,7 @@ def do_implicit_cast(
fail_with_implicit_cast_error(location, errormsg_template, from, to)

types->implicit_cast_type = to
types->implicit_array_to_pointer_cast = (from->kind == TypeKind::Array and is_pointer_type(to))
types->implicit_array_to_pointer_cast = (from->kind == TypeKind::Array and to->is_pointer_type())

if types->implicit_array_to_pointer_cast:
ensure_can_take_address(
Expand All @@ -640,7 +640,7 @@ def do_implicit_cast(

def cast_array_to_pointer(fom: FunctionOrMethodTypes*, types: ExpressionTypes*) -> None:
assert types->type->kind == TypeKind::Array
do_implicit_cast(fom, types, get_pointer_type(types->type->array.item_type), Location{}, NULL)
do_implicit_cast(fom, types, types->type->array.item_type->pointer(), Location{}, NULL)

def do_explicit_cast(fom: FunctionOrMethodTypes*, types: ExpressionTypes*, to: Type*, location: Location) -> None:
assert types->implicit_cast_type == NULL
Expand All @@ -656,7 +656,7 @@ def do_explicit_cast(fom: FunctionOrMethodTypes*, types: ExpressionTypes*, to: T
snprintf(msg, sizeof(msg), "cannot cast from type %s to %s", from->name, to->name)
fail(location, msg)

if from->kind == TypeKind::Array and is_pointer_type(to):
if from->kind == TypeKind::Array and to->is_pointer_type():
cast_array_to_pointer(fom, types)

def typecheck_expression_not_void(ft: FileTypes*, expr: AstExpression*) -> ExpressionTypes*:
Expand Down Expand Up @@ -714,12 +714,12 @@ def check_binop(
assert False

got_bools = lhstypes->type == boolType and rhstypes->type == boolType
got_integers = is_integer_type(lhstypes->type) and is_integer_type(rhstypes->type)
got_numbers = is_number_type(lhstypes->type) and is_number_type(rhstypes->type)
got_integers = lhstypes->type->is_integer_type() and rhstypes->type->is_integer_type()
got_numbers = lhstypes->type->is_number_type() and rhstypes->type->is_number_type()
got_enums = lhstypes->type->kind == TypeKind::Enum and rhstypes->type->kind == TypeKind::Enum
got_pointers = (
is_pointer_type(lhstypes->type)
and is_pointer_type(rhstypes->type)
lhstypes->type->is_pointer_type()
and rhstypes->type->is_pointer_type()
and (
# Ban comparisons like int* == byte*, unless one of the two types is void*
lhstypes->type == rhstypes->type
Expand Down Expand Up @@ -811,7 +811,7 @@ def check_increment_or_decrement(ft: FileTypes*, expr: AstExpression*) -> Type*:
ensure_can_take_address(ft->current_fom_types, &expr->operands[0], bad_expr_fmt)

t = typecheck_expression_not_void(ft, &expr->operands[0])->type
if not is_integer_type(t) and not is_pointer_type(t):
if not t->is_integer_type() and not t->is_pointer_type():
msg: byte[500]
snprintf(msg, sizeof(msg), bad_type_fmt, t->name)
fail(expr->location, msg)
Expand Down Expand Up @@ -847,7 +847,7 @@ def typecheck_indexing(
assert ptrtype->kind == TypeKind::Pointer

indextypes = typecheck_expression_not_void(ft, indexexpr)
if not is_integer_type(indextypes->type):
if not indextypes->type->is_integer_type():
snprintf(msg, sizeof(msg), "the index inside [...] must be an integer, not %s", indextypes->type->name)
fail(indexexpr->location, msg)

Expand Down Expand Up @@ -962,7 +962,7 @@ def typecheck_function_or_method_call(ft: FileTypes*, call: AstCall*, self_type:
if types->type->kind == TypeKind::Array:
cast_array_to_pointer(ft->current_fom_types, types)
elif (
(is_integer_type(types->type) and types->type->size_in_bits < 32)
(types->type->is_integer_type() and types->type->size_in_bits < 32)
or types->type == boolType
):
# Add implicit cast to signed int, just like in C.
Expand Down Expand Up @@ -1120,7 +1120,7 @@ def typecheck_expression(ft: FileTypes*, expr: AstExpression*) -> ExpressionType
elif expr->kind == AstExpressionKind::Null:
result = voidPtrType
elif expr->kind == AstExpressionKind::String:
result = get_pointer_type(byteType)
result = byteType->pointer()

elif expr->kind == AstExpressionKind::GetEnumMember:
result = find_type(ft, expr->enum_member.enum_name)
Expand Down Expand Up @@ -1157,7 +1157,7 @@ def typecheck_expression(ft: FileTypes*, expr: AstExpression*) -> ExpressionType

membertype = cast_array_members_to_a_common_type(ft->current_fom_types, expr->location, exprtypes)
free(exprtypes)
result = get_array_type(membertype, n)
result = membertype->array_type(n)

elif expr->kind == AstExpressionKind::GetClassField:
if expr->class_field.uses_arrow_operator:
Expand Down Expand Up @@ -1201,7 +1201,7 @@ def typecheck_expression(ft: FileTypes*, expr: AstExpression*) -> ExpressionType
if strcmp(m->name, expr->call.name) != 0:
continue

if is_pointer_type(m->argtypes[0]):
if m->argtypes[0]->is_pointer_type():
assert strstr(expr->call.name, "%") == NULL
snprintf(
msg, sizeof msg,
Expand All @@ -1224,7 +1224,7 @@ def typecheck_expression(ft: FileTypes*, expr: AstExpression*) -> ExpressionType
elif expr->kind == AstExpressionKind::AddressOf:
ensure_can_take_address(ft->current_fom_types, &expr->operands[0], "the '&' operator cannot be used with %s")
temptype = typecheck_expression_not_void(ft, &expr->operands[0])->type
result = get_pointer_type(temptype)
result = temptype->pointer()

elif expr->kind == AstExpressionKind::GetVariable:
result = find_any_var(ft, expr->varname)
Expand Down
Loading

0 comments on commit 1042b14

Please sign in to comment.