hey it can calculate 4 again xP
This commit is contained in:
parent
d253497b3e
commit
8a44d045ae
7 changed files with 50 additions and 36 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
/target
|
||||
*.sh
|
||||
*.sh
|
||||
sample.akai
|
||||
|
|
@ -2,19 +2,23 @@
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum Expression<'src> {
|
||||
// Identifier
|
||||
Ident(&'src str),
|
||||
|
||||
// Types
|
||||
Integer(i64),
|
||||
Float(f64),
|
||||
String(String),
|
||||
Bool(bool),
|
||||
|
||||
// Operations
|
||||
Negatation(Box<Expression<'src>>),
|
||||
Add(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||
Substract(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||
Multiply(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||
Divide(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||
|
||||
// Keywords
|
||||
Var {
|
||||
name: &'src str,
|
||||
rhs: Box<Expression<'src>>,
|
||||
|
|
@ -37,16 +41,24 @@ pub fn eval<'src>(
|
|||
funcs: &mut Vec<(&'src str, &'src [&'src str], &'src Expression<'src>)>,
|
||||
) -> Result<f64, String> {
|
||||
match expr {
|
||||
Expression::Ident(_) => todo!(),
|
||||
Expression::Ident(name) => {
|
||||
if let Some((_, val)) = vars.iter().rev().find(|(var, _)| var == name) {
|
||||
Ok(*val)
|
||||
} else {
|
||||
Err(format!("Cannot find variable `{name}` in scope"))
|
||||
}
|
||||
},
|
||||
|
||||
Expression::Integer(x) => Ok((*x) as f64),
|
||||
// Types
|
||||
Expression::Integer(x) => Ok((*x) as f64), // todo
|
||||
|
||||
Expression::Float(_) => todo!(),
|
||||
Expression::Float(x) => Ok(*x),
|
||||
|
||||
Expression::String(_) => todo!(),
|
||||
|
||||
Expression::Bool(_) => todo!(),
|
||||
|
||||
// Operations
|
||||
Expression::Negatation(lhs) => todo!(),
|
||||
|
||||
Expression::Add(lhs, rhs) => Ok(eval(lhs, vars, funcs)? + eval(rhs, vars, funcs)?),
|
||||
|
|
@ -57,14 +69,26 @@ pub fn eval<'src>(
|
|||
|
||||
Expression::Divide(lhs, rhs) => Ok(eval(lhs, vars, funcs)? / eval(rhs, vars, funcs)?),
|
||||
|
||||
Expression::Var { name, rhs, then } => todo!(),
|
||||
// Keywords
|
||||
Expression::Var { name, rhs, then } => {
|
||||
let rhs = eval(rhs, vars, funcs)?;
|
||||
vars.push((*name, rhs));
|
||||
let output = eval(then, vars, funcs);
|
||||
vars.pop();
|
||||
output
|
||||
},
|
||||
|
||||
Expression::Function {
|
||||
name,
|
||||
args,
|
||||
body,
|
||||
then,
|
||||
} => todo!(),
|
||||
} => {
|
||||
funcs.push((name, args, body));
|
||||
let output = eval(then, vars, funcs);
|
||||
funcs.pop();
|
||||
output
|
||||
},
|
||||
|
||||
Expression::Unit => todo!(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
pub mod ast;
|
||||
pub mod op;
|
||||
pub mod parser;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
use chumsky::{
|
||||
IterParser, Parser,
|
||||
combinator::Or,
|
||||
prelude::{choice, just, recursive},
|
||||
recursive, select,
|
||||
text::{self, ascii::ident},
|
||||
combinator::Or, prelude::{choice, just, recursive}, recursive, select, select_ref, text::{self, ascii::ident, whitespace}, IterParser, Parser
|
||||
};
|
||||
|
||||
use crate::{language_frontend::abstract_syntax_tree::ast::Expression, language_frontend::lexer::tokens::Token};
|
||||
|
|
@ -12,8 +8,8 @@ use crate::{language_frontend::abstract_syntax_tree::ast::Expression, language_f
|
|||
|
||||
#[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 ident = select_ref! {
|
||||
Token::Ident(ident) => *ident
|
||||
};
|
||||
|
||||
let keyword = |kw: &'static str| {
|
||||
|
|
@ -41,6 +37,8 @@ pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>
|
|||
.repeated()
|
||||
.foldr(atom, |_op, rhs| Expression::Negatation(Box::new(rhs)));
|
||||
|
||||
// "Punktrechnung vor Strichrechnung :nerd:"
|
||||
|
||||
let binary_1 = unary.clone().foldl(
|
||||
just(Token::Multiply)
|
||||
.or(just(Token::Divide))
|
||||
|
|
@ -70,9 +68,9 @@ pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>
|
|||
|
||||
let decl = recursive(|decl| {
|
||||
let r#var = keyword("var")
|
||||
.ignore_then(ident.clone())
|
||||
.ignore_then(ident)
|
||||
.then_ignore(eq.clone())
|
||||
.then(decl.clone())
|
||||
.then(expr.clone())
|
||||
.then(decl.clone())
|
||||
.map(|((name, rhs), then)| Expression::Var {
|
||||
name,
|
||||
|
|
@ -82,10 +80,10 @@ pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>
|
|||
|
||||
let r#fun = keyword("fun")
|
||||
.ignore_then(ident.clone())
|
||||
.then(ident.clone().repeated().collect())
|
||||
.then(ident.repeated().collect::<Vec<_>>())
|
||||
.then_ignore(eq.clone())
|
||||
.then(decl.clone())
|
||||
.then(decl.clone())
|
||||
.then(expr.clone())
|
||||
.then(decl)
|
||||
.map(|(((name, args), body), then)| Expression::Function {
|
||||
name,
|
||||
args,
|
||||
|
|
@ -37,9 +37,12 @@ pub enum Token<'src> {
|
|||
#[token("}")]
|
||||
BraceEnd,
|
||||
|
||||
#[regex("[0-9]+", |lex| lex.slice().parse::<i64>().unwrap())]
|
||||
#[regex(r"[+-]?[0-9]+", |lex| lex.slice().parse::<i64>().unwrap(), priority = 3)]
|
||||
Integer(i64),
|
||||
|
||||
#[regex(r"[+-]?([0-9]*[.])?[0-9]+", |lex| lex.slice().parse::<f64>().unwrap())]
|
||||
Float(f64),
|
||||
|
||||
#[regex(r"[_a-zA-Z][_0-9a-zA-Z]*")]
|
||||
Ident(&'src str),
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,2 @@
|
|||
pub mod abstract_syntax_tree;
|
||||
pub mod lexer;
|
||||
pub mod parser;
|
||||
|
|
|
|||
20
src/main.rs
20
src/main.rs
|
|
@ -1,11 +1,11 @@
|
|||
use chumsky::Parser;
|
||||
use logos::Logos;
|
||||
|
||||
use crate::language_frontend::abstract_syntax_tree;
|
||||
use crate::{
|
||||
language_frontend::lexer::tokens::Token, language_frontend::parser::parser};
|
||||
language_frontend::lexer::tokens::Token, language_frontend::abstract_syntax_tree::parser::parser};
|
||||
|
||||
use crate::language_frontend::abstract_syntax_tree::ast::{eval, Expression};
|
||||
|
||||
mod language_frontend;
|
||||
|
||||
/*
|
||||
|
|
@ -17,7 +17,8 @@ Simple Compiler -> 4 Stages:
|
|||
*/
|
||||
|
||||
fn main() {
|
||||
let lexer = Token::lexer("1 + 1 * 3");
|
||||
let sourcecode = std::fs::read_to_string("sample.akai").unwrap();
|
||||
let lexer = Token::lexer(&sourcecode);
|
||||
|
||||
let mut tokens = vec![];
|
||||
for (token, span) in lexer.spanned() {
|
||||
|
|
@ -30,19 +31,6 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
match parser().parse(&tokens).into_result() {
|
||||
Ok(expr) => match eval(&ast, &mut Vec::new(), &mut Vec::new()) {
|
||||
Ok(output) => println!("{output}"),
|
||||
Err(eval_err) => println!("Evaluation error: {eval_err}"),
|
||||
}
|
||||
Err(e) => {
|
||||
println!("parse error: {:#?}", e);
|
||||
return;
|
||||
}
|
||||
}; */
|
||||
|
||||
|
||||
match parser().parse(&tokens).into_result() {
|
||||
Ok(ast) => match eval(&ast, &mut Vec::new(), &mut Vec::new()) {
|
||||
Ok(output) => println!("{output}"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue