blob: 9483114cef9777ebdacf7c7988d172660ecb36bb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2021 CentraleSupelec, CEA-LIST
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Erwan Mahé (CentraleSupelec) - initial API and implementation
*******************************************************************************/
use pest::Parser;
use pest::iterators::{Pair,Pairs};
use crate::core::context::general::GeneralContext;
use crate::core::syntax::data::generic::TD_Generic;
use crate::core::syntax::data::td_type::TD_DataType;
use crate::core::syntax::data::builtin::string::TD_String;
use crate::core::syntax::data::builtin::bool::TD_Bool;
use crate::core::syntax::data::builtin::number::{ARITH_FACTOR_SIGN, ARITH_ADD_SIGN};
use crate::core::syntax::data::builtin::integer::TD_Integer;
use crate::core::syntax::data::builtin::float::TD_Float;
use crate::core::syntax::data::var_ref::VariableReference;
use crate::from_text::error::HibouParsingError;
use crate::from_text::parser::*;
use crate::from_text::data::arithmetic::{ParsingNumberKind,parse_arith_expr};
use crate::from_text::data::logic::parse_logic_expr;
pub fn parse_data(gen_ctx : &GeneralContext,
td_value : Pair<Rule>,
opt_ms_id : &Option<usize>) -> Result<TD_Generic,HibouParsingError> {
let data_pair = td_value.into_inner().next().unwrap();
match data_pair.as_rule() {
Rule::MSG_PRM_REF => {
match opt_ms_id {
None => {
return Err( HibouParsingError::ParameterUsageError("need contextual message to parse data with message parameter reference".to_string()));
},
Some( ms_id ) => {
match gen_ctx.get_ms_spec(*ms_id) {
Err(e) => {
panic!();
},
Ok( ms_spec ) => {
let content = data_pair.into_inner().next().unwrap();
match content.as_rule() {
Rule::PRM_LABEL => {
let prm_label : String = content.as_str().chars().filter(|c| !c.is_whitespace()).collect();
let mut idx : usize = 0;
for (pr_type,opt_pr_name) in ms_spec {
if let Some(got_pr_name) = opt_pr_name {
if got_pr_name == prm_label {
let var_ref = VariableReference::MSG_PARAMETER(*ms_id,idx);
match pr_type {
TD_DataType::Bool => {
return Ok( TD_Generic::Bool( TD_Bool::Reference(var_ref) ) );
},
TD_DataType::Integer => {
return Ok( TD_Generic::Integer( TD_Integer::Reference(var_ref) ) );
},
TD_DataType::Float => {
return Ok( TD_Generic::Float( TD_Float::Reference(var_ref) ) );
},
TD_DataType::String => {
return Ok( TD_Generic::String( TD_String::Reference(var_ref) ) );
},
_ => {
panic!();
}
}
}
}
idx = idx +1;
}
return Err(HibouParsingError::ParameterUsageError( format!("no parameter '{}' in message '{}'",prm_label,gen_ctx.get_ms_name(*ms_id).unwrap()) ));
},
Rule::ARITH_INTEGER => {
let pr_id : usize = content.as_str().parse::<usize>().unwrap();
match ms_spec.get(pr_id) {
None => {
return Err(HibouParsingError::ParameterUsageError(format!("missing parameter declaration")));
},
Some( (pr_type,opt_pr_name) ) => {
let var_ref = VariableReference::MSG_PARAMETER(*ms_id,pr_id);
match pr_type {
TD_DataType::Bool => {
return Ok( TD_Generic::Bool( TD_Bool::Reference(var_ref) ) );
},
TD_DataType::Integer => {
return Ok( TD_Generic::Integer( TD_Integer::Reference(var_ref) ) );
},
TD_DataType::Float => {
return Ok( TD_Generic::Float( TD_Float::Reference(var_ref) ) );
},
TD_DataType::String => {
return Ok( TD_Generic::String( TD_String::Reference(var_ref) ) );
},
_ => {
panic!();
}
}
}
}
},
_ => {
panic!("what rule then ? : {:?}", content.as_rule() );
}
}
}
}
}
}
},
Rule::VAR_LABEL => {
let var_name : String = data_pair.as_str().chars().filter(|c| !c.is_whitespace()).collect();
match gen_ctx.get_vr_id( &var_name) {
None => {
return Err( HibouParsingError::MissingVariableDeclarationError(var_name) );
},
Some( vr_id ) => {
match gen_ctx.get_vr_type(vr_id) {
Err(_) => {
panic!();
},
Ok( var_type ) => {
let var_ref = VariableReference::VARIABLE(vr_id);
match var_type {
TD_DataType::Bool => {
return Ok( TD_Generic::Bool( TD_Bool::Reference(var_ref) ) );
},
TD_DataType::Integer => {
return Ok( TD_Generic::Integer( TD_Integer::Reference(var_ref) ) );
},
TD_DataType::Float => {
return Ok( TD_Generic::Float( TD_Float::Reference(var_ref) ) );
},
TD_DataType::String => {
return Ok( TD_Generic::String( TD_String::Reference(var_ref) ) );
},
_ => {
panic!();
}
}
}
}
}
}
},
Rule::STRING_content => {
let string_content = data_pair.as_str().chars().filter(|c| !c.is_whitespace()).collect();
let string_value = TD_String::Value( string_content );
return Ok( TD_Generic::String( string_value ));
},
Rule::ARITH_EXPR => {
return parse_arith_expr(gen_ctx, data_pair,opt_ms_id);
},
Rule::LOGIC_EXPR => {
match parse_logic_expr(gen_ctx, data_pair, opt_ms_id) {
Err(e) => {
return Err(e);
},
Ok( td_bool ) => {
return Ok( TD_Generic::Bool(td_bool) );
}
}
},
_ => {
panic!("what rule then ? : {:?}", data_pair.as_rule() );
}
}
}