From 2ea1ccb0e90be9765279a8ee4bb8ce66c107c113 Mon Sep 17 00:00:00 2001 From: Andrew Segavac Date: Tue, 1 Jun 2021 23:05:17 -0600 Subject: [PATCH] added normal assignment --- boring/parse.py | 20 +++++++++++++++++++- boring/type_checking.py | 19 +++++++++++++++++-- examples/math/main.bl | 1 + notes.txt | 7 ++++++- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/boring/parse.py b/boring/parse.py index 7c9aa50..9902691 100644 --- a/boring/parse.py +++ b/boring/parse.py @@ -109,7 +109,14 @@ class LetStatement: expression: Expression -Statement = Union[LetStatement, Expression] +@dataclass +class AssignmentStatement: + variable_name: str + type: TypeUsage + expression: Expression + + +Statement = Union[LetStatement, AssignmentStatement, Expression] @dataclass @@ -177,7 +184,10 @@ boring_grammar = r""" let_statement : "let" identifier "=" expression ";" | "let" identifier ":" type_usage "=" expression ";" + assignment_statement : identifier "=" expression ";" + statement : let_statement + | assignment_statement | return_statement | expression @@ -298,6 +308,14 @@ class TreeToBoring(Transformer): expression=expression, ) + def assignment_statement(self, assignment_statement) -> AssignmentStatement: + (variable_name, expression) = assignment_statement + return AssignmentStatement( + variable_name=variable_name, + type=UnknownTypeUsage(), + expression=expression, + ) + def statement(self, statement): (statement,) = statement return statement diff --git a/boring/type_checking.py b/boring/type_checking.py index 6ed5237..6634680 100644 --- a/boring/type_checking.py +++ b/boring/type_checking.py @@ -130,8 +130,10 @@ class TypeChecker: def with_statement(self, ctx: Context, statement: parse.Statement) -> bool: if isinstance(statement, parse.ReturnStatement): return self.with_return_statement(ctx, statement) - if isinstance(statement, parse.LetStatement): + elif isinstance(statement, parse.LetStatement): return self.with_let_statement(ctx, statement) + elif isinstance(statement, parse.AssignmentStatement): + return self.with_assignment_statement(ctx, statement) elif isinstance(statement, parse.Expression): # expression return self.with_expression(ctx, statement) else: @@ -144,7 +146,20 @@ class TypeChecker: ctx.environment[let_statement.variable_name] = let_statement if self.with_expression(ctx, let_statement.expression): changed = True - changed = unify(ctx, let_statement, let_statement.expression) + if unify(ctx, let_statement, let_statement.expression): + changed = True + return changed + + def with_assignment_statement( + self, ctx: Context, assignment_statement: parse.AssignmentStatement + ) -> bool: + changed = False + if self.with_expression(ctx, assignment_statement.expression): + changed = True + if unify(ctx, assignment_statement, ctx.environment[assignment_statement.variable_name]): + changed = True + if unify(ctx, assignment_statement, assignment_statement.expression): + changed = True return changed def with_return_statement( diff --git a/examples/math/main.bl b/examples/math/main.bl index 9a7a167..7874587 100644 --- a/examples/math/main.bl +++ b/examples/math/main.bl @@ -4,6 +4,7 @@ fn add(a: I32, b: I32): I32 { let test_float: F32 = { 10.2 }; + test_float = 5.0; a + b + foo } diff --git a/notes.txt b/notes.txt index 2346f5a..b69579e 100644 --- a/notes.txt +++ b/notes.txt @@ -35,8 +35,13 @@ blocks propagate never except at the function level; TODO: * ~Float Literals~ * ~Block expression~ -* ~Return keyword ~ +* ~Return keyword~ +* ~Normal assignment~ * Structs + * Define + * Literal + * Getter + * Setter * Generics * Enums * Methods