Skip to content

Commit

Permalink
Let expression context specify type arguments
Browse files Browse the repository at this point in the history
This patch adds the ability to explicitly specify the type arguments of
generics when used in an expression context.

It also fixes some of the API ugliness around `mem::size_of` and
`mem::align_of` that this previously caused.
  • Loading branch information
kukrimate committed Apr 9, 2023
1 parent c15f3f6 commit 3278d63
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 93 deletions.
2 changes: 1 addition & 1 deletion misc/grm.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ Argument: () = {

PrimExpr: () = {
"(" Expr ")",
Path,
Path ("::" "<" TypeNameList ">")?,
"nil",
"true",
"false",
Expand Down
7 changes: 6 additions & 1 deletion mpc/src/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,10 +907,15 @@ impl<'repo> Parser<'repo> {
}
(loc, Token::Ident(s)) => {
let mut crumbs = vec![s];
let mut type_args = Vec::new();
while maybe_want!(self, Token::DColon) {
if let (_, Token::LAngle) = self.look(0) {
type_args = self.parse_type_args()?;
break;
}
crumbs.push(want!(self, Token::Ident(name), *name)?);
}
Ok(Expr::Path(loc, Path(crumbs)))
Ok(Expr::Inst(loc, Path(crumbs), type_args))
}
(loc, Token::KwNil) => {
Ok(Expr::Nil(loc))
Expand Down
4 changes: 2 additions & 2 deletions mpc/src/parse/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub enum BinOp {

#[derive(Clone, Debug)]
pub enum Expr {
Path(SourceLocation, Path),
Inst(SourceLocation, Path, Vec<Ty>),
Nil(SourceLocation),
Bool(SourceLocation, bool),
Int(SourceLocation, usize),
Expand Down Expand Up @@ -110,7 +110,7 @@ impl Expr {
#[allow(dead_code)]
pub fn loc(&self) -> &SourceLocation {
match self {
Expr::Path(loc, _) => loc,
Expr::Inst(loc, _, _) => loc,
Expr::Nil(loc) => loc,
Expr::Bool(loc, _) => loc,
Expr::Int(loc, _) => loc,
Expand Down
47 changes: 30 additions & 17 deletions mpc/src/resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct ResolveCtx<'a> {
parent_id: DefId,

// Local variables
locals: Vec<(IsMut, Option<ResolvedTy>)>,
locals: usize,

// Match bindings
bindings: usize,
Expand All @@ -34,12 +34,12 @@ enum Sym {
Param(usize),
Local(usize),
Binding(usize),
TParam(usize),
TParam(usize)
}

impl<'a> ResolveCtx<'a> {
fn new(repo: &'a Repository, parent_id: DefId) -> Self {
ResolveCtx { repo, parent_id, locals: Vec::new(), bindings: 0, scopes: Vec::new() }
ResolveCtx { repo, parent_id, locals: 0, bindings: 0, scopes: Vec::new() }
}

fn new_generic(repo: &'a Repository,
Expand Down Expand Up @@ -120,10 +120,7 @@ impl<'a> ResolveCtx<'a> {
Double(loc) => ResolvedTy::Double(loc.clone()),
Inst(loc, path, type_args) => {
// Resolve type arguments
let type_args = type_args
.iter()
.map(|ty| self.resolve_ty(ty))
.monadic_collect()?;
let type_args = self.resolve_ty_args(type_args)?;

// Resolve path
match self.lookup(loc.clone(), path)? {
Expand Down Expand Up @@ -165,6 +162,13 @@ impl<'a> ResolveCtx<'a> {
})
}

fn resolve_ty_args(&mut self, ty_args: &Vec<parse::Ty>) -> Result<Vec<ResolvedTy>, CompileError> {
ty_args
.iter()
.map(|ty| self.resolve_ty(ty))
.monadic_collect()
}

fn resolve_params(&mut self, params: &Vec<(RefStr, parse::Ty)>) -> Result<Vec<(RefStr, ResolvedTy)>, CompileError> {
params
.iter()
Expand All @@ -176,7 +180,7 @@ impl<'a> ResolveCtx<'a> {
use parse::Expr::*;

Ok(match expr {
Path(loc, path) => {
Inst(loc, path, type_args) => {
match self.lookup(loc.clone(), path)? {
Sym::Def(def_id) => match self.repo.parsed_by_id(def_id) {
parse::Def::Const(..) => {
Expand All @@ -192,10 +196,15 @@ impl<'a> ResolveCtx<'a> {
ResolvedExpr::ExternFuncRef(loc.clone(), def_id)
}
parse::Def::Func(..) => {
ResolvedExpr::FuncRef(loc.clone(), def_id)
ResolvedExpr::FuncRef(loc.clone(),
def_id,
self.resolve_ty_args(type_args)?)
}
parse::Def::Variant(def) => {
ResolvedExpr::UnitVariantLit(loc.clone(), def.parent_enum, def.variant_index)
ResolvedExpr::UnitVariantLit(loc.clone(),
def.parent_enum,
self.resolve_ty_args(type_args)?,
def.variant_index)
}
_ => Err(CompileError::InvalidValueName(loc.clone(), path.clone()))?
}
Expand Down Expand Up @@ -250,17 +259,21 @@ impl<'a> ResolveCtx<'a> {

loop {
// Check for aggregate constructor
if let Path(_, path) = &**called {
if let Inst(_, path, type_args) = &**called {
match self.lookup(loc.clone(), path)? {
Sym::Def(def_id) => match self.repo.parsed_by_id(def_id) {
parse::Def::Type(..) => { todo!() }
parse::Def::Struct(..) => {
break ResolvedExpr::StructLit(loc.clone(), def_id, args);
break ResolvedExpr::StructLit(loc.clone(),
def_id,
self.resolve_ty_args(type_args)?,
args);
}
parse::Def::Union(..) if args.len() == 1 => {
let (name, val) = args.into_iter().nth(0).unwrap();
break ResolvedExpr::UnionLit(loc.clone(),
def_id,
self.resolve_ty_args(type_args)?,
name,
Box::new(val));
}
Expand All @@ -270,6 +283,7 @@ impl<'a> ResolveCtx<'a> {
parse::Def::Variant(def) => {
break ResolvedExpr::StructVariantLit(loc.clone(),
def.parent_enum,
self.resolve_ty_args(type_args)?,
def.variant_index,
args);
}
Expand Down Expand Up @@ -359,11 +373,11 @@ impl<'a> ResolveCtx<'a> {
None
};

let index = self.locals.len();
self.locals.push((*is_mut, ty));
let index = self.locals;
self.define(*name, Sym::Local(index));
self.locals += 1;

ResolvedExpr::Let(loc.clone(), index, init)
ResolvedExpr::Let(loc.clone(), index, is_mut.clone(), ty, init)
}
If(loc, cond, tbody, ebody) => {
let cond = self.resolve_expr(cond)?;
Expand Down Expand Up @@ -503,8 +517,7 @@ pub fn resolve_defs(repo: &mut Repository) -> Result<(), CompileError> {
Ok((*name, *is_mut, ctx.resolve_ty(ty)?)))
.monadic_collect()?,
ret_ty: ctx.resolve_ty(&def.ret_ty)?,
body: ctx.resolve_expr(&def.body)?,
locals: ctx.locals,
body: ctx.resolve_expr(&def.body)?
}));
}
parse::Def::ExternData(def) => {
Expand Down
25 changes: 12 additions & 13 deletions mpc/src/resolve/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ pub enum ResolvedExpr {
Unit(SourceLocation),
TupleLit(SourceLocation, Vec<(RefStr, ResolvedExpr)>),
ArrayLit(SourceLocation, Vec<ResolvedExpr>),
StructLit(SourceLocation, DefId, Vec<(RefStr, ResolvedExpr)>),
UnionLit(SourceLocation, DefId, RefStr, Box<ResolvedExpr>),
UnitVariantLit(SourceLocation, DefId, usize),
StructVariantLit(SourceLocation, DefId, usize, Vec<(RefStr, ResolvedExpr)>),
StructLit(SourceLocation, DefId, Vec<ResolvedTy>, Vec<(RefStr, ResolvedExpr)>),
UnionLit(SourceLocation, DefId, Vec<ResolvedTy>, RefStr, Box<ResolvedExpr>),
UnitVariantLit(SourceLocation, DefId, Vec<ResolvedTy>, usize),
StructVariantLit(SourceLocation, DefId, Vec<ResolvedTy>, usize, Vec<(RefStr, ResolvedExpr)>),

// References
FuncRef(SourceLocation, DefId),
FuncRef(SourceLocation, DefId, Vec<ResolvedTy>),
ExternFuncRef(SourceLocation, DefId),
ConstRef(SourceLocation, DefId),
DataRef(SourceLocation, DefId),
Expand All @@ -78,7 +78,7 @@ pub enum ResolvedExpr {
Continue(SourceLocation),
Break(SourceLocation, Box<ResolvedExpr>),
Return(SourceLocation, Box<ResolvedExpr>),
Let(SourceLocation, usize, Option<Box<ResolvedExpr>>),
Let(SourceLocation, usize, IsMut, Option<ResolvedTy>, Option<Box<ResolvedExpr>>),
If(SourceLocation, Box<ResolvedExpr>, Box<ResolvedExpr>, Box<ResolvedExpr>),
While(SourceLocation, Box<ResolvedExpr>, Box<ResolvedExpr>),
Loop(SourceLocation, Box<ResolvedExpr>),
Expand Down Expand Up @@ -118,19 +118,19 @@ impl ResolvedExpr {
ResolvedExpr::Match(loc, _, _) => loc,
ResolvedExpr::TupleLit(loc, _) => loc,
ResolvedExpr::ArrayLit(loc, _) => loc,
ResolvedExpr::StructLit(loc, _, _) => loc,
ResolvedExpr::UnionLit(loc, _, _, _) => loc,
ResolvedExpr::UnitVariantLit(loc, _, _) => loc,
ResolvedExpr::StructVariantLit(loc, _, _, _) => loc,
ResolvedExpr::FuncRef(loc, _) => loc,
ResolvedExpr::StructLit(loc, _, _, _) => loc,
ResolvedExpr::UnionLit(loc, _, _, _, _) => loc,
ResolvedExpr::UnitVariantLit(loc, _, _, _) => loc,
ResolvedExpr::StructVariantLit(loc, _, _, _, _) => loc,
ResolvedExpr::FuncRef(loc, _, _) => loc,
ResolvedExpr::ExternFuncRef(loc, _) => loc,
ResolvedExpr::ConstRef(loc, _) => loc,
ResolvedExpr::DataRef(loc, _) => loc,
ResolvedExpr::ExternDataRef(loc, _) => loc,
ResolvedExpr::ParamRef(loc, _) => loc,
ResolvedExpr::LetRef(loc, _) => loc,
ResolvedExpr::BindingRef(loc, _) => loc,
ResolvedExpr::Let(loc, _, _) => loc,
ResolvedExpr::Let(loc, _, _, _, _) => loc,
}
}
}
Expand Down Expand Up @@ -247,7 +247,6 @@ pub struct ResolvedFuncDef {
pub type_params: usize,
pub params: Vec<(RefStr, IsMut, ResolvedTy)>,
pub ret_ty: ResolvedTy,
pub locals: Vec<(IsMut, Option<ResolvedTy>)>,
pub body: ResolvedExpr,
}

Expand Down
Loading

0 comments on commit 3278d63

Please sign in to comment.