Add function calls to parsing, also Top Level Expressions
This commit is contained in:
parent
ee14e18787
commit
42e74f49f8
@ -9,3 +9,4 @@ let multiplier = 5 * 2;
|
|||||||
|
|
||||||
let result = arithmetic + multiplier * arithmetic;
|
let result = arithmetic + multiplier * arithmetic;
|
||||||
print(result);
|
print(result);
|
||||||
|
function(one, two);
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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)?;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user