Add return types, function args

This commit is contained in:
Sofia 2023-08-03 20:30:00 +03:00
parent 420fd7b74b
commit 4c8417cbee
3 changed files with 66 additions and 7 deletions

View File

@ -2,14 +2,19 @@
import std::print; import std::print;
fn somethingelse() {
return 12;
}
fn main() { fn main() {
let hello = 32 + { let hello = 32 + {
2 + somethingelse() 2 + 2
}; };
let beep = hello + 5; let beep = hello + fibonacci(15);
return beep; return beep;
} }
// Fibonacci
fn fibonacci(value: i32) -> i32 {
if value < 3 {
return 1;
}
return fibonacci(value - 1) + fibonacci(value - 2);
}

View File

@ -10,6 +10,24 @@ where
fn parse(stream: TokenStream) -> Result<Self, Error>; fn parse(stream: TokenStream) -> Result<Self, Error>;
} }
#[derive(Debug, Clone)]
pub enum Type {
I32,
}
impl Parse for Type {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
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)] #[derive(Debug, Clone)]
pub enum Literal { pub enum Literal {
I32(i32), I32(i32),
@ -187,14 +205,34 @@ impl Parse for FunctionDefinition {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FunctionSignature { pub struct FunctionSignature {
pub name: String, pub name: String,
pub args: Vec<(String, Type)>,
pub return_type: Option<Type>,
} }
impl Parse for FunctionSignature { impl Parse for FunctionSignature {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
if let Some(Token::Identifier(name)) = stream.next() { if let Some(Token::Identifier(name)) = stream.next() {
stream.expect(Token::ParenOpen)?; 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)?; 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 { } else {
Err(stream.expected_err("identifier")?)? Err(stream.expected_err("identifier")?)?
} }

View File

@ -18,6 +18,8 @@ pub enum Token {
ReturnKeyword, ReturnKeyword,
/// `fn` /// `fn`
FnKeyword, FnKeyword,
/// `->`
Arrow,
// Symbols // Symbols
/// `;` /// `;`
@ -30,6 +32,12 @@ pub enum Token {
Plus, Plus,
/// `*` /// `*`
Times, Times,
/// `-`
Minus,
/// `>`
GreaterThan,
/// `<`
LessThan,
/// `(` /// `(`
ParenOpen, ParenOpen,
/// `)` /// `)`
@ -48,6 +56,7 @@ impl Token {
pub fn get_token_prec(&self) -> i8 { pub fn get_token_prec(&self) -> i8 {
match &self { match &self {
Token::Plus => 10, Token::Plus => 10,
Token::Minus => 10,
Token::Times => 20, Token::Times => 20,
_ => -1, _ => -1,
} }
@ -160,12 +169,19 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
} }
Token::DecimalValue(value) Token::DecimalValue(value)
} }
'-' if cursor.first() == Some('>') => {
cursor.next(); // Eat `>`
Token::Arrow
}
// Single character tokens // Single character tokens
'=' => Token::Equals, '=' => Token::Equals,
';' => Token::Semi, ';' => Token::Semi,
':' => Token::Colon, ':' => Token::Colon,
'+' => Token::Plus, '+' => Token::Plus,
'*' => Token::Times, '*' => Token::Times,
'-' => Token::Minus,
'>' => Token::GreaterThan,
'<' => Token::LessThan,
'(' => Token::ParenOpen, '(' => Token::ParenOpen,
')' => Token::ParenClose, ')' => Token::ParenClose,
'{' => Token::BraceOpen, '{' => Token::BraceOpen,