diff --git a/client.gpsl b/client.gpsl index 63f3aa2..6006c4b 100644 --- a/client.gpsl +++ b/client.gpsl @@ -1,6 +1,6 @@ -#[server(ip = "localhost:8080")] +#[server(ip = "172.25.5.189:8080")] fn encrypt_add(a: eep, b: eep) { print("a: "); println(a); @@ -11,14 +11,20 @@ fn encrypt_add(a: eep, b: eep) { fn main() { - let enc_a: eep; - let enc_b: eep; + print("Input a: ") + let a = to_u512(read_line()) - enc_a = encrypt(10); - enc_b = encrypt(4); + print("Input b: ") + let b = to_u512(read_line()) - let enc_res: eep; - enc_res = encrypt_add(enc_a, enc_b); + let enc_a = encrypt(a) + let enc_b = encrypt(b) - println(decrypt(enc_res)); + let enc_res = encrypt_add(enc_a, enc_b) + + println(decrypt(enc_res)) + + for (let i=0 i<10 i+=1) { + println(i) + } } diff --git a/src/gpsl/external_function.rs b/src/gpsl/external_function.rs index 88a9396..c619dbe 100644 --- a/src/gpsl/external_function.rs +++ b/src/gpsl/external_function.rs @@ -1,5 +1,6 @@ use primitive_types::U512; use serde::{Deserialize, Serialize}; +use std::io::{stdout, Write}; use crate::{ elliptic_curve::{elliptic_curve::EllipticCurvePoint, encryption::Encryption}, @@ -41,6 +42,7 @@ pub const STD_FUNC: fn( let encryption = data.encryption; let plain = match args[0] { Variable::Number { value } => U512::from(value), + Variable::U512 { value } => value, _ => panic!("encrypt: first argument must be a number"), }; let ec = encryption.plain_to_ec_point(plain); @@ -82,6 +84,14 @@ pub const STD_FUNC: fn( }), }; } + Variable::Text { value } => { + return ExternalFuncReturn { + status: ExternalFuncStatus::SUCCESS, + value: Some(Variable::U512 { + value: U512::from_dec_str(&value).unwrap(), + }), + }; + } _ => { return ExternalFuncReturn { status: ExternalFuncStatus::ERROR, @@ -90,6 +100,23 @@ pub const STD_FUNC: fn( } } } + "read_line" => { + if accept.contains(&Permission::StdIo) && !reject.contains(&Permission::StdIo) { + let mut buffer = String::default(); + std::io::stdin().read_line(&mut buffer).unwrap(); + return ExternalFuncReturn { + status: ExternalFuncStatus::SUCCESS, + value: Some(Variable::Text { + value: String::from(buffer.trim()), + }), + }; + } else { + return ExternalFuncReturn { + status: ExternalFuncStatus::REJECTED, + value: None, + }; + } + } "println" => { if accept.contains(&Permission::StdIo) && !reject.contains(&Permission::StdIo) { match &args[0] { @@ -121,6 +148,8 @@ pub const STD_FUNC: fn( Variable::PairedEncrypted { value } => print!("{:x}", value.value), _ => {} } + + stdout().flush().unwrap(); ExternalFuncReturn { status: ExternalFuncStatus::SUCCESS, value: None, diff --git a/src/gpsl/grammar/GpslParser.g4 b/src/gpsl/grammar/GpslParser.g4 index 31a8f49..7ff36ed 100644 --- a/src/gpsl/grammar/GpslParser.g4 +++ b/src/gpsl/grammar/GpslParser.g4 @@ -16,7 +16,7 @@ stmt: let | expr SEMICOLON ; -let: LET IDENT COLON IDENT SEMICOLON ; +let: LET IDENT ((COLON IDENT (EQ expr)?) | EQ expr) SEMICOLON ; block: permission? LCURL stmt* RCURL ; return: RETURN expr? SEMICOLON ; if: IF LPAREN expr RPAREN stmt (ELSE stmt)? ; diff --git a/src/gpsl/node.rs b/src/gpsl/node.rs index 80e5fb7..5c96b80 100644 --- a/src/gpsl/node.rs +++ b/src/gpsl/node.rs @@ -72,7 +72,8 @@ pub enum Node { }, Define { name: String, - var_type: String, + var_type: Option, + value: Option>, }, Call { name: String, diff --git a/src/gpsl/parser.rs b/src/gpsl/parser.rs index a7f9489..a341234 100644 --- a/src/gpsl/parser.rs +++ b/src/gpsl/parser.rs @@ -116,14 +116,39 @@ impl Parser { { let ident = self.tokenizer.current_token().clone(); self.tokenizer.expect_kind(TokenKind::IDENT)?; - self.tokenizer.expect(String::from(":"))?; - let var_type = self.tokenizer.current_token().clone(); - self.tokenizer.expect_kind(TokenKind::IDENT)?; - self.tokenizer.expect(String::from(";"))?; - return Ok(Box::new(Node::Define { - name: ident.str, - var_type: var_type.str, - })); + + let var_type = if self + .tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from(":")) + { + let var_type = self.tokenizer.current_token().clone(); + self.tokenizer.expect_kind(TokenKind::IDENT)?; + Some(var_type.str) + } else { + None + }; + + if self + .tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from("=")) + { + let value = self.expr()?; + self.tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from(";")); + return Ok(Box::new(Node::Define { + name: ident.str, + var_type, + value: Some(value), + })); + } else { + self.tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from(";")); + return Ok(Box::new(Node::Define { + name: ident.str, + var_type, + value: None, + })); + } } debug!("{}: parsing permission", line!()); @@ -164,7 +189,8 @@ impl Parser { if self.tokenizer.consume_kind(TokenKind::RETURN) { let node = Node::Return { lhs: self.expr()? }; - self.tokenizer.expect(String::from(";"))?; + self.tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from(";")); return Ok(Box::new(node)); } @@ -202,11 +228,12 @@ impl Parser { self.tokenizer.expect(String::from("("))?; let init: Option> = if self.tokenizer.current_token().str != String::from(";") { - Some(self.expr()?) + Some(self.stmt()?) } else { None }; - self.tokenizer.expect(String::from(";"))?; + self.tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from(";")); let condition: Option> = if self.tokenizer.current_token().str != String::from(";") { @@ -214,7 +241,8 @@ impl Parser { } else { None }; - self.tokenizer.expect(String::from(";"))?; + self.tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from(";")); let update: Option> = if self.tokenizer.current_token().str != String::from(")") { @@ -238,7 +266,8 @@ impl Parser { } let node = self.expr(); - self.tokenizer.expect(String::from(";"))?; + self.tokenizer + .consume_kind_str(TokenKind::RESERVED, String::from(";")); return node; } diff --git a/src/gpsl/variable.rs b/src/gpsl/variable.rs index 0d33f87..4cb6353 100644 --- a/src/gpsl/variable.rs +++ b/src/gpsl/variable.rs @@ -15,3 +15,17 @@ pub enum Variable { U512 { value: U512 }, None {}, } + +impl Variable { + pub fn get_type(&self) -> String { + match self { + Variable::Number { .. } => "num".to_string(), + Variable::Text { .. } => "String".to_string(), + Variable::Return { .. } => "return".to_string(), + Variable::PureEncrypted { .. } => "eep".to_string(), + Variable::PairedEncrypted { .. } => "eep_p".to_string(), + Variable::U512 { .. } => "U512".to_string(), + Variable::None { .. } => "none".to_string(), + } + } +} diff --git a/src/gpsl/vm/gpsl.rs b/src/gpsl/vm/gpsl.rs index b1d02ef..ec28da7 100644 --- a/src/gpsl/vm/gpsl.rs +++ b/src/gpsl/vm/gpsl.rs @@ -49,7 +49,7 @@ pub struct GPSL { #[derive(Clone, Debug)] pub struct LocalVariable { pub name: String, - pub value: Variable, + pub value: Option, pub status: VariableStatus, } @@ -286,7 +286,7 @@ impl GPSL { if let Ok(Some(rhs)) = rhs { match *(lhs.clone()) { Node::Lvar { value } => { - self.get_local_var_mut(&value).unwrap().value = rhs; + self.get_local_var_mut(&value).unwrap().value = Some(rhs); self.get_local_var_mut(&value).unwrap().status.initialized = true; } _ => {} @@ -388,7 +388,9 @@ impl GPSL { } } Node::Lvar { value } => { - return Ok(Some(self.get_local_var(&value).unwrap().value.clone())); + return Ok(Some( + self.get_local_var(&value).unwrap().value.clone().unwrap(), + )); } Node::Return { lhs } => { if let Ok(Some(lhs)) = self.evaluate(lhs) { @@ -555,32 +557,59 @@ impl GPSL { return Ok(None); } - Node::Define { name, var_type } => { - let value = if var_type == "num" { - Variable::Number { value: 0 } - } else if var_type == "String" { - Variable::Text { - value: String::default(), - } - } else if var_type == "eep" { - Variable::PureEncrypted { - value: EncryptedEllipticCurvePoint::default(), + Node::Define { + name, + var_type, + value, + } => { + if let Some(value) = value { + if let Ok(Some(value)) = self.evaluate(value) { + if value.get_type() == var_type.unwrap_or(value.get_type()) { + self.blocks.front_mut().unwrap().variables.insert( + name.clone(), + LocalVariable { + name, + value: Some(value), + status: VariableStatus { initialized: true }, + }, + ); + return Ok(None); + } else { + return Err(String::from("Type mismatch.")); + } + } else { + return Err(String::from("Cannot evaluate value.")); } } else { - return Err(format!("{}: 未知の型です。", var_type)); - }; - self.blocks.front_mut().unwrap().variables.insert( - name.clone(), - LocalVariable { - name, - value, - status: VariableStatus::default(), - }, - ); + let value = match &*var_type.unwrap() { + "num" => Variable::Number { value: 0 }, + "String" => Variable::Text { + value: String::new(), + }, + "eep" => Variable::PureEncrypted { + value: EncryptedEllipticCurvePoint::default(), + }, + "U512" => Variable::U512 { + value: U512::default(), + }, + _ => { + panic!("Invalid variable type."); + } + }; - debug!("Define: {:?}", self.blocks.front()); + self.blocks.front_mut().unwrap().variables.insert( + name.clone(), + LocalVariable { + name, + value: Some(value), + status: VariableStatus::default(), + }, + ); - return Ok(None); + debug!("Define: {:?}", self.blocks.front()); + + return Ok(None); + } } _ => Ok(None), } @@ -600,7 +629,7 @@ impl GPSL { name.clone(), LocalVariable { name: name.clone(), - value, + value: Some(value), status: VariableStatus::default(), }, );