From a730b48c49ab2afc292d25c85072cf71ee2db262 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sun, 23 Mar 2025 14:56:44 +0100
Subject: [PATCH] add SugaredStructMember & SugaredVariantEnum

---
 src/pretty.rs |  15 ++++++-
 src/sugar.rs  | 120 +++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 123 insertions(+), 12 deletions(-)

diff --git a/src/pretty.rs b/src/pretty.rs
index 40a7541..47f85f7 100644
--- a/src/pretty.rs
+++ b/src/pretty.rs
@@ -1,9 +1,20 @@
 use {
-    crate::{TypeDict, dict::TypeID},
-    crate::sugar::SugaredTypeTerm,
+    crate::{dict::TypeID, sugar::SugaredTypeTerm, SugaredStructMember, SugaredEnumVariant, TypeDict},
     tiny_ansi::TinyAnsi
 };
 
+
+impl SugaredStructMember {
+    pub fn pretty(&self, dict: &TypeDict, indent: u64) -> String {
+        format!("{}: {}", self.symbol, self.ty.pretty(dict, indent+1))
+    }
+}
+impl SugaredEnumVariant {
+    pub fn pretty(&self, dict: &TypeDict, indent: u64) -> String {
+        format!("{}: {}", self.symbol, self.ty.pretty(dict, indent+1))
+    }
+}
+
 impl SugaredTypeTerm {
     pub fn pretty(&self, dict: &TypeDict, indent: u64) -> String {
         let indent_width = 4;
diff --git a/src/sugar.rs b/src/sugar.rs
index 4734b6f..aa1ff4e 100644
--- a/src/sugar.rs
+++ b/src/sugar.rs
@@ -1,7 +1,19 @@
 use {
-    crate::{TypeTerm, TypeID, parser::ParseLadderType}
+    crate::{parser::ParseLadderType, TypeDict, TypeID, TypeTerm}
 };
 
+#[derive(Clone, PartialEq)]
+pub struct SugaredStructMember {
+    pub symbol: String,
+    pub ty: SugaredTypeTerm
+}
+
+#[derive(Clone, PartialEq)]
+pub struct SugaredEnumVariant {
+    pub symbol: String,
+    pub ty: SugaredTypeTerm
+}
+
 #[derive(Clone, PartialEq)]
 pub enum SugaredTypeTerm {
     TypeID(TypeID),
@@ -12,11 +24,73 @@ pub enum SugaredTypeTerm {
     Func(Vec< SugaredTypeTerm >),
     Morph(Vec< SugaredTypeTerm >),
     Ladder(Vec< SugaredTypeTerm >),
-    Struct(Vec< SugaredTypeTerm >),
-    Enum(Vec< SugaredTypeTerm >),
+    Struct(Vec< SugaredStructMember >),
+    Enum(Vec< SugaredEnumVariant >),
     Seq(Vec< SugaredTypeTerm >)
 }
 
+impl SugaredStructMember {
+    pub fn parse( dict: &mut impl TypeDict, ty: &TypeTerm ) -> Option<Self> {
+        match ty {
+            TypeTerm::App(args) => {
+                if args.len() != 3 {
+                    return None;
+                }
+
+                if args[0] != dict.parse("Struct.Field").expect("parse") {
+                    return None;
+                }
+
+                let symbol = match args[1] {
+                    TypeTerm::Char(c) => c.to_string(),
+                    TypeTerm::TypeID(id) => dict.get_typename(&id).expect("cant get member name"),
+                    _ => {
+                        return None;
+                    }
+                };
+
+                let ty = args[2].clone().sugar(dict);
+
+                Some(SugaredStructMember { symbol, ty })
+            }
+            _ => {
+                None
+            }
+        }
+    }
+}
+
+impl SugaredEnumVariant {
+    pub fn parse( dict: &mut impl TypeDict, ty: &TypeTerm ) -> Option<Self> {
+        match ty {
+            TypeTerm::App(args) => {
+                if args.len() != 3 {
+                    return None;
+                }
+
+                if args[0] != dict.parse("Enum.Variant").expect("parse") {
+                    return None;
+                }
+
+                let symbol = match args[1] {
+                    TypeTerm::Char(c) => c.to_string(),
+                    TypeTerm::TypeID(id) => dict.get_typename(&id).expect("cant get member name"),
+                    _ => {
+                        return None;
+                    }
+                };
+
+                let ty = args[2].clone().sugar(dict);
+
+                Some(SugaredEnumVariant { symbol, ty })
+            }
+            _ => {
+                None
+            }
+        }
+    }
+}
+
 impl TypeTerm {
     pub fn sugar(self: TypeTerm, dict: &mut impl crate::TypeDict) -> SugaredTypeTerm {
         match self {
@@ -31,10 +105,10 @@ impl TypeTerm {
                     SugaredTypeTerm::Morph( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() )
                 }
                 else if first == &dict.parse("Struct").unwrap() {
-                    SugaredTypeTerm::Struct( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() )
+                    SugaredTypeTerm::Struct( args[1..].into_iter().map(|t| SugaredStructMember::parse(dict, t).expect("cant parse field")).collect() )
                 }
                 else if first == &dict.parse("Enum").unwrap() {
-                    SugaredTypeTerm::Enum( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() )
+                    SugaredTypeTerm::Enum( args[1..].into_iter().map(|t| SugaredEnumVariant::parse(dict, t).expect("cant parse variant")).collect() )
                 }
                 else if first == &dict.parse("Seq").unwrap() {
                     SugaredTypeTerm::Seq( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() )
@@ -55,12 +129,33 @@ impl TypeTerm {
             } else {
                 SugaredTypeTerm::Spec(args.into_iter().map(|t| t.sugar(dict)).collect())
             },
-            TypeTerm::Ladder(rungs) =>            
+            TypeTerm::Ladder(rungs) =>
                SugaredTypeTerm::Ladder(rungs.into_iter().map(|t| t.sugar(dict)).collect())
         }
     }
 }
 
+
+impl SugaredStructMember {
+    pub fn desugar(self, dict: &mut impl crate::TypeDict) -> TypeTerm {
+        TypeTerm::App(vec![
+            dict.parse("Struct.Field").expect("parse"),
+            dict.parse(&self.symbol).expect("parse"),
+            self.ty.desugar(dict)
+        ])
+    }
+}
+
+impl SugaredEnumVariant {
+    pub fn desugar(self, dict: &mut impl crate::TypeDict) -> TypeTerm {
+        TypeTerm::App(vec![
+            dict.parse("Enum.Variant").expect("parse"),
+            dict.parse(&self.symbol).expect("parse"),
+            self.ty.desugar(dict)
+        ])
+    }
+}
+
 impl SugaredTypeTerm {
     pub fn desugar(self, dict: &mut impl crate::TypeDict) -> TypeTerm {
         match self {
@@ -103,12 +198,17 @@ impl SugaredTypeTerm {
             SugaredTypeTerm::Ladder(ts) |
             SugaredTypeTerm::Func(ts) |
             SugaredTypeTerm::Morph(ts) |
-            SugaredTypeTerm::Struct(ts) |
-            SugaredTypeTerm::Enum(ts) |
             SugaredTypeTerm::Seq(ts) => {
-                ts.iter().fold(true, |s,t|s&&t.is_empty())
+                ts.iter().fold(true, |s,t| s && t.is_empty() )
+            }
+            SugaredTypeTerm::Struct(ts) => {
+                ts.iter()
+                    .fold(true, |s,member_decl| s && member_decl.ty.is_empty() )
+            }
+            SugaredTypeTerm::Enum(ts) => {
+                ts.iter()
+                    .fold(true, |s,variant_decl| s && variant_decl.ty.is_empty() )
             }
         }
     }
 }
-