mirror of
https://github.com/fluencelabs/aquavm
synced 2025-03-15 20:40:50 +00:00
Introduce never
instruction (#335)
This commit is contained in:
parent
250b316682
commit
20bb230a3a
@ -1,3 +1,11 @@
|
|||||||
|
## Version 0.29.0 (2022-09-19)
|
||||||
|
|
||||||
|
[PR 335](https://github.com/fluencelabs/aquavm/pull/335):
|
||||||
|
Introduce `never` instruction
|
||||||
|
|
||||||
|
[PR 332](https://github.com/fluencelabs/aquavm/pull/332):
|
||||||
|
Fix bug with incorrect positions in `canon` instruction
|
||||||
|
|
||||||
## Version 0.28.0 (2022-09-07)
|
## Version 0.28.0 (2022-09-07)
|
||||||
|
|
||||||
[PR 314](https://github.com/fluencelabs/aquavm/pull/314):
|
[PR 314](https://github.com/fluencelabs/aquavm/pull/314):
|
||||||
|
10
README.md
10
README.md
@ -28,7 +28,7 @@ AIR scripts control the Fluence peer-to-peer network, its peers and, through Mar
|
|||||||
### What is AIR?
|
### What is AIR?
|
||||||
|
|
||||||
- S-expression-based low-level language with binary form to come
|
- S-expression-based low-level language with binary form to come
|
||||||
- Consists of twelve (12) instructions with more instructions to come
|
- Consists of fourteen (14) instructions with more instructions to come
|
||||||
- Semantics are inspired by [π-calculus](https://en.wikipedia.org/wiki/%CE%A0-calculus), [λ-calculus](https://en.wikipedia.org/wiki/Lambda_calculus) and [category theory](https://en.wikipedia.org/wiki/Category_theory)
|
- Semantics are inspired by [π-calculus](https://en.wikipedia.org/wiki/%CE%A0-calculus), [λ-calculus](https://en.wikipedia.org/wiki/Lambda_calculus) and [category theory](https://en.wikipedia.org/wiki/Category_theory)
|
||||||
- Syntax is inspired by [Wasm Text Format](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format) (WAT) and [Lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language))
|
- Syntax is inspired by [Wasm Text Format](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format) (WAT) and [Lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language))
|
||||||
|
|
||||||
@ -175,6 +175,14 @@ Example
|
|||||||
(fail 1337 "error message")
|
(fail 1337 "error message")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### never
|
||||||
|
|
||||||
|
```wasm
|
||||||
|
(never)
|
||||||
|
```
|
||||||
|
|
||||||
|
- marks a subgraph as incomplete, useful for code generation
|
||||||
|
|
||||||
#### null
|
#### null
|
||||||
|
|
||||||
```wasm
|
```wasm
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "air-interpreter"
|
name = "air-interpreter"
|
||||||
version = "0.28.0"
|
version = "0.29.0"
|
||||||
description = "Crate-wrapper for air"
|
description = "Crate-wrapper for air"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "air"
|
name = "air"
|
||||||
version = "0.28.0"
|
version = "0.29.0"
|
||||||
description = "Interpreter of AIR scripts intended to coordinate request flow in the Fluence network"
|
description = "Interpreter of AIR scripts intended to coordinate request flow in the Fluence network"
|
||||||
authors = ["Fluence Labs"]
|
authors = ["Fluence Labs"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
@ -24,6 +24,7 @@ mod fold_scalar;
|
|||||||
mod fold_stream;
|
mod fold_stream;
|
||||||
mod match_;
|
mod match_;
|
||||||
mod mismatch;
|
mod mismatch;
|
||||||
|
mod never;
|
||||||
mod new;
|
mod new;
|
||||||
mod next;
|
mod next;
|
||||||
mod null;
|
mod null;
|
||||||
@ -80,6 +81,7 @@ impl<'i> ExecutableInstruction<'i> for Instruction<'i> {
|
|||||||
Instruction::Fail(fail) => execute!(self, fail, exec_ctx, trace_ctx),
|
Instruction::Fail(fail) => execute!(self, fail, exec_ctx, trace_ctx),
|
||||||
Instruction::FoldScalar(fold) => execute!(self, fold, exec_ctx, trace_ctx),
|
Instruction::FoldScalar(fold) => execute!(self, fold, exec_ctx, trace_ctx),
|
||||||
Instruction::FoldStream(fold) => execute!(self, fold, exec_ctx, trace_ctx),
|
Instruction::FoldStream(fold) => execute!(self, fold, exec_ctx, trace_ctx),
|
||||||
|
Instruction::Never(never) => execute!(self, never, exec_ctx, trace_ctx),
|
||||||
Instruction::New(new) => execute!(self, new, exec_ctx, trace_ctx),
|
Instruction::New(new) => execute!(self, new, exec_ctx, trace_ctx),
|
||||||
Instruction::Next(next) => execute!(self, next, exec_ctx, trace_ctx),
|
Instruction::Next(next) => execute!(self, next, exec_ctx, trace_ctx),
|
||||||
Instruction::Null(null) => execute!(self, null, exec_ctx, trace_ctx),
|
Instruction::Null(null) => execute!(self, null, exec_ctx, trace_ctx),
|
||||||
|
31
air/src/execution_step/air/never.rs
Normal file
31
air/src/execution_step/air/never.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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 super::ExecutionCtx;
|
||||||
|
use super::ExecutionResult;
|
||||||
|
use super::TraceHandler;
|
||||||
|
use crate::log_instruction;
|
||||||
|
|
||||||
|
use air_parser::ast::Never;
|
||||||
|
|
||||||
|
impl<'i> super::ExecutableInstruction<'i> for Never {
|
||||||
|
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
|
||||||
|
log_instruction!(null, exec_ctx, trace_ctx);
|
||||||
|
exec_ctx.subgraph_complete = false;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ mod fail;
|
|||||||
mod fold;
|
mod fold;
|
||||||
mod match_;
|
mod match_;
|
||||||
mod mismatch;
|
mod mismatch;
|
||||||
|
mod never;
|
||||||
mod new;
|
mod new;
|
||||||
mod par;
|
mod par;
|
||||||
mod seq;
|
mod seq;
|
||||||
|
34
air/tests/test_module/instructions/never.rs
Normal file
34
air/tests/test_module/instructions/never.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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 air_test_utils::prelude::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn never_not_complete_subgraph() {
|
||||||
|
let vm_peer_id = "test_peer_id";
|
||||||
|
let mut vm = create_avm(unit_call_service(), vm_peer_id);
|
||||||
|
|
||||||
|
let script = f!(r#"
|
||||||
|
(seq
|
||||||
|
(never)
|
||||||
|
(call "{vm_peer_id}" ("" "") [])
|
||||||
|
)
|
||||||
|
"#);
|
||||||
|
|
||||||
|
let result = checked_call_vm!(vm, <_>::default(), script, "", "");
|
||||||
|
let actual_trace = trace_from_result(&result);
|
||||||
|
assert!(actual_trace.is_empty());
|
||||||
|
}
|
@ -37,6 +37,7 @@ pub enum Instruction<'i> {
|
|||||||
Fail(Fail<'i>),
|
Fail(Fail<'i>),
|
||||||
FoldScalar(FoldScalar<'i>),
|
FoldScalar(FoldScalar<'i>),
|
||||||
FoldStream(FoldStream<'i>),
|
FoldStream(FoldStream<'i>),
|
||||||
|
Never(Never),
|
||||||
New(New<'i>),
|
New(New<'i>),
|
||||||
Next(Next<'i>),
|
Next(Next<'i>),
|
||||||
Null(Null),
|
Null(Null),
|
||||||
@ -137,6 +138,10 @@ pub struct Next<'i> {
|
|||||||
pub iterator: Scalar<'i>,
|
pub iterator: Scalar<'i>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// (never)
|
||||||
|
#[derive(Serialize, Debug, PartialEq, Eq)]
|
||||||
|
pub struct Never;
|
||||||
|
|
||||||
/// (new variable instruction)
|
/// (new variable instruction)
|
||||||
#[derive(Serialize, Debug, PartialEq)]
|
#[derive(Serialize, Debug, PartialEq)]
|
||||||
pub struct New<'i> {
|
pub struct New<'i> {
|
||||||
|
@ -34,6 +34,7 @@ impl fmt::Display for Instruction<'_> {
|
|||||||
Fail(fail) => write!(f, "{}", fail),
|
Fail(fail) => write!(f, "{}", fail),
|
||||||
FoldScalar(fold) => write!(f, "{}", fold),
|
FoldScalar(fold) => write!(f, "{}", fold),
|
||||||
FoldStream(fold) => write!(f, "{}", fold),
|
FoldStream(fold) => write!(f, "{}", fold),
|
||||||
|
Never(never) => write!(f, "{}", never),
|
||||||
Next(next) => write!(f, "{}", next),
|
Next(next) => write!(f, "{}", next),
|
||||||
New(new) => write!(f, "{}", new),
|
New(new) => write!(f, "{}", new),
|
||||||
Null(null) => write!(f, "{}", null),
|
Null(null) => write!(f, "{}", null),
|
||||||
@ -131,6 +132,12 @@ impl fmt::Display for MisMatch<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Never {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "never")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Next<'_> {
|
impl fmt::Display for Next<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "next {}", self.iterator)
|
write!(f, "next {}", self.iterator)
|
||||||
|
@ -46,6 +46,7 @@ Instr: Box<Instruction<'input>> = {
|
|||||||
|
|
||||||
"(" seq <l:Instr> <r:Instr> ")" => Box::new(Instruction::Seq(Seq::new(l, r))),
|
"(" seq <l:Instr> <r:Instr> ")" => Box::new(Instruction::Seq(Seq::new(l, r))),
|
||||||
"(" par <l:Instr> <r:Instr> ")" => Box::new(Instruction::Par(Par::new(l, r))),
|
"(" par <l:Instr> <r:Instr> ")" => Box::new(Instruction::Par(Par::new(l, r))),
|
||||||
|
"(" never ")" => Box::new(Instruction::Never(Never)),
|
||||||
"(" null ")" => Box::new(Instruction::Null(Null)),
|
"(" null ")" => Box::new(Instruction::Null(Null)),
|
||||||
|
|
||||||
<left: @L> "(" new <argument: NewArgument> <instruction:Instr> ")" <right: @R> => {
|
<left: @L> "(" new <argument: NewArgument> <instruction:Instr> ")" <right: @R> => {
|
||||||
@ -264,6 +265,7 @@ extern {
|
|||||||
fail => Token::Fail,
|
fail => Token::Fail,
|
||||||
fold => Token::Fold,
|
fold => Token::Fold,
|
||||||
xor => Token::Xor,
|
xor => Token::Xor,
|
||||||
|
never => Token::Never,
|
||||||
new => Token::New,
|
new => Token::New,
|
||||||
next => Token::Next,
|
next => Token::Next,
|
||||||
null => Token::Null,
|
null => Token::Null,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -183,6 +183,7 @@ fn string_to_token(input: &str, start_pos: usize) -> LexerResult<Token> {
|
|||||||
FAIL_INSTR => Ok(Token::Fail),
|
FAIL_INSTR => Ok(Token::Fail),
|
||||||
FOLD_INSTR => Ok(Token::Fold),
|
FOLD_INSTR => Ok(Token::Fold),
|
||||||
XOR_INSTR => Ok(Token::Xor),
|
XOR_INSTR => Ok(Token::Xor),
|
||||||
|
NEVER_INSTR => Ok(Token::Never),
|
||||||
NEW_INSTR => Ok(Token::New),
|
NEW_INSTR => Ok(Token::New),
|
||||||
NEXT_INSTR => Ok(Token::Next),
|
NEXT_INSTR => Ok(Token::Next),
|
||||||
NULL_INSTR => Ok(Token::Null),
|
NULL_INSTR => Ok(Token::Null),
|
||||||
@ -233,6 +234,7 @@ const PAR_INSTR: &str = "par";
|
|||||||
const FAIL_INSTR: &str = "fail";
|
const FAIL_INSTR: &str = "fail";
|
||||||
const FOLD_INSTR: &str = "fold";
|
const FOLD_INSTR: &str = "fold";
|
||||||
const XOR_INSTR: &str = "xor";
|
const XOR_INSTR: &str = "xor";
|
||||||
|
const NEVER_INSTR: &str = "never";
|
||||||
const NEW_INSTR: &str = "new";
|
const NEW_INSTR: &str = "new";
|
||||||
const NEXT_INSTR: &str = "next";
|
const NEXT_INSTR: &str = "next";
|
||||||
const NULL_INSTR: &str = "null";
|
const NULL_INSTR: &str = "null";
|
||||||
|
@ -74,6 +74,7 @@ pub enum Token<'input> {
|
|||||||
Fail,
|
Fail,
|
||||||
Fold,
|
Fold,
|
||||||
Xor,
|
Xor,
|
||||||
|
Never,
|
||||||
New,
|
New,
|
||||||
Next,
|
Next,
|
||||||
Null,
|
Null,
|
||||||
|
@ -65,6 +65,10 @@ pub(super) fn new<'i>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn never() -> Instruction<'static> {
|
||||||
|
Instruction::Never(Never)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn null() -> Instruction<'static> {
|
pub(super) fn null() -> Instruction<'static> {
|
||||||
Instruction::Null(Null)
|
Instruction::Null(Null)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ mod dsl;
|
|||||||
mod fail;
|
mod fail;
|
||||||
mod fold;
|
mod fold;
|
||||||
mod match_;
|
mod match_;
|
||||||
|
mod never;
|
||||||
mod new;
|
mod new;
|
||||||
mod null;
|
mod null;
|
||||||
mod par;
|
mod par;
|
||||||
|
32
crates/air-lib/air-parser/src/parser/tests/never.rs
Normal file
32
crates/air-lib/air-parser/src/parser/tests/never.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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 super::dsl::*;
|
||||||
|
use super::parse;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_null() {
|
||||||
|
let source_code = r#"
|
||||||
|
(seq
|
||||||
|
(never)
|
||||||
|
|
||||||
|
( never )
|
||||||
|
)
|
||||||
|
"#;
|
||||||
|
let instruction = parse(source_code);
|
||||||
|
let expected = seq(never(), never());
|
||||||
|
assert_eq!(instruction, expected)
|
||||||
|
}
|
@ -138,6 +138,7 @@ impl<W: io::Write> Beautifier<W> {
|
|||||||
ast::Instruction::FoldStream(fold_stream) => {
|
ast::Instruction::FoldStream(fold_stream) => {
|
||||||
self.beautify_fold_stream(fold_stream, indent)
|
self.beautify_fold_stream(fold_stream, indent)
|
||||||
}
|
}
|
||||||
|
ast::Instruction::Never(never) => self.beautify_simple(never, indent),
|
||||||
ast::Instruction::New(new) => self.beautify_new(new, indent),
|
ast::Instruction::New(new) => self.beautify_new(new, indent),
|
||||||
ast::Instruction::Next(next) => self.beautify_simple(next, indent),
|
ast::Instruction::Next(next) => self.beautify_simple(next, indent),
|
||||||
ast::Instruction::Null(null) => self.beautify_simple(null, indent),
|
ast::Instruction::Null(null) => self.beautify_simple(null, indent),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user