Skip to content

Commit dbdfc13

Browse files
committed
feat: add complex trait bounds and full iterator combinators to stdlib
Grammar additions: - Where clauses for impl blocks (where T: Trait<Item=U>) - Associated type bindings in generics (Iterator<Item=T>) - Tuple types ((T1, T2), (T1, T2, T3)) - Tuple expressions ((a, b), (a, b, c)) - Trait bounds in where clauses with + syntax Stdlib additions: - Full iterator combinator types (MapIterator, FilterIterator, etc.) - IteratorExt trait with blanket impl for all Iterator types - Methods: map, filter, take, skip, enumerate, zip, chain, flat_map - Methods: fold, collect, find, any, all, count, first, last, for_each - HashMap and HashSet wrapper functions - Complete Option and Result methods with match expressions All 200 ZynML tests pass.
1 parent ff4c5a4 commit dbdfc13

2 files changed

Lines changed: 957 additions & 44 deletions

File tree

crates/zynml/ml.zyn

Lines changed: 252 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -604,14 +604,27 @@ associated_type = { "type" ~ name:identifier ~ (":" ~ type_bounds)? }
604604
name: intern(name),
605605
}
606606

607-
trait_method = { "fn" ~ name:identifier ~ type_params? ~ "(" ~ trait_params? ~ ")" ~ ("->" ~ type_expr)? }
607+
// Trait method with def keyword and colon return type: def name(params): Type
608+
trait_method_def = { "def" ~ name:identifier ~ type_params? ~ "(" ~ trait_params? ~ ")" ~ (":" ~ type_expr)? }
608609
-> TypedDeclaration::Function {
609610
name: intern(name),
610611
params: [],
611612
return_type: Type::Unit,
612613
body: None,
613614
}
614615

616+
// Legacy trait method with fn keyword and arrow return type: fn name(params) -> Type
617+
trait_method_fn = { "fn" ~ name:identifier ~ type_params? ~ "(" ~ trait_params? ~ ")" ~ ("->" ~ type_expr)? }
618+
-> TypedDeclaration::Function {
619+
name: intern(name),
620+
params: [],
621+
return_type: Type::Unit,
622+
body: None,
623+
}
624+
625+
trait_method = { item:trait_method_def | item:trait_method_fn }
626+
-> item
627+
615628
trait_params = { param:trait_param ~ ("," ~ param:trait_param)* }
616629
-> param
617630

@@ -888,10 +901,18 @@ impl_abstract_inherent_simple = { "impl" ~ name:identifier ~ "(" ~ type_expr ~ "
888901
}
889902

890903
// impl<T> Trait<Args> for Type<T> { ... }
891-
// Split into generic and non-generic variants
892-
impl_block_with_args = { decl:impl_block_with_args_generic | decl:impl_block_with_args_simple }
904+
// Split into generic and non-generic variants, with optional where clauses
905+
impl_block_with_args = { decl:impl_block_with_args_generic_where | decl:impl_block_with_args_generic | decl:impl_block_with_args_simple }
893906
-> decl
894907

908+
// impl<T> IteratorExt<T> for I where I: Iterator<Item=T> { ... }
909+
impl_block_with_args_generic_where = { "impl" ~ type_params ~ trait_name:identifier ~ type_args_angle ~ "for" ~ for_type:type_expr_name ~ where_clause ~ "{" ~ items:impl_items ~ "}" }
910+
-> TypedDeclaration::Impl {
911+
trait_name: intern(trait_name),
912+
for_type: intern(for_type),
913+
items: items,
914+
}
915+
895916
// impl<T> Add<T> for Container<T> { ... }
896917
impl_block_with_args_generic = { "impl" ~ type_params ~ trait_name:identifier ~ type_args_angle ~ "for" ~ for_type:type_expr_name ~ "{" ~ items:impl_items ~ "}" }
897918
-> TypedDeclaration::Impl {
@@ -909,10 +930,18 @@ impl_block_with_args_simple = { "impl" ~ trait_name:identifier ~ type_args_angle
909930
}
910931

911932
// impl<T> Trait for Type<T> { ... } - trait implementation
912-
// Split into generic and non-generic variants
913-
impl_block_trait = { decl:impl_block_trait_generic | decl:impl_block_trait_simple }
933+
// Split into generic and non-generic variants, with optional where clauses
934+
impl_block_trait = { decl:impl_block_trait_generic_where | decl:impl_block_trait_generic | decl:impl_block_trait_simple }
914935
-> decl
915936

937+
// impl<T> Iterator for ListIterator<T> where T: Clone { ... }
938+
impl_block_trait_generic_where = { "impl" ~ type_params ~ trait_name:identifier ~ "for" ~ for_type:type_expr_name ~ where_clause ~ "{" ~ items:impl_items ~ "}" }
939+
-> TypedDeclaration::Impl {
940+
trait_name: intern(trait_name),
941+
for_type: intern(for_type),
942+
items: items,
943+
}
944+
916945
// impl<T> Iterator for ListIterator<T> { ... }
917946
impl_block_trait_generic = { "impl" ~ type_params ~ trait_name:identifier ~ "for" ~ for_type:type_expr_name ~ "{" ~ items:impl_items ~ "}" }
918947
-> TypedDeclaration::Impl {
@@ -970,6 +999,9 @@ impl_items = { item:impl_item* }
970999
// NOTE: indent-bodied must come after expression-bodied to prefer single-expression form when applicable
9711000
impl_item = {
9721001
decl:impl_assoc_type |
1002+
// New def-style methods (preferred)
1003+
decl:impl_method_def_return | decl:impl_method_def_params | decl:impl_method_def_simple |
1004+
// Legacy fn-style methods
9731005
decl:impl_method_return_expr | decl:impl_method_return_indent | decl:impl_method_return |
9741006
decl:impl_method_params_expr | decl:impl_method_params_indent | decl:impl_method_params |
9751007
decl:impl_method_simple_indent | decl:impl_method_simple
@@ -1069,6 +1101,35 @@ impl_method_simple = { "fn" ~ name:identifier ~ "(" ~ ")" ~ body:block }
10691101
body: Some(body),
10701102
}
10711103

1104+
// ========== New def-style methods (with colon return type) ==========
1105+
1106+
// def name(params): Type { body }
1107+
impl_method_def_return = { "def" ~ name:identifier ~ type_params? ~ "(" ~ params:fn_params? ~ ")" ~ ":" ~ ret:type_expr ~ body:block }
1108+
-> TypedDeclaration::Function {
1109+
name: intern(name),
1110+
params: params,
1111+
return_type: ret,
1112+
body: Some(body),
1113+
}
1114+
1115+
// def name(params) { body } - no return type
1116+
impl_method_def_params = { "def" ~ name:identifier ~ type_params? ~ "(" ~ params:fn_params ~ ")" ~ body:block }
1117+
-> TypedDeclaration::Function {
1118+
name: intern(name),
1119+
params: params,
1120+
return_type: Type::Unit,
1121+
body: Some(body),
1122+
}
1123+
1124+
// def name() { body } - no params, no return type
1125+
impl_method_def_simple = { "def" ~ name:identifier ~ "(" ~ ")" ~ body:block }
1126+
-> TypedDeclaration::Function {
1127+
name: intern(name),
1128+
params: [],
1129+
return_type: Type::Unit,
1130+
body: Some(body),
1131+
}
1132+
10721133
// Type arguments in angle brackets (for trait impl)
10731134
type_args_angle = { "<" ~ args:type_args ~ ">" }
10741135
-> args
@@ -1086,7 +1147,52 @@ type_args_angle = { "<" ~ args:type_args ~ ">" }
10861147
// List<int> -> List<int>
10871148
// int -> int
10881149
//
1089-
type_expr = { ty:optional_type | ty:generic_type | ty:array_type | ty:simple_type }
1150+
type_expr = { ty:optional_type | ty:fn_type | ty:tuple_type | ty:generic_type | ty:array_type | ty:simple_type }
1151+
-> ty
1152+
1153+
// Tuple type: (T1, T2) or (T1, T2, T3)
1154+
// Must come after fn_type since both start with parens (fn_type has "def" keyword)
1155+
tuple_type = { ty:tuple_type_2 | ty:tuple_type_3 | ty:tuple_type_4 }
1156+
-> ty
1157+
1158+
// Two-element tuple: (T1, T2)
1159+
tuple_type_2 = { "(" ~ t1:type_expr ~ "," ~ t2:type_expr ~ ")" }
1160+
-> Type::Tuple {
1161+
elements: [t1, t2],
1162+
}
1163+
1164+
// Three-element tuple: (T1, T2, T3)
1165+
tuple_type_3 = { "(" ~ t1:type_expr ~ "," ~ t2:type_expr ~ "," ~ t3:type_expr ~ ")" }
1166+
-> Type::Tuple {
1167+
elements: [t1, t2, t3],
1168+
}
1169+
1170+
// Four-element tuple: (T1, T2, T3, T4)
1171+
tuple_type_4 = { "(" ~ t1:type_expr ~ "," ~ t2:type_expr ~ "," ~ t3:type_expr ~ "," ~ t4:type_expr ~ ")" }
1172+
-> Type::Tuple {
1173+
elements: [t1, t2, t3, t4],
1174+
}
1175+
1176+
// Function type: def(T, U): R
1177+
fn_type = { ty:fn_type_with_return | ty:fn_type_unit }
1178+
-> ty
1179+
1180+
// def(T, U): R - function type with return
1181+
fn_type_with_return = { "def" ~ "(" ~ params:fn_type_params? ~ ")" ~ ":" ~ ret:type_expr }
1182+
-> Type::Function {
1183+
params: params,
1184+
return_type: ret,
1185+
}
1186+
1187+
// def(T, U) - function type returning unit
1188+
fn_type_unit = { "def" ~ "(" ~ params:fn_type_params? ~ ")" }
1189+
-> Type::Function {
1190+
params: params,
1191+
return_type: Type::Unit,
1192+
}
1193+
1194+
// Function type parameter list
1195+
fn_type_params = { ty:type_expr ~ ("," ~ ty:type_expr)* }
10901196
-> ty
10911197

10921198
// ?T shorthand for Option<T>
@@ -1097,7 +1203,7 @@ optional_type = { "?" ~ inner:type_expr_non_optional }
10971203
}
10981204

10991205
// Type expression without the optional prefix (to avoid infinite recursion)
1100-
type_expr_non_optional = { ty:generic_type | ty:array_type | ty:simple_type }
1206+
type_expr_non_optional = { ty:fn_type | ty:tuple_type | ty:generic_type | ty:array_type | ty:simple_type }
11011207
-> ty
11021208

11031209
simple_type = { name:identifier }
@@ -1115,8 +1221,75 @@ generic_type = { name:identifier ~ "<" ~ type_args ~ ">" }
11151221
name: intern(name),
11161222
}
11171223

1118-
type_args = { ty:type_expr ~ ("," ~ ty:type_expr)* }
1119-
-> ty
1224+
// Type arguments: can be regular types or associated type bindings (Item=T)
1225+
type_args = { arg:type_arg ~ ("," ~ arg:type_arg)* }
1226+
-> arg
1227+
1228+
// Single type argument: either associated binding or regular type
1229+
// Associated binding must come first to match "Item=T" before "Item" is parsed as simple type
1230+
type_arg = { arg:assoc_type_binding | arg:type_expr }
1231+
-> arg
1232+
1233+
// Associated type binding: Item=T, Output=U
1234+
// Used in trait bounds like Iterator<Item=T>
1235+
assoc_type_binding = { name:identifier ~ "=" ~ ty:type_expr }
1236+
-> Type::AssocBinding {
1237+
name: intern(name),
1238+
ty: ty,
1239+
}
1240+
1241+
// ============================================================================
1242+
// Where Clauses
1243+
// ============================================================================
1244+
// Where clauses for complex trait bounds:
1245+
// impl<I, T> Iterator for MyIter<I, T>
1246+
// where I: Iterator<Item=T>,
1247+
// T: Clone
1248+
//
1249+
// Grammar accepts where clauses but they are primarily for documentation/parsing
1250+
// The full semantic handling is done by the type checker
1251+
1252+
// Optional where clause - may be empty
1253+
where_clause = { "where" ~ bounds:where_bounds }
1254+
-> bounds
1255+
1256+
// Multiple where bounds separated by commas
1257+
where_bounds = { bound:where_bound ~ ("," ~ bound:where_bound)* }
1258+
-> bound
1259+
1260+
// Single where bound: T: Trait or T: Trait<Args>
1261+
// Also supports: T: Trait1 + Trait2 (multiple bounds on same type)
1262+
where_bound = { name:identifier ~ ":" ~ bounds:where_trait_bounds }
1263+
-> Type::WhereBound {
1264+
name: intern(name),
1265+
bounds: bounds,
1266+
}
1267+
1268+
// Multiple trait bounds separated by +: Clone + Debug + Iterator<Item=T>
1269+
where_trait_bounds = { bound:where_trait_bound ~ ("+" ~ bound:where_trait_bound)* }
1270+
-> bound
1271+
1272+
// Single trait bound: Clone, Debug, Iterator<Item=T>, def(T): U (function bounds)
1273+
where_trait_bound = { bound:trait_bound_generic | bound:trait_bound_fn | bound:trait_bound_simple }
1274+
-> bound
1275+
1276+
// Generic trait bound: Iterator<Item=T>
1277+
trait_bound_generic = { name:identifier ~ "<" ~ args:type_args ~ ">" }
1278+
-> Type::TraitBound {
1279+
name: intern(name),
1280+
type_args: args,
1281+
}
1282+
1283+
// Simple trait bound: Clone, Debug
1284+
trait_bound_simple = { name:identifier }
1285+
-> Type::TraitBound {
1286+
name: intern(name),
1287+
type_args: [],
1288+
}
1289+
1290+
// Function type as trait bound: def(T): U
1291+
trait_bound_fn = { bound:fn_type }
1292+
-> bound
11201293

11211294
// ============================================================================
11221295
// Function Definition
@@ -1671,10 +1844,53 @@ match_arm = { "case" ~ pat:pattern ~ body:block }
16711844
body: body,
16721845
}
16731846

1674-
// Pattern: literal, identifier (binding), or wildcard (_)
1675-
pattern = { string_literal | int_literal | bool_literal | wildcard | identifier }
1847+
// Pattern: literal, constructor, identifier (binding), or wildcard (_)
1848+
pattern = {
1849+
pat:pattern_tuple_two |
1850+
pat:pattern_constructor_with_field |
1851+
pat:pattern_constructor_unit |
1852+
pat:pattern_literal |
1853+
pat:pattern_wildcard |
1854+
pat:pattern_binding
1855+
}
1856+
-> pat
1857+
1858+
// Tuple pattern for destructuring: (a, b)
1859+
pattern_tuple_two = { "(" ~ p1:pattern ~ "," ~ p2:pattern ~ ")" }
1860+
-> TypedPattern::Tuple {
1861+
elements: [p1, p2],
1862+
}
16761863

1677-
// Wildcard pattern
1864+
// Constructor pattern with field: Some(x), Ok(v), Err(e)
1865+
pattern_constructor_with_field = { name:identifier ~ "(" ~ inner:pattern ~ ")" }
1866+
-> TypedPattern::Constructor {
1867+
name: intern(name),
1868+
fields: [inner],
1869+
}
1870+
1871+
// Unit constructor: None(), Nil() - requires parens to distinguish from binding
1872+
pattern_constructor_unit = { name:identifier ~ "(" ~ ")" }
1873+
-> TypedPattern::Constructor {
1874+
name: intern(name),
1875+
fields: [],
1876+
}
1877+
1878+
// Literal patterns
1879+
pattern_literal = { pat:string_literal | pat:int_literal | pat:bool_literal }
1880+
-> pat
1881+
1882+
// Wildcard pattern: _
1883+
pattern_wildcard = { "_" }
1884+
-> TypedPattern::Wildcard {}
1885+
1886+
// Binding pattern: just an identifier (catches any value)
1887+
pattern_binding = { name:identifier }
1888+
-> TypedPattern::Identifier {
1889+
name: intern(name),
1890+
is_mutable: false,
1891+
}
1892+
1893+
// Wildcard (legacy, also used in expressions)
16781894
wildcard = { "_" }
16791895
-> TypedExpression::Wildcard {}
16801896

@@ -1969,11 +2185,35 @@ primary_expr = {
19692185
f_string_literal |
19702186
string_literal |
19712187
bool_literal |
2188+
tuple_expr | // Must come before grouped_expr (both start with '(')
19722189
grouped_expr |
19732190
path_expr |
19742191
var_expr
19752192
}
19762193

2194+
// Tuple expression: (a, b) or (a, b, c)
2195+
// Must come before grouped_expr since both start with '('
2196+
tuple_expr = { e:tuple_expr_2 | e:tuple_expr_3 | e:tuple_expr_4 }
2197+
-> e
2198+
2199+
// Two-element tuple: (a, b)
2200+
tuple_expr_2 = { "(" ~ e1:expr ~ "," ~ e2:expr ~ ")" }
2201+
-> TypedExpression::Tuple {
2202+
elements: [e1, e2],
2203+
}
2204+
2205+
// Three-element tuple: (a, b, c)
2206+
tuple_expr_3 = { "(" ~ e1:expr ~ "," ~ e2:expr ~ "," ~ e3:expr ~ ")" }
2207+
-> TypedExpression::Tuple {
2208+
elements: [e1, e2, e3],
2209+
}
2210+
2211+
// Four-element tuple: (a, b, c, d)
2212+
tuple_expr_4 = { "(" ~ e1:expr ~ "," ~ e2:expr ~ "," ~ e3:expr ~ "," ~ e4:expr ~ ")" }
2213+
-> TypedExpression::Tuple {
2214+
elements: [e1, e2, e3, e4],
2215+
}
2216+
19772217
// ============================================================================
19782218
// Load with Type Cast
19792219
// ============================================================================

0 commit comments

Comments
 (0)