Skip to content

Commit

Permalink
Update fun sigs, in prep for new assoc fn syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
osa1 committed Jan 22, 2025
1 parent 33c03d1 commit b050cb3
Show file tree
Hide file tree
Showing 7 changed files with 12,214 additions and 10,740 deletions.
23 changes: 20 additions & 3 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ pub struct FunSig {
/// The bound can refer to assocaited types, e.g. `[A, I: Iterator[Item = A]]`.
pub type_params: Context,

/// Whether the function has a `self` parameter.
pub self_: bool,
/// `self` parameter of the function.
pub self_: SelfParam,

/// Parameters of the function.
pub params: Vec<(Id, L<Type>)>,
Expand All @@ -250,6 +250,18 @@ pub struct FunSig {
pub exceptions: Option<L<Type>>,
}

#[derive(Debug, Clone)]
pub enum SelfParam {
/// Function signature doesn't have a `self` type.
No,

/// Function signature has a `self` parameter, but without type signature.
Inferred,

/// Function signature has a `self` parameter with explicit type signature.
Explicit(L<Type>),
}

#[derive(Debug, Clone)]
pub struct FunDecl {
pub name: L<Id>,
Expand All @@ -259,7 +271,12 @@ pub struct FunDecl {

impl FunDecl {
pub fn num_params(&self) -> u32 {
self.sig.params.len() as u32 + if self.sig.self_ { 1 } else { 0 }
self.sig.params.len() as u32
+ if !matches!(&self.sig.self_, SelfParam::No) {
1
} else {
0
}
}
}

Expand Down
18 changes: 14 additions & 4 deletions src/ast/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,20 @@ impl FunSig {
buffer.push(']');
}
buffer.push('(');
if self.self_ {
buffer.push_str("self");
if !self.params.is_empty() {
buffer.push_str(", ");
match &self.self_ {
SelfParam::No => {}
SelfParam::Inferred => {
buffer.push_str("self");
if !self.params.is_empty() {
buffer.push_str(", ");
}
}
SelfParam::Explicit(ty) => {
buffer.push_str("self: ");
ty.node.print(buffer);
if !self.params.is_empty() {
buffer.push_str(", ");
}
}
}
for (i, (param_name, param_ty)) in self.params.iter().enumerate() {
Expand Down
2 changes: 1 addition & 1 deletion src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ fn call_ast_fun<W: Write>(
let mut locals: Map<Id, u64> = Default::default();

let mut arg_idx: usize = 0;
if fun.sig.self_ {
if !matches!(fun.sig.self_, ast::SelfParam::No) {
locals.insert(Id::new("self"), args[0]);
arg_idx += 1;
}
Expand Down
1 change: 0 additions & 1 deletion src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ lexgen::lexer! {
"match" = TokenKind::Match,
"prim" = TokenKind::Prim,
"return" = TokenKind::Return, // maybe shorten as "ret"?
"self" = TokenKind::Self_,
"trait" = TokenKind::Trait,
"type" = TokenKind::Type,
"var" = TokenKind::Var,
Expand Down
61 changes: 43 additions & 18 deletions src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ extern {
"else" => Token { kind: TokenKind::Else, .. },
"elif" => Token { kind: TokenKind::Elif, .. },
"match" => Token { kind: TokenKind::Match, .. },
"self" => Token { kind: TokenKind::Self_, .. },
"for" => Token { kind: TokenKind::For, .. },
"while" => Token { kind: TokenKind::While, .. },
"in" => Token { kind: TokenKind::In, .. },
Expand Down Expand Up @@ -297,31 +296,56 @@ FunDecl: L<FunDecl> = {
}

FunSig: (L<Id>, FunSig) = {
<name:LLowerId>
<type_params:Context>
"(" <self_:("self" ","?)?> <params:Sep<(<LowerId> ":" <LType>), ",">> ")"
<ret:ReturnType>
=>
<l:@L> <name:LLowerId> <type_params:Context> "(" <params:Params> ")" <ret:ReturnType> => {
let mut self_: SelfParam = SelfParam::No;
let mut params_w_tys: Vec<(Id, L<Type>)> = Vec::with_capacity(params.len());
for (i, (param_id, param_ty)) in params.into_iter().enumerate() {
if param_id == "self" {
if i != 0 {
panic!("{}:{}:{}: \"self\" argument needs to come first in the prameter list", module, l.line + 1, l.col + 1);
}
self_ = match param_ty {
None => SelfParam::Inferred,
Some(ty) => SelfParam::Explicit(ty),
};
} else {
match param_ty {
None => {
panic!("{}:{}:{}: Parameter {} needs a type signature", module, l.line + 1, l.col + 1, i);
}
Some(param_ty) => {
params_w_tys.push((param_id, param_ty));
}
}
}
}
(name,
FunSig {
type_params,
self_: self_.is_some(),
params: params.into_iter().map(|(name, ty)| (name.smol_str(), ty)).collect(),
self_,
params: params_w_tys,
exceptions: ret.0,
return_ty: ret.1,
}),
})
},

<name:LLowerId> <type_params:Context> <ret:ReturnType> =>
(name,
FunSig {
type_params,
self_: false,
self_: SelfParam::No,
params: vec![],
exceptions: ret.0,
return_ty: ret.1,
})
}

Params: Vec<(Id, Option<L<Type>>)> = {
<params:Sep<(<LowerId> <(":" <LType>)?>), ",">> => {
params.into_iter().map(|(id, ty)| (id.smol_str(), ty)).collect()
},
}

ReturnType: (Option<L<Type>>, Option<L<Type>>) = {
=> (None, None),

Expand Down Expand Up @@ -471,11 +495,12 @@ LInlineExpr: L<Expr> = {
// Inline expressions can be made statements with a NEWLINE after them.
InlineExpr: Expr = {
#[precedence(level = "0")]
"self" =>
Expr::Self_,

<id:LowerId> =>
Expr::Var(VarExpr { id: id.smol_str(), ty_args: vec![] }),
if id.smol_str() == "self" {
Expr::Self_
} else {
Expr::Var(VarExpr { id: id.smol_str(), ty_args: vec![] })
},

<id:UpperId> =>
Expr::Constr(ConstrExpr { id: id.smol_str(), ty_args: vec![] }),
Expand Down Expand Up @@ -805,7 +830,7 @@ InlineExpr: Expr = {
Expr::Fn(FnExpr {
sig: FunSig {
type_params: vec![],
self_: false,
self_: SelfParam::No,
params: params.into_iter().map(|(name, ty)| (name.smol_str(), ty)).collect(),
exceptions: ret.0,
return_ty: ret.1,
Expand All @@ -819,7 +844,7 @@ InlineExpr: Expr = {
Expr::Fn(FnExpr {
sig: FunSig {
type_params: vec![],
self_: false,
self_: SelfParam::No,
params: params.into_iter().map(|(name, ty)| (name.smol_str(), ty)).collect(),
exceptions: ret.0,
return_ty: ret.1,
Expand All @@ -832,7 +857,7 @@ InlineExpr: Expr = {
Expr::Fn(FnExpr {
sig: FunSig {
type_params: vec![],
self_: false,
self_: SelfParam::No,
params: vec![],
exceptions: None,
return_ty: None,
Expand All @@ -845,7 +870,7 @@ InlineExpr: Expr = {
Expr::Fn(FnExpr {
sig: FunSig {
type_params: vec![],
self_: false,
self_: SelfParam::No,
params: vec![],
exceptions: None,
return_ty: None,
Expand Down
Loading

0 comments on commit b050cb3

Please sign in to comment.