Skip to content

Commit

Permalink
Signature methods
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Jan 10, 2025
1 parent 1042b14 commit 138de9d
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 87 deletions.
8 changes: 4 additions & 4 deletions compiler/build_cf_graph.jou
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ def build_function_or_method_call(
assert selfclass->kind == TypeKind::Class

for s = selfclass->classdata.methods; s < &selfclass->classdata.methods[selfclass->classdata.nmethods]; s++:
assert get_self_class(s) == selfclass
assert s->get_self_class() == selfclass
if strcmp(s->name, call->name) == 0:
sig = s
break
Expand All @@ -552,7 +552,7 @@ def build_function_or_method_call(
ins = CfInstruction{
location = location,
kind = CfInstructionKind::Call,
signature = copy_signature(sig),
signature = sig->copy(),
}

if call->method_call_self != NULL:
Expand Down Expand Up @@ -1093,13 +1093,13 @@ def build_function_or_method(

assert st->fomtypes == NULL
for f = st->filetypes->fomtypes; f < &st->filetypes->fomtypes[st->filetypes->nfomtypes]; f++:
if strcmp(f->signature.name, name) == 0 and get_self_class(&f->signature) == selfclass:
if strcmp(f->signature.name, name) == 0 and f->signature.get_self_class() == selfclass:
st->fomtypes = f
break
assert st->fomtypes != NULL

st->cfg = calloc(1, sizeof *st->cfg)
st->cfg->signature = copy_signature(&st->fomtypes->signature)
st->cfg->signature = st->fomtypes->signature.copy()

# Copy local variables over from type checking.
# Ownership of the variables changes, they will be freed when graphs are freed.
Expand Down
6 changes: 3 additions & 3 deletions compiler/cf_graph.jou
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ class CfInstruction:
printf("boolean negation of ")
self->operands[0]->print()
elif self->kind == CfInstructionKind::Call:
if get_self_class(&self->signature) != NULL:
printf("call method %s.", get_self_class(&self->signature)->name)
if self->signature.get_self_class() != NULL:
printf("call method %s.", self->signature.get_self_class()->name)
else:
printf("call function ")
printf("%s(", self->signature.name)
Expand Down Expand Up @@ -236,7 +236,7 @@ class CfGraph:
def print(self) -> None:
printed_varnames_idx = 0

sigstr: byte* = signature_to_string(&self->signature, True, True)
sigstr: byte* = self->signature.to_string(True, True)
printf("Function %s\n", sigstr)
free(sigstr)

Expand Down
6 changes: 3 additions & 3 deletions compiler/codegen.jou
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ class CodeGen:

def do_function_or_method_decl(self, sig: Signature*) -> LLVMValue*:
fullname: byte[200]
if get_self_class(sig) != NULL:
snprintf(fullname, sizeof fullname, "%s.%s", get_self_class(sig)->name, sig->name)
if sig->get_self_class() != NULL:
snprintf(fullname, sizeof fullname, "%s.%s", sig->get_self_class()->name, sig->name)
else:
assert sizeof(fullname) >= sizeof(sig->name)
assert sizeof(sig->name) > 50 # this is an array, not a pointer to dynamic length string
Expand Down Expand Up @@ -419,7 +419,7 @@ class CodeGen:
assert cfg->all_blocks[0] == &cfg->start_block
LLVMPositionBuilderAtEnd(self->builder, blocks[0])

if get_self_class(&cfg->signature) == NULL and strcmp(cfg->signature.name, "main") == 0:
if cfg->signature.get_self_class() == NULL and strcmp(cfg->signature.name, "main") == 0:
# Insert special code at start of main()
self->do_call_of_special_startup_func()

Expand Down
2 changes: 1 addition & 1 deletion compiler/main.jou
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class FileState:
self->types.functions = realloc(self->types.functions, sizeof(self->types.functions[0]) * (self->types.nfunctions + 1))
assert self->types.functions != NULL
self->types.functions[self->types.nfunctions++] = SignatureAndUsedPtr{
signature = copy_signature(&es->funcsignature),
signature = es->funcsignature.copy(),
usedptr = &imp->used,
}
elif es->kind == ExportSymbolKind::Type:
Expand Down
15 changes: 1 addition & 14 deletions compiler/structs.jou
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "stdlib/io.jou"

import "./ast.jou"
import "./types.jou"
import "./errors_and_warnings.jou"


class CommandLineArgs:
argv0: byte* # Program name
Expand Down Expand Up @@ -69,19 +69,6 @@ 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
argtypes: Type**
argnames: byte[100]*
takes_varargs: bool # true for functions like printf()
# TODO: rename to return_type
returntype: Type* # NULL, if does not return a value
is_noreturn: bool
# TODO: rename to return_type_location
returntype_location: Location # meaningful even if returntype is NULL


class GlobalVariable:
name: byte[100] # Same as in user's code, never empty
type: Type*
Expand Down
6 changes: 3 additions & 3 deletions compiler/typecheck.jou
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def handle_signature(ft: FileTypes*, astsig: AstSignature*, self_class: Type*) -
ft->functions = realloc(ft->functions, sizeof(ft->functions[0]) * (ft->nfunctions + 1))
assert ft->functions != NULL
ft->functions[ft->nfunctions++] = SignatureAndUsedPtr{
signature = copy_signature(&sig),
signature = sig.copy(),
usedptr = NULL,
}

Expand Down Expand Up @@ -928,7 +928,7 @@ def typecheck_function_or_method_call(ft: FileTypes*, call: AstCall*, self_type:
else:
function_or_method = "method"

sigstr = signature_to_string(sig, False, False)
sigstr = sig->to_string(False, False)

nargs = sig->nargs
if self_type != NULL:
Expand Down Expand Up @@ -1482,7 +1482,7 @@ def typecheck_function_or_method_body(ft: FileTypes*, sig: Signature*, body: Ast
ft->fomtypes[ft->nfomtypes++] = FunctionOrMethodTypes{}

ft->current_fom_types = &ft->fomtypes[ft->nfomtypes - 1]
ft->current_fom_types->signature = copy_signature(sig)
ft->current_fom_types->signature = sig->copy()

for i = 0; i < sig->nargs; i++:
v = add_variable(ft, sig->argtypes[i], sig->argnames[i])
Expand Down
129 changes: 70 additions & 59 deletions compiler/types.jou
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import "stdlib/mem.jou"
import "stdlib/str.jou"

import "./structs.jou"
import "./errors_and_warnings.jou"
import "./free.jou"

class ClassField:
Expand Down Expand Up @@ -243,71 +245,80 @@ def create_enum(name: byte*, membercount: int, membernames: byte[100]*) -> Type*
return &result->type


# TODO: move out
def get_self_class(sig: Signature*) -> Type*:
if sig->nargs > 0 and strcmp(sig->argnames[0], "self") == 0:
if sig->argtypes[0]->kind == TypeKind::Pointer:
return sig->argtypes[0]->value_type
if sig->argtypes[0]->kind == TypeKind::Class:
return sig->argtypes[0]
assert False
return NULL

# TODO: move out
def signature_to_string(sig: Signature*, include_return_type: bool, include_self: bool) -> byte*:
result = strdup(sig->name)
assert result != NULL

result = realloc(result, strlen(result) + 2)
assert result != NULL
strcat(result, "(")

for i = 0; i < sig->nargs; i++:
if strcmp(sig->argnames[i], "self") == 0 and not include_self:
continue
class Signature:
name: byte[100] # Function or method name. For methods it does not include the name of the class.
nargs: int
argtypes: Type**
argnames: byte[100]*
takes_varargs: bool # true for functions like printf()
# TODO: rename to return_type
returntype: Type* # NULL, if does not return a value
is_noreturn: bool
# TODO: rename to return_type_location
returntype_location: Location # meaningful even if returntype is NULL

def get_self_class(self) -> Type*:
if self->nargs > 0 and strcmp(self->argnames[0], "self") == 0:
if self->argtypes[0]->kind == TypeKind::Pointer:
return self->argtypes[0]->value_type
if self->argtypes[0]->kind == TypeKind::Class:
return self->argtypes[0]
assert False
return NULL

def to_string(self, include_return_type: bool, include_self: bool) -> byte*:
result = strdup(self->name)
assert result != NULL

assert sizeof sig->argnames[i] == 100
assert sizeof sig->argtypes[i]->name == 500
result = realloc(result, strlen(result) + 1000)
result = realloc(result, strlen(result) + 2)
assert result != NULL
strcat(result, sig->argnames[i])
strcat(result, ": ")
strcat(result, sig->argtypes[i]->name)
if i < sig->nargs - 1:
strcat(result, ", ")

result = realloc(result, strlen(result) + 100)
assert result != NULL

if sig->takes_varargs:
if sig->nargs != 0:
strcat(result, ", ")
strcat(result, "...")
strcat(result, ")")

if include_return_type:
assert sizeof(sig->returntype->name) == 500
result = realloc(result, strlen(result) + 600)
strcat(result, "(")

for i = 0; i < self->nargs; i++:
if strcmp(self->argnames[i], "self") == 0 and not include_self:
continue

assert sizeof self->argnames[i] == 100
assert sizeof self->argtypes[i]->name == 500
result = realloc(result, strlen(result) + 1000)
assert result != NULL
strcat(result, self->argnames[i])
strcat(result, ": ")
strcat(result, self->argtypes[i]->name)
if i < self->nargs - 1:
strcat(result, ", ")

result = realloc(result, strlen(result) + 100)
assert result != NULL

strcat(result, " -> ")
if sig->is_noreturn:
strcat(result, "noreturn")
elif sig->returntype == NULL:
strcat(result, "void")
else:
strcat(result, sig->returntype->name)
if self->takes_varargs:
if self->nargs != 0:
strcat(result, ", ")
strcat(result, "...")
strcat(result, ")")

return result
if include_return_type:
assert sizeof(self->returntype->name) == 500
result = realloc(result, strlen(result) + 600)
assert result != NULL

# TODO: move out
def copy_signature(sig: Signature*) -> Signature:
result = *sig
strcat(result, " -> ")
if self->is_noreturn:
strcat(result, "noreturn")
elif self->returntype == NULL:
strcat(result, "void")
else:
strcat(result, self->returntype->name)

return result

def copy(self) -> Signature:
result = *self

result.argtypes = malloc(sizeof(result.argtypes[0]) * result.nargs)
memcpy(result.argtypes, sig->argtypes, sizeof(result.argtypes[0]) * result.nargs)
result.argtypes = malloc(sizeof(result.argtypes[0]) * result.nargs)
memcpy(result.argtypes, self->argtypes, sizeof(result.argtypes[0]) * result.nargs)

result.argnames = malloc(sizeof(result.argnames[0]) * result.nargs)
memcpy(result.argnames, sig->argnames, sizeof(result.argnames[0]) * result.nargs)
result.argnames = malloc(sizeof(result.argnames[0]) * result.nargs)
memcpy(result.argnames, self->argnames, sizeof(result.argnames[0]) * result.nargs)

return result
return result

0 comments on commit 138de9d

Please sign in to comment.