add mode grammar

This commit is contained in:
Masato Imai
2022-07-14 11:29:34 +09:00
parent 0e0952d40a
commit 2cc8651e7e
7 changed files with 205 additions and 199 deletions

View File

@ -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_]+ ;

View File

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

View File

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

View File

@ -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()?));

View File

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

View File

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

3
test.gpsl Normal file
View File

@ -0,0 +1,3 @@
fn main() {
println("test");
}