mirror of
https://github.com/mii443/encrypt.git
synced 2025-08-22 15:05:33 +00:00
add server function call
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -144,9 +144,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.8.4"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
|
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"humantime",
|
"humantime",
|
||||||
|
@ -12,7 +12,7 @@ rand = {version = "0.7.3"}
|
|||||||
rand_chacha = "*"
|
rand_chacha = "*"
|
||||||
clap = { version = "3.2.8", features = ["derive"] }
|
clap = { version = "3.2.8", features = ["derive"] }
|
||||||
uuid = { version = "0.8.1", features = ["serde", "v4"] }
|
uuid = { version = "0.8.1", features = ["serde", "v4"] }
|
||||||
log = "0.4.0"
|
log = "0.4.17"
|
||||||
env_logger = "0.8.4"
|
env_logger = "0.9.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "*"
|
serde_json = "*"
|
||||||
|
11
client.gpsl
11
client.gpsl
@ -1,4 +1,9 @@
|
|||||||
fn main() {
|
|
||||||
send("test");
|
#[server(ip = "localhost:8080")]
|
||||||
println(receive());
|
fn add(a: num, b: num) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println(add(1, 2));
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#[server(ip = "localhost:8080")]
|
||||||
fn main() {
|
fn main() {
|
||||||
send(receive());
|
send(receive());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use serde::Deserializer;
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
use crate::gpsl::{permission::Permission, variable::Variable};
|
use crate::gpsl::{permission::Permission, variable::Variable};
|
||||||
use std::{
|
use std::{
|
||||||
@ -7,7 +7,7 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq, Debug, Serialize, Deserialize)]
|
||||||
pub enum ExternalFuncStatus {
|
pub enum ExternalFuncStatus {
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
NOTFOUND,
|
NOTFOUND,
|
||||||
@ -15,23 +15,19 @@ pub enum ExternalFuncStatus {
|
|||||||
REJECTED,
|
REJECTED,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct ExternalFuncReturn {
|
pub struct ExternalFuncReturn {
|
||||||
pub status: ExternalFuncStatus,
|
pub status: ExternalFuncStatus,
|
||||||
pub value: Option<Variable>,
|
pub value: Option<Variable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExternalFuncCallData {
|
|
||||||
pub stream: Arc<Mutex<Option<TcpStream>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const STD_FUNC: fn(
|
pub const STD_FUNC: fn(
|
||||||
String,
|
String,
|
||||||
Vec<Variable>,
|
Vec<Variable>,
|
||||||
Vec<Permission>,
|
Vec<Permission>,
|
||||||
Vec<Permission>,
|
Vec<Permission>,
|
||||||
Option<ExternalFuncCallData>,
|
) -> ExternalFuncReturn = |name, args, accept, reject| {
|
||||||
) -> ExternalFuncReturn = |name, args, accept, reject, data| {
|
|
||||||
let name = name.as_str();
|
let name = name.as_str();
|
||||||
match name {
|
match name {
|
||||||
"println" => {
|
"println" => {
|
||||||
@ -69,42 +65,42 @@ pub const STD_FUNC: fn(
|
|||||||
value: None,
|
value: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} /*
|
||||||
"receive" => {
|
"receive" => {
|
||||||
println!("Waiting for client...");
|
println!("Waiting for client...");
|
||||||
let mut buffer = String::default();
|
let mut buffer = String::default();
|
||||||
let data = data.unwrap();
|
let data = data.unwrap();
|
||||||
let mut stream = data.stream.lock().unwrap();
|
let mut stream = data.stream.lock().unwrap();
|
||||||
|
|
||||||
let stream = match &mut *stream {
|
let stream = match &mut *stream {
|
||||||
Some(stream) => stream,
|
Some(stream) => stream,
|
||||||
None => panic!("Cannot access to tcp stream"),
|
None => panic!("Cannot access to tcp stream"),
|
||||||
};
|
};
|
||||||
let mut reader = BufReader::new(stream);
|
let mut reader = BufReader::new(stream);
|
||||||
reader.read_line(&mut buffer).unwrap();
|
reader.read_line(&mut buffer).unwrap();
|
||||||
ExternalFuncReturn {
|
ExternalFuncReturn {
|
||||||
status: ExternalFuncStatus::SUCCESS,
|
status: ExternalFuncStatus::SUCCESS,
|
||||||
value: Some(serde_json::from_str(&buffer).unwrap()),
|
value: Some(serde_json::from_str(&buffer).unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"send" => {
|
"send" => {
|
||||||
let data = data.unwrap();
|
let data = data.unwrap();
|
||||||
let mut stream = data.stream.lock().unwrap();
|
let mut stream = data.stream.lock().unwrap();
|
||||||
|
|
||||||
let stream = match &mut *stream {
|
let stream = match &mut *stream {
|
||||||
Some(stream) => stream,
|
Some(stream) => stream,
|
||||||
None => panic!("Cannot access to tcp stream"),
|
None => panic!("Cannot access to tcp stream"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = serde_json::to_string(&args[0]).unwrap();
|
let value = serde_json::to_string(&args[0]).unwrap();
|
||||||
|
|
||||||
stream.write_fmt(format_args!("{}\n", value)).unwrap();
|
stream.write_fmt(format_args!("{}\n", value)).unwrap();
|
||||||
|
|
||||||
ExternalFuncReturn {
|
ExternalFuncReturn {
|
||||||
status: ExternalFuncStatus::SUCCESS,
|
status: ExternalFuncStatus::SUCCESS,
|
||||||
value: None,
|
value: None,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
_ => ExternalFuncReturn {
|
_ => ExternalFuncReturn {
|
||||||
status: ExternalFuncStatus::NOTFOUND,
|
status: ExternalFuncStatus::NOTFOUND,
|
||||||
value: None,
|
value: None,
|
||||||
|
@ -3,7 +3,7 @@ options { tokenVocab = GpslLexer; }
|
|||||||
|
|
||||||
gpslFile: function* EOF ;
|
gpslFile: function* EOF ;
|
||||||
|
|
||||||
function: FN IDENT LPAREN (IDENT COLON IDENT COMMA?)* RPAREN (ARROW IDENT)? block ;
|
function: attribute? FN IDENT LPAREN (IDENT COLON IDENT COMMA?)* RPAREN (ARROW IDENT)? block ;
|
||||||
|
|
||||||
program: stmt* ;
|
program: stmt* ;
|
||||||
|
|
||||||
@ -23,6 +23,8 @@ if: IF LPAREN expr RPAREN stmt (ELSE stmt)? ;
|
|||||||
while: WHILE LPAREN expr RPAREN stmt ;
|
while: WHILE LPAREN expr RPAREN stmt ;
|
||||||
for: FOR LPAREN expr? SEMICOLON expr? SEMICOLON expr? RPAREN stmt ;
|
for: FOR LPAREN expr? SEMICOLON expr? SEMICOLON expr? RPAREN stmt ;
|
||||||
|
|
||||||
|
|
||||||
|
attribute: SHARP LBRACKET IDENT (assign COMMA?)* RBRACKET ;
|
||||||
mode: SHARP IDENT ;
|
mode: SHARP IDENT ;
|
||||||
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
|
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||||
pub enum NodeKind {
|
pub enum NodeKind {
|
||||||
ASSIGN,
|
ASSIGN,
|
||||||
ADD,
|
ADD,
|
||||||
@ -13,12 +15,18 @@ pub enum NodeKind {
|
|||||||
LE, // <=
|
LE, // <=
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Node {
|
pub enum Node {
|
||||||
Function {
|
Function {
|
||||||
name: String,
|
name: String,
|
||||||
args: HashMap<String, String>,
|
args_name: Vec<String>,
|
||||||
|
args_type: Vec<String>,
|
||||||
body: Vec<Box<Node>>,
|
body: Vec<Box<Node>>,
|
||||||
|
attribute: Option<Box<Node>>,
|
||||||
|
},
|
||||||
|
Attribute {
|
||||||
|
name: String,
|
||||||
|
args: Vec<Box<Node>>,
|
||||||
},
|
},
|
||||||
Mode {
|
Mode {
|
||||||
mode: String,
|
mode: String,
|
||||||
@ -87,4 +95,24 @@ impl Node {
|
|||||||
pub fn new_lvar_node(value: String) -> Box<Node> {
|
pub fn new_lvar_node(value: String) -> Box<Node> {
|
||||||
Box::new(Node::Lvar { value })
|
Box::new(Node::Lvar { value })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn extract_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Node::Text { value } => value.clone(),
|
||||||
|
Node::Number { value } => value.to_string(),
|
||||||
|
Node::Lvar { value } => value.clone(),
|
||||||
|
_ => String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extract_function_args(&self) -> (Vec<String>, Vec<String>) {
|
||||||
|
match self {
|
||||||
|
Node::Function {
|
||||||
|
args_name,
|
||||||
|
args_type,
|
||||||
|
..
|
||||||
|
} => (args_name.clone(), args_type.clone()),
|
||||||
|
_ => (Vec::new(), Vec::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use crate::gpsl::node::*;
|
use crate::gpsl::node::*;
|
||||||
use crate::gpsl::token::*;
|
use crate::gpsl::token::*;
|
||||||
use crate::gpsl::tokenizer::*;
|
use crate::gpsl::tokenizer::*;
|
||||||
|
use env_logger;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use log::{debug, error, info, warn};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -29,40 +31,57 @@ impl Parser {
|
|||||||
function: FN IDENT LPAREN (IDENT COLON IDENT COMMA?)* RPAREN (ARROW IDENT)? block ;
|
function: FN IDENT LPAREN (IDENT COLON IDENT COMMA?)* RPAREN (ARROW IDENT)? block ;
|
||||||
*/
|
*/
|
||||||
pub fn function(&mut self) -> Result<Box<Node>, String> {
|
pub fn function(&mut self) -> Result<Box<Node>, String> {
|
||||||
|
// parse attribute
|
||||||
|
let attribute = if self.tokenizer.current_token().str == String::from("#") {
|
||||||
|
println!("{:?}", self.tokenizer.current_token());
|
||||||
|
Some(self.attribute()?)
|
||||||
|
} else {
|
||||||
|
Some(Box::new(Node::Attribute {
|
||||||
|
name: String::from(""),
|
||||||
|
args: vec![],
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("{:?}", self.tokenizer.current_token());
|
||||||
|
|
||||||
if self
|
if self
|
||||||
.tokenizer
|
.tokenizer
|
||||||
.consume_kind_str(TokenKind::RESERVED, String::from("fn"))
|
.consume_kind_str(TokenKind::RESERVED, String::from("fn"))
|
||||||
{
|
{
|
||||||
debug!("parsing function");
|
debug!("{}: parsing function", line!());
|
||||||
let func_name = self.tokenizer.current_token().clone();
|
let func_name = self.tokenizer.current_token().clone();
|
||||||
self.tokenizer.expect_kind(TokenKind::IDENT)?;
|
self.tokenizer.expect_kind(TokenKind::IDENT)?;
|
||||||
let mut args = HashMap::new();
|
let mut args_name = vec![];
|
||||||
|
let mut args_type = vec![];
|
||||||
self.tokenizer.expect(String::from("("))?;
|
self.tokenizer.expect(String::from("("))?;
|
||||||
debug!("parsing args");
|
debug!("{}: parsing args", line!());
|
||||||
while !self
|
while !self
|
||||||
.tokenizer
|
.tokenizer
|
||||||
.consume_kind_str(TokenKind::RESERVED, String::from(")"))
|
.consume_kind_str(TokenKind::RESERVED, String::from(")"))
|
||||||
{
|
{
|
||||||
debug!("consume argument");
|
debug!("{}: consume argument", line!());
|
||||||
let name = self.tokenizer.expect_ident()?;
|
let name = self.tokenizer.expect_ident()?;
|
||||||
self.tokenizer
|
self.tokenizer
|
||||||
.consume_kind_str(TokenKind::RESERVED, String::from(":"));
|
.consume_kind_str(TokenKind::RESERVED, String::from(":"));
|
||||||
let type_str = self.tokenizer.expect_ident()?;
|
let type_str = self.tokenizer.expect_ident()?;
|
||||||
self.tokenizer
|
self.tokenizer
|
||||||
.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
||||||
args.insert(name, type_str);
|
args_name.push(name);
|
||||||
|
args_type.push(type_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut nodes: Vec<Box<Node>> = vec![];
|
let mut nodes: Vec<Box<Node>> = vec![];
|
||||||
debug!("parsing body node");
|
debug!("{}: parsing body node", line!());
|
||||||
loop {
|
loop {
|
||||||
nodes.push(self.stmt()?);
|
nodes.push(self.stmt()?);
|
||||||
debug!("body nodes parsed");
|
debug!("{}: body nodes parsed", line!());
|
||||||
//self.tokenizer.expect(String::from("}"))?;
|
//self.tokenizer.expect(String::from("}"))?;
|
||||||
return Ok(Box::new(Node::Function {
|
return Ok(Box::new(Node::Function {
|
||||||
name: func_name.str,
|
name: func_name.str,
|
||||||
args,
|
args_name,
|
||||||
|
args_type,
|
||||||
body: nodes,
|
body: nodes,
|
||||||
|
attribute,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -112,14 +131,14 @@ impl Parser {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("parsing permission");
|
debug!("{}: parsing permission", line!());
|
||||||
let permission = if self.tokenizer.current_token().str == "$" {
|
let permission = if self.tokenizer.current_token().str == "$" {
|
||||||
Some(self.permission()?)
|
Some(self.permission()?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("parsing mode");
|
debug!("{}: parsing mode", line!());
|
||||||
let mode = if self.tokenizer.current_token().str == "#" {
|
let mode = if self.tokenizer.current_token().str == "#" {
|
||||||
Some(self.mode()?)
|
Some(self.mode()?)
|
||||||
} else {
|
} else {
|
||||||
@ -228,6 +247,33 @@ impl Parser {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
attribute: SHARP LBRACKET IDENT LPAREN (assign COMMA?)* RPAREN RBRACKET ;
|
||||||
|
*/
|
||||||
|
pub fn attribute(&mut self) -> Result<Box<Node>, String> {
|
||||||
|
self.tokenizer.expect(String::from("#"))?;
|
||||||
|
self.tokenizer.expect(String::from("["))?;
|
||||||
|
let name = self.tokenizer.current_token().clone();
|
||||||
|
self.tokenizer.expect_kind(TokenKind::IDENT)?;
|
||||||
|
self.tokenizer.expect(String::from("("))?;
|
||||||
|
let mut args: Vec<Box<Node>> = vec![];
|
||||||
|
loop {
|
||||||
|
if self.tokenizer.current_token().str == String::from(")") {
|
||||||
|
self.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(")"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
args.push(self.assign()?);
|
||||||
|
self.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
||||||
|
}
|
||||||
|
self.tokenizer.expect(String::from("]"))?;
|
||||||
|
return Ok(Box::new(Node::Attribute {
|
||||||
|
name: name.str,
|
||||||
|
args,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
mode: SHARP IDENT ;
|
mode: SHARP IDENT ;
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Source {
|
pub struct Source {
|
||||||
pub src: Vec<char>,
|
pub src: Vec<char>,
|
||||||
pub pos: usize,
|
pub pos: usize,
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use crate::gpsl::external_function::{
|
use crate::gpsl::external_function::{ExternalFuncReturn, ExternalFuncStatus};
|
||||||
ExternalFuncCallData, ExternalFuncReturn, ExternalFuncStatus,
|
|
||||||
};
|
|
||||||
use crate::gpsl::node::*;
|
use crate::gpsl::node::*;
|
||||||
use crate::gpsl::permission::Permission;
|
use crate::gpsl::permission::Permission;
|
||||||
use crate::gpsl::source::Source;
|
use crate::gpsl::source::Source;
|
||||||
use crate::gpsl::variable::*;
|
use crate::gpsl::variable::*;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
use std::io::{BufRead, BufReader, Read, Write};
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::string::*;
|
use std::string::*;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
@ -19,21 +19,16 @@ pub struct Block {
|
|||||||
pub is_split: bool,
|
pub is_split: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct GPSL {
|
pub struct GPSL {
|
||||||
pub functions: Option<HashMap<String, Box<Node>>>,
|
pub functions: Option<HashMap<String, Box<Node>>>,
|
||||||
|
pub server_functions: Option<HashMap<String, HashMap<String, Box<Node>>>>,
|
||||||
|
pub servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
|
||||||
pub global_variables: Vec<Variable>,
|
pub global_variables: Vec<Variable>,
|
||||||
pub source: Source,
|
pub source: Source,
|
||||||
pub blocks: VecDeque<Block>,
|
pub blocks: VecDeque<Block>,
|
||||||
pub tcp_stream: Arc<Mutex<Option<TcpStream>>>,
|
pub external_func:
|
||||||
pub external_func: Vec<
|
Vec<fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn>,
|
||||||
fn(
|
|
||||||
String,
|
|
||||||
Vec<Variable>,
|
|
||||||
Vec<Permission>,
|
|
||||||
Vec<Permission>,
|
|
||||||
Option<ExternalFuncCallData>,
|
|
||||||
) -> ExternalFuncReturn,
|
|
||||||
>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -48,6 +43,12 @@ pub struct VariableStatus {
|
|||||||
pub initialized: bool,
|
pub initialized: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ServerFunctionCall {
|
||||||
|
pub name: String,
|
||||||
|
pub args: HashMap<String, Variable>,
|
||||||
|
}
|
||||||
|
|
||||||
impl VariableStatus {
|
impl VariableStatus {
|
||||||
pub fn default() -> VariableStatus {
|
pub fn default() -> VariableStatus {
|
||||||
VariableStatus { initialized: false }
|
VariableStatus { initialized: false }
|
||||||
@ -58,23 +59,19 @@ impl GPSL {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
source: Source,
|
source: Source,
|
||||||
functions: Option<HashMap<String, Box<Node>>>,
|
functions: Option<HashMap<String, Box<Node>>>,
|
||||||
tcp_sream: Arc<Mutex<Option<TcpStream>>>,
|
server_functions: Option<HashMap<String, HashMap<String, Box<Node>>>>,
|
||||||
|
servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
|
||||||
external_func: Vec<
|
external_func: Vec<
|
||||||
fn(
|
fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn,
|
||||||
String,
|
|
||||||
Vec<Variable>,
|
|
||||||
Vec<Permission>,
|
|
||||||
Vec<Permission>,
|
|
||||||
Option<ExternalFuncCallData>,
|
|
||||||
) -> ExternalFuncReturn,
|
|
||||||
>,
|
>,
|
||||||
) -> GPSL {
|
) -> GPSL {
|
||||||
GPSL {
|
GPSL {
|
||||||
source,
|
source,
|
||||||
functions,
|
functions,
|
||||||
|
server_functions,
|
||||||
|
servers,
|
||||||
global_variables: vec![],
|
global_variables: vec![],
|
||||||
blocks: VecDeque::new(),
|
blocks: VecDeque::new(),
|
||||||
tcp_stream: tcp_sream,
|
|
||||||
external_func,
|
external_func,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,6 +125,50 @@ impl GPSL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Searching server function: {}, ({:?})",
|
||||||
|
&function_name, args_value
|
||||||
|
);
|
||||||
|
|
||||||
|
for server in self.server_functions.clone().unwrap() {
|
||||||
|
for function in server.1 {
|
||||||
|
if function.0 == function_name {
|
||||||
|
let mut servers = self.servers.clone().unwrap();
|
||||||
|
let stream = servers.get_mut(&server.0).unwrap();
|
||||||
|
let mut stream = stream.lock().unwrap();
|
||||||
|
|
||||||
|
let function_args = function.1.extract_function_args();
|
||||||
|
let mut args: HashMap<String, Variable> = HashMap::new();
|
||||||
|
for (i, arg_name) in function_args.0.iter().enumerate() {
|
||||||
|
args.insert(arg_name.clone(), args_value[i].clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let server_function_call = serde_json::to_string(&ServerFunctionCall {
|
||||||
|
name: function_name.clone(),
|
||||||
|
args: args.clone(),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
println!("{}", server_function_call);
|
||||||
|
|
||||||
|
stream
|
||||||
|
.write_fmt(format_args!("{}\n", server_function_call))
|
||||||
|
.unwrap();
|
||||||
|
let mut buf = String::new();
|
||||||
|
debug!("try clone");
|
||||||
|
BufReader::new(stream.try_clone().unwrap())
|
||||||
|
.read_line(&mut buf)
|
||||||
|
.unwrap();
|
||||||
|
let res: ExternalFuncReturn = serde_json::from_str(&buf).unwrap();
|
||||||
|
if res.status == ExternalFuncStatus::SUCCESS {
|
||||||
|
return Ok(res.value);
|
||||||
|
}
|
||||||
|
if res.status == ExternalFuncStatus::REJECTED {
|
||||||
|
return Err("Server function rejected.".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(functions) = self.functions.clone() {
|
if let Some(functions) = self.functions.clone() {
|
||||||
debug!(
|
debug!(
|
||||||
"functions: {:?}",
|
"functions: {:?}",
|
||||||
@ -185,9 +226,6 @@ impl GPSL {
|
|||||||
args_value.clone(),
|
args_value.clone(),
|
||||||
block.accept.clone(),
|
block.accept.clone(),
|
||||||
block.reject.clone(),
|
block.reject.clone(),
|
||||||
Some(ExternalFuncCallData {
|
|
||||||
stream: self.tcp_stream.clone(),
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
if res.status == ExternalFuncStatus::SUCCESS {
|
if res.status == ExternalFuncStatus::SUCCESS {
|
||||||
return Ok(res.value);
|
return Ok(res.value);
|
||||||
@ -499,15 +537,33 @@ impl GPSL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self, function_name: String, _: Vec<Box<Node>>) -> Result<Variable, String> {
|
pub fn run(
|
||||||
|
&mut self,
|
||||||
|
function_name: String,
|
||||||
|
args: HashMap<String, Variable>,
|
||||||
|
) -> Result<Variable, String> {
|
||||||
debug!("functions: {:?}", self.functions);
|
debug!("functions: {:?}", self.functions);
|
||||||
debug!("searching {}", function_name);
|
debug!("searching {}", function_name);
|
||||||
|
|
||||||
|
let mut local_variables = HashMap::new();
|
||||||
|
for (name, value) in args {
|
||||||
|
local_variables.insert(
|
||||||
|
name.clone(),
|
||||||
|
LocalVariable {
|
||||||
|
name: name.clone(),
|
||||||
|
value,
|
||||||
|
status: VariableStatus::default(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.blocks.push_front(Block {
|
self.blocks.push_front(Block {
|
||||||
accept: vec![Permission::Administrator, Permission::StdIo],
|
accept: vec![Permission::Administrator, Permission::StdIo],
|
||||||
reject: vec![],
|
reject: vec![],
|
||||||
variables: HashMap::new(),
|
variables: local_variables,
|
||||||
is_split: true,
|
is_split: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(functions) = self.functions.clone() {
|
if let Some(functions) = self.functions.clone() {
|
||||||
if let Node::Function { body, .. } = &*(functions[&function_name]) {
|
if let Node::Function { body, .. } = &*(functions[&function_name]) {
|
||||||
for program in body {
|
for program in body {
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod elliptic_curve;
|
pub mod elliptic_curve;
|
||||||
pub mod gpsl;
|
pub mod gpsl;
|
||||||
#[macro_use]
|
|
||||||
extern crate log;
|
|
||||||
|
144
src/main.rs
144
src/main.rs
@ -1,7 +1,16 @@
|
|||||||
mod gpsl;
|
mod gpsl;
|
||||||
|
use gpsl::external_function::ExternalFuncReturn;
|
||||||
|
use gpsl::external_function::ExternalFuncStatus;
|
||||||
|
use gpsl::node::Node;
|
||||||
|
use gpsl::node::NodeKind;
|
||||||
use gpsl::variable::Variable;
|
use gpsl::variable::Variable;
|
||||||
|
use gpsl::vm::gpsl::ServerFunctionCall;
|
||||||
use gpsl::{external_function::STD_FUNC, parser::*, source::*, tokenizer::*, vm::gpsl::*};
|
use gpsl::{external_function::STD_FUNC, parser::*, source::*, tokenizer::*, vm::gpsl::*};
|
||||||
use primitive_types::U512;
|
use log::*;
|
||||||
|
use std::env;
|
||||||
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::io::Write;
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::{collections::HashMap, fs};
|
use std::{collections::HashMap, fs};
|
||||||
@ -55,10 +64,13 @@ struct Args {
|
|||||||
mode: String,
|
mode: String,
|
||||||
|
|
||||||
#[clap(short, long, value_parser)]
|
#[clap(short, long, value_parser)]
|
||||||
file: String,
|
file: Option<String>,
|
||||||
|
|
||||||
#[clap(short, long, value_parser)]
|
#[clap(short, long, value_parser)]
|
||||||
ip: Option<String>,
|
ip: Option<String>,
|
||||||
|
|
||||||
|
#[clap(short, long, value_parser)]
|
||||||
|
port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn listen_tcp_server(port: u16) -> TcpStream {
|
fn listen_tcp_server(port: u16) -> TcpStream {
|
||||||
@ -79,7 +91,66 @@ fn listen_tcp_server(port: u16) -> TcpStream {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let mut source = Source::new(fs::read_to_string(&(args.file)).expect("Cannot read file."));
|
match &*args.mode {
|
||||||
|
"server" => {
|
||||||
|
server(args);
|
||||||
|
}
|
||||||
|
"client" => {
|
||||||
|
client(args);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Unknown mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn server(args: Args) {
|
||||||
|
let mut stream = listen_tcp_server(args.port.unwrap());
|
||||||
|
|
||||||
|
debug!("Receiving functions...");
|
||||||
|
let mut buf = String::default();
|
||||||
|
BufReader::new(stream.try_clone().unwrap())
|
||||||
|
.read_line(&mut buf)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let functions: HashMap<String, Box<Node>> = serde_json::from_str(&buf).unwrap();
|
||||||
|
debug!("Received: {:?}", functions);
|
||||||
|
|
||||||
|
let mut gpsl = GPSL::new(
|
||||||
|
Source::new(String::default()),
|
||||||
|
Some(functions),
|
||||||
|
Some(HashMap::new()),
|
||||||
|
Some(HashMap::new()),
|
||||||
|
vec![STD_FUNC],
|
||||||
|
);
|
||||||
|
|
||||||
|
debug!("Receiving function call...");
|
||||||
|
BufReader::new(stream.try_clone().unwrap())
|
||||||
|
.read_line(&mut buf)
|
||||||
|
.unwrap();
|
||||||
|
debug!("Received");
|
||||||
|
debug!("{}", buf);
|
||||||
|
|
||||||
|
let function_call: ServerFunctionCall = serde_json::from_str(&buf).unwrap();
|
||||||
|
|
||||||
|
let result = gpsl.run(function_call.name, function_call.args);
|
||||||
|
let external_function_return = ExternalFuncReturn {
|
||||||
|
status: ExternalFuncStatus::SUCCESS,
|
||||||
|
value: Some(result.unwrap()),
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("Sending result...");
|
||||||
|
stream
|
||||||
|
.write_fmt(format_args!(
|
||||||
|
"{}\n",
|
||||||
|
serde_json::to_string(&external_function_return).unwrap()
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn client(args: Args) {
|
||||||
|
let mut source =
|
||||||
|
Source::new(fs::read_to_string(&(args.file.unwrap())).expect("Cannot read file."));
|
||||||
|
|
||||||
let mut tokenizer = Tokenizer::new();
|
let mut tokenizer = Tokenizer::new();
|
||||||
tokenizer.tokenize(&mut source).unwrap();
|
tokenizer.tokenize(&mut source).unwrap();
|
||||||
@ -89,19 +160,70 @@ fn main() {
|
|||||||
local_vars: HashMap::new(),
|
local_vars: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let stream = match &*args.mode {
|
let functions = parser.functions().unwrap();
|
||||||
"server" => listen_tcp_server(8080),
|
let mut server_functions: HashMap<String, HashMap<String, Box<Node>>> = HashMap::new();
|
||||||
"client" => TcpStream::connect(args.ip.unwrap()).unwrap(),
|
for function in functions.clone() {
|
||||||
_ => panic!("Cannot start tcp stream."),
|
match *function.clone().1 {
|
||||||
};
|
Node::Function { attribute, .. } => match *(attribute.unwrap()) {
|
||||||
|
Node::Attribute { name, args } => {
|
||||||
|
if name == String::from("server") {
|
||||||
|
println!("{:?}", function);
|
||||||
|
let ip = {
|
||||||
|
let mut t_ip = None;
|
||||||
|
for arg in args {
|
||||||
|
let ip = match *arg {
|
||||||
|
Node::Operator { kind, lhs, rhs } => {
|
||||||
|
if kind == NodeKind::ASSIGN {
|
||||||
|
if lhs.extract_string() == String::from("ip") {
|
||||||
|
println!("IP: {}", rhs.extract_string());
|
||||||
|
Some(rhs.extract_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if ip.is_some() {
|
||||||
|
t_ip = ip;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t_ip.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let t_functions = server_functions.entry(ip).or_insert(HashMap::new());
|
||||||
|
t_functions.insert(function.clone().0.clone(), function.clone().1.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut servers: HashMap<String, Arc<Mutex<TcpStream>>> = HashMap::new();
|
||||||
|
for (ip, functions) in server_functions.clone() {
|
||||||
|
let mut stream = TcpStream::connect(ip.clone()).unwrap();
|
||||||
|
stream
|
||||||
|
.write_fmt(format_args!(
|
||||||
|
"{}\n",
|
||||||
|
serde_json::to_string(&functions).unwrap()
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
servers.insert(ip, Arc::new(Mutex::new(stream)));
|
||||||
|
}
|
||||||
|
|
||||||
let mut gpsl = GPSL::new(
|
let mut gpsl = GPSL::new(
|
||||||
source,
|
source,
|
||||||
Some(parser.functions().unwrap()),
|
Some(functions),
|
||||||
Arc::new(Mutex::new(Some(stream))),
|
Some(server_functions),
|
||||||
|
Some(servers),
|
||||||
vec![STD_FUNC],
|
vec![STD_FUNC],
|
||||||
);
|
);
|
||||||
let res = gpsl.run("main".to_string(), vec![]);
|
let res = gpsl.run("main".to_string(), HashMap::new());
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
println!("Error: {:?}", err);
|
println!("Error: {:?}", err);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user