文法を緩く

This commit is contained in:
Masato Imai
2022-07-25 13:44:10 +09:00
parent c6888e8ab2
commit 4842bf561b
7 changed files with 157 additions and 49 deletions

View File

@ -1,6 +1,6 @@
#[server(ip = "localhost:8080")] #[server(ip = "172.25.5.189:8080")]
fn encrypt_add(a: eep, b: eep) { fn encrypt_add(a: eep, b: eep) {
print("a: "); print("a: ");
println(a); println(a);
@ -11,14 +11,20 @@ fn encrypt_add(a: eep, b: eep) {
fn main() { fn main() {
let enc_a: eep; print("Input a: ")
let enc_b: eep; let a = to_u512(read_line())
enc_a = encrypt(10); print("Input b: ")
enc_b = encrypt(4); let b = to_u512(read_line())
let enc_res: eep; let enc_a = encrypt(a)
enc_res = encrypt_add(enc_a, enc_b); 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)
}
} }

View File

@ -1,5 +1,6 @@
use primitive_types::U512; use primitive_types::U512;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::io::{stdout, Write};
use crate::{ use crate::{
elliptic_curve::{elliptic_curve::EllipticCurvePoint, encryption::Encryption}, elliptic_curve::{elliptic_curve::EllipticCurvePoint, encryption::Encryption},
@ -41,6 +42,7 @@ pub const STD_FUNC: fn(
let encryption = data.encryption; let encryption = data.encryption;
let plain = match args[0] { let plain = match args[0] {
Variable::Number { value } => U512::from(value), Variable::Number { value } => U512::from(value),
Variable::U512 { value } => value,
_ => panic!("encrypt: first argument must be a number"), _ => panic!("encrypt: first argument must be a number"),
}; };
let ec = encryption.plain_to_ec_point(plain); 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 { return ExternalFuncReturn {
status: ExternalFuncStatus::ERROR, 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" => { "println" => {
if accept.contains(&Permission::StdIo) && !reject.contains(&Permission::StdIo) { if accept.contains(&Permission::StdIo) && !reject.contains(&Permission::StdIo) {
match &args[0] { match &args[0] {
@ -121,6 +148,8 @@ pub const STD_FUNC: fn(
Variable::PairedEncrypted { value } => print!("{:x}", value.value), Variable::PairedEncrypted { value } => print!("{:x}", value.value),
_ => {} _ => {}
} }
stdout().flush().unwrap();
ExternalFuncReturn { ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS, status: ExternalFuncStatus::SUCCESS,
value: None, value: None,

View File

@ -16,7 +16,7 @@ stmt: let
| expr SEMICOLON | expr SEMICOLON
; ;
let: LET IDENT COLON IDENT SEMICOLON ; let: LET IDENT ((COLON IDENT (EQ expr)?) | EQ expr) SEMICOLON ;
block: permission? LCURL stmt* RCURL ; block: permission? LCURL stmt* RCURL ;
return: RETURN expr? SEMICOLON ; return: RETURN expr? SEMICOLON ;
if: IF LPAREN expr RPAREN stmt (ELSE stmt)? ; if: IF LPAREN expr RPAREN stmt (ELSE stmt)? ;

View File

@ -72,7 +72,8 @@ pub enum Node {
}, },
Define { Define {
name: String, name: String,
var_type: String, var_type: Option<String>,
value: Option<Box<Node>>,
}, },
Call { Call {
name: String, name: String,

View File

@ -116,14 +116,39 @@ impl Parser {
{ {
let ident = self.tokenizer.current_token().clone(); let ident = self.tokenizer.current_token().clone();
self.tokenizer.expect_kind(TokenKind::IDENT)?; self.tokenizer.expect_kind(TokenKind::IDENT)?;
self.tokenizer.expect(String::from(":"))?;
let var_type = self.tokenizer.current_token().clone(); let var_type = if self
self.tokenizer.expect_kind(TokenKind::IDENT)?; .tokenizer
self.tokenizer.expect(String::from(";"))?; .consume_kind_str(TokenKind::RESERVED, String::from(":"))
return Ok(Box::new(Node::Define { {
name: ident.str, let var_type = self.tokenizer.current_token().clone();
var_type: var_type.str, 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!()); debug!("{}: parsing permission", line!());
@ -164,7 +189,8 @@ impl Parser {
if self.tokenizer.consume_kind(TokenKind::RETURN) { if self.tokenizer.consume_kind(TokenKind::RETURN) {
let node = Node::Return { lhs: self.expr()? }; 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)); return Ok(Box::new(node));
} }
@ -202,11 +228,12 @@ impl Parser {
self.tokenizer.expect(String::from("("))?; self.tokenizer.expect(String::from("("))?;
let init: Option<Box<Node>> = let init: Option<Box<Node>> =
if self.tokenizer.current_token().str != String::from(";") { if self.tokenizer.current_token().str != String::from(";") {
Some(self.expr()?) Some(self.stmt()?)
} else { } else {
None None
}; };
self.tokenizer.expect(String::from(";"))?; self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(";"));
let condition: Option<Box<Node>> = let condition: Option<Box<Node>> =
if self.tokenizer.current_token().str != String::from(";") { if self.tokenizer.current_token().str != String::from(";") {
@ -214,7 +241,8 @@ impl Parser {
} else { } else {
None None
}; };
self.tokenizer.expect(String::from(";"))?; self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(";"));
let update: Option<Box<Node>> = let update: Option<Box<Node>> =
if self.tokenizer.current_token().str != String::from(")") { if self.tokenizer.current_token().str != String::from(")") {
@ -238,7 +266,8 @@ impl Parser {
} }
let node = self.expr(); let node = self.expr();
self.tokenizer.expect(String::from(";"))?; self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(";"));
return node; return node;
} }

View File

@ -15,3 +15,17 @@ pub enum Variable {
U512 { value: U512 }, U512 { value: U512 },
None {}, 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(),
}
}
}

View File

@ -49,7 +49,7 @@ pub struct GPSL {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LocalVariable { pub struct LocalVariable {
pub name: String, pub name: String,
pub value: Variable, pub value: Option<Variable>,
pub status: VariableStatus, pub status: VariableStatus,
} }
@ -286,7 +286,7 @@ impl GPSL {
if let Ok(Some(rhs)) = rhs { if let Ok(Some(rhs)) = rhs {
match *(lhs.clone()) { match *(lhs.clone()) {
Node::Lvar { value } => { 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; self.get_local_var_mut(&value).unwrap().status.initialized = true;
} }
_ => {} _ => {}
@ -388,7 +388,9 @@ impl GPSL {
} }
} }
Node::Lvar { value } => { 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 } => { Node::Return { lhs } => {
if let Ok(Some(lhs)) = self.evaluate(lhs) { if let Ok(Some(lhs)) = self.evaluate(lhs) {
@ -555,32 +557,59 @@ impl GPSL {
return Ok(None); return Ok(None);
} }
Node::Define { name, var_type } => { Node::Define {
let value = if var_type == "num" { name,
Variable::Number { value: 0 } var_type,
} else if var_type == "String" { value,
Variable::Text { } => {
value: String::default(), if let Some(value) = value {
} if let Ok(Some(value)) = self.evaluate(value) {
} else if var_type == "eep" { if value.get_type() == var_type.unwrap_or(value.get_type()) {
Variable::PureEncrypted { self.blocks.front_mut().unwrap().variables.insert(
value: EncryptedEllipticCurvePoint::default(), 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 { } else {
return Err(format!("{}: 未知の型です。", var_type)); let value = match &*var_type.unwrap() {
}; "num" => Variable::Number { value: 0 },
self.blocks.front_mut().unwrap().variables.insert( "String" => Variable::Text {
name.clone(), value: String::new(),
LocalVariable { },
name, "eep" => Variable::PureEncrypted {
value, value: EncryptedEllipticCurvePoint::default(),
status: VariableStatus::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), _ => Ok(None),
} }
@ -600,7 +629,7 @@ impl GPSL {
name.clone(), name.clone(),
LocalVariable { LocalVariable {
name: name.clone(), name: name.clone(),
value, value: Some(value),
status: VariableStatus::default(), status: VariableStatus::default(),
}, },
); );