From 637b5024d5eff3820931c1e499e7467643722296 Mon Sep 17 00:00:00 2001 From: Grant Wuerker Date: Wed, 22 Jun 2022 14:16:44 -0600 Subject: [PATCH] hacking --- crates/analyzer/src/traversal/const_expr.rs | 1 + crates/analyzer/src/traversal/expressions.rs | 31 +++++++++++++++++++- crates/parser/src/ast.rs | 4 +-- crates/parser/src/grammar/expressions.rs | 2 +- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/crates/analyzer/src/traversal/const_expr.rs b/crates/analyzer/src/traversal/const_expr.rs index 0aa5e43c62..b8e0042151 100644 --- a/crates/analyzer/src/traversal/const_expr.rs +++ b/crates/analyzer/src/traversal/const_expr.rs @@ -59,6 +59,7 @@ pub(crate) fn eval_expr( | ast::Expr::Attribute { .. } | ast::Expr::Call { .. } | ast::Expr::List { .. } + | ast::Expr::Repeat { .. } | ast::Expr::Tuple { .. } | ast::Expr::Unit => Err(not_const_error(context, expr.span)), } diff --git a/crates/analyzer/src/traversal/expressions.rs b/crates/analyzer/src/traversal/expressions.rs index 79c319cbdf..dc0fae9fba 100644 --- a/crates/analyzer/src/traversal/expressions.rs +++ b/crates/analyzer/src/traversal/expressions.rs @@ -1,5 +1,5 @@ use crate::builtins::{ContractTypeMethod, GlobalFunction, Intrinsic, ValueMethod}; -use crate::context::{AnalyzerContext, CallType, ExpressionAttributes, Location, NamedThing}; +use crate::context::{AnalyzerContext, CallType, Constant, ExpressionAttributes, Location, NamedThing}; use crate::errors::{FatalError, IndexingError}; use crate::namespace::items::{Class, FunctionId, Item, TypeDef}; use crate::namespace::scopes::BlockScopeType; @@ -19,7 +19,9 @@ use num_bigint::BigInt; use smol_str::SmolStr; use std::ops::RangeInclusive; use std::str::FromStr; +use num_traits::ToPrimitive; use vec1::Vec1; +use crate::traversal::const_expr::eval_expr; /// Gather context information for expressions and check for type errors. pub fn expr( @@ -45,6 +47,7 @@ pub fn expr( args, } => expr_call(context, func, generic_args, args), fe::Expr::List { elts } => expr_list(context, elts, expected_type.as_array()), + fe::Expr::Repeat { value, len } => expr_repeat(context, value, len, expected_type.as_array()), fe::Expr::Tuple { .. } => expr_tuple(context, exp, expected_type.as_tuple()), fe::Expr::Str(_) => expr_str(context, exp, expected_type.as_string()), fe::Expr::Unit => Ok(ExpressionAttributes::new(Type::unit(), Location::Value)), @@ -136,6 +139,32 @@ pub fn expr_list( }) } +pub fn expr_repeat( + context: &mut dyn AnalyzerContext, + value: Node, + len: Node, + expected_type: Option<&Array>, +) -> Result { + let value = assignable_expr(context, &value, None)?; + let len = if let Constant::Int(len) = eval_expr(context, &len) { + len + } else { + panic!("shit") + }; + + let array_typ = Array { + size: len.to_usize().unwrap(), + inner: value.typ, + }; + + Ok(ExpressionAttributes { + typ: Type::Array(array_typ), + location: Location::Memory, + move_location: None, + const_value: None, + }) +} + /// Gather context information for expressions and check for type errors. /// /// Also ensures that the expression is on the stack. diff --git a/crates/parser/src/ast.rs b/crates/parser/src/ast.rs index 5ec578c972..03d79170d1 100644 --- a/crates/parser/src/ast.rs +++ b/crates/parser/src/ast.rs @@ -338,7 +338,7 @@ pub enum Expr { elts: Vec>, }, Repeat { - elt: Box>, + value: Box>, len: Box> }, Tuple { @@ -968,7 +968,7 @@ impl fmt::Display for Expr { write!(f, "({})", node_comma_joined(&args.kind)) } Expr::List { elts } => write!(f, "[{}]", node_comma_joined(elts)), - Expr::Repeat { elt, len } => write!(f, "[{}; {}]", elt.kind, len.kind), + Expr::Repeat { value: elt, len } => write!(f, "[{}; {}]", elt.kind, len.kind), Expr::Tuple { elts } => { if elts.len() == 1 { write!(f, "({},)", elts[0].kind) diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index 807e1ec78f..b380e07b3e 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -312,7 +312,7 @@ fn parse_list_or_repeat(par: &mut Parser) -> ParseResult> { let len = parse_expr(par)?; let rbracket = par.assert(TokenKind::BracketClose); let span = lbracket.span + rbracket.span; - Ok(Node::new(Expr::Repeat {elt: Box::new(elts[0].clone()), len: Box::new(len) }, span)) + Ok(Node::new(Expr::Repeat { value: Box::new(elts[0].clone()), len: Box::new(len) }, span)) } else { panic!("shit") }