added funciton declaration

This commit is contained in:
Andrew Segavac
2021-07-17 15:40:22 -06:00
parent 290646b8e2
commit 691009dd59
4 changed files with 50 additions and 43 deletions

View File

@@ -156,7 +156,14 @@ class VariableDeclaration:
class Function: class Function:
declaration: "FunctionDeclaration" declaration: "FunctionDeclaration"
block: Block block: Block
type: TypeUsage
@property
def type(self):
return self.declaration.type
@type.setter
def type(self, value):
self.declaration.type = value
@dataclass @dataclass
@@ -317,6 +324,7 @@ boring_grammar = r"""
type_declaration : struct_type_declaration type_declaration : struct_type_declaration
| type_alias_declaration | type_alias_declaration
| trait_declaration
impl : "impl" identifier "{" function* "}" impl : "impl" identifier "{" function* "}"
| "impl" identifier "for" identifier "{" function* "}" | "impl" identifier "for" identifier "{" function* "}"
@@ -470,22 +478,22 @@ class TreeToBoring(Transformer):
def function_declaration_without_return(self, fdwr) -> FunctionDeclaration: def function_declaration_without_return(self, fdwr) -> FunctionDeclaration:
return FunctionDeclaration( return FunctionDeclaration(
name=function[0], name=fdwr[0],
arguments=function[1:], arguments=fdwr[1:],
return_type=DataTypeUsage(name=UNIT_TYPE), return_type=DataTypeUsage(name=UNIT_TYPE),
type=FunctionTypeUsage( type=FunctionTypeUsage(
arguments=[arg.type for arg in function[1:]], arguments=[arg.type for arg in fdwr[1:]],
return_type=DataTypeUsage(name=UNIT_TYPE), return_type=DataTypeUsage(name=UNIT_TYPE),
), ),
) )
def function_declaration_with_return(self, fdwr) -> FunctionDeclaration: def function_declaration_with_return(self, fdwr) -> FunctionDeclaration:
return Function( return FunctionDeclaration(
name=function[0], name=fdwr[0],
arguments=function[1:-1], arguments=fdwr[1:-1],
return_type=function[-1], return_type=fdwr[-1],
type=FunctionTypeUsage( type=FunctionTypeUsage(
arguments=[arg.type for arg in function[1:-1]], return_type=function[-1] arguments=[arg.type for arg in fdwr[1:-1]], return_type=fdwr[-1]
), ),
) )
@@ -494,27 +502,9 @@ class TreeToBoring(Transformer):
assert isinstance(fd, FunctionDeclaration) assert isinstance(fd, FunctionDeclaration)
return fd return fd
def function(self, function) -> Function:
return Function(
declaration=function[0],
block=function[1],
type=UnknownTypeUsage(),
)
def function_with_return(self, function) -> Function:
return Function(
name=function[0],
arguments=function[1:-2],
return_type=function[-2],
block=function[-1],
type=FunctionTypeUsage(
arguments=[arg.type for arg in function[1:-2]], return_type=function[-2]
),
)
def function(self, function): def function(self, function):
(function,) = function (declaration, block) = function
return function return Function(declaration, block)
def struct_definition_field(self, struct_definition_field): def struct_definition_field(self, struct_definition_field):
(field, type_usage) = struct_definition_field (field, type_usage) = struct_definition_field

View File

@@ -67,10 +67,10 @@ class TypeAliasResolver:
return return
def with_function(self, ctx: Context, function: parse.Function): def with_function(self, ctx: Context, function: parse.Function):
for argument in function.arguments: for argument in function.declaration.arguments:
argument.type = process_type(ctx, argument.type) argument.type = process_type(ctx, argument.type)
function.return_type = process_type(ctx, function.return_type) function.declaration.return_type = process_type(ctx, function.declaration.return_type)
function.type = process_type(ctx, function.type) function.declaration.type = process_type(ctx, function.declaration.type)
self.with_block(ctx, function.block) self.with_block(ctx, function.block)
return return

View File

@@ -104,7 +104,7 @@ class TypeChecker:
for name, field in type_declaration.fields.items(): for name, field in type_declaration.fields.items():
assert_exists(ctx, field) assert_exists(ctx, field)
for function in module.functions: for function in module.functions:
ctx.environment[function.name] = function ctx.environment[function.declaration.name] = function
changed = False changed = False
for impl in module.impls: for impl in module.impls:
@@ -120,9 +120,9 @@ class TypeChecker:
def with_function(self, ctx: Context, function: parse.Function) -> bool: def with_function(self, ctx: Context, function: parse.Function) -> bool:
function_ctx = ctx.copy() function_ctx = ctx.copy()
function_ctx.current_function = function function_ctx.current_function = function
for argument in function.arguments: for argument in function.declaration.arguments:
function_ctx.environment[argument.name] = argument function_ctx.environment[argument.name] = argument
assert isinstance(function.type, parse.FunctionTypeUsage) assert isinstance(function.declaration.type, parse.FunctionTypeUsage)
changed = self.with_block(function_ctx, function.block) changed = self.with_block(function_ctx, function.block)
@@ -131,10 +131,10 @@ class TypeChecker:
and function.block.type.name == parse.NEVER_TYPE and function.block.type.name == parse.NEVER_TYPE
): ):
type, compare_changed = type_compare( type, compare_changed = type_compare(
function_ctx, function.block.type, function.type.return_type function_ctx, function.block.type, function.declaration.type.return_type
) )
function.block.type = type function.block.type = type
function.type.return_type = type function.declaration.type.return_type = type
if compare_changed is True: if compare_changed is True:
changed = True changed = True
return changed return changed
@@ -224,12 +224,12 @@ class TypeChecker:
and return_statement.source.type.name == parse.NEVER_TYPE and return_statement.source.type.name == parse.NEVER_TYPE
): ):
assert isinstance(ctx.current_function, parse.Function) assert isinstance(ctx.current_function, parse.Function)
assert isinstance(ctx.current_function.type, parse.FunctionTypeUsage) assert isinstance(ctx.current_function.declaration.type, parse.FunctionTypeUsage)
type, compare_changed = type_compare( type, compare_changed = type_compare(
ctx, return_statement.source.type, ctx.current_function.type.return_type ctx, return_statement.source.type, ctx.current_function.declaration.type.return_type
) )
return_statement.source.type = type return_statement.source.type = type
ctx.current_function.type.return_type = type ctx.current_function.declaration.type.return_type = type
if compare_changed is True: if compare_changed is True:
changed = True changed = True
return changed return changed
@@ -356,10 +356,10 @@ class TypeChecker:
found = False found = False
for impl in impls: for impl in impls:
for function in impl.functions: for function in impl.functions:
if function.name == struct_getter.attribute: if function.declaration.name == struct_getter.attribute:
assert isinstance(function.type, parse.FunctionTypeUsage) assert isinstance(function.declaration.type, parse.FunctionTypeUsage)
result_type, changed_getter = type_compare( result_type, changed_getter = type_compare(
ctx, struct_getter.type, function_to_method(function.type) ctx, struct_getter.type, function_to_method(function.declaration.type)
) )
found = True found = True
break break

View File

@@ -64,3 +64,20 @@ impl User {
return self.id; return self.id;
} }
} }
type TestTrait trait {
fn classMethod(id: I64): Self;
fn instanceMethod(self: Self): I64;
fn defaultImpl(self: Self): I64 {
return self.instanceMethod;
}
}
impl TestTrait for User {
fn classMethod(id: I64): Self {
return User{id: id,};
}
fn instanceMethod(self: Self): I64 {
return self.get_id();
}
}