Iterate over binary ops (instead of recursing)
This commit is contained in:
		@ -918,165 +918,193 @@ impl Node<MemberExpression> {
 | 
			
		||||
impl Node<BinaryExpression> {
 | 
			
		||||
    #[async_recursion]
 | 
			
		||||
    pub async fn get_result(&self, exec_state: &mut ExecState, ctx: &ExecutorContext) -> Result<KclValue, KclError> {
 | 
			
		||||
        let left_value = self.left.get_result(exec_state, ctx).await?;
 | 
			
		||||
        let right_value = self.right.get_result(exec_state, ctx).await?;
 | 
			
		||||
        let mut meta = left_value.metadata();
 | 
			
		||||
        meta.extend(right_value.metadata());
 | 
			
		||||
 | 
			
		||||
        // First check if we are doing string concatenation.
 | 
			
		||||
        if self.operator == BinaryOperator::Add {
 | 
			
		||||
            if let (KclValue::String { value: left, meta: _ }, KclValue::String { value: right, meta: _ }) =
 | 
			
		||||
                (&left_value, &right_value)
 | 
			
		||||
            {
 | 
			
		||||
                return Ok(KclValue::String {
 | 
			
		||||
                    value: format!("{}{}", left, right),
 | 
			
		||||
                    meta,
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        let mut partial = self.right.get_result(exec_state, ctx).await?;
 | 
			
		||||
        let mut next = &self.left;
 | 
			
		||||
        let source_range = self.into();
 | 
			
		||||
        // Don't recurse through a big chain of binary operations, iterate instead.
 | 
			
		||||
        while let BinaryPart::BinaryExpression(next_binary_expr) = next {
 | 
			
		||||
            let metadata = partial.metadata();
 | 
			
		||||
            partial = do_binary_op(
 | 
			
		||||
                partial,
 | 
			
		||||
                next_binary_expr.right.get_result(exec_state, ctx).await?,
 | 
			
		||||
                next_binary_expr.operator,
 | 
			
		||||
                metadata,
 | 
			
		||||
                source_range,
 | 
			
		||||
                exec_state,
 | 
			
		||||
                ctx,
 | 
			
		||||
            )
 | 
			
		||||
            .await?;
 | 
			
		||||
            next = &next_binary_expr.left;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Then check if we have solids.
 | 
			
		||||
        if self.operator == BinaryOperator::Add || self.operator == BinaryOperator::Or {
 | 
			
		||||
            if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
                let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
 | 
			
		||||
                let result =
 | 
			
		||||
                    crate::std::csg::inner_union(vec![*left.clone(), *right.clone()], exec_state, args).await?;
 | 
			
		||||
                return Ok(result.into());
 | 
			
		||||
            }
 | 
			
		||||
        } else if self.operator == BinaryOperator::Sub {
 | 
			
		||||
            // Check if we have solids.
 | 
			
		||||
            if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
                let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
 | 
			
		||||
                let result =
 | 
			
		||||
                    crate::std::csg::inner_subtract(vec![*left.clone()], vec![*right.clone()], exec_state, args)
 | 
			
		||||
                        .await?;
 | 
			
		||||
                return Ok(result.into());
 | 
			
		||||
            }
 | 
			
		||||
        } else if self.operator == BinaryOperator::And {
 | 
			
		||||
            // Check if we have solids.
 | 
			
		||||
            if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
                let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
 | 
			
		||||
                let result =
 | 
			
		||||
                    crate::std::csg::inner_intersect(vec![*left.clone(), *right.clone()], exec_state, args).await?;
 | 
			
		||||
                return Ok(result.into());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check if we are doing logical operations on booleans.
 | 
			
		||||
        if self.operator == BinaryOperator::Or || self.operator == BinaryOperator::And {
 | 
			
		||||
            let KclValue::Bool {
 | 
			
		||||
                value: left_value,
 | 
			
		||||
                meta: _,
 | 
			
		||||
            } = left_value
 | 
			
		||||
            else {
 | 
			
		||||
                return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
                    message: format!(
 | 
			
		||||
                        "Cannot apply logical operator to non-boolean value: {}",
 | 
			
		||||
                        left_value.human_friendly_type()
 | 
			
		||||
                    ),
 | 
			
		||||
                    source_ranges: vec![self.left.clone().into()],
 | 
			
		||||
                }));
 | 
			
		||||
            };
 | 
			
		||||
            let KclValue::Bool {
 | 
			
		||||
                value: right_value,
 | 
			
		||||
                meta: _,
 | 
			
		||||
            } = right_value
 | 
			
		||||
            else {
 | 
			
		||||
                return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
                    message: format!(
 | 
			
		||||
                        "Cannot apply logical operator to non-boolean value: {}",
 | 
			
		||||
                        right_value.human_friendly_type()
 | 
			
		||||
                    ),
 | 
			
		||||
                    source_ranges: vec![self.right.clone().into()],
 | 
			
		||||
                }));
 | 
			
		||||
            };
 | 
			
		||||
            let raw_value = match self.operator {
 | 
			
		||||
                BinaryOperator::Or => left_value || right_value,
 | 
			
		||||
                BinaryOperator::And => left_value && right_value,
 | 
			
		||||
                _ => unreachable!(),
 | 
			
		||||
            };
 | 
			
		||||
            return Ok(KclValue::Bool { value: raw_value, meta });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let left = number_as_f64(&left_value, self.left.clone().into())?;
 | 
			
		||||
        let right = number_as_f64(&right_value, self.right.clone().into())?;
 | 
			
		||||
 | 
			
		||||
        let value = match self.operator {
 | 
			
		||||
            BinaryOperator::Add => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Adding", exec_state);
 | 
			
		||||
                KclValue::Number { value: l + r, meta, ty }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Sub => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Subtracting", exec_state);
 | 
			
		||||
                KclValue::Number { value: l - r, meta, ty }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Mul => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_mul(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Multiplying", exec_state);
 | 
			
		||||
                KclValue::Number { value: l * r, meta, ty }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Div => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_div(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Dividing", exec_state);
 | 
			
		||||
                KclValue::Number { value: l / r, meta, ty }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Mod => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_div(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Modulo of", exec_state);
 | 
			
		||||
                KclValue::Number { value: l % r, meta, ty }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Pow => KclValue::Number {
 | 
			
		||||
                value: left.n.powf(right.n),
 | 
			
		||||
                meta,
 | 
			
		||||
                ty: NumericType::Unknown,
 | 
			
		||||
            },
 | 
			
		||||
            BinaryOperator::Neq => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Comparing", exec_state);
 | 
			
		||||
                KclValue::Bool { value: l != r, meta }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Gt => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Comparing", exec_state);
 | 
			
		||||
                KclValue::Bool { value: l > r, meta }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Gte => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Comparing", exec_state);
 | 
			
		||||
                KclValue::Bool { value: l >= r, meta }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Lt => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Comparing", exec_state);
 | 
			
		||||
                KclValue::Bool { value: l < r, meta }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Lte => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Comparing", exec_state);
 | 
			
		||||
                KclValue::Bool { value: l <= r, meta }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::Eq => {
 | 
			
		||||
                let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
                self.warn_on_unknown(&ty, "Comparing", exec_state);
 | 
			
		||||
                KclValue::Bool { value: l == r, meta }
 | 
			
		||||
            }
 | 
			
		||||
            BinaryOperator::And | BinaryOperator::Or => unreachable!(),
 | 
			
		||||
        };
 | 
			
		||||
        let next_value = next.get_result(exec_state, ctx).await?;
 | 
			
		||||
        let mut meta = partial.metadata();
 | 
			
		||||
        meta.extend(next_value.metadata());
 | 
			
		||||
 | 
			
		||||
        let value = do_binary_op(partial, next_value, self.operator, meta, self.into(), exec_state, ctx).await?;
 | 
			
		||||
        Ok(value)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    fn warn_on_unknown(&self, ty: &NumericType, verb: &str, exec_state: &mut ExecState) {
 | 
			
		||||
        if *CHECK_NUMERIC_TYPES && ty == &NumericType::Unknown {
 | 
			
		||||
            // TODO suggest how to fix this
 | 
			
		||||
            exec_state.warn(CompilationError::err(
 | 
			
		||||
                self.as_source_range(),
 | 
			
		||||
                format!("{} numbers which have unknown or incompatible units.", verb),
 | 
			
		||||
            ));
 | 
			
		||||
fn warn_on_unknown(source_range: SourceRange, ty: &NumericType, verb: &str, exec_state: &mut ExecState) {
 | 
			
		||||
    if *CHECK_NUMERIC_TYPES && ty == &NumericType::Unknown {
 | 
			
		||||
        // TODO suggest how to fix this
 | 
			
		||||
        exec_state.warn(CompilationError::err(
 | 
			
		||||
            source_range,
 | 
			
		||||
            format!("{} numbers which have unknown or incompatible units.", verb),
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn do_binary_op(
 | 
			
		||||
    left_value: KclValue,
 | 
			
		||||
    right_value: KclValue,
 | 
			
		||||
    operator: BinaryOperator,
 | 
			
		||||
    meta: Vec<Metadata>,
 | 
			
		||||
    source_range: SourceRange,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    ctx: &ExecutorContext,
 | 
			
		||||
) -> Result<KclValue, KclError> {
 | 
			
		||||
    // First check if we are doing string concatenation.
 | 
			
		||||
    if operator == BinaryOperator::Add {
 | 
			
		||||
        if let (KclValue::String { value: left, meta: _ }, KclValue::String { value: right, meta: _ }) =
 | 
			
		||||
            (&left_value, &right_value)
 | 
			
		||||
        {
 | 
			
		||||
            return Ok(KclValue::String {
 | 
			
		||||
                value: format!("{}{}", left, right),
 | 
			
		||||
                meta,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Then check if we have solids.
 | 
			
		||||
    if operator == BinaryOperator::Add || operator == BinaryOperator::Or {
 | 
			
		||||
        if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
            let args = crate::std::Args::new(Default::default(), source_range, ctx.clone(), None);
 | 
			
		||||
            let result = crate::std::csg::inner_union(vec![*left.clone(), *right.clone()], exec_state, args).await?;
 | 
			
		||||
            return Ok(result.into());
 | 
			
		||||
        }
 | 
			
		||||
    } else if operator == BinaryOperator::Sub {
 | 
			
		||||
        // Check if we have solids.
 | 
			
		||||
        if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
            let args = crate::std::Args::new(Default::default(), source_range, ctx.clone(), None);
 | 
			
		||||
            let result =
 | 
			
		||||
                crate::std::csg::inner_subtract(vec![*left.clone()], vec![*right.clone()], exec_state, args).await?;
 | 
			
		||||
            return Ok(result.into());
 | 
			
		||||
        }
 | 
			
		||||
    } else if operator == BinaryOperator::And {
 | 
			
		||||
        // Check if we have solids.
 | 
			
		||||
        if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
 | 
			
		||||
            let args = crate::std::Args::new(Default::default(), source_range, ctx.clone(), None);
 | 
			
		||||
            let result =
 | 
			
		||||
                crate::std::csg::inner_intersect(vec![*left.clone(), *right.clone()], exec_state, args).await?;
 | 
			
		||||
            return Ok(result.into());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check if we are doing logical operations on booleans.
 | 
			
		||||
    if operator == BinaryOperator::Or || operator == BinaryOperator::And {
 | 
			
		||||
        let KclValue::Bool {
 | 
			
		||||
            value: left_value,
 | 
			
		||||
            meta: _,
 | 
			
		||||
        } = left_value
 | 
			
		||||
        else {
 | 
			
		||||
            return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
                message: format!(
 | 
			
		||||
                    "Cannot apply logical operator to non-boolean value: {}",
 | 
			
		||||
                    left_value.human_friendly_type()
 | 
			
		||||
                ),
 | 
			
		||||
                source_ranges: left_value.into(),
 | 
			
		||||
            }));
 | 
			
		||||
        };
 | 
			
		||||
        let KclValue::Bool {
 | 
			
		||||
            value: right_value,
 | 
			
		||||
            meta: _,
 | 
			
		||||
        } = right_value
 | 
			
		||||
        else {
 | 
			
		||||
            return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
                message: format!(
 | 
			
		||||
                    "Cannot apply logical operator to non-boolean value: {}",
 | 
			
		||||
                    right_value.human_friendly_type()
 | 
			
		||||
                ),
 | 
			
		||||
                source_ranges: right_value.into(),
 | 
			
		||||
            }));
 | 
			
		||||
        };
 | 
			
		||||
        let raw_value = match operator {
 | 
			
		||||
            BinaryOperator::Or => left_value || right_value,
 | 
			
		||||
            BinaryOperator::And => left_value && right_value,
 | 
			
		||||
            _ => unreachable!(),
 | 
			
		||||
        };
 | 
			
		||||
        return Ok(KclValue::Bool { value: raw_value, meta });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let left = number_as_f64(&left_value, (&left_value).into())?;
 | 
			
		||||
    let right = number_as_f64(&right_value, (&left_value).into())?;
 | 
			
		||||
 | 
			
		||||
    let value = match operator {
 | 
			
		||||
        BinaryOperator::Add => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Adding", exec_state);
 | 
			
		||||
            KclValue::Number { value: l + r, meta, ty }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Sub => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Subtracting", exec_state);
 | 
			
		||||
            KclValue::Number { value: l - r, meta, ty }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Mul => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_mul(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Multiplying", exec_state);
 | 
			
		||||
            KclValue::Number { value: l * r, meta, ty }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Div => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_div(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Dividing", exec_state);
 | 
			
		||||
            KclValue::Number { value: l / r, meta, ty }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Mod => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_div(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Modulo of", exec_state);
 | 
			
		||||
            KclValue::Number { value: l % r, meta, ty }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Pow => KclValue::Number {
 | 
			
		||||
            value: left.n.powf(right.n),
 | 
			
		||||
            meta,
 | 
			
		||||
            ty: NumericType::Unknown,
 | 
			
		||||
        },
 | 
			
		||||
        BinaryOperator::Neq => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Comparing", exec_state);
 | 
			
		||||
            KclValue::Bool { value: l != r, meta }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Gt => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Comparing", exec_state);
 | 
			
		||||
            KclValue::Bool { value: l > r, meta }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Gte => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Comparing", exec_state);
 | 
			
		||||
            KclValue::Bool { value: l >= r, meta }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Lt => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Comparing", exec_state);
 | 
			
		||||
            KclValue::Bool { value: l < r, meta }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Lte => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Comparing", exec_state);
 | 
			
		||||
            KclValue::Bool { value: l <= r, meta }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::Eq => {
 | 
			
		||||
            let (l, r, ty) = NumericType::combine_eq(left, right);
 | 
			
		||||
            warn_on_unknown(source_range, &ty, "Comparing", exec_state);
 | 
			
		||||
            KclValue::Bool { value: l == r, meta }
 | 
			
		||||
        }
 | 
			
		||||
        BinaryOperator::And | BinaryOperator::Or => unreachable!(),
 | 
			
		||||
    };
 | 
			
		||||
    Ok(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Node<UnaryExpression> {
 | 
			
		||||
 | 
			
		||||
@ -2832,7 +2832,7 @@ impl BinaryExpression {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, FromStr, Display)]
 | 
			
		||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS, JsonSchema, FromStr, Display)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
#[serde(rename_all = "snake_case")]
 | 
			
		||||
#[display(style = "snake_case")]
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -2,6 +2,6 @@ fn f(i) {
 | 
			
		||||
  return i * 2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
x = f(0) + f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) + f(8) + f(9) + f(10) + f(11) + f(12) + f(13) + f(14) + f(15) + f(16) + f(17) + f(18) + f(19) + f(20) + f(21) + f(22) + f(23) + f(24) + f(25) + f(26) + f(27) + f(28) + f(29) + f(30) + f(31) + f(32) + f(33) + f(34) + f(35) + f(36) + f(37) + f(38) + f(39) + f(40) + f(41) + f(42) + f(43) + f(44) + f(45) + f(46) + f(47) + f(48) + f(49) + f(50) + f(51) + f(52) + f(53) + f(54) + f(55) + f(56) + f(57) + f(58) + f(59) + f(60) + f(61) + f(62) + f(63) + f(64) + f(65) + f(66) + f(67) + f(68) + f(69) + f(70)
 | 
			
		||||
x = f(0) + f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) + f(8) + f(9) + f(10) + f(11) + f(12) + f(13) + f(14) + f(15) + f(16) + f(17) + f(18) + f(19) + f(20) + f(21) + f(22) + f(23) + f(24) + f(25) + f(26) + f(27) + f(28) + f(29) + f(30) + f(31) + f(32) + f(33) + f(34) + f(35) + f(36) + f(37) + f(38) + f(39) + f(40) + f(41) + f(42) + f(43) + f(44) + f(45) + f(46) + f(47) + f(48) + f(49) + f(50) + f(51) + f(52) + f(53) + f(54) + f(55) + f(56) + f(57) + f(58) + f(59) + f(60) + f(61) + f(62) + f(63) + f(64) + f(65) + f(66) + f(67) + f(68) + f(69) + f(70) + f(71) + f(72) + f(73) + f(74) + f(75) + f(76) + f(77) + f(78) + f(79) + f(80) + f(81) + f(82) + f(83) + f(84) + f(85) + f(86) + f(87) + f(88) + f(89) + f(90) + f(91) + f(92) + f(93) + f(94) + f(95) + f(96) + f(97) + f(98) + f(99) + f(100)
 | 
			
		||||
 | 
			
		||||
assertEqual(x, 4970, 0.1, "Big sum")
 | 
			
		||||
assertEqual(x, 10100, 0.1, "Big sum")
 | 
			
		||||
 | 
			
		||||
@ -1278,6 +1278,546 @@ description: Operations executed add_lots.kcl
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupBegin",
 | 
			
		||||
    "group": {
 | 
			
		||||
      "type": "FunctionCall",
 | 
			
		||||
      "name": "f",
 | 
			
		||||
      "functionSourceRange": [
 | 
			
		||||
        4,
 | 
			
		||||
        26,
 | 
			
		||||
        0
 | 
			
		||||
      ],
 | 
			
		||||
      "unlabeledArg": null,
 | 
			
		||||
      "labeledArgs": {}
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "GroupEnd"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ description: Variables in memory after executing add_lots.kcl
 | 
			
		||||
  },
 | 
			
		||||
  "x": {
 | 
			
		||||
    "type": "Number",
 | 
			
		||||
    "value": 4970.0,
 | 
			
		||||
    "value": 10100.0,
 | 
			
		||||
    "ty": {
 | 
			
		||||
      "type": "Default",
 | 
			
		||||
      "len": {
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,6 @@ fn f(i) {
 | 
			
		||||
  return i * 2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
x = f(0) + f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) + f(8) + f(9) + f(10) + f(11) + f(12) + f(13) + f(14) + f(15) + f(16) + f(17) + f(18) + f(19) + f(20) + f(21) + f(22) + f(23) + f(24) + f(25) + f(26) + f(27) + f(28) + f(29) + f(30) + f(31) + f(32) + f(33) + f(34) + f(35) + f(36) + f(37) + f(38) + f(39) + f(40) + f(41) + f(42) + f(43) + f(44) + f(45) + f(46) + f(47) + f(48) + f(49) + f(50) + f(51) + f(52) + f(53) + f(54) + f(55) + f(56) + f(57) + f(58) + f(59) + f(60) + f(61) + f(62) + f(63) + f(64) + f(65) + f(66) + f(67) + f(68) + f(69) + f(70)
 | 
			
		||||
x = f(0) + f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) + f(8) + f(9) + f(10) + f(11) + f(12) + f(13) + f(14) + f(15) + f(16) + f(17) + f(18) + f(19) + f(20) + f(21) + f(22) + f(23) + f(24) + f(25) + f(26) + f(27) + f(28) + f(29) + f(30) + f(31) + f(32) + f(33) + f(34) + f(35) + f(36) + f(37) + f(38) + f(39) + f(40) + f(41) + f(42) + f(43) + f(44) + f(45) + f(46) + f(47) + f(48) + f(49) + f(50) + f(51) + f(52) + f(53) + f(54) + f(55) + f(56) + f(57) + f(58) + f(59) + f(60) + f(61) + f(62) + f(63) + f(64) + f(65) + f(66) + f(67) + f(68) + f(69) + f(70) + f(71) + f(72) + f(73) + f(74) + f(75) + f(76) + f(77) + f(78) + f(79) + f(80) + f(81) + f(82) + f(83) + f(84) + f(85) + f(86) + f(87) + f(88) + f(89) + f(90) + f(91) + f(92) + f(93) + f(94) + f(95) + f(96) + f(97) + f(98) + f(99) + f(100)
 | 
			
		||||
 | 
			
		||||
assertEqual(x, 4970, 0.1, "Big sum")
 | 
			
		||||
assertEqual(x, 10100, 0.1, "Big sum")
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user