@@ -6023,6 +6023,58 @@ fn eval_const_scalar( |
| 6023 | 6023 | None |
| 6024 | 6024 | } |
| 6025 | 6025 | } |
| 6026 | + "bit_size" => { |
| 6027 | + // F2018 §16.9.31: BIT_SIZE(I) returns the number of |
| 6028 | + // bits in the model integer for argument I. Folds at |
| 6029 | + // compile time when the argument has a known kind. |
| 6030 | + // Without this, module-level |
| 6031 | + // `integer, parameter :: K = bit_size(1_8)` |
| 6032 | + // initializers stored zero in .data — the linked |
| 6033 | + // binary then read K=0 inside any function that |
| 6034 | + // imported the module, breaking F2018 §13.7 |
| 6035 | + // semantics. stdlib_random's MAX_INT_BIT_SIZE was |
| 6036 | + // the failing repro. |
| 6037 | + let arg = args.first()?; |
| 6038 | + let crate::ast::expr::SectionSubscript::Element(e) = &arg.value else { |
| 6039 | + return None; |
| 6040 | + }; |
| 6041 | + let kind = match &e.node { |
| 6042 | + Expr::IntegerLiteral { kind, .. } => match kind.as_deref() { |
| 6043 | + None => 4, |
| 6044 | + Some(s) => match s.parse::<i64>().ok() { |
| 6045 | + Some(k) => k, |
| 6046 | + None => { |
| 6047 | + let key = s.to_lowercase(); |
| 6048 | + match key.as_str() { |
| 6049 | + "int8" => 1, |
| 6050 | + "int16" => 2, |
| 6051 | + "int32" => 4, |
| 6052 | + "int64" => 8, |
| 6053 | + _ => match param_consts.get(&key).copied() { |
| 6054 | + Some(ConstScalar::Int(v)) => v as i64, |
| 6055 | + _ => return None, |
| 6056 | + }, |
| 6057 | + } |
| 6058 | + } |
| 6059 | + }, |
| 6060 | + }, |
| 6061 | + Expr::Name { name } => { |
| 6062 | + let key = name.to_lowercase(); |
| 6063 | + match key.as_str() { |
| 6064 | + "int8" => 1, |
| 6065 | + "int16" => 2, |
| 6066 | + "int32" => 4, |
| 6067 | + "int64" => 8, |
| 6068 | + _ => match param_consts.get(&key).copied() { |
| 6069 | + Some(ConstScalar::Int(v)) => v as i64, |
| 6070 | + _ => return None, |
| 6071 | + }, |
| 6072 | + } |
| 6073 | + } |
| 6074 | + _ => 4, |
| 6075 | + }; |
| 6076 | + Some(ConstScalar::Int((kind as i128) * 8)) |
| 6077 | + } |
| 6026 | 6078 | "selected_real_kind" => { |
| 6027 | 6079 | if let Some(ConstScalar::Int(p)) = first_arg { |
| 6028 | 6080 | let p = p as i64; |