mirror of
https://github.com/mii443/encrypt.git
synced 2025-08-22 15:05:33 +00:00
add mode grammar
This commit is contained in:
@ -5,6 +5,7 @@ WS
|
|||||||
-> skip
|
-> skip
|
||||||
;
|
;
|
||||||
|
|
||||||
|
SHARP: '#' ;
|
||||||
DOLLER: '$' ;
|
DOLLER: '$' ;
|
||||||
ADD: '+' ;
|
ADD: '+' ;
|
||||||
SUB: '-' ;
|
SUB: '-' ;
|
||||||
@ -47,4 +48,4 @@ RETURN: 'return' ;
|
|||||||
NUM: [1-9] [0-9]* ;
|
NUM: [1-9] [0-9]* ;
|
||||||
|
|
||||||
TEXT: QUOTE [a-zA-Z0-9_-]* QUOTE ;
|
TEXT: QUOTE [a-zA-Z0-9_-]* QUOTE ;
|
||||||
IDENT: [a-zA-Z_]+ ;
|
IDENT: [a-zA-Z_]+ ;
|
||||||
|
@ -23,6 +23,7 @@ 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 ;
|
||||||
|
|
||||||
|
mode: SHARP IDENT ;
|
||||||
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
|
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
|
||||||
|
|
||||||
expr: assign ;
|
expr: assign ;
|
||||||
|
@ -18,11 +18,14 @@ pub enum Node {
|
|||||||
Function {
|
Function {
|
||||||
name: String,
|
name: String,
|
||||||
args: HashMap<String, String>,
|
args: HashMap<String, String>,
|
||||||
body: Vec<Box<Node>>
|
body: Vec<Box<Node>>,
|
||||||
|
},
|
||||||
|
Mode {
|
||||||
|
mode: String,
|
||||||
},
|
},
|
||||||
Permission {
|
Permission {
|
||||||
accept: Vec<String>,
|
accept: Vec<String>,
|
||||||
reject: Vec<String>
|
reject: Vec<String>,
|
||||||
},
|
},
|
||||||
Operator {
|
Operator {
|
||||||
kind: NodeKind,
|
kind: NodeKind,
|
||||||
@ -58,7 +61,8 @@ pub enum Node {
|
|||||||
},
|
},
|
||||||
Block {
|
Block {
|
||||||
stmts: Vec<Box<Node>>,
|
stmts: Vec<Box<Node>>,
|
||||||
permission: Option<Box<Node>>
|
permission: Option<Box<Node>>,
|
||||||
|
mode: Option<Box<Node>>,
|
||||||
},
|
},
|
||||||
Define {
|
Define {
|
||||||
name: String,
|
name: String,
|
||||||
@ -68,7 +72,7 @@ pub enum Node {
|
|||||||
name: String,
|
name: String,
|
||||||
args: Vec<Box<Node>>,
|
args: Vec<Box<Node>>,
|
||||||
},
|
},
|
||||||
None
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
|
@ -15,7 +15,7 @@ impl Parser {
|
|||||||
loop {
|
loop {
|
||||||
if self.tokenizer.current_token().kind != TokenKind::EOF {
|
if self.tokenizer.current_token().kind != TokenKind::EOF {
|
||||||
let function = self.function()?;
|
let function = self.function()?;
|
||||||
if let Node::Function{name, .. } = *function.clone() {
|
if let Node::Function { name, .. } = *function.clone() {
|
||||||
nodes.insert(name, function);
|
nodes.insert(name, function);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -28,19 +28,27 @@ 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> {
|
||||||
if self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from("fn")) {
|
if self
|
||||||
|
.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from("fn"))
|
||||||
|
{
|
||||||
debug!("parsing function");
|
debug!("parsing function");
|
||||||
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 = HashMap::new();
|
||||||
self.tokenizer.expect(String::from("("))?;
|
self.tokenizer.expect(String::from("("))?;
|
||||||
debug!("parsing args");
|
debug!("parsing args");
|
||||||
while !self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from(")")) {
|
while !self
|
||||||
|
.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(")"))
|
||||||
|
{
|
||||||
debug!("consume argument");
|
debug!("consume argument");
|
||||||
let name = self.tokenizer.expect_ident()?;
|
let name = self.tokenizer.expect_ident()?;
|
||||||
self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from(":"));
|
self.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(":"));
|
||||||
let type_str = self.tokenizer.expect_ident()?;
|
let type_str = self.tokenizer.expect_ident()?;
|
||||||
self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
self.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
||||||
args.insert(name, type_str);
|
args.insert(name, type_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +61,7 @@ impl Parser {
|
|||||||
return Ok(Box::new(Node::Function {
|
return Ok(Box::new(Node::Function {
|
||||||
name: func_name.str,
|
name: func_name.str,
|
||||||
args,
|
args,
|
||||||
body: nodes
|
body: nodes,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -110,9 +118,17 @@ impl Parser {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
debug!("parsing mode");
|
||||||
|
let mode = if self.tokenizer.current_token().str == "#" {
|
||||||
|
Some(self.mode()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
if self
|
if self
|
||||||
.tokenizer
|
.tokenizer
|
||||||
.consume_kind_str(TokenKind::RESERVED, String::from("{")) || permission != None
|
.consume_kind_str(TokenKind::RESERVED, String::from("{"))
|
||||||
|
|| permission != None
|
||||||
{
|
{
|
||||||
let mut stmts: Vec<Box<Node>> = vec![];
|
let mut stmts: Vec<Box<Node>> = vec![];
|
||||||
loop {
|
loop {
|
||||||
@ -120,7 +136,11 @@ impl Parser {
|
|||||||
.tokenizer
|
.tokenizer
|
||||||
.consume_kind_str(TokenKind::RESERVED, String::from("}"))
|
.consume_kind_str(TokenKind::RESERVED, String::from("}"))
|
||||||
{
|
{
|
||||||
return Ok(Box::new(Node::Block { stmts, permission: permission }));
|
return Ok(Box::new(Node::Block {
|
||||||
|
stmts,
|
||||||
|
permission: permission,
|
||||||
|
mode: mode,
|
||||||
|
}));
|
||||||
} else {
|
} else {
|
||||||
stmts.push(self.stmt()?);
|
stmts.push(self.stmt()?);
|
||||||
}
|
}
|
||||||
@ -207,6 +227,17 @@ impl Parser {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
mode: SHARP IDENT ;
|
||||||
|
*/
|
||||||
|
pub fn mode(&mut self) -> Result<Box<Node>, String> {
|
||||||
|
self.tokenizer.expect(String::from("#"))?;
|
||||||
|
let mode = self.tokenizer.current_token().clone();
|
||||||
|
self.tokenizer.expect_kind(TokenKind::IDENT)?;
|
||||||
|
self.tokenizer.expect(String::from(";"))?;
|
||||||
|
return Ok(Box::new(Node::Mode { mode: mode.str }));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
|
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
|
||||||
*/
|
*/
|
||||||
@ -217,15 +248,23 @@ impl Parser {
|
|||||||
let mut accept: Vec<String> = vec![];
|
let mut accept: Vec<String> = vec![];
|
||||||
let mut reject: Vec<String> = vec![];
|
let mut reject: Vec<String> = vec![];
|
||||||
|
|
||||||
while !self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from(")")) {
|
while !self
|
||||||
|
.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(")"))
|
||||||
|
{
|
||||||
let name = self.tokenizer.expect_ident()?;
|
let name = self.tokenizer.expect_ident()?;
|
||||||
if name != "accept" && name != "reject" {
|
if name != "accept" && name != "reject" {
|
||||||
return Err(String::from(format!("Unexpected: {}", name)));
|
return Err(String::from(format!("Unexpected: {}", name)));
|
||||||
}
|
}
|
||||||
self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from("["));
|
self.tokenizer
|
||||||
while !self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from("]")) {
|
.consume_kind_str(TokenKind::RESERVED, String::from("["));
|
||||||
|
while !self
|
||||||
|
.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from("]"))
|
||||||
|
{
|
||||||
let permission = self.tokenizer.expect_ident()?;
|
let permission = self.tokenizer.expect_ident()?;
|
||||||
self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
self.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
||||||
|
|
||||||
if name == "accept" {
|
if name == "accept" {
|
||||||
accept.push(permission);
|
accept.push(permission);
|
||||||
@ -234,7 +273,8 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tokenizer.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
self.tokenizer
|
||||||
|
.consume_kind_str(TokenKind::RESERVED, String::from(","));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Box::new(Node::Permission { accept, reject }))
|
Ok(Box::new(Node::Permission { accept, reject }))
|
||||||
@ -378,7 +418,7 @@ impl Parser {
|
|||||||
return Ok(Box::new(Node::Call {
|
return Ok(Box::new(Node::Call {
|
||||||
name: node.clone(),
|
name: node.clone(),
|
||||||
args: args,
|
args: args,
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
return Ok(Node::new_lvar_node(node.clone()));
|
return Ok(Node::new_lvar_node(node.clone()));
|
||||||
}
|
}
|
||||||
@ -386,9 +426,7 @@ impl Parser {
|
|||||||
if self.tokenizer.current_token().kind == TokenKind::TEXT {
|
if self.tokenizer.current_token().kind == TokenKind::TEXT {
|
||||||
let text = self.tokenizer.current_token().str.clone();
|
let text = self.tokenizer.current_token().str.clone();
|
||||||
self.tokenizer.consume_kind(TokenKind::TEXT);
|
self.tokenizer.consume_kind(TokenKind::TEXT);
|
||||||
return Ok(Box::new(Node::Text {
|
return Ok(Box::new(Node::Text { value: text }));
|
||||||
value: text,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(Node::new_num_node(self.tokenizer.expect_number()?));
|
return Ok(Node::new_num_node(self.tokenizer.expect_number()?));
|
||||||
|
@ -33,7 +33,12 @@ impl Tokenizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn consume_kind_str(&mut self, kind: TokenKind, string: String) -> bool {
|
pub fn consume_kind_str(&mut self, kind: TokenKind, string: String) -> bool {
|
||||||
debug!("consume kind str {:?} {:?} {:?}", kind ,string, self.current_token());
|
debug!(
|
||||||
|
"consume kind str {:?} {:?} {:?}",
|
||||||
|
kind,
|
||||||
|
string,
|
||||||
|
self.current_token()
|
||||||
|
);
|
||||||
return if self.current_token().kind == kind && self.current_token().str == string {
|
return if self.current_token().kind == kind && self.current_token().str == string {
|
||||||
self.cursor += 1;
|
self.cursor += 1;
|
||||||
true
|
true
|
||||||
@ -63,10 +68,7 @@ impl Tokenizer {
|
|||||||
pub fn expect_ident(&mut self) -> Result<String, String> {
|
pub fn expect_ident(&mut self) -> Result<String, String> {
|
||||||
debug!("Expect IDENT {:?}", self.current_token());
|
debug!("Expect IDENT {:?}", self.current_token());
|
||||||
if self.current_token().kind != TokenKind::IDENT {
|
if self.current_token().kind != TokenKind::IDENT {
|
||||||
return Err(format!(
|
return Err(format!("Unexpected type : {:?}", self.current_token().kind));
|
||||||
"Unexpected type : {:?}",
|
|
||||||
self.current_token().kind
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
let val = self.current_token().str.clone();
|
let val = self.current_token().str.clone();
|
||||||
self.cursor += 1;
|
self.cursor += 1;
|
||||||
@ -113,6 +115,7 @@ impl Tokenizer {
|
|||||||
String::from("-="),
|
String::from("-="),
|
||||||
String::from("*="),
|
String::from("*="),
|
||||||
String::from("/="),
|
String::from("/="),
|
||||||
|
String::from("#"),
|
||||||
String::from("$"),
|
String::from("$"),
|
||||||
String::from("+"),
|
String::from("+"),
|
||||||
String::from("-"),
|
String::from("-"),
|
||||||
@ -159,7 +162,7 @@ impl Tokenizer {
|
|||||||
self.tokens.push(Token {
|
self.tokens.push(Token {
|
||||||
kind: TokenKind::TEXT,
|
kind: TokenKind::TEXT,
|
||||||
str: text,
|
str: text,
|
||||||
num: 0
|
num: 0,
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub struct Block {
|
|||||||
pub accept: Vec<Permission>,
|
pub accept: Vec<Permission>,
|
||||||
pub reject: Vec<Permission>,
|
pub reject: Vec<Permission>,
|
||||||
pub variables: HashMap<String, LocalVariable>,
|
pub variables: HashMap<String, LocalVariable>,
|
||||||
pub is_split: bool
|
pub is_split: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GPSL {
|
pub struct GPSL {
|
||||||
@ -19,7 +19,8 @@ pub struct GPSL {
|
|||||||
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 external_func: Vec<fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn>
|
pub external_func:
|
||||||
|
Vec<fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -41,13 +42,19 @@ impl VariableStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GPSL {
|
impl GPSL {
|
||||||
pub fn new(source: Source, functions: Option<HashMap<String, Box<Node>>>, external_func: Vec<fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn>) -> GPSL {
|
pub fn new(
|
||||||
|
source: Source,
|
||||||
|
functions: Option<HashMap<String, Box<Node>>>,
|
||||||
|
external_func: Vec<
|
||||||
|
fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn,
|
||||||
|
>,
|
||||||
|
) -> GPSL {
|
||||||
GPSL {
|
GPSL {
|
||||||
source,
|
source,
|
||||||
functions,
|
functions,
|
||||||
global_variables: vec![],
|
global_variables: vec![],
|
||||||
blocks: VecDeque::new(),
|
blocks: VecDeque::new(),
|
||||||
external_func
|
external_func,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +65,7 @@ impl GPSL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.blocks[x].is_split {
|
if self.blocks[x].is_split {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -75,7 +82,7 @@ impl GPSL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.blocks[x].is_split {
|
if self.blocks[x].is_split {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -83,12 +90,8 @@ impl GPSL {
|
|||||||
|
|
||||||
pub fn extract_number(node: Variable) -> Result<usize, String> {
|
pub fn extract_number(node: Variable) -> Result<usize, String> {
|
||||||
match node {
|
match node {
|
||||||
Variable::Number { value } => {
|
Variable::Number { value } => Ok(value),
|
||||||
Ok(value)
|
_ => Err(String::from("Not a number")),
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
Err(String::from("Not a number"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,8 +108,18 @@ impl GPSL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(functions) = self.functions.clone() {
|
if let Some(functions) = self.functions.clone() {
|
||||||
debug!("functions: {:?}", functions.iter().map(|f| format!("{},", f.0)).collect::<String>());
|
debug!(
|
||||||
debug!("{}: {}", &function_name, functions.contains_key(&function_name));
|
"functions: {:?}",
|
||||||
|
functions
|
||||||
|
.iter()
|
||||||
|
.map(|f| format!("{},", f.0))
|
||||||
|
.collect::<String>()
|
||||||
|
);
|
||||||
|
debug!(
|
||||||
|
"{}: {}",
|
||||||
|
&function_name,
|
||||||
|
functions.contains_key(&function_name)
|
||||||
|
);
|
||||||
if functions.contains_key(&function_name) {
|
if functions.contains_key(&function_name) {
|
||||||
if let Node::Function { body, .. } = &*(functions[&function_name]) {
|
if let Node::Function { body, .. } = &*(functions[&function_name]) {
|
||||||
for program in body {
|
for program in body {
|
||||||
@ -119,7 +132,7 @@ impl GPSL {
|
|||||||
accept: block.accept.clone(),
|
accept: block.accept.clone(),
|
||||||
reject: block.reject.clone(),
|
reject: block.reject.clone(),
|
||||||
variables: HashMap::new(),
|
variables: HashMap::new(),
|
||||||
is_split: true
|
is_split: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = self.evaluate(Box::new(*program.clone()));
|
let res = self.evaluate(Box::new(*program.clone()));
|
||||||
@ -146,7 +159,12 @@ impl GPSL {
|
|||||||
|
|
||||||
for func in f {
|
for func in f {
|
||||||
let block = self.blocks.front().unwrap();
|
let block = self.blocks.front().unwrap();
|
||||||
let res = func(function_name.clone(), args_value.clone(), block.accept.clone(), block.reject.clone());
|
let res = func(
|
||||||
|
function_name.clone(),
|
||||||
|
args_value.clone(),
|
||||||
|
block.accept.clone(),
|
||||||
|
block.reject.clone(),
|
||||||
|
);
|
||||||
if res.status == ExternalFuncStatus::SUCCESS {
|
if res.status == ExternalFuncStatus::SUCCESS {
|
||||||
return Ok(res.value);
|
return Ok(res.value);
|
||||||
}
|
}
|
||||||
@ -157,16 +175,8 @@ impl GPSL {
|
|||||||
|
|
||||||
Err(format!("Function not found: {}", function_name))
|
Err(format!("Function not found: {}", function_name))
|
||||||
}
|
}
|
||||||
Node::Text { value } => {
|
Node::Text { value } => Ok(Some(Variable::Text { value })),
|
||||||
Ok(Some(Variable::Text {
|
Node::Number { value } => Ok(Some(Variable::Number { value })),
|
||||||
value
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Node::Number { value } => {
|
|
||||||
Ok(Some(Variable::Number {
|
|
||||||
value
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Node::Operator { kind, lhs, rhs } => {
|
Node::Operator { kind, lhs, rhs } => {
|
||||||
if kind == NodeKind::ASSIGN {
|
if kind == NodeKind::ASSIGN {
|
||||||
debug!("Assign: {:?}", self.blocks.front());
|
debug!("Assign: {:?}", self.blocks.front());
|
||||||
@ -191,132 +201,76 @@ impl GPSL {
|
|||||||
if let Some(lhs) = lhs {
|
if let Some(lhs) = lhs {
|
||||||
if let Some(rhs) = rhs {
|
if let Some(rhs) = rhs {
|
||||||
match kind {
|
match kind {
|
||||||
NodeKind::ADD => {
|
NodeKind::ADD => match GPSL::extract_number(lhs) {
|
||||||
match GPSL::extract_number(lhs) {
|
Ok(lhs) => match GPSL::extract_number(rhs) {
|
||||||
Ok(lhs) => {
|
Ok(rhs) => Ok(Some(Variable::Number { value: lhs + rhs })),
|
||||||
match GPSL::extract_number(rhs) {
|
Err(err) => Err(err),
|
||||||
Ok(rhs) => {
|
},
|
||||||
Ok(Some(Variable::Number {
|
Err(err) => Err(err),
|
||||||
value: lhs + rhs
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
NodeKind::DIV => {
|
NodeKind::DIV => match GPSL::extract_number(lhs) {
|
||||||
match GPSL::extract_number(lhs) {
|
Ok(lhs) => match GPSL::extract_number(rhs) {
|
||||||
Ok(lhs) => {
|
Ok(rhs) => Ok(Some(Variable::Number { value: lhs / rhs })),
|
||||||
match GPSL::extract_number(rhs) {
|
Err(err) => Err(err),
|
||||||
Ok(rhs) => {
|
},
|
||||||
Ok(Some(Variable::Number {
|
Err(err) => Err(err),
|
||||||
value: lhs / rhs
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
NodeKind::MUL => {
|
NodeKind::MUL => match GPSL::extract_number(lhs) {
|
||||||
match GPSL::extract_number(lhs) {
|
Ok(lhs) => match GPSL::extract_number(rhs) {
|
||||||
Ok(lhs) => {
|
Ok(rhs) => Ok(Some(Variable::Number { value: lhs * rhs })),
|
||||||
match GPSL::extract_number(rhs) {
|
Err(err) => Err(err),
|
||||||
Ok(rhs) => {
|
},
|
||||||
Ok(Some(Variable::Number {
|
Err(err) => Err(err),
|
||||||
value: lhs * rhs
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
NodeKind::SUB => {
|
NodeKind::SUB => match GPSL::extract_number(lhs) {
|
||||||
match GPSL::extract_number(lhs) {
|
Ok(lhs) => match GPSL::extract_number(rhs) {
|
||||||
Ok(lhs) => {
|
Ok(rhs) => Ok(Some(Variable::Number { value: lhs - rhs })),
|
||||||
match GPSL::extract_number(rhs) {
|
Err(err) => Err(err),
|
||||||
Ok(rhs) => {
|
},
|
||||||
Ok(Some(Variable::Number {
|
Err(err) => Err(err),
|
||||||
value: lhs - rhs
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
NodeKind::EQ => {
|
NodeKind::EQ => {
|
||||||
if lhs == rhs {
|
if lhs == rhs {
|
||||||
Ok(Some(Variable::Number {
|
Ok(Some(Variable::Number { value: 1 }))
|
||||||
value: 1
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(Variable::Number {
|
Ok(Some(Variable::Number { value: 0 }))
|
||||||
value: 0
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
NodeKind::NE => {
|
NodeKind::NE => {
|
||||||
if lhs != rhs {
|
if lhs != rhs {
|
||||||
Ok(Some(Variable::Number {
|
Ok(Some(Variable::Number { value: 1 }))
|
||||||
value: 1
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(Variable::Number {
|
Ok(Some(Variable::Number { value: 0 }))
|
||||||
value: 0
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
NodeKind::LT => {
|
NodeKind::LT => match GPSL::extract_number(lhs) {
|
||||||
match GPSL::extract_number(lhs) {
|
Ok(lhs) => match GPSL::extract_number(rhs) {
|
||||||
Ok(lhs) => {
|
Ok(rhs) => {
|
||||||
match GPSL::extract_number(rhs) {
|
if lhs < rhs {
|
||||||
Ok(rhs) => {
|
Ok(Some(Variable::Number { value: 1 }))
|
||||||
if lhs < rhs {
|
} else {
|
||||||
Ok(Some(Variable::Number {
|
Ok(Some(Variable::Number { value: 0 }))
|
||||||
value: 1
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
Ok(Some(Variable::Number {
|
|
||||||
value: 0
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => { Err(err) }
|
Err(err) => Err(err),
|
||||||
}
|
},
|
||||||
|
Err(err) => Err(err),
|
||||||
},
|
},
|
||||||
NodeKind::LE => {
|
NodeKind::LE => match GPSL::extract_number(lhs) {
|
||||||
match GPSL::extract_number(lhs) {
|
Ok(lhs) => match GPSL::extract_number(rhs) {
|
||||||
Ok(lhs) => {
|
Ok(rhs) => {
|
||||||
match GPSL::extract_number(rhs) {
|
if lhs <= rhs {
|
||||||
Ok(rhs) => {
|
Ok(Some(Variable::Number { value: 1 }))
|
||||||
if lhs <= rhs {
|
} else {
|
||||||
Ok(Some(Variable::Number {
|
Ok(Some(Variable::Number { value: 0 }))
|
||||||
value: 1
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
Ok(Some(Variable::Number {
|
|
||||||
value: 0
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => { Err(err) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => { Err(err) }
|
Err(err) => Err(err),
|
||||||
}
|
},
|
||||||
|
Err(err) => Err(err),
|
||||||
},
|
},
|
||||||
_ => Ok(None)
|
_ => Ok(None),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(String::from("RHS Variable is null."))
|
Err(String::from("RHS Variable is null."))
|
||||||
@ -331,7 +285,7 @@ impl GPSL {
|
|||||||
Node::Return { lhs } => {
|
Node::Return { lhs } => {
|
||||||
if let Ok(Some(lhs)) = self.evaluate(lhs) {
|
if let Ok(Some(lhs)) = self.evaluate(lhs) {
|
||||||
return Ok(Some(Variable::Return {
|
return Ok(Some(Variable::Return {
|
||||||
value: Box::new(lhs)
|
value: Box::new(lhs),
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
return Err(String::from("Cannot evaluate LHS."));
|
return Err(String::from("Cannot evaluate LHS."));
|
||||||
@ -345,7 +299,7 @@ impl GPSL {
|
|||||||
if let Ok(Some(condition)) = self.evaluate(condition) {
|
if let Ok(Some(condition)) = self.evaluate(condition) {
|
||||||
if match condition {
|
if match condition {
|
||||||
Variable::Number { value } => value == 1,
|
Variable::Number { value } => value == 1,
|
||||||
_ => false
|
_ => false,
|
||||||
} {
|
} {
|
||||||
if let Ok(Some(res)) = self.evaluate(stmt) {
|
if let Ok(Some(res)) = self.evaluate(stmt) {
|
||||||
match res.clone() {
|
match res.clone() {
|
||||||
@ -378,22 +332,18 @@ impl GPSL {
|
|||||||
let mut cond = if let Some(condition) = self.evaluate(condition.clone())? {
|
let mut cond = if let Some(condition) = self.evaluate(condition.clone())? {
|
||||||
condition
|
condition
|
||||||
} else {
|
} else {
|
||||||
Variable::Number {
|
Variable::Number { value: 0 }
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
while match cond {
|
while match cond {
|
||||||
Variable::Number { value } => value == 1,
|
Variable::Number { value } => value == 1,
|
||||||
_ => false
|
_ => false,
|
||||||
} {
|
} {
|
||||||
self.evaluate(stmt.clone())?;
|
self.evaluate(stmt.clone())?;
|
||||||
cond = if let Some(condition) = self.evaluate(condition.clone())? {
|
cond = if let Some(condition) = self.evaluate(condition.clone())? {
|
||||||
condition
|
condition
|
||||||
} else {
|
} else {
|
||||||
Variable::Number {
|
Variable::Number { value: 0 }
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,7 +356,9 @@ impl GPSL {
|
|||||||
stmt,
|
stmt,
|
||||||
} => {
|
} => {
|
||||||
match init {
|
match init {
|
||||||
Some(init) => {self.evaluate(init)?;},
|
Some(init) => {
|
||||||
|
self.evaluate(init)?;
|
||||||
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,26 +367,22 @@ impl GPSL {
|
|||||||
if let Some(condition) = self.evaluate(condition)? {
|
if let Some(condition) = self.evaluate(condition)? {
|
||||||
condition
|
condition
|
||||||
} else {
|
} else {
|
||||||
Variable::Number {
|
Variable::Number { value: 0 }
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
Variable::Number {
|
|
||||||
value: 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => Variable::Number { value: 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
while match cond {
|
while match cond {
|
||||||
Variable::Number { value } => value == 1,
|
Variable::Number { value } => value == 1,
|
||||||
_ => false
|
_ => false,
|
||||||
} {
|
} {
|
||||||
self.evaluate(stmt.clone())?;
|
self.evaluate(stmt.clone())?;
|
||||||
|
|
||||||
match update.clone() {
|
match update.clone() {
|
||||||
Some(update) => {self.evaluate(update)?;},
|
Some(update) => {
|
||||||
|
self.evaluate(update)?;
|
||||||
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,35 +391,45 @@ impl GPSL {
|
|||||||
if let Some(condition) = self.evaluate(condition)? {
|
if let Some(condition) = self.evaluate(condition)? {
|
||||||
condition
|
condition
|
||||||
} else {
|
} else {
|
||||||
Variable::Number {
|
Variable::Number { value: 0 }
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
Variable::Number {
|
|
||||||
value: 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => Variable::Number { value: 1 },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
Node::Block { stmts, permission } => {
|
Node::Block {
|
||||||
|
stmts,
|
||||||
|
permission,
|
||||||
|
mode,
|
||||||
|
} => {
|
||||||
let accept = self.blocks.front().unwrap().accept.clone();
|
let accept = self.blocks.front().unwrap().accept.clone();
|
||||||
let reject = self.blocks.front().unwrap().reject.clone();
|
let reject = self.blocks.front().unwrap().reject.clone();
|
||||||
let (accept, reject) = if let Node::Permission { accept, reject } = *permission.unwrap_or(Box::new(Node::None)) {
|
let (accept, reject) = if let Node::Permission { accept, reject } =
|
||||||
(accept.iter().map(|p| Permission::from_string(p)).collect(), reject.iter().map(|p| Permission::from_string(p)).collect())
|
*permission.unwrap_or(Box::new(Node::None))
|
||||||
|
{
|
||||||
|
(
|
||||||
|
accept.iter().map(|p| Permission::from_string(p)).collect(),
|
||||||
|
reject.iter().map(|p| Permission::from_string(p)).collect(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
(accept, reject)
|
(accept, reject)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mode = if let Node::Mode { mode } = *mode.unwrap_or(Box::new(Node::None)) {
|
||||||
|
mode
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
println!("Mode: {}", mode);
|
||||||
|
|
||||||
self.blocks.push_front(Block {
|
self.blocks.push_front(Block {
|
||||||
accept: accept,
|
accept: accept,
|
||||||
reject: reject,
|
reject: reject,
|
||||||
variables: HashMap::new(),
|
variables: HashMap::new(),
|
||||||
is_split: false
|
is_split: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
for stmt in stmts {
|
for stmt in stmts {
|
||||||
@ -492,12 +450,10 @@ impl GPSL {
|
|||||||
}
|
}
|
||||||
Node::Define { name, var_type } => {
|
Node::Define { name, var_type } => {
|
||||||
let value = if var_type == "num" {
|
let value = if var_type == "num" {
|
||||||
Variable::Number {
|
Variable::Number { value: 0 }
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
} else if var_type == "String" {
|
} else if var_type == "String" {
|
||||||
Variable::Text {
|
Variable::Text {
|
||||||
value: String::default()
|
value: String::default(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(format!("{}: 未知の型です。", var_type));
|
return Err(format!("{}: 未知の型です。", var_type));
|
||||||
@ -515,7 +471,7 @@ impl GPSL {
|
|||||||
|
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
_ => { Ok(None) },
|
_ => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +482,7 @@ impl GPSL {
|
|||||||
accept: vec![Permission::Administrator, Permission::StdIo],
|
accept: vec![Permission::Administrator, Permission::StdIo],
|
||||||
reject: vec![],
|
reject: vec![],
|
||||||
variables: HashMap::new(),
|
variables: HashMap::new(),
|
||||||
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]) {
|
||||||
|
Reference in New Issue
Block a user