Skip to content

Commit

Permalink
🚧 WIP
Browse files Browse the repository at this point in the history
semver: chore
  • Loading branch information
Lucas de Jong committed Oct 31, 2024
1 parent 290acf3 commit 2f4e41f
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 43 deletions.
1 change: 1 addition & 0 deletions src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ impl<'de> Iterator for Lexer<'de> {
"dec" => Ok((TokenKind::DecimalType, TokenValue::None)),
"str" => Ok((TokenKind::StringType, TokenValue::None)),
"char" => Ok((TokenKind::CharacterType, TokenValue::None)),
"return" => Ok((TokenKind::Return, TokenValue::None)),
ident => Ok((
TokenKind::Identifier,
TokenValue::Identifier(ident.to_string().into()),
Expand Down
57 changes: 39 additions & 18 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use lexer::{Lexer, TokenKind};
use owo_colors::{Style, Styled};
use parser::Parser;
use passer::Passer;
use parser::{
ast::{Expression, Statement},
Parser,
};
use passer::{typing::Typing, Passer};
use std::vec;

pub mod lexer;
Expand All @@ -21,15 +24,7 @@ fn main() {
}))
.unwrap();

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

let mut parser = Parser::new(input);
Expand All @@ -41,14 +36,39 @@ fn main() {
}
};

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

for note in typing_pass.non_critical {
println!("{:?}", note.with_source_code(input.to_string()));
match symbol {
parser::ast::Symbol::Statement(statement) => print_statement(statement),
parser::ast::Symbol::Expression(expression) => print_expression(expression),
}

for note in typing_pass.critical {
println!("{:?}", note.with_source_code(input.to_string()));
// 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()));
// }
}

fn print_expression(expression: Expression) {
println!(
"{:?} of type ({:?})",
expression,
expression.possible_types()
);
}

fn print_statement(statement: Statement) {
match statement {
Statement::Block(statements) => {
for statement in statements {
print_statement(statement);
}
}
Statement::Expression(expression) => print_expression(expression),
_ => println!("{:?}", statement),
}
}

Expand Down Expand Up @@ -79,7 +99,8 @@ impl miette::highlighters::HighlighterState for SomHighlighterState {
| TokenKind::Struct
| TokenKind::Enum
| TokenKind::Function
| TokenKind::Trait => Style::new().fg_rgb::<197, 120, 221>(),
| TokenKind::Trait
| TokenKind::Return => Style::new().fg_rgb::<197, 120, 221>(),
TokenKind::Identifier => Style::new().fg_rgb::<224, 108, 117>(),
TokenKind::String => Style::new().fg_rgb::<152, 195, 121>().italic(),
TokenKind::Integer | TokenKind::Decimal => {
Expand Down
10 changes: 8 additions & 2 deletions src/parser/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ pub enum Statement<'de> {
name: Cow<'de, str>,
functions: Vec<FunctionHeader<'de>>,
},
Return(Expression<'de>),
Conditional {
condition: Box<Expression<'de>>,
truthy: Box<Statement<'de>>,
falsy: Option<Box<Statement<'de>>>,
},
}

#[derive(Debug)]
Expand All @@ -50,10 +56,10 @@ pub enum Expression<'de> {
statements: Vec<Statement<'de>>,
return_value: Box<Expression<'de>>,
},
If {
Conditional {
condition: Box<Expression<'de>>,
truthy: Box<Expression<'de>>,
falsy: Option<Box<Expression<'de>>>,
falsy: Box<Expression<'de>>,
},
Call {
callee: Box<Expression<'de>>,
Expand Down
27 changes: 12 additions & 15 deletions src/parser/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl Default for Lookup<'_> {
.add_expression_handler(TokenKind::String, expression::primitive::string)
.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::If, BindingPower::None, conditional)
.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)
Expand Down Expand Up @@ -204,31 +204,28 @@ impl Default for Lookup<'_> {
.add_type_handler(TokenKind::StringType, typing::string)
.add_type_handler(TokenKind::SquareOpen, typing::collection)
.add_type_handler(TokenKind::CurlyOpen, typing::set)
.add_statement_handler(TokenKind::Return, statement::return_)
.add_statement_handler(TokenKind::If, statement::if_)
}
}

fn if_<'de>(
fn conditional<'de>(
parser: &mut Parser<'de>,
lhs: Expression<'de>,
binding_power: BindingPower,
) -> Result<Expression<'de>> {
let condition = expression::parse(parser, binding_power)?;
let condition = expression::parse(parser, binding_power.clone())?;

let falsy = if parser.lexer.peek().map_or(false, |token| {
token
.as_ref()
.map_or(false, |token| token.kind == TokenKind::Else)
}) {
parser.lexer.next();
Some(expression::parse(parser, BindingPower::None)?)
} else {
None
};
parser
.lexer
.expect(TokenKind::Else, "expected an else branch")?;

let falsy = expression::parse(parser, binding_power)?;

Ok(Expression::If {
Ok(Expression::Conditional {
condition: Box::new(condition),
truthy: Box::new(lhs),
falsy: falsy.map(Box::new),
falsy: Box::new(falsy),
})
}

Expand Down
39 changes: 38 additions & 1 deletion src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
},
expression,
lookup::BindingPower,
typing, Parser,
statement, typing, Parser,
};
use crate::lexer::{TokenKind, TokenValue};
use miette::{Context, Result};
Expand Down Expand Up @@ -358,3 +358,40 @@ pub fn trait_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
functions,
})
}

pub fn return_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
parser
.lexer
.expect(TokenKind::Return, "expected a return keyword")?;

let expression = expression::parse(parser, BindingPower::None)?;

Ok(Statement::Return(expression))
}

pub fn if_<'de>(parser: &mut Parser<'de>) -> Result<Statement<'de>> {
parser
.lexer
.expect(TokenKind::If, "expected an if keyword")?;

let condition = expression::parse(parser, BindingPower::None)?;

let truthy = statement::parse(parser, true)?;

let falsy = if parser.lexer.peek().map_or(false, |token| {
token
.as_ref()
.map_or(false, |token| token.kind == TokenKind::Else)
}) {
parser.lexer.next();
Some(statement::parse(parser, true)?)
} else {
None
};

Ok(Statement::Conditional {
condition: Box::new(condition),
truthy: Box::new(truthy),
falsy: falsy.map(Box::new),
})
}
53 changes: 46 additions & 7 deletions src/passer/typing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{Passer, PasserResult};
use crate::parser::ast::Symbol;
use crate::parser::ast::{Expression, Statement, Symbol, Type};
use miette::{Result, Severity};

pub struct TypingPasser;
Expand All @@ -9,15 +9,54 @@ impl Passer for TypingPasser {
let mut critical = vec![];
let mut non_critical = vec![];

non_critical.push(miette::miette! {
severity = Severity::Warning,
labels = vec![miette::LabeledSpan::at(100, "uwu")],
"Typing is not yet implemented"
});

Ok(PasserResult {
critical,
non_critical,
})
}
}

pub trait Typing {
fn possible_types(&self) -> Vec<Type>;
}

impl Typing for Expression<'_> {
fn possible_types(&self) -> Vec<Type> {
match self {
Expression::Primitive(primitive) => vec![match primitive {
crate::parser::ast::Primitive::Integer(_) => Type::Integer,
crate::parser::ast::Primitive::Decimal(_) => Type::Decimal,
crate::parser::ast::Primitive::String(_) => Type::String,
crate::parser::ast::Primitive::Identifier(value) => Type::Symbol(value.clone()),
crate::parser::ast::Primitive::Character(_) => Type::Character,
crate::parser::ast::Primitive::Boolean(_) => Type::Boolean,
crate::parser::ast::Primitive::Unit => Type::Unit,
}],
Expression::Binary {
operator,
left,
right,
} => {
let mut types = left.possible_types();
types.extend(right.possible_types());
types
}
Expression::Unary { operator, operand } => operand.possible_types(),
Expression::Group(expression) => expression.possible_types(),
Expression::Block {
statements,
return_value,
} => return_value.possible_types(),
Expression::Conditional {
condition,
truthy,
falsy,
} => {
let mut types = truthy.possible_types();
types.extend(falsy.possible_types());
types
}
Expression::Call { callee, arguments } => callee.possible_types(),
}
}
}

0 comments on commit 2f4e41f

Please sign in to comment.