diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index e102a7a..40669f7 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -183,19 +183,24 @@ fn reduce_lambda(params: &Vec, body: &Block, symbol_table: &SymbolT } fn reduce_named_struct(name: &Rc, fields: &Vec<(Rc, Meta)>, symbol_table: &SymbolTable) -> Expr { - let (type_name, table_fields) = match symbol_table.lookup_by_name(name) { - Some(Symbol { spec: SymbolSpec::RecordConstructor { members, type_name }, .. }) => (type_name, members), + let (type_name, index, members_from_table) = match symbol_table.lookup_by_name(name) { + Some(Symbol { spec: SymbolSpec::RecordConstructor { members, type_name, index }, .. }) => (type_name.clone(), index, members), _ => return Expr::ReductionError("Not a record constructor".to_string()), }; - /* - let arity = table_fields.len(); - let f = Expr::Constructor { - type_name, arity, - }; - let args = fields.map(; + let arity = members_from_table.len(); + + let mut args: Vec<(Rc, Expr)> = fields.iter() + .map(|(name, expr)| (name.clone(), expr.node().reduce(symbol_table))) + .collect(); + + args.as_mut_slice() + .sort_unstable_by(|(name1, _), (name2, _)| name1.cmp(name2)); //arbitrary - sorting by alphabetical order + + let args = args.into_iter().map(|(_, expr)| expr).collect(); + + //TODO make sure this sorting actually works + let f = box Expr::Constructor { type_name, name: name.clone(), tag: *index, arity, }; Expr::Call { f, args } - */ - panic!("Still not done") } fn reduce_call_expression(func: &Meta, arguments: &Vec>, symbol_table: &SymbolTable) -> Expr { diff --git a/schala-lang/language/src/symbol_table.rs b/schala-lang/language/src/symbol_table.rs index cc2cb21..af43168 100644 --- a/schala-lang/language/src/symbol_table.rs +++ b/schala-lang/language/src/symbol_table.rs @@ -81,6 +81,7 @@ pub enum SymbolSpec { type_args: Vec>, }, RecordConstructor { + index: usize, members: HashMap, TypeName>, type_name: TypeName, }, @@ -93,7 +94,7 @@ impl fmt::Display for SymbolSpec { match self { Func(type_names) => write!(f, "Func({:?})", type_names), DataConstructor { index, type_name, type_args } => write!(f, "DataConstructor(idx: {})({:?} -> {})", index, type_args, type_name), - RecordConstructor { type_name, ..} => write!(f, "RecordConstructor( -> {})", type_name), + RecordConstructor { type_name, index, ..} => write!(f, "RecordConstructor(idx: {})( -> {})", index, type_name), Binding => write!(f, "Binding"), } } @@ -226,7 +227,7 @@ impl SymbolTable { if duplicate_member_definitions.len() != 0 { return Err(format!("Duplicate member(s) in definition of type {}: {:?}", type_name, duplicate_member_definitions)); } - let spec = SymbolSpec::RecordConstructor { type_name: type_name.clone(), members }; + let spec = SymbolSpec::RecordConstructor { index, type_name: type_name.clone(), members }; self.add_new_symbol(name, scope_name_stack, spec); }, }