Add function calls to parsing, also Top Level Expressions

This commit is contained in:
Sofia 2023-07-27 23:01:50 +03:00
parent ee14e18787
commit 42e74f49f8
4 changed files with 57 additions and 16 deletions

View File

@ -8,4 +8,5 @@ let arithmetic = 3 + 2 * 5 + 1 * 2;
let multiplier = 5 * 2; let multiplier = 5 * 2;
let result = arithmetic + multiplier * arithmetic; let result = arithmetic + multiplier * arithmetic;
print(result); print(result);
function(one, two);

View File

@ -70,6 +70,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Strin
'*' => Token::Times, '*' => Token::Times,
'(' => Token::ParenOpen, '(' => Token::ParenOpen,
')' => Token::ParenClose, ')' => Token::ParenClose,
',' => Token::Comma,
// Invalid token // Invalid token
_ => Err(format!( _ => Err(format!(
"Unknown token '{}' at {}, {}", "Unknown token '{}' at {}, {}",
@ -112,6 +113,7 @@ pub enum Token {
Times, Times,
ParenOpen, // ( ParenOpen, // (
ParenClose, // ) ParenClose, // )
Comma,
Eof, Eof,
} }

View File

@ -1,6 +1,6 @@
use crate::{lexer::Token, token_stream::TokenStream}; use crate::{lexer::Token, token_stream::TokenStream};
pub trait Parseable pub trait Parse
where where
Self: std::marker::Sized, Self: std::marker::Sized,
{ {
@ -13,9 +13,10 @@ pub enum Expression {
ContantI32(i32), ContantI32(i32),
BinopAdd(Box<Expression>, Box<Expression>), BinopAdd(Box<Expression>, Box<Expression>),
BinopMult(Box<Expression>, Box<Expression>), BinopMult(Box<Expression>, Box<Expression>),
FunctionCall(Box<FunctionCallExpression>),
} }
impl Parseable for Expression { impl Parse for Expression {
fn parse(mut stream: TokenStream) -> Result<Expression, ()> { fn parse(mut stream: TokenStream) -> Result<Expression, ()> {
let lhs = parse_primary_expression(&mut stream)?; let lhs = parse_primary_expression(&mut stream)?;
parse_binop_rhs(&mut stream, lhs, 0) parse_binop_rhs(&mut stream, lhs, 0)
@ -23,14 +24,16 @@ impl Parseable for Expression {
} }
fn parse_primary_expression(stream: &mut TokenStream) -> Result<Expression, ()> { fn parse_primary_expression(stream: &mut TokenStream) -> Result<Expression, ()> {
if let Some(token) = stream.next() { if let Ok(exp) = stream.parse() {
Ok(Expression::FunctionCall(Box::new(exp)))
} else if let Some(token) = stream.next() {
Ok(match &token { Ok(match &token {
Token::Identifier(v) => Expression::VariableName(v.clone()), Token::Identifier(v) => Expression::VariableName(v.clone()),
Token::DecimalValue(v) => Expression::ContantI32(v.parse().unwrap()), Token::DecimalValue(v) => Expression::ContantI32(v.parse().unwrap()),
_ => Err(())?, _ => Err(())?, // TODO: Add error raporting!
}) })
} else { } else {
Err(()) Err(()) // TODO: Add error raporting!
} }
} }
@ -66,7 +69,7 @@ fn parse_binop_rhs(
lhs = match &token { lhs = match &token {
Token::Plus => Expression::BinopAdd(Box::new(lhs), Box::new(rhs)), Token::Plus => Expression::BinopAdd(Box::new(lhs), Box::new(rhs)),
Token::Times => Expression::BinopMult(Box::new(lhs), Box::new(rhs)), Token::Times => Expression::BinopMult(Box::new(lhs), Box::new(rhs)),
_ => Err(())?, _ => Err(())?, // TODO: Add error raporting!
}; };
} }
} }
@ -74,18 +77,53 @@ fn parse_binop_rhs(
Ok(lhs) Ok(lhs)
} }
#[derive(Debug, Clone)]
pub struct FunctionCallExpression(String, Vec<Expression>);
impl Parse for FunctionCallExpression {
fn parse(mut stream: TokenStream) -> Result<Self, ()> {
if let Some(Token::Identifier(name)) = stream.next() {
stream.expect(Token::ParenOpen)?;
let mut args = Vec::new();
if let Ok(exp) = stream.parse() {
args.push(exp);
while stream.expect(Token::Comma).is_ok() {
args.push(stream.parse()?);
}
}
stream.expect(Token::ParenClose)?;
Ok(FunctionCallExpression(name, args))
} else {
Err(())? // TODO: Add error raporting!
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum TopLevelStatement { pub enum TopLevelStatement {
Let(LetStatement), Let(LetStatement),
Import(ImportStatement), Import(ImportStatement),
TLExpression(Expression),
} }
impl Parseable for TopLevelStatement { impl Parse for TopLevelStatement {
fn parse(mut stream: TokenStream) -> Result<Self, ()> { fn parse(mut stream: TokenStream) -> Result<Self, ()> {
Ok(match stream.peek() { Ok(match stream.peek() {
Some(Token::LetKeyword) => TopLevelStatement::Let(stream.parse()?), Some(Token::LetKeyword) => TopLevelStatement::Let(stream.parse()?),
Some(Token::ImportKeyword) => TopLevelStatement::Import(stream.parse()?), Some(Token::ImportKeyword) => TopLevelStatement::Import(stream.parse()?),
_ => Err(())?, _ => {
if let Ok(e) = stream.parse() {
stream.expect(Token::Semicolon)?;
TopLevelStatement::TLExpression(e)
} else {
Err(())? // TODO: Add error raporting!
}
}
}) })
} }
} }
@ -93,7 +131,7 @@ impl Parseable for TopLevelStatement {
#[derive(Debug)] #[derive(Debug)]
pub struct LetStatement(String, Expression); pub struct LetStatement(String, Expression);
impl Parseable for LetStatement { impl Parse for LetStatement {
fn parse(mut stream: TokenStream) -> Result<LetStatement, ()> { fn parse(mut stream: TokenStream) -> Result<LetStatement, ()> {
stream.expect(Token::LetKeyword)?; stream.expect(Token::LetKeyword)?;
@ -104,7 +142,7 @@ impl Parseable for LetStatement {
stream.expect(Token::Semicolon)?; stream.expect(Token::Semicolon)?;
Ok(LetStatement(variable, expression)) Ok(LetStatement(variable, expression))
} else { } else {
Err(()) Err(()) // TODO: Add error raporting!
} }
} }
} }
@ -112,7 +150,7 @@ impl Parseable for LetStatement {
#[derive(Debug)] #[derive(Debug)]
pub struct ImportStatement(Vec<String>); pub struct ImportStatement(Vec<String>);
impl Parseable for ImportStatement { impl Parse for ImportStatement {
fn parse(mut stream: TokenStream) -> Result<Self, ()> { fn parse(mut stream: TokenStream) -> Result<Self, ()> {
stream.expect(Token::ImportKeyword)?; stream.expect(Token::ImportKeyword)?;
@ -124,11 +162,11 @@ impl Parseable for ImportStatement {
if let Some(Token::Identifier(name)) = stream.next() { if let Some(Token::Identifier(name)) = stream.next() {
import_list.push(name); import_list.push(name);
} else { } else {
Err(())? Err(())? // TODO: Add error raporting!
} }
} }
} else { } else {
Err(())? Err(())? // TODO: Add error raporting!
} }
stream.expect(Token::Semicolon)?; stream.expect(Token::Semicolon)?;

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
lexer::{FullToken, Token}, lexer::{FullToken, Token},
parser::Parseable, parser::Parse,
}; };
pub struct TokenStream<'a, 'b> { pub struct TokenStream<'a, 'b> {
@ -49,7 +49,7 @@ impl<'a, 'b> TokenStream<'a, 'b> {
} }
} }
pub fn parse<T: Parseable>(&mut self) -> Result<T, ()> { pub fn parse<T: Parse>(&mut self) -> Result<T, ()> {
let mut ref_pos = self.position; let mut ref_pos = self.position;
let position = self.position; let position = self.position;