mirror of
https://github.com/artegoser/ONLang
synced 2024-11-05 20:43:57 +03:00
feat: input, sleep
This commit is contained in:
parent
89207ca812
commit
10ebab6b90
8 changed files with 256 additions and 29 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -190,13 +190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||
|
||||
[[package]]
|
||||
name = "onlang"
|
||||
name = "on"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
|
@ -206,6 +200,12 @@ dependencies = [
|
|||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.2.0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "onlang"
|
||||
name = "on"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
29
README.md
Normal file
29
README.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
![onlang logo](static/logos/OnLang-transparent.png)
|
||||
|
||||
# You may have questions
|
||||
|
||||
ONLang - Object Notation Language (js`ON`)
|
||||
|
||||
## 1. God, what the f\*\*\*\* is this
|
||||
|
||||
ONLang is an experimental, esoteric programming language, that allows you to use **json** for **PROGRAMMING**. The interpreter currently supports only json5 format.
|
||||
|
||||
## 2. What is it for
|
||||
|
||||
For writing simple scripts.
|
||||
|
||||
## 3. How run scripts
|
||||
|
||||
1. Add the executable file to the path variable
|
||||
2. `on example.json5`
|
||||
|
||||
or
|
||||
|
||||
1. Clone this repo
|
||||
2. `cargo run --quiet --release -- example.json5`
|
||||
|
||||
## 4. How to write on this
|
||||
|
||||
[Documentation](doc/main.md)
|
||||
|
||||
If you want to help create a pull request
|
12
ROADMAP.md
Normal file
12
ROADMAP.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
# TODO CONCEPTS
|
||||
|
||||
1. Functions
|
||||
2. imports
|
||||
3. scopes of visibility
|
||||
4. parallel tasks `{parallel:[..tasks]}`
|
||||
5. types conversion
|
||||
6. methods for arrays
|
||||
7. writing objects to a variable
|
||||
8. yaml support?
|
||||
|
||||
and something else
|
140
doc/main.md
Normal file
140
doc/main.md
Normal file
|
@ -0,0 +1,140 @@
|
|||
# How to
|
||||
|
||||
`All posibilities in example.json5`
|
||||
|
||||
## How to print
|
||||
|
||||
```json5
|
||||
[
|
||||
"Just string in array",
|
||||
["array", "of", "strings"],
|
||||
{
|
||||
print: ["Function"],
|
||||
},
|
||||
{
|
||||
println: ["Function"],
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## How to calclulate values
|
||||
|
||||
works only with numbers (and variables with number type)
|
||||
|
||||
```json5
|
||||
[
|
||||
{ calc: [2, "*", 3] }, //only 3 arguments
|
||||
{ calc: [{ var: "some_variable" }, "-", 2] }, //{var:"some_var"} this is a way to get a variable
|
||||
]
|
||||
```
|
||||
|
||||
### Supported operators
|
||||
|
||||
1. \+
|
||||
2. \-
|
||||
3. \*
|
||||
4. \/
|
||||
5. \%
|
||||
6. \>\>
|
||||
7. \<\<
|
||||
8. \^
|
||||
9. \&
|
||||
10. \|
|
||||
|
||||
## How to compare values
|
||||
|
||||
```json5
|
||||
[
|
||||
{ comp: [true, "!=", false] }, //only 3 arguments
|
||||
{
|
||||
comp: [
|
||||
{
|
||||
comp: [
|
||||
{ comp: [{ calc: [1, "+", 1] }, ">", 3] },
|
||||
"==",
|
||||
{ var: "var_with_bool_value" },
|
||||
],
|
||||
},
|
||||
"&&",
|
||||
{ comp: [{ comp: [{ calc: [1, "+", 1] }, ">", 3] }, "==", true] },
|
||||
],
|
||||
}, //more complex comparisons: (( 1 + 1 > 3 ) == var_with_bool_value) && (( 1 + 1 > 3 ) == true)
|
||||
]
|
||||
```
|
||||
|
||||
### Supported operators for compare
|
||||
|
||||
1. ==
|
||||
2. !=
|
||||
3. \>
|
||||
4. \<
|
||||
5. \>=
|
||||
6. \<=
|
||||
7. \&\&
|
||||
8. \|\|
|
||||
|
||||
## How to create a variable
|
||||
|
||||
```json5
|
||||
[
|
||||
{
|
||||
let: {
|
||||
str: "A",
|
||||
num: 2,
|
||||
arr: ["Array", "in", "variable"],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
let: {
|
||||
calculated: { calc: [{ var: "num" }, "*", 4] }, //result 8
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## How to assign variable
|
||||
|
||||
```json5
|
||||
[
|
||||
{
|
||||
assign: {
|
||||
calculated: { calc: [{ var: "calculated" }, "+", 1] }, // calculated = calculated + 1
|
||||
},
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## Loops
|
||||
|
||||
```json5
|
||||
[
|
||||
{
|
||||
loop: [
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "i" }, ">=", 10] }, //if i >= 10 break loop
|
||||
body: ["break"],
|
||||
//else: [..commands] also work
|
||||
},
|
||||
},
|
||||
{ assign: { i: { calc: [{ var: "i" }, "+", 1] } } }, // i += 1
|
||||
{ print: ["\ri = ", { var: "i" }] },
|
||||
{ sleep: 500 }, //sleep 500 ms
|
||||
],
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
## Input from console
|
||||
|
||||
```json5
|
||||
[
|
||||
{
|
||||
let: {
|
||||
name: { input: "Your name: " },
|
||||
},
|
||||
},
|
||||
{ print: ["Bye, ", { var: "name" }, "!"] },
|
||||
]
|
||||
```
|
|
@ -163,6 +163,7 @@
|
|||
["After executing calculated = ", { var: "calculated" }],
|
||||
|
||||
"\nRun loop",
|
||||
|
||||
{
|
||||
loop: [
|
||||
{
|
||||
|
@ -174,10 +175,11 @@
|
|||
loop: [
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "num" }, ">=", 200000] },
|
||||
condition: { comp: [{ var: "num" }, ">=", 100000] },
|
||||
body: ["break"],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
assign: {
|
||||
num: { calc: [{ var: "num" }, "+", 1] },
|
||||
|
@ -203,7 +205,7 @@
|
|||
},
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "calculated" }, ">=", 200000] },
|
||||
condition: { comp: [{ var: "calculated" }, ">=", 100000] },
|
||||
body: ["\n", "break"],
|
||||
},
|
||||
},
|
||||
|
@ -212,30 +214,43 @@
|
|||
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "calculated" }, ">=", 199999] },
|
||||
body: [["Calculated is >= ", 199999]],
|
||||
else: [["Calculated is < ", 199999]],
|
||||
condition: { comp: [{ var: "calculated" }, ">=", 99999] },
|
||||
body: [["сalculated is >= ", 99999]],
|
||||
else: [["сalculated is < ", 99999]],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "calculated" }, ">", 200000] },
|
||||
body: [["Calculated is > ", 200000]],
|
||||
else: [["Calculated is <= ", 200000]],
|
||||
condition: { comp: [{ var: "calculated" }, ">", 100000] },
|
||||
body: [["сalculated is > ", 100000]],
|
||||
else: [["сalculated is <= ", 100000]],
|
||||
},
|
||||
},
|
||||
|
||||
"clear",
|
||||
{ let: { i: 0 } },
|
||||
|
||||
// //TODO CONCEPTS ##########################################################################################################################################################################################################################
|
||||
"\nLoop with sleep",
|
||||
|
||||
// {
|
||||
// while: {
|
||||
// cond: { comp: [1, ">=", {var: "variable"}] },
|
||||
// body: [
|
||||
// //commands
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
loop: [
|
||||
{
|
||||
if: {
|
||||
condition: { comp: [{ var: "i" }, ">=", 10] },
|
||||
body: ["break"],
|
||||
},
|
||||
},
|
||||
{ assign: { i: { calc: [{ var: "i" }, "+", 1] } } },
|
||||
{ print: ["\ri = ", { var: "i" }] },
|
||||
{ sleep: 500 },
|
||||
],
|
||||
},
|
||||
|
||||
"\nInput a var",
|
||||
{
|
||||
let: {
|
||||
name: { input: "Your name: " },
|
||||
},
|
||||
},
|
||||
{ print: ["Bye, ", { var: "name" }, "!"] },
|
||||
]
|
|
@ -2,6 +2,8 @@ use colored::*;
|
|||
use json5;
|
||||
use serde_json::{json, Map, Value};
|
||||
use std::collections::HashMap;
|
||||
use std::io::{self, Write};
|
||||
use std::{thread, time};
|
||||
pub struct Interpreter {
|
||||
input: String,
|
||||
vars: HashMap<String, Value>,
|
||||
|
@ -18,8 +20,8 @@ impl Interpreter {
|
|||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
let obj = json5::from_str::<Value>(&self.input).unwrap();
|
||||
let arr = obj.as_array().unwrap();
|
||||
let obj = json5::from_str::<Value>(&self.input).expect("Your json is invalid!");
|
||||
let arr = obj.as_array().expect("Json must be an array!");
|
||||
|
||||
for command in arr {
|
||||
self.eval_node(command);
|
||||
|
@ -102,6 +104,22 @@ impl Interpreter {
|
|||
self.error("Unsupported data type for the let argument");
|
||||
}
|
||||
},
|
||||
"input" => match value {
|
||||
Value::String(value) => {
|
||||
return self.input(value);
|
||||
}
|
||||
_ => {
|
||||
self.error("Unsupported data type for the input argument");
|
||||
}
|
||||
},
|
||||
"sleep" => match value {
|
||||
Value::Number(value) => {
|
||||
self.sleep(value);
|
||||
}
|
||||
_ => {
|
||||
self.error("Unsupported data type for the sleep argument");
|
||||
}
|
||||
},
|
||||
"if" => match value {
|
||||
Value::Object(value) => {
|
||||
return self.if_node(value);
|
||||
|
@ -150,10 +168,23 @@ impl Interpreter {
|
|||
return Value::Null;
|
||||
}
|
||||
|
||||
fn sleep(&self, value: &serde_json::Number) {
|
||||
let value = value.as_f64().unwrap() as u64;
|
||||
thread::sleep(time::Duration::from_millis(value));
|
||||
}
|
||||
|
||||
fn clear(&self) {
|
||||
print!("{}[2J", 27 as char);
|
||||
}
|
||||
|
||||
fn input(&self, value: &String) -> Value {
|
||||
let mut input = String::new();
|
||||
print!("{}", value);
|
||||
io::stdout().flush().unwrap_or_default();
|
||||
io::stdin().read_line(&mut input).unwrap_or_default();
|
||||
Value::String(input.trim_end().to_string())
|
||||
}
|
||||
|
||||
fn if_node(&mut self, value: &Map<String, Value>) -> Value {
|
||||
let condition = self.eval_node(&value["condition"]);
|
||||
let nodes = &value.get("body");
|
||||
|
@ -477,6 +508,7 @@ impl Interpreter {
|
|||
if ln == true {
|
||||
println!();
|
||||
}
|
||||
io::stdout().flush().unwrap_or_default();
|
||||
}
|
||||
|
||||
fn print_one(&mut self, arg: &Value) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use clap::Parser;
|
||||
use std::fs;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
struct Args {
|
||||
|
|
Loading…
Reference in a new issue