various fixes
This commit is contained in:
parent
c08c263f32
commit
28377bd3c2
11 changed files with 149 additions and 87 deletions
32
Cargo.lock
generated
32
Cargo.lock
generated
|
@ -28,9 +28,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-random"
|
name = "const-random"
|
||||||
version = "0.1.13"
|
version = "0.1.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4"
|
checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"const-random-macro",
|
"const-random-macro",
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
|
@ -38,12 +38,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-random-macro"
|
name = "const-random-macro"
|
||||||
version = "0.1.13"
|
version = "0.1.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40"
|
checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"lazy_static",
|
"once_cell",
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"tiny-keccak",
|
"tiny-keccak",
|
||||||
]
|
]
|
||||||
|
@ -65,12 +65,6 @@ dependencies = [
|
||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.126"
|
version = "0.2.126"
|
||||||
|
@ -78,18 +72,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-hack"
|
name = "once_cell"
|
||||||
version = "0.5.19"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prout"
|
name = "porte"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chumsky",
|
"chumsky",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-hack"
|
||||||
|
version = "0.5.20+deprecated"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-keccak"
|
name = "tiny-keccak"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
[package]
|
[package]
|
||||||
name = "prout"
|
name = "porte"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["JOLIMAITRE Matthieu <matthieu@imagevo.fr>"]
|
authors = ["JOLIMAITRE Matthieu <matthieu@imagevo.fr>"]
|
||||||
description = "A minimal programming language providing tools to automate file management like backups, building process or unit testing."
|
description = "A minimal programming language providing tools to automate file management like backups, building process or unit testing."
|
||||||
license = "MIT"
|
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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
10
README.md
10
README.md
|
@ -1,15 +1,15 @@
|
||||||
|
|
||||||
# PROUT
|
# PORTE
|
||||||
|
|
||||||
* Programmable
|
* Programmable
|
||||||
* Repeatable
|
|
||||||
* Opinionated
|
* Opinionated
|
||||||
* Understandable
|
* Repeatable
|
||||||
* Tiny
|
* Tiny
|
||||||
|
* Extensible
|
||||||
|
|
||||||
## Description
|
## 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
|
## Usage
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ PROUT is a minimal programming language providing tools to automate file managem
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
||||||
$ prout hello-world.pr
|
$ porte hello-world.pr
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -22,6 +22,13 @@ array_get: (self, index) => {
|
||||||
get(self, str(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) => {
|
array_push: (self, e) => {
|
||||||
i: array_len(self);
|
i: array_len(self);
|
||||||
self <- set(self, str(i), e);
|
self <- set(self, str(i), e);
|
||||||
|
@ -39,30 +46,72 @@ array_pop: (self) => {
|
||||||
e: array_get(self, i);
|
e: array_get(self, i);
|
||||||
self <- set(self, str(i), false);
|
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: obj();
|
||||||
r <- set(r, "tail", e);
|
r <- set(r, "tail", e);
|
||||||
r <- set(r, "rest", self);
|
r <- set(r, "rest", rest);
|
||||||
r
|
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) => {
|
array_print: (self) => {
|
||||||
l: array_len(self);
|
l: array_len(self);
|
||||||
r: "[";
|
r: "[ ";
|
||||||
for(0, l, (i) => {
|
for(0, l, (i) => {
|
||||||
r <- add(r, array_get(self, 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)
|
out(r)
|
||||||
};
|
};
|
||||||
|
|
||||||
main: () => {
|
"########################";
|
||||||
a: array_new();
|
"# main #";
|
||||||
a <- array_push(a, 1);
|
"########################";
|
||||||
a <- array_push(a, 2);
|
|
||||||
a <- array_push(a, 3);
|
|
||||||
a <- array_push(a, 4);
|
|
||||||
array_print(a)
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
hello: "hello";
|
hello: "hello";
|
||||||
prout: "prout";
|
porte: "porte";
|
||||||
|
|
||||||
line: hello;
|
line: hello;
|
||||||
line <- add(line, " ");
|
line <- add(line, " ");
|
||||||
line <- add(line, prout);
|
line <- add(line, porte);
|
||||||
|
|
||||||
say-it: () => {
|
say-it: () => {
|
||||||
out(line)
|
out(line)
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl Parser {
|
||||||
let parent_scope_id = parser_scope.get_parent_id();
|
let parent_scope_id = parser_scope.get_parent_id();
|
||||||
let expressions = instructions
|
let expressions = instructions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|expression| self.parse_expression(expression, &parser_scope))
|
.map(|expression| self.parse_expression(expression, parser_scope))
|
||||||
.collect();
|
.collect();
|
||||||
let local_variables = parser_scope.local_variable_ids();
|
let local_variables = parser_scope.local_variable_ids();
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ impl Parser {
|
||||||
|
|
||||||
let variable_id = parser_scope
|
let variable_id = parser_scope
|
||||||
.get_variable_id(&name)
|
.get_variable_id(&name)
|
||||||
.expect(&format!("call of undeclared function '{name}'"));
|
.unwrap_or_else(|| panic!("call of undeclared function '{name}'"));
|
||||||
let parameters = arguments
|
let parameters = arguments
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|argument| self.parse_expression(argument, parser_scope))
|
.map(|argument| self.parse_expression(argument, parser_scope))
|
||||||
|
@ -390,7 +390,7 @@ impl ParserScope {
|
||||||
next_id: self.next_id.clone(),
|
next_id: self.next_id.clone(),
|
||||||
variables: Rc::new(Mutex::new(variables)),
|
variables: Rc::new(Mutex::new(variables)),
|
||||||
current_id,
|
current_id,
|
||||||
current_function_scope_id: Some(current_id.clone()),
|
current_function_scope_id: Some(current_id),
|
||||||
current_loop_scope_id: None,
|
current_loop_scope_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,24 +409,24 @@ impl ParserScope {
|
||||||
variables: Rc::new(Mutex::new(variables)),
|
variables: Rc::new(Mutex::new(variables)),
|
||||||
current_id,
|
current_id,
|
||||||
current_function_scope_id: self.get_current_function_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 {
|
pub fn get_current_id(&self) -> Id {
|
||||||
self.current_id.clone()
|
self.current_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_function_id(&self) -> Option<Id> {
|
pub fn get_current_function_id(&self) -> Option<Id> {
|
||||||
self.current_function_scope_id.clone()
|
self.current_function_scope_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_current_loop_id(&self) -> Option<Id> {
|
pub fn get_current_loop_id(&self) -> Option<Id> {
|
||||||
self.current_loop_scope_id.clone()
|
self.current_loop_scope_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_parent_id(&self) -> Option<Id> {
|
pub fn get_parent_id(&self) -> Option<Id> {
|
||||||
self.parent_id.clone()
|
self.parent_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_variable_id(&self, name: &str) -> Option<Id> {
|
pub fn get_variable_id(&self, name: &str) -> Option<Id> {
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -1,20 +1,20 @@
|
||||||
use std::{env::args, fs};
|
use std::{env::args, fs};
|
||||||
|
|
||||||
|
pub mod demo;
|
||||||
pub mod execution_tree;
|
pub mod execution_tree;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
pub mod syntax_tree;
|
pub mod syntax_tree;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
pub mod demo;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use prelude::std_prelude;
|
use prelude::std_prelude;
|
||||||
|
|
||||||
let path = args().nth(1).expect("[error]: usage 'prout <path>'");
|
let path = args().nth(1).expect("[error]: usage 'porte <path>'");
|
||||||
let input = fs::read_to_string(path).expect("file not found");
|
let input = fs::read_to_string(path).expect("file not found");
|
||||||
let ast_parser = syntax_tree::parser::ParserWrapper::new();
|
let ast_parser = syntax_tree::parser::ParserWrapper::new();
|
||||||
let parsed = ast_parser.parse(&input).unwrap();
|
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();
|
let mut runtime = runtime::Runtime::new();
|
||||||
runtime.execute(&executable);
|
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")]),
|
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: --");
|
println!("\n\n\n-- running: --");
|
||||||
let _result = Runtime::new().execute(&exec);
|
let _result = Runtime::new().execute(&exec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn std_prelude(builder: &mut ParserBuilder) {
|
pub fn std_prelude(builder: &mut ParserBuilder) {
|
||||||
let functions: Vec<(_, _, fn(Vec<Value>) -> Value)> = vec![
|
type FunctOper = fn(Vec<Value>) -> Value;
|
||||||
|
let functions: Vec<(_, _, FunctOper)> = vec![
|
||||||
("out", 1, out),
|
("out", 1, out),
|
||||||
("add", 2, add),
|
("add", 2, add),
|
||||||
("sub", 2, sub),
|
("sub", 2, sub),
|
||||||
|
@ -42,7 +43,7 @@ fn add(args: Vec<Value>) -> Value {
|
||||||
(Value::String(l), Value::String(r)) => format!("{l}{r}").into(),
|
(Value::String(l), Value::String(r)) => format!("{l}{r}").into(),
|
||||||
(Value::Number(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(),
|
(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 {
|
||||||
(Value::Bool(l), Value::Bool(r)) => (l == r).into(),
|
(Value::Bool(l), Value::Bool(r)) => (l == r).into(),
|
||||||
(Value::Number(l), Value::Number(r)) => (l == r).into(),
|
(Value::Number(l), Value::Number(r)) => (l == r).into(),
|
||||||
(Value::String(l), Value::String(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>) -> Value {
|
||||||
fn get(args: Vec<Value>) -> Value {
|
fn get(args: Vec<Value>) -> Value {
|
||||||
let object = args.get(0).unwrap().as_object().unwrap();
|
let object = args.get(0).unwrap().as_object().unwrap();
|
||||||
let name = args.get(1).unwrap().as_string().unwrap();
|
let name = args.get(1).unwrap().as_string().unwrap();
|
||||||
object
|
object.get(name).cloned().unwrap_or_else(|| false.into())
|
||||||
.get(name)
|
|
||||||
.map(|value| value.clone())
|
|
||||||
.unwrap_or_else(|| false.into())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl FrameBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variable(&mut self, variable_id: &Id, default: Value) {
|
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);
|
builder(&mut frame_builder);
|
||||||
|
|
||||||
let FrameBuilder { variables } = frame_builder;
|
let FrameBuilder { variables } = frame_builder;
|
||||||
let scope_id = scope_id.clone();
|
let scope_id = *scope_id;
|
||||||
Self {
|
Self {
|
||||||
_scope_id: scope_id,
|
_scope_id: scope_id,
|
||||||
variables,
|
variables,
|
||||||
|
@ -99,6 +99,12 @@ impl Stack {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Stack {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ShortCircuit {
|
pub struct ShortCircuit {
|
||||||
value: Value,
|
value: Value,
|
||||||
destination_scope_id: Id,
|
destination_scope_id: Id,
|
||||||
|
@ -138,9 +144,9 @@ impl ExecReturn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ExecReturn> for Value {
|
impl From<Value> for ExecReturn {
|
||||||
fn into(self) -> ExecReturn {
|
fn from(val: Value) -> Self {
|
||||||
ExecReturn::new_value(self)
|
ExecReturn::new_value(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +175,7 @@ impl Runtime {
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut FrameBuilder),
|
F: FnOnce(&mut FrameBuilder),
|
||||||
{
|
{
|
||||||
let scope = program.scopes.get(&scope_id).unwrap();
|
let scope = program.scopes.get(scope_id).unwrap();
|
||||||
let Scope {
|
let Scope {
|
||||||
parent_scope_id: _,
|
parent_scope_id: _,
|
||||||
expressions,
|
expressions,
|
||||||
|
@ -210,9 +216,7 @@ impl Runtime {
|
||||||
ExprInner::FnDef(function_definition) => {
|
ExprInner::FnDef(function_definition) => {
|
||||||
self.execute_function_definition(function_definition)
|
self.execute_function_definition(function_definition)
|
||||||
}
|
}
|
||||||
ExprInner::FnCall(function_call) => {
|
ExprInner::FnCall(function_call) => self.execute_function_call(function_call, program),
|
||||||
self.execute_function_call(function_call, program).into()
|
|
||||||
}
|
|
||||||
ExprInner::FnRet(function_return) => {
|
ExprInner::FnRet(function_return) => {
|
||||||
self.execute_function_return(function_return, program)
|
self.execute_function_return(function_return, program)
|
||||||
}
|
}
|
||||||
|
@ -272,7 +276,7 @@ impl Runtime {
|
||||||
parameter_ids: argument_ids,
|
parameter_ids: argument_ids,
|
||||||
body_scope_id,
|
body_scope_id,
|
||||||
} = function_definition;
|
} = 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);
|
let value = Value::Function(value);
|
||||||
value.into()
|
value.into()
|
||||||
}
|
}
|
||||||
|
@ -367,7 +371,7 @@ impl Runtime {
|
||||||
}) => value,
|
}) => 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 {
|
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 {
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -52,8 +52,7 @@ pub fn literal_value() -> impl AbstractParser<Value> {
|
||||||
.unwrapped()
|
.unwrapped()
|
||||||
.map(|n: f64| n.into());
|
.map(|n: f64| n.into());
|
||||||
|
|
||||||
let literal = bool.or(none).or(string).or(number);
|
bool.or(none).or(string).or(number)
|
||||||
literal
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -66,11 +65,11 @@ fn test_literal_value() {
|
||||||
pub fn name() -> impl AbstractParser<String> + Clone {
|
pub fn name() -> impl AbstractParser<String> + Clone {
|
||||||
let first = one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
let first = one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
let rest = first.clone().or(one_of("1234567890-_+/*"));
|
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);
|
let rest = String::from_iter(&v);
|
||||||
format!("{f}{rest}")
|
format!("{f}{rest}")
|
||||||
});
|
})
|
||||||
name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variable_definition_parser(
|
pub fn variable_definition_parser(
|
||||||
|
@ -205,7 +204,7 @@ pub fn condition_parser(
|
||||||
just("if ")
|
just("if ")
|
||||||
.ignore_then(expression.clone())
|
.ignore_then(expression.clone())
|
||||||
.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 {
|
.map(|((condition, arm_true), arm_false)| Cond {
|
||||||
condition,
|
condition,
|
||||||
arm_true,
|
arm_true,
|
||||||
|
@ -296,7 +295,7 @@ fn _sugar_parser(expression: impl AbstractParser<Expr> + Clone) -> impl Abstract
|
||||||
let and = expression
|
let and = expression
|
||||||
.clone()
|
.clone()
|
||||||
.then_ignore(just(" && "))
|
.then_ignore(just(" && "))
|
||||||
.then(expression.clone())
|
.then(expression)
|
||||||
.map(|(l, r)| {
|
.map(|(l, r)| {
|
||||||
FnCall {
|
FnCall {
|
||||||
name: "and".into(),
|
name: "and".into(),
|
||||||
|
@ -317,7 +316,7 @@ pub fn expression_parser() -> impl AbstractParser<Expr> {
|
||||||
let loop_ = loop_parser(expression.clone()).map(|i| i.into());
|
let loop_ = loop_parser(expression.clone()).map(|i| i.into());
|
||||||
let loop_break = loop_break_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 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_definition = variable_definition_parser(expression.clone()).map(|i| i.into());
|
||||||
let variable_assignment = variable_assignement_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());
|
let function_call = function_call_parser(expression.clone()).map(|i| i.into());
|
||||||
|
@ -354,11 +353,11 @@ fn parser() -> impl AbstractParser<Program> {
|
||||||
.separated_by(just(';').padded())
|
.separated_by(just(';').padded())
|
||||||
.then_ignore(just(';').padded().or_not())
|
.then_ignore(just(';').padded().or_not())
|
||||||
.then_ignore(end());
|
.then_ignore(end());
|
||||||
let program = scope.map(|instructions| {
|
|
||||||
|
scope.map(|instructions| {
|
||||||
let body = Scope { instructions };
|
let body = Scope { instructions };
|
||||||
Program { body }
|
Program { body }
|
||||||
});
|
})
|
||||||
program
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -390,11 +389,17 @@ impl ParserWrapper {
|
||||||
ParserWrapper { inner }
|
ParserWrapper { inner }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse<'i>(&self, input: &'i str) -> Result<Program, Vec<Simple<char>>> {
|
pub fn parse(&self, input: &str) -> Result<Program, Vec<Simple<char>>> {
|
||||||
self.inner.parse(input)
|
self.inner.parse(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ParserWrapper {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// example
|
// example
|
||||||
|
|
||||||
|
|
|
@ -55,9 +55,9 @@ pub mod function {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Value> for Function {
|
impl From<Function> for Value {
|
||||||
fn into(self) -> Value {
|
fn from(val: Function) -> Self {
|
||||||
Value::Function(self)
|
Value::Function(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue