Skip to content

Commit

Permalink
🚧 WIP
Browse files Browse the repository at this point in the history
semver: chore
  • Loading branch information
Somfic committed Oct 30, 2024
1 parent 811c453 commit 675a034
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 33 deletions.
23 changes: 8 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,15 @@ pub mod parser;

fn main() {
let input = "
let x = {1};
let a = \"hello\";
let b = 123;
let b = b if b <= 100 else 100;
struct Human: name, age;
enum Color: red, green, blue, orange;
fn add(a, b) { a + b }
fn sub(a, b) { a - b }
fn mul(a, b) { a * b }
fn div(a, b) { a / b }
fn main() {
fib(9999);
}
trait Add:
fn add(a, b);
";
fn fib(n ~ number) ~ number {
return if n < 2;
fib(n - 1) + fib(n - 2)
}
";

miette::set_hook(Box::new(|_| {
Box::new(
Expand Down
4 changes: 4 additions & 0 deletions src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ pub enum Expression<'de> {
truthy: Box<Expression<'de>>,
falsy: Option<Box<Expression<'de>>>,
},
Call {
callee: Box<Expression<'de>>,
arguments: Vec<Expression<'de>>,
},
}

#[derive(Debug)]
Expand Down
34 changes: 33 additions & 1 deletion src/parser/expression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use miette::Result;

use super::{ast::Expression, Parser};
use crate::parser::lookup::BindingPower;
use crate::{lexer::TokenKind, parser::lookup::BindingPower};

pub mod binary;
pub mod primitive;
Expand Down Expand Up @@ -67,3 +67,35 @@ pub fn parse<'de>(

Ok(lhs)
}

pub fn call<'de>(
parser: &mut Parser<'de>,
lhs: Expression<'de>,
binding_power: BindingPower,
) -> Result<Expression<'de>> {
let mut arguments = Vec::new();

while parser.lexer.peek().map_or(false, |token| {
token
.as_ref()
.map_or(false, |token| token.kind != TokenKind::ParenClose)
}) {
if !arguments.is_empty() {
parser
.lexer
.expect(TokenKind::Comma, "expected a comma between arguments")?;
}

let argument = parse(parser, BindingPower::None)?;
arguments.push(argument);
}

parser
.lexer
.expect(TokenKind::ParenClose, "expected a closing parenthesis")?;

Ok(Expression::Call {
callee: Box::new(lhs),
arguments,
})
}
1 change: 1 addition & 0 deletions src/parser/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl<'de> Default for Lookup<'de> {
.add_expression_handler(TokenKind::Identifier, expression::primitive::identifier)
.add_expression_handler(TokenKind::ParenOpen, group)
.add_left_expression_handler(TokenKind::If, BindingPower::None, if_)
.add_left_expression_handler(TokenKind::ParenOpen, BindingPower::None, expression::call)
.add_expression_handler(TokenKind::Not, expression::unary::negate)
.add_expression_handler(TokenKind::Minus, expression::unary::negative)
.add_expression_handler(TokenKind::CurlyOpen, block)
Expand Down
48 changes: 31 additions & 17 deletions src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn let_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
.expect(TokenKind::Let, "expected a let keyword")?;
let identifier = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected a variable name")?;
let identifier = match identifier.value {
TokenValue::Identifier(identifier) => identifier,
_ => unreachable!(),
Expand All @@ -72,7 +72,7 @@ pub fn struct_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {

let identifier = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected a struct name")?;

let identifier = match identifier.value {
TokenValue::Identifier(identifier) => identifier,
Expand All @@ -89,12 +89,14 @@ pub fn struct_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
.map_or(false, |token| token.kind != TokenKind::Semicolon)
}) {
if !fields.is_empty() {
parser.lexer.expect(TokenKind::Comma, "expected a comma")?;
parser
.lexer
.expect(TokenKind::Comma, "expected a comma between fields")?;
}

let field = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected a field name")?;

let field = match field.value {
TokenValue::Identifier(field) => field,
Expand All @@ -121,7 +123,7 @@ pub fn enum_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {

let identifier = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected an enum name")?;

let identifier = match identifier.value {
TokenValue::Identifier(identifier) => identifier,
Expand All @@ -138,12 +140,14 @@ pub fn enum_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
.map_or(false, |token| token.kind != TokenKind::Semicolon)
}) {
if !variants.is_empty() {
parser.lexer.expect(TokenKind::Comma, "expected a comma")?;
parser
.lexer
.expect(TokenKind::Comma, "expected a comma between enum members")?;
}

let variant = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected an enum member name")?;

let variant = match variant.value {
TokenValue::Identifier(variant) => variant,
Expand All @@ -166,11 +170,11 @@ pub fn enum_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
pub fn function_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
parser
.lexer
.expect(TokenKind::Function, "expected a fn keyword")?;
.expect(TokenKind::Function, "expected a function keyword")?;

let identifier = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected function name")?;

let identifier = match identifier.value {
TokenValue::Identifier(identifier) => identifier,
Expand All @@ -189,12 +193,14 @@ pub fn function_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
.map_or(false, |token| token.kind != TokenKind::ParenClose)
}) {
if !parameters.is_empty() {
parser.lexer.expect(TokenKind::Comma, "expected a comma")?;
parser
.lexer
.expect(TokenKind::Comma, "expected a comma between parameters")?;
}

let parameter = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected a parameter name")?;

let parameter = match parameter.value {
TokenValue::Identifier(parameter) => parameter,
Expand Down Expand Up @@ -224,7 +230,7 @@ pub fn trait_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {

let identifier = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected a trait name")?;

let identifier = match identifier.value {
TokenValue::Identifier(identifier) => identifier,
Expand All @@ -241,16 +247,18 @@ pub fn trait_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
.map_or(false, |token| token.kind != TokenKind::Semicolon)
}) {
if !functions.is_empty() {
parser.lexer.expect(TokenKind::Comma, "expected a comma")?;
parser
.lexer
.expect(TokenKind::Comma, "expected a comma between functions")?;
}

parser
.lexer
.expect(TokenKind::Function, "expected a fn keyword")?;
.expect(TokenKind::Function, "expected a function keyword")?;

let function = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected a function name")?;

let function = match function.value {
TokenValue::Identifier(function) => function,
Expand All @@ -269,12 +277,14 @@ pub fn trait_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
.map_or(false, |token| token.kind != TokenKind::ParenClose)
}) {
if !parameters.is_empty() {
parser.lexer.expect(TokenKind::Comma, "expected a comma")?;
parser
.lexer
.expect(TokenKind::Comma, "expected a comma in between arguments")?;
}

let parameter = parser
.lexer
.expect(TokenKind::Identifier, "expected an identifier")?;
.expect(TokenKind::Identifier, "expected an argument name")?;

let parameter = match parameter.value {
TokenValue::Identifier(parameter) => parameter,
Expand All @@ -284,6 +294,10 @@ pub fn trait_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
parameters.push(parameter);
}

parser
.lexer
.expect(TokenKind::ParenClose, "expected a close parenthesis")?;

functions.push((function, parameters));
}

Expand Down

0 comments on commit 675a034

Please sign in to comment.