mirror of
https://github.com/fluencelabs/aquavm
synced 2024-12-04 15:20:16 +00:00
Refactor call
triplets (#269)
Older grammar allowed some variabilty in triple format. Now, the only format allowed is: `peer_id (service_id function_name)` As less errors can happen during parsing of the triplet, the code was simplified further . Closes #267.
This commit is contained in:
parent
99d7aa0d93
commit
3c23ab735c
@ -32,20 +32,6 @@ pub enum CallInstrValue<'i> {
|
||||
Variable(VariableWithLambda<'i>),
|
||||
}
|
||||
|
||||
/// The peer part of a call instruction triplet
|
||||
#[derive(Serialize, Debug, PartialEq)]
|
||||
pub enum PeerPart<'i> {
|
||||
PeerPk(CallInstrValue<'i>),
|
||||
PeerPkWithServiceId(CallInstrValue<'i>, CallInstrValue<'i>),
|
||||
}
|
||||
|
||||
/// The function part of a call instruction triplet
|
||||
#[derive(Serialize, Debug, PartialEq)]
|
||||
pub enum FunctionPart<'i> {
|
||||
FuncName(CallInstrValue<'i>),
|
||||
ServiceIdWithFuncName(CallInstrValue<'i>, CallInstrValue<'i>),
|
||||
}
|
||||
|
||||
/// Triplet represents a location of the executable code in the network.
|
||||
/// It is build from `PeerPart` and `FunctionPart` of a `Call` instruction.
|
||||
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
|
||||
|
@ -76,30 +76,6 @@ impl fmt::Display for ApArgument<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PeerPart<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use PeerPart::*;
|
||||
|
||||
match self {
|
||||
PeerPk(peer_pk) => write!(f, "{}", peer_pk),
|
||||
PeerPkWithServiceId(peer_pk, service_id) => write!(f, "({} {})", peer_pk, service_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FunctionPart<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use FunctionPart::*;
|
||||
|
||||
match self {
|
||||
FuncName(func_name) => write!(f, "{}", func_name),
|
||||
ServiceIdWithFuncName(service_id, func_name) => {
|
||||
write!(f, "({} {})", service_id, func_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Triplet<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
|
@ -3,8 +3,6 @@ use crate::parser::ParserError;
|
||||
use crate::parser::VariableValidator;
|
||||
use crate::parser::Span;
|
||||
use crate::parser::lexer::Token;
|
||||
use crate::parser::air_utils::*;
|
||||
use crate::make_user_error;
|
||||
|
||||
use air_lambda_parser::LambdaAST;
|
||||
use lalrpop_util::ErrorRecovery;
|
||||
@ -16,16 +14,7 @@ grammar<'err, 'input, 'v>(input: &'input str, errors: &'err mut Vec<ErrorRecover
|
||||
pub AIR = Instr;
|
||||
|
||||
Instr: Box<Instruction<'input>> = {
|
||||
<left: @L> "(" call <peer_part:PeerPart> <function_part:FPart> <args:Args> <output:CallOutput?> ")" <right: @R> => {
|
||||
let triplet = match try_to_raw_triplet(peer_part, function_part) {
|
||||
Some(raw_triplet) => raw_triplet,
|
||||
None => {
|
||||
// none means error
|
||||
errors.push(make_user_error!(InvalidCallTriplet, left, Token::Call, right));
|
||||
return Box::new(Instruction::Error);
|
||||
}
|
||||
};
|
||||
|
||||
<left: @L> "(" call <triplet:Triplet> <args:Args> <output:CallOutput?> ")" <right: @R> => {
|
||||
let args = Rc::new(args);
|
||||
let output = output.map(CallOutputValue::Variable).unwrap_or(CallOutputValue::None);
|
||||
let call = Call::new(triplet, args, output);
|
||||
@ -117,14 +106,12 @@ Args: Vec<Value<'input>> = {
|
||||
"[" <args:(<Arg>)*> "]" => args
|
||||
}
|
||||
|
||||
FPart: FunctionPart<'input> = {
|
||||
<f:Function> => FunctionPart::FuncName(f),
|
||||
"(" <sid:ServiceId> <f:Function> ")" => FunctionPart::ServiceIdWithFuncName(sid, f),
|
||||
}
|
||||
|
||||
PeerPart: PeerPart<'input> = {
|
||||
<pid:PeerId> => PeerPart::PeerPk(pid),
|
||||
"(" <pid:PeerId> <sid:ServiceId> ")" => PeerPart::PeerPkWithServiceId(pid, sid),
|
||||
Triplet: Triplet<'input> = {
|
||||
<peer_pk:PeerId> "(" <service_id:ServiceId> <function_name:Function> ")" => Triplet {
|
||||
peer_pk,
|
||||
service_id,
|
||||
function_name
|
||||
}
|
||||
}
|
||||
|
||||
ApResult = ScriptVariable;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,10 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mod triplet;
|
||||
|
||||
pub(crate) use triplet::try_to_raw_triplet;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_user_error(
|
||||
($error_type:ident, $start_pos: ident, $token:expr, $end_pos: ident) => { {
|
||||
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::ast::FunctionPart;
|
||||
use crate::ast::PeerPart;
|
||||
use crate::ast::Triplet;
|
||||
|
||||
/// Build a `Triplet` from `Call`'s `PeerPart` and `FunctionPart`
|
||||
pub(crate) fn try_to_raw_triplet<'i>(
|
||||
peer: PeerPart<'i>,
|
||||
f: FunctionPart<'i>,
|
||||
) -> Option<Triplet<'i>> {
|
||||
use FunctionPart::*;
|
||||
use PeerPart::*;
|
||||
|
||||
let (peer_pk, service_id, function_name) = match (peer, f) {
|
||||
(PeerPkWithServiceId(peer_pk, _), ServiceIdWithFuncName(service_id, func_name)) => {
|
||||
(peer_pk, service_id, func_name)
|
||||
}
|
||||
(PeerPkWithServiceId(peer_pk, peer_service_id), FuncName(func_name)) => {
|
||||
(peer_pk, peer_service_id, func_name)
|
||||
}
|
||||
(PeerPk(peer_pk), ServiceIdWithFuncName(service_id, func_name)) => {
|
||||
(peer_pk, service_id, func_name)
|
||||
}
|
||||
(PeerPk(_), FuncName(_)) => return None,
|
||||
};
|
||||
|
||||
let raw_triplet = Triplet {
|
||||
peer_pk,
|
||||
service_id,
|
||||
function_name,
|
||||
};
|
||||
|
||||
Some(raw_triplet)
|
||||
}
|
@ -36,10 +36,6 @@ pub enum ParserError {
|
||||
#[error("last error with non-empty path is ambiguous, please use just %last_error%")]
|
||||
AmbiguousFailLastError(Span),
|
||||
|
||||
/// Semantic errors in a call instructions.
|
||||
#[error("call should have service id specified by peer part or function part")]
|
||||
InvalidCallTriplet(Span),
|
||||
|
||||
#[error("new can't be applied to a '{iterator_name}' because it's an iterator")]
|
||||
IteratorRestrictionNotAllowed { span: Span, iterator_name: String },
|
||||
|
||||
@ -60,7 +56,6 @@ impl ParserError {
|
||||
Self::UndefinedVariable { span, .. } => *span,
|
||||
Self::UndefinedIterable { span, .. } => *span,
|
||||
Self::AmbiguousFailLastError(span) => *span,
|
||||
Self::InvalidCallTriplet(span) => *span,
|
||||
Self::IteratorRestrictionNotAllowed { span, .. } => *span,
|
||||
Self::MultipleIterableValuesForOneIterator { span, .. } => *span,
|
||||
Self::MultipleNextInFold { span, .. } => *span,
|
||||
|
@ -174,31 +174,6 @@ fn parse_undefined_stream_with_lambda() {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_call_with_invalid_triplet() {
|
||||
let source_code = r#"
|
||||
(call "" "" [$stream.$.json_path])
|
||||
"#;
|
||||
|
||||
let lexer = crate::AIRLexer::new(source_code);
|
||||
|
||||
let parser = crate::AIRParser::new();
|
||||
let mut errors = Vec::new();
|
||||
let mut validator = crate::parser::VariableValidator::new();
|
||||
parser
|
||||
.parse(source_code, &mut errors, &mut validator, lexer)
|
||||
.expect("parser shouldn't fail");
|
||||
|
||||
assert_eq!(errors.len(), 1);
|
||||
let error = &errors[0].error;
|
||||
let parser_error = match error {
|
||||
ParseError::User { error } => error,
|
||||
_ => panic!("unexpected error type"),
|
||||
};
|
||||
|
||||
assert!(matches!(parser_error, ParserError::InvalidCallTriplet(..)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_lambda_complex() {
|
||||
let source_code = r#"
|
||||
|
@ -55,7 +55,7 @@ fn parse_par_par() {
|
||||
(par
|
||||
(par
|
||||
(call "" ("" "") [])
|
||||
(call ("" "") ("" "") [])
|
||||
(call "" ("" "") [])
|
||||
)
|
||||
(call "" ("" "") [])
|
||||
)
|
||||
|
@ -59,7 +59,7 @@ fn parse_seq_seq() {
|
||||
(seq
|
||||
(seq
|
||||
(call peer_id (service_id function_name) [])
|
||||
(call (peer_id service_A) ("service_B" function_name) [])
|
||||
(call peer_id ("service_B" function_name) [])
|
||||
)
|
||||
(call "peer_id" ("service_id" "function_name") ["hello" name] $output)
|
||||
)
|
||||
@ -70,14 +70,14 @@ fn parse_seq_seq() {
|
||||
call(
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("peer_id", 53)),
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("service_id", 62)),
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("function_name", 073)),
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("function_name", 73)),
|
||||
Rc::new(vec![]),
|
||||
CallOutputValue::None,
|
||||
),
|
||||
call(
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("peer_id", 115)),
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("peer_id", 114)),
|
||||
CallInstrValue::Literal("service_B"),
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("function_name", 147)),
|
||||
CallInstrValue::Variable(VariableWithLambda::scalar("function_name", 135)),
|
||||
Rc::new(vec![]),
|
||||
CallOutputValue::None,
|
||||
),
|
||||
@ -88,9 +88,9 @@ fn parse_seq_seq() {
|
||||
CallInstrValue::Literal("function_name"),
|
||||
Rc::new(vec![
|
||||
Value::Literal("hello"),
|
||||
Value::Variable(VariableWithLambda::scalar("name", 248)),
|
||||
Value::Variable(VariableWithLambda::scalar("name", 236)),
|
||||
]),
|
||||
CallOutputValue::Variable(Variable::stream("$output", 254)),
|
||||
CallOutputValue::Variable(Variable::stream("$output", 242)),
|
||||
),
|
||||
);
|
||||
assert_eq!(instruction, expected);
|
||||
|
Loading…
Reference in New Issue
Block a user