Type AST migration (#140): replace string-based types with structured Type enum#168
Open
Type AST migration (#140): replace string-based types with structured Type enum#168
Conversation
Introduce BuiltinType, GenericType, FunctionType, and Type enums/structs in compiler/common.casa. Add parse_type_str (str -> Type) and Type.format (Type -> str) with round-trip test coverage for builtins, generics, nested generics, function types, type vars, and named types.
str::starts_with, str::ends_with, str::contains, and str::find take needle/prefix/suffix as the first parameter. The original calls passed them as the second, so 'fn[T -> U]' parsed as a single-string Generic blob (base='fn[T -> U]', params=[]) instead of a real Type::Function. Type::format round-trips it correctly so the bug stayed undetected, but Type::substitute cannot decompose the blob, breaking trait default method synthesis (e.g. Iterable::map for non-generic receivers).
…signature Final piece of the Type AST migration (#167). make_named_param and make_signature now take Type / List[Type] directly, eliminating internal parse_type_str round-trips. apply_type_subs_to_sig and resolve_trait_sig operate on Type values via Type::substitute and TRAIT_SELF_TYPE checks. Adds direct test for Type::substitute on Type::Function nodes — the round-trip tests previously masked decomposition failures.
…_sig Inline the if/else branches by reassigning typ_str/ret_str when self matches, then parse once at the end. Same behavior, less repetition.
Eliminate format/parse round-trip on the non-self branch by passing param.typ and ret as Type values, parsing type_var once up front. Reduces work proportional to (params + returns) per trait method synthesis call.
Eliminates three parse_type_str call sites in syntax.casa by parsing the function-type string once at construction in build_hidden_trait_methods, then passing Type values through make_named_param and Variable directly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements PRD #140. Replaces stringly-typed compiler internals with a structured
Typeenum (Unknown,Builtin,Generic,Function,TypeVar).Closes issues #161-#167.
Per-commit breakdown
976a730Type AST foundation: enum,parse_type_str,Type.format, round-trip testse7ef718MigrateParameter.typ: str → Typea658ef5MigrateVariable.typandMember.typtoTypec64f7d1MigrateSignature.return_types: List[str] → List[Type]606f79eMigrateTypedStack.types: List[str] → List[Type]2f59857AddTypemethods:base,type_params,is_type_var,substitute45f1b12Fix RPN argument order inparse_type_str(str helpers; see below)83de95eRemove internal string boundaries atmake_named_param/make_signatureBug discovered and fixed
parse_type_strpassedstarts_with/ends_with/contains/findarguments in the wrong RPN order, soparse_type_str("fn[T -> U]")returned aGeneric{base="fn[T -> U]", params=[]}blob instead of a realType::Function.Type::formatround-tripped it correctly so the bug was masked, butType::substitutecouldn't decompose the blob — broke trait default method synthesis (e.g.Counter.mapfromIterable::map). Direct substitute test added intest_type_ast.casaas a regression guard.Notes on Casa enum move-semantics
Casa enum values (
Type,Option[T]) are move-semantic: a named variable is consumed on first method call.resolve_trait_sigtherefore uses a format → check → re-parse pattern when it needs to compare aTypeagainstTRAIT_SELF_TYPEand reuse it.signature_matchessimilarly stays str-based.Test plan
tests/test_compiler.sh < /dev/null— 28/28 passtests/test_examples.sh— 40/40 pass