Implement list literals

This commit is contained in:
Greg Shuflin 2021-11-02 21:19:29 -07:00
parent 8336211a4b
commit a13ad0edaa
5 changed files with 26 additions and 6 deletions

View File

@ -187,7 +187,7 @@ impl<'a, 'b> Reducer<'a, 'b> {
Expression::Loop { cond, statements }
}
ForExpression { .. } => Expression::ReductionError("For expr not implemented".to_string()),
ListLiteral { .. } => Expression::ReductionError("ListLiteral expr not implemented".to_string()),
ListLiteral(items) => Expression::List(items.iter().map(|item| self.expression(item)).collect()),
Access { name, expr } =>
Expression::Access { name: name.as_ref().to_string(), expr: Box::new(self.expression(expr)) },
}

View File

@ -51,6 +51,7 @@ pub enum Statement {
pub enum Expression {
Literal(Literal),
Tuple(Vec<Expression>),
List(Vec<Expression>),
Lookup(Lookup),
Assign { lval: DefId, rval: Box<Expression> },
Access { name: String, expr: Box<Expression> },

View File

@ -111,6 +111,12 @@ impl<'a, 'b> Evaluator<'a, 'b> {
.map(|expr| self.expression(expr))
.collect::<EvalResult<Vec<Primitive>>>()?,
),
Expression::List(items) => Primitive::List(
items
.into_iter()
.map(|expr| self.expression(expr))
.collect::<EvalResult<Vec<Primitive>>>()?,
),
Expression::Lookup(kind) => match kind {
Lookup::Function(ref id) => {
let mem = id.into();

View File

@ -61,16 +61,16 @@ impl RuntimeError {
}
}
fn paren_wrapped(terms: impl Iterator<Item = String>) -> String {
fn delim_wrapped(lhs: char, rhs: char, terms: impl Iterator<Item = String>) -> String {
let mut buf = String::new();
write!(buf, "(").unwrap();
write!(buf, "{}", lhs).unwrap();
for term in terms.map(Some).intersperse(None) {
match term {
Some(e) => write!(buf, "{}", e).unwrap(),
None => write!(buf, ", ").unwrap(),
};
}
write!(buf, ")").unwrap();
write!(buf, "{}", rhs).unwrap();
buf
}
@ -110,6 +110,7 @@ impl From<Primitive> for RuntimeValue {
#[derive(Debug, Clone)]
enum Primitive {
Tuple(Vec<Primitive>),
List(Vec<Primitive>),
Literal(Literal),
Callable(Callable),
Object { type_id: TypeId, tag: u32, ordered_fields: Option<Vec<String>>, items: Vec<Primitive> },
@ -124,7 +125,7 @@ impl Primitive {
format!(
"{}{}",
type_context.variant_local_name(type_id, *tag).unwrap(),
paren_wrapped(items.iter().map(|item| item.to_repl(type_context)))
delim_wrapped('(', ')', items.iter().map(|item| item.to_repl(type_context)))
)
}
Primitive::Object { type_id, items, tag, ordered_fields: Some(fields) } => {
@ -145,7 +146,8 @@ impl Primitive {
Literal::Bool(b) => format!("{}", b),
Literal::StringLit(s) => format!("\"{}\"", s),
},
Primitive::Tuple(terms) => paren_wrapped(terms.iter().map(|x| x.to_repl(type_context))),
Primitive::Tuple(terms) => delim_wrapped('(', ')', terms.iter().map(|x| x.to_repl(type_context))),
Primitive::List(terms) => delim_wrapped('[', ']', terms.iter().map(|x| x.to_repl(type_context))),
Primitive::Callable(..) => "<some-callable>".to_string(),
}
}

View File

@ -526,3 +526,14 @@ while a < 10 {
acc"#;
eval_assert(source, "19");
}
#[test]
fn list_literals() {
eval_assert(
r#"
let a = [7, 8, 9]
a
"#,
"[7, 8, 9]",
);
}