add server function call

This commit is contained in:
Masato Imai
2022-07-21 16:04:00 +09:00
parent be3bd2572e
commit 660ed217be
12 changed files with 351 additions and 97 deletions

4
Cargo.lock generated
View File

@ -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",

View File

@ -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 = "*"

View File

@ -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));
} }

View File

@ -1,3 +1,4 @@
#[server(ip = "localhost:8080")]
fn main() { fn main() {
send(receive()); send(receive());
} }

View File

@ -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,

View File

@ -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 ;

View File

@ -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()),
}
}
} }

View File

@ -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 ;
*/ */

View File

@ -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,

View File

@ -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 {

View File

@ -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;

View File

@ -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);
} }