From 03712e3762e07fdaed92e053a8b679c85105274b Mon Sep 17 00:00:00 2001 From: pca006132 Date: Wed, 30 Dec 2020 09:40:56 +0800 Subject: [PATCH] code formatting --- nac3core/src/expression.rs | 12 +- nac3core/src/lib.rs | 548 ++++++++++++++++++++++++------------- nac3core/src/operators.rs | 1 - nac3core/src/typedef.rs | 3 +- 4 files changed, 372 insertions(+), 192 deletions(-) diff --git a/nac3core/src/expression.rs b/nac3core/src/expression.rs index 805626e5ae..17ab351f0c 100644 --- a/nac3core/src/expression.rs +++ b/nac3core/src/expression.rs @@ -23,13 +23,17 @@ pub fn parse_expr(ctx: &GlobalContext, sym_table: &SymTable, expr: &Expression) ExpressionType::Binop { a, b, op } => parse_bin_ops(ctx, sym_table, op, a, b), ExpressionType::Unop { op, a } => parse_unary_ops(ctx, sym_table, op, a), ExpressionType::Compare { vals, ops } => parse_compare(ctx, sym_table, vals, ops), - ExpressionType::Call { args, function, keywords} => { + ExpressionType::Call { + args, + function, + keywords, + } => { if keywords.len() > 0 { Err("keyword is not supported".into()) } else { parse_call(ctx, sym_table, &args, &function) } - }, + } ExpressionType::Subscript { a, b } => parse_subscript(ctx, sym_table, a, b), ExpressionType::IfExpression { test, body, orelse } => { parse_if_expr(ctx, sym_table, &test, &body, orelse) @@ -356,7 +360,8 @@ fn parse_list_comprehension( let boolean = PrimitiveType(BOOL_TYPE); for test in comprehension.ifs.iter() { - let result = parse_expr(ctx, &local_sym, test)?.ok_or("no value in test".to_string())?; + let result = + parse_expr(ctx, &local_sym, test)?.ok_or("no value in test".to_string())?; if result.as_ref() != &boolean { return Err("test must be bool".into()); } @@ -366,4 +371,3 @@ fn parse_list_comprehension( Err("iteration is supported for list only".into()) } } - diff --git a/nac3core/src/lib.rs b/nac3core/src/lib.rs index 8384caa9b0..81213e19e3 100644 --- a/nac3core/src/lib.rs +++ b/nac3core/src/lib.rs @@ -1,34 +1,33 @@ -extern crate num_bigint; extern crate inkwell; +extern crate num_bigint; extern crate rustpython_parser; +pub mod expression; pub mod inference; +mod operators; pub mod primitives; pub mod typedef; -pub mod expression; -mod operators; +use std::collections::HashMap; use std::error::Error; use std::fmt; use std::path::Path; -use std::collections::HashMap; use num_traits::cast::ToPrimitive; use rustpython_parser::ast; -use inkwell::OptimizationLevel; +use inkwell::basic_block; use inkwell::builder::Builder; use inkwell::context::Context; use inkwell::module::Module; +use inkwell::passes; use inkwell::targets::*; use inkwell::types; use inkwell::types::BasicType; use inkwell::values; -use inkwell::{IntPredicate, FloatPredicate}; -use inkwell::basic_block; -use inkwell::passes; - +use inkwell::OptimizationLevel; +use inkwell::{FloatPredicate, IntPredicate}; #[derive(Debug)] enum CompileErrorKind { @@ -38,26 +37,25 @@ enum CompileErrorKind { IncompatibleTypes, UnboundIdentifier, BreakOutsideLoop, - Internal(&'static str) + Internal(&'static str), } impl fmt::Display for CompileErrorKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - CompileErrorKind::Unsupported(feature) - => write!(f, "The following Python feature is not supported by NAC3: {}", feature), - CompileErrorKind::MissingTypeAnnotation - => write!(f, "Missing type annotation"), - CompileErrorKind::UnknownTypeAnnotation - => write!(f, "Unknown type annotation"), - CompileErrorKind::IncompatibleTypes - => write!(f, "Incompatible types"), - CompileErrorKind::UnboundIdentifier - => write!(f, "Unbound identifier"), - CompileErrorKind::BreakOutsideLoop - => write!(f, "Break outside loop"), - CompileErrorKind::Internal(details) - => write!(f, "Internal compiler error: {}", details), + CompileErrorKind::Unsupported(feature) => write!( + f, + "The following Python feature is not supported by NAC3: {}", + feature + ), + CompileErrorKind::MissingTypeAnnotation => write!(f, "Missing type annotation"), + CompileErrorKind::UnknownTypeAnnotation => write!(f, "Unknown type annotation"), + CompileErrorKind::IncompatibleTypes => write!(f, "Incompatible types"), + CompileErrorKind::UnboundIdentifier => write!(f, "Unbound identifier"), + CompileErrorKind::BreakOutsideLoop => write!(f, "Break outside loop"), + CompileErrorKind::Internal(details) => { + write!(f, "Internal compiler error: {}", details) + } } } } @@ -108,7 +106,9 @@ impl<'ctx> CodeGen<'ctx> { module.add_function("output", fn_type, None); CodeGen { - context, module, pass_manager, + context, + module, + pass_manager, builder: context.create_builder(), current_source_location: ast::Location::default(), namespace: HashMap::new(), @@ -123,7 +123,7 @@ impl<'ctx> CodeGen<'ctx> { fn compile_error(&self, kind: CompileErrorKind) -> CompileError { CompileError { location: self.current_source_location, - kind + kind, } } @@ -134,7 +134,7 @@ impl<'ctx> CodeGen<'ctx> { "int64" => Ok(self.context.i64_type().into()), "float32" => Ok(self.context.f32_type().into()), "float64" => Ok(self.context.f64_type().into()), - _ => Err(self.compile_error(CompileErrorKind::UnknownTypeAnnotation)) + _ => Err(self.compile_error(CompileErrorKind::UnknownTypeAnnotation)), } } @@ -148,37 +148,53 @@ impl<'ctx> CodeGen<'ctx> { is_async: bool, ) -> CompileResult> { if is_async { - return Err(self.compile_error(CompileErrorKind::Unsupported("async functions"))) + return Err(self.compile_error(CompileErrorKind::Unsupported("async functions"))); } for decorator in decorator_list.iter() { self.set_source_location(decorator.location); if let ast::ExpressionType::Identifier { name } = &decorator.node { if name != "kernel" && name != "portable" { - return Err(self.compile_error(CompileErrorKind::Unsupported("custom decorators"))) + return Err( + self.compile_error(CompileErrorKind::Unsupported("custom decorators")) + ); } } else { - return Err(self.compile_error(CompileErrorKind::Unsupported("decorator must be an identifier"))) + return Err(self.compile_error(CompileErrorKind::Unsupported( + "decorator must be an identifier", + ))); } } - let args_type = args.args.iter().map(|val| { - self.set_source_location(val.location); - if let Some(annotation) = &val.annotation { - if let ast::ExpressionType::Identifier { name } = &annotation.node { - Ok(self.get_basic_type(&name)?) + let args_type = args + .args + .iter() + .map(|val| { + self.set_source_location(val.location); + if let Some(annotation) = &val.annotation { + if let ast::ExpressionType::Identifier { name } = &annotation.node { + Ok(self.get_basic_type(&name)?) + } else { + Err(self.compile_error(CompileErrorKind::Unsupported( + "type annotation must be an identifier", + ))) + } } else { - Err(self.compile_error(CompileErrorKind::Unsupported("type annotation must be an identifier"))) + Err(self.compile_error(CompileErrorKind::MissingTypeAnnotation)) } - } else { - Err(self.compile_error(CompileErrorKind::MissingTypeAnnotation)) - } - }).collect::>>()?; + }) + .collect::>>()?; let return_type = if let Some(returns) = returns { self.set_source_location(returns.location); if let ast::ExpressionType::Identifier { name } = &returns.node { - if name == "None" { None } else { Some(self.get_basic_type(name)?) } + if name == "None" { + None + } else { + Some(self.get_basic_type(name)?) + } } else { - return Err(self.compile_error(CompileErrorKind::Unsupported("type annotation must be an identifier"))) + return Err(self.compile_error(CompileErrorKind::Unsupported( + "type annotation must be an identifier", + ))); } } else { None @@ -186,7 +202,7 @@ impl<'ctx> CodeGen<'ctx> { let fn_type = match return_type { Some(ty) => ty.fn_type(&args_type, false), - None => self.context.void_type().fn_type(&args_type, false) + None => self.context.void_type().fn_type(&args_type, false), }; let function = self.module.add_function(name, fn_type, None); @@ -207,57 +223,74 @@ impl<'ctx> CodeGen<'ctx> { fn compile_expression( &mut self, - expression: &ast::Expression + expression: &ast::Expression, ) -> CompileResult> { self.set_source_location(expression.location); match &expression.node { ast::ExpressionType::True => Ok(self.context.bool_type().const_int(1, false).into()), ast::ExpressionType::False => Ok(self.context.bool_type().const_int(0, false).into()), - ast::ExpressionType::Number { value: ast::Number::Integer { value } } => { + ast::ExpressionType::Number { + value: ast::Number::Integer { value }, + } => { let mut bits = value.bits(); if value.sign() == num_bigint::Sign::Minus { bits += 1; } match bits { - 0..=32 => Ok(self.context.i32_type().const_int(value.to_i32().unwrap() as _, true).into()), - 33..=64 => Ok(self.context.i64_type().const_int(value.to_i64().unwrap() as _, true).into()), - _ => Err(self.compile_error(CompileErrorKind::Unsupported("integers larger than 64 bits"))) - } - }, - ast::ExpressionType::Number { value: ast::Number::Float { value } } => { - Ok(self.context.f64_type().const_float(*value).into()) - }, - ast::ExpressionType::Identifier { name } => { - match self.namespace.get(name) { - Some(value) => Ok(self.builder.build_load(*value, name).into()), - None => Err(self.compile_error(CompileErrorKind::UnboundIdentifier)) + 0..=32 => Ok(self + .context + .i32_type() + .const_int(value.to_i32().unwrap() as _, true) + .into()), + 33..=64 => Ok(self + .context + .i64_type() + .const_int(value.to_i64().unwrap() as _, true) + .into()), + _ => Err(self.compile_error(CompileErrorKind::Unsupported( + "integers larger than 64 bits", + ))), } + } + ast::ExpressionType::Number { + value: ast::Number::Float { value }, + } => Ok(self.context.f64_type().const_float(*value).into()), + ast::ExpressionType::Identifier { name } => match self.namespace.get(name) { + Some(value) => Ok(self.builder.build_load(*value, name).into()), + None => Err(self.compile_error(CompileErrorKind::UnboundIdentifier)), }, ast::ExpressionType::Unop { op, a } => { let a = self.compile_expression(&a)?; match (op, a) { - (ast::UnaryOperator::Pos, values::BasicValueEnum::IntValue(a)) - => Ok(a.into()), - (ast::UnaryOperator::Pos, values::BasicValueEnum::FloatValue(a)) - => Ok(a.into()), - (ast::UnaryOperator::Neg, values::BasicValueEnum::IntValue(a)) - => Ok(self.builder.build_int_neg(a, "tmpneg").into()), - (ast::UnaryOperator::Neg, values::BasicValueEnum::FloatValue(a)) - => Ok(self.builder.build_float_neg(a, "tmpneg").into()), - (ast::UnaryOperator::Inv, values::BasicValueEnum::IntValue(a)) - => Ok(self.builder.build_not(a, "tmpnot").into()), + (ast::UnaryOperator::Pos, values::BasicValueEnum::IntValue(a)) => Ok(a.into()), + (ast::UnaryOperator::Pos, values::BasicValueEnum::FloatValue(a)) => { + Ok(a.into()) + } + (ast::UnaryOperator::Neg, values::BasicValueEnum::IntValue(a)) => { + Ok(self.builder.build_int_neg(a, "tmpneg").into()) + } + (ast::UnaryOperator::Neg, values::BasicValueEnum::FloatValue(a)) => { + Ok(self.builder.build_float_neg(a, "tmpneg").into()) + } + (ast::UnaryOperator::Inv, values::BasicValueEnum::IntValue(a)) => { + Ok(self.builder.build_not(a, "tmpnot").into()) + } (ast::UnaryOperator::Not, values::BasicValueEnum::IntValue(a)) => { // boolean "not" if a.get_type().get_bit_width() != 1 { - Err(self.compile_error(CompileErrorKind::Unsupported("unimplemented unary operation"))) + Err(self.compile_error(CompileErrorKind::Unsupported( + "unimplemented unary operation", + ))) } else { Ok(self.builder.build_not(a, "tmpnot").into()) } - }, - _ => Err(self.compile_error(CompileErrorKind::Unsupported("unimplemented unary operation"))), + } + _ => Err(self.compile_error(CompileErrorKind::Unsupported( + "unimplemented unary operation", + ))), } - }, + } ast::ExpressionType::Binop { a, op, b } => { let a = self.compile_expression(&a)?; let b = self.compile_expression(&b)?; @@ -266,27 +299,53 @@ impl<'ctx> CodeGen<'ctx> { } use ast::Operator::*; match (op, a, b) { - (Add, values::BasicValueEnum::IntValue(a), values::BasicValueEnum::IntValue(b)) - => Ok(self.builder.build_int_add(a, b, "tmpadd").into()), - (Sub, values::BasicValueEnum::IntValue(a), values::BasicValueEnum::IntValue(b)) - => Ok(self.builder.build_int_sub(a, b, "tmpsub").into()), - (Mult, values::BasicValueEnum::IntValue(a), values::BasicValueEnum::IntValue(b)) - => Ok(self.builder.build_int_mul(a, b, "tmpmul").into()), + ( + Add, + values::BasicValueEnum::IntValue(a), + values::BasicValueEnum::IntValue(b), + ) => Ok(self.builder.build_int_add(a, b, "tmpadd").into()), + ( + Sub, + values::BasicValueEnum::IntValue(a), + values::BasicValueEnum::IntValue(b), + ) => Ok(self.builder.build_int_sub(a, b, "tmpsub").into()), + ( + Mult, + values::BasicValueEnum::IntValue(a), + values::BasicValueEnum::IntValue(b), + ) => Ok(self.builder.build_int_mul(a, b, "tmpmul").into()), - (Add, values::BasicValueEnum::FloatValue(a), values::BasicValueEnum::FloatValue(b)) - => Ok(self.builder.build_float_add(a, b, "tmpadd").into()), - (Sub, values::BasicValueEnum::FloatValue(a), values::BasicValueEnum::FloatValue(b)) - => Ok(self.builder.build_float_sub(a, b, "tmpsub").into()), - (Mult, values::BasicValueEnum::FloatValue(a), values::BasicValueEnum::FloatValue(b)) - => Ok(self.builder.build_float_mul(a, b, "tmpmul").into()), + ( + Add, + values::BasicValueEnum::FloatValue(a), + values::BasicValueEnum::FloatValue(b), + ) => Ok(self.builder.build_float_add(a, b, "tmpadd").into()), + ( + Sub, + values::BasicValueEnum::FloatValue(a), + values::BasicValueEnum::FloatValue(b), + ) => Ok(self.builder.build_float_sub(a, b, "tmpsub").into()), + ( + Mult, + values::BasicValueEnum::FloatValue(a), + values::BasicValueEnum::FloatValue(b), + ) => Ok(self.builder.build_float_mul(a, b, "tmpmul").into()), - (Div, values::BasicValueEnum::FloatValue(a), values::BasicValueEnum::FloatValue(b)) - => Ok(self.builder.build_float_div(a, b, "tmpdiv").into()), - (FloorDiv, values::BasicValueEnum::IntValue(a), values::BasicValueEnum::IntValue(b)) - => Ok(self.builder.build_int_signed_div(a, b, "tmpdiv").into()), - _ => Err(self.compile_error(CompileErrorKind::Unsupported("unimplemented binary operation"))), + ( + Div, + values::BasicValueEnum::FloatValue(a), + values::BasicValueEnum::FloatValue(b), + ) => Ok(self.builder.build_float_div(a, b, "tmpdiv").into()), + ( + FloorDiv, + values::BasicValueEnum::IntValue(a), + values::BasicValueEnum::IntValue(b), + ) => Ok(self.builder.build_int_signed_div(a, b, "tmpdiv").into()), + _ => Err(self.compile_error(CompileErrorKind::Unsupported( + "unimplemented binary operation", + ))), } - }, + } ast::ExpressionType::Compare { vals, ops } => { let mut vals = vals.iter(); let mut ops = ops.iter(); @@ -299,43 +358,93 @@ impl<'ctx> CodeGen<'ctx> { if a.get_type() != b.get_type() { return Err(self.compile_error(CompileErrorKind::IncompatibleTypes)); } - let this_result = match (a, b) { - (values::BasicValueEnum::IntValue(a), values::BasicValueEnum::IntValue(b)) => { - match op { - ast::Comparison::Equal - => self.builder.build_int_compare(IntPredicate::EQ, a, b, "tmpeq"), - ast::Comparison::NotEqual - => self.builder.build_int_compare(IntPredicate::NE, a, b, "tmpne"), - ast::Comparison::Less - => self.builder.build_int_compare(IntPredicate::SLT, a, b, "tmpslt"), - ast::Comparison::LessOrEqual - => self.builder.build_int_compare(IntPredicate::SLE, a, b, "tmpsle"), - ast::Comparison::Greater - => self.builder.build_int_compare(IntPredicate::SGT, a, b, "tmpsgt"), - ast::Comparison::GreaterOrEqual - => self.builder.build_int_compare(IntPredicate::SGE, a, b, "tmpsge"), - _ => return Err(self.compile_error(CompileErrorKind::Unsupported("special comparison"))), + let this_result = + match (a, b) { + ( + values::BasicValueEnum::IntValue(a), + values::BasicValueEnum::IntValue(b), + ) => { + match op { + ast::Comparison::Equal => self.builder.build_int_compare( + IntPredicate::EQ, + a, + b, + "tmpeq", + ), + ast::Comparison::NotEqual => self + .builder + .build_int_compare(IntPredicate::NE, a, b, "tmpne"), + ast::Comparison::Less => self.builder.build_int_compare( + IntPredicate::SLT, + a, + b, + "tmpslt", + ), + ast::Comparison::LessOrEqual => self + .builder + .build_int_compare(IntPredicate::SLE, a, b, "tmpsle"), + ast::Comparison::Greater => self.builder.build_int_compare( + IntPredicate::SGT, + a, + b, + "tmpsgt", + ), + ast::Comparison::GreaterOrEqual => self + .builder + .build_int_compare(IntPredicate::SGE, a, b, "tmpsge"), + _ => { + return Err(self.compile_error( + CompileErrorKind::Unsupported("special comparison"), + )) + } + } } - }, - (values::BasicValueEnum::FloatValue(a), values::BasicValueEnum::FloatValue(b)) => { - match op { - ast::Comparison::Equal - => self.builder.build_float_compare(FloatPredicate::OEQ, a, b, "tmpoeq"), - ast::Comparison::NotEqual - => self.builder.build_float_compare(FloatPredicate::UNE, a, b, "tmpune"), - ast::Comparison::Less - => self.builder.build_float_compare(FloatPredicate::OLT, a, b, "tmpolt"), - ast::Comparison::LessOrEqual - => self.builder.build_float_compare(FloatPredicate::OLE, a, b, "tmpole"), - ast::Comparison::Greater - => self.builder.build_float_compare(FloatPredicate::OGT, a, b, "tmpogt"), - ast::Comparison::GreaterOrEqual - => self.builder.build_float_compare(FloatPredicate::OGE, a, b, "tmpoge"), - _ => return Err(self.compile_error(CompileErrorKind::Unsupported("special comparison"))), + ( + values::BasicValueEnum::FloatValue(a), + values::BasicValueEnum::FloatValue(b), + ) => match op { + ast::Comparison::Equal => self.builder.build_float_compare( + FloatPredicate::OEQ, + a, + b, + "tmpoeq", + ), + ast::Comparison::NotEqual => self.builder.build_float_compare( + FloatPredicate::UNE, + a, + b, + "tmpune", + ), + ast::Comparison::Less => self.builder.build_float_compare( + FloatPredicate::OLT, + a, + b, + "tmpolt", + ), + ast::Comparison::LessOrEqual => self + .builder + .build_float_compare(FloatPredicate::OLE, a, b, "tmpole"), + ast::Comparison::Greater => self.builder.build_float_compare( + FloatPredicate::OGT, + a, + b, + "tmpogt", + ), + ast::Comparison::GreaterOrEqual => self + .builder + .build_float_compare(FloatPredicate::OGE, a, b, "tmpoge"), + _ => { + return Err(self.compile_error( + CompileErrorKind::Unsupported("special comparison"), + )) + } + }, + _ => { + return Err(self.compile_error(CompileErrorKind::Unsupported( + "comparison of non-numerical types", + ))) } - }, - _ => return Err(self.compile_error(CompileErrorKind::Unsupported("comparison of non-numerical types"))), - }; + }; match result { Some(last) => { result = Some(self.builder.build_and(last, this_result, "tmpand")); @@ -346,15 +455,23 @@ impl<'ctx> CodeGen<'ctx> { } a = b; } else { - return Ok(result.unwrap().into()) + return Ok(result.unwrap().into()); } } - }, - ast::ExpressionType::Call { function, args, keywords } => { + } + ast::ExpressionType::Call { + function, + args, + keywords, + } => { if !keywords.is_empty() { - return Err(self.compile_error(CompileErrorKind::Unsupported("keyword arguments"))) + return Err( + self.compile_error(CompileErrorKind::Unsupported("keyword arguments")) + ); } - let args = args.iter().map(|val| self.compile_expression(val)) + let args = args + .iter() + .map(|val| self.compile_expression(val)) .collect::>>()?; self.set_source_location(expression.location); if let ast::ExpressionType::Identifier { name } = &function.node { @@ -362,67 +479,99 @@ impl<'ctx> CodeGen<'ctx> { ("int32", values::BasicValueEnum::IntValue(a)) => { let nbits = a.get_type().get_bit_width(); if nbits < 32 { - Ok(self.builder.build_int_s_extend(a, self.context.i32_type(), "tmpsext").into()) + Ok(self + .builder + .build_int_s_extend(a, self.context.i32_type(), "tmpsext") + .into()) } else if nbits > 32 { - Ok(self.builder.build_int_truncate(a, self.context.i32_type(), "tmptrunc").into()) + Ok(self + .builder + .build_int_truncate(a, self.context.i32_type(), "tmptrunc") + .into()) } else { Ok(a.into()) } - }, + } ("int64", values::BasicValueEnum::IntValue(a)) => { let nbits = a.get_type().get_bit_width(); if nbits < 64 { - Ok(self.builder.build_int_s_extend(a, self.context.i64_type(), "tmpsext").into()) + Ok(self + .builder + .build_int_s_extend(a, self.context.i64_type(), "tmpsext") + .into()) } else { Ok(a.into()) } - }, - ("int32", values::BasicValueEnum::FloatValue(a)) => { - Ok(self.builder.build_float_to_signed_int(a, self.context.i32_type(), "tmpfptosi").into()) - }, - ("int64", values::BasicValueEnum::FloatValue(a)) => { - Ok(self.builder.build_float_to_signed_int(a, self.context.i64_type(), "tmpfptosi").into()) - }, - ("float32", values::BasicValueEnum::IntValue(a)) => { - Ok(self.builder.build_signed_int_to_float(a, self.context.f32_type(), "tmpsitofp").into()) - }, - ("float64", values::BasicValueEnum::IntValue(a)) => { - Ok(self.builder.build_signed_int_to_float(a, self.context.f64_type(), "tmpsitofp").into()) - }, + } + ("int32", values::BasicValueEnum::FloatValue(a)) => Ok(self + .builder + .build_float_to_signed_int(a, self.context.i32_type(), "tmpfptosi") + .into()), + ("int64", values::BasicValueEnum::FloatValue(a)) => Ok(self + .builder + .build_float_to_signed_int(a, self.context.i64_type(), "tmpfptosi") + .into()), + ("float32", values::BasicValueEnum::IntValue(a)) => Ok(self + .builder + .build_signed_int_to_float(a, self.context.f32_type(), "tmpsitofp") + .into()), + ("float64", values::BasicValueEnum::IntValue(a)) => Ok(self + .builder + .build_signed_int_to_float(a, self.context.f64_type(), "tmpsitofp") + .into()), ("float32", values::BasicValueEnum::FloatValue(a)) => { if a.get_type() == self.context.f64_type() { - Ok(self.builder.build_float_trunc(a, self.context.f32_type(), "tmptrunc").into()) + Ok(self + .builder + .build_float_trunc(a, self.context.f32_type(), "tmptrunc") + .into()) } else { Ok(a.into()) } - }, + } ("float64", values::BasicValueEnum::FloatValue(a)) => { if a.get_type() == self.context.f32_type() { - Ok(self.builder.build_float_ext(a, self.context.f64_type(), "tmpext").into()) + Ok(self + .builder + .build_float_ext(a, self.context.f64_type(), "tmpext") + .into()) } else { Ok(a.into()) } - }, + } ("output", values::BasicValueEnum::IntValue(a)) => { let fn_value = self.module.get_function("output").unwrap(); - Ok(self.builder.build_call(fn_value, &[a.into()], "call") - .try_as_basic_value().left().unwrap()) - }, - _ => Err(self.compile_error(CompileErrorKind::Unsupported("unrecognized call"))) + Ok(self + .builder + .build_call(fn_value, &[a.into()], "call") + .try_as_basic_value() + .left() + .unwrap()) + } + _ => { + Err(self + .compile_error(CompileErrorKind::Unsupported("unrecognized call"))) + } } } else { - return Err(self.compile_error(CompileErrorKind::Unsupported("function must be an identifier"))) + return Err(self.compile_error(CompileErrorKind::Unsupported( + "function must be an identifier", + ))); } - }, - _ => return Err(self.compile_error(CompileErrorKind::Unsupported("unimplemented expression"))), + } + _ => { + return Err( + self.compile_error(CompileErrorKind::Unsupported("unimplemented expression")) + ) + } } } fn compile_statement( &mut self, statement: &ast::Statement, - return_type: Option + return_type: Option, ) -> CompileResult<()> { self.set_source_location(statement.location); @@ -434,29 +583,43 @@ impl<'ctx> CodeGen<'ctx> { self.set_source_location(target.location); if let ast::ExpressionType::Identifier { name } = &target.node { let builder = &self.builder; - let target = self.namespace.entry(name.clone()).or_insert_with( - || builder.build_alloca(value.get_type(), name)); - if target.get_type() != value.get_type().ptr_type(inkwell::AddressSpace::Generic) { + let target = self + .namespace + .entry(name.clone()) + .or_insert_with(|| builder.build_alloca(value.get_type(), name)); + if target.get_type() + != value.get_type().ptr_type(inkwell::AddressSpace::Generic) + { return Err(self.compile_error(CompileErrorKind::IncompatibleTypes)); } builder.build_store(*target, value); } else { - return Err(self.compile_error(CompileErrorKind::Unsupported("assignment target must be an identifier"))) + return Err(self.compile_error(CompileErrorKind::Unsupported( + "assignment target must be an identifier", + ))); } } - }, - Expression { expression } => { self.compile_expression(expression)?; }, + } + Expression { expression } => { + self.compile_expression(expression)?; + } If { test, body, orelse } => { let test = self.compile_expression(test)?; if test.get_type() != self.context.bool_type().into() { return Err(self.compile_error(CompileErrorKind::IncompatibleTypes)); } - let parent = self.builder.get_insert_block().unwrap().get_parent().unwrap(); + let parent = self + .builder + .get_insert_block() + .unwrap() + .get_parent() + .unwrap(); let then_bb = self.context.append_basic_block(parent, "then"); let else_bb = self.context.append_basic_block(parent, "else"); let cont_bb = self.context.append_basic_block(parent, "ifcont"); - self.builder.build_conditional_branch(test.into_int_value(), then_bb, else_bb); + self.builder + .build_conditional_branch(test.into_int_value(), then_bb, else_bb); self.builder.position_at_end(then_bb); self.compile_suite(body, return_type)?; @@ -468,9 +631,14 @@ impl<'ctx> CodeGen<'ctx> { } self.builder.build_unconditional_branch(cont_bb); self.builder.position_at_end(cont_bb); - }, + } While { test, body, orelse } => { - let parent = self.builder.get_insert_block().unwrap().get_parent().unwrap(); + let parent = self + .builder + .get_insert_block() + .unwrap() + .get_parent() + .unwrap(); let test_bb = self.context.append_basic_block(parent, "test"); self.builder.build_unconditional_branch(test_bb); self.builder.position_at_end(test_bb); @@ -482,7 +650,8 @@ impl<'ctx> CodeGen<'ctx> { let then_bb = self.context.append_basic_block(parent, "then"); let else_bb = self.context.append_basic_block(parent, "else"); let cont_bb = self.context.append_basic_block(parent, "ifcont"); - self.builder.build_conditional_branch(test.into_int_value(), then_bb, else_bb); + self.builder + .build_conditional_branch(test.into_int_value(), then_bb, else_bb); self.break_bb = Some(cont_bb); @@ -498,11 +667,16 @@ impl<'ctx> CodeGen<'ctx> { self.builder.position_at_end(cont_bb); self.break_bb = None; - }, + } Break => { if let Some(bb) = self.break_bb { self.builder.build_unconditional_branch(bb); - let parent = self.builder.get_insert_block().unwrap().get_parent().unwrap(); + let parent = self + .builder + .get_insert_block() + .unwrap() + .get_parent() + .unwrap(); let unreachable_bb = self.context.append_basic_block(parent, "unreachable"); self.builder.position_at_end(unreachable_bb); } else { @@ -519,13 +693,13 @@ impl<'ctx> CodeGen<'ctx> { } else { return Err(self.compile_error(CompileErrorKind::IncompatibleTypes)); } - }, + } Return { value: None } => { if !return_type.is_none() { return Err(self.compile_error(CompileErrorKind::IncompatibleTypes)); } self.builder.build_return(None); - }, + } Pass => (), _ => return Err(self.compile_error(CompileErrorKind::Unsupported("special statement"))), } @@ -535,7 +709,7 @@ impl<'ctx> CodeGen<'ctx> { fn compile_suite( &mut self, suite: &ast::Suite, - return_type: Option + return_type: Option, ) -> CompileResult<()> { for statement in suite.iter() { self.compile_statement(statement, return_type)?; @@ -546,18 +720,22 @@ impl<'ctx> CodeGen<'ctx> { pub fn compile_toplevel(&mut self, statement: &ast::Statement) -> CompileResult<()> { self.set_source_location(statement.location); if let ast::StatementType::FunctionDef { - is_async, - name, - args, - body, - decorator_list, - returns, - } = &statement.node { - let function = self.compile_function_def(name, args, body, decorator_list, returns, *is_async)?; + is_async, + name, + args, + body, + decorator_list, + returns, + } = &statement.node + { + let function = + self.compile_function_def(name, args, body, decorator_list, returns, *is_async)?; self.pass_manager.run_on(&function); Ok(()) } else { - Err(self.compile_error(CompileErrorKind::Internal("top-level is not a function definition"))) + Err(self.compile_error(CompileErrorKind::Internal( + "top-level is not a function definition", + ))) } } @@ -568,8 +746,8 @@ impl<'ctx> CodeGen<'ctx> { pub fn output(&self, filename: &str) { //let triple = TargetTriple::create("riscv32-none-linux-gnu"); let triple = TargetMachine::get_default_triple(); - let target = Target::from_triple(&triple) - .expect("couldn't create target from target triple"); + let target = + Target::from_triple(&triple).expect("couldn't create target from target triple"); let target_machine = target .create_target_machine( diff --git a/nac3core/src/operators.rs b/nac3core/src/operators.rs index 5619b2e46a..b0c248b458 100644 --- a/nac3core/src/operators.rs +++ b/nac3core/src/operators.rs @@ -56,4 +56,3 @@ pub fn comparison_name(op: &Comparison) -> Option<&'static str> { _ => None, } } - diff --git a/nac3core/src/typedef.rs b/nac3core/src/typedef.rs index e4886b307b..5fe42279ea 100644 --- a/nac3core/src/typedef.rs +++ b/nac3core/src/typedef.rs @@ -215,8 +215,7 @@ impl Type { pub fn get_base<'b: 'a, 'a>(&'a self, ctx: &'b GlobalContext) -> Option<&'b TypeDef> { match self { Type::PrimitiveType(id) => Some(ctx.get_primitive(*id)), - Type::ClassType(id) - | Type::VirtualClassType(id) => Some(&ctx.get_class(*id).base), + Type::ClassType(id) | Type::VirtualClassType(id) => Some(&ctx.get_class(*id).base), Type::ParametricType(id, _) => Some(&ctx.get_parametric(*id).base), _ => None, }