From 48098f83c1e3943d1fb76aaecdce3b4f56cf4d4a Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sat, 17 Apr 2021 08:28:24 +0200 Subject: feat(grfn/achilles): Implement tuples, and tuple patterns Implement tuple expressions, types, and patterns, all the way through the parser down to the typechecker. In LLVM, these are implemented as anonymous structs, using an `extract` instruction when they're pattern matched on to get out the individual fields. Currently the only limitation here is patterns aren't supported in function argument position, but you can still do something like fn xy = let (x, y) = xy in x + y Change-Id: I357f17e9d4052e741eda8605b6662822f331efde Reviewed-on: https://cl.tvl.fyi/c/depot/+/3027 Reviewed-by: grfn Tested-by: BuildkiteCI --- users/grfn/achilles/src/passes/hir/mod.rs | 22 ++++++++++++++++++---- .../src/passes/hir/strip_positive_units.rs | 8 +++++--- 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'users/grfn/achilles/src/passes') diff --git a/users/grfn/achilles/src/passes/hir/mod.rs b/users/grfn/achilles/src/passes/hir/mod.rs index 845bfcb7ab6a..872c449eb020 100644 --- a/users/grfn/achilles/src/passes/hir/mod.rs +++ b/users/grfn/achilles/src/passes/hir/mod.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::ast::hir::{Binding, Decl, Expr}; +use crate::ast::hir::{Binding, Decl, Expr, Pattern}; use crate::ast::{BinaryOperator, Ident, Literal, UnaryOperator}; pub(crate) mod monomorphize; @@ -29,9 +29,12 @@ pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a { Ok(()) } + fn visit_pattern(&mut self, _pat: &mut Pattern<'ast, T>) -> Result<(), Self::Error> { + Ok(()) + } + fn visit_binding(&mut self, binding: &mut Binding<'ast, T>) -> Result<(), Self::Error> { - self.visit_ident(&mut binding.ident)?; - self.visit_type(&mut binding.type_)?; + self.visit_pattern(&mut binding.pat)?; self.visit_expr(&mut binding.body)?; Ok(()) } @@ -54,6 +57,13 @@ pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a { Ok(()) } + fn visit_tuple(&mut self, members: &mut Vec>) -> Result<(), Self::Error> { + for expr in members { + self.visit_expr(expr)?; + } + Ok(()) + } + fn pre_visit_expr(&mut self, _expr: &mut Expr<'ast, T>) -> Result<(), Self::Error> { Ok(()) } @@ -137,12 +147,16 @@ pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a { self.visit_type(type_)?; self.post_visit_call(fun, type_args, args)?; } + Expr::Tuple(tup, type_) => { + self.visit_tuple(tup)?; + self.visit_type(type_)?; + } } Ok(()) } - fn post_visit_decl(&mut self, decl: &'a Decl<'ast, T>) -> Result<(), Self::Error> { + fn post_visit_decl(&mut self, _decl: &'a Decl<'ast, T>) -> Result<(), Self::Error> { Ok(()) } diff --git a/users/grfn/achilles/src/passes/hir/strip_positive_units.rs b/users/grfn/achilles/src/passes/hir/strip_positive_units.rs index 91b56551c82d..85ee1cce4859 100644 --- a/users/grfn/achilles/src/passes/hir/strip_positive_units.rs +++ b/users/grfn/achilles/src/passes/hir/strip_positive_units.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::mem; -use ast::hir::Binding; +use ast::hir::{Binding, Pattern}; use ast::Literal; use void::{ResultVoidExt, Void}; @@ -42,8 +42,10 @@ impl<'a, 'ast> Visitor<'a, 'ast, ast::Type<'ast>> for StripPositiveUnits { bindings: extracted .into_iter() .map(|expr| Binding { - ident: Ident::from_str_unchecked("___discarded"), - type_: expr.type_().clone(), + pat: Pattern::Id( + Ident::from_str_unchecked("___discarded"), + expr.type_().clone(), + ), body: expr, }) .collect(), -- cgit 1.4.1