From d97b3e3636ee4b9baca203546f68fdf3054e440a Mon Sep 17 00:00:00 2001 From: nothendev Date: Sat, 6 May 2023 18:57:45 +0300 Subject: [PATCH] aaaaaaa --- Cargo.lock | 16 +++ programs/aidl/Cargo.toml | 1 + programs/aidl/SPEC.md | 10 +- programs/aidl/assets/core.idl | 15 ++- programs/aidl/assets/core.rs | 21 ++++ programs/aidl/assets/libaidl_core.rlib | Bin 0 -> 27722 bytes programs/aidl/assets/libaidl_vfs.rlib | Bin 0 -> 8762 bytes programs/aidl/assets/moves.idl | 6 ++ programs/aidl/assets/vfs.idl | 22 ++-- programs/aidl/assets/vfs.rs | 26 +++++ programs/aidl/assets/why.idl | 17 ++-- programs/aidl/src/ast.rs | 3 +- programs/aidl/src/codegen.rs | 130 +++++++++++++++++++++++- programs/aidl/src/lexer.rs | 3 + programs/aidl/src/main.rs | 32 ++++-- programs/aidl/src/parser/enumeration.rs | 24 +++-- programs/aidl/src/parser/expr.rs | 8 +- programs/aidl/src/parser/interface.rs | 12 ++- programs/aidl/src/parser/mod.rs | 57 ++++------- programs/aidl/src/parser/structure.rs | 8 +- programs/aidl/src/parser/types.rs | 14 ++- 21 files changed, 319 insertions(+), 106 deletions(-) create mode 100644 programs/aidl/assets/core.rs create mode 100644 programs/aidl/assets/libaidl_core.rlib create mode 100644 programs/aidl/assets/libaidl_vfs.rlib create mode 100644 programs/aidl/assets/moves.idl create mode 100644 programs/aidl/assets/vfs.rs diff --git a/Cargo.lock b/Cargo.lock index 24b26cc..17acdf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,6 +37,7 @@ version = "0.1.0" dependencies = [ "codespan-reporting", "derive_more", + "itertools", "logos", "proc-macro2", "quote", @@ -174,6 +175,12 @@ dependencies = [ "syn 1.0.105", ] +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + [[package]] name = "fnv" version = "1.0.7" @@ -229,6 +236,15 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "libc" version = "0.2.138" diff --git a/programs/aidl/Cargo.toml b/programs/aidl/Cargo.toml index 75503f4..265768f 100644 --- a/programs/aidl/Cargo.toml +++ b/programs/aidl/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] codespan-reporting = "0.11.1" derive_more = "0.99.17" +itertools = "0.10.5" logos = "0" proc-macro2 = "1.0.56" quote = "1.0.26" diff --git a/programs/aidl/SPEC.md b/programs/aidl/SPEC.md index ae2279a..667a6c1 100644 --- a/programs/aidl/SPEC.md +++ b/programs/aidl/SPEC.md @@ -4,7 +4,7 @@ The example implementation will be in rust IDL | Rust __________ -boolean | bool +Boolean | bool I8 | i8 I16 | i16 I32 | i32 @@ -15,8 +15,8 @@ U32 | u32 U64 | u64 F32 | f32 F64 | f64 -Constant X Y Z | const X: Y = Z; -Type | type +Constant X = Make Y { Z } | const X: Y = Y { Z }; +Alias | type Vector | Vec -Array[X;Y] | [X;Y] -Function X accepts(YX) returns(ZX) | fn X(YX) -> ZX +Array | [X; Y] +Function X Takes(YX) Returns(ZX) | fn X(YX) -> ZX diff --git a/programs/aidl/assets/core.idl b/programs/aidl/assets/core.idl index 330598f..58b42e6 100644 --- a/programs/aidl/assets/core.idl +++ b/programs/aidl/assets/core.idl @@ -1,11 +1,5 @@ -Alias Byte = U8; -Alias Int = U32; -Alias String = Vector; - -Enumeration Boolean { - False = 0, - True = 1, -} +Alias Byte = u8; +Alias Int = u32; Enumeration Nothing {} @@ -14,6 +8,11 @@ Enumeration Option { Some(T) } +Enumeration Result { + Ok(T), + Err(E) +} + Structure Version { major: Byte, minor: Byte, diff --git a/programs/aidl/assets/core.rs b/programs/aidl/assets/core.rs new file mode 100644 index 0000000..cfa749c --- /dev/null +++ b/programs/aidl/assets/core.rs @@ -0,0 +1,21 @@ +#![crate_name = "aidl_core"] +#![crate_type = "rlib"] +#![no_implicit_prelude] + +extern crate core as rust_core; +extern crate alloc as rust_alloc; + +pub use self::rust_core::{option::Option, result::Result}; +pub use self::rust_alloc::{vec::Vec as Vector, string::String}; + +pub type Nothing = (); + +pub type Byte = u8; +pub type Int = u32; + +#[derive(Debug, Clone, Copy)] +pub struct Version { + pub major: Byte, + pub minor: Byte, + pub patch: Byte +} diff --git a/programs/aidl/assets/libaidl_core.rlib b/programs/aidl/assets/libaidl_core.rlib new file mode 100644 index 0000000000000000000000000000000000000000..a746cf8cb1c678e01922d54b5a5f1a050e552d7b GIT binary patch literal 27722 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 WM}@xe@pDYrN318o3=ocgO#c93{i$#O literal 0 HcmV?d00001 diff --git a/programs/aidl/assets/moves.idl b/programs/aidl/assets/moves.idl new file mode 100644 index 0000000..c4cc5b9 --- /dev/null +++ b/programs/aidl/assets/moves.idl @@ -0,0 +1,6 @@ +Interface Thing { + Function moves Takes(Move Self) Returns(Self); + + Function immut_ref Takes(Reference Self); + Function mut_ref Takes(Mutable Reference Self); +} diff --git a/programs/aidl/assets/vfs.idl b/programs/aidl/assets/vfs.idl index 10d0a51..80602bf 100644 --- a/programs/aidl/assets/vfs.idl +++ b/programs/aidl/assets/vfs.idl @@ -1,24 +1,26 @@ +Module vfs; // core provides lots of useful types like String and Byte -Use core; +Use core.Version; +Use core.Vector; +Use core.String; Constant VERSION = Make Version { - major: 1, - minor: 0, - patch: 0, + major: 1, + minor: 0, + patch: 0, }; Alias Path = String; Structure File { - name: String, - data: Vector, + name: String, + data: Vector, } Interface File { - Function new Takes(Path) Returns(None); + Function create Takes(Path) Returns(Nothing); - // Open in this iteration assumes the file exists - Function open Takes(Path) Returns(File); + Function open Takes(Path) Returns(File); - Function close Takes(File) Returns(None); + Function close Takes(File) Returns(Nothing); } diff --git a/programs/aidl/assets/vfs.rs b/programs/aidl/assets/vfs.rs new file mode 100644 index 0000000..285f0c5 --- /dev/null +++ b/programs/aidl/assets/vfs.rs @@ -0,0 +1,26 @@ +#![crate_name = "aidl_vfs"] +#![crate_type = "rlib"] +#![no_implicit_prelude] +extern crate aidl_core; + +use aidl_core::{Vector, Version, String}; + +pub const VERSION: Version = Version { + major: 1, + minor: 0, + patch: 0, +}; + +pub type Path = String; + +pub struct FFile { + pub name: String +} + +pub trait File { + fn fields(&self) -> &FFile; + fn fields_mut(&mut self) -> &mut FFile; + fn into_fields(self) -> FFile where Self: Sized; + + fn new(path: Path) -> Self; +} diff --git a/programs/aidl/assets/why.idl b/programs/aidl/assets/why.idl index e39c329..bc0a408 100644 --- a/programs/aidl/assets/why.idl +++ b/programs/aidl/assets/why.idl @@ -5,25 +5,24 @@ Constant Hi = "WHY???/\n"; Alias Yo = Byte; Constant Version = Make Version { - major: 1 - minor: 0 - patch: 0 + major: 1, minor: 0, patch: 0 }; Interface Iface { - Function hello Takes(Int Boolean) Returns(Int); + Function hello Takes(Int, Boolean,) Returns(Int); } Function a_free_function Returns(Boolean); Structure Hello { - world: Boolean prompt: Option + world: Boolean, + prompt: Option, } Enumeration Reality { - Dead(Boolean Boolean), + Dead(Boolean, Boolean), Alive { - health: Int - dying: Boolean - } + health: Int, + dying: Boolean, + }, } diff --git a/programs/aidl/src/ast.rs b/programs/aidl/src/ast.rs index 3ffa60d..e198e2e 100644 --- a/programs/aidl/src/ast.rs +++ b/programs/aidl/src/ast.rs @@ -9,6 +9,7 @@ use std::collections::HashMap; /// - items #[derive(Debug)] pub struct IDLModule { + pub name: String, // why: only allow use before other items // parser will error if use is present in any other place pub uses: Vec, @@ -121,7 +122,7 @@ pub enum EnumerationContent { #[derive(Debug)] pub struct UseDecl { - pub module: ModulePath, + pub path: (String, Option) } #[derive(Debug)] diff --git a/programs/aidl/src/codegen.rs b/programs/aidl/src/codegen.rs index 6baf426..4392027 100644 --- a/programs/aidl/src/codegen.rs +++ b/programs/aidl/src/codegen.rs @@ -1,10 +1,130 @@ -use std::path::Path; +use std::default::default; -use crate::ast::IDLModule; +use crate::{ast::{IDLModule, ItemInterface, TypeArguments, Type}, unwrap_match}; -use proc_macro2::{TokenStream, Ident, Span}; -use quote::quote; +use itertools::Itertools; +use proc_macro2::{Ident, Span, TokenStream}; +use quote::{quote, ToTokens}; +use syn::{Attribute, ItemExternCrate, ItemTrait, ItemUse, LitStr, Meta, Path, UsePath, Generics, punctuated::Punctuated, TypeArray, LitInt}; + +fn attr_inner(meta: Meta) -> Attribute { + Attribute { + pound_token: default(), + style: syn::AttrStyle::Inner(default()), + bracket_token: default(), + meta, + } +} + +fn attr_just(name: &'static str) -> Attribute { + attr_inner(Meta::Path(Path::from(Ident::new(name, Span::call_site())))) +} + +fn attr_inner_eq(name: &'static str, expr: &str) -> Attribute { + attr_inner(Meta::NameValue(syn::MetaNameValue { + path: Path::from(Ident::new(name, Span::call_site())), + eq_token: default(), + value: syn::Expr::Lit(syn::ExprLit { + attrs: vec![], + lit: syn::Lit::Str(LitStr::new(expr, Span::call_site())), + }), + })) +} + +fn extern_crate(name: &str) -> ItemExternCrate { + ItemExternCrate { + attrs: vec![], + vis: syn::Visibility::Inherited, + extern_token: default(), + crate_token: default(), + ident: Ident::new(name, Span::call_site()), + rename: None, + semi_token: default(), + } +} + +fn make_use(a: &str, b: &str) -> ItemUse { + ItemUse { + attrs: vec![], + vis: syn::Visibility::Inherited, + use_token: default(), + tree: syn::UseTree::Path(UsePath { + tree: Box::new(syn::UseTree::Name(syn::UseName { + ident: Ident::new(b, Span::call_site()), + })), + ident: Ident::new(a, Span::call_site()), + colon2_token: default(), + }), + semi_token: default(), + leading_colon: None, + } +} + +fn _gen_type(ty: Type) -> syn::Type { + fn make_array(mut args: Vec>) -> TypeArray { + let box arity = args.pop().unwrap(); + let box real = args.pop().unwrap(); + + drop(args); + + TypeArray { bracket_token: default(), elem: Box::new(gen_type(real)), semi_token: default(), len: syn::Expr::Lit(syn::ExprLit { attrs: vec![], lit: syn::Lit::Int(LitInt::new(&arity.name, Span::call_site())) }) } + } + match ty.name.as_str() { + "Array" => syn::Type::Array(make_array(unwrap_match!(ty.arguments, TypeArguments::AngleBracketed(angle) => angle))), + name => syn::Type::Path(syn::TypePath { qself: None, path: Path::from(Ident::new(name, Span::call_site())) }) + } +} + +// fn gen_iface(interface: ItemInterface) -> ItemTrait { +// ItemTrait { +// attrs: default(), +// vis: syn::Visibility::Public(default()), +// unsafety: None, +// auto_token: None, +// restriction: None, +// trait_token: default(), +// ident: Ident::new(&interface.name, Span::call_site()), +// generics: , +// colon_token: (), +// supertraits: (), +// brace_token: (), +// items: (), +// } +// } pub fn generate(module: IDLModule) -> TokenStream { - quote! {} + let name = String::from("aidl_") + &module.name; + let attrs: TokenStream = [ + attr_inner_eq("crate_name", &name), + attr_inner_eq("crate_type", "rlib"), + attr_just("no_implicit_prelude"), + ] + .into_iter() + .map(ToTokens::into_token_stream) + .collect(); + let uses: Vec<_> = module + .uses + .into_iter() + .map(|a| a.path) + .map(|(a, b)| (String::from("aidl_") + &a, b)) // aidl_core.Something + .collect(); + let extern_crates: TokenStream = uses + .iter() + .map(|(a, _)| a.as_str()) + .unique() + .map(extern_crate) + .map(ToTokens::into_token_stream) + .collect(); + let use_defs: TokenStream = uses + .iter() + .filter_map(|(ref a, ref b)| b.as_ref().map(|b| make_use(a.as_str(), b.as_str()))) + .map(ToTokens::into_token_stream) + .collect(); + + quote! { + #attrs + + #extern_crates + #use_defs + } } diff --git a/programs/aidl/src/lexer.rs b/programs/aidl/src/lexer.rs index 1fa8e9e..2d45b80 100644 --- a/programs/aidl/src/lexer.rs +++ b/programs/aidl/src/lexer.rs @@ -83,6 +83,9 @@ pub enum Token { #[derive(Logos, Debug, Clone, PartialEq, Eq, derive_more::Display)] pub enum Ident { + #[token("Module")] + #[display(fmt = "Module")] + Module, #[token("Interface")] #[display(fmt = "Interface")] Interface, diff --git a/programs/aidl/src/main.rs b/programs/aidl/src/main.rs index 0000eaf..765db7d 100644 --- a/programs/aidl/src/main.rs +++ b/programs/aidl/src/main.rs @@ -1,29 +1,30 @@ #![feature(result_option_inspect)] +#![feature(box_patterns)] +#![feature(default_free_fn)] #![allow(non_snake_case)] use std::{fmt::Display, path::Path, process::exit}; +use ast::IDLModule; +use codegen::generate; use codespan_reporting::{ diagnostic::{Diagnostic, Label, Severity}, files::SimpleFile, term::{ emit, - termcolor::{ColorSpec, StandardStream, StandardStreamLock}, - Config, Styles, + termcolor::{StandardStream, StandardStreamLock}, + Config, }, }; use lexer::{NumberSuffix, Token}; -use logos::Logos; use parser::TokenIterator; use crate::lexer::Spanned; mod ast; +mod codegen; mod lexer; mod parser; -mod codegen; - -//const TEST: &str = include_str!("../assets/why.idl"); fn precheck>( writer: &mut StandardStreamLock<'_>, @@ -68,10 +69,10 @@ fn precheck>( Diagnostic::warning() .with_message("Potentially invalid use of an uppercased number type") .with_labels(vec![Label::primary((), span.0)]) - .with_notes(vec![format!( - "Replace {ident} with {}", - ident.to_lowercase() - ), "Code generation might fail".into()]), + .with_notes(vec![ + format!("Replace {ident} with {}", ident.to_lowercase()), + "Code generation might fail".into(), + ]), ); } _ => {} @@ -98,6 +99,9 @@ fn precheck>( fn main() { let mut args = std::env::args(); args.next().unwrap(); + + let mut ast: Option = None; + if let Some(file) = args.next() { let path = Path::new(&file); let codespan_file = codespan_reporting::files::SimpleFile::new( @@ -113,7 +117,10 @@ fn main() { precheck(&mut writer.lock(), &config, &codespan_file); match parser::parse(codespan_file.source()) { - Ok(ast) => println!("{:#?}", ast), + Ok(ast_) => { + println!("{:#?}", ast_); + ast = Some(ast_); + } Err(e) => { let msg = e.to_string(); let label = match e { @@ -145,6 +152,9 @@ fn main() { } else { eprintln!("No file given. Aborting."); } + + let rust = generate(ast.unwrap()); + println!("{}", rust); } #[macro_export] diff --git a/programs/aidl/src/parser/enumeration.rs b/programs/aidl/src/parser/enumeration.rs index c6d728c..65f0c33 100644 --- a/programs/aidl/src/parser/enumeration.rs +++ b/programs/aidl/src/parser/enumeration.rs @@ -41,8 +41,12 @@ impl<'a> Parser<'a> { match self.tokens.peek()?.0 { Token::Ident(Ident::Other(_)) => { tuple.push(self.ask_type()?.0); - if let Token::Comma = self.tokens.peek()?.0 { - self.eat(); + match self.tokens.peek()?.0 { + Token::Comma => { + self.eat(); + } + Token::RightParen => {} + _ => return Err(self.expected("a comma or closing parentheses")), }; } Token::RightParen => { @@ -74,8 +78,12 @@ impl<'a> Parser<'a> { )?; structure.insert(field_name, self.ask_type()?.0); - if let Token::Comma = self.tokens.peek()?.0 { - self.eat(); + match self.tokens.peek()?.0 { + Token::Comma => { + self.eat(); + } + Token::RightCurly => {} + _ => return Err(self.expected("a comma or closing curly braces")), }; } Token::RightCurly => { @@ -101,8 +109,12 @@ impl<'a> Parser<'a> { } } - if let Spanned(Token::Comma, _) = self.tokens.peek()? { - self.eat(); + match self.tokens.peek()?.0 { + Token::Comma => { + self.eat(); + } + Token::RightCurly => {} + _ => return Err(self.expected("a comma or closing curly braces")), } variants.push(EnumerationVariant { diff --git a/programs/aidl/src/parser/expr.rs b/programs/aidl/src/parser/expr.rs index ff2632c..b63bd2c 100644 --- a/programs/aidl/src/parser/expr.rs +++ b/programs/aidl/src/parser/expr.rs @@ -83,9 +83,11 @@ impl<'a> Parser<'a> { self.get_real(|token| matches!(token, Token::Colon), "a colon")?; let Spanned(value, _) = self.ask_expr()?; params.insert(ident, value); - if let Token::Comma = self.tokens.peek()?.0 { - self.eat(); - }; + match self.tokens.peek()?.0 { + Token::Comma => self.eat(), + Token::RightCurly => {}, + _ => return Err(self.expected("a comma or a closing curly brace")) + } } Token::RightCurly => break, _ => return Err(self.expected("an identifier or a closing curly brace (`}`)")), diff --git a/programs/aidl/src/parser/interface.rs b/programs/aidl/src/parser/interface.rs index 651ad18..8f3582d 100644 --- a/programs/aidl/src/parser/interface.rs +++ b/programs/aidl/src/parser/interface.rs @@ -61,8 +61,12 @@ impl<'a> Parser<'a> { match peeked { Token::Ident(_) => { takes.push(self.ask_type()?.0); - if let Token::Comma = self.tokens.peek()?.0 { - self.eat(); + match self.tokens.peek()?.0 { + Token::Comma => { + self.eat(); + } + Token::RightParen => {} + _ => return Err(self.expected("a comma or closing parentheses")), }; } Token::RightParen => { @@ -78,7 +82,7 @@ impl<'a> Parser<'a> { Token::Ident(Ident::Returns) => { self.get_real( |token| matches!(token, Token::LeftParen), - "Opening parentheses", + "opening parentheses", )?; let Spanned(returns_, _) = self.ask_type()?; @@ -87,7 +91,7 @@ impl<'a> Parser<'a> { self.get_real( |token| matches!(token, Token::RightParen), - "Closing parentheses", + "closing parentheses", )?; self.semi()?; diff --git a/programs/aidl/src/parser/mod.rs b/programs/aidl/src/parser/mod.rs index a1f0b0a..373316e 100644 --- a/programs/aidl/src/parser/mod.rs +++ b/programs/aidl/src/parser/mod.rs @@ -7,7 +7,7 @@ mod types; use logos::{Lexer, Logos}; use crate::{ - ast::{IDLModule, Item, ItemAlias, ItemConstant, ModulePath, UseDecl}, + ast::{IDLModule, Item, ItemAlias, ItemConstant, UseDecl}, lexer::{Ident, Span, Spanned, Token}, }; use std::iter::Iterator; @@ -118,41 +118,6 @@ impl<'a> Parser<'a> { ) } - fn ask_modpath( - &mut self, - end: impl Fn(&Token) -> bool, - ) -> Result, ParserError> { - let mut segments = vec![]; - let mut in_path_seg = false; - let mut waiting_next_seg = true; - let mut span = Span::ZERO; - - loop { - match self.tokens.next()? { - Spanned(Token::Ident(Ident::Other(ident)), span_span) - if !in_path_seg && waiting_next_seg => - { - span += span_span; - segments.push(ident); - in_path_seg = true; - waiting_next_seg = false; - } - Spanned(Token::Dot, span_span) if in_path_seg && !waiting_next_seg => { - span += span_span; - waiting_next_seg = true; - in_path_seg = false; - } - v if end(&v.0) && (in_path_seg || !waiting_next_seg) => { - span += v.1; - break; - } - _ => return Err(self.expected("a path segment")), - } - } - - Ok(Spanned(ModulePath { segments }, span)) - } - fn ask_alias(&mut self) -> Result, ParserError> { let Spanned(_, kSp) = self.get_real( |token| matches!(token, Token::Ident(Ident::Alias)), @@ -203,19 +168,33 @@ impl<'a> Parser<'a> { } fn ask_use(&mut self) -> Result, ParserError> { - let Spanned(_, kSp) = { + let Spanned(_, span) = { match self.tokens.peek()? { Spanned(Token::Ident(Ident::Use), _) => Ok(self.tokens.next()?), _ => Err(ParserError::PleaseStopParsingUse), } }?; - let Spanned(module, nSp) = self.ask_modpath(|token| matches!(token, Token::Semicolon))?; + let mut path = (self.ask_ident()?.0, None); - Ok(Spanned::new(UseDecl { module }, [kSp, nSp])) + if let Token::Dot = self.tokens.peek()?.0 { + self.eat(); + path.1 = Some(self.ask_ident()?.0); + } + + Ok(Spanned::new(UseDecl { path }, [span, self.semi()?])) } pub fn parse(mut self) -> Result { Ok(IDLModule { + name: { + self.get_real( + |token| matches!(token, Token::Ident(Ident::Module)), + "the `Module` keyword", + )?; + let name = self.ask_ident()?.0; + self.semi()?; + name + }, uses: { let mut real = vec![]; loop { diff --git a/programs/aidl/src/parser/structure.rs b/programs/aidl/src/parser/structure.rs index 14a82fa..0b36536 100644 --- a/programs/aidl/src/parser/structure.rs +++ b/programs/aidl/src/parser/structure.rs @@ -29,8 +29,12 @@ impl<'a> Parser<'a> { self.get_real(|token| matches!(token, Token::Colon), "a colon")?; let Spanned(value, _) = self.ask_type()?; fields.insert(ident, value); - if let Token::Comma = self.tokens.peek()?.0 { - self.eat(); + match self.tokens.peek()?.0 { + Token::Comma => { + self.eat(); + } + Token::RightCurly => {} + _ => return Err(self.expected("a comma or closing curly braces")), }; } Token::RightCurly => break, diff --git a/programs/aidl/src/parser/types.rs b/programs/aidl/src/parser/types.rs index 5afbefa..da1cf8a 100644 --- a/programs/aidl/src/parser/types.rs +++ b/programs/aidl/src/parser/types.rs @@ -33,14 +33,22 @@ impl<'a> Parser<'a> { args.push(Box::new(self.ask_type()?.0)); - if let Spanned(Token::Comma, _) = self.tokens.peek()? { - self.eat(); // skip comma, allow trailing comma + match self.tokens.peek()?.0 { + Token::Comma => self.eat(), + Token::RightArrow => {} + _ => return Err(self.expected("a comma or closing angle brackets")), }; loop { match self.tokens.peek()? { Spanned(Token::Ident(_) | Token::NumberLiteral(_), _) => { - args.push(Box::new(self.ask_type()?.0)) + args.push(Box::new(self.ask_type()?.0)); + + match self.tokens.peek()?.0 { + Token::Comma => self.eat(), + Token::RightArrow => {} + _ => return Err(self.expected("a comma or closing angle brackets")), + } } Spanned(Token::RightArrow, _) => { self.eat();