diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index ca2f2f15..870713ba 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -636,7 +636,8 @@ impl Nac3 { TopLevelDef::Function { codegen_callback, .. } => { *codegen_callback = Some(rpc_codegen_callback(*is_async)); } - TopLevelDef::Class { methods, .. } => { + TopLevelDef::Class { methods, .. } | TopLevelDef::Module { methods, .. } => { + // TODO: Update this to handle functions as well let (class_def, method_name) = class_data.as_ref().unwrap(); for (name, _, id) in &*methods { if name != method_name { diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 0118ca43..0dbf65ee 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -980,6 +980,7 @@ pub fn gen_call<'ctx, G: CodeGenerator>( return Ok(Some(generator.gen_constructor(ctx, fun.0, &def, params)?)) } TopLevelDef::Variable { .. } => unreachable!(), + TopLevelDef::Module { .. } => unreachable!(), // TODO: Throw error here } } .or_else(|_: String| { diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 6040ced1..499fed79 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -101,7 +101,9 @@ impl TopLevelComposer { let builtin_name_list = definition_ast_list .iter() .map(|def_ast| match *def_ast.0.read() { - TopLevelDef::Class { name, .. } => name.to_string(), + TopLevelDef::Class { name, .. } | TopLevelDef::Module { name, .. } => { + name.to_string() + } TopLevelDef::Function { simple_name, .. } | TopLevelDef::Variable { simple_name, .. } => simple_name.to_string(), }) diff --git a/nac3core/src/toplevel/helper.rs b/nac3core/src/toplevel/helper.rs index 71c1859b..81eb47b6 100644 --- a/nac3core/src/toplevel/helper.rs +++ b/nac3core/src/toplevel/helper.rs @@ -359,6 +359,23 @@ pub fn make_exception_fields(int32: Type, int64: Type, str: Type) -> Vec<(StrRef impl TopLevelDef { pub fn to_string(&self, unifier: &mut Unifier) -> String { match self { + TopLevelDef::Module { name, fields, methods, .. } => { + let fields_str = fields + .iter() + .map(|(n, ty, _)| (n.to_string(), unifier.stringify(*ty))) + .collect_vec(); + + let methods_str = methods + .iter() + .map(|(n, ty, id)| (n.to_string(), unifier.stringify(*ty), *id)) + .collect_vec(); + format!( + "Module {{\nname: {:?},\nfields: {:?},\nmethods: {:?}\n}}", + name, + fields_str.iter().map(|(a, _)| a).collect_vec(), + methods_str.iter().map(|(a, b, _)| (a, b)).collect_vec(), + ) + } TopLevelDef::Class { name, ancestors, fields, methods, type_vars, .. } => { let fields_str = fields .iter() diff --git a/nac3core/src/toplevel/mod.rs b/nac3core/src/toplevel/mod.rs index cba2f5e7..346932ef 100644 --- a/nac3core/src/toplevel/mod.rs +++ b/nac3core/src/toplevel/mod.rs @@ -92,6 +92,24 @@ pub struct FunInstance { #[derive(Debug, Clone)] pub enum TopLevelDef { + Module { + /// Module name + name: StrRef, + /// Module fields. + /// + /// Name and type is mutable. + fields: Vec<(StrRef, Type, bool)>, + /// Module Attributes. + /// + /// Name, type, value. + attributes: Vec<(StrRef, Type, ast::Constant)>, + /// Class methods, pointing to the corresponding function definition. + methods: Vec<(StrRef, Type, DefinitionId)>, + /// Symbol resolver of the module defined the class; [None] if it is built-in type. + resolver: Option>, + /// Definition location. + loc: Option, + }, Class { /// Name for error messages and symbols. name: StrRef, diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index 6068f630..a057e894 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -2695,7 +2695,7 @@ impl<'a> Inferencer<'a> { .read() .iter() .map(|def| match *def.read() { - TopLevelDef::Class { name, .. } => (name, false), + TopLevelDef::Class { name, .. } | TopLevelDef::Module { name, .. } => (name, false), // TODO: Check if should be global TopLevelDef::Function { simple_name, .. } => (simple_name, false), TopLevelDef::Variable { simple_name, .. } => (simple_name, true), })