diff --git a/dev/src/idl/mod.rs b/dev/src/idl/mod.rs index cc7f55e1..6533bcde 100644 --- a/dev/src/idl/mod.rs +++ b/dev/src/idl/mod.rs @@ -22,6 +22,8 @@ enum Token { // Tokens can be literal strings, of any length. #[token("type")] Type, + #[token("fn", priority = 5)] + Fn, #[token("enum")] Enum, @@ -56,7 +58,7 @@ enum Token { #[token("->")] RArrow, - #[regex("[a-zA-Z_]+", |lex|{lex.slice().to_string()})] + #[regex("[a-zA-Z_][a-zA-Z_1234567890]+", |lex|{lex.slice().to_string()})] Identifier(String), #[regex("[1234567890]+", |lex|{lex.slice().parse::().unwrap()})] @@ -86,9 +88,6 @@ pub fn build_idl(name: String) { println!("{:#?}", parse(tokens)); } -fn build(a: Vec) { -} - fn open_protocol(name: String) -> String { let path = format!("sysdata/idl/{}/src/protocol.aldi", name); let mut file = std::fs::File::open(path).unwrap(); diff --git a/dev/src/idl/parser.rs b/dev/src/idl/parser.rs index f3cffa31..78ae4a6a 100644 --- a/dev/src/idl/parser.rs +++ b/dev/src/idl/parser.rs @@ -47,7 +47,7 @@ struct ProtocolDeclaration{ #[derive(Debug, Clone, PartialEq)] struct FuncDeclaration { name : String, - input_types : Vec, + arg_list : Vec, return_type : String, } @@ -87,6 +87,7 @@ fn declaration(tokens : &mut Peekable>) -> Option { Token::Enum => Some(enum_decl(tokens)), Token::Struct => Some(struct_decl(tokens)), Token::Type => Some(type_declaration(tokens)), + Token::Protocol => Some(protocol_declaration(tokens)), _ => None, } } @@ -214,3 +215,60 @@ fn parse_number(tokens : &mut Peekable>) -> Option { result } +fn protocol_declaration(tokens : &mut Peekable>) -> Declaration { + consume(tokens, Token::Protocol); + let name = identifier(tokens).expect("Expected Identifier after `protocol`"); + consume(tokens, Token::LBrace); + let mut interface = Vec::new(); + match tokens.peek().expect("Unexpected EOF after LBrace") { + Token::RBrace => {}, + _ => { + functions(tokens, &mut interface); + }, + }; + Declaration::ProtocolDeclaration(ProtocolDeclaration{name, interface}) +} + +fn functions(tokens : &mut Peekable>, interface : &mut Vec) { + loop { + match function(tokens) { + Some(x) => interface.push(x), + None => break, + } + } +} + +fn function(tokens : &mut Peekable>) -> Option{ + if let Some(Token::Fn) = tokens.peek() { + consume(tokens, Token::Fn); + let name = identifier(tokens).expect("Expected Identifier after `fn`"); + consume(tokens, Token::LParen); + let arg_list = arg_list(tokens); + consume(tokens, Token::RParen); + consume(tokens, Token::RArrow); + let return_type = identifier(tokens).expect("Expected return type after `->"); + Some(FuncDeclaration{name, arg_list, return_type}) + } else { + None + } +} + +fn arg_list(tokens : &mut Peekable>) -> Vec { + let mut result = Vec::new(); + loop { + match identifier(tokens) { + None => break, + Some(i) =>{ + result.push(i); + if **tokens.peek().expect("Unexpected EOF in argument list") == Token::Comma{ + consume(tokens, Token::Comma); + match tokens.peek().expect("Unexpected EOF in argument list") { + Token::Identifier(_) => {}, + _ => panic!("Unexpected symbol after Comma in argument list"), + } + } + } + } + } + result +}