added github as repo

This commit is contained in:
LunarAkai 2025-08-06 12:10:42 +02:00
commit e769b891ab
9 changed files with 24 additions and 114 deletions

View file

@ -1 +1,3 @@
pub mod ast;
pub mod parser;
pub mod tokens;

View file

@ -0,0 +1,93 @@
use chumsky::{combinator::Or, prelude::{choice, just, recursive}, recursive, select, text::{self, ascii::ident}, IterParser, Parser};
use crate::{language_frontend::ast::ast::Expression, language_frontend::tokens::Token};
#[allow(clippy::let_and_return)]
pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>> {
let ident = select! {
Token::Ident(ident) => ident
};
let keyword = |kw: &'static str| select! {
Token::Keyword(k) if k == kw => ()
};
let eq = just(Token::Equals);
let expr = recursive(
|expr|
{
let atom = {
let parenthesized = expr
.clone()
.delimited_by(just(Token::ParenBegin), just(Token::ParenEnd));
let integer = select! {
Token::Integer(n) => Expression::Integer(n),
};
parenthesized.or(integer)
};
let unary = just(Token::Substract)
.repeated()
.foldr(atom, |_op, rhs| Expression::Negatation(Box::new(rhs)));
let binary_1 = unary.clone().foldl(
just(Token::Multiply)
.or(just(Token::Divide))
.then(unary)
.repeated(),
|lhs, (op, rhs)| match op {
Token::Multiply => Expression::Multiply(Box::new(lhs), Box::new(rhs)),
Token::Divide => Expression::Divide(Box::new(lhs), Box::new(rhs)),
_ => unreachable!(),
},
);
let binary_2 = binary_1.clone().foldl(
just(Token::Add)
.or(just(Token::Substract))
.then(binary_1)
.repeated(),
|lhs, (op, rhs)| match op {
Token::Add => Expression::Add(Box::new(lhs), Box::new(rhs)),
Token::Substract => Expression::Substract(Box::new(lhs), Box::new(rhs)),
_ => unreachable!(),
},
);
binary_2
});
let decl = recursive(|decl| {
let r#var = keyword("var")
.ignore_then(ident.clone())
.then_ignore(eq.clone())
.then(decl.clone())
.then(decl.clone())
.map(|((name, rhs), then)| Expression::Var {
name,
rhs: Box::new(rhs),
then: Box::new(then),
});
let r#fun = keyword("fun")
.ignore_then(ident.clone())
.then(ident.clone().repeated().collect())
.then_ignore(eq.clone())
.then(decl.clone())
.then(decl.clone())
.map(|(((name, args), body), then)| Expression::Function {
name,
args,
body: Box::new(body),
then: Box::new(then),
});
var.or(r#fun).or(expr)
});
decl
}

View file

@ -0,0 +1,57 @@
use logos::{Lexer, Logos};
#[derive(Logos, Debug, Clone, PartialEq)]
#[logos(skip r"[ \t\r\n\f]+")] // Skips whitespace
pub enum Token<'src> {
#[token("false", |_| false)]
#[token("true", |_| true)]
Bool(bool),
#[token("+")]
Add,
#[token("-")]
Substract,
#[token("*")]
Multiply,
#[token("/")]
Divide,
#[token("=")]
Equals,
#[token(":")]
Colon,
#[token("(")]
ParenBegin,
#[token(")")]
ParenEnd,
#[token("{")]
BraceBegin,
#[token("}")]
BraceEnd,
#[regex("[0-9]+", |lex| lex.slice().parse::<i64>().unwrap())]
Integer(i64),
#[regex(r"[_a-zA-Z][_0-9a-zA-Z]*")]
Ident(&'src str),
#[regex(r#""([^"\\\x00-\x1F]|\\(["\\bnfrt/]|u[a-fA-F0-9]{4}))*""#, |lex| lex.slice().to_owned())]
String(String),
#[token("class")]
#[token("fun")]
#[token("var")]
#[token("if")]
#[token("else")]
Keyword(&'src str),
}