diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 809b7cc4b..fa80fb810 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -6,7 +6,7 @@ use nac3core::{ }, symbol_resolver::ValueEnum, toplevel::{DefinitionId, GenCall}, - typecheck::typedef::{FunSignature, FuncArg, Type, TypeEnum} + typecheck::typedef::{FunSignature, FuncArg, Type, TypeEnum}, }; use nac3parser::ast::{Expr, ExprKind, Located, Stmt, StmtKind, StrRef}; @@ -15,7 +15,10 @@ use inkwell::{ context::Context, module::Linkage, types::IntType, values::BasicValueEnum, AddressSpace, }; -use pyo3::{PyObject, PyResult, Python, types::{PyDict, PyList}}; +use pyo3::{ + types::{PyDict, PyList}, + PyObject, PyResult, Python, +}; use crate::{symbol_resolver::InnerResolver, timeline::TimeFns}; @@ -68,7 +71,11 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { ) -> Result>, String> { let result = gen_call(self, ctx, obj, fun, params)?; if let Some(end) = self.end.clone() { - let old_end = self.gen_expr(ctx, &end)?.unwrap().to_basic_value_enum(ctx, self, end.custom.unwrap())?; + let old_end = self.gen_expr(ctx, &end)?.unwrap().to_basic_value_enum( + ctx, + self, + end.custom.unwrap(), + )?; let now = self.timeline.emit_now_mu(ctx); let smax = ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| { let i64 = ctx.ctx.i64_type(); @@ -88,7 +95,11 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { ctx.builder.build_store(end_store, max); } if let Some(start) = self.start.clone() { - let start_val = self.gen_expr(ctx, &start)?.unwrap().to_basic_value_enum(ctx, self, start.custom.unwrap())?; + let start_val = self.gen_expr(ctx, &start)?.unwrap().to_basic_value_enum( + ctx, + self, + start.custom.unwrap(), + )?; self.timeline.emit_at_mu(ctx, start_val); } Ok(result) @@ -120,7 +131,11 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { let old_start = self.start.take(); let old_end = self.end.take(); let now = if let Some(old_start) = &old_start { - self.gen_expr(ctx, old_start)?.unwrap().to_basic_value_enum(ctx, self, old_start.custom.unwrap())? + self.gen_expr(ctx, old_start)?.unwrap().to_basic_value_enum( + ctx, + self, + old_start.custom.unwrap(), + )? } else { self.timeline.emit_now_mu(ctx) }; @@ -174,10 +189,11 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { }; // set duration let end_expr = self.end.take().unwrap(); - let end_val = self - .gen_expr(ctx, &end_expr)? - .unwrap() - .to_basic_value_enum(ctx, self, end_expr.custom.unwrap())?; + let end_val = self.gen_expr(ctx, &end_expr)?.unwrap().to_basic_value_enum( + ctx, + self, + end_expr.custom.unwrap(), + )?; // inside a sequential block if old_start.is_none() { @@ -293,7 +309,7 @@ fn rpc_codegen_callback_fn<'ctx, 'a>( let int32 = ctx.ctx.i32_type(); let tag_ptr_type = ctx.ctx.struct_type(&[ptr_type.into(), size_type.into()], false); - let service_id = int32.const_int(fun.1.0 as u64, false); + let service_id = int32.const_int(fun.1 .0 as u64, false); // -- setup rpc tags let mut tag = Vec::new(); if obj.is_some() { @@ -363,10 +379,8 @@ fn rpc_codegen_callback_fn<'ctx, 'a>( } // default value handling for k in keys.into_iter() { - mapping.insert( - k.name, - ctx.gen_symbol_val(generator, &k.default_value.unwrap(), k.ty).into() - ); + mapping + .insert(k.name, ctx.gen_symbol_val(generator, &k.default_value.unwrap(), k.ty).into()); } // reorder the parameters let mut real_params = fun @@ -507,9 +521,15 @@ pub fn attributes_writeback<'ctx, 'a>( let mut scratch_buffer = Vec::new(); for (_, val) in globals.iter() { let val = val.as_ref(py); - let ty = inner_resolver.get_obj_type(py, val, &mut ctx.unifier, &top_levels, &ctx.primitives)?; + let ty = inner_resolver.get_obj_type( + py, + val, + &mut ctx.unifier, + &top_levels, + &ctx.primitives, + )?; if let Err(ty) = ty { - return Ok(Err(ty)) + return Ok(Err(ty)); } let ty = ty.unwrap(); match &*ctx.unifier.get_ty(ty) { @@ -522,14 +542,18 @@ pub fn attributes_writeback<'ctx, 'a>( let obj = inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap(); for (name, (field_ty, is_mutable)) in fields.iter() { if !is_mutable { - continue + continue; } if gen_rpc_tag(ctx, *field_ty, &mut scratch_buffer).is_ok() { attributes.push(name.to_string()); let index = ctx.get_attr_index(ty, *name); - values.push((*field_ty, ctx.build_gep_and_load( - obj.into_pointer_value(), - &[zero, int32.const_int(index as u64, false)]))); + values.push(( + *field_ty, + ctx.build_gep_and_load( + obj.into_pointer_value(), + &[zero, int32.const_int(index as u64, false)], + ), + )); } } if !attributes.is_empty() { @@ -538,33 +562,43 @@ pub fn attributes_writeback<'ctx, 'a>( pydict.set_item("fields", attributes)?; host_attributes.append(pydict)?; } - }, + } TypeEnum::TList { ty: elem_ty } => { if gen_rpc_tag(ctx, *elem_ty, &mut scratch_buffer).is_ok() { let pydict = PyDict::new(py); pydict.set_item("obj", val)?; host_attributes.append(pydict)?; - values.push((ty, inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap())); + values.push(( + ty, + inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap(), + )); } - }, + } _ => {} } } let fun = FunSignature { - args: values.iter().enumerate().map(|(i, (ty, _))| FuncArg { - name: i.to_string().into(), - ty: *ty, - default_value: None - }).collect(), + args: values + .iter() + .enumerate() + .map(|(i, (ty, _))| FuncArg { + name: i.to_string().into(), + ty: *ty, + default_value: None, + }) + .collect(), ret: ctx.primitives.none, - vars: Default::default() + vars: Default::default(), }; - let args: Vec<_> = values.into_iter().map(|(_, val)| (None, ValueEnum::Dynamic(val))).collect(); - if let Err(e) = rpc_codegen_callback_fn(ctx, None, (&fun, DefinitionId(0)), args, generator) { + let args: Vec<_> = + values.into_iter().map(|(_, val)| (None, ValueEnum::Dynamic(val))).collect(); + if let Err(e) = rpc_codegen_callback_fn(ctx, None, (&fun, DefinitionId(0)), args, generator) + { return Ok(Err(e)); } Ok(Ok(())) - }).unwrap()?; + }) + .unwrap()?; Ok(()) } diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index d6ed943fa..26af419e0 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -17,9 +17,9 @@ use nac3parser::{ ast::{self, ExprKind, Stmt, StmtKind, StrRef}, parser::{self, parse_program}, }; +use pyo3::create_exception; use pyo3::prelude::*; use pyo3::{exceptions, types::PyBytes, types::PyDict, types::PySet}; -use pyo3::create_exception; use parking_lot::{Mutex, RwLock}; @@ -40,7 +40,7 @@ use tempfile::{self, TempDir}; use crate::codegen::attributes_writeback; use crate::{ codegen::{rpc_codegen_callback, ArtiqCodeGenerator}, - symbol_resolver::{InnerResolver, PythonHelper, Resolver, DeferredEvaluationStore}, + symbol_resolver::{DeferredEvaluationStore, InnerResolver, PythonHelper, Resolver}, }; mod codegen; @@ -93,7 +93,7 @@ struct Nac3 { top_levels: Vec, string_store: Arc>>, exception_ids: Arc>>, - deferred_eval_store: DeferredEvaluationStore + deferred_eval_store: DeferredEvaluationStore, } create_exception!(nac3artiq, CompileError, exceptions::PyException); @@ -268,7 +268,7 @@ fn add_exceptions( composer: &mut TopLevelComposer, builtin_def: &mut HashMap, builtin_ty: &mut HashMap, - error_names: &[&str] + error_names: &[&str], ) -> Vec { let mut types = Vec::new(); // note: this is only for builtin exceptions, i.e. the exception name is "0:{exn}" @@ -281,7 +281,7 @@ fn add_exceptions( // constructor id def_id + 1, &mut composer.unifier, - &composer.primitives_ty + &composer.primitives_ty, ); composer.definition_ast_list.push((Arc::new(RwLock::new(exception_class)), None)); composer.definition_ast_list.push((Arc::new(RwLock::new(exception_fn)), None)); @@ -331,7 +331,8 @@ impl Nac3 { }, Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| { let arg_ty = fun.0.args[0].ty; - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap(); + let arg = + args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap(); time_fns.emit_at_mu(ctx, arg); Ok(None) }))), @@ -349,7 +350,8 @@ impl Nac3 { }, Arc::new(GenCall::new(Box::new(move |ctx, _, fun, args, generator| { let arg_ty = fun.0.args[0].ty; - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap(); + let arg = + args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty).unwrap(); time_fns.emit_delay_mu(ctx, arg); Ok(None) }))), @@ -363,18 +365,19 @@ impl Nac3 { let types_mod = PyModule::import(py, "types").unwrap(); let get_id = |x| id_fn.call1((x,)).unwrap().extract().unwrap(); - let get_attr_id = |obj: &PyModule, attr| id_fn.call1((obj.getattr(attr).unwrap(),)) - .unwrap().extract().unwrap(); + let get_attr_id = |obj: &PyModule, attr| { + id_fn.call1((obj.getattr(attr).unwrap(),)).unwrap().extract().unwrap() + }; let primitive_ids = PrimitivePythonId { virtual_id: get_id( - builtins_mod - .getattr("globals") - .unwrap() - .call0() - .unwrap() - .get_item("virtual") - .unwrap( - )), + builtins_mod + .getattr("globals") + .unwrap() + .call0() + .unwrap() + .get_item("virtual") + .unwrap(), + ), generic_alias: ( get_attr_id(typing_mod, "_GenericAlias"), get_attr_id(types_mod, "GenericAlias"), @@ -519,8 +522,9 @@ impl Nac3 { let class_obj; if let StmtKind::ClassDef { name, .. } = &stmt.node { let class = py_module.getattr(name.to_string()).unwrap(); - if issubclass.call1((class, exn_class)).unwrap().extract().unwrap() && - class.getattr("artiq_builtin").is_err() { + if issubclass.call1((class, exn_class)).unwrap().extract().unwrap() + && class.getattr("artiq_builtin").is_err() + { class_obj = Some(class); } else { class_obj = None; @@ -566,13 +570,12 @@ impl Nac3 { let (name, def_id, ty) = composer .register_top_level(stmt.clone(), Some(resolver.clone()), path.clone()) .map_err(|e| { - CompileError::new_err(format!( - "compilation failed\n----------\n{}", - e - )) + CompileError::new_err(format!("compilation failed\n----------\n{}", e)) })?; if let Some(class_obj) = class_obj { - self.exception_ids.write().insert(def_id.0, store_obj.call1(py, (class_obj, ))?.extract(py)?); + self.exception_ids + .write() + .insert(def_id.0, store_obj.call1(py, (class_obj,))?.extract(py)?); } match &stmt.node { @@ -642,7 +645,8 @@ impl Nac3 { exception_ids: self.exception_ids.clone(), deferred_eval_store: self.deferred_eval_store.clone(), }); - let resolver = Arc::new(Resolver(inner_resolver.clone())) as Arc; + let resolver = + Arc::new(Resolver(inner_resolver.clone())) as Arc; let (_, def_id, _) = composer .register_top_level(synthesized.pop().unwrap(), Some(resolver.clone()), "".into()) .unwrap(); @@ -651,8 +655,12 @@ impl Nac3 { FunSignature { args: vec![], ret: self.primitive.none, vars: HashMap::new() }; let mut store = ConcreteTypeStore::new(); let mut cache = HashMap::new(); - let signature = - store.from_signature(&mut composer.unifier, &self.primitive, &fun_signature, &mut cache); + let signature = store.from_signature( + &mut composer.unifier, + &self.primitive, + &fun_signature, + &mut cache, + ); let signature = store.add_cty(signature); if let Err(e) = composer.start_analysis(true) { @@ -738,8 +746,12 @@ impl Nac3 { let mut store = ConcreteTypeStore::new(); let mut cache = HashMap::new(); - let signature = - store.from_signature(&mut composer.unifier, &self.primitive, &fun_signature, &mut cache); + let signature = store.from_signature( + &mut composer.unifier, + &self.primitive, + &fun_signature, + &mut cache, + ); let signature = store.add_cty(signature); let attributes_writeback_task = CodeGenTask { subst: Default::default(), @@ -777,14 +789,23 @@ impl Nac3 { registry.add_task(task); registry.wait_tasks_complete(handles); - let mut generator = ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns); + let mut generator = + ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns); let context = inkwell::context::Context::create(); let module = context.create_module("attributes_writeback"); let builder = context.create_builder(); - let (_, module, _) = gen_func_impl(&context, &mut generator, ®istry, builder, module, - attributes_writeback_task, |generator, ctx| { + let (_, module, _) = gen_func_impl( + &context, + &mut generator, + ®istry, + builder, + module, + attributes_writeback_task, + |generator, ctx| { attributes_writeback(ctx, generator, inner_resolver.as_ref(), host_attributes) - }).unwrap(); + }, + ) + .unwrap(); let buffer = module.write_bitcode_to_memory(); let buffer = buffer.as_slice().into(); membuffer.lock().push(buffer); @@ -800,13 +821,22 @@ impl Nac3 { .create_module_from_ir(MemoryBuffer::create_from_memory_range(buffer, "main")) .unwrap(); - main.link_in_module(other) - .map_err(|err| CompileError::new_err(err.to_string()))?; + main.link_in_module(other).map_err(|err| CompileError::new_err(err.to_string()))?; } let builder = context.create_builder(); - let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap(); + let modinit_return = main + .get_function("__modinit__") + .unwrap() + .get_last_basic_block() + .unwrap() + .get_terminator() + .unwrap(); builder.position_before(&modinit_return); - builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback"); + builder.build_call( + main.get_function("attributes_writeback").unwrap(), + &[], + "attributes_writeback", + ); main.link_in_module(load_irrt(&context)) .map_err(|err| CompileError::new_err(err.to_string()))?; @@ -880,9 +910,7 @@ impl Nac3 { return Err(CompileError::new_err("failed to start linker")); } } else { - return Err(CompileError::new_err( - "linker returned non-zero status code", - )); + return Err(CompileError::new_err("linker returned non-zero status code")); } Ok(()) diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index b4f1cc3c6..b2f4b333b 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -17,9 +17,9 @@ use pyo3::{ use std::{ collections::HashMap, sync::{ + atomic::{AtomicBool, Ordering::Relaxed}, Arc, - atomic::{AtomicBool, Ordering::Relaxed} - } + }, }; use crate::PrimitivePythonId; @@ -153,7 +153,8 @@ impl StaticValue for PythonValue { self.resolver .get_obj_value(py, self.value.as_ref(py), ctx, generator, expected_ty) .map(Option::unwrap) - }).map_err(|e| e.to_string()) + }) + .map_err(|e| e.to_string()) } fn get_field<'ctx, 'a>( @@ -175,9 +176,9 @@ impl StaticValue for PythonValue { let obj = self.value.getattr(py, &name.to_string())?; let id = self.resolver.helper.id_fn.call1(py, (&obj,))?.extract(py)?; if self.id == self.resolver.primitive_ids.none { - return Ok(None) + return Ok(None); } else { - return Ok(Some((id, obj))) + return Ok(Some((id, obj))); } } let def_id = { *self.resolver.pyid_to_def.read().get(&ty_id).unwrap() }; @@ -384,11 +385,11 @@ impl InnerResolver { } } if needs_defer { - self.deferred_eval_store.store.write() - .push((result.clone(), - constraints.extract()?, - pyty.getattr("__name__")?.extract::()? - )) + self.deferred_eval_store.store.write().push(( + result.clone(), + constraints.extract()?, + pyty.getattr("__name__")?.extract::()?, + )) } result }; @@ -531,10 +532,7 @@ impl InnerResolver { let str_fn = pyo3::types::PyModule::import(py, "builtins").unwrap().getattr("repr").unwrap(); let str_repr: String = str_fn.call1((pyty,)).unwrap().extract().unwrap(); - Ok(Err(format!( - "{} is not registered with NAC3 (@nac3 decorator missing?)", - str_repr - ))) + Ok(Err(format!("{} is not registered with NAC3 (@nac3 decorator missing?)", str_repr))) } } @@ -549,7 +547,7 @@ impl InnerResolver { let ty = self.helper.type_fn.call1(py, (obj,)).unwrap(); let py_obj_id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?; if let Some(ty) = self.pyid_to_type.read().get(&py_obj_id) { - return Ok(Ok(*ty)) + return Ok(Ok(*ty)); } let (extracted_ty, inst_check) = match self.get_pyty_obj_type( py, @@ -616,7 +614,7 @@ impl InnerResolver { let field_data = match obj.getattr("_nac3_option") { Ok(d) => d, // we use `none = Option(None)`, so the obj always have attr `_nac3_option` - Err(_) => unreachable!("cannot be None") + Err(_) => unreachable!("cannot be None"), }; // if is `none` let zelf_id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?; @@ -627,7 +625,9 @@ impl InnerResolver { let var_map = params .iter() .map(|(id_var, ty)| { - if let TypeEnum::TVar { id, range, name, loc, .. } = &*unifier.get_ty(*ty) { + if let TypeEnum::TVar { id, range, name, loc, .. } = + &*unifier.get_ty(*ty) + { assert_eq!(*id, *id_var); (*id, unifier.get_fresh_var_with_range(range, *name, *loc).0) } else { @@ -635,7 +635,7 @@ impl InnerResolver { } }) .collect::>(); - return Ok(Ok(unifier.subst(primitives.option, &var_map).unwrap())) + return Ok(Ok(unifier.subst(primitives.option, &var_map).unwrap())); } else { unreachable!("must be tobj") } @@ -659,9 +659,7 @@ impl InnerResolver { let var_map = params .iter() .map(|(id_var, ty)| { - if let TypeEnum::TVar { id, range, name, loc, .. } = - &*unifier.get_ty(*ty) - { + if let TypeEnum::TVar { id, range, name, loc, .. } = &*unifier.get_ty(*ty) { assert_eq!(*id, *id_var); (*id, unifier.get_fresh_var_with_range(range, *name, *loc).0) } else { @@ -673,7 +671,7 @@ impl InnerResolver { // loop through non-function fields of the class to get the instantiated value for field in fields.iter() { let name: String = (*field.0).into(); - if let TypeEnum::TFunc(..) = &*unifier.get_ty(field.1.0) { + if let TypeEnum::TFunc(..) = &*unifier.get_ty(field.1 .0) { continue; } else { let field_data = obj.getattr(&name)?; @@ -689,7 +687,7 @@ impl InnerResolver { } }; let field_ty = - unifier.subst(field.1.0, &var_map).unwrap_or(field.1.0); + unifier.subst(field.1 .0, &var_map).unwrap_or(field.1 .0); if let Err(e) = unifier.unify(ty, field_ty) { // field type mismatch return Ok(Err(format!( @@ -706,14 +704,15 @@ impl InnerResolver { return Ok(Err("object is not of concrete type".into())); } } - let extracted_ty = unifier.subst(extracted_ty, &var_map).unwrap_or(extracted_ty); + let extracted_ty = + unifier.subst(extracted_ty, &var_map).unwrap_or(extracted_ty); Ok(Ok(extracted_ty)) }; let result = instantiate_obj(); // update/remove the cache according to the result match result { Ok(Ok(ty)) => self.pyid_to_type.write().insert(py_obj_id, ty), - _ => self.pyid_to_type.write().remove(&py_obj_id) + _ => self.pyid_to_type.write().remove(&py_obj_id), }; result } @@ -722,32 +721,32 @@ impl InnerResolver { if unifier.unioned(extracted_ty, primitives.int32) { obj.extract::().map_or_else( |_| Ok(Err(format!("{} is not in the range of int32", obj))), - |_| Ok(Ok(extracted_ty)) + |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.int64) { obj.extract::().map_or_else( |_| Ok(Err(format!("{} is not in the range of int64", obj))), - |_| Ok(Ok(extracted_ty)) + |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.uint32) { obj.extract::().map_or_else( |_| Ok(Err(format!("{} is not in the range of uint32", obj))), - |_| Ok(Ok(extracted_ty)) + |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.uint64) { obj.extract::().map_or_else( |_| Ok(Err(format!("{} is not in the range of uint64", obj))), - |_| Ok(Ok(extracted_ty)) + |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.bool) { obj.extract::().map_or_else( |_| Ok(Err(format!("{} is not in the range of bool", obj))), - |_| Ok(Ok(extracted_ty)) + |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.float) { obj.extract::().map_or_else( |_| Ok(Err(format!("{} is not in the range of float64", obj))), - |_| Ok(Ok(extracted_ty)) + |_| Ok(Ok(extracted_ty)), ) } else { Ok(Ok(extracted_ty)) @@ -799,8 +798,8 @@ impl InnerResolver { } let len: usize = self.helper.len_fn.call1(py, (obj,))?.extract(py)?; - let elem_ty = - if let TypeEnum::TList { ty } = ctx.unifier.get_ty_immutable(expected_ty).as_ref() + let elem_ty = if let TypeEnum::TList { ty } = + ctx.unifier.get_ty_immutable(expected_ty).as_ref() { *ty } else { @@ -825,13 +824,14 @@ impl InnerResolver { let arr: Result>, _> = (0..len) .map(|i| { - obj - .get_item(i) - .and_then(|elem| self.get_obj_value(py, elem, ctx, generator, elem_ty) - .map_err( - |e| super::CompileError::new_err( - format!("Error getting element {}: {}", i, e)) - )) + obj.get_item(i).and_then(|elem| { + self.get_obj_value(py, elem, ctx, generator, elem_ty).map_err(|e| { + super::CompileError::new_err(format!( + "Error getting element {}: {}", + i, e + )) + }) + }) }) .collect(); let arr = arr?.unwrap(); @@ -876,18 +876,19 @@ impl InnerResolver { let tup_tys = ty.iter(); let elements: &PyTuple = obj.cast_as()?; assert_eq!(elements.len(), tup_tys.len()); - let val: Result>, _> = - elements - .iter() - .enumerate() - .zip(tup_tys) - .map(|((i, elem), ty)| self - .get_obj_value(py, elem, ctx, generator, *ty).map_err(|e| - super::CompileError::new_err( - format!("Error getting element {}: {}", i, e) - ) - ) - ).collect(); + let val: Result>, _> = elements + .iter() + .enumerate() + .zip(tup_tys) + .map(|((i, elem), ty)| { + self.get_obj_value(py, elem, ctx, generator, *ty).map_err(|e| { + super::CompileError::new_err(format!( + "Error getting element {}: {}", + i, e + )) + }) + }) + .collect(); let val = val?.unwrap(); let val = ctx.ctx.const_struct(&val, false); Ok(Some(val.into())) @@ -901,7 +902,7 @@ impl InnerResolver { { *params.iter().next().unwrap().1 } - _ => unreachable!("must be option type") + _ => unreachable!("must be option type"), }; if id == self.primitive_ids.none { // for option type, just a null ptr @@ -913,7 +914,13 @@ impl InnerResolver { )) } else { match self - .get_obj_value(py, obj.getattr("_nac3_option").unwrap(), ctx, generator, option_val_ty) + .get_obj_value( + py, + obj.getattr("_nac3_option").unwrap(), + ctx, + generator, + option_val_ty, + ) .map_err(|e| { super::CompileError::new_err(format!( "Error getting value of Option object: {}", @@ -924,18 +931,27 @@ impl InnerResolver { let global_str = format!("{}_option", id); { if self.global_value_ids.read().contains_key(&id) { - let global = ctx.module.get_global(&global_str).unwrap_or_else(|| { - ctx.module.add_global(v.get_type(), Some(AddressSpace::Generic), &global_str) - }); + let global = + ctx.module.get_global(&global_str).unwrap_or_else(|| { + ctx.module.add_global( + v.get_type(), + Some(AddressSpace::Generic), + &global_str, + ) + }); return Ok(Some(global.as_pointer_value().into())); } else { self.global_value_ids.write().insert(id, obj.into()); } } - let global = ctx.module.add_global(v.get_type(), Some(AddressSpace::Generic), &global_str); + let global = ctx.module.add_global( + v.get_type(), + Some(AddressSpace::Generic), + &global_str, + ); global.set_initializer(&v); Ok(Some(global.as_pointer_value().into())) - }, + } None => Ok(None), } } @@ -973,7 +989,12 @@ impl InnerResolver { .iter() .map(|(name, ty, _)| { self.get_obj_value(py, obj.getattr(&name.to_string())?, ctx, generator, *ty) - .map_err(|e| super::CompileError::new_err(format!("Error getting field {}: {}", name, e))) + .map_err(|e| { + super::CompileError::new_err(format!( + "Error getting field {}: {}", + name, e + )) + }) }) .collect(); let values = values?; @@ -1028,8 +1049,7 @@ impl InnerResolver { if id == self.primitive_ids.none { Ok(SymbolValue::OptionNone) } else { - self - .get_default_param_obj_value(py, obj.getattr("_nac3_option").unwrap())? + self.get_default_param_obj_value(py, obj.getattr("_nac3_option").unwrap())? .map(|v| SymbolValue::OptionSome(Box::new(v))) } } else { @@ -1184,7 +1204,7 @@ impl SymbolResolver for Resolver { &self, unifier: &mut Unifier, defs: &[Arc>], - primitives: &PrimitiveStore + primitives: &PrimitiveStore, ) -> Result<(), String> { // we don't need a lock because this will only be run in a single thread if self.0.deferred_eval_store.needs_defer.load(Relaxed) { @@ -1214,7 +1234,8 @@ impl SymbolResolver for Resolver { } } Ok(Ok(())) - }).unwrap()? + }) + .unwrap()? } Ok(()) } diff --git a/nac3ast/src/ast_gen.rs b/nac3ast/src/ast_gen.rs index e62f6a733..0d42fa2c0 100644 --- a/nac3ast/src/ast_gen.rs +++ b/nac3ast/src/ast_gen.rs @@ -1,16 +1,17 @@ // File automatically generated by ast/asdl_rs.py. -pub use crate::location::Location; pub use crate::constant::*; +pub use crate::location::Location; -use std::{fmt, collections::HashMap, cell::RefCell}; -use parking_lot::{Mutex, MutexGuard}; -use string_interner::{DefaultBackend, DefaultSymbol, StringInterner, symbol::SymbolU32}; use fxhash::FxBuildHasher; +use parking_lot::{Mutex, MutexGuard}; +use std::{cell::RefCell, collections::HashMap, fmt}; +use string_interner::{symbol::SymbolU32, DefaultBackend, DefaultSymbol, StringInterner}; pub type Interner = StringInterner, FxBuildHasher>; lazy_static! { - static ref INTERNER: Mutex = Mutex::new(StringInterner::with_hasher(FxBuildHasher::default())); + static ref INTERNER: Mutex = + Mutex::new(StringInterner::with_hasher(FxBuildHasher::default())); } thread_local! { @@ -54,7 +55,7 @@ impl From<&str> for StrRef { } } -impl From for String{ +impl From for String { fn from(s: StrRef) -> Self { get_str_from_ref(&get_str_ref_lock(), s).to_string() } @@ -89,20 +90,10 @@ impl Located { #[derive(Clone, Debug, PartialEq)] pub enum Mod { - Module { - body: Vec>, - type_ignores: Vec, - }, - Interactive { - body: Vec>, - }, - Expression { - body: Box>, - }, - FunctionType { - argtypes: Vec>, - returns: Box>, - }, + Module { body: Vec>, type_ignores: Vec }, + Interactive { body: Vec> }, + Expression { body: Box> }, + FunctionType { argtypes: Vec>, returns: Box> }, } #[derive(Clone, Debug, PartialEq)] @@ -430,11 +421,7 @@ pub struct Comprehension { #[derive(Clone, Debug, PartialEq)] pub enum ExcepthandlerKind { - ExceptHandler { - type_: Option>>, - name: Option, - body: Vec>, - }, + ExceptHandler { type_: Option>>, name: Option, body: Vec> }, } pub type Excepthandler = Located, U>; @@ -478,13 +465,9 @@ pub struct Withitem { #[derive(Clone, Debug, PartialEq)] pub enum TypeIgnore { - TypeIgnore { - lineno: usize, - tag: String, - }, + TypeIgnore { lineno: usize, tag: String }, } - #[cfg(feature = "fold")] pub mod fold { use super::*; @@ -492,123 +475,159 @@ pub mod fold { pub trait Fold { type TargetU; type Error; - fn map_user(&mut self, user: U) -> Result; - fn fold_mod(&mut self, node: Mod) -> Result, Self::Error> { - fold_mod(self, node) - } - fn fold_stmt(&mut self, node: Stmt) -> Result, Self::Error> { - fold_stmt(self, node) - } - fn fold_expr(&mut self, node: Expr) -> Result, Self::Error> { - fold_expr(self, node) - } - fn fold_expr_context(&mut self, node: ExprContext) -> Result { - fold_expr_context(self, node) - } - fn fold_boolop(&mut self, node: Boolop) -> Result { - fold_boolop(self, node) - } - fn fold_operator(&mut self, node: Operator) -> Result { - fold_operator(self, node) - } - fn fold_unaryop(&mut self, node: Unaryop) -> Result { - fold_unaryop(self, node) - } - fn fold_cmpop(&mut self, node: Cmpop) -> Result { - fold_cmpop(self, node) - } - fn fold_comprehension(&mut self, node: Comprehension) -> Result, Self::Error> { - fold_comprehension(self, node) - } - fn fold_excepthandler(&mut self, node: Excepthandler) -> Result, Self::Error> { - fold_excepthandler(self, node) - } - fn fold_arguments(&mut self, node: Arguments) -> Result, Self::Error> { - fold_arguments(self, node) - } - fn fold_arg(&mut self, node: Arg) -> Result, Self::Error> { - fold_arg(self, node) - } - fn fold_keyword(&mut self, node: Keyword) -> Result, Self::Error> { - fold_keyword(self, node) - } - fn fold_alias(&mut self, node: Alias) -> Result { - fold_alias(self, node) - } - fn fold_withitem(&mut self, node: Withitem) -> Result, Self::Error> { - fold_withitem(self, node) - } - fn fold_type_ignore(&mut self, node: TypeIgnore) -> Result { - fold_type_ignore(self, node) - } + fn map_user(&mut self, user: U) -> Result; + fn fold_mod(&mut self, node: Mod) -> Result, Self::Error> { + fold_mod(self, node) + } + fn fold_stmt(&mut self, node: Stmt) -> Result, Self::Error> { + fold_stmt(self, node) + } + fn fold_expr(&mut self, node: Expr) -> Result, Self::Error> { + fold_expr(self, node) + } + fn fold_expr_context(&mut self, node: ExprContext) -> Result { + fold_expr_context(self, node) + } + fn fold_boolop(&mut self, node: Boolop) -> Result { + fold_boolop(self, node) + } + fn fold_operator(&mut self, node: Operator) -> Result { + fold_operator(self, node) + } + fn fold_unaryop(&mut self, node: Unaryop) -> Result { + fold_unaryop(self, node) + } + fn fold_cmpop(&mut self, node: Cmpop) -> Result { + fold_cmpop(self, node) + } + fn fold_comprehension( + &mut self, + node: Comprehension, + ) -> Result, Self::Error> { + fold_comprehension(self, node) + } + fn fold_excepthandler( + &mut self, + node: Excepthandler, + ) -> Result, Self::Error> { + fold_excepthandler(self, node) + } + fn fold_arguments( + &mut self, + node: Arguments, + ) -> Result, Self::Error> { + fold_arguments(self, node) + } + fn fold_arg(&mut self, node: Arg) -> Result, Self::Error> { + fold_arg(self, node) + } + fn fold_keyword( + &mut self, + node: Keyword, + ) -> Result, Self::Error> { + fold_keyword(self, node) + } + fn fold_alias(&mut self, node: Alias) -> Result { + fold_alias(self, node) + } + fn fold_withitem( + &mut self, + node: Withitem, + ) -> Result, Self::Error> { + fold_withitem(self, node) + } + fn fold_type_ignore(&mut self, node: TypeIgnore) -> Result { + fold_type_ignore(self, node) + } } - fn fold_located + ?Sized, T, MT>(folder: &mut F, node: Located, f: impl FnOnce(&mut F, T) -> Result) -> Result, F::Error> { - Ok(Located { custom: folder.map_user(node.custom)?, location: node.location, node: f(folder, node.node)? }) + fn fold_located + ?Sized, T, MT>( + folder: &mut F, + node: Located, + f: impl FnOnce(&mut F, T) -> Result, + ) -> Result, F::Error> { + Ok(Located { + custom: folder.map_user(node.custom)?, + location: node.location, + node: f(folder, node.node)?, + }) } impl Foldable for Mod { type Mapped = Mod; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_mod(self) } } - pub fn fold_mod + ?Sized>(#[allow(unused)] folder: &mut F, node: Mod) -> Result, F::Error> { + pub fn fold_mod + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Mod, + ) -> Result, F::Error> { match node { - Mod::Module { body,type_ignores } => { - Ok(Mod::Module { - body: Foldable::fold(body, folder)?, - type_ignores: Foldable::fold(type_ignores, folder)?, - }) - } + Mod::Module { body, type_ignores } => Ok(Mod::Module { + body: Foldable::fold(body, folder)?, + type_ignores: Foldable::fold(type_ignores, folder)?, + }), Mod::Interactive { body } => { - Ok(Mod::Interactive { - body: Foldable::fold(body, folder)?, - }) - } - Mod::Expression { body } => { - Ok(Mod::Expression { - body: Foldable::fold(body, folder)?, - }) - } - Mod::FunctionType { argtypes,returns } => { - Ok(Mod::FunctionType { - argtypes: Foldable::fold(argtypes, folder)?, - returns: Foldable::fold(returns, folder)?, - }) + Ok(Mod::Interactive { body: Foldable::fold(body, folder)? }) } + Mod::Expression { body } => Ok(Mod::Expression { body: Foldable::fold(body, folder)? }), + Mod::FunctionType { argtypes, returns } => Ok(Mod::FunctionType { + argtypes: Foldable::fold(argtypes, folder)?, + returns: Foldable::fold(returns, folder)?, + }), } } impl Foldable for Stmt { type Mapped = Stmt; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_stmt(self) } } - pub fn fold_stmt + ?Sized>(#[allow(unused)] folder: &mut F, node: Stmt) -> Result, F::Error> { - fold_located(folder, node, |folder, node| { - match node { - StmtKind::FunctionDef { name,args,body,decorator_list,returns,type_comment,config_comment } => { - Ok(StmtKind::FunctionDef { - name: Foldable::fold(name, folder)?, - args: Foldable::fold(args, folder)?, - body: Foldable::fold(body, folder)?, - decorator_list: Foldable::fold(decorator_list, folder)?, - returns: Foldable::fold(returns, folder)?, - type_comment: Foldable::fold(type_comment, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::AsyncFunctionDef { name,args,body,decorator_list,returns,type_comment,config_comment } => { - Ok(StmtKind::AsyncFunctionDef { - name: Foldable::fold(name, folder)?, - args: Foldable::fold(args, folder)?, - body: Foldable::fold(body, folder)?, - decorator_list: Foldable::fold(decorator_list, folder)?, - returns: Foldable::fold(returns, folder)?, - type_comment: Foldable::fold(type_comment, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::ClassDef { name,bases,keywords,body,decorator_list,config_comment } => { + pub fn fold_stmt + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Stmt, + ) -> Result, F::Error> { + fold_located(folder, node, |folder, node| match node { + StmtKind::FunctionDef { + name, + args, + body, + decorator_list, + returns, + type_comment, + config_comment, + } => Ok(StmtKind::FunctionDef { + name: Foldable::fold(name, folder)?, + args: Foldable::fold(args, folder)?, + body: Foldable::fold(body, folder)?, + decorator_list: Foldable::fold(decorator_list, folder)?, + returns: Foldable::fold(returns, folder)?, + type_comment: Foldable::fold(type_comment, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::AsyncFunctionDef { + name, + args, + body, + decorator_list, + returns, + type_comment, + config_comment, + } => Ok(StmtKind::AsyncFunctionDef { + name: Foldable::fold(name, folder)?, + args: Foldable::fold(args, folder)?, + body: Foldable::fold(body, folder)?, + decorator_list: Foldable::fold(decorator_list, folder)?, + returns: Foldable::fold(returns, folder)?, + type_comment: Foldable::fold(type_comment, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::ClassDef { name, bases, keywords, body, decorator_list, config_comment } => { Ok(StmtKind::ClassDef { name: Foldable::fold(name, folder)?, bases: Foldable::fold(bases, folder)?, @@ -618,19 +637,15 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::Return { value,config_comment } => { - Ok(StmtKind::Return { - value: Foldable::fold(value, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::Delete { targets,config_comment } => { - Ok(StmtKind::Delete { - targets: Foldable::fold(targets, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::Assign { targets,value,type_comment,config_comment } => { + StmtKind::Return { value, config_comment } => Ok(StmtKind::Return { + value: Foldable::fold(value, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::Delete { targets, config_comment } => Ok(StmtKind::Delete { + targets: Foldable::fold(targets, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::Assign { targets, value, type_comment, config_comment } => { Ok(StmtKind::Assign { targets: Foldable::fold(targets, folder)?, value: Foldable::fold(value, folder)?, @@ -638,15 +653,13 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::AugAssign { target,op,value,config_comment } => { - Ok(StmtKind::AugAssign { - target: Foldable::fold(target, folder)?, - op: Foldable::fold(op, folder)?, - value: Foldable::fold(value, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::AnnAssign { target,annotation,value,simple,config_comment } => { + StmtKind::AugAssign { target, op, value, config_comment } => Ok(StmtKind::AugAssign { + target: Foldable::fold(target, folder)?, + op: Foldable::fold(op, folder)?, + value: Foldable::fold(value, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::AnnAssign { target, annotation, value, simple, config_comment } => { Ok(StmtKind::AnnAssign { target: Foldable::fold(target, folder)?, annotation: Foldable::fold(annotation, folder)?, @@ -655,7 +668,7 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::For { target,iter,body,orelse,type_comment,config_comment } => { + StmtKind::For { target, iter, body, orelse, type_comment, config_comment } => { Ok(StmtKind::For { target: Foldable::fold(target, folder)?, iter: Foldable::fold(iter, folder)?, @@ -665,7 +678,7 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::AsyncFor { target,iter,body,orelse,type_comment,config_comment } => { + StmtKind::AsyncFor { target, iter, body, orelse, type_comment, config_comment } => { Ok(StmtKind::AsyncFor { target: Foldable::fold(target, folder)?, iter: Foldable::fold(iter, folder)?, @@ -675,31 +688,25 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::While { test,body,orelse,config_comment } => { - Ok(StmtKind::While { - test: Foldable::fold(test, folder)?, - body: Foldable::fold(body, folder)?, - orelse: Foldable::fold(orelse, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::If { test,body,orelse,config_comment } => { - Ok(StmtKind::If { - test: Foldable::fold(test, folder)?, - body: Foldable::fold(body, folder)?, - orelse: Foldable::fold(orelse, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::With { items,body,type_comment,config_comment } => { - Ok(StmtKind::With { - items: Foldable::fold(items, folder)?, - body: Foldable::fold(body, folder)?, - type_comment: Foldable::fold(type_comment, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::AsyncWith { items,body,type_comment,config_comment } => { + StmtKind::While { test, body, orelse, config_comment } => Ok(StmtKind::While { + test: Foldable::fold(test, folder)?, + body: Foldable::fold(body, folder)?, + orelse: Foldable::fold(orelse, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::If { test, body, orelse, config_comment } => Ok(StmtKind::If { + test: Foldable::fold(test, folder)?, + body: Foldable::fold(body, folder)?, + orelse: Foldable::fold(orelse, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::With { items, body, type_comment, config_comment } => Ok(StmtKind::With { + items: Foldable::fold(items, folder)?, + body: Foldable::fold(body, folder)?, + type_comment: Foldable::fold(type_comment, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::AsyncWith { items, body, type_comment, config_comment } => { Ok(StmtKind::AsyncWith { items: Foldable::fold(items, folder)?, body: Foldable::fold(body, folder)?, @@ -707,14 +714,12 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::Raise { exc,cause,config_comment } => { - Ok(StmtKind::Raise { - exc: Foldable::fold(exc, folder)?, - cause: Foldable::fold(cause, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::Try { body,handlers,orelse,finalbody,config_comment } => { + StmtKind::Raise { exc, cause, config_comment } => Ok(StmtKind::Raise { + exc: Foldable::fold(exc, folder)?, + cause: Foldable::fold(cause, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::Try { body, handlers, orelse, finalbody, config_comment } => { Ok(StmtKind::Try { body: Foldable::fold(body, folder)?, handlers: Foldable::fold(handlers, folder)?, @@ -723,20 +728,16 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::Assert { test,msg,config_comment } => { - Ok(StmtKind::Assert { - test: Foldable::fold(test, folder)?, - msg: Foldable::fold(msg, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::Import { names,config_comment } => { - Ok(StmtKind::Import { - names: Foldable::fold(names, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::ImportFrom { module,names,level,config_comment } => { + StmtKind::Assert { test, msg, config_comment } => Ok(StmtKind::Assert { + test: Foldable::fold(test, folder)?, + msg: Foldable::fold(msg, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::Import { names, config_comment } => Ok(StmtKind::Import { + names: Foldable::fold(names, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::ImportFrom { module, names, level, config_comment } => { Ok(StmtKind::ImportFrom { module: Foldable::fold(module, folder)?, names: Foldable::fold(names, folder)?, @@ -744,155 +745,111 @@ pub mod fold { config_comment: Foldable::fold(config_comment, folder)?, }) } - StmtKind::Global { names,config_comment } => { - Ok(StmtKind::Global { - names: Foldable::fold(names, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::Nonlocal { names,config_comment } => { - Ok(StmtKind::Nonlocal { - names: Foldable::fold(names, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } - StmtKind::Expr { value,config_comment } => { - Ok(StmtKind::Expr { - value: Foldable::fold(value, folder)?, - config_comment: Foldable::fold(config_comment, folder)?, - }) - } + StmtKind::Global { names, config_comment } => Ok(StmtKind::Global { + names: Foldable::fold(names, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::Nonlocal { names, config_comment } => Ok(StmtKind::Nonlocal { + names: Foldable::fold(names, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), + StmtKind::Expr { value, config_comment } => Ok(StmtKind::Expr { + value: Foldable::fold(value, folder)?, + config_comment: Foldable::fold(config_comment, folder)?, + }), StmtKind::Pass { config_comment } => { - Ok(StmtKind::Pass { - config_comment: Foldable::fold(config_comment, folder)?, - }) + Ok(StmtKind::Pass { config_comment: Foldable::fold(config_comment, folder)? }) } StmtKind::Break { config_comment } => { - Ok(StmtKind::Break { - config_comment: Foldable::fold(config_comment, folder)?, - }) + Ok(StmtKind::Break { config_comment: Foldable::fold(config_comment, folder)? }) } StmtKind::Continue { config_comment } => { - Ok(StmtKind::Continue { - config_comment: Foldable::fold(config_comment, folder)?, - }) + Ok(StmtKind::Continue { config_comment: Foldable::fold(config_comment, folder)? }) } - } - }) + }) } impl Foldable for Expr { type Mapped = Expr; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_expr(self) } } - pub fn fold_expr + ?Sized>(#[allow(unused)] folder: &mut F, node: Expr) -> Result, F::Error> { - fold_located(folder, node, |folder, node| { - match node { - ExprKind::BoolOp { op,values } => { - Ok(ExprKind::BoolOp { - op: Foldable::fold(op, folder)?, - values: Foldable::fold(values, folder)?, - }) - } - ExprKind::NamedExpr { target,value } => { - Ok(ExprKind::NamedExpr { - target: Foldable::fold(target, folder)?, - value: Foldable::fold(value, folder)?, - }) - } - ExprKind::BinOp { left,op,right } => { - Ok(ExprKind::BinOp { - left: Foldable::fold(left, folder)?, - op: Foldable::fold(op, folder)?, - right: Foldable::fold(right, folder)?, - }) - } - ExprKind::UnaryOp { op,operand } => { - Ok(ExprKind::UnaryOp { - op: Foldable::fold(op, folder)?, - operand: Foldable::fold(operand, folder)?, - }) - } - ExprKind::Lambda { args,body } => { - Ok(ExprKind::Lambda { - args: Foldable::fold(args, folder)?, - body: Foldable::fold(body, folder)?, - }) - } - ExprKind::IfExp { test,body,orelse } => { - Ok(ExprKind::IfExp { - test: Foldable::fold(test, folder)?, - body: Foldable::fold(body, folder)?, - orelse: Foldable::fold(orelse, folder)?, - }) - } - ExprKind::Dict { keys,values } => { - Ok(ExprKind::Dict { - keys: Foldable::fold(keys, folder)?, - values: Foldable::fold(values, folder)?, - }) - } - ExprKind::Set { elts } => { - Ok(ExprKind::Set { - elts: Foldable::fold(elts, folder)?, - }) - } - ExprKind::ListComp { elt,generators } => { - Ok(ExprKind::ListComp { - elt: Foldable::fold(elt, folder)?, - generators: Foldable::fold(generators, folder)?, - }) - } - ExprKind::SetComp { elt,generators } => { - Ok(ExprKind::SetComp { - elt: Foldable::fold(elt, folder)?, - generators: Foldable::fold(generators, folder)?, - }) - } - ExprKind::DictComp { key,value,generators } => { - Ok(ExprKind::DictComp { - key: Foldable::fold(key, folder)?, - value: Foldable::fold(value, folder)?, - generators: Foldable::fold(generators, folder)?, - }) - } - ExprKind::GeneratorExp { elt,generators } => { - Ok(ExprKind::GeneratorExp { - elt: Foldable::fold(elt, folder)?, - generators: Foldable::fold(generators, folder)?, - }) - } + pub fn fold_expr + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Expr, + ) -> Result, F::Error> { + fold_located(folder, node, |folder, node| match node { + ExprKind::BoolOp { op, values } => Ok(ExprKind::BoolOp { + op: Foldable::fold(op, folder)?, + values: Foldable::fold(values, folder)?, + }), + ExprKind::NamedExpr { target, value } => Ok(ExprKind::NamedExpr { + target: Foldable::fold(target, folder)?, + value: Foldable::fold(value, folder)?, + }), + ExprKind::BinOp { left, op, right } => Ok(ExprKind::BinOp { + left: Foldable::fold(left, folder)?, + op: Foldable::fold(op, folder)?, + right: Foldable::fold(right, folder)?, + }), + ExprKind::UnaryOp { op, operand } => Ok(ExprKind::UnaryOp { + op: Foldable::fold(op, folder)?, + operand: Foldable::fold(operand, folder)?, + }), + ExprKind::Lambda { args, body } => Ok(ExprKind::Lambda { + args: Foldable::fold(args, folder)?, + body: Foldable::fold(body, folder)?, + }), + ExprKind::IfExp { test, body, orelse } => Ok(ExprKind::IfExp { + test: Foldable::fold(test, folder)?, + body: Foldable::fold(body, folder)?, + orelse: Foldable::fold(orelse, folder)?, + }), + ExprKind::Dict { keys, values } => Ok(ExprKind::Dict { + keys: Foldable::fold(keys, folder)?, + values: Foldable::fold(values, folder)?, + }), + ExprKind::Set { elts } => Ok(ExprKind::Set { elts: Foldable::fold(elts, folder)? }), + ExprKind::ListComp { elt, generators } => Ok(ExprKind::ListComp { + elt: Foldable::fold(elt, folder)?, + generators: Foldable::fold(generators, folder)?, + }), + ExprKind::SetComp { elt, generators } => Ok(ExprKind::SetComp { + elt: Foldable::fold(elt, folder)?, + generators: Foldable::fold(generators, folder)?, + }), + ExprKind::DictComp { key, value, generators } => Ok(ExprKind::DictComp { + key: Foldable::fold(key, folder)?, + value: Foldable::fold(value, folder)?, + generators: Foldable::fold(generators, folder)?, + }), + ExprKind::GeneratorExp { elt, generators } => Ok(ExprKind::GeneratorExp { + elt: Foldable::fold(elt, folder)?, + generators: Foldable::fold(generators, folder)?, + }), ExprKind::Await { value } => { - Ok(ExprKind::Await { - value: Foldable::fold(value, folder)?, - }) + Ok(ExprKind::Await { value: Foldable::fold(value, folder)? }) } ExprKind::Yield { value } => { - Ok(ExprKind::Yield { - value: Foldable::fold(value, folder)?, - }) + Ok(ExprKind::Yield { value: Foldable::fold(value, folder)? }) } ExprKind::YieldFrom { value } => { - Ok(ExprKind::YieldFrom { - value: Foldable::fold(value, folder)?, - }) + Ok(ExprKind::YieldFrom { value: Foldable::fold(value, folder)? }) } - ExprKind::Compare { left,ops,comparators } => { - Ok(ExprKind::Compare { - left: Foldable::fold(left, folder)?, - ops: Foldable::fold(ops, folder)?, - comparators: Foldable::fold(comparators, folder)?, - }) - } - ExprKind::Call { func,args,keywords } => { - Ok(ExprKind::Call { - func: Foldable::fold(func, folder)?, - args: Foldable::fold(args, folder)?, - keywords: Foldable::fold(keywords, folder)?, - }) - } - ExprKind::FormattedValue { value,conversion,format_spec } => { + ExprKind::Compare { left, ops, comparators } => Ok(ExprKind::Compare { + left: Foldable::fold(left, folder)?, + ops: Foldable::fold(ops, folder)?, + comparators: Foldable::fold(comparators, folder)?, + }), + ExprKind::Call { func, args, keywords } => Ok(ExprKind::Call { + func: Foldable::fold(func, folder)?, + args: Foldable::fold(args, folder)?, + keywords: Foldable::fold(keywords, folder)?, + }), + ExprKind::FormattedValue { value, conversion, format_spec } => { Ok(ExprKind::FormattedValue { value: Foldable::fold(value, folder)?, conversion: Foldable::fold(conversion, folder)?, @@ -900,250 +857,171 @@ pub mod fold { }) } ExprKind::JoinedStr { values } => { - Ok(ExprKind::JoinedStr { - values: Foldable::fold(values, folder)?, - }) + Ok(ExprKind::JoinedStr { values: Foldable::fold(values, folder)? }) } - ExprKind::Constant { value,kind } => { - Ok(ExprKind::Constant { - value: Foldable::fold(value, folder)?, - kind: Foldable::fold(kind, folder)?, - }) - } - ExprKind::Attribute { value,attr,ctx } => { - Ok(ExprKind::Attribute { - value: Foldable::fold(value, folder)?, - attr: Foldable::fold(attr, folder)?, - ctx: Foldable::fold(ctx, folder)?, - }) - } - ExprKind::Subscript { value,slice,ctx } => { - Ok(ExprKind::Subscript { - value: Foldable::fold(value, folder)?, - slice: Foldable::fold(slice, folder)?, - ctx: Foldable::fold(ctx, folder)?, - }) - } - ExprKind::Starred { value,ctx } => { - Ok(ExprKind::Starred { - value: Foldable::fold(value, folder)?, - ctx: Foldable::fold(ctx, folder)?, - }) - } - ExprKind::Name { id,ctx } => { - Ok(ExprKind::Name { - id: Foldable::fold(id, folder)?, - ctx: Foldable::fold(ctx, folder)?, - }) - } - ExprKind::List { elts,ctx } => { - Ok(ExprKind::List { - elts: Foldable::fold(elts, folder)?, - ctx: Foldable::fold(ctx, folder)?, - }) - } - ExprKind::Tuple { elts,ctx } => { - Ok(ExprKind::Tuple { - elts: Foldable::fold(elts, folder)?, - ctx: Foldable::fold(ctx, folder)?, - }) - } - ExprKind::Slice { lower,upper,step } => { - Ok(ExprKind::Slice { - lower: Foldable::fold(lower, folder)?, - upper: Foldable::fold(upper, folder)?, - step: Foldable::fold(step, folder)?, - }) - } - } - }) + ExprKind::Constant { value, kind } => Ok(ExprKind::Constant { + value: Foldable::fold(value, folder)?, + kind: Foldable::fold(kind, folder)?, + }), + ExprKind::Attribute { value, attr, ctx } => Ok(ExprKind::Attribute { + value: Foldable::fold(value, folder)?, + attr: Foldable::fold(attr, folder)?, + ctx: Foldable::fold(ctx, folder)?, + }), + ExprKind::Subscript { value, slice, ctx } => Ok(ExprKind::Subscript { + value: Foldable::fold(value, folder)?, + slice: Foldable::fold(slice, folder)?, + ctx: Foldable::fold(ctx, folder)?, + }), + ExprKind::Starred { value, ctx } => Ok(ExprKind::Starred { + value: Foldable::fold(value, folder)?, + ctx: Foldable::fold(ctx, folder)?, + }), + ExprKind::Name { id, ctx } => Ok(ExprKind::Name { + id: Foldable::fold(id, folder)?, + ctx: Foldable::fold(ctx, folder)?, + }), + ExprKind::List { elts, ctx } => Ok(ExprKind::List { + elts: Foldable::fold(elts, folder)?, + ctx: Foldable::fold(ctx, folder)?, + }), + ExprKind::Tuple { elts, ctx } => Ok(ExprKind::Tuple { + elts: Foldable::fold(elts, folder)?, + ctx: Foldable::fold(ctx, folder)?, + }), + ExprKind::Slice { lower, upper, step } => Ok(ExprKind::Slice { + lower: Foldable::fold(lower, folder)?, + upper: Foldable::fold(upper, folder)?, + step: Foldable::fold(step, folder)?, + }), + }) } impl Foldable for ExprContext { type Mapped = ExprContext; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_expr_context(self) } } - pub fn fold_expr_context + ?Sized>(#[allow(unused)] folder: &mut F, node: ExprContext) -> Result { + pub fn fold_expr_context + ?Sized>( + #[allow(unused)] folder: &mut F, + node: ExprContext, + ) -> Result { match node { - ExprContext::Load { } => { - Ok(ExprContext::Load { - }) - } - ExprContext::Store { } => { - Ok(ExprContext::Store { - }) - } - ExprContext::Del { } => { - Ok(ExprContext::Del { - }) - } + ExprContext::Load {} => Ok(ExprContext::Load {}), + ExprContext::Store {} => Ok(ExprContext::Store {}), + ExprContext::Del {} => Ok(ExprContext::Del {}), } } impl Foldable for Boolop { type Mapped = Boolop; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_boolop(self) } } - pub fn fold_boolop + ?Sized>(#[allow(unused)] folder: &mut F, node: Boolop) -> Result { + pub fn fold_boolop + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Boolop, + ) -> Result { match node { - Boolop::And { } => { - Ok(Boolop::And { - }) - } - Boolop::Or { } => { - Ok(Boolop::Or { - }) - } + Boolop::And {} => Ok(Boolop::And {}), + Boolop::Or {} => Ok(Boolop::Or {}), } } impl Foldable for Operator { type Mapped = Operator; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_operator(self) } } - pub fn fold_operator + ?Sized>(#[allow(unused)] folder: &mut F, node: Operator) -> Result { + pub fn fold_operator + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Operator, + ) -> Result { match node { - Operator::Add { } => { - Ok(Operator::Add { - }) - } - Operator::Sub { } => { - Ok(Operator::Sub { - }) - } - Operator::Mult { } => { - Ok(Operator::Mult { - }) - } - Operator::MatMult { } => { - Ok(Operator::MatMult { - }) - } - Operator::Div { } => { - Ok(Operator::Div { - }) - } - Operator::Mod { } => { - Ok(Operator::Mod { - }) - } - Operator::Pow { } => { - Ok(Operator::Pow { - }) - } - Operator::LShift { } => { - Ok(Operator::LShift { - }) - } - Operator::RShift { } => { - Ok(Operator::RShift { - }) - } - Operator::BitOr { } => { - Ok(Operator::BitOr { - }) - } - Operator::BitXor { } => { - Ok(Operator::BitXor { - }) - } - Operator::BitAnd { } => { - Ok(Operator::BitAnd { - }) - } - Operator::FloorDiv { } => { - Ok(Operator::FloorDiv { - }) - } + Operator::Add {} => Ok(Operator::Add {}), + Operator::Sub {} => Ok(Operator::Sub {}), + Operator::Mult {} => Ok(Operator::Mult {}), + Operator::MatMult {} => Ok(Operator::MatMult {}), + Operator::Div {} => Ok(Operator::Div {}), + Operator::Mod {} => Ok(Operator::Mod {}), + Operator::Pow {} => Ok(Operator::Pow {}), + Operator::LShift {} => Ok(Operator::LShift {}), + Operator::RShift {} => Ok(Operator::RShift {}), + Operator::BitOr {} => Ok(Operator::BitOr {}), + Operator::BitXor {} => Ok(Operator::BitXor {}), + Operator::BitAnd {} => Ok(Operator::BitAnd {}), + Operator::FloorDiv {} => Ok(Operator::FloorDiv {}), } } impl Foldable for Unaryop { type Mapped = Unaryop; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_unaryop(self) } } - pub fn fold_unaryop + ?Sized>(#[allow(unused)] folder: &mut F, node: Unaryop) -> Result { + pub fn fold_unaryop + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Unaryop, + ) -> Result { match node { - Unaryop::Invert { } => { - Ok(Unaryop::Invert { - }) - } - Unaryop::Not { } => { - Ok(Unaryop::Not { - }) - } - Unaryop::UAdd { } => { - Ok(Unaryop::UAdd { - }) - } - Unaryop::USub { } => { - Ok(Unaryop::USub { - }) - } + Unaryop::Invert {} => Ok(Unaryop::Invert {}), + Unaryop::Not {} => Ok(Unaryop::Not {}), + Unaryop::UAdd {} => Ok(Unaryop::UAdd {}), + Unaryop::USub {} => Ok(Unaryop::USub {}), } } impl Foldable for Cmpop { type Mapped = Cmpop; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_cmpop(self) } } - pub fn fold_cmpop + ?Sized>(#[allow(unused)] folder: &mut F, node: Cmpop) -> Result { + pub fn fold_cmpop + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Cmpop, + ) -> Result { match node { - Cmpop::Eq { } => { - Ok(Cmpop::Eq { - }) - } - Cmpop::NotEq { } => { - Ok(Cmpop::NotEq { - }) - } - Cmpop::Lt { } => { - Ok(Cmpop::Lt { - }) - } - Cmpop::LtE { } => { - Ok(Cmpop::LtE { - }) - } - Cmpop::Gt { } => { - Ok(Cmpop::Gt { - }) - } - Cmpop::GtE { } => { - Ok(Cmpop::GtE { - }) - } - Cmpop::Is { } => { - Ok(Cmpop::Is { - }) - } - Cmpop::IsNot { } => { - Ok(Cmpop::IsNot { - }) - } - Cmpop::In { } => { - Ok(Cmpop::In { - }) - } - Cmpop::NotIn { } => { - Ok(Cmpop::NotIn { - }) - } + Cmpop::Eq {} => Ok(Cmpop::Eq {}), + Cmpop::NotEq {} => Ok(Cmpop::NotEq {}), + Cmpop::Lt {} => Ok(Cmpop::Lt {}), + Cmpop::LtE {} => Ok(Cmpop::LtE {}), + Cmpop::Gt {} => Ok(Cmpop::Gt {}), + Cmpop::GtE {} => Ok(Cmpop::GtE {}), + Cmpop::Is {} => Ok(Cmpop::Is {}), + Cmpop::IsNot {} => Ok(Cmpop::IsNot {}), + Cmpop::In {} => Ok(Cmpop::In {}), + Cmpop::NotIn {} => Ok(Cmpop::NotIn {}), } } impl Foldable for Comprehension { type Mapped = Comprehension; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_comprehension(self) } } - pub fn fold_comprehension + ?Sized>(#[allow(unused)] folder: &mut F, node: Comprehension) -> Result, F::Error> { - let Comprehension { target,iter,ifs,is_async } = node; + pub fn fold_comprehension + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Comprehension, + ) -> Result, F::Error> { + let Comprehension { target, iter, ifs, is_async } = node; Ok(Comprehension { target: Foldable::fold(target, folder)?, iter: Foldable::fold(iter, folder)?, @@ -1153,31 +1031,42 @@ pub mod fold { } impl Foldable for Excepthandler { type Mapped = Excepthandler; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_excepthandler(self) } } - pub fn fold_excepthandler + ?Sized>(#[allow(unused)] folder: &mut F, node: Excepthandler) -> Result, F::Error> { - fold_located(folder, node, |folder, node| { - match node { - ExcepthandlerKind::ExceptHandler { type_,name,body } => { + pub fn fold_excepthandler + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Excepthandler, + ) -> Result, F::Error> { + fold_located(folder, node, |folder, node| match node { + ExcepthandlerKind::ExceptHandler { type_, name, body } => { Ok(ExcepthandlerKind::ExceptHandler { type_: Foldable::fold(type_, folder)?, name: Foldable::fold(name, folder)?, body: Foldable::fold(body, folder)?, }) } - } - }) + }) } impl Foldable for Arguments { type Mapped = Arguments; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_arguments(self) } } - pub fn fold_arguments + ?Sized>(#[allow(unused)] folder: &mut F, node: Arguments) -> Result, F::Error> { - let Arguments { posonlyargs,args,vararg,kwonlyargs,kw_defaults,kwarg,defaults } = node; + pub fn fold_arguments + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Arguments, + ) -> Result, F::Error> { + let Arguments { posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults } = + node; Ok(Arguments { posonlyargs: Foldable::fold(posonlyargs, folder)?, args: Foldable::fold(args, folder)?, @@ -1190,56 +1079,77 @@ pub mod fold { } impl Foldable for Arg { type Mapped = Arg; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_arg(self) } } - pub fn fold_arg + ?Sized>(#[allow(unused)] folder: &mut F, node: Arg) -> Result, F::Error> { - fold_located(folder, node, |folder, node| { - let ArgData { arg,annotation,type_comment } = node; - Ok(ArgData { - arg: Foldable::fold(arg, folder)?, - annotation: Foldable::fold(annotation, folder)?, - type_comment: Foldable::fold(type_comment, folder)?, + pub fn fold_arg + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Arg, + ) -> Result, F::Error> { + fold_located(folder, node, |folder, node| { + let ArgData { arg, annotation, type_comment } = node; + Ok(ArgData { + arg: Foldable::fold(arg, folder)?, + annotation: Foldable::fold(annotation, folder)?, + type_comment: Foldable::fold(type_comment, folder)?, + }) }) - }) } impl Foldable for Keyword { type Mapped = Keyword; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_keyword(self) } } - pub fn fold_keyword + ?Sized>(#[allow(unused)] folder: &mut F, node: Keyword) -> Result, F::Error> { - fold_located(folder, node, |folder, node| { - let KeywordData { arg,value } = node; - Ok(KeywordData { - arg: Foldable::fold(arg, folder)?, - value: Foldable::fold(value, folder)?, + pub fn fold_keyword + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Keyword, + ) -> Result, F::Error> { + fold_located(folder, node, |folder, node| { + let KeywordData { arg, value } = node; + Ok(KeywordData { + arg: Foldable::fold(arg, folder)?, + value: Foldable::fold(value, folder)?, + }) }) - }) } impl Foldable for Alias { type Mapped = Alias; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_alias(self) } } - pub fn fold_alias + ?Sized>(#[allow(unused)] folder: &mut F, node: Alias) -> Result { - let Alias { name,asname } = node; - Ok(Alias { - name: Foldable::fold(name, folder)?, - asname: Foldable::fold(asname, folder)?, - }) + pub fn fold_alias + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Alias, + ) -> Result { + let Alias { name, asname } = node; + Ok(Alias { name: Foldable::fold(name, folder)?, asname: Foldable::fold(asname, folder)? }) } impl Foldable for Withitem { type Mapped = Withitem; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_withitem(self) } } - pub fn fold_withitem + ?Sized>(#[allow(unused)] folder: &mut F, node: Withitem) -> Result, F::Error> { - let Withitem { context_expr,optional_vars } = node; + pub fn fold_withitem + ?Sized>( + #[allow(unused)] folder: &mut F, + node: Withitem, + ) -> Result, F::Error> { + let Withitem { context_expr, optional_vars } = node; Ok(Withitem { context_expr: Foldable::fold(context_expr, folder)?, optional_vars: Foldable::fold(optional_vars, folder)?, @@ -1247,19 +1157,22 @@ pub mod fold { } impl Foldable for TypeIgnore { type Mapped = TypeIgnore; - fn fold + ?Sized>(self, folder: &mut F) -> Result { + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { folder.fold_type_ignore(self) } } - pub fn fold_type_ignore + ?Sized>(#[allow(unused)] folder: &mut F, node: TypeIgnore) -> Result { + pub fn fold_type_ignore + ?Sized>( + #[allow(unused)] folder: &mut F, + node: TypeIgnore, + ) -> Result { match node { - TypeIgnore::TypeIgnore { lineno,tag } => { - Ok(TypeIgnore::TypeIgnore { - lineno: Foldable::fold(lineno, folder)?, - tag: Foldable::fold(tag, folder)?, - }) - } + TypeIgnore::TypeIgnore { lineno, tag } => Ok(TypeIgnore::TypeIgnore { + lineno: Foldable::fold(lineno, folder)?, + tag: Foldable::fold(tag, folder)?, + }), } } } - diff --git a/nac3ast/src/constant.rs b/nac3ast/src/constant.rs index d9b0d338f..b5e535884 100644 --- a/nac3ast/src/constant.rs +++ b/nac3ast/src/constant.rs @@ -85,33 +85,22 @@ impl crate::fold::Fold for ConstantOptimizer { fn fold_expr(&mut self, node: crate::Expr) -> Result, Self::Error> { match node.node { crate::ExprKind::Tuple { elts, ctx } => { - let elts = elts - .into_iter() - .map(|x| self.fold_expr(x)) - .collect::, _>>()?; - let expr = if elts - .iter() - .all(|e| matches!(e.node, crate::ExprKind::Constant { .. })) - { - let tuple = elts - .into_iter() - .map(|e| match e.node { - crate::ExprKind::Constant { value, .. } => value, - _ => unreachable!(), - }) - .collect(); - crate::ExprKind::Constant { - value: Constant::Tuple(tuple), - kind: None, - } - } else { - crate::ExprKind::Tuple { elts, ctx } - }; - Ok(crate::Expr { - node: expr, - custom: node.custom, - location: node.location, - }) + let elts = + elts.into_iter().map(|x| self.fold_expr(x)).collect::, _>>()?; + let expr = + if elts.iter().all(|e| matches!(e.node, crate::ExprKind::Constant { .. })) { + let tuple = elts + .into_iter() + .map(|e| match e.node { + crate::ExprKind::Constant { value, .. } => value, + _ => unreachable!(), + }) + .collect(); + crate::ExprKind::Constant { value: Constant::Tuple(tuple), kind: None } + } else { + crate::ExprKind::Tuple { elts, ctx } + }; + Ok(crate::Expr { node: expr, custom: node.custom, location: node.location }) } _ => crate::fold::fold_expr(self, node), } @@ -138,18 +127,12 @@ mod tests { Located { location, custom, - node: ExprKind::Constant { - value: 1.into(), - kind: None, - }, + node: ExprKind::Constant { value: 1.into(), kind: None }, }, Located { location, custom, - node: ExprKind::Constant { - value: 2.into(), - kind: None, - }, + node: ExprKind::Constant { value: 2.into(), kind: None }, }, Located { location, @@ -160,26 +143,17 @@ mod tests { Located { location, custom, - node: ExprKind::Constant { - value: 3.into(), - kind: None, - }, + node: ExprKind::Constant { value: 3.into(), kind: None }, }, Located { location, custom, - node: ExprKind::Constant { - value: 4.into(), - kind: None, - }, + node: ExprKind::Constant { value: 4.into(), kind: None }, }, Located { location, custom, - node: ExprKind::Constant { - value: 5.into(), - kind: None, - }, + node: ExprKind::Constant { value: 5.into(), kind: None }, }, ], }, @@ -187,9 +161,7 @@ mod tests { ], }, }; - let new_ast = ConstantOptimizer::new() - .fold_expr(ast) - .unwrap_or_else(|e| match e {}); + let new_ast = ConstantOptimizer::new().fold_expr(ast).unwrap_or_else(|e| match e {}); assert_eq!( new_ast, Located { @@ -199,11 +171,7 @@ mod tests { value: Constant::Tuple(vec![ 1.into(), 2.into(), - Constant::Tuple(vec![ - 3.into(), - 4.into(), - 5.into(), - ]) + Constant::Tuple(vec![3.into(), 4.into(), 5.into(),]) ]), kind: None }, diff --git a/nac3ast/src/fold_helpers.rs b/nac3ast/src/fold_helpers.rs index 5ff83d0b1..b7e551215 100644 --- a/nac3ast/src/fold_helpers.rs +++ b/nac3ast/src/fold_helpers.rs @@ -64,11 +64,4 @@ macro_rules! simple_fold { }; } -simple_fold!( - usize, - String, - bool, - StrRef, - constant::Constant, - constant::ConversionFlag -); +simple_fold!(usize, String, bool, StrRef, constant::Constant, constant::ConversionFlag); diff --git a/nac3ast/src/impls.rs b/nac3ast/src/impls.rs index 666acd1fd..82398dac8 100644 --- a/nac3ast/src/impls.rs +++ b/nac3ast/src/impls.rs @@ -34,10 +34,7 @@ impl ExprKind { ExprKind::Starred { .. } => "starred", ExprKind::Slice { .. } => "slice", ExprKind::JoinedStr { values } => { - if values - .iter() - .any(|e| matches!(e.node, ExprKind::JoinedStr { .. })) - { + if values.iter().any(|e| matches!(e.node, ExprKind::JoinedStr { .. })) { "f-string expression" } else { "literal" diff --git a/nac3ast/src/lib.rs b/nac3ast/src/lib.rs index 2a1786d62..46259896c 100644 --- a/nac3ast/src/lib.rs +++ b/nac3ast/src/lib.rs @@ -9,6 +9,6 @@ mod impls; mod location; pub use ast_gen::*; -pub use location::{Location, FileName}; +pub use location::{FileName, Location}; pub type Suite = Vec>; diff --git a/nac3ast/src/location.rs b/nac3ast/src/location.rs index 880b824a4..c912708f2 100644 --- a/nac3ast/src/location.rs +++ b/nac3ast/src/location.rs @@ -21,7 +21,7 @@ impl From for FileName { pub struct Location { pub row: usize, pub column: usize, - pub file: FileName + pub file: FileName, } impl fmt::Display for Location { @@ -53,11 +53,7 @@ impl Location { ) } } - Visualize { - loc: *self, - line, - desc, - } + Visualize { loc: *self, line, desc } } } diff --git a/nac3core/build.rs b/nac3core/build.rs index a032bb934..edc60748e 100644 --- a/nac3core/build.rs +++ b/nac3core/build.rs @@ -18,17 +18,8 @@ fn main() { * Compiling for WASM32 and filtering the output with regex is the closest we can get. */ - const FLAG: &[&str] = &[ - "--target=wasm32", - FILE, - "-O3", - "-emit-llvm", - "-S", - "-Wall", - "-Wextra", - "-o", - "-", - ]; + const FLAG: &[&str] = + &["--target=wasm32", FILE, "-O3", "-emit-llvm", "-S", "-Wall", "-Wextra", "-o", "-"]; let output = Command::new("clang") .args(FLAG) .output() diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 50e5b5603..e2c308791 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -11,22 +11,22 @@ use crate::{ symbol_resolver::{SymbolValue, ValueEnum}, toplevel::{DefinitionId, TopLevelDef}, typecheck::{ + magic_methods::{binop_assign_name, binop_name}, typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier}, - magic_methods::{binop_name, binop_assign_name}, }, }; use inkwell::{ - AddressSpace, attributes::{Attribute, AttributeLoc}, types::{AnyType, BasicType, BasicTypeEnum}, - values::{BasicValueEnum, FunctionValue, IntValue, PointerValue} + values::{BasicValueEnum, FunctionValue, IntValue, PointerValue}, + AddressSpace, }; use itertools::{chain, izip, zip, Itertools}; use nac3parser::ast::{ self, Boolop, Comprehension, Constant, Expr, ExprKind, Location, Operator, StrRef, }; -use super::{CodeGenerator, need_sret}; +use super::{need_sret, CodeGenerator}; pub fn get_subst_key( unifier: &mut Unifier, @@ -241,7 +241,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { op: &Operator, lhs: BasicValueEnum<'ctx>, rhs: BasicValueEnum<'ctx>, - signed: bool + signed: bool, ) -> BasicValueEnum<'ctx> { let (lhs, rhs) = if let (BasicValueEnum::IntValue(lhs), BasicValueEnum::IntValue(rhs)) = (lhs, rhs) { @@ -270,9 +270,15 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { (Operator::BitXor, _) => self.builder.build_xor(lhs, rhs, "xor").into(), (Operator::BitAnd, _) => self.builder.build_and(lhs, rhs, "and").into(), (Operator::LShift, _) => self.builder.build_left_shift(lhs, rhs, "lshift").into(), - (Operator::RShift, _) => self.builder.build_right_shift(lhs, rhs, true, "rshift").into(), - (Operator::FloorDiv, true) => self.builder.build_int_signed_div(lhs, rhs, "floordiv").into(), - (Operator::FloorDiv, false) => self.builder.build_int_unsigned_div(lhs, rhs, "floordiv").into(), + (Operator::RShift, _) => { + self.builder.build_right_shift(lhs, rhs, true, "rshift").into() + } + (Operator::FloorDiv, true) => { + self.builder.build_int_signed_div(lhs, rhs, "floordiv").into() + } + (Operator::FloorDiv, false) => { + self.builder.build_int_unsigned_div(lhs, rhs, "floordiv").into() + } (Operator::Pow, s) => integer_power(generator, self, lhs, rhs, s).into(), // special implementation? (Operator::MatMult, _) => unreachable!(), @@ -340,18 +346,28 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { let byval_id = Attribute::get_named_enum_kind_id("byval"); let offset = if fun.get_enum_attribute(AttributeLoc::Param(0), sret_id).is_some() { - return_slot = Some(self.builder.build_alloca(fun.get_type().get_param_types()[0] - .into_pointer_type().get_element_type().into_struct_type(), call_name)); + return_slot = Some( + self.builder.build_alloca( + fun.get_type().get_param_types()[0] + .into_pointer_type() + .get_element_type() + .into_struct_type(), + call_name, + ), + ); loc_params.push((*return_slot.as_ref().unwrap()).into()); 1 } else { 0 }; for (i, param) in params.iter().enumerate() { - if fun.get_enum_attribute(AttributeLoc::Param((i + offset) as u32), byval_id).is_some() { + if fun + .get_enum_attribute(AttributeLoc::Param((i + offset) as u32), byval_id) + .is_some() + { // lazy update if loc_params.is_empty() { - loc_params.extend(params[0..i+offset].iter().copied()); + loc_params.extend(params[0..i + offset].iter().copied()); } let slot = self.builder.build_alloca(param.get_type(), call_name); loc_params.push(slot.into()); @@ -361,11 +377,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } } - let params = if loc_params.is_empty() { - params - } else { - &loc_params - }; + let params = if loc_params.is_empty() { params } else { &loc_params }; let result = if let Some(target) = self.unwind_target { let current = self.builder.get_insert_block().unwrap().get_parent().unwrap(); let then_block = self.ctx.append_basic_block(current, &format!("after.{}", call_name)); @@ -496,7 +508,10 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>( match def { TopLevelDef::Class { methods, .. } => { // TODO: what about other fields that require alloca? - let fun_id = methods.iter().find(|method| method.0 == "__init__".into()).and_then(|method| Some(method.2)); + let fun_id = methods + .iter() + .find(|method| method.0 == "__init__".into()) + .and_then(|method| Some(method.2)); let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type(); let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap(); let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into(); @@ -636,8 +651,12 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( ); } // reorder the parameters - let mut real_params = - fun.0.args.iter().map(|arg| (mapping.remove(&arg.name).unwrap(), arg.ty)).collect_vec(); + let mut real_params = fun + .0 + .args + .iter() + .map(|arg| (mapping.remove(&arg.name).unwrap(), arg.ty)) + .collect_vec(); if let Some(obj) = &obj { real_params.insert(0, (obj.1.clone(), obj.0)); } @@ -700,32 +719,48 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( }; let has_sret = ret_type.map_or(false, |ret_type| need_sret(ctx.ctx, ret_type)); let mut byvals = Vec::new(); - let mut params = - args.iter().enumerate().map(|(i, arg)| match ctx.get_llvm_type(generator, arg.ty) { - BasicTypeEnum::StructType(ty) if is_extern => { - byvals.push((i, ty)); - ty.ptr_type(AddressSpace::Generic).into() - }, - x => x - }.into()).collect_vec(); + let mut params = args + .iter() + .enumerate() + .map(|(i, arg)| { + match ctx.get_llvm_type(generator, arg.ty) { + BasicTypeEnum::StructType(ty) if is_extern => { + byvals.push((i, ty)); + ty.ptr_type(AddressSpace::Generic).into() + } + x => x, + } + .into() + }) + .collect_vec(); if has_sret { params.insert(0, ret_type.unwrap().ptr_type(AddressSpace::Generic).into()); } let fun_ty = match ret_type { Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, false), - _ => ctx.ctx.void_type().fn_type(¶ms, false) + _ => ctx.ctx.void_type().fn_type(¶ms, false), }; let fun_val = ctx.module.add_function(&symbol, fun_ty, None); let offset = if has_sret { - fun_val.add_attribute(AttributeLoc::Param(0), - ctx.ctx.create_type_attribute(Attribute::get_named_enum_kind_id("sret"), ret_type.unwrap().as_any_type_enum())); + fun_val.add_attribute( + AttributeLoc::Param(0), + ctx.ctx.create_type_attribute( + Attribute::get_named_enum_kind_id("sret"), + ret_type.unwrap().as_any_type_enum(), + ), + ); 1 } else { 0 }; for (i, ty) in byvals { - fun_val.add_attribute(AttributeLoc::Param((i as u32) + offset), - ctx.ctx.create_type_attribute(Attribute::get_named_enum_kind_id("byval"), ty.as_any_type_enum())); + fun_val.add_attribute( + AttributeLoc::Param((i as u32) + offset), + ctx.ctx.create_type_attribute( + Attribute::get_named_enum_kind_id("byval"), + ty.as_any_type_enum(), + ), + ); } fun_val }); @@ -789,7 +824,11 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( let cont_bb = ctx.ctx.append_basic_block(current, "cont"); let Comprehension { target, iter, ifs, .. } = &generators[0]; - let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(ctx, generator, iter.custom.unwrap())?; + let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum( + ctx, + generator, + iter.custom.unwrap(), + )?; let int32 = ctx.ctx.i32_type(); let size_t = generator.get_size_type(ctx.ctx); let zero_size_t = size_t.const_zero(); @@ -930,14 +969,16 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( ) -> Result>, String> { let ty1 = ctx.unifier.get_representative(left.custom.unwrap()); let ty2 = ctx.unifier.get_representative(right.custom.unwrap()); - let left_val = generator - .gen_expr(ctx, left)? - .unwrap() - .to_basic_value_enum(ctx, generator, left.custom.unwrap())?; - let right_val = generator - .gen_expr(ctx, right)? - .unwrap() - .to_basic_value_enum(ctx, generator, right.custom.unwrap())?; + let left_val = generator.gen_expr(ctx, left)?.unwrap().to_basic_value_enum( + ctx, + generator, + left.custom.unwrap(), + )?; + let right_val = generator.gen_expr(ctx, right)?.unwrap().to_basic_value_enum( + ctx, + generator, + right.custom.unwrap(), + )?; // we can directly compare the types, because we've got their representatives // which would be unchanged until further unification, which we would never do @@ -957,7 +998,8 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( let ty = f64_t.fn_type(&[f64_t.into(), i32_t.into()], false); ctx.module.add_function("llvm.powi.f64.i32", ty, None) }); - let res = ctx.builder + let res = ctx + .builder .build_call(pow_intr, &[left_val.into(), right_val.into()], "f_pow_i") .try_as_basic_value() .unwrap_left(); @@ -966,10 +1008,8 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( let (op_name, id) = if let TypeEnum::TObj { fields, obj_id, .. } = ctx.unifier.get_ty_immutable(left.custom.unwrap()).as_ref() { - let (binop_name, binop_assign_name) = ( - binop_name(op).into(), - binop_assign_name(op).into() - ); + let (binop_name, binop_assign_name) = + (binop_name(op).into(), binop_assign_name(op).into()); // if is aug_assign, try aug_assign operator first if is_aug_assign && fields.contains_key(&binop_assign_name) { (binop_assign_name, *obj_id) @@ -994,7 +1034,7 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( } else { unreachable!("must be tobj") } - }, + } }; let fun_id = { let defs = ctx.top_level.definitions.read(); @@ -1011,7 +1051,8 @@ pub fn gen_binop_expr<'ctx, 'a, G: CodeGenerator>( Some((left.custom.unwrap(), left_val.into())), (&signature, fun_id), vec![(None, right_val.into())], - ).map(|f| f.map(|f| f.into())) + ) + .map(|f| f.map(|f| f.into())) } } @@ -1033,14 +1074,14 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( ctx.unifier.get_ty(expr.custom.unwrap()).as_ref(), ctx.unifier.get_ty(ctx.primitives.option).as_ref(), ) { - ( - TypeEnum::TObj { obj_id, params, .. }, - TypeEnum::TObj { obj_id: opt_id, .. }, - ) if *obj_id == *opt_id => ctx - .get_llvm_type(generator, *params.iter().next().unwrap().1) - .ptr_type(AddressSpace::Generic) - .const_null() - .into(), + (TypeEnum::TObj { obj_id, params, .. }, TypeEnum::TObj { obj_id: opt_id, .. }) + if *obj_id == *opt_id => + { + ctx.get_llvm_type(generator, *params.iter().next().unwrap().1) + .ptr_type(AddressSpace::Generic) + .const_null() + .into() + } _ => unreachable!("must be option type"), } } @@ -1058,12 +1099,9 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( let elements = elts .iter() .map(|x| { - generator - .gen_expr(ctx, x) - .map_or_else( - Err, - |v| v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap()) - ) + generator.gen_expr(ctx, x).map_or_else(Err, |v| { + v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap()) + }) }) .collect::, _>>()?; let ty = if elements.is_empty() { @@ -1094,9 +1132,9 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( let element_val = elts .iter() .map(|x| { - generator - .gen_expr(ctx, x) - .map_or_else(Err, |v| v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap())) + generator.gen_expr(ctx, x).map_or_else(Err, |v| { + v.unwrap().to_basic_value_enum(ctx, generator, x.custom.unwrap()) + }) }) .collect::, _>>()?; let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec(); @@ -1117,14 +1155,17 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( ExprKind::Attribute { value, attr, .. } => { // note that we would handle class methods directly in calls match generator.gen_expr(ctx, value)?.unwrap() { - ValueEnum::Static(v) => v.get_field(*attr, ctx).map_or_else(|| { - let v = v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?; - let index = ctx.get_attr_index(value.custom.unwrap(), *attr); - Ok(ValueEnum::Dynamic(ctx.build_gep_and_load( - v.into_pointer_value(), - &[zero, int32.const_int(index as u64, false)], - ))) as Result<_, String> - }, Ok)?, + ValueEnum::Static(v) => v.get_field(*attr, ctx).map_or_else( + || { + let v = v.to_basic_value_enum(ctx, generator, value.custom.unwrap())?; + let index = ctx.get_attr_index(value.custom.unwrap(), *attr); + Ok(ValueEnum::Dynamic(ctx.build_gep_and_load( + v.into_pointer_value(), + &[zero, int32.const_int(index as u64, false)], + ))) as Result<_, String> + }, + Ok, + )?, ValueEnum::Dynamic(v) => { let index = ctx.get_attr_index(value.custom.unwrap(), *attr); ValueEnum::Dynamic(ctx.build_gep_and_load( @@ -1184,10 +1225,11 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( } ExprKind::UnaryOp { op, operand } => { let ty = ctx.unifier.get_representative(operand.custom.unwrap()); - let val = - generator.gen_expr(ctx, operand)? - .unwrap() - .to_basic_value_enum(ctx, generator, operand.custom.unwrap())?; + let val = generator.gen_expr(ctx, operand)?.unwrap().to_basic_value_enum( + ctx, + generator, + operand.custom.unwrap(), + )?; if ty == ctx.primitives.bool { let val = val.into_int_value(); match op { @@ -1244,14 +1286,16 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( BasicValueEnum::IntValue(lhs), BasicValueEnum::IntValue(rhs), ) = ( - generator - .gen_expr(ctx, lhs)? - .unwrap() - .to_basic_value_enum(ctx, generator, lhs.custom.unwrap())?, - generator - .gen_expr(ctx, rhs)? - .unwrap() - .to_basic_value_enum(ctx, generator, rhs.custom.unwrap())?, + generator.gen_expr(ctx, lhs)?.unwrap().to_basic_value_enum( + ctx, + generator, + lhs.custom.unwrap(), + )?, + generator.gen_expr(ctx, rhs)?.unwrap().to_basic_value_enum( + ctx, + generator, + rhs.custom.unwrap(), + )?, ) { (lhs, rhs) } else { @@ -1272,14 +1316,16 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( BasicValueEnum::FloatValue(lhs), BasicValueEnum::FloatValue(rhs), ) = ( - generator - .gen_expr(ctx, lhs)? - .unwrap() - .to_basic_value_enum(ctx, generator, lhs.custom.unwrap())?, - generator - .gen_expr(ctx, rhs)? - .unwrap() - .to_basic_value_enum(ctx, generator, rhs.custom.unwrap())?, + generator.gen_expr(ctx, lhs)?.unwrap().to_basic_value_enum( + ctx, + generator, + lhs.custom.unwrap(), + )?, + generator.gen_expr(ctx, rhs)?.unwrap().to_basic_value_enum( + ctx, + generator, + rhs.custom.unwrap(), + )?, ) { (lhs, rhs) } else { @@ -1337,7 +1383,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( match result { None => None, Some(v) => { - let b = b.unwrap().to_basic_value_enum(ctx, generator, orelse.custom.unwrap())?; + let b = + b.unwrap().to_basic_value_enum(ctx, generator, orelse.custom.unwrap())?; Some(ctx.builder.build_store(v, b)) } }; @@ -1345,7 +1392,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( ctx.builder.position_at_end(cont_bb); match result { None => return Ok(None), - Some(v) => return Ok(Some(ctx.builder.build_load(v, "if_exp_val_load").into())) + Some(v) => return Ok(Some(ctx.builder.build_load(v, "if_exp_val_load").into())), } } ExprKind::Call { func, args, keywords } => { @@ -1419,14 +1466,12 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( .unwrap() .get_parent() .unwrap(); - let unreachable_block = ctx.ctx.append_basic_block( - current_fun, - "unwrap_none_unreachable" - ); - let exn_block = ctx.ctx.append_basic_block( - current_fun, - "unwrap_none_exception" - ); + let unreachable_block = ctx + .ctx + .append_basic_block(current_fun, "unwrap_none_unreachable"); + let exn_block = ctx + .ctx + .append_basic_block(current_fun, "unwrap_none_exception"); ctx.builder.build_unconditional_branch(exn_block); ctx.builder.position_at_end(exn_block); ctx.raise_exn( @@ -1434,22 +1479,24 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( "0:UnwrapNoneError", err_msg, [None, None, None], - ctx.current_loc + ctx.current_loc, ); ctx.builder.position_at_end(unreachable_block); let ptr = ctx .get_llvm_type(generator, value.custom.unwrap()) .into_pointer_type() .const_null(); - return Ok(Some(ctx.builder.build_load( - ptr, - "unwrap_none_unreachable_load" - ).into())); + return Ok(Some( + ctx.builder + .build_load(ptr, "unwrap_none_unreachable_load") + .into(), + )); } Some(v) => return Ok(Some(v)), - } + }, ValueEnum::Dynamic(BasicValueEnum::PointerValue(ptr)) => { - let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null"); + let not_null = + ctx.builder.build_is_not_null(ptr, "unwrap_not_null"); ctx.make_assert( generator, not_null, @@ -1458,12 +1505,11 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( [None, None, None], expr.location, ); - return Ok(Some(ctx.builder.build_load( - ptr, - "unwrap_some_load" - ).into())) + return Ok(Some( + ctx.builder.build_load(ptr, "unwrap_some_load").into(), + )); } - _ => unreachable!("option must be static or ptr") + _ => unreachable!("option must be static or ptr"), } } return Ok(generator @@ -1574,30 +1620,26 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( } else { unreachable!("tuple subscript must be const int after type check"); }; - let v = generator - .gen_expr(ctx, value)? - .unwrap(); + let v = generator.gen_expr(ctx, value)?.unwrap(); match v { ValueEnum::Dynamic(v) => { let v = v.into_struct_value(); ctx.builder.build_extract_value(v, index, "tup_elem").unwrap().into() } - ValueEnum::Static(v) => { - match v.get_tuple_element(index) { - Some(v) => v, - None => { - let tup = v - .to_basic_value_enum(ctx, generator, value.custom.unwrap())? - .into_struct_value(); - ctx.builder.build_extract_value(tup, index, "tup_elem").unwrap().into() - } + ValueEnum::Static(v) => match v.get_tuple_element(index) { + Some(v) => v, + None => { + let tup = v + .to_basic_value_enum(ctx, generator, value.custom.unwrap())? + .into_struct_value(); + ctx.builder.build_extract_value(tup, index, "tup_elem").unwrap().into() } - } + }, } } else { unreachable!("should not be other subscriptable types after type check"); } - }, + } ExprKind::ListComp { .. } => gen_comprehension(generator, ctx, expr)?.into(), _ => unimplemented!(), })) diff --git a/nac3core/src/codegen/irrt/mod.rs b/nac3core/src/codegen/irrt/mod.rs index 95f6e52fa..0947fd9b4 100644 --- a/nac3core/src/codegen/irrt/mod.rs +++ b/nac3core/src/codegen/irrt/mod.rs @@ -261,7 +261,11 @@ pub fn handle_slice_index_bound<'a, 'ctx, G: CodeGenerator>( ctx.module.add_function(SYMBOL, fn_t, None) }); - let i = generator.gen_expr(ctx, i)?.unwrap().to_basic_value_enum(ctx, generator, i.custom.unwrap())?; + let i = generator.gen_expr(ctx, i)?.unwrap().to_basic_value_enum( + ctx, + generator, + i.custom.unwrap(), + )?; Ok(ctx .builder .build_call(func, &[i.into(), length.into()], "bounded_ind") @@ -329,27 +333,19 @@ pub fn list_slice_assignment<'ctx, 'a>( // index in bound and positive should be done // assert if dest.step == 1 then len(src) <= len(dest) else len(src) == len(dest), and // throw exception if not satisfied - let src_end = ctx.builder + let src_end = ctx + .builder .build_select( - ctx.builder.build_int_compare( - inkwell::IntPredicate::SLT, - src_idx.2, - zero, - "is_neg", - ), + ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, src_idx.2, zero, "is_neg"), ctx.builder.build_int_sub(src_idx.1, one, "e_min_one"), ctx.builder.build_int_add(src_idx.1, one, "e_add_one"), "final_e", ) .into_int_value(); - let dest_end = ctx.builder + let dest_end = ctx + .builder .build_select( - ctx.builder.build_int_compare( - inkwell::IntPredicate::SLT, - dest_idx.2, - zero, - "is_neg", - ), + ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, dest_idx.2, zero, "is_neg"), ctx.builder.build_int_sub(dest_idx.1, one, "e_min_one"), ctx.builder.build_int_add(dest_idx.1, one, "e_add_one"), "final_e", diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 191b023ed..0354e1e8e 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -8,8 +8,6 @@ use crate::{ }; use crossbeam::channel::{unbounded, Receiver, Sender}; use inkwell::{ - AddressSpace, - OptimizationLevel, attributes::{Attribute, AttributeLoc}, basic_block::BasicBlock, builder::Builder, @@ -17,10 +15,11 @@ use inkwell::{ module::Module, passes::{PassManager, PassManagerBuilder}, types::{AnyType, BasicType, BasicTypeEnum}, - values::{BasicValueEnum, FunctionValue, PhiValue, PointerValue} + values::{BasicValueEnum, FunctionValue, PhiValue, PointerValue}, + AddressSpace, OptimizationLevel, }; use itertools::Itertools; -use nac3parser::ast::{Stmt, StrRef, Location}; +use nac3parser::ast::{Location, Stmt, StrRef}; use parking_lot::{Condvar, Mutex}; use std::collections::{HashMap, HashSet}; use std::sync::{ @@ -300,7 +299,10 @@ fn get_llvm_type<'ctx>( &*definition.read() { let struct_type = ctx.opaque_struct_type(&name.to_string()); - type_cache.insert(unifier.get_representative(ty), struct_type.ptr_type(AddressSpace::Generic).into()); + type_cache.insert( + unifier.get_representative(ty), + struct_type.ptr_type(AddressSpace::Generic).into(), + ); let fields = fields_list .iter() .map(|f| { @@ -326,7 +328,11 @@ fn get_llvm_type<'ctx>( // a struct with fields in the order present in the tuple let fields = ty .iter() - .map(|ty| get_llvm_type(ctx, generator, unifier, top_level, type_cache, primitives, *ty)) + .map(|ty| { + get_llvm_type( + ctx, generator, unifier, top_level, type_cache, primitives, *ty, + ) + }) .collect_vec(); ctx.struct_type(&fields, false).into() } @@ -349,26 +355,35 @@ fn get_llvm_type<'ctx>( } fn need_sret<'ctx>(ctx: &'ctx Context, ty: BasicTypeEnum<'ctx>) -> bool { - fn need_sret_impl<'ctx>(ctx: &'ctx Context, ty: BasicTypeEnum<'ctx>, maybe_large: bool) -> bool { + fn need_sret_impl<'ctx>( + ctx: &'ctx Context, + ty: BasicTypeEnum<'ctx>, + maybe_large: bool, + ) -> bool { match ty { BasicTypeEnum::IntType(_) | BasicTypeEnum::PointerType(_) => false, BasicTypeEnum::FloatType(_) if maybe_large => false, - BasicTypeEnum::StructType(ty) if maybe_large && ty.count_fields() <= 2 => - ty.get_field_types().iter().any(|ty| need_sret_impl(ctx, *ty, false)), + BasicTypeEnum::StructType(ty) if maybe_large && ty.count_fields() <= 2 => { + ty.get_field_types().iter().any(|ty| need_sret_impl(ctx, *ty, false)) + } _ => true, } } need_sret_impl(ctx, ty, true) } -pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenContext) -> Result<(), String>> ( +pub fn gen_func_impl< + 'ctx, + G: CodeGenerator, + F: FnOnce(&mut G, &mut CodeGenContext) -> Result<(), String>, +>( context: &'ctx Context, generator: &mut G, registry: &WorkerRegistry, builder: Builder<'ctx>, module: Module<'ctx>, task: CodeGenTask, - codegen_function: F + codegen_function: F, ) -> Result<(Builder<'ctx>, Module<'ctx>, FunctionValue<'ctx>), (Builder<'ctx>, String)> { let top_level_ctx = registry.top_level_ctx.clone(); let static_value_store = registry.static_value_store.clone(); @@ -463,7 +478,15 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte let ret_type = if unifier.unioned(ret, primitives.none) { None } else { - Some(get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, &primitives, ret)) + Some(get_llvm_type( + context, + generator, + &mut unifier, + top_level_ctx.as_ref(), + &mut type_cache, + &primitives, + ret, + )) }; let has_sret = ret_type.map_or(false, |ty| need_sret(context, ty)); @@ -489,7 +512,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte let fn_type = match ret_type { Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, false), - _ => context.void_type().fn_type(¶ms, false) + _ => context.void_type().fn_type(¶ms, false), }; let symbol = &task.symbol_name; @@ -504,9 +527,13 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte fn_val.set_personality_function(personality); } if has_sret { - fn_val.add_attribute(AttributeLoc::Param(0), - context.create_type_attribute(Attribute::get_named_enum_kind_id("sret"), - ret_type.unwrap().as_any_type_enum())); + fn_val.add_attribute( + AttributeLoc::Param(0), + context.create_type_attribute( + Attribute::get_named_enum_kind_id("sret"), + ret_type.unwrap().as_any_type_enum(), + ), + ); } let init_bb = context.append_basic_block(fn_val, "init"); diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index 5b58d5053..935b5a065 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -87,19 +87,15 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( .unwrap() .to_basic_value_enum(ctx, generator, value.custom.unwrap())? .into_pointer_value(); - let len = ctx - .build_gep_and_load(v, &[zero, i32_type.const_int(1, false)]) - .into_int_value(); + let len = + ctx.build_gep_and_load(v, &[zero, i32_type.const_int(1, false)]).into_int_value(); let raw_index = generator .gen_expr(ctx, slice)? .unwrap() .to_basic_value_enum(ctx, generator, slice.custom.unwrap())? .into_int_value(); - let raw_index = ctx.builder.build_int_s_extend( - raw_index, - generator.get_size_type(ctx.ctx), - "sext", - ); + let raw_index = + ctx.builder.build_int_s_extend(raw_index, generator.get_size_type(ctx.ctx), "sext"); // handle negative index let is_negative = ctx.builder.build_int_compare( inkwell::IntPredicate::SLT, @@ -114,12 +110,8 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( .into_int_value(); // unsigned less than is enough, because negative index after adjustment is // bigger than the length (for unsigned cmp) - let bound_check = ctx.builder.build_int_compare( - inkwell::IntPredicate::ULT, - index, - len, - "inbound", - ); + let bound_check = + ctx.builder.build_int_compare(inkwell::IntPredicate::ULT, index, len, "inbound"); ctx.make_assert( generator, bound_check, @@ -696,12 +688,15 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>( &mut ctx.unifier, type_.custom.unwrap(), ); - let obj_id = if let TypeEnum::TObj { obj_id, .. } = &*ctx.unifier.get_ty(type_.custom.unwrap()) { + let obj_id = if let TypeEnum::TObj { obj_id, .. } = + &*ctx.unifier.get_ty(type_.custom.unwrap()) + { *obj_id } else { unreachable!() }; - let exception_name = format!("{}:{}", ctx.resolver.get_exception_id(obj_id.0), exn_name); + let exception_name = + format!("{}:{}", ctx.resolver.get_exception_id(obj_id.0), exn_name); let exn_id = ctx.resolver.get_string_id(&exception_name); let exn_id_global = ctx.module.add_global(ctx.ctx.i32_type(), None, &format!("exn.{}", exn_id)); @@ -751,7 +746,9 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>( let mut final_proxy_lambda = |ctx: &mut CodeGenContext<'ctx, 'a>, target: BasicBlock<'ctx>, - block: BasicBlock<'ctx>| final_proxy(ctx, target, block, final_data.as_mut().unwrap()); + block: BasicBlock<'ctx>| { + final_proxy(ctx, target, block, final_data.as_mut().unwrap()) + }; let mut redirect_lambda = |ctx: &mut CodeGenContext<'ctx, 'a>, target: BasicBlock<'ctx>, block: BasicBlock<'ctx>| { @@ -1059,7 +1056,7 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( stmt.location, ) } - _ => unimplemented!() + _ => unimplemented!(), }; Ok(()) } diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index 678016338..ed9144c8f 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -160,7 +160,7 @@ pub trait SymbolResolver { &self, _unifier: &mut Unifier, _top_level_defs: &[Arc>], - _primitives: &PrimitiveStore + _primitives: &PrimitiveStore, ) -> Result<(), String> { Ok(()) } diff --git a/nac3core/src/toplevel/builtins.rs b/nac3core/src/toplevel/builtins.rs index 15fa2e071..1c1228fc6 100644 --- a/nac3core/src/toplevel/builtins.rs +++ b/nac3core/src/toplevel/builtins.rs @@ -14,8 +14,8 @@ pub fn get_exn_constructor( class_id: usize, cons_id: usize, unifier: &mut Unifier, - primitives: &PrimitiveStore -)-> (TopLevelDef, TopLevelDef, Type, Type) { + primitives: &PrimitiveStore, +) -> (TopLevelDef, TopLevelDef, Type, Type) { let int32 = primitives.int32; let int64 = primitives.int64; let string = primitives.str; @@ -225,11 +225,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, obj, _, _, generator| { let expect_ty = obj.clone().unwrap().0; - let obj_val = obj.unwrap().1.clone().to_basic_value_enum( - ctx, - generator, - expect_ty, - )?; + let obj_val = + obj.unwrap().1.clone().to_basic_value_enum(ctx, generator, expect_ty)?; if let BasicValueEnum::PointerValue(ptr) = obj_val { Ok(Some(ctx.builder.build_is_not_null(ptr, "is_some").into())) } else { @@ -250,11 +247,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, obj, _, _, generator| { let expect_ty = obj.clone().unwrap().0; - let obj_val = obj.unwrap().1.clone().to_basic_value_enum( - ctx, - generator, - expect_ty, - )?; + let obj_val = + obj.unwrap().1.clone().to_basic_value_enum(ctx, generator, expect_ty)?; if let BasicValueEnum::PointerValue(ptr) = obj_val { Ok(Some(ctx.builder.build_is_null(ptr, "is_none").into())) } else { @@ -272,11 +266,9 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new( - |_, _, _, _, _| { - unreachable!("handled in gen_expr") - }, - )))), + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|_, _, _, _, _| { + unreachable!("handled in gen_expr") + })))), loc: None, })), Arc::new(RwLock::new(TopLevelDef::Function { @@ -567,7 +559,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, _, _, args, generator| { - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, ctx.primitives.float)?; + let arg = args[0].1.clone().to_basic_value_enum( + ctx, + generator, + ctx.primitives.float, + )?; let round_intrinsic = ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -607,7 +603,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, _, _, args, generator| { - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, ctx.primitives.float)?; + let arg = args[0].1.clone().to_basic_value_enum( + ctx, + generator, + ctx.primitives.float, + )?; let round_intrinsic = ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -668,13 +668,15 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { let ty_i32 = ctx.primitives.int32; for (i, arg) in args.iter().enumerate() { if arg.0 == Some("start".into()) { - start = Some(arg.1.clone().to_basic_value_enum(ctx, generator, ty_i32)?); + start = + Some(arg.1.clone().to_basic_value_enum(ctx, generator, ty_i32)?); } else if arg.0 == Some("stop".into()) { stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator, ty_i32)?); } else if arg.0 == Some("step".into()) { step = Some(arg.1.clone().to_basic_value_enum(ctx, generator, ty_i32)?); } else if i == 0 { - start = Some(arg.1.clone().to_basic_value_enum(ctx, generator, ty_i32)?); + start = + Some(arg.1.clone().to_basic_value_enum(ctx, generator, ty_i32)?); } else if i == 1 { stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator, ty_i32)?); } else if i == 2 { @@ -829,7 +831,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, _, _, args, generator| { - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, ctx.primitives.float)?; + let arg = args[0].1.clone().to_basic_value_enum( + ctx, + generator, + ctx.primitives.float, + )?; let floor_intrinsic = ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -869,7 +875,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, _, _, args, generator| { - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, ctx.primitives.float)?; + let arg = args[0].1.clone().to_basic_value_enum( + ctx, + generator, + ctx.primitives.float, + )?; let floor_intrinsic = ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -909,7 +919,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, _, _, args, generator| { - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, ctx.primitives.float)?; + let arg = args[0].1.clone().to_basic_value_enum( + ctx, + generator, + ctx.primitives.float, + )?; let ceil_intrinsic = ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -949,7 +963,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( |ctx, _, _, args, generator| { - let arg = args[0].1.clone().to_basic_value_enum(ctx, generator, ctx.primitives.float)?; + let arg = args[0].1.clone().to_basic_value_enum( + ctx, + generator, + ctx.primitives.float, + )?; let ceil_intrinsic = ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -1005,7 +1023,10 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { Ok(if ctx.unifier.unioned(arg_ty, range_ty) { let arg = arg.into_pointer_value(); let (start, end, step) = destructure_range(ctx, arg); - Some(calculate_len_for_slice_range(generator, ctx, start, end, step).into()) + Some( + calculate_len_for_slice_range(generator, ctx, start, end, step) + .into(), + ) } else { let int32 = ctx.ctx.i32_type(); let zero = int32.const_zero(); @@ -1249,25 +1270,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { ( izip!(top_level_def_list, ast_list).collect_vec(), &[ - "int32", - "int64", - "uint32", - "uint64", - "float", - "round", - "round64", - "range", - "str", - "bool", - "floor", - "floor64", - "ceil", - "ceil64", - "len", - "min", - "max", - "abs", - "Some", + "int32", "int64", "uint32", "uint64", "float", "round", "round64", "range", "str", + "bool", "floor", "floor64", "ceil", "ceil64", "len", "min", "max", "abs", "Some", ], ) } diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index d35a4c020..a812fdc0c 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -91,8 +91,7 @@ impl TopLevelComposer { assert!(name == *simple_name); builtin_ty.insert(name, *signature); builtin_id.insert(name, DefinitionId(id)); - } else if let TopLevelDef::Class { name, constructor, object_id, .. } = &*def - { + } else if let TopLevelDef::Class { name, constructor, object_id, .. } = &*def { assert!(id == object_id.0); if let Some(constructor) = constructor { builtin_ty.insert(*name, *constructor); @@ -739,8 +738,13 @@ impl TopLevelComposer { let mut subst_list = Some(Vec::new()); // unification of previously assigned typevar let mut unification_helper = |ty, def| { - let target_ty = - get_type_from_type_annotation_kinds(&temp_def_list, unifier, primitives, &def, &mut subst_list)?; + let target_ty = get_type_from_type_annotation_kinds( + &temp_def_list, + unifier, + primitives, + &def, + &mut subst_list, + )?; unifier.unify(ty, target_ty).map_err(|e| e.to_display(unifier).to_string())?; Ok(()) as Result<(), String> }; @@ -780,7 +784,9 @@ impl TopLevelComposer { match &*def.read() { TopLevelDef::Class { resolver: Some(resolver), .. } | TopLevelDef::Function { resolver: Some(resolver), .. } => { - if let Err(e) = resolver.handle_deferred_eval(unifier, &temp_def_list, primitives) { + if let Err(e) = + resolver.handle_deferred_eval(unifier, &temp_def_list, primitives) + { errors.insert(e); } } @@ -904,7 +910,7 @@ impl TopLevelComposer { unifier, primitives_store, &type_annotation, - &mut None + &mut None, )?; Ok(FuncArg { @@ -972,7 +978,7 @@ impl TopLevelComposer { unifier, primitives_store, &return_ty_annotation, - &mut None + &mut None, )? } else { primitives_store.none @@ -1334,7 +1340,7 @@ impl TopLevelComposer { )); } } - ast::StmtKind::Assign { .. } => {}, // we don't class attributes + ast::StmtKind::Assign { .. } => {} // we don't class attributes ast::StmtKind::Pass { .. } => {} ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior _ => { @@ -1483,24 +1489,30 @@ impl TopLevelComposer { // first, fix function typevar ids // they may be changed with our use of placeholders for (def, _) in definition_ast_list.iter().skip(self.builtin_num) { - if let TopLevelDef::Function { - signature, - var_id, - .. - } = &mut *def.write() { + if let TopLevelDef::Function { signature, var_id, .. } = &mut *def.write() { if let TypeEnum::TFunc(FunSignature { args, ret, vars }) = - unifier.get_ty(*signature).as_ref() { - let new_var_ids = vars.values().map(|v| match &*unifier.get_ty(*v) { - TypeEnum::TVar{id, ..} => *id, - _ => unreachable!(), - }).collect_vec(); + unifier.get_ty(*signature).as_ref() + { + let new_var_ids = vars + .values() + .map(|v| match &*unifier.get_ty(*v) { + TypeEnum::TVar { id, .. } => *id, + _ => unreachable!(), + }) + .collect_vec(); if new_var_ids != *var_id { let new_signature = FunSignature { args: args.clone(), ret: *ret, - vars: new_var_ids.iter().zip(vars.values()).map(|(id, v)| (*id, *v)).collect(), + vars: new_var_ids + .iter() + .zip(vars.values()) + .map(|(id, v)| (*id, *v)) + .collect(), }; - unifier.unification_table.set_value(*signature, Rc::new(TypeEnum::TFunc(new_signature))); + unifier + .unification_table + .set_value(*signature, Rc::new(TypeEnum::TFunc(new_signature))); *var_id = new_var_ids; } } @@ -1527,7 +1539,7 @@ impl TopLevelComposer { unifier, primitives_ty, &make_self_type_annotation(type_vars, *object_id), - &mut None + &mut None, )?; if ancestors .iter() @@ -1696,14 +1708,15 @@ impl TopLevelComposer { unifier, primitives_ty, &ty_ann, - &mut None + &mut None, )?; - vars.extend(type_vars.iter().map(|ty| + vars.extend(type_vars.iter().map(|ty| { if let TypeEnum::TVar { id, .. } = &*unifier.get_ty(*ty) { (*id, *ty) } else { unreachable!() - })); + } + })); Some((self_ty, type_vars.clone())) } else { unreachable!("must be class def") @@ -1918,7 +1931,12 @@ impl TopLevelComposer { } instance_to_stmt.insert( - get_subst_key(unifier, self_type, &subst, Some(&vars.keys().cloned().collect())), + get_subst_key( + unifier, + self_type, + &subst, + Some(&vars.keys().cloned().collect()), + ), FunInstance { body: Arc::new(fun_body), unifier_id: 0, diff --git a/nac3core/src/toplevel/helper.rs b/nac3core/src/toplevel/helper.rs index c6311862d..460b9eda1 100644 --- a/nac3core/src/toplevel/helper.rs +++ b/nac3core/src/toplevel/helper.rs @@ -521,65 +521,66 @@ pub fn parse_parameter_default_value( } match &default.node { ast::ExprKind::Constant { value, .. } => handle_constant(value, &default.location), - ast::ExprKind::Call { func, args, .. } if args.len() == 1 => { - match &func.node { - ast::ExprKind::Name { id, .. } if *id == "int64".into() => match &args[0].node { - ast::ExprKind::Constant { value: Constant::Int(v), .. } => { - let v: Result = (*v).try_into(); - match v { - Ok(v) => Ok(SymbolValue::I64(v)), - _ => Err(format!("default param value out of range at {}", default.location)), + ast::ExprKind::Call { func, args, .. } if args.len() == 1 => match &func.node { + ast::ExprKind::Name { id, .. } if *id == "int64".into() => match &args[0].node { + ast::ExprKind::Constant { value: Constant::Int(v), .. } => { + let v: Result = (*v).try_into(); + match v { + Ok(v) => Ok(SymbolValue::I64(v)), + _ => { + Err(format!("default param value out of range at {}", default.location)) } } - _ => Err(format!("only allow constant integer here at {}", default.location)) } - ast::ExprKind::Name { id, .. } if *id == "uint32".into() => match &args[0].node { - ast::ExprKind::Constant { value: Constant::Int(v), .. } => { - let v: Result = (*v).try_into(); - match v { - Ok(v) => Ok(SymbolValue::U32(v)), - _ => Err(format!("default param value out of range at {}", default.location)), + _ => Err(format!("only allow constant integer here at {}", default.location)), + }, + ast::ExprKind::Name { id, .. } if *id == "uint32".into() => match &args[0].node { + ast::ExprKind::Constant { value: Constant::Int(v), .. } => { + let v: Result = (*v).try_into(); + match v { + Ok(v) => Ok(SymbolValue::U32(v)), + _ => { + Err(format!("default param value out of range at {}", default.location)) } } - _ => Err(format!("only allow constant integer here at {}", default.location)) } - ast::ExprKind::Name { id, .. } if *id == "uint64".into() => match &args[0].node { - ast::ExprKind::Constant { value: Constant::Int(v), .. } => { - let v: Result = (*v).try_into(); - match v { - Ok(v) => Ok(SymbolValue::U64(v)), - _ => Err(format!("default param value out of range at {}", default.location)), + _ => Err(format!("only allow constant integer here at {}", default.location)), + }, + ast::ExprKind::Name { id, .. } if *id == "uint64".into() => match &args[0].node { + ast::ExprKind::Constant { value: Constant::Int(v), .. } => { + let v: Result = (*v).try_into(); + match v { + Ok(v) => Ok(SymbolValue::U64(v)), + _ => { + Err(format!("default param value out of range at {}", default.location)) } } - _ => Err(format!("only allow constant integer here at {}", default.location)) } - ast::ExprKind::Name { id, .. } if *id == "Some".into() => Ok( - SymbolValue::OptionSome( - Box::new(parse_parameter_default_value(&args[0], resolver)?) - ) - ), - _ => Err(format!("unsupported default parameter at {}", default.location)), - } - } - ast::ExprKind::Tuple { elts, .. } => Ok(SymbolValue::Tuple(elts - .iter() - .map(|x| parse_parameter_default_value(x, resolver)) - .collect::, _>>()? + _ => Err(format!("only allow constant integer here at {}", default.location)), + }, + ast::ExprKind::Name { id, .. } if *id == "Some".into() => Ok(SymbolValue::OptionSome( + Box::new(parse_parameter_default_value(&args[0], resolver)?), + )), + _ => Err(format!("unsupported default parameter at {}", default.location)), + }, + ast::ExprKind::Tuple { elts, .. } => Ok(SymbolValue::Tuple( + elts.iter() + .map(|x| parse_parameter_default_value(x, resolver)) + .collect::, _>>()?, )), ast::ExprKind::Name { id, .. } if id == &"none".into() => Ok(SymbolValue::OptionNone), ast::ExprKind::Name { id, .. } => { - resolver.get_default_param_value(default).ok_or_else( - || format!( + resolver.get_default_param_value(default).ok_or_else(|| { + format!( "`{}` cannot be used as a default parameter at {} \ (not primitive type, option or tuple / not defined?)", - id, - default.location + id, default.location ) - ) + }) } _ => Err(format!( "unsupported default parameter (not primitive type, option or tuple) at {}", default.location - )) + )), } } diff --git a/nac3core/src/toplevel/type_annotation.rs b/nac3core/src/toplevel/type_annotation.rs index 116a6b4cd..8df59ad1e 100644 --- a/nac3core/src/toplevel/type_annotation.rs +++ b/nac3core/src/toplevel/type_annotation.rs @@ -34,23 +34,23 @@ impl TypeAnnotation { } None => format!("class_def_{}", id.0), }; - format!( - "{}{}", - class_name, - { - let param_list = params.iter().map(|p| p.stringify(unifier)).collect_vec().join(", "); - if param_list.is_empty() { - "".into() - } else { - format!("[{}]", param_list) - } + format!("{}{}", class_name, { + let param_list = + params.iter().map(|p| p.stringify(unifier)).collect_vec().join(", "); + if param_list.is_empty() { + "".into() + } else { + format!("[{}]", param_list) } - ) + }) } Virtual(ty) => format!("virtual[{}]", ty.stringify(unifier)), List(ty) => format!("list[{}]", ty.stringify(unifier)), Tuple(types) => { - format!("tuple[{}]", types.iter().map(|p| p.stringify(unifier)).collect_vec().join(", ")) + format!( + "tuple[{}]", + types.iter().map(|p| p.stringify(unifier)).collect_vec().join(", ") + ) } } } @@ -302,7 +302,7 @@ pub fn get_type_from_type_annotation_kinds( unifier: &mut Unifier, primitives: &PrimitiveStore, ann: &TypeAnnotation, - subst_list: &mut Option> + subst_list: &mut Option>, ) -> Result { match ann { TypeAnnotation::CustomClass { id: obj_id, params } => { @@ -324,7 +324,7 @@ pub fn get_type_from_type_annotation_kinds( unifier, primitives, x, - subst_list + subst_list, ) }) .collect::, _>>()?; @@ -402,7 +402,7 @@ pub fn get_type_from_type_annotation_kinds( unifier, primitives, ty.as_ref(), - subst_list + subst_list, )?; Ok(unifier.add_ty(TypeEnum::TVirtual { ty })) } @@ -412,7 +412,7 @@ pub fn get_type_from_type_annotation_kinds( unifier, primitives, ty.as_ref(), - subst_list + subst_list, )?; Ok(unifier.add_ty(TypeEnum::TList { ty })) } @@ -420,7 +420,13 @@ pub fn get_type_from_type_annotation_kinds( let tys = tys .iter() .map(|x| { - get_type_from_type_annotation_kinds(top_level_defs, unifier, primitives, x, subst_list) + get_type_from_type_annotation_kinds( + top_level_defs, + unifier, + primitives, + x, + subst_list, + ) }) .collect::, _>>()?; Ok(unifier.add_ty(TypeEnum::TTuple { ty: tys })) diff --git a/nac3core/src/typecheck/function_check.rs b/nac3core/src/typecheck/function_check.rs index c2dc884db..9b47e0139 100644 --- a/nac3core/src/typecheck/function_check.rs +++ b/nac3core/src/typecheck/function_check.rs @@ -20,8 +20,9 @@ impl<'a> Inferencer<'a> { defined_identifiers: &mut HashSet, ) -> Result<(), String> { match &pattern.node { - ast::ExprKind::Name { id, .. } if id == &"none".into() => - Err(format!("cannot assign to a `none` (at {})", pattern.location)), + ast::ExprKind::Name { id, .. } if id == &"none".into() => { + Err(format!("cannot assign to a `none` (at {})", pattern.location)) + } ExprKind::Name { id, .. } => { if !defined_identifiers.contains(id) { defined_identifiers.insert(*id); diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index c72e1998f..7762c7017 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -430,7 +430,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> { self.unify(test.custom.unwrap(), self.primitives.bool, &test.location)?; match msg { Some(m) => self.unify(m.custom.unwrap(), self.primitives.str, &m.location)?, - None => () + None => (), } } _ => return report_error("Unsupported statement type", stmt.location), @@ -464,9 +464,14 @@ impl<'a> fold::Fold<()> for Inferencer<'a> { let var_map = params .iter() .map(|(id_var, ty)| { - if let TypeEnum::TVar { id, range, name, loc, .. } = &*self.unifier.get_ty(*ty) { + if let TypeEnum::TVar { id, range, name, loc, .. } = + &*self.unifier.get_ty(*ty) + { assert_eq!(*id, *id_var); - (*id, self.unifier.get_fresh_var_with_range(range, *name, *loc).0) + ( + *id, + self.unifier.get_fresh_var_with_range(range, *name, *loc).0, + ) } else { unreachable!() } @@ -822,7 +827,7 @@ impl<'a> Inferencer<'a> { }, }); } else { - return report_error("Integer out of bound", args[0].location) + return report_error("Integer out of bound", args[0].location); } } } @@ -842,13 +847,13 @@ impl<'a> Inferencer<'a> { }, }); } else { - return report_error("Integer out of bound", args[0].location) + return report_error("Integer out of bound", args[0].location); } } } if id == "uint64".into() && args.len() == 1 { if let ExprKind::Constant { value: ast::Constant::Int(val), kind } = - &args[0].node + &args[0].node { let custom = Some(self.primitives.uint64); let v: Result = (*val).try_into(); @@ -862,7 +867,7 @@ impl<'a> Inferencer<'a> { }, }); } else { - return report_error("Integer out of bound", args[0].location) + return report_error("Integer out of bound", args[0].location); } } } @@ -962,8 +967,9 @@ impl<'a> Inferencer<'a> { Ok(self.unifier.add_ty(TypeEnum::TTuple { ty: ty? })) } ast::Constant::Str(_) => Ok(self.primitives.str), - ast::Constant::None - => report_error("CPython `None` not supported (nac3 uses `none` instead)", *loc), + ast::Constant::None => { + report_error("CPython `None` not supported (nac3 uses `none` instead)", *loc) + } _ => report_error("not supported", *loc), } } @@ -998,8 +1004,11 @@ impl<'a> Inferencer<'a> { } (None, _) => { let t = self.unifier.stringify(ty); - report_error(&format!("`{}::{}` field/method does not exist", t, attr), value.location) - }, + report_error( + &format!("`{}::{}` field/method does not exist", t, attr), + value.location, + ) + } } } else { let attr_ty = self.unifier.get_dummy_var().0; @@ -1033,10 +1042,8 @@ impl<'a> Inferencer<'a> { let method = if let TypeEnum::TObj { fields, .. } = self.unifier.get_ty_immutable(left.custom.unwrap()).as_ref() { - let (binop_name, binop_assign_name) = ( - binop_name(op).into(), - binop_assign_name(op).into() - ); + let (binop_name, binop_assign_name) = + (binop_name(op).into(), binop_assign_name(op).into()); // if is aug_assign, try aug_assign operator first if is_aug_assign && fields.contains_key(&binop_assign_name) { binop_assign_name @@ -1115,9 +1122,11 @@ impl<'a> Inferencer<'a> { Ok(ty) } _ => { - if let TypeEnum::TTuple { .. } = &*self.unifier.get_ty(value.custom.unwrap()) - { - return report_error("Tuple index must be a constant (KernelInvariant is also not supported)", slice.location) + if let TypeEnum::TTuple { .. } = &*self.unifier.get_ty(value.custom.unwrap()) { + return report_error( + "Tuple index must be a constant (KernelInvariant is also not supported)", + slice.location, + ); } // the index is not a constant, so value can only be a list self.constrain(slice.custom.unwrap(), self.primitives.int32, &slice.location)?; diff --git a/nac3core/src/typecheck/typedef/mod.rs b/nac3core/src/typecheck/typedef/mod.rs index 861a2e37b..c028c7246 100644 --- a/nac3core/src/typecheck/typedef/mod.rs +++ b/nac3core/src/typecheck/typedef/mod.rs @@ -173,7 +173,7 @@ pub struct Unifier { pub(crate) calls: Vec>, var_id: u32, unify_cache: HashSet<(Type, Type)>, - snapshot: Option<(usize, u32)> + snapshot: Option<(usize, u32)>, } impl Default for Unifier { @@ -459,13 +459,10 @@ impl Unifier { if let Some(i) = required.iter().position(|v| v == k) { required.remove(i); } - let i = all_names - .iter() - .position(|v| &v.0 == k) - .ok_or_else(|| { - self.restore_snapshot(); - TypeError::new(TypeErrorKind::UnknownArgName(*k), *loc) - })?; + let i = all_names.iter().position(|v| &v.0 == k).ok_or_else(|| { + self.restore_snapshot(); + TypeError::new(TypeErrorKind::UnknownArgName(*k), *loc) + })?; let (name, expected) = all_names.remove(i); self.unify_impl(expected, *t, false).map_err(|_| { self.restore_snapshot(); diff --git a/nac3core/src/typecheck/typedef/test.rs b/nac3core/src/typecheck/typedef/test.rs index 52e420a7d..bbbc6f271 100644 --- a/nac3core/src/typecheck/typedef/test.rs +++ b/nac3core/src/typecheck/typedef/test.rs @@ -479,7 +479,8 @@ fn test_typevar_range() { assert_eq!( env.unify(a_list, int_list), Err("Incompatible types: list[typevar22] and list[0]\ - \n\nNotes:\n typevar22 ∈ {1}".into()) + \n\nNotes:\n typevar22 ∈ {1}" + .into()) ); let a = env.unifier.get_fresh_var_with_range(&[int, float], None, None).0; @@ -507,7 +508,10 @@ fn test_rigid_var() { assert_eq!(env.unify(a, b), Err("Incompatible types: typevar3 and typevar2".to_string())); env.unifier.unify(list_a, list_x).unwrap(); - assert_eq!(env.unify(list_x, list_int), Err("Incompatible types: list[typevar2] and list[0]".to_string())); + assert_eq!( + env.unify(list_x, list_int), + Err("Incompatible types: list[typevar2] and list[0]".to_string()) + ); env.unifier.replace_rigid_var(a, int); env.unifier.unify(list_x, list_int).unwrap(); diff --git a/nac3core/src/typecheck/unification_table.rs b/nac3core/src/typecheck/unification_table.rs index 101057c5e..5b0570f9e 100644 --- a/nac3core/src/typecheck/unification_table.rs +++ b/nac3core/src/typecheck/unification_table.rs @@ -16,21 +16,10 @@ pub struct UnificationTable { #[derive(Clone, Debug)] enum Action { - Parent { - key: usize, - original_parent: usize, - }, - Value { - key: usize, - original_value: Option, - }, - Rank { - key: usize, - original_rank: u32, - }, - Marker { - generation: u32, - } + Parent { key: usize, original_parent: usize }, + Value { key: usize, original_value: Option }, + Rank { key: usize, original_rank: u32 }, + Marker { generation: u32 }, } impl Default for UnificationTable { @@ -41,7 +30,13 @@ impl Default for UnificationTable { impl UnificationTable { pub fn new() -> UnificationTable { - UnificationTable { parents: Vec::new(), ranks: Vec::new(), values: Vec::new(), log: Vec::new(), generation: 0 } + UnificationTable { + parents: Vec::new(), + ranks: Vec::new(), + values: Vec::new(), + log: Vec::new(), + generation: 0, + } } pub fn new_key(&mut self, v: V) -> UnificationKey { @@ -125,7 +120,10 @@ impl UnificationTable { pub fn restore_snapshot(&mut self, snapshot: (usize, u32)) { let (log_len, generation) = snapshot; assert!(self.log.len() >= log_len, "snapshot restoration error"); - assert!(matches!(self.log[log_len - 1], Action::Marker { generation: gen } if gen == generation), "snapshot restoration error"); + assert!( + matches!(self.log[log_len - 1], Action::Marker { generation: gen } if gen == generation), + "snapshot restoration error" + ); for action in self.log.drain(log_len - 1..).rev() { match action { Action::Parent { key, original_parent } => { @@ -145,7 +143,10 @@ impl UnificationTable { pub fn discard_snapshot(&mut self, snapshot: (usize, u32)) { let (log_len, generation) = snapshot; assert!(self.log.len() >= log_len, "snapshot discard error"); - assert!(matches!(self.log[log_len - 1], Action::Marker { generation: gen } if gen == generation), "snapshot discard error"); + assert!( + matches!(self.log[log_len - 1], Action::Marker { generation: gen } if gen == generation), + "snapshot discard error" + ); self.log.clear(); } } @@ -159,11 +160,23 @@ where .enumerate() .map(|(i, (v, p))| if *p == i { v.as_ref().map(|v| v.as_ref().clone()) } else { None }) .collect(); - UnificationTable { parents: self.parents.clone(), ranks: self.ranks.clone(), values, log: Vec::new(), generation: 0 } + UnificationTable { + parents: self.parents.clone(), + ranks: self.ranks.clone(), + values, + log: Vec::new(), + generation: 0, + } } pub fn from_send(table: &UnificationTable) -> UnificationTable> { let values = table.values.iter().cloned().map(|v| v.map(Rc::new)).collect(); - UnificationTable { parents: table.parents.clone(), ranks: table.ranks.clone(), values, log: Vec::new(), generation: 0 } + UnificationTable { + parents: table.parents.clone(), + ranks: table.ranks.clone(), + values, + log: Vec::new(), + generation: 0, + } } } diff --git a/nac3parser/src/config_comment_helper.rs b/nac3parser/src/config_comment_helper.rs index dbc472574..c91e14af7 100644 --- a/nac3parser/src/config_comment_helper.rs +++ b/nac3parser/src/config_comment_helper.rs @@ -1,15 +1,15 @@ -use lalrpop_util::ParseError; -use nac3ast::*; use crate::ast::Ident; use crate::ast::Location; -use crate::token::Tok; use crate::error::*; +use crate::token::Tok; +use lalrpop_util::ParseError; +use nac3ast::*; pub fn make_config_comment( com_loc: Location, stmt_loc: Location, nac3com_above: Vec<(Ident, Tok)>, - nac3com_end: Option + nac3com_end: Option, ) -> Result, ParseError> { if com_loc.column() != stmt_loc.column() && !nac3com_above.is_empty() { return Err(ParseError::User { @@ -23,18 +23,21 @@ pub fn make_config_comment( ) ) } - }) + }); }; - Ok( - nac3com_above - .into_iter() - .map(|(com, _)| com) - .chain(nac3com_end.map_or_else(|| vec![].into_iter(), |com| vec![com].into_iter())) - .collect() - ) + Ok(nac3com_above + .into_iter() + .map(|(com, _)| com) + .chain(nac3com_end.map_or_else(|| vec![].into_iter(), |com| vec![com].into_iter())) + .collect()) } -pub fn handle_small_stmt(stmts: &mut [Stmt], nac3com_above: Vec<(Ident, Tok)>, nac3com_end: Option, com_above_loc: Location) -> Result<(), ParseError> { +pub fn handle_small_stmt( + stmts: &mut [Stmt], + nac3com_above: Vec<(Ident, Tok)>, + nac3com_end: Option, + com_above_loc: Location, +) -> Result<(), ParseError> { if com_above_loc.column() != stmts[0].location.column() && !nac3com_above.is_empty() { return Err(ParseError::User { error: LexicalError { @@ -47,17 +50,12 @@ pub fn handle_small_stmt(stmts: &mut [Stmt], nac3com_above: Vec<(Ident, To ) ) } - }) + }); } - apply_config_comments( - &mut stmts[0], - nac3com_above - .into_iter() - .map(|(com, _)| com).collect() - ); + apply_config_comments(&mut stmts[0], nac3com_above.into_iter().map(|(com, _)| com).collect()); apply_config_comments( stmts.last_mut().unwrap(), - nac3com_end.map_or_else(Vec::new, |com| vec![com]) + nac3com_end.map_or_else(Vec::new, |com| vec![com]), ); Ok(()) } @@ -72,7 +70,7 @@ fn apply_config_comments(stmt: &mut Stmt, comments: Vec) { | StmtKind::AnnAssign { config_comment, .. } | StmtKind::Break { config_comment, .. } | StmtKind::Continue { config_comment, .. } - | StmtKind::Return { config_comment, .. } + | StmtKind::Return { config_comment, .. } | StmtKind::Raise { config_comment, .. } | StmtKind::Import { config_comment, .. } | StmtKind::ImportFrom { config_comment, .. } @@ -80,6 +78,8 @@ fn apply_config_comments(stmt: &mut Stmt, comments: Vec) { | StmtKind::Nonlocal { config_comment, .. } | StmtKind::Assert { config_comment, .. } => config_comment.extend(comments), - _ => { unreachable!("only small statements should call this function") } + _ => { + unreachable!("only small statements should call this function") + } } } diff --git a/nac3parser/src/error.rs b/nac3parser/src/error.rs index 21497c45c..405c17deb 100644 --- a/nac3parser/src/error.rs +++ b/nac3parser/src/error.rs @@ -145,35 +145,27 @@ impl From> for ParseError { fn from(err: LalrpopError) -> Self { match err { // TODO: Are there cases where this isn't an EOF? - LalrpopError::InvalidToken { location } => ParseError { - error: ParseErrorType::Eof, - location, - }, - LalrpopError::ExtraToken { token } => ParseError { - error: ParseErrorType::ExtraToken(token.1), - location: token.0, - }, - LalrpopError::User { error } => ParseError { - error: ParseErrorType::Lexical(error.error), - location: error.location, - }, + LalrpopError::InvalidToken { location } => { + ParseError { error: ParseErrorType::Eof, location } + } + LalrpopError::ExtraToken { token } => { + ParseError { error: ParseErrorType::ExtraToken(token.1), location: token.0 } + } + LalrpopError::User { error } => { + ParseError { error: ParseErrorType::Lexical(error.error), location: error.location } + } LalrpopError::UnrecognizedToken { token, expected } => { // Hacky, but it's how CPython does it. See PyParser_AddToken, // in particular "Only one possible expected token" comment. - let expected = if expected.len() == 1 { - Some(expected[0].clone()) - } else { - None - }; + let expected = if expected.len() == 1 { Some(expected[0].clone()) } else { None }; ParseError { error: ParseErrorType::UnrecognizedToken(token.1, expected), location: token.0, } } - LalrpopError::UnrecognizedEOF { location, .. } => ParseError { - error: ParseErrorType::Eof, - location, - }, + LalrpopError::UnrecognizedEOF { location, .. } => { + ParseError { error: ParseErrorType::Eof, location } + } } } } diff --git a/nac3parser/src/fstring.rs b/nac3parser/src/fstring.rs index 6910ddc93..e0d6318a8 100644 --- a/nac3parser/src/fstring.rs +++ b/nac3parser/src/fstring.rs @@ -15,10 +15,7 @@ struct FStringParser<'a> { impl<'a> FStringParser<'a> { fn new(source: &'a str, str_location: Location) -> Self { - Self { - chars: source.chars().peekable(), - str_location, - } + Self { chars: source.chars().peekable(), str_location } } #[inline] @@ -251,17 +248,11 @@ impl<'a> FStringParser<'a> { } if !content.is_empty() { - values.push(self.expr(ExprKind::Constant { - value: content.into(), - kind: None, - })) + values.push(self.expr(ExprKind::Constant { value: content.into(), kind: None })) } let s = match values.len() { - 0 => self.expr(ExprKind::Constant { - value: String::new().into(), - kind: None, - }), + 0 => self.expr(ExprKind::Constant { value: String::new().into(), kind: None }), 1 => values.into_iter().next().unwrap(), _ => self.expr(ExprKind::JoinedStr { values }), }; @@ -277,9 +268,7 @@ fn parse_fstring_expr(source: &str) -> Result { /// Parse an fstring from a string, located at a certain position in the sourcecode. /// In case of errors, we will get the location and the error returned. pub fn parse_located_fstring(source: &str, location: Location) -> Result { - FStringParser::new(source, location) - .parse() - .map_err(|error| FStringError { error, location }) + FStringParser::new(source, location).parse().map_err(|error| FStringError { error, location }) } #[cfg(test)] diff --git a/nac3parser/src/function.rs b/nac3parser/src/function.rs index a6fa07e0e..a6969e0fb 100644 --- a/nac3parser/src/function.rs +++ b/nac3parser/src/function.rs @@ -69,10 +69,7 @@ pub fn parse_args(func_args: Vec) -> Result { diff --git a/nac3parser/src/lexer.rs b/nac3parser/src/lexer.rs index 6804df05b..bca4477b0 100644 --- a/nac3parser/src/lexer.rs +++ b/nac3parser/src/lexer.rs @@ -3,12 +3,12 @@ //! This means source code is translated into separate tokens. pub use super::token::Tok; -use crate::ast::{Location, FileName}; +use crate::ast::{FileName, Location}; use crate::error::{LexicalError, LexicalErrorType}; use std::char; use std::cmp::Ordering; -use std::str::FromStr; use std::num::IntErrorKind; +use std::str::FromStr; use unic_emoji_char::is_emoji_presentation; use unic_ucd_ident::{is_xid_continue, is_xid_start}; @@ -32,20 +32,14 @@ impl IndentationLevel { if self.spaces <= other.spaces { Ok(Ordering::Less) } else { - Err(LexicalError { - location, - error: LexicalErrorType::TabError, - }) + Err(LexicalError { location, error: LexicalErrorType::TabError }) } } Ordering::Greater => { if self.spaces >= other.spaces { Ok(Ordering::Greater) } else { - Err(LexicalError { - location, - error: LexicalErrorType::TabError, - }) + Err(LexicalError { location, error: LexicalErrorType::TabError }) } } Ordering::Equal => Ok(self.spaces.cmp(&other.spaces)), @@ -63,7 +57,7 @@ pub struct Lexer> { chr1: Option, chr2: Option, location: Location, - config_comment_prefix: Option<&'static str> + config_comment_prefix: Option<&'static str>, } pub static KEYWORDS: phf::Map<&'static str, Tok> = phf::phf_map! { @@ -136,11 +130,7 @@ where T: Iterator, { pub fn new(source: T) -> Self { - let mut nlh = NewlineHandler { - source, - chr0: None, - chr1: None, - }; + let mut nlh = NewlineHandler { source, chr0: None, chr1: None }; nlh.shift(); nlh.shift(); nlh @@ -195,7 +185,7 @@ where location: start, chr1: None, chr2: None, - config_comment_prefix: Some(" nac3:") + config_comment_prefix: Some(" nac3:"), }; lxr.next_char(); lxr.next_char(); @@ -287,15 +277,15 @@ where let end_pos = self.get_pos(); let value = match i128::from_str_radix(&value_text, radix) { Ok(value) => value, - Err(e) => { - match e.kind() { - IntErrorKind::PosOverflow | IntErrorKind::NegOverflow => i128::MAX, - _ => return Err(LexicalError { + Err(e) => match e.kind() { + IntErrorKind::PosOverflow | IntErrorKind::NegOverflow => i128::MAX, + _ => { + return Err(LexicalError { error: LexicalErrorType::OtherError(format!("{:?}", e)), location: start_pos, - }), + }) } - } + }, }; Ok((start_pos, Tok::Int { value }, end_pos)) } @@ -338,14 +328,7 @@ where if self.chr0 == Some('j') || self.chr0 == Some('J') { self.next_char(); let end_pos = self.get_pos(); - Ok(( - start_pos, - Tok::Complex { - real: 0.0, - imag: value, - }, - end_pos, - )) + Ok((start_pos, Tok::Complex { real: 0.0, imag: value }, end_pos)) } else { let end_pos = self.get_pos(); Ok((start_pos, Tok::Float { value }, end_pos)) @@ -364,7 +347,7 @@ where let value = value_text.parse::().ok(); let nonzero = match value { Some(value) => value != 0i128, - None => true + None => true, }; if start_is_zero && nonzero { return Err(LexicalError { @@ -433,9 +416,8 @@ where fn lex_comment(&mut self) -> Option { self.next_char(); // if possibly nac3 pseudocomment, special handling for `# nac3:` - let (mut prefix, mut is_comment) = self - .config_comment_prefix - .map_or_else(|| ("".chars(), false), |v| (v.chars(), true)); + let (mut prefix, mut is_comment) = + self.config_comment_prefix.map_or_else(|| ("".chars(), false), |v| (v.chars(), true)); // for the correct location of config comment let mut start_loc = self.location; start_loc.go_left(); @@ -460,22 +442,20 @@ where return Some(( start_loc, Tok::ConfigComment { content: content.trim().into() }, - self.location + self.location, )); } } } } self.next_char(); - }; + } } fn unicode_literal(&mut self, literal_number: usize) -> Result { let mut p: u32 = 0u32; - let unicode_error = LexicalError { - error: LexicalErrorType::UnicodeError, - location: self.get_pos(), - }; + let unicode_error = + LexicalError { error: LexicalErrorType::UnicodeError, location: self.get_pos() }; for i in 1..=literal_number { match self.next_char() { Some(c) => match c.to_digit(16) { @@ -530,10 +510,8 @@ where } } } - unicode_names2::character(&name).ok_or(LexicalError { - error: LexicalErrorType::UnicodeError, - location: start_pos, - }) + unicode_names2::character(&name) + .ok_or(LexicalError { error: LexicalErrorType::UnicodeError, location: start_pos }) } fn lex_string( @@ -650,14 +628,9 @@ where let end_pos = self.get_pos(); let tok = if is_bytes { - Tok::Bytes { - value: string_content.chars().map(|c| c as u8).collect(), - } + Tok::Bytes { value: string_content.chars().map(|c| c as u8).collect() } } else { - Tok::String { - value: string_content, - is_fstring, - } + Tok::String { value: string_content, is_fstring } }; Ok((start_pos, tok, end_pos)) @@ -842,11 +815,7 @@ where let tok_start = self.get_pos(); self.next_char(); let tok_end = self.get_pos(); - self.emit(( - tok_start, - Tok::Name { name: c.to_string().into() }, - tok_end, - )); + self.emit((tok_start, Tok::Name { name: c.to_string().into() }, tok_end)); } else { self.consume_character(c)?; } @@ -1439,14 +1408,8 @@ class Foo(A, B): assert_eq!( tokens, vec![ - Tok::String { - value: "\\\\".to_owned(), - is_fstring: false, - }, - Tok::String { - value: "\\".to_owned(), - is_fstring: false, - }, + Tok::String { value: "\\\\".to_owned(), is_fstring: false }, + Tok::String { value: "\\".to_owned(), is_fstring: false }, Tok::Newline, ] ); @@ -1459,27 +1422,13 @@ class Foo(A, B): assert_eq!( tokens, vec![ - Tok::Int { - value: 47i128, - }, - Tok::Int { - value: 13i128, - }, - Tok::Int { - value: 0i128, - }, - Tok::Int { - value: 123i128, - }, + Tok::Int { value: 47i128 }, + Tok::Int { value: 13i128 }, + Tok::Int { value: 0i128 }, + Tok::Int { value: 123i128 }, Tok::Float { value: 0.2 }, - Tok::Complex { - real: 0.0, - imag: 2.0, - }, - Tok::Complex { - real: 0.0, - imag: 2.2, - }, + Tok::Complex { real: 0.0, imag: 2.0 }, + Tok::Complex { real: 0.0, imag: 2.2 }, Tok::Newline, ] ); @@ -1539,21 +1488,13 @@ class Foo(A, B): assert_eq!( tokens, vec![ - Tok::Name { - name: String::from("avariable").into(), - }, + Tok::Name { name: String::from("avariable").into() }, Tok::Equal, - Tok::Int { - value: 99i128 - }, + Tok::Int { value: 99i128 }, Tok::Plus, - Tok::Int { - value: 2i128 - }, + Tok::Int { value: 2i128 }, Tok::Minus, - Tok::Int { - value: 0i128 - }, + Tok::Int { value: 0i128 }, Tok::Newline, ] ); @@ -1740,42 +1681,15 @@ class Foo(A, B): assert_eq!( tokens, vec![ - Tok::String { - value: String::from("double"), - is_fstring: false, - }, - Tok::String { - value: String::from("single"), - is_fstring: false, - }, - Tok::String { - value: String::from("can't"), - is_fstring: false, - }, - Tok::String { - value: String::from("\\\""), - is_fstring: false, - }, - Tok::String { - value: String::from("\t\r\n"), - is_fstring: false, - }, - Tok::String { - value: String::from("\\g"), - is_fstring: false, - }, - Tok::String { - value: String::from("raw\\'"), - is_fstring: false, - }, - Tok::String { - value: String::from("Đ"), - is_fstring: false, - }, - Tok::String { - value: String::from("\u{80}\u{0}a"), - is_fstring: false, - }, + Tok::String { value: String::from("double"), is_fstring: false }, + Tok::String { value: String::from("single"), is_fstring: false }, + Tok::String { value: String::from("can't"), is_fstring: false }, + Tok::String { value: String::from("\\\""), is_fstring: false }, + Tok::String { value: String::from("\t\r\n"), is_fstring: false }, + Tok::String { value: String::from("\\g"), is_fstring: false }, + Tok::String { value: String::from("raw\\'"), is_fstring: false }, + Tok::String { value: String::from("Đ"), is_fstring: false }, + Tok::String { value: String::from("\u{80}\u{0}a"), is_fstring: false }, Tok::Newline, ] ); @@ -1840,41 +1754,17 @@ class Foo(A, B): fn test_raw_byte_literal() { let source = r"rb'\x1z'"; let tokens = lex_source(source); - assert_eq!( - tokens, - vec![ - Tok::Bytes { - value: b"\\x1z".to_vec() - }, - Tok::Newline - ] - ); + assert_eq!(tokens, vec![Tok::Bytes { value: b"\\x1z".to_vec() }, Tok::Newline]); let source = r"rb'\\'"; let tokens = lex_source(source); - assert_eq!( - tokens, - vec![ - Tok::Bytes { - value: b"\\\\".to_vec() - }, - Tok::Newline - ] - ) + assert_eq!(tokens, vec![Tok::Bytes { value: b"\\\\".to_vec() }, Tok::Newline]) } #[test] fn test_escape_octet() { let source = r##"b'\43a\4\1234'"##; let tokens = lex_source(source); - assert_eq!( - tokens, - vec![ - Tok::Bytes { - value: b"#a\x04S4".to_vec() - }, - Tok::Newline - ] - ) + assert_eq!(tokens, vec![Tok::Bytes { value: b"#a\x04S4".to_vec() }, Tok::Newline]) } #[test] @@ -1883,13 +1773,7 @@ class Foo(A, B): let tokens = lex_source(source); assert_eq!( tokens, - vec![ - Tok::String { - value: "\u{2002}".to_owned(), - is_fstring: false, - }, - Tok::Newline - ] + vec![Tok::String { value: "\u{2002}".to_owned(), is_fstring: false }, Tok::Newline] ) } } diff --git a/nac3parser/src/lib.rs b/nac3parser/src/lib.rs index 5e2530593..991cf3018 100644 --- a/nac3parser/src/lib.rs +++ b/nac3parser/src/lib.rs @@ -31,5 +31,5 @@ lalrpop_mod!( #[allow(unused)] python ); -pub mod token; pub mod config_comment_helper; +pub mod token; diff --git a/nac3parser/src/parser.rs b/nac3parser/src/parser.rs index b8968d598..a4e89c41a 100644 --- a/nac3parser/src/parser.rs +++ b/nac3parser/src/parser.rs @@ -75,9 +75,7 @@ pub fn parse(source: &str, mode: Mode, file: FileName) -> Result if *value != i128::MAX { write!(f, "'{}'", value) } else { write!(f, "'#OFL#'") }, + Name { name } => { + write!(f, "'{}'", ast::get_str_from_ref(&ast::get_str_ref_lock(), *name)) + } + Int { value } => { + if *value != i128::MAX { + write!(f, "'{}'", value) + } else { + write!(f, "'#OFL#'") + } + } Float { value } => write!(f, "'{}'", value), Complex { real, imag } => write!(f, "{}j{}", real, imag), String { value, is_fstring } => { @@ -134,7 +142,11 @@ impl fmt::Display for Tok { } f.write_str("\"") } - ConfigComment { content } => write!(f, "ConfigComment: '{}'", ast::get_str_from_ref(&ast::get_str_ref_lock(), *content)), + ConfigComment { content } => write!( + f, + "ConfigComment: '{}'", + ast::get_str_from_ref(&ast::get_str_ref_lock(), *content) + ), Newline => f.write_str("Newline"), Indent => f.write_str("Indent"), Dedent => f.write_str("Dedent"), diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index 3d93d1da8..0ccce3d0e 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -52,22 +52,16 @@ fn handle_typevar_definition( Default::default(), )?; get_type_from_type_annotation_kinds( - def_list, unifier, primitives, &ty, &mut None + def_list, unifier, primitives, &ty, &mut None, ) }) .collect::, _>>()?; Ok(unifier.get_fresh_var_with_range(&constraints, None, None).0) } else { - Err(format!( - "expression {:?} cannot be handled as a TypeVar in global scope", - var - )) + Err(format!("expression {:?} cannot be handled as a TypeVar in global scope", var)) } } else { - Err(format!( - "expression {:?} cannot be handled as a TypeVar in global scope", - var - )) + Err(format!("expression {:?} cannot be handled as a TypeVar in global scope", var)) } } @@ -92,15 +86,13 @@ fn handle_assignment_pattern( ) { internal_resolver.add_id_type(*id, var); Ok(()) - } else if let Ok(val) = - parse_parameter_default_value(value.borrow(), resolver) - { + } else if let Ok(val) = parse_parameter_default_value(value.borrow(), resolver) { internal_resolver.add_module_global(*id, val); Ok(()) } else { - Err(format!("fails to evaluate this expression `{:?}` as a constant or TypeVar at {}", - targets[0].node, - targets[0].location, + Err(format!( + "fails to evaluate this expression `{:?}` as a constant or TypeVar at {}", + targets[0].node, targets[0].location, )) } } @@ -146,10 +138,7 @@ fn handle_assignment_pattern( Ok(()) } } - _ => Err(format!( - "unpack of this expression is not supported at {}", - value.location - )), + _ => Err(format!("unpack of this expression is not supported at {}", value.location)), } } } @@ -178,7 +167,8 @@ fn main() { class_names: Default::default(), module_globals: Default::default(), str_store: Default::default(), - }.into(); + } + .into(); let resolver = Arc::new(Resolver(internal_resolver.clone())) as Arc; @@ -202,13 +192,19 @@ fn main() { eprintln!("{}", err); return; } - }, + } // allow (and ignore) "from __future__ import annotations" StmtKind::ImportFrom { module, names, .. } - if module == &Some("__future__".into()) && names.len() == 1 && names[0].name == "annotations".into() => (), + if module == &Some("__future__".into()) + && names.len() == 1 + && names[0].name == "annotations".into() => + { + () + } _ => { - let (name, def_id, ty) = - composer.register_top_level(stmt, Some(resolver.clone()), "__main__".into()).unwrap(); + let (name, def_id, ty) = composer + .register_top_level(stmt, Some(resolver.clone()), "__main__".into()) + .unwrap(); internal_resolver.add_id_def(name, def_id); if let Some(ty) = ty { internal_resolver.add_id_type(name, ty); diff --git a/runkernel/src/main.rs b/runkernel/src/main.rs index 84f1e3237..8c6d2d181 100644 --- a/runkernel/src/main.rs +++ b/runkernel/src/main.rs @@ -47,12 +47,11 @@ pub extern "C" fn __nac3_personality(_state: u32, _exception_object: u32, _conte unimplemented!(); } - fn main() { let filename = env::args().nth(1).unwrap(); unsafe { let lib = libloading::Library::new(filename).unwrap(); - let func: libloading::Symbol = lib.get(b"__modinit__").unwrap(); + let func: libloading::Symbol = lib.get(b"__modinit__").unwrap(); func() } }