diff --git a/boring/main.py b/boring/main.py index b847e68..ea9d739 100644 --- a/boring/main.py +++ b/boring/main.py @@ -2,6 +2,7 @@ import sys from typing import List from boring.parse import boring_parser, TreeToBoring, pretty_print from boring.type_checking import TypeChecker, Context +from boring.type_alias_resolution import TypeAliasResolver, Context as AliasContex from boring import typedefs, parse builtins = { @@ -28,6 +29,9 @@ if __name__ == "__main__": # print(tree) result = TreeToBoring().transform(tree) # pretty_print(result) + alias_resolver = TypeAliasResolver() + alias_resolver.with_module(AliasContex([]), result) + pretty_print(result) type_checker = TypeChecker() while type_checker.with_module(Context(builtins, None), result): print("loop") diff --git a/boring/parse.py b/boring/parse.py index 8ed1214..d8df141 100644 --- a/boring/parse.py +++ b/boring/parse.py @@ -173,13 +173,25 @@ class StructTypeDeclaration: fields: Dict[str, TypeUsage] -TypeDeclaration = Union[StructTypeDeclaration, PrimitiveTypeDeclaration] +@dataclass +class AliasTypeDeclaration: + new: DataTypeUsage + old: TypeUsage + + +TypeDeclaration = Union[StructTypeDeclaration, PrimitiveTypeDeclaration, AliasTypeDeclaration] + +@dataclass +class Impl: + struct: str + functions: List[Function] @dataclass class Module: functions: List[Function] types: List[TypeDeclaration] + impls: List[Impl] boring_grammar = r""" @@ -262,9 +274,14 @@ boring_grammar = r""" struct_type_declaration : "type" identifier "struct" "{" (struct_definition_field ",")* "}" - type_declaration : struct_type_declaration + type_alias_declaration : "type" identifier "=" type_usage ";" - module : (function|type_declaration)* + type_declaration : struct_type_declaration + | type_alias_declaration + + impl : "impl" identifier "{" function* "}" + + module : (function|type_declaration|impl)* %import common.CNAME %import common.SIGNED_INT @@ -447,19 +464,29 @@ class TreeToBoring(Transformer): fields = {key: value for (key, value) in struct_type_declaration[1:]} return StructTypeDeclaration(name=name, fields=fields) + def type_alias_declaration(self, type_alias_declaration) -> AliasTypeDeclaration: + (name, existing) = type_alias_declaration + return AliasTypeDeclaration(new=DataTypeUsage(name), old=type_alias_declaration) + def type_declaration(self, type_declaration): (type_declaration,) = type_declaration return type_declaration + def impl(self, impl) -> Impl: + return Impl(struct=impl[0], functions=impl[1:]) + def module(self, module_items) -> Module: functions = [] types = [] + impls = [] for item in module_items: if isinstance(item, Function): functions.append(item) + elif isinstance(item, Impl): + impls.append(item) else: types.append(item) - return Module(functions=functions, types=types) + return Module(functions=functions, types=types, impls=impls) boring_parser = Lark(boring_grammar, start="module", lexer="standard") diff --git a/boring/type_checking.py b/boring/type_checking.py index 39c71a4..28ac63c 100644 --- a/boring/type_checking.py +++ b/boring/type_checking.py @@ -97,7 +97,13 @@ class TypeChecker: assert_exists(ctx, field) for function in module.functions: ctx.environment[function.name] = function + changed = False + for impl in module.impls: + for function in impl.functions: + if self.with_function(ctx, function): + changed = True + for function in module.functions: if self.with_function(ctx, function): changed = True @@ -355,7 +361,7 @@ class TypeChecker: def with_literal_struct( self, ctx: Context, literal_struct: parse.LiteralStruct ) -> bool: - assert literal_struct.name in ctx.environment + assert literal_struct.name in ctx.environment, literal_struct.name struct_declaration = ctx.environment[literal_struct.name] assert isinstance(struct_declaration, parse.StructTypeDeclaration) changed = False diff --git a/examples/math/main.bl b/examples/math/main.bl index 24e48b9..6f48b44 100644 --- a/examples/math/main.bl +++ b/examples/math/main.bl @@ -48,3 +48,15 @@ fn get_user_id(): U64 { type User struct { id: U64, } + +impl User { + fn new(id: U64): Self { + return Self{ + id: id, + }; + } + + fn get_id(self: Self): U64 { + return self.id; + } +} diff --git a/notes.txt b/notes.txt index 7a11c61..a6a1898 100644 --- a/notes.txt +++ b/notes.txt @@ -42,7 +42,10 @@ TODO: * ~Literal~ * ~Getter~ * ~Setter~ +* ~Type Aliases~ * Methods + * ~Declaration~ + * Use * Traits * Generics * Enums @@ -51,3 +54,5 @@ TODO: * Lambdas * Async * Imports +* Visibility +* Const / Mut