diff --git a/examples/reid/easiest.reid b/examples/reid/easiest.reid index dce07b9..fa6f89b 100644 --- a/examples/reid/easiest.reid +++ b/examples/reid/easiest.reid @@ -2,14 +2,19 @@ import std::print; -fn somethingelse() { - return 12; -} - fn main() { let hello = 32 + { - 2 + somethingelse() + 2 + 2 }; - let beep = hello + 5; + let beep = hello + fibonacci(15); return beep; +} + +// Fibonacci + +fn fibonacci(value: i32) -> i32 { + if value < 3 { + return 1; + } + return fibonacci(value - 1) + fibonacci(value - 2); } \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index f7a6c6b..431bdad 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -10,6 +10,24 @@ where fn parse(stream: TokenStream) -> Result; } +#[derive(Debug, Clone)] +pub enum Type { + I32, +} + +impl Parse for Type { + fn parse(mut stream: TokenStream) -> Result { + if let Some(Token::Identifier(ident)) = stream.next() { + Ok(match &*ident { + "i32" => Type::I32, + _ => panic!("asd"), + }) + } else { + Err(stream.expected_err("type identifier")?) + } + } +} + #[derive(Debug, Clone)] pub enum Literal { I32(i32), @@ -187,14 +205,34 @@ impl Parse for FunctionDefinition { #[derive(Debug, Clone)] pub struct FunctionSignature { pub name: String, + pub args: Vec<(String, Type)>, + pub return_type: Option, } impl Parse for FunctionSignature { fn parse(mut stream: TokenStream) -> Result { if let Some(Token::Identifier(name)) = stream.next() { stream.expect(Token::ParenOpen)?; + let mut args = Vec::new(); + + while let Some(Token::Identifier(arg_name)) = stream.peek() { + stream.next(); + stream.expect(Token::Colon)?; + args.push((arg_name, stream.parse()?)); + } + stream.expect(Token::ParenClose)?; - Ok(FunctionSignature { name }) + + let mut return_type = None; + if stream.expect(Token::Arrow).is_ok() { + return_type = Some(stream.parse()?); + } + + Ok(FunctionSignature { + name, + args, + return_type, + }) } else { Err(stream.expected_err("identifier")?)? } diff --git a/src/lexer.rs b/src/lexer.rs index cd53fef..9624678 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -18,6 +18,8 @@ pub enum Token { ReturnKeyword, /// `fn` FnKeyword, + /// `->` + Arrow, // Symbols /// `;` @@ -30,6 +32,12 @@ pub enum Token { Plus, /// `*` Times, + /// `-` + Minus, + /// `>` + GreaterThan, + /// `<` + LessThan, /// `(` ParenOpen, /// `)` @@ -48,6 +56,7 @@ impl Token { pub fn get_token_prec(&self) -> i8 { match &self { Token::Plus => 10, + Token::Minus => 10, Token::Times => 20, _ => -1, } @@ -160,12 +169,19 @@ pub fn tokenize>(to_tokenize: T) -> Result, Error } Token::DecimalValue(value) } + '-' if cursor.first() == Some('>') => { + cursor.next(); // Eat `>` + Token::Arrow + } // Single character tokens '=' => Token::Equals, ';' => Token::Semi, ':' => Token::Colon, '+' => Token::Plus, '*' => Token::Times, + '-' => Token::Minus, + '>' => Token::GreaterThan, + '<' => Token::LessThan, '(' => Token::ParenOpen, ')' => Token::ParenClose, '{' => Token::BraceOpen,