From 42511334f7ac47295f74c9168ca9c5a74bc553f0 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Fri, 25 Jun 2021 16:49:58 +0800 Subject: [PATCH] fixed some inference rules... --- nac3core/src/expression_inference.rs | 84 ++++++++-------------------- 1 file changed, 24 insertions(+), 60 deletions(-) diff --git a/nac3core/src/expression_inference.rs b/nac3core/src/expression_inference.rs index 9466d044..fafe04e5 100644 --- a/nac3core/src/expression_inference.rs +++ b/nac3core/src/expression_inference.rs @@ -66,12 +66,7 @@ fn infer_constant( if int32.is_ok() { Ok(Some(ctx.get_primitive(INT32_TYPE))) } else { - let int64: Result = value.try_into(); - if int64.is_ok() { - Ok(Some(ctx.get_primitive(INT64_TYPE))) - } else { - Err("integer out of range".into()) - } + Err("integer out of range".into()) } } Number::Float { .. } => Ok(Some(ctx.get_primitive(FLOAT_TYPE))), @@ -98,6 +93,7 @@ fn infer_list<'b: 'a, 'a>( return Err("list elements must have some type".into()); } for v in types { + // TODO: try virtual type... if v? != head { return Err("inhomogeneous list is not allowed".into()); } @@ -124,31 +120,14 @@ fn infer_attribute<'a>( name: &str, ) -> ParserResult { let value = infer_expr(ctx, value)?.ok_or_else(|| "no value".to_string())?; - if let TypeVariable(id) = value.as_ref() { - let v = ctx.get_variable_def(*id); - if v.bound.is_empty() { - return Err("no fields on unbounded type variable".into()); - } - let ty = v.bound[0].get_base(ctx).and_then(|v| v.fields.get(name)); - if ty.is_none() { - return Err("unknown field".into()); - } - for x in v.bound[1..].iter() { - let ty1 = x.get_base(ctx).and_then(|v| v.fields.get(name)); - if ty1 != ty { - return Err("unknown field (type mismatch between variants)".into()); - } - } - return Ok(Some(ty.unwrap().clone())); + if let TypeVariable(_) = value.as_ref() { + return Err("no fields for type variable".into()); } - match value.get_base(ctx) { - Some(b) => match b.fields.get(name) { - Some(t) => Ok(Some(t.clone())), - None => Err("no such field".into()), - }, - None => Err("this object has no fields".into()), - } + value + .get_base(ctx) + .and_then(|b| b.fields.get(name).cloned()) + .map_or_else(|| Err("no such field".to_string()), |v| Ok(Some(v))) } fn infer_bool_ops<'a>(ctx: &mut InferenceContext<'a>, values: &'a [Expression]) -> ParserResult { @@ -223,6 +202,7 @@ fn infer_call<'b: 'a, 'a>( args: &'b [Expression], function: &'b Expression, ) -> ParserResult { + // TODO: special handling for int64 constant let types: Result>, _> = args.iter().map(|v| infer_expr(ctx, v)).collect(); let types = types?; if types.is_none() { @@ -396,15 +376,19 @@ mod test { let ast = parse_expression("2147483648").unwrap(); let result = infer_expr(&mut ctx, &ast); - assert_eq!(result.unwrap().unwrap(), ctx.get_primitive(INT64_TYPE)); - - let ast = parse_expression("9223372036854775807").unwrap(); - let result = infer_expr(&mut ctx, &ast); - assert_eq!(result.unwrap().unwrap(), ctx.get_primitive(INT64_TYPE)); - - let ast = parse_expression("9223372036854775808").unwrap(); - let result = infer_expr(&mut ctx, &ast); assert_eq!(result, Err("integer out of range".into())); + // + // let ast = parse_expression("2147483648").unwrap(); + // let result = infer_expr(&mut ctx, &ast); + // assert_eq!(result.unwrap().unwrap(), ctx.get_primitive(INT64_TYPE)); + + // let ast = parse_expression("9223372036854775807").unwrap(); + // let result = infer_expr(&mut ctx, &ast); + // assert_eq!(result.unwrap().unwrap(), ctx.get_primitive(INT64_TYPE)); + + // let ast = parse_expression("9223372036854775808").unwrap(); + // let result = infer_expr(&mut ctx, &ast); + // assert_eq!(result, Err("integer out of range".into())); let ast = parse_expression("123.456").unwrap(); let result = infer_expr(&mut ctx, &ast); @@ -582,31 +566,11 @@ mod test { let ast = parse_expression("v0.a").unwrap(); let result = infer_expr(&mut ctx, &ast); - assert_eq!(result, Err("no fields on unbounded type variable".into())); + assert_eq!(result, Err("no fields for type variable".into())); let ast = parse_expression("v1.a").unwrap(); let result = infer_expr(&mut ctx, &ast); - assert_eq!(result.unwrap().unwrap(), ctx.get_primitive(INT32_TYPE)); - - // shall we support this? - let ast = parse_expression("v1.b").unwrap(); - let result = infer_expr(&mut ctx, &ast); - assert_eq!( - result, - Err("unknown field (type mismatch between variants)".into()) - ); - // assert_eq!(result.unwrap().unwrap(), TypeVariable(v1).into()); - - let ast = parse_expression("v1.c").unwrap(); - let result = infer_expr(&mut ctx, &ast); - assert_eq!( - result, - Err("unknown field (type mismatch between variants)".into()) - ); - - let ast = parse_expression("v1.d").unwrap(); - let result = infer_expr(&mut ctx, &ast); - assert_eq!(result, Err("unknown field".into())); + assert_eq!(result, Err("no fields for type variable".into())); let ast = parse_expression("none().a").unwrap(); let result = infer_expr(&mut ctx, &ast); @@ -614,7 +578,7 @@ mod test { let ast = parse_expression("bot.a").unwrap(); let result = infer_expr(&mut ctx, &ast); - assert_eq!(result, Err("this object has no fields".into())); + assert_eq!(result, Err("no such field".into())); } #[test]