Skip to content

Commit

Permalink
Misc refactoring to self-hosted compiler (#593)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Jan 10, 2025
1 parent fb0e840 commit baa063b
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 32 deletions.
2 changes: 1 addition & 1 deletion compiler/ast.jou
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ class AstIfStatement:
# for init; cond; incr:
# ...body...
class AstForLoop:
# init and incr must be pointers because this struct goes inside AstStatement.
# init and incr must be pointers because this goes inside AstStatement.
init: AstStatement*
cond: AstExpression
incr: AstStatement*
Expand Down
2 changes: 1 addition & 1 deletion compiler/cf_graph.jou
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Control Flow Graph.
# Struct names not prefixed with Cfg because it looks too much like "config" to me
# Class names not prefixed with Cfg because it looks too much like "config" to me

import "stdlib/mem.jou"
import "stdlib/io.jou"
Expand Down
4 changes: 2 additions & 2 deletions compiler/codegen.jou
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ def codegen_class_type(type: Type*) -> LLVMType*:

flat_elems: LLVMType** = malloc(sizeof(flat_elems[0]) * n)
for i = 0; i < n; i++:
# Treat all pointers inside structs as if they were void*.
# This allows structs to contain pointers to themselves.
# Treat all pointers inside classes as if they were void*.
# This allows classes to contain pointers to themselves.
if type->classdata.fields[i].type->kind == TypeKind::Pointer:
flat_elems[i] = codegen_type(voidPtrType)
else:
Expand Down
20 changes: 0 additions & 20 deletions compiler/typecheck/common.jou
Original file line number Diff line number Diff line change
Expand Up @@ -224,23 +224,3 @@ def type_from_ast(ft: FileTypes*, asttype: AstType*) -> Type*:
return tmp->array_type(len)

assert False


def short_type_description(t: Type*) -> byte*:
if t->kind == TypeKind::OpaqueClass or t->kind == TypeKind::Class:
return "a class"
if t->kind == TypeKind::Enum:
return "an enum"
if t->kind == TypeKind::VoidPointer or t->kind == TypeKind::Pointer:
return "a pointer type"
if (
t->kind == TypeKind::SignedInteger
or t->kind == TypeKind::UnsignedInteger
or t->kind == TypeKind::FloatingPoint
):
return "a number type"
if t->kind == TypeKind::Array:
return "an array type"
if t->kind == TypeKind::Bool:
return "the built-in bool type"
assert False
2 changes: 1 addition & 1 deletion compiler/typecheck/step1_create_types.jou
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def typecheck_step1_create_types(ft: FileTypes*, ast: AstFile*) -> ExportSymbol*
existing = ft->find_type(name)
if existing != NULL:
msg: byte[500]
snprintf(msg, sizeof(msg), "%s named '%s' already exists", short_type_description(existing), name)
snprintf(msg, sizeof(msg), "%s named '%s' already exists", existing->short_description(), name)
fail(stmt->location, msg)

ft->types = realloc(ft->types, sizeof(ft->types[0]) * (ft->ntypes + 1))
Expand Down
6 changes: 3 additions & 3 deletions compiler/typecheck/step2_populate_types.jou
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ def handle_signature(ft: FileTypes*, astsig: AstSignature*, self_class: Type*) -
return sig


def handle_class_members_step2(ft: FileTypes*, classdef: AstClassDef*) -> None:
# Previous type-checking step created an opaque struct.
def handle_class_members(ft: FileTypes*, classdef: AstClassDef*) -> None:
# Previous type-checking step created an opaque class.
type: Type* = NULL
for s = ft->owned_types; s < &ft->owned_types[ft->n_owned_types]; s++:
if strcmp((*s)->name, classdef->name) == 0:
Expand Down Expand Up @@ -194,7 +194,7 @@ def typecheck_step2_populate_types(ft: FileTypes*, ast: AstFile*) -> ExportSymbo
strcpy(es.name, sig.name)
exports[nexports++] = es
elif stmt->kind == AstStatementKind::Class:
handle_class_members_step2(ft, &stmt->classdef)
handle_class_members(ft, &stmt->classdef)
elif stmt->kind == AstStatementKind::Enum:
pass # Everything done in previous type-checking steps.
else:
Expand Down
6 changes: 3 additions & 3 deletions compiler/typecheck/step3_function_and_method_bodies.jou
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ def typecheck_function_or_method_call(ft: FileTypes*, call: AstCall*, self_type:
snprintf(
msg, sizeof(msg),
"type %s does not have any methods because it is %s, not a class",
self_type->name, short_type_description(self_type))
self_type->name, self_type->short_description())

fail(location, msg)

Expand Down Expand Up @@ -658,7 +658,7 @@ def typecheck_instantiation(ft: FileTypes*, inst: AstInstantiation*, location: L
snprintf(
msg, sizeof(msg),
"the %s{...} syntax is only for classes, but %s is %s",
t->name, t->name, short_type_description(t))
t->name, t->name, t->short_description())
fail(location, msg)

specified_fields: ClassField** = malloc(sizeof(specified_fields[0]) * inst->nfields)
Expand Down Expand Up @@ -789,7 +789,7 @@ def typecheck_expression(ft: FileTypes*, expr: AstExpression*) -> ExpressionType
msg, sizeof(msg),
"the '::' syntax is only for enums, but %s is %s",
expr->enum_member.enum_name,
short_type_description(result),
result->short_description(),
)
fail(expr->location, msg)
if not enum_member_exists(result, expr->enum_member.member_name):
Expand Down
21 changes: 20 additions & 1 deletion compiler/types.jou
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ enum TypeKind:
VoidPointer
Array
Class
OpaqueClass # class with unknown members. TODO when used?
OpaqueClass # class with unknown members, used temporarily during type checking
Enum

class Type:
Expand Down Expand Up @@ -88,6 +88,25 @@ class Type:
info->arrays[info->narrays++] = arr
return &arr->type

def short_description(self) -> byte*:
if self->kind == TypeKind::OpaqueClass or self->kind == TypeKind::Class:
return "a class"
if self->kind == TypeKind::Enum:
return "an enum"
if self->kind == TypeKind::VoidPointer or self->kind == TypeKind::Pointer:
return "a pointer type"
if (
self->kind == TypeKind::SignedInteger
or self->kind == TypeKind::UnsignedInteger
or self->kind == TypeKind::FloatingPoint
):
return "a number type"
if self->kind == TypeKind::Array:
return "an array type"
if self->kind == TypeKind::Bool:
return "the built-in bool type"
assert False

def find_method(self, name: byte*) -> Signature*:
if self->kind != TypeKind::Class:
return NULL
Expand Down

0 comments on commit baa063b

Please sign in to comment.