From 28377bd3c271e70afc27c297c19a28884d70d288 Mon Sep 17 00:00:00 2001 From: JOLIMAITRE Matthieu Date: Mon, 12 Jun 2023 01:02:07 +0200 Subject: [PATCH] various fixes --- Cargo.lock | 32 +++++++-------- Cargo.toml | 6 +-- README.md | 10 ++--- examples/array.pr | 77 +++++++++++++++++++++++++++++------- examples/hello-world.pr | 4 +- src/execution_tree/parser.rs | 16 ++++---- src/main.rs | 10 ++--- src/prelude.rs | 12 +++--- src/runtime.rs | 34 ++++++++++------ src/syntax_tree/parser.rs | 29 ++++++++------ src/value.rs | 6 +-- 11 files changed, 149 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5dea35e..402a8a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "const-random" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4" +checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e" dependencies = [ "const-random-macro", "proc-macro-hack", @@ -38,12 +38,12 @@ dependencies = [ [[package]] name = "const-random-macro" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40" +checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb" dependencies = [ "getrandom", - "lazy_static", + "once_cell", "proc-macro-hack", "tiny-keccak", ] @@ -65,12 +65,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.126" @@ -78,18 +72,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] -name = "proc-macro-hack" -version = "0.5.19" +name = "once_cell" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] -name = "prout" -version = "0.3.0" +name = "porte" +version = "0.4.0" dependencies = [ "chumsky", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "tiny-keccak" version = "2.0.2" diff --git a/Cargo.toml b/Cargo.toml index be6f6a9..ad121e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "prout" -version = "0.3.0" +name = "porte" +version = "0.4.0" edition = "2021" authors = ["JOLIMAITRE Matthieu "] description = "A minimal programming language providing tools to automate file management like backups, building process or unit testing." license = "MIT" -repository = "https://github.com/MajorBarnulf/prout" +repository = "https://github.com/MajorBarnulf/porte" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md index 2e25b19..527c8b3 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ -# PROUT +# PORTE * Programmable -* Repeatable * Opinionated -* Understandable +* Repeatable * Tiny +* Extensible ## Description -PROUT is a minimal programming language providing tools to automate file management like backups, building process or unit testing. +PORTE is a minimal programming language providing tools to automate file management like backups, building process or unit testing. ## Usage @@ -17,7 +17,7 @@ PROUT is a minimal programming language providing tools to automate file managem ```sh -$ prout hello-world.pr +$ porte hello-world.pr ``` diff --git a/examples/array.pr b/examples/array.pr index abd9097..2b65370 100644 --- a/examples/array.pr +++ b/examples/array.pr @@ -22,6 +22,13 @@ array_get: (self, index) => { get(self, str(index)) }; +foreach: (arr, f) => { + l: array_len(arr); + for(0, l, (i) => { + f(array_get(arr, i)) + }) +}; + array_push: (self, e) => { i: array_len(self); self <- set(self, str(i), e); @@ -38,31 +45,73 @@ array_pop: (self) => { i: sub(l, 1); e: array_get(self, i); self <- set(self, str(i), false); - + + rest: array_new(); + foreach(self, (item) => { if not(eq(item, false)) rest <- array_push(rest, item) }); + r: obj(); r <- set(r, "tail", e); - r <- set(r, "rest", self); + r <- set(r, "rest", rest); r }; +array_swap: (self, i, j) => { + i_value: array_get(self, i); + j_value: array_get(self, j); + self <- set(self, str(j), i_value); + self <- set(self, str(i), j_value); + self +}; + +array_sort: (self, cmp) => { + l: array_len(self); + for(0, sub(l, 1), (i) => { + i_min: i; + for(add(i, 1), l, (j) => { + e_j: array_get(self, j); + e_min: array_get(self, i_min); + if inf(cmp(e_j, e_min), 0) i_min <- j + }); + self <- array_swap(self, i, i_min) + }); + self +}; + array_print: (self) => { l: array_len(self); - r: "["; + r: "[ "; for(0, l, (i) => { r <- add(r, array_get(self, i)); - r <- add(r, ", ") + if not(eq(i, sub(l, 1))) r <- add(r, ", ") }); - r <- add(r, "]"); + r <- add(r, " ]"); out(r) }; -main: () => { - a: array_new(); - a <- array_push(a, 1); - a <- array_push(a, 2); - a <- array_push(a, 3); - a <- array_push(a, 4); - array_print(a) -}; +"########################"; +"# main #"; +"########################"; -main(); +a: array_new(); +out("new:"); +array_print(a); + +a <- array_push(a, 1); +a <- array_push(a, 4); +a <- array_push(a, 6); +a <- array_push(a, 3); +a <- array_push(a, 2); +out(""); +out("pushed:"); +array_print(a); + +r: array_pop(a); +a <- get(r, "rest"); +out(""); +out("popped:"); +array_print(a); + +a <- array_sort(a, (a, b) => { if sup(a, b) 1 else -1 }); +out(""); +out("sorted:"); +array_print(a); diff --git a/examples/hello-world.pr b/examples/hello-world.pr index c7862c1..0b3072d 100644 --- a/examples/hello-world.pr +++ b/examples/hello-world.pr @@ -1,10 +1,10 @@ hello: "hello"; -prout: "prout"; +porte: "porte"; line: hello; line <- add(line, " "); -line <- add(line, prout); +line <- add(line, porte); say-it: () => { out(line) diff --git a/src/execution_tree/parser.rs b/src/execution_tree/parser.rs index 6d2e59a..c504ac3 100644 --- a/src/execution_tree/parser.rs +++ b/src/execution_tree/parser.rs @@ -73,7 +73,7 @@ impl Parser { let parent_scope_id = parser_scope.get_parent_id(); let expressions = instructions .into_iter() - .map(|expression| self.parse_expression(expression, &parser_scope)) + .map(|expression| self.parse_expression(expression, parser_scope)) .collect(); let local_variables = parser_scope.local_variable_ids(); @@ -218,7 +218,7 @@ impl Parser { let variable_id = parser_scope .get_variable_id(&name) - .expect(&format!("call of undeclared function '{name}'")); + .unwrap_or_else(|| panic!("call of undeclared function '{name}'")); let parameters = arguments .into_iter() .map(|argument| self.parse_expression(argument, parser_scope)) @@ -390,7 +390,7 @@ impl ParserScope { next_id: self.next_id.clone(), variables: Rc::new(Mutex::new(variables)), current_id, - current_function_scope_id: Some(current_id.clone()), + current_function_scope_id: Some(current_id), current_loop_scope_id: None, } } @@ -409,24 +409,24 @@ impl ParserScope { variables: Rc::new(Mutex::new(variables)), current_id, current_function_scope_id: self.get_current_function_id(), - current_loop_scope_id: Some(current_id.clone()), + current_loop_scope_id: Some(current_id), } } pub fn get_current_id(&self) -> Id { - self.current_id.clone() + self.current_id } pub fn get_current_function_id(&self) -> Option { - self.current_function_scope_id.clone() + self.current_function_scope_id } pub fn get_current_loop_id(&self) -> Option { - self.current_loop_scope_id.clone() + self.current_loop_scope_id } pub fn get_parent_id(&self) -> Option { - self.parent_id.clone() + self.parent_id } pub fn get_variable_id(&self, name: &str) -> Option { diff --git a/src/main.rs b/src/main.rs index 6cb7da7..bedf467 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,20 +1,20 @@ use std::{env::args, fs}; +pub mod demo; pub mod execution_tree; pub mod prelude; pub mod runtime; pub mod syntax_tree; pub mod value; -pub mod demo; fn main() { use prelude::std_prelude; - let path = args().nth(1).expect("[error]: usage 'prout '"); + let path = args().nth(1).expect("[error]: usage 'porte '"); let input = fs::read_to_string(path).expect("file not found"); let ast_parser = syntax_tree::parser::ParserWrapper::new(); let parsed = ast_parser.parse(&input).unwrap(); - let executable = execution_tree::parser::Parser::parse(parsed, |b| std_prelude(b)); + let executable = execution_tree::parser::Parser::parse(parsed, std_prelude); let mut runtime = runtime::Runtime::new(); runtime.execute(&executable); } @@ -40,11 +40,11 @@ fn it_works() { ]), ), ), - Expr::new_function_call("my_print", vec!["hello, PROUT".into()]), + Expr::new_function_call("my_print", vec!["hello, PORTE".into()]), Expr::new_function_call("print", vec![Expr::new_variable_call("a")]), ]), }; - let exec = Parser::parse(ast, |builder| std_prelude(builder)); + let exec = Parser::parse(ast, std_prelude); println!("\n\n\n-- running: --"); let _result = Runtime::new().execute(&exec); } diff --git a/src/prelude.rs b/src/prelude.rs index a6a3a71..0869c9e 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -6,7 +6,8 @@ use crate::{ }; pub fn std_prelude(builder: &mut ParserBuilder) { - let functions: Vec<(_, _, fn(Vec) -> Value)> = vec![ + type FunctOper = fn(Vec) -> Value; + let functions: Vec<(_, _, FunctOper)> = vec![ ("out", 1, out), ("add", 2, add), ("sub", 2, sub), @@ -42,7 +43,7 @@ fn add(args: Vec) -> Value { (Value::String(l), Value::String(r)) => format!("{l}{r}").into(), (Value::Number(l), Value::String(r)) => format!("{l}{r}").into(), (Value::String(l), Value::Number(r)) => format!("{l}{r}").into(), - _ => unreachable!(), + _ => panic!("adding incompatible types"), } } @@ -62,7 +63,7 @@ fn eq(args: Vec) -> Value { (Value::Bool(l), Value::Bool(r)) => (l == r).into(), (Value::Number(l), Value::Number(r)) => (l == r).into(), (Value::String(l), Value::String(r)) => (l == r).into(), - _ => panic!("comparing different types"), + _ => false.into(), } } @@ -143,8 +144,5 @@ fn set(args: Vec) -> Value { fn get(args: Vec) -> Value { let object = args.get(0).unwrap().as_object().unwrap(); let name = args.get(1).unwrap().as_string().unwrap(); - object - .get(name) - .map(|value| value.clone()) - .unwrap_or_else(|| false.into()) + object.get(name).cloned().unwrap_or_else(|| false.into()) } diff --git a/src/runtime.rs b/src/runtime.rs index 4ee2cf8..22df2d4 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -24,7 +24,7 @@ impl FrameBuilder { } pub fn variable(&mut self, variable_id: &Id, default: Value) { - self.variables.insert(variable_id.clone(), default); + self.variables.insert(*variable_id, default); } } @@ -52,7 +52,7 @@ impl Frame { builder(&mut frame_builder); let FrameBuilder { variables } = frame_builder; - let scope_id = scope_id.clone(); + let scope_id = *scope_id; Self { _scope_id: scope_id, variables, @@ -99,6 +99,12 @@ impl Stack { } } +impl Default for Stack { + fn default() -> Self { + Self::new() + } +} + pub struct ShortCircuit { value: Value, destination_scope_id: Id, @@ -138,9 +144,9 @@ impl ExecReturn { } } -impl Into for Value { - fn into(self) -> ExecReturn { - ExecReturn::new_value(self) +impl From for ExecReturn { + fn from(val: Value) -> Self { + ExecReturn::new_value(val) } } @@ -169,7 +175,7 @@ impl Runtime { where F: FnOnce(&mut FrameBuilder), { - let scope = program.scopes.get(&scope_id).unwrap(); + let scope = program.scopes.get(scope_id).unwrap(); let Scope { parent_scope_id: _, expressions, @@ -210,9 +216,7 @@ impl Runtime { ExprInner::FnDef(function_definition) => { self.execute_function_definition(function_definition) } - ExprInner::FnCall(function_call) => { - self.execute_function_call(function_call, program).into() - } + ExprInner::FnCall(function_call) => self.execute_function_call(function_call, program), ExprInner::FnRet(function_return) => { self.execute_function_return(function_return, program) } @@ -272,7 +276,7 @@ impl Runtime { parameter_ids: argument_ids, body_scope_id, } = function_definition; - let value = Function::new_constructed(argument_ids.clone(), body_scope_id.clone()); + let value = Function::new_constructed(argument_ids.clone(), *body_scope_id); let value = Value::Function(value); value.into() } @@ -367,7 +371,7 @@ impl Runtime { }) => value, }; - ExecReturn::new_short_circuit(value, function_scope_id.clone()) + ExecReturn::new_short_circuit(value, *function_scope_id) } pub fn execute_loop(&mut self, loop_: &Loop, program: &Program) -> ExecReturn { @@ -401,7 +405,7 @@ impl Runtime { } }; - ExecReturn::new_short_circuit(value, loop_scope_id.clone()) + ExecReturn::new_short_circuit(value, *loop_scope_id) } pub fn execute_condition(&mut self, condition: &Cond, program: &Program) -> ExecReturn { @@ -432,3 +436,9 @@ impl Runtime { } } } + +impl Default for Runtime { + fn default() -> Self { + Self::new() + } +} diff --git a/src/syntax_tree/parser.rs b/src/syntax_tree/parser.rs index 3ce7100..fbdb93f 100644 --- a/src/syntax_tree/parser.rs +++ b/src/syntax_tree/parser.rs @@ -52,8 +52,7 @@ pub fn literal_value() -> impl AbstractParser { .unwrapped() .map(|n: f64| n.into()); - let literal = bool.or(none).or(string).or(number); - literal + bool.or(none).or(string).or(number) } #[test] @@ -66,11 +65,11 @@ fn test_literal_value() { pub fn name() -> impl AbstractParser + Clone { let first = one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); let rest = first.clone().or(one_of("1234567890-_+/*")); - let name = first.then(rest.repeated()).map(|(f, v)| { + + first.then(rest.repeated()).map(|(f, v)| { let rest = String::from_iter(&v); format!("{f}{rest}") - }); - name + }) } pub fn variable_definition_parser( @@ -205,7 +204,7 @@ pub fn condition_parser( just("if ") .ignore_then(expression.clone()) .then(expression.clone()) - .then(just("else ").ignore_then(expression.clone()).or_not()) + .then(just("else ").ignore_then(expression).or_not()) .map(|((condition, arm_true), arm_false)| Cond { condition, arm_true, @@ -296,7 +295,7 @@ fn _sugar_parser(expression: impl AbstractParser + Clone) -> impl Abstract let and = expression .clone() .then_ignore(just(" && ")) - .then(expression.clone()) + .then(expression) .map(|(l, r)| { FnCall { name: "and".into(), @@ -317,7 +316,7 @@ pub fn expression_parser() -> impl AbstractParser { let loop_ = loop_parser(expression.clone()).map(|i| i.into()); let loop_break = loop_break_parser(expression.clone()).map(|i| i.into()); let scope = scope_parser(expression.clone()).map(|i| i.into()); - let litteral = literal_value().map(|v| Expr::new_literal(v)); + let litteral = literal_value().map(Expr::new_literal); let variable_definition = variable_definition_parser(expression.clone()).map(|i| i.into()); let variable_assignment = variable_assignement_parser(expression.clone()).map(|i| i.into()); let function_call = function_call_parser(expression.clone()).map(|i| i.into()); @@ -354,11 +353,11 @@ fn parser() -> impl AbstractParser { .separated_by(just(';').padded()) .then_ignore(just(';').padded().or_not()) .then_ignore(end()); - let program = scope.map(|instructions| { + + scope.map(|instructions| { let body = Scope { instructions }; Program { body } - }); - program + }) } #[test] @@ -390,11 +389,17 @@ impl ParserWrapper { ParserWrapper { inner } } - pub fn parse<'i>(&self, input: &'i str) -> Result>> { + pub fn parse(&self, input: &str) -> Result>> { self.inner.parse(input) } } +impl Default for ParserWrapper { + fn default() -> Self { + Self::new() + } +} + /* // example diff --git a/src/value.rs b/src/value.rs index 463e766..7f4b424 100644 --- a/src/value.rs +++ b/src/value.rs @@ -55,9 +55,9 @@ pub mod function { } } - impl Into for Function { - fn into(self) -> Value { - Value::Function(self) + impl From for Value { + fn from(val: Function) -> Self { + Value::Function(val) } } }