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
|
/target
|
||||||
*.sh
|
*.sh
|
||||||
|
sample.akai
|
||||||
|
|
@ -2,19 +2,23 @@
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Expression<'src> {
|
pub enum Expression<'src> {
|
||||||
|
// Identifier
|
||||||
Ident(&'src str),
|
Ident(&'src str),
|
||||||
|
|
||||||
|
// Types
|
||||||
Integer(i64),
|
Integer(i64),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
String(String),
|
String(String),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
|
|
||||||
|
// Operations
|
||||||
Negatation(Box<Expression<'src>>),
|
Negatation(Box<Expression<'src>>),
|
||||||
Add(Box<Expression<'src>>, Box<Expression<'src>>),
|
Add(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||||
Substract(Box<Expression<'src>>, Box<Expression<'src>>),
|
Substract(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||||
Multiply(Box<Expression<'src>>, Box<Expression<'src>>),
|
Multiply(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||||
Divide(Box<Expression<'src>>, Box<Expression<'src>>),
|
Divide(Box<Expression<'src>>, Box<Expression<'src>>),
|
||||||
|
|
||||||
|
// Keywords
|
||||||
Var {
|
Var {
|
||||||
name: &'src str,
|
name: &'src str,
|
||||||
rhs: Box<Expression<'src>>,
|
rhs: Box<Expression<'src>>,
|
||||||
|
|
@ -37,16 +41,24 @@ pub fn eval<'src>(
|
||||||
funcs: &mut Vec<(&'src str, &'src [&'src str], &'src Expression<'src>)>,
|
funcs: &mut Vec<(&'src str, &'src [&'src str], &'src Expression<'src>)>,
|
||||||
) -> Result<f64, String> {
|
) -> Result<f64, String> {
|
||||||
match expr {
|
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::String(_) => todo!(),
|
||||||
|
|
||||||
Expression::Bool(_) => todo!(),
|
Expression::Bool(_) => todo!(),
|
||||||
|
|
||||||
|
// Operations
|
||||||
Expression::Negatation(lhs) => todo!(),
|
Expression::Negatation(lhs) => todo!(),
|
||||||
|
|
||||||
Expression::Add(lhs, rhs) => Ok(eval(lhs, vars, funcs)? + eval(rhs, vars, funcs)?),
|
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::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 {
|
Expression::Function {
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
body,
|
body,
|
||||||
then,
|
then,
|
||||||
} => todo!(),
|
} => {
|
||||||
|
funcs.push((name, args, body));
|
||||||
|
let output = eval(then, vars, funcs);
|
||||||
|
funcs.pop();
|
||||||
|
output
|
||||||
|
},
|
||||||
|
|
||||||
Expression::Unit => todo!(),
|
Expression::Unit => todo!(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
pub mod op;
|
pub mod op;
|
||||||
|
pub mod parser;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
use chumsky::{
|
use chumsky::{
|
||||||
IterParser, Parser,
|
combinator::Or, prelude::{choice, just, recursive}, recursive, select, select_ref, text::{self, ascii::ident, whitespace}, IterParser, Parser
|
||||||
combinator::Or,
|
|
||||||
prelude::{choice, just, recursive},
|
|
||||||
recursive, select,
|
|
||||||
text::{self, ascii::ident},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{language_frontend::abstract_syntax_tree::ast::Expression, language_frontend::lexer::tokens::Token};
|
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)]
|
#[allow(clippy::let_and_return)]
|
||||||
pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>> {
|
pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>> {
|
||||||
let ident = select! {
|
let ident = select_ref! {
|
||||||
Token::Ident(ident) => ident
|
Token::Ident(ident) => *ident
|
||||||
};
|
};
|
||||||
|
|
||||||
let keyword = |kw: &'static str| {
|
let keyword = |kw: &'static str| {
|
||||||
|
|
@ -41,6 +37,8 @@ pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>
|
||||||
.repeated()
|
.repeated()
|
||||||
.foldr(atom, |_op, rhs| Expression::Negatation(Box::new(rhs)));
|
.foldr(atom, |_op, rhs| Expression::Negatation(Box::new(rhs)));
|
||||||
|
|
||||||
|
// "Punktrechnung vor Strichrechnung :nerd:"
|
||||||
|
|
||||||
let binary_1 = unary.clone().foldl(
|
let binary_1 = unary.clone().foldl(
|
||||||
just(Token::Multiply)
|
just(Token::Multiply)
|
||||||
.or(just(Token::Divide))
|
.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 decl = recursive(|decl| {
|
||||||
let r#var = keyword("var")
|
let r#var = keyword("var")
|
||||||
.ignore_then(ident.clone())
|
.ignore_then(ident)
|
||||||
.then_ignore(eq.clone())
|
.then_ignore(eq.clone())
|
||||||
.then(decl.clone())
|
.then(expr.clone())
|
||||||
.then(decl.clone())
|
.then(decl.clone())
|
||||||
.map(|((name, rhs), then)| Expression::Var {
|
.map(|((name, rhs), then)| Expression::Var {
|
||||||
name,
|
name,
|
||||||
|
|
@ -82,10 +80,10 @@ pub fn parser<'src>() -> impl Parser<'src, &'src [Token<'src>], Expression<'src>
|
||||||
|
|
||||||
let r#fun = keyword("fun")
|
let r#fun = keyword("fun")
|
||||||
.ignore_then(ident.clone())
|
.ignore_then(ident.clone())
|
||||||
.then(ident.clone().repeated().collect())
|
.then(ident.repeated().collect::<Vec<_>>())
|
||||||
.then_ignore(eq.clone())
|
.then_ignore(eq.clone())
|
||||||
.then(decl.clone())
|
.then(expr.clone())
|
||||||
.then(decl.clone())
|
.then(decl)
|
||||||
.map(|(((name, args), body), then)| Expression::Function {
|
.map(|(((name, args), body), then)| Expression::Function {
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
|
|
@ -37,9 +37,12 @@ pub enum Token<'src> {
|
||||||
#[token("}")]
|
#[token("}")]
|
||||||
BraceEnd,
|
BraceEnd,
|
||||||
|
|
||||||
#[regex("[0-9]+", |lex| lex.slice().parse::<i64>().unwrap())]
|
#[regex(r"[+-]?[0-9]+", |lex| lex.slice().parse::<i64>().unwrap(), priority = 3)]
|
||||||
Integer(i64),
|
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]*")]
|
#[regex(r"[_a-zA-Z][_0-9a-zA-Z]*")]
|
||||||
Ident(&'src str),
|
Ident(&'src str),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod abstract_syntax_tree;
|
pub mod abstract_syntax_tree;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
pub mod parser;
|
|
||||||
|
|
|
||||||
20
src/main.rs
20
src/main.rs
|
|
@ -1,11 +1,11 @@
|
||||||
use chumsky::Parser;
|
use chumsky::Parser;
|
||||||
use logos::Logos;
|
use logos::Logos;
|
||||||
|
|
||||||
use crate::language_frontend::abstract_syntax_tree;
|
|
||||||
use crate::{
|
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};
|
use crate::language_frontend::abstract_syntax_tree::ast::{eval, Expression};
|
||||||
|
|
||||||
mod language_frontend;
|
mod language_frontend;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -17,7 +17,8 @@ Simple Compiler -> 4 Stages:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn main() {
|
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![];
|
let mut tokens = vec![];
|
||||||
for (token, span) in lexer.spanned() {
|
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() {
|
match parser().parse(&tokens).into_result() {
|
||||||
Ok(ast) => match eval(&ast, &mut Vec::new(), &mut Vec::new()) {
|
Ok(ast) => match eval(&ast, &mut Vec::new(), &mut Vec::new()) {
|
||||||
Ok(output) => println!("{output}"),
|
Ok(output) => println!("{output}"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue