Skip to content

Commit

Permalink
🚧 WIP
Browse files Browse the repository at this point in the history
semver: chore
  • Loading branch information
Somfic committed Nov 1, 2024
1 parent 2a5be64 commit fdb5b4e
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 143 deletions.
86 changes: 22 additions & 64 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use lexer::{Lexer, TokenKind};
use owo_colors::{Style, Styled};
use parser::{
ast::{Expression, Statement},
ast::{Expression, ExpressionValue, Statement},
Parser,
};
use passer::{typing::Typing, Passer};
Expand All @@ -11,6 +11,19 @@ pub mod lexer;
pub mod parser;
pub mod passer;

const INPUT: &str = "
fn main() {
fib(9999);
}
fn fib(n ~ int) ~ int {
let n = 12;
if n < 2 return n;
fib(n - 1) + fib(n - 20)
}
";

fn main() {
miette::set_hook(Box::new(|_| {
Box::new(
Expand All @@ -24,79 +37,24 @@ fn main() {
}))
.unwrap();

let input = "
fn main() {
fib(9999);
}
fn fib(n ~ int) ~ int {
let n = 12;
if n < 2 return n;
fib(n - 1) + fib(n - 20)
}
";

let mut parser = Parser::new(input);
let mut parser = Parser::new(INPUT);
let symbol = match parser.parse() {
Ok(symbol) => symbol,
Err(err) => {
println!("{:?}", err.with_source_code(input.to_string()));
println!("{:?}", err.with_source_code(INPUT));
return;
}
};

match &symbol {
parser::ast::Symbol::Statement(statement) => print_statement(statement),
parser::ast::Symbol::Expression(expression) => print_expression(expression),
}

// let typing_pass = passer::typing::TypingPasser::pass(&symbol).unwrap();

// for note in typing_pass.non_critical {
// println!("{:?}", note.with_source_code(input.to_string()));
// }

// for note in typing_pass.critical {
// println!("{:?}", note.with_source_code(input.to_string()));
// }
}
let typing_pass = passer::typing::TypingPasser::pass(&symbol).unwrap();

fn print_expression(expression: &Expression) {
match &expression {
Expression::Block {
statements,
return_value,
} => {
for statement in statements {
print_statement(statement);
}
print_expression(return_value);
}
Expression::Group(expression) => print_expression(expression),
e => println!("{:?} typeof {:?}", e, e.possible_types()),
for note in typing_pass.non_critical {
println!("{:?}", note.with_source_code(INPUT));
}
}

fn print_statement(statement: &Statement) {
match statement {
Statement::Block(statements) => {
for statement in statements {
print_statement(statement);
}
}
Statement::Function {
header,
body,
explicit_return_type,
} => {
print_expression(body);
}
Statement::Return(expression) => print_expression(expression),
Statement::Expression(expression) => print_expression(expression),
Statement::Assignment { name, value } => print_expression(value),
_ => {}
};
for note in typing_pass.critical {
println!("{:?}", note.with_source_code(INPUT));
}
}

struct SomHighlighter {}
Expand Down
44 changes: 43 additions & 1 deletion src/parser/ast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::borrow::Cow;

use miette::SourceSpan;

#[derive(Debug, Clone)]
pub enum Symbol<'de> {
Statement(Statement<'de>),
Expand Down Expand Up @@ -40,7 +42,47 @@ pub enum Statement<'de> {
}

#[derive(Debug, Clone)]
pub enum Expression<'de> {
pub struct Expression<'de> {
pub value: ExpressionValue<'de>,
pub span: miette::SourceSpan,
}

impl<'de> Expression<'de> {
pub fn at(span: miette::SourceSpan, value: ExpressionValue<'de>) -> Self {
Self { value, span }
}

pub fn at_multiple(
spans: Vec<impl Into<miette::SourceSpan>>,
value: ExpressionValue<'de>,
) -> Expression<'de> {
let spans = spans.into_iter().map(|s| s.into()).collect::<Vec<_>>();

let start = spans
.iter()
.min_by_key(|s| s.offset())
.map(|s| s.offset())
.unwrap_or(0);

// Go through all the spans and find the one with the highest end offset
let end = spans
.iter()
.max_by_key(|s| s.offset() + s.len())
.map(|s| s.offset() + s.len())
.unwrap_or(0);

let span = miette::SourceSpan::new(start.into(), end - start);

Expression::at(span, value)
}

pub fn label(&self, text: impl Into<String>) -> miette::LabeledSpan {
miette::LabeledSpan::at(self.span, text.into())
}
}

#[derive(Debug, Clone)]
pub enum ExpressionValue<'de> {
Primitive(Primitive<'de>),
Binary {
operator: BinaryOperator,
Expand Down
15 changes: 9 additions & 6 deletions src/parser/expression/binary.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::parser::{
ast::{BinaryOperator, Expression},
ast::{BinaryOperator, Expression, ExpressionValue},
lookup::BindingPower,
Parser,
};
Expand All @@ -13,11 +13,14 @@ pub fn parse_binary_expression<'de>(
) -> Result<Expression<'de>> {
let rhs = crate::parser::expression::parse(parser, bp)?;

Ok(Expression::Binary {
operator,
left: Box::new(lhs),
right: Box::new(rhs),
})
Ok(Expression::at_multiple(
vec![rhs.span, lhs.span],
ExpressionValue::Binary {
operator,
left: Box::new(lhs),
right: Box::new(rhs),
},
))
}

pub fn addition<'de>(
Expand Down
16 changes: 11 additions & 5 deletions src/parser/expression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use miette::Result;

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

pub mod binary;
Expand Down Expand Up @@ -94,8 +97,11 @@ pub fn call<'de>(
.lexer
.expect(TokenKind::ParenClose, "expected a closing parenthesis")?;

Ok(Expression::Call {
callee: Box::new(lhs),
arguments,
})
Ok(Expression::at(
lhs.span,
ExpressionValue::Call {
callee: Box::new(lhs.clone()),
arguments,
},
))
}
32 changes: 25 additions & 7 deletions src/parser/expression/primitive.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
lexer::{TokenKind, TokenValue},
parser::{
ast::{Expression, Primitive},
ast::{Expression, ExpressionValue, Primitive},
Parser,
},
};
Expand All @@ -17,7 +17,10 @@ pub fn integer<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
_ => unreachable!(),
};

Ok(Expression::Primitive(Primitive::Integer(value)))
Ok(Expression::at(
token.span,
ExpressionValue::Primitive(Primitive::Integer(value)),
))
}

pub fn decimal<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
Expand All @@ -30,7 +33,10 @@ pub fn decimal<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
_ => unreachable!(),
};

Ok(Expression::Primitive(Primitive::Decimal(value)))
Ok(Expression::at(
token.span,
ExpressionValue::Primitive(Primitive::Decimal(value)),
))
}

pub fn boolean<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
Expand All @@ -43,7 +49,10 @@ pub fn boolean<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
_ => unreachable!(),
};

Ok(Expression::Primitive(Primitive::Boolean(value)))
Ok(Expression::at(
token.span,
ExpressionValue::Primitive(Primitive::Boolean(value)),
))
}

pub fn character<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
Expand All @@ -56,7 +65,10 @@ pub fn character<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
_ => unreachable!(),
};

Ok(Expression::Primitive(Primitive::Character(value)))
Ok(Expression::at(
token.span,
ExpressionValue::Primitive(Primitive::Character(value)),
))
}

pub fn string<'de>(parser: &mut Parser<'de>) -> Result<Expression<'de>> {
Expand All @@ -69,7 +81,10 @@ pub fn string<'de>(parser: &mut Parser<'de>) -> Result<Expression<'de>> {
_ => unreachable!(),
};

Ok(Expression::Primitive(Primitive::String(value)))
Ok(Expression::at(
token.span,
ExpressionValue::Primitive(Primitive::String(value)),
))
}

pub fn identifier<'de>(parser: &mut Parser<'de>) -> Result<Expression<'de>> {
Expand All @@ -82,5 +97,8 @@ pub fn identifier<'de>(parser: &mut Parser<'de>) -> Result<Expression<'de>> {
_ => unreachable!(),
};

Ok(Expression::Primitive(Primitive::Identifier(value)))
Ok(Expression::at(
token.span,
ExpressionValue::Primitive(Primitive::Identifier(value)),
))
}
28 changes: 17 additions & 11 deletions src/parser/expression/unary.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
use crate::{
lexer::TokenKind,
parser::{
ast::{Expression, UnaryOperator},
ast::{Expression, ExpressionValue, UnaryOperator},
lookup::BindingPower,
Parser,
},
};
use miette::Result;

pub fn negate<'de>(parser: &mut Parser<'de>) -> Result<Expression<'de>> {
parser
let token = parser
.lexer
.expect(TokenKind::Not, "expected a negate operator")?;
let expression = crate::parser::expression::parse(parser, BindingPower::None)?;

Ok(Expression::Unary {
operator: UnaryOperator::Negate,
operand: Box::new(expression),
})
Ok(Expression::at_multiple(
vec![token.span, expression.span],
ExpressionValue::Unary {
operator: UnaryOperator::Negate,
operand: Box::new(expression),
},
))
}

pub fn negative<'de>(parser: &mut Parser<'de>) -> Result<Expression<'de>> {
parser
let token = parser
.lexer
.expect(TokenKind::Minus, "expected a negative operator")?;
let expression = crate::parser::expression::parse(parser, BindingPower::None)?;

Ok(Expression::Unary {
operator: UnaryOperator::Negative,
operand: Box::new(expression),
})
Ok(Expression::at_multiple(
vec![token.span, expression.span],
ExpressionValue::Unary {
operator: UnaryOperator::Negative,
operand: Box::new(expression),
},
))
}
Loading

0 comments on commit fdb5b4e

Please sign in to comment.