Add functions and some clean up

This commit is contained in:
Julius 2022-07-03 16:01:45 +02:00
parent df3f0bf0a7
commit c67cbf66e6
Signed by: j00lz
GPG key ID: AF241B0AA237BBA2
6 changed files with 111 additions and 195 deletions

View file

@ -47,14 +47,6 @@ impl Env<'_> {
false false
} }
} }
pub fn update(&self, name: &str, f: impl FnOnce(&Value) -> Value) {
if let Some(v) = self.values.write().unwrap().get_mut(name) {
*v = f(v);
} else if let Some(parent) = self.parent {
parent.update(name, f);
}
}
} }
impl<'env> Env<'env> { impl<'env> Env<'env> {

View file

@ -3,7 +3,7 @@ use std::{collections::HashMap, marker::PhantomData};
use crate::{ use crate::{
env::Env, env::Env,
statement::Statement, statement::Statement,
value::{FromValue, Value}, value::{FromValue, Value}, pest_parser::FuncHolder,
}; };
mod function_impl; mod function_impl;
@ -44,6 +44,12 @@ impl FunctionMap {
); );
} }
pub fn insert_holder(&mut self, holder:FuncHolder) {
for f in holder {
self.insert_interpreter(&f.0, f.1, f.2);
}
}
pub fn call(&self, name: &str, env: &Env, args: &[Value]) -> Result<Value, String> { pub fn call(&self, name: &str, env: &Env, args: &[Value]) -> Result<Value, String> {
let (f, t) = self let (f, t) = self
.0 .0

View file

@ -49,7 +49,7 @@ root_statement = {
SOI ~ statement* ~ EOI SOI ~ statement* ~ EOI
} }
statement = { ( assignment | assignment_let | expression ) ~ ";" | while_block | if_block | block } statement = { ( assignment | assignment_let | expression ) ~ ";" | def | while_block | if_block | block }
block = { "{" ~ statement* ~ "}" } block = { "{" ~ statement* ~ "}" }
@ -61,6 +61,10 @@ while_block = { "while" ~ expression ~ block }
if_block = { "if" ~ expression ~ block ~ ("else if" ~ expression ~ block)* ~ ("else" ~ block)? } if_block = { "if" ~ expression ~ block ~ ("else if" ~ expression ~ block)* ~ ("else" ~ block)? }
def_params = { "(" ~ (identifier ~ ","?)* ~ ")" }
def = { "def" ~ identifier ~ def_params ~ block }
equals = { "==" } equals = { "==" }
not_equals = { "!=" } not_equals = { "!=" }

View file

@ -1,9 +1,7 @@
use std::fs::read_to_string; use std::fs::read_to_string;
use env::Env; use env::Env;
use expression::{BinaryOperation, Expression}; use function::FunctionMap;
use function::{Function, FunctionMap, NativeFunction};
use pest::Parser;
use statement::Statement; use statement::Statement;
use value::Value; use value::Value;
@ -17,125 +15,19 @@ mod value;
// mod parser; // mod parser;
mod pest_parser; mod pest_parser;
fn run(functions: FunctionMap, statements: &[Statement]) { fn run(functions: FunctionMap, statement: Statement) {
let env = Env::new(); let env = Env::new();
for statement in statements { statement.eval(&env, &functions);
statement.eval(&env, &functions);
}
} }
fn main() { fn main() {
// let statements = vec![
// Statement::Assignment("a".to_string(), Expression::from(1)),
// Statement::Assignment("b".to_string(), Expression::from(2)),
// Statement::Assignment("c".to_string(), Expression::from(3)),
// Statement::Print(Expression::Binary(
// Box::new(Expression::Variable("a".to_string())),
// BinaryOperation::Add,
// Box::new(Expression::Variable("b".to_string())),
// )),
// Statement::Print(Expression::Binary(
// Box::new(Expression::Variable("a".to_string())),
// BinaryOperation::Add,
// Box::new(Expression::Variable("c".to_string())),
// )),
// Statement::Print(Expression::Binary(
// Box::new(Expression::Variable("b".to_string())),
// BinaryOperation::Add,
// Box::new(Expression::Variable("c".to_string())),
// )),
// ];
// run(FunctionMap::new(), &statements);
// let while_test = vec![
// Statement::Print("while test".to_string().into()),
// Statement::Assignment("a".to_string(), Expression::from(1)),
// Statement::While(
// Expression::Binary(
// Box::new(Expression::Variable("a".to_string())),
// BinaryOperation::LessThan,
// Box::new(10.into()),
// ),
// vec![
// Statement::Assignment(
// "a".to_string(),
// Expression::Binary(
// Box::new(Expression::Variable("a".to_string())),
// BinaryOperation::Add,
// Box::new(1.into()),
// ),
// ),
// Statement::Print(Expression::Variable("a".to_string())),
// ],
// ),
// ];
// run(FunctionMap::new(), &while_test);
// {
// let env = Env::new();
// let res = (|arg: &i32| arg + 1).native_execute(&env, &[Value::Int(1)]);
// println!("{:?}", res);
// }
// {
// let z = || 100;
// let env = Env::new();
// let res = z.native_execute(&env, &[]);
// println!("{:?}", res);
// }
// {
// let z = |a: &Value| a.clone();
// let env = Env::new();
// let res = z.into_function().execute(&env, &FunctionMap::new(), &[]);
// println!("{:?}", res);
// }
// {
// let z = |a: &String| a.clone();
// let env = Env::new();
// let res = z.native_execute(&env, &[100.into()]);
// println!("{:?}", res);
// }
// {
// let v: Vec<Box<dyn Function>> = vec![
// Box::new((|| 100).into_function()),
// Box::new((|a: &i32| a + 1).into_function()),
// ];
// for f in v {
// let r = f.execute(&Env::new(), &FunctionMap::new(), &[100.into()]);
// println!("{:?}", r);
// }
// }
// let mut m: FunctionMap = Default::default();
// m.insert_native("print", |a: &Value| {
// println!("{}", a);
// });
// m.insert_native("waluigi", || "Waluigi");
// m.insert_interpreter("call_print", vec!["what".to_string()], vec![
// Statement::Expression(Expression::Call("print".to_string(), vec![Expression::Variable("what".to_string())])),
// ]);
// run(
// m,
// &vec![Statement::Expression(Expression::Call(
// "call_print".to_string(),
// vec![Expression::Call("waluigi".to_string(), vec![])],
// ))],
// );
let f = read_to_string("./test.foo").unwrap(); let f = read_to_string("./test.foo").unwrap();
let mut m: FunctionMap = Default::default(); let (res, funcs) = pest_parser::parse(f);
let mut m = FunctionMap::new();
m.insert_holder(funcs);
m.insert_native("print", |a: &Value| { m.insert_native("print", |a: &Value| {
println!("{}", a); println!("{}", a);
}); });
m.insert_native("waluigi", || "Waluigi"); m.insert_native("waluigi", || "Waluigi");
let res = pest_parser::parse(f); run(m, res);
let env = &Env::new();
res.eval(env, &m);
} }

View file

@ -1,77 +1,72 @@
use pest::{iterators::Pair, Parser}; use pest::{iterators::Pair, Parser};
use pest_derive::Parser; use pest_derive::Parser;
use crate::{ use crate::{expression::Expression, statement::Statement, value::Value};
expression::{BinaryOperation, Expression},
statement::Statement,
value::Value,
};
#[derive(Parser)] #[derive(Parser)]
#[grammar = "grammar.pest"] #[grammar = "grammar.pest"]
pub struct LangParser; pub struct LangParser;
pub fn parse<S: ToString>(source: S) -> Statement { pub fn parse<S: ToString>(source: S) -> (Statement, FuncHolder) {
let source = source.to_string(); let source = source.to_string();
let pairs = LangParser::parse(Rule::root_statement, &source).unwrap(); let pairs = LangParser::parse(Rule::root_statement, &source).unwrap();
handle_rules(pairs) handle_rules(pairs)
} }
type Func = (String, Vec<String>, Vec<Statement>);
pub fn parser_test() { #[derive(Default)]
// let p = LangParser::parse(Rule::number, "-273.15").unwrap(); pub struct FuncHolder(Vec<Func>);
// println!("{:?}", p);
// let p = LangParser::parse(Rule::number, "25565");
// println!("{:?}", p);
// let str_test = LangParser::parse(Rule::string, "\"hello\"").unwrap(); impl FuncHolder {
// println!("{:?}", str_test); fn insert(mut self, name: String, params: Vec<String>, body: Vec<Statement>) -> Self {
self.0.push((name, params, body));
// let str_test = LangParser::parse(Rule::char, "'a'").unwrap(); self
// println!("{:?}", str_test); }
// let foo = LangParser::parse(Rule::statement, "10 + foo + bar(20) * 40;").unwrap();
// println!("{:?}", foo);
// let bar = "
// let x = 10;
// let y = 20;
// let z = x + y;
// print(z);
// while (x < y) {
// x = x + 1;
// }
// let x = x + \"lmao\";
// ";
// let bar = LangParser::parse(Rule::root_statement, bar);
// println!("{:?}", bar);
let baz = "
if x {
a;
} else if y {
b;
} else {
c;
}";
let baz = LangParser::parse(Rule::root_statement, baz);
println!("{:?}", baz);
let x = "x == 10;";
let x = LangParser::parse(Rule::statement, x);
handle_rules(x.unwrap());
} }
fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> Statement {
fn parse_statement(pair: Pair<Rule>) -> Statement { impl Extend<Func> for FuncHolder {
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = Func>,
{
self.0.extend(iter);
}
}
impl Extend<FuncHolder> for FuncHolder {
fn extend<T>(&mut self, iter: T)
where
T: IntoIterator<Item = FuncHolder>,
{
self.0
.extend(iter.into_iter().flat_map(|h| h.0.into_iter()));
}
}
impl IntoIterator for FuncHolder {
type Item = Func;
type IntoIter = std::vec::IntoIter<Func>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> (Statement, FuncHolder) {
fn parse_statement(pair: Pair<Rule>) -> (Statement, FuncHolder) {
match pair.as_rule() { match pair.as_rule() {
Rule::root_statement => { Rule::root_statement => {
Statement::Body(pair.into_inner().map(parse_statement).collect()) let (z, f) = pair.into_inner().map(parse_statement).unzip();
(Statement::Body(z), f)
} }
Rule::while_block => { Rule::while_block => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let expr = inner.next().unwrap(); let expr = inner.next().unwrap();
let body = inner.next().unwrap(); let body = inner.next().unwrap();
Statement::While(parse_expression(expr), Box::new(parse_statement(body))) (
Statement::While(parse_expression(expr), Box::new(parse_statement(body).0)),
FuncHolder::default(),
)
} }
Rule::if_block => { Rule::if_block => {
let mut inner = pair.into_inner().into_iter(); let mut inner = pair.into_inner().into_iter();
@ -80,31 +75,61 @@ fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> Statement {
while let Some(expr) = inner.next() { while let Some(expr) = inner.next() {
if expr.as_rule() == Rule::expression { if expr.as_rule() == Rule::expression {
let body = inner.next().unwrap(); let body = inner.next().unwrap();
the_list.push((parse_expression(expr), parse_statement(body))); the_list.push((parse_expression(expr), parse_statement(body).0));
} else { } else {
the_else = Some(Box::new(parse_statement(expr))); the_else = Some(Box::new(parse_statement(expr).0));
} }
} }
Statement::If(the_list, the_else) (Statement::If(the_list, the_else), FuncHolder::default())
} }
Rule::assignment => { Rule::assignment => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let name = inner.next().unwrap(); let name = inner.next().unwrap();
let expr = inner.next().unwrap(); let expr = inner.next().unwrap();
Statement::Assignment(name.as_str().to_string(), parse_expression(expr), false) (
Statement::Assignment(name.as_str().to_string(), parse_expression(expr), false),
FuncHolder::default(),
)
} }
Rule::assignment_let => { Rule::assignment_let => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let name = inner.next().unwrap(); let name = inner.next().unwrap();
let expr = inner.next().unwrap(); let expr = inner.next().unwrap();
Statement::Assignment(name.as_str().to_string(), parse_expression(expr), true) (
Statement::Assignment(name.as_str().to_string(), parse_expression(expr), true),
FuncHolder::default(),
)
} }
Rule::expression => Statement::Expression(parse_expression(pair)), Rule::expression => (
Statement::Expression(parse_expression(pair)),
FuncHolder::default(),
),
Rule::statement => { Rule::statement => {
let inner = pair.into_inner().next().unwrap(); let inner = pair.into_inner().next().unwrap();
parse_statement(inner) parse_statement(inner)
} }
Rule::EOI => Statement::Body(vec![]), Rule::block => {
let (z, _): (_, FuncHolder) = pair.into_inner().map(parse_statement).unzip();
(Statement::Body(z), FuncHolder::default())
}
Rule::def => {
let mut inner = pair.into_inner();
let name = inner.next().unwrap();
let args = inner
.next()
.unwrap()
.into_inner()
.map(|a| a.to_string())
.collect();
let body = inner.next().unwrap();
let body = parse_statement(body);
(
Statement::Body(vec![]),
FuncHolder::default().insert(name.as_str().to_string(), args, vec![body.0]),
)
}
Rule::EOI => (Statement::Body(vec![]), FuncHolder::default()),
x => unreachable!("How did we get to {:?}", x), x => unreachable!("How did we get to {:?}", x),
} }
} }
@ -209,13 +234,3 @@ fn handle_rules(mut p: pest::iterators::Pairs<Rule>) -> Statement {
let z = p.next().unwrap(); let z = p.next().unwrap();
parse_statement(z) parse_statement(z)
} }
#[cfg(test)]
mod tests {
use pest::Parser;
use super::{LangParser, Rule};
#[test]
fn foo() {}
}

View file

@ -1,3 +1,10 @@
foo();
def foo() {
print("hello, world!");
}
let x = 10; let x = 10;
let y = x-5; let y = x-5;