diff --git a/bootstrap_compiler/typecheck.c b/bootstrap_compiler/typecheck.c index 67605a87..ce60b385 100644 --- a/bootstrap_compiler/typecheck.c +++ b/bootstrap_compiler/typecheck.c @@ -1087,6 +1087,7 @@ static void handle_conflicting_class_field_and_enum_member_syntax(const FileType return; } + free(expr->data.classfield.obj); expr->kind = AST_EXPR_GET_ENUM_MEMBER; memset(&expr->data, 0, sizeof(expr->data)); safe_strcpy(expr->data.enummember.enumname, enum_name); diff --git a/compiler/ast.jou b/compiler/ast.jou index a176b3f4..e4ed4207 100644 --- a/compiler/ast.jou +++ b/compiler/ast.jou @@ -328,19 +328,19 @@ class AstExpression: self->operands[i].print_with_tree_printer(tp.print_prefix(i == self->get_arity()-1)) def free(self) -> None: - if self->kind == AstExpressionKind.Call: - self->call.free() - elif self->kind == AstExpressionKind.As: - self->as_->free() - free(self->as_) - elif self->kind == AstExpressionKind.String: + if self->kind == AstExpressionKind.String: free(self->string) elif self->kind == AstExpressionKind.Array: self->array.free() + elif self->kind == AstExpressionKind.Call: + self->call.free() elif self->kind == AstExpressionKind.Instantiate: self->instantiation.free() elif self->kind == AstExpressionKind.GetClassField: self->class_field.free() + elif self->kind == AstExpressionKind.As: + self->as_->free() + free(self->as_) if self->get_arity() != 0: for i = 0; i < self->get_arity(); i++: @@ -454,6 +454,9 @@ class AstCall: for i = 0; i < self->nargs; i++: self->args[i].free() free(self->args) + if self->method_call_self != NULL: + self->method_call_self->free() + free(self->method_call_self) # Useful for formatting error messages, but not much else. # TODO: use this @@ -469,6 +472,10 @@ class AstAssertion: condition: AstExpression condition_str: byte* + def free(self) -> None: + self->condition.free() + free(self->condition_str) + enum AstStatementKind: ExpressionStatement # Evaluate an expression. Discard the result. @@ -502,8 +509,8 @@ class AstStatement: if_statement: AstIfStatement while_loop: AstConditionAndBody for_loop: AstForLoop - return_value: AstExpression* # can be NULL - assignment: AstAssignment + return_value: AstExpression* # can be NULL + assignment: AstAssignment # also used for +=, -= etc var_declaration: AstNameTypeValue # DeclareLocalVar function: AstFunctionOrMethod classdef: AstClassDef @@ -582,19 +589,40 @@ class AstStatement: printf("??????\n") def free(self) -> None: - if self->kind == AstStatementKind.Enum: - self->enumdef.free() if self->kind == AstStatementKind.ExpressionStatement: self->expression.free() + if self->kind == AstStatementKind.Assert: + self->assertion.free() if self->kind == AstStatementKind.Return and self->return_value != NULL: self->return_value->free() free(self->return_value) if self->kind == AstStatementKind.If: self->if_statement.free() + if self->kind == AstStatementKind.WhileLoop: + self->while_loop.free() if self->kind == AstStatementKind.ForLoop: self->for_loop.free() + if ( + self->kind == AstStatementKind.DeclareLocalVar + or self->kind == AstStatementKind.GlobalVariableDeclaration + or self->kind == AstStatementKind.GlobalVariableDefinition + ): + self->var_declaration.free() + if ( + self->kind == AstStatementKind.Assign + or self->kind == AstStatementKind.InPlaceAdd + or self->kind == AstStatementKind.InPlaceSub + or self->kind == AstStatementKind.InPlaceMul + or self->kind == AstStatementKind.InPlaceDiv + or self->kind == AstStatementKind.InPlaceMod + ): + self->assignment.free() + if self->kind == AstStatementKind.Function: + self->function.free() if self->kind == AstStatementKind.Class: self->classdef.free() + if self->kind == AstStatementKind.Enum: + self->enumdef.free() # Useful for e.g. "while condition: body", "if condition: body" @@ -631,6 +659,10 @@ class AstAssignment: self->target.print_with_tree_printer(tp.print_prefix(False)) self->value.print_with_tree_printer(tp.print_prefix(True)) + def free(self) -> None: + self->target.free() + self->value.free() + # if foo: # ... @@ -730,9 +762,10 @@ class AstNameTypeValue: self->value->print_with_tree_printer(sub) def free(self) -> None: + self->type.free() if self->value != NULL: self->value->free() - free(self->value) + free(self->value) # typically multiple indented lines after a ":" at end of line diff --git a/compiler/build_cf_graph.jou b/compiler/build_cf_graph.jou index a343be44..550ce372 100644 --- a/compiler/build_cf_graph.jou +++ b/compiler/build_cf_graph.jou @@ -734,7 +734,7 @@ class CfBuilder: assert sizeof(c.double_or_float_text) == sizeof(expr->float_or_double_text) strcpy(c.double_or_float_text, expr->float_or_double_text) elif expr->kind == AstExpressionKind.String: - c = Constant{kind = ConstantKind.String, str = strdup(expr->string)} + c = Constant{kind = ConstantKind.String, str = expr->string} else: assert False result = self->add_var(t) diff --git a/compiler/parser.jou b/compiler/parser.jou index bfd019f3..d10a09ed 100644 --- a/compiler/parser.jou +++ b/compiler/parser.jou @@ -151,6 +151,8 @@ def check_class_for_duplicate_names(classdef: AstClassDef*) -> None: ) fail(p2->name_location, message) + free(infos) + # TODO: this function is just bad... def read_assertion_from_file(start: Location, end: Location) -> byte*: diff --git a/compiler/tokenizer.jou b/compiler/tokenizer.jou index 3412ad56..6f103bd3 100644 --- a/compiler/tokenizer.jou +++ b/compiler/tokenizer.jou @@ -600,6 +600,8 @@ def tokenize(path: byte*, import_location: Location*) -> Token*: fail(*import_location, message) raw_tokens = tokenize_without_indent_dedent_tokens(file, path) + fclose(file) + better_tokens = handle_indentations(raw_tokens) free(raw_tokens) return better_tokens diff --git a/compiler/typecheck/step3_function_and_method_bodies.jou b/compiler/typecheck/step3_function_and_method_bodies.jou index 33afeb2f..6b13a926 100644 --- a/compiler/typecheck/step3_function_and_method_bodies.jou +++ b/compiler/typecheck/step3_function_and_method_bodies.jou @@ -824,6 +824,7 @@ def handle_conflicting_class_field_and_enum_member_syntax(ft: FileTypes*, expr: if expr->class_field.uses_arrow_operator: fail(expr->location, "the '->' operator cannot be used to look up enum members") + free(expr->class_field.instance) expr->kind = AstExpressionKind.GetEnumMember expr->enum_member = AstEnumMember{ enum_name = enum_name,