@@ -19,8 +19,9 @@ use zyntax_typed_ast::{
1919 TypedIf , TypedWhile , TypedFor , TypedUnary , TypedFieldAccess , TypedIndex ,
2020 TypedRange , TypedStructLiteral , TypedFieldInit , TypedPattern ,
2121 TypedParameter , TypedVariant , TypedVariantFields , TypedTypeAlias , ParameterKind ,
22- TypedInterface ,
22+ TypedInterface , TypedExtern , TypedExternStruct , TypedTypeParam ,
2323 TypedAnnotation , TypedAnnotationArg , TypedAnnotationValue ,
24+ TypedLambda , TypedLambdaBody , TypedLambdaParam , TypedImportModifier ,
2425 UnaryOp ,
2526 typed_node, Span ,
2627 type_registry:: { Type , PrimitiveType , Mutability , Visibility , CallingConvention , NullabilityKind , ConstValue } ,
@@ -277,6 +278,10 @@ impl<'g> GrammarInterpreter<'g> {
277278 [ "SuffixField" ] | [ "SuffixMethod" ] | [ "SuffixCall" ] | [ "SuffixIndex" ] | [ "SuffixSlice" ] => {
278279 self . construct_suffix ( type_path, fields, state)
279280 }
281+ // Lambda parameter
282+ [ "TypedLambdaParam" ] => {
283+ self . construct_lambda_param ( fields, state, span)
284+ }
280285 _ => Err ( format ! ( "unknown type path: {}" , type_path) ) ,
281286 }
282287 }
@@ -609,6 +614,29 @@ impl<'g> GrammarInterpreter<'g> {
609614 step : step. map ( Box :: new) ,
610615 } )
611616 }
617+ "Lambda" => {
618+ // Lambda expression: def(x): x * 2
619+ let params = self . get_field_as_lambda_param_list ( "params" , fields, state) ?;
620+ let body = self . get_field_as_expr ( "body" , fields, state) ?;
621+
622+ TypedExpression :: Lambda ( TypedLambda {
623+ params,
624+ body : TypedLambdaBody :: Expression ( Box :: new ( body) ) ,
625+ captures : vec ! [ ] ,
626+ } )
627+ }
628+ "ImportModifier" => {
629+ // Import modifier expression: import asset("image.jpg") as Image
630+ let loader = self . get_field_as_interned ( "loader" , fields, state) ?;
631+ let path = self . get_field_as_interned ( "path" , fields, state) ?;
632+ let target_type = self . get_field_as_interned ( "target_type" , fields, state) ?;
633+
634+ TypedExpression :: ImportModifier ( TypedImportModifier {
635+ loader,
636+ path,
637+ target_type,
638+ } )
639+ }
612640 _ => return Err ( format ! ( "unknown TypedExpression variant: {}" , variant) ) ,
613641 } ;
614642
@@ -864,6 +892,16 @@ impl<'g> GrammarInterpreter<'g> {
864892 span,
865893 } )
866894 }
895+ "ExternStruct" => {
896+ let name = self . get_field_as_interned ( "name" , fields, state) ?;
897+ let type_params = self . get_field_as_type_param_list ( "type_params" , fields, state) ?;
898+
899+ TypedDeclaration :: Extern ( TypedExtern :: Struct ( TypedExternStruct {
900+ name,
901+ runtime_prefix : name, // Use name as default runtime prefix
902+ type_params,
903+ } ) )
904+ }
867905 _ => return Err ( format ! ( "unknown TypedDeclaration variant: {}" , variant) ) ,
868906 } ;
869907
@@ -1288,6 +1326,22 @@ impl<'g> GrammarInterpreter<'g> {
12881326 } ) )
12891327 }
12901328
1329+ /// Construct a TypedLambdaParam (lambda parameter)
1330+ fn construct_lambda_param < ' a > (
1331+ & self ,
1332+ fields : & [ ( String , ExprIR ) ] ,
1333+ state : & mut ParserState < ' a > ,
1334+ _span : Span ,
1335+ ) -> Result < ParsedValue , String > {
1336+ let name = self . get_field_as_interned ( "name" , fields, state) ?;
1337+ let ty = self . get_field_optional ( "ty" , fields, state) ?;
1338+
1339+ Ok ( ParsedValue :: LambdaParam ( TypedLambdaParam {
1340+ name,
1341+ ty,
1342+ } ) )
1343+ }
1344+
12911345 /// Get a field value as a Type
12921346 fn get_field_as_type < ' a > (
12931347 & self ,
@@ -2873,6 +2927,108 @@ impl<'g> GrammarInterpreter<'g> {
28732927 }
28742928 }
28752929
2930+ /// Get a field as a list of TypedTypeParam
2931+ fn get_field_as_type_param_list < ' a > (
2932+ & self ,
2933+ name : & str ,
2934+ fields : & [ ( String , ExprIR ) ] ,
2935+ state : & mut ParserState < ' a > ,
2936+ ) -> Result < Vec < TypedTypeParam > , String > {
2937+ match self . get_field ( name, fields) {
2938+ Some ( expr) => {
2939+ let val = self . eval_expr ( expr, state) ?;
2940+ match val {
2941+ ParsedValue :: List ( items) => {
2942+ let mut result = Vec :: new ( ) ;
2943+ for item in items {
2944+ let interned = self . parsed_value_to_interned ( item, state) ?;
2945+ result. push ( TypedTypeParam {
2946+ name : interned,
2947+ bounds : vec ! [ ] ,
2948+ default : None ,
2949+ span : Span :: default ( ) ,
2950+ } ) ;
2951+ }
2952+ Ok ( result)
2953+ }
2954+ ParsedValue :: None => Ok ( vec ! [ ] ) ,
2955+ ParsedValue :: Optional ( None ) => Ok ( vec ! [ ] ) ,
2956+ ParsedValue :: Interned ( i) => Ok ( vec ! [ TypedTypeParam {
2957+ name: i,
2958+ bounds: vec![ ] ,
2959+ default : None ,
2960+ span: Span :: default ( ) ,
2961+ } ] ) ,
2962+ ParsedValue :: Text ( s) => Ok ( vec ! [ TypedTypeParam {
2963+ name: state. intern( & s) ,
2964+ bounds: vec![ ] ,
2965+ default : None ,
2966+ span: Span :: default ( ) ,
2967+ } ] ) ,
2968+ _ => Err ( format ! ( "field '{}' is not a type param list" , name) ) ,
2969+ }
2970+ }
2971+ None => Ok ( vec ! [ ] ) ,
2972+ }
2973+ }
2974+
2975+ /// Get a field as a list of lambda parameters
2976+ fn get_field_as_lambda_param_list < ' a > (
2977+ & self ,
2978+ name : & str ,
2979+ fields : & [ ( String , ExprIR ) ] ,
2980+ state : & mut ParserState < ' a > ,
2981+ ) -> Result < Vec < TypedLambdaParam > , String > {
2982+ match self . get_field ( name, fields) {
2983+ Some ( expr) => {
2984+ let val = self . eval_expr ( expr, state) ?;
2985+ match val {
2986+ ParsedValue :: List ( items) => {
2987+ let mut result = Vec :: new ( ) ;
2988+ for item in items {
2989+ let param = self . parsed_value_to_lambda_param ( item, state) ?;
2990+ result. push ( param) ;
2991+ }
2992+ Ok ( result)
2993+ }
2994+ ParsedValue :: None => Ok ( vec ! [ ] ) ,
2995+ ParsedValue :: Optional ( None ) => Ok ( vec ! [ ] ) ,
2996+ ParsedValue :: LambdaParam ( p) => Ok ( vec ! [ p] ) ,
2997+ ParsedValue :: Interned ( i) => Ok ( vec ! [ TypedLambdaParam {
2998+ name: i,
2999+ ty: None ,
3000+ } ] ) ,
3001+ ParsedValue :: Text ( s) => Ok ( vec ! [ TypedLambdaParam {
3002+ name: state. intern( & s) ,
3003+ ty: None ,
3004+ } ] ) ,
3005+ _ => Err ( format ! ( "field '{}' is not a lambda param list: {:?}" , name, val) ) ,
3006+ }
3007+ }
3008+ None => Ok ( vec ! [ ] ) ,
3009+ }
3010+ }
3011+
3012+ /// Convert ParsedValue to TypedLambdaParam
3013+ fn parsed_value_to_lambda_param < ' a > (
3014+ & self ,
3015+ val : ParsedValue ,
3016+ state : & mut ParserState < ' a > ,
3017+ ) -> Result < TypedLambdaParam , String > {
3018+ match val {
3019+ ParsedValue :: LambdaParam ( p) => Ok ( p) ,
3020+ ParsedValue :: Interned ( i) => Ok ( TypedLambdaParam {
3021+ name : i,
3022+ ty : None ,
3023+ } ) ,
3024+ ParsedValue :: Text ( s) => Ok ( TypedLambdaParam {
3025+ name : state. intern ( & s) ,
3026+ ty : None ,
3027+ } ) ,
3028+ _ => Err ( format ! ( "cannot convert value to lambda param: {:?}" , val) ) ,
3029+ }
3030+ }
3031+
28763032 /// Convert ParsedValue to TypedEffectOp
28773033 fn parsed_value_to_effect_op ( & self , val : ParsedValue ) -> Result < zyntax_typed_ast:: TypedEffectOp , String > {
28783034 match val {
0 commit comments