@@ -39,7 +39,7 @@ use crate::{
39
39
node_interner:: { DefinitionKind , TraitImplKind } ,
40
40
parser:: { self } ,
41
41
token:: { Attribute , SecondaryAttribute , Token } ,
42
- QuotedType , Shared , Type ,
42
+ Kind , QuotedType , ResolvedGeneric , Shared , Type , TypeVariable ,
43
43
} ;
44
44
45
45
use self :: builtin_helpers:: { get_array, get_str, get_u8} ;
@@ -139,7 +139,8 @@ impl<'local, 'context> Interpreter<'local, 'context> {
139
139
"slice_push_front" => slice_push_front ( interner, arguments, location) ,
140
140
"slice_remove" => slice_remove ( interner, arguments, location, call_stack) ,
141
141
"str_as_bytes" => str_as_bytes ( interner, arguments, location) ,
142
- "struct_def_add_attribute" => struct_def_add_attribute ( self , arguments, location) ,
142
+ "struct_def_add_attribute" => struct_def_add_attribute ( interner, arguments, location) ,
143
+ "struct_def_add_generic" => struct_def_add_generic ( interner, arguments, location) ,
143
144
"struct_def_as_type" => struct_def_as_type ( interner, arguments, location) ,
144
145
"struct_def_fields" => struct_def_fields ( interner, arguments, location) ,
145
146
"struct_def_generics" => struct_def_generics ( interner, arguments, location) ,
@@ -280,13 +281,13 @@ fn str_as_bytes(
280
281
281
282
// fn add_attribute<let N: u32>(self, attribute: str<N>)
282
283
fn struct_def_add_attribute (
283
- interpreter : & mut Interpreter ,
284
+ interner : & mut NodeInterner ,
284
285
arguments : Vec < ( Value , Location ) > ,
285
286
location : Location ,
286
287
) -> IResult < Value > {
287
288
let ( self_argument, attribute) = check_two_arguments ( arguments, location) ?;
288
289
let attribute_location = attribute. 1 ;
289
- let attribute = get_str ( interpreter . elaborator . interner , attribute) ?;
290
+ let attribute = get_str ( interner, attribute) ?;
290
291
291
292
let mut tokens = Lexer :: lex ( & format ! ( "#[{}]" , attribute) ) . 0 . 0 ;
292
293
if let Some ( Token :: EOF ) = tokens. last ( ) . map ( |token| token. token ( ) ) {
@@ -315,13 +316,68 @@ fn struct_def_add_attribute(
315
316
} ;
316
317
317
318
let struct_id = get_struct ( self_argument) ?;
318
- interpreter . elaborator . interner . update_struct_attributes ( struct_id, |attributes| {
319
+ interner. update_struct_attributes ( struct_id, |attributes| {
319
320
attributes. push ( attribute. clone ( ) ) ;
320
321
} ) ;
321
322
322
323
Ok ( Value :: Unit )
323
324
}
324
325
326
+ // fn add_generic<let N: u32>(self, generic_name: str<N>)
327
+ fn struct_def_add_generic (
328
+ interner : & NodeInterner ,
329
+ arguments : Vec < ( Value , Location ) > ,
330
+ location : Location ,
331
+ ) -> IResult < Value > {
332
+ let ( self_argument, generic) = check_two_arguments ( arguments, location) ?;
333
+ let generic_location = generic. 1 ;
334
+ let generic = get_str ( interner, generic) ?;
335
+
336
+ let mut tokens = Lexer :: lex ( & generic) . 0 . 0 ;
337
+ if let Some ( Token :: EOF ) = tokens. last ( ) . map ( |token| token. token ( ) ) {
338
+ tokens. pop ( ) ;
339
+ }
340
+
341
+ if tokens. len ( ) != 1 {
342
+ return Err ( InterpreterError :: GenericNameShouldBeAnIdent {
343
+ name : generic,
344
+ location : generic_location,
345
+ } ) ;
346
+ }
347
+
348
+ let Token :: Ident ( generic_name) = tokens. pop ( ) . unwrap ( ) . into_token ( ) else {
349
+ return Err ( InterpreterError :: GenericNameShouldBeAnIdent {
350
+ name : generic,
351
+ location : generic_location,
352
+ } ) ;
353
+ } ;
354
+
355
+ let struct_id = get_struct ( self_argument) ?;
356
+ let the_struct = interner. get_struct ( struct_id) ;
357
+ let mut the_struct = the_struct. borrow_mut ( ) ;
358
+ let name = Rc :: new ( generic_name) ;
359
+
360
+ for generic in & the_struct. generics {
361
+ if generic. name == name {
362
+ return Err ( InterpreterError :: DuplicateGeneric {
363
+ name,
364
+ struct_name : the_struct. name . to_string ( ) ,
365
+ existing_location : Location :: new ( generic. span , the_struct. location . file ) ,
366
+ duplicate_location : generic_location,
367
+ } ) ;
368
+ }
369
+ }
370
+
371
+ let type_var = TypeVariable :: unbound ( interner. next_type_variable_id ( ) ) ;
372
+ let span = generic_location. span ;
373
+ let kind = Kind :: Normal ;
374
+ let typ = Type :: NamedGeneric ( type_var. clone ( ) , name. clone ( ) , kind. clone ( ) ) ;
375
+ let new_generic = ResolvedGeneric { name, type_var, span, kind } ;
376
+ the_struct. generics . push ( new_generic) ;
377
+
378
+ Ok ( Value :: Type ( typ) )
379
+ }
380
+
325
381
/// fn as_type(self) -> Type
326
382
fn struct_def_as_type (
327
383
interner : & NodeInterner ,
0 commit comments