Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .github/workflows/test-compiler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v5
with:
ref: main
path: main-src
- name: Download casac release binary
run: |
curl --silent --location --fail \
--output casac-release \
"https://github.com/frendsick/casa/releases/latest/download/casac"
chmod +x casac-release
- name: Bootstrap stage0 compiler from main
run: |
cd main-src
../casac-release -L lib casa.casa -o ../casac-main
- name: Bootstrap stage1 compiler from branch
run: ./casac-main -L lib casa.casa -o casac-stage1
run: ./casac-release -L lib casa.casa -o casac-stage1
- name: Run compiler tests
run: ./tests/test_compiler.sh ./casac-stage1
10 changes: 1 addition & 9 deletions .github/workflows/test-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v5
with:
ref: main
path: main-src
- name: Download casac release binary
run: |
curl --silent --location --fail \
--output casac-release \
"https://github.com/frendsick/casa/releases/latest/download/casac"
chmod +x casac-release
- name: Bootstrap stage0 compiler from main
run: |
cd main-src
../casac-release -L lib casa.casa -o ../casac-main
- name: Bootstrap stage1 compiler from branch
run: ./casac-main -L lib casa.casa -o casac-stage1
run: ./casac-release -L lib casa.casa -o casac-stage1
- name: Test example programs
run: ./tests/test_examples.sh ./casac-stage1
14 changes: 7 additions & 7 deletions compiler/common.casa
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ struct CasaTrait {
name: str
type_params: List[str]
methods: List[TraitMethod]
supertraits: List[TraitBound]
location: Location
}

Expand Down Expand Up @@ -831,7 +832,8 @@ struct Program {
# Constants
# ============================================================================
"_start" = GLOBAL_SCOPE_LABEL
"any" = ANY_TYPE
"?" = TYPE_UNKNOWN
"<missing>" = TYPE_MISSING
"_" = MATCH_WILDCARD
"self" = TRAIT_SELF_TYPE
8 = WORD_SIZE
Expand Down Expand Up @@ -966,7 +968,6 @@ fn is_builtin_type typ:str -> bool {
"str" typ == ||
"ptr" typ == ||
"array" typ == ||
"any" typ == ||
}

# ============================================================================
Expand Down Expand Up @@ -1057,7 +1058,7 @@ fn signature_matches sig_a:Signature sig_b:Signature -> bool {
while index sig_a Signature::parameters.length > do
index sig_a Signature::parameters.get Parameter::typ = type_a
index sig_b Signature::parameters.get Parameter::typ = type_b
if type_a type_b != ANY_TYPE type_a != && ANY_TYPE type_b != && then
if type_a type_b != TYPE_UNKNOWN type_a != && TYPE_UNKNOWN type_b != && then
type_b extract_generic_base = base_b
type_a extract_generic_base = base_a
if base_b.is_some type_a base_b.unwrap_or "" == && ! then
Expand All @@ -1073,7 +1074,7 @@ fn signature_matches sig_a:Signature sig_b:Signature -> bool {
while index sig_a Signature::return_types.length > do
index sig_a Signature::return_types.get = return_a
index sig_b Signature::return_types.get = return_b
if return_a return_b != ANY_TYPE return_a != && ANY_TYPE return_b != && then
if return_a return_b != TYPE_UNKNOWN return_a != && TYPE_UNKNOWN return_b != && then
return_b extract_generic_base = return_base_b
return_a extract_generic_base = return_base_a
if return_base_b.is_some return_base_a.is_some && return_base_b.unwrap return_base_a.unwrap == && then
Expand All @@ -1090,8 +1091,8 @@ fn signature_matches sig_a:Signature sig_b:Signature -> bool {
param_index params_b.get = param_b
if
param_a param_b !=
ANY_TYPE param_a != &&
ANY_TYPE param_b != &&
TYPE_UNKNOWN param_a != &&
TYPE_UNKNOWN param_b != &&
param_a.length 1 != &&
param_b.length 1 != &&
then
Expand Down Expand Up @@ -1493,7 +1494,6 @@ fn symbol_store_new -> SymbolStore {
"cstr" builtins.add = builtins
"ptr" builtins.add = builtins
"array" builtins.add = builtins
"any" builtins.add = builtins

builtins
Map::new(Map[str CasaTrait])
Expand Down
67 changes: 64 additions & 3 deletions compiler/syntax.casa
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ fn parse_type cursor:TokenCursor -> str {
cursor.peek = peek_opt
if peek_opt.is_none then
empty_location "Expected type" ErrorKind::UnexpectedToken raise_error
"any" return
"" return
fi
peek_opt.unwrap = peek

Expand Down Expand Up @@ -285,6 +285,7 @@ fn get_op_type_cast cursor:TokenCursor -> Op {
close_token Token::location Location::span Span::offset = close_offset
close_offset open_offset - 1 + = length
length open_offset open_token Token::location Location::file make_location = loc

loc cast_type OpValue::TypeCast make_op
}

Expand Down Expand Up @@ -868,6 +869,37 @@ fn parse_signature cursor:TokenCursor -> Signature {
# Bounds whose trait is not registered in the store are silently skipped,
# matching the pre-extraction behavior of both call sites.

fn collect_trait_methods_into
seen:Set[str]
result:List[TraitMethod]
parser:Parser
trait_def:CasaTrait
-> Set[str] {
for ctm_method in trait_def CasaTrait::methods.iter do
if ctm_method TraitMethod::name seen.has ! then
ctm_method TraitMethod::name seen.add = seen
ctm_method result.push
fi
done
for ctm_super in trait_def CasaTrait::supertraits.iter do
ctm_super TraitBound::name parser.store.traits.get = ctm_super_opt
if ctm_super_opt.is_some then
ctm_super_opt.unwrap parser result seen collect_trait_methods_into = seen
fi
done
seen
}
# Returns all methods (abstract + default) from `trait_def` and its
# transitive supertraits, deduplicated by name. The trait's own methods
# come first; supertrait methods follow in declaration order.

fn collect_trait_methods parser:Parser trait_def:CasaTrait -> List[TraitMethod] {
List::new(List[TraitMethod]) = result
Set::new(Set[str]) = seen
trait_def parser result seen collect_trait_methods_into drop
result
}

fn build_hidden_trait_methods
parser:Parser
trait_bounds:Map[str TraitBound]
Expand All @@ -891,7 +923,7 @@ fn build_hidden_trait_methods
1 += bhtm_sub_index
done
fi
for bound_method in bound_trait CasaTrait::methods.iter do
for bound_method in bound_trait parser collect_trait_methods.iter do
# Skip default methods — only abstract methods need hidden fn ptrs
if 0 bound_method TraitMethod::default_ops.length == then
f"__trait_{bound_type_var}_{bound_method TraitMethod::name}" = hidden_name
Expand Down Expand Up @@ -1288,6 +1320,35 @@ fn parse_trait parser:Parser cursor:TokenCursor -> CasaTrait {
"trait" cursor parse_simple_type_vars = type_params
fi

List::new(List[TraitBound]) = supertraits
cursor.peek = colon_opt
if colon_opt.is_some ":" colon_opt.unwrap Token::value == && then
cursor.pop drop
true = parse_super_loop
while parse_super_loop do
TokenKind::Identifier cursor expect_token_kind = super_token
super_token Token::value = super_name
super_name parser.store.traits.get = super_def_opt
if super_def_opt.is_none then
super_token Token::location f"Supertrait `{super_name}` is not defined" ErrorKind::UndefinedName raise_error
fi
super_token cursor parse_bound_type_args = super_args
if super_def_opt.is_some then
super_def_opt.unwrap CasaTrait::type_params = super_params
if super_args.length super_params.length != then
super_token Token::location f"Supertrait `{super_name}` expects {super_params.length} type argument(s), got {super_args.length}" ErrorKind::Syntax raise_error
fi
fi
super_args super_name TraitBound supertraits.push
cursor.peek = plus_opt
if plus_opt.is_some "+" plus_opt.unwrap Token::value == && then
cursor.pop drop
else
false = parse_super_loop
fi
done
fi

List::new(List[TraitMethod]) = methods
"{" cursor expect_token_value drop

Expand Down Expand Up @@ -1329,7 +1390,7 @@ fn parse_trait parser:Parser cursor:TokenCursor -> CasaTrait {
fi
done

name_token Token::location methods type_params name_token Token::value CasaTrait
name_token Token::location supertraits methods type_params name_token Token::value CasaTrait
}

# ============================================================================
Expand Down
Loading