Changeset - 7e5f19869dd2
src/protocol/ast.rs
Show inline comments
 
@@ -1095,14 +1095,13 @@ impl ProcedureSource {
 
            _ => true,
 
        }
 
    }
 
}
 

	
 

	
 
/// Generic storage for functions, primitive components and composite
 
/// components.
 
/// Generic storage for functions and components.
 
// Note that we will have function definitions for builtin functions as well. In
 
// that case the span, the identifier span and the body are all invalid.
 
#[derive(Debug)]
 
pub struct ProcedureDefinition {
 
    pub this: ProcedureDefinitionId,
 
    pub defined_in: RootId,
src/protocol/parser/pass_definitions.rs
Show inline comments
 
@@ -289,13 +289,13 @@ impl PassDefinitions {
 
        function.parameters = parameters;
 
        function.scope = scope_id;
 
        function.body = body_id;
 

	
 
        Ok(())
 
    }
 
    
 

	
 
    fn visit_component_definition(
 
        &mut self, module: &Module, iter: &mut TokenIter, ctx: &mut PassCtx
 
    ) -> Result<(), ParseError> {
 
        // Consume component variant and name
 
        let (_component_text, _) = consume_any_ident(&module.source, iter)?;
 
        debug_assert!(_component_text == KW_COMPONENT);
 
@@ -1660,14 +1660,20 @@ impl PassDefinitions {
 
                            },
 
                            Definition::Procedure(proc_def) => {
 
                                // Check whether it is a builtin function
 
                                // TODO: Once we start generating bytecode this is unnecessary
 
                                let procedure_id = proc_def.this;
 
                                let method = match proc_def.source {
 
                                    ProcedureSource::FuncUserDefined => Method::UserFunction,
 
                                    ProcedureSource::CompUserDefined => Method::UserComponent,
 
                                    // Bit of a hack, at this point the source is not yet known, except if it is a
 
                                    // builtin. So we check for the "kind"
 
                                    ProcedureSource::FuncUserDefined | ProcedureSource::CompUserDefined => {
 
                                        match proc_def.kind {
 
                                            ProcedureKind::Function => Method::UserFunction,
 
                                            ProcedureKind::Component => Method::UserComponent,
 
                                        }
 
                                    },
 
                                    ProcedureSource::FuncGet => Method::Get,
 
                                    ProcedureSource::FuncPut => Method::Put,
 
                                    ProcedureSource::FuncFires => Method::Fires,
 
                                    ProcedureSource::FuncCreate => Method::Create,
 
                                    ProcedureSource::FuncLength => Method::Length,
 
                                    ProcedureSource::FuncAssert => Method::Assert,
src/protocol/tests/parser_validation.rs
Show inline comments
 
@@ -593,13 +593,13 @@ fn test_variable_introduction_in_scope() {
 
#[test]
 
fn test_correct_select_statement() {
 

	
 
    Tester::new_single_source_expect_ok(
 
        "guard variable decl",
 
        "
 
        primitive f() {
 
        comp f() {
 
            channel<u32> unused -> input;
 

	
 
            u32 outer_value = 0;
 
            sync select {
 
                auto in_same_guard = get(input) -> {} // decl A1
 
                auto in_same_gaurd = get(input) -> {} // decl A2
 
@@ -609,18 +609,18 @@ fn test_correct_select_statement() {
 
        }
 
        "
 
    );
 

	
 
    Tester::new_single_source_expect_ok(
 
        "empty select",
 
        "primitive f() { sync select {} }"
 
        "comp f() { sync select {} }"
 
    );
 

	
 
    Tester::new_single_source_expect_ok(
 
        "mixed uses", "
 
        primitive f() {
 
        comp f() {
 
            channel unused_output -> input;
 
            u32 outer_value = 0;
 
            sync select {
 
                outer_value = get(input) -> outer_value = 0;
 
                auto new_value = get(input) -> {
 
                    outer_value = new_value;
 
@@ -641,35 +641,35 @@ fn test_correct_select_statement() {
 
}
 

	
 
#[test]
 
fn test_incorrect_select_statement() {
 
    Tester::new_single_source_expect_err(
 
        "outside sync",
 
        "primitive f() { select {} }"
 
        "comp f() { select {} }"
 
    ).error(|e| { e
 
        .assert_num(1)
 
        .assert_occurs_at(0, "select")
 
        .assert_msg_has(0, "inside sync blocks");
 
    });
 

	
 
    Tester::new_single_source_expect_err(
 
        "variable in previous block",
 
        "primitive f() {
 
        "comp f() {
 
            channel<u32> tx -> rx;
 
            u32 a = 0; // this one will be shadowed
 
            sync select { auto a = get(rx) -> {} }
 
        }"
 
    ).error(|e| { e
 
        .assert_num(2)
 
        .assert_occurs_at(0, "a = get").assert_msg_has(0, "variable name conflicts")
 
        .assert_occurs_at(1, "a = 0").assert_msg_has(1, "Previous variable");
 
    });
 

	
 
    Tester::new_single_source_expect_err(
 
        "put inside arm",
 
        "primitive f() {
 
        "comp f() {
 
            channel<u32> a -> b;
 
            sync select { put(a) -> {} }
 
        }"
 
    ).error(|e| { e
 
        .assert_occurs_at(0, "put")
 
        .assert_msg_has(0, "may not occur");
 
@@ -722,38 +722,38 @@ fn test_incorrect_goto_statement() {
 
        .assert_occurs_at(0, "nested;")
 
        .assert_msg_has(0, "could not find this label");
 
    });
 

	
 
    Tester::new_single_source_expect_err(
 
        "goto jumping outside sync",
 
        "primitive f() {
 
        "comp f() {
 
            sync { goto exit; }
 
            exit: u32 v = 0;
 
        }"
 
    ).error(|e| { e
 
        .assert_num(3)
 
        .assert_occurs_at(0, "goto exit;").assert_msg_has(0, "not escape the surrounding sync")
 
        .assert_occurs_at(1, "exit: u32 v").assert_msg_has(1, "target of the goto")
 
        .assert_occurs_at(2, "sync {").assert_msg_has(2, "jump past this");
 
    });
 

	
 
    Tester::new_single_source_expect_err(
 
        "goto jumping to select case",
 
        "primitive f(in<u32> i) {
 
        "comp f(in<u32> i) {
 
            sync select {
 
                hello: auto a = get(i) -> i += 1
 
            }
 
            goto hello;
 
        }"
 
    ).error(|e| { e
 
        .assert_msg_has(0, "expected '->'");
 
    });
 

	
 
    Tester::new_single_source_expect_err(
 
        "goto jumping into select case skipping variable",
 
        "primitive f(in<u32> i) {
 
        "comp f(in<u32> i) {
 
            goto waza;
 
            sync select {
 
                auto a = get(i) -> {
 
                    waza: a += 1;
 
                }
 
            }
 
@@ -794,13 +794,13 @@ fn test_incorrect_while_statement() {
 
        .assert_occurs_at(0, "target; }").assert_msg_has(0, "not nested under the target")
 
        .assert_occurs_at(1, "target: while").assert_msg_has(1, "is found here");
 
    });
 

	
 
    Tester::new_single_source_expect_err(
 
        "break outside of sync",
 
        "primitive f() {
 
        "comp f() {
 
            outer: while (true) { //mark
 
                sync while(true) { break outer; }
 
            }
 
        }"
 
    ).error(|e| { e
 
        .assert_num(3)
src/runtime/tests/api_component.rs
Show inline comments
 
@@ -5,13 +5,13 @@
 

	
 
use super::*;
 

	
 
#[test]
 
fn test_put_and_get() {
 
    const CODE: &'static str = "
 
    primitive handler(in<u32> request, out<u32> response, u32 loops) {
 
    comp handler(in<u32> request, out<u32> response, u32 loops) {
 
        u32 index = 0;
 
        while (index < loops) {
 
            sync {
 
                auto value = get(request);
 
                put(response, value * 2);
 
            }
 
@@ -49,13 +49,13 @@ fn test_put_and_get() {
 
    }
 
}
 

	
 
#[test]
 
fn test_getting_from_component() {
 
    const CODE: &'static str ="
 
    primitive loop_sender(out<u32> numbers, u32 cur, u32 last) {
 
    comp loop_sender(out<u32> numbers, u32 cur, u32 last) {
 
        while (cur < last) {
 
            sync {
 
                put(numbers, cur);
 
                cur += 1;
 
            }
 
        }
 
@@ -88,13 +88,13 @@ fn test_getting_from_component() {
 
    }
 
}
 

	
 
#[test]
 
fn test_putting_to_component() {
 
    const CODE: &'static str = "
 
    primitive loop_receiver(in<u32> numbers, u32 cur, u32 last) {
 
    comp loop_receiver(in<u32> numbers, u32 cur, u32 last) {
 
        while (cur < last) {
 
            sync {
 
                auto number = get(numbers);
 
                assert(number == cur);
 
                cur += 1;
 
            }
 
@@ -123,13 +123,13 @@ fn test_putting_to_component() {
 
    }
 
}
 

	
 
#[test]
 
fn test_doing_nothing() {
 
    const CODE: &'static str = "
 
    primitive getter(in<bool> input, u32 num_loops) {
 
    comp getter(in<bool> input, u32 num_loops) {
 
        u32 index = 0;
 
        while (index < num_loops) {
 
            sync {}
 
            sync { auto res = get(input); assert(res); }
 
            index += 1;
 
        }
src/runtime/tests/data_transmission.rs
Show inline comments
 
@@ -6,13 +6,13 @@ use super::*;
 

	
 
#[test]
 
fn test_doing_nothing() {
 
    // If this thing does not get into an infinite loop, (hence: the runtime
 
    // exits), then the test works
 
    const CODE: &'static str ="
 
    primitive silent_willy(u32 loops) {
 
    comp silent_willy(u32 loops) {
 
        u32 index = 0;
 
        while (index < loops) {
 
            sync { index += 1; }
 
        }
 
    }
 
    ";
 
@@ -25,23 +25,23 @@ fn test_doing_nothing() {
 
    });
 
}
 

	
 
#[test]
 
fn test_single_put_and_get() {
 
    const CODE: &'static str = "
 
    primitive putter(out<bool> sender, u32 loops) {
 
    comp putter(out<bool> sender, u32 loops) {
 
        u32 index = 0;
 
        while (index < loops) {
 
            sync {
 
                put(sender, true);
 
            }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive getter(in<bool> receiver, u32 loops) {
 
    comp getter(in<bool> receiver, u32 loops) {
 
        u32 index = 0;
 
        while (index < loops) {
 
            sync {
 
                auto result = get(receiver);
 
                assert(result);
 
            }
 
@@ -66,25 +66,25 @@ fn test_single_put_and_get() {
 
    });
 
}
 

	
 
#[test]
 
fn test_combined_put_and_get() {
 
    const CODE: &'static str = "
 
    primitive put_then_get(out<bool> output, in<bool> input, u32 num_loops) {
 
    comp put_then_get(out<bool> output, in<bool> input, u32 num_loops) {
 
        u32 index = 0;
 
        while (index < num_loops) {
 
            sync {
 
                put(output, true);
 
                auto value = get(input);
 
                assert(value);
 
                index += 1;
 
            }
 
        }
 
    }
 

	
 
    composite constructor(u32 num_loops) {
 
    comp constructor(u32 num_loops) {
 
        channel output_a -> input_a;
 
        channel output_b -> input_b;
 
        new put_then_get(output_a, input_b, num_loops);
 
        new put_then_get(output_b, input_a, num_loops);
 
    }
 
    ";
 
@@ -96,26 +96,26 @@ fn test_combined_put_and_get() {
 
    })
 
}
 

	
 
#[test]
 
fn test_multi_put_and_get() {
 
    const CODE: &'static str = "
 
    primitive putter_static(out<u8> vals, u32 num_loops) {
 
    comp putter_static(out<u8> vals, u32 num_loops) {
 
        u32 index = 0;
 
        while (index < num_loops) {
 
            sync {
 
                put(vals, 0b00000001);
 
                put(vals, 0b00000100);
 
                put(vals, 0b00010000);
 
                put(vals, 0b01000000);
 
            }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive getter_dynamic(in<u8> vals, u32 num_loops) {
 
    comp getter_dynamic(in<u8> vals, u32 num_loops) {
 
        u32 loop_index = 0;
 
        while (loop_index < num_loops) {
 
            sync {
 
                u32 recv_index = 0;
 
                u8 expected = 1;
 
                while (recv_index < 4) {
src/runtime/tests/network_shapes.rs
Show inline comments
 
@@ -2,24 +2,24 @@
 

	
 
use super::*;
 

	
 
#[test]
 
fn test_star_shaped_request() {
 
    const CODE: &'static str = "
 
    primitive edge(in<u32> input, out<u32> output, u32 loops) {
 
    comp edge(in<u32> input, out<u32> output, u32 loops) {
 
        u32 index = 0;
 
        while (index < loops) {
 
            sync {
 
                auto req = get(input);
 
                put(output, req * 2);
 
            }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive center(out<u32>[] requests, in<u32>[] responses, u32 loops) {
 
    comp center(out<u32>[] requests, in<u32>[] responses, u32 loops) {
 
        u32 loop_index = 0;
 
        auto num_edges = length(requests);
 

	
 
        while (loop_index < loops) {
 
            // print(\"starting loop\");
 
            sync {
 
@@ -36,13 +36,13 @@ fn test_star_shaped_request() {
 
            }
 
            // print(\"ending loop\");
 
            loop_index += 1;
 
        }
 
    }
 

	
 
    composite constructor(u32 num_edges, u32 num_loops) {
 
    comp constructor(u32 num_edges, u32 num_loops) {
 
        auto requests = {};
 
        auto responses = {};
 

	
 
        u32 edge_index = 0;
 
        while (edge_index < num_edges) {
 
            channel req_put -> req_get;
 
@@ -67,26 +67,26 @@ fn test_star_shaped_request() {
 
    });
 
}
 

	
 
#[test]
 
fn test_conga_line_request() {
 
    const CODE: &'static str = "
 
    primitive start(out<u32> req, in<u32> resp, u32 num_nodes, u32 num_loops) {
 
    comp start(out<u32> req, in<u32> resp, u32 num_nodes, u32 num_loops) {
 
        u32 loop_index = 0;
 
        u32 initial_value = 1337;
 
        while (loop_index < num_loops) {
 
            sync {
 
                put(req, initial_value);
 
                auto result = get(resp);
 
                assert(result == initial_value + num_nodes * 2);
 
            }
 
            loop_index += 1;
 
        }
 
    }
 

	
 
    primitive middle(
 
    comp middle(
 
        in<u32> req_in, out<u32> req_forward,
 
        in<u32> resp_in, out<u32> resp_forward,
 
        u32 num_loops
 
    ) {
 
        u32 loop_index = 0;
 
        while (loop_index < num_loops) {
 
@@ -97,24 +97,24 @@ fn test_conga_line_request() {
 
                put(resp_forward, resp + 1);
 
            }
 
            loop_index += 1;
 
        }
 
    }
 

	
 
    primitive end(in<u32> req_in, out<u32> resp_out, u32 num_loops) {
 
    comp end(in<u32> req_in, out<u32> resp_out, u32 num_loops) {
 
        u32 loop_index = 0;
 
        while (loop_index < num_loops) {
 
            sync {
 
                auto req = get(req_in);
 
                put(resp_out, req);
 
            }
 
            loop_index += 1;
 
        }
 
    }
 

	
 
    composite constructor(u32 num_nodes, u32 num_loops) {
 
    comp constructor(u32 num_nodes, u32 num_loops) {
 
        channel initial_req -> req_in;
 
        channel resp_out -> final_resp;
 
        new start(initial_req, final_resp, num_nodes, num_loops);
 

	
 
        in<u32> last_req_in = req_in;
 
        out<u32> last_resp_out = resp_out;
src/runtime/tests/speculation.rs
Show inline comments
 
@@ -5,39 +5,39 @@ use super::*;
 
#[test]
 
fn test_maybe_do_nothing() {
 
    // Three variants in which the behaviour in which nothing is performed is
 
    // somehow not allowed. Note that we "check" by seeing if the test finishes.
 
    // Only the branches in which ports fire increment the loop index
 
    const CODE: &'static str = "
 
    primitive only_puts(out<bool> output, u32 num_loops) {
 
    comp only_puts(out<bool> output, u32 num_loops) {
 
        u32 index = 0;
 
        while (index < num_loops) {
 
            sync { put(output, true); }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive might_put(out<bool> output, u32 num_loops) {
 
    comp might_put(out<bool> output, u32 num_loops) {
 
        u32 index = 0;
 
        while (index < num_loops) {
 
            sync {
 
                fork { put(output, true); index += 1; }
 
                or   {}
 
            }
 
        }
 
    }
 

	
 
    primitive only_gets(in<bool> input, u32 num_loops) {
 
    comp only_gets(in<bool> input, u32 num_loops) {
 
        u32 index = 0;
 
        while (index < num_loops) {
 
            sync { auto res = get(input); assert(res); }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive might_get(in<bool> input, u32 num_loops) {
 
    comp might_get(in<bool> input, u32 num_loops) {
 
        u32 index = 0;
 
        while (index < num_loops) {
 
            sync fork { auto res = get(input); assert(res); index += 1; } or {}
 
        }
 
    }
 
    ";
src/runtime/tests/sync_failure.rs
Show inline comments
 
@@ -6,20 +6,20 @@ use super::*;
 

	
 
#[test]
 
fn test_local_sync_failure() {
 
    // If the component exits cleanly, then the runtime exits cleanly, and the
 
    // test will finish
 
    const CODE: &'static str = "
 
    primitive immediate_failure_inside_sync() {
 
    comp immediate_failure_inside_sync() {
 
        u32[] only_allows_index_0 = { 1 };
 
        while (true) sync { // note the infinite loop
 
            auto value = only_allows_index_0[1];
 
        }
 
    }
 

	
 
    primitive immediate_failure_outside_sync() {
 
    comp immediate_failure_outside_sync() {
 
        u32[] only_allows_index_0 = { 1 };
 
        auto never_gonna_get = only_allows_index_0[1];
 
        while (true) sync {}
 
    }
 
    ";
 

	
 
@@ -32,13 +32,13 @@ fn test_local_sync_failure() {
 
            .expect("create component");
 
    })
 
}
 

	
 
const SHARED_SYNC_CODE: &'static str = "
 
enum Location { BeforeSync, AfterPut, AfterGet, AfterSync, Never }
 
primitive failing_at_location(in<bool> input, out<bool> output, Location loc) {
 
comp failing_at_location(in<bool> input, out<bool> output, Location loc) {
 
    u32[] failure_array = {};
 
    while (true) {
 
        if (loc == Location::BeforeSync) failure_array[0];
 
        sync {
 
            put(output, true);
 
            if (loc == Location::AfterPut) failure_array[0];
 
@@ -47,27 +47,27 @@ primitive failing_at_location(in<bool> input, out<bool> output, Location loc) {
 
            if (loc == Location::AfterGet) failure_array[0];
 
        }
 
        if (loc == Location::AfterSync) failure_array[0];
 
    }
 
}
 

	
 
composite constructor_pair_a(Location loc) {
 
comp constructor_pair_a(Location loc) {
 
    channel output_a -> input_a;
 
    channel output_b -> input_b;
 
    new failing_at_location(input_b, output_a, loc);
 
    new failing_at_location(input_a, output_b, Location::Never);
 
}
 

	
 
composite constructor_pair_b(Location loc) {
 
comp constructor_pair_b(Location loc) {
 
    channel output_a -> input_a;
 
    channel output_b -> input_b;
 
    new failing_at_location(input_b, output_a, Location::Never);
 
    new failing_at_location(input_a, output_b, loc);
 
}
 

	
 
composite constructor_ring(u32 ring_size, u32 fail_a, Location loc_a, u32 fail_b, Location loc_b) {
 
comp constructor_ring(u32 ring_size, u32 fail_a, Location loc_a, u32 fail_b, Location loc_b) {
 
    channel output_first -> input_old;
 
    channel output_cur -> input_new;
 

	
 
    u32 ring_index = 0;
 
    while (ring_index < ring_size) {
 
        auto cur_loc = Location::Never;
src/runtime2/component/component.rs
Show inline comments
 
@@ -732,13 +732,12 @@ pub(crate) fn default_handle_start_exit(
 
        default_handle_sync_decision(sched_ctx, exec_state, comp_ctx, decision, consensus);
 
    }
 

	
 
    // Iterating over ports by index to work around borrowing rules
 
    for port_index in 0..comp_ctx.num_ports() {
 
        let port = comp_ctx.get_port_by_index_mut(port_index);
 
        println!("DEBUG: Considering port:\n{:?}", port);
 
        if port.state.is_closed() || port.state.is_set(PortStateFlag::Transmitted) || port.close_at_sync_end {
 
            // Already closed, or in the process of being closed
 
            continue;
 
        }
 

	
 
        // Mark as closed
src/runtime2/tests/error_handling.rs
Show inline comments
 
use super::*;
 

	
 
#[test]
 
fn test_unconnected_component_error() {
 
    compile_and_create_component("
 
    primitive interact_with_noone() {
 
    comp interact_with_noone() {
 
        u8[] array = { 5 };
 
        auto value = array[1];
 
    }", "interact_with_noone", no_args());
 
}
 

	
 
#[test]
 
fn test_connected_uncommunicating_component_error() {
 
    compile_and_create_component("
 
    primitive crashing_and_burning(out<u32> unused) {
 
    comp crashing_and_burning(out<u32> unused) {
 
        u8[] array = { 1337 };
 
        auto value = array[1337];
 
    }
 
    primitive sitting_idly_waiting(in<u32> never_providing) {
 
    comp sitting_idly_waiting(in<u32> never_providing) {
 
        sync auto a = get(never_providing);
 
    }
 
    composite constructor() {
 
    comp constructor() {
 
        // Test one way
 
        // channel a -> b;
 
        // new sitting_idly_waiting(b);
 
        // new crashing_and_burning(a);
 

	
 
        // And the other way around
 
@@ -32,23 +32,23 @@ fn test_connected_uncommunicating_component_error() {
 
    }", "constructor", no_args())
 
}
 

	
 
#[test]
 
fn test_connected_communicating_component_error() {
 
    compile_and_create_component("
 
    primitive send_and_fail(out<u32> tx) {
 
    comp send_and_fail(out<u32> tx) {
 
        u8[] array = {};
 
        sync {
 
            put(tx, 0);
 
            array[0] = 5;
 
        }
 
    }
 
    primitive receive_once(in<u32> rx) {
 
    comp receive_once(in<u32> rx) {
 
        sync auto a = get(rx);
 
    }
 
    composite constructor() {
 
    comp constructor() {
 
        channel a -> b;
 
        new send_and_fail(a);
 
        new receive_once(b);
 

	
 
        channel c -> d;
 
        new receive_once(d);
 
@@ -57,18 +57,18 @@ fn test_connected_communicating_component_error() {
 
    ", "constructor", no_args())
 
}
 

	
 
#[test]
 
fn test_failing_after_successful_sync() {
 
    compile_and_create_component("
 
    primitive put_and_fail(out<u8> tx) { sync put(tx, 1); u8 a = {}[0]; }
 
    primitive get_and_fail(in<u8> rx) { sync auto a = get(rx); u8 a = {}[0]; }
 
    primitive put_and_exit(out<u8> tx) { sync put(tx, 2); }
 
    primitive get_and_exit(in<u8> rx) { sync auto a = get(rx); }
 
    comp put_and_fail(out<u8> tx) { sync put(tx, 1); u8 a = {}[0]; }
 
    comp get_and_fail(in<u8> rx) { sync auto a = get(rx); u8 a = {}[0]; }
 
    comp put_and_exit(out<u8> tx) { sync put(tx, 2); }
 
    comp get_and_exit(in<u8> rx) { sync auto a = get(rx); }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        {
 
            channel a -> b;
 
            new put_and_fail(a);
 
            new get_and_exit(b);
 
        }
 
        {
src/runtime2/tests/internet.rs
Show inline comments
 
@@ -4,58 +4,58 @@ use super::*;
 
// stuff with the actual components
 
#[test]
 
fn test_stdlib_file() {
 
    compile_and_create_component("
 
    import std.internet as inet;
 

	
 
    primitive fake_listener_once(out<inet::TcpConnection> tx) {
 
    comp fake_listener_once(out<inet::TcpConnection> tx) {
 
        channel cmd_tx -> cmd_rx;
 
        channel data_tx -> data_rx;
 
        new fake_client(cmd_rx, data_tx);
 
        new fake_socket(cmd_rx, data_tx);
 
        sync put(tx, inet::TcpConnection{
 
            tx: cmd_tx,
 
            rx: data_rx,
 
        });
 
    }
 

	
 
    primitive fake_socket(in<inet::Cmd> cmds, out<u8[]> tx) {
 
    comp fake_socket(in<inet::Cmd> cmds, out<u8[]> tx) {
 
        auto to_send = {};
 

	
 
        auto shutdown = false;
 
        while (!shutdown) {
 
            auto keep_going = true;
 
            sync {
 
                while (keep_going) {
 
                    let cmd = get(cmds);
 
                    auto cmd = get(cmds);
 
                    if (let inet::Cmd::Send(data) = cmd) {
 
                        to_send = data;
 
                    } else if (let inet::Cmd::Receive(data) = cmd) {
 
                    } else if (let inet::Cmd::Receive = cmd) {
 
                        put(tx, to_send);
 
                    } else if (let inet::Cmd::Finish = cmd) {
 
                        keep_going = false;
 
                    } else if (let inet::Cmd::Shutdown = cmd) {
 
                        keep_going = false;
 
                        shutdown = true;
 
                    }
 
                }
 
            }
 
        }
 
    }
 

	
 
    primitive fake_client(inet::TcpConnection conn) {
 
    comp fake_client(inet::TcpConnection conn) {
 
        sync put(conn.tx, inet::Cmd::Send({1, 3, 3, 7}));
 
        sync {
 
            put(conn.tx, inet::Cmd::Receive);
 
            auto val = get(conn.rx);
 
            while (val[0] != 1 || val[1] != 3 || val[2] != 3 || val[3] != 7) {}
 
            put(conn.tx, inet::Cmd::Finish);
 
        }
 
        sync put(conn.tx, inet::Cmd::Shutdown);
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel conn_tx -> conn_rx;
 
        new fake_listener_once(conn_tx);
 

	
 
        // Same crap as before:
 
        channel cmd_tx -> unused_cmd_rx;
 
        channel unused_data_tx -> data_rx;
src/runtime2/tests/messaging.rs
Show inline comments
 
use super::*;
 

	
 

	
 
#[test]
 
fn test_component_communication() {
 
    let pd = ProtocolDescription::parse(b"
 
    primitive sender(out<u32> o, u32 outside_loops, u32 inside_loops) {
 
    comp sender(out<u32> o, u32 outside_loops, u32 inside_loops) {
 
        u32 outside_index = 0;
 
        while (outside_index < outside_loops) {
 
            u32 inside_index = 0;
 
            sync while (inside_index < inside_loops) {
 
                put(o, inside_index);
 
                inside_index += 1;
 
            }
 
            outside_index += 1;
 
        }
 
    }
 

	
 
    primitive receiver(in<u32> i, u32 outside_loops, u32 inside_loops) {
 
    comp receiver(in<u32> i, u32 outside_loops, u32 inside_loops) {
 
        u32 outside_index = 0;
 
        while (outside_index < outside_loops) {
 
            u32 inside_index = 0;
 
            sync while (inside_index < inside_loops) {
 
                auto val = get(i);
 
                while (val != inside_index) {} // infinite loop if incorrect value is received
 
                inside_index += 1;
 
            }
 
            outside_index += 1;
 
        }
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel o_orom -> i_orom;
 
        channel o_mrom -> i_mrom;
 
        channel o_ormm -> i_ormm;
 
        channel o_mrmm -> i_mrmm;
 

	
 
        // one round, one message per round
 
@@ -55,13 +55,13 @@ fn test_component_communication() {
 
    create_component(&rt, "", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_send_to_self() {
 
    compile_and_create_component("
 
    primitive insane_in_the_membrane() {
 
    comp insane_in_the_membrane() {
 
        channel a -> b;
 
        sync {
 
            put(a, 1);
 
            auto v = get(b);
 
            while (v != 1) {}
 
        }
 
@@ -69,46 +69,46 @@ fn test_send_to_self() {
 
    ", "insane_in_the_membrane", no_args());
 
}
 

	
 
#[test]
 
fn test_intermediate_messenger() {
 
    let pd = ProtocolDescription::parse(b"
 
    primitive receiver<T>(in<T> rx, u32 num) {
 
    comp receiver<T>(in<T> rx, u32 num) {
 
        auto index = 0;
 
        while (index < num) {
 
            sync { auto v = get(rx); }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive middleman<T>(in<T> rx, out<T> tx, u32 num) {
 
    comp middleman<T>(in<T> rx, out<T> tx, u32 num) {
 
        auto index = 0;
 
        while (index < num) {
 
            sync { put(tx, get(rx)); }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive sender<T>(out<T> tx, u32 num) {
 
    comp sender<T>(out<T> tx, u32 num) {
 
        auto index = 0;
 
        while (index < num) {
 
            sync put(tx, 1337);
 
            index += 1;
 
        }
 
    }
 

	
 
    composite constructor_template<T>() {
 
    comp constructor_template<T>() {
 
        auto num = 0;
 
        channel<T> tx_a -> rx_a;
 
        channel tx_b -> rx_b;
 
        new sender(tx_a, 3);
 
        new middleman(rx_a, tx_b, 3);
 
        new receiver(rx_b, 3);
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        new constructor_template<u16>();
 
        new constructor_template<u32>();
 
        new constructor_template<u64>();
 
        new constructor_template<s16>();
 
        new constructor_template<s32>();
 
        new constructor_template<s64>();
src/runtime2/tests/mod.rs
Show inline comments
 
@@ -32,13 +32,13 @@ pub(crate) fn create_component(rt: &Runtime, module_name: &str, routine_name: &s
 

	
 
pub(crate) fn no_args() -> ValueGroup { ValueGroup::new_stack(Vec::new()) }
 

	
 
#[test]
 
fn test_component_creation() {
 
    let pd = ProtocolDescription::parse(b"
 
    primitive nothing_at_all() {
 
    comp nothing_at_all() {
 
        s32 a = 5;
 
        auto b = 5 + a;
 
    }
 
    ").expect("compilation");
 
    let rt = Runtime::new(1, LOG_LEVEL, pd).unwrap();
 

	
 
@@ -52,13 +52,13 @@ fn test_simple_select() {
 
    let pd = ProtocolDescription::parse(b"
 
    func infinite_assert<T>(T val, T expected) -> () {
 
        while (val != expected) { print(\"nope!\"); }
 
        return ();
 
    }
 

	
 
    primitive receiver(in<u32> in_a, in<u32> in_b, u32 num_sends) {
 
    comp receiver(in<u32> in_a, in<u32> in_b, u32 num_sends) {
 
        auto num_from_a = 0;
 
        auto num_from_b = 0;
 
        while (num_from_a + num_from_b < 2 * num_sends) {
 
            sync select {
 
                auto v = get(in_a) -> {
 
                    print(\"got something from A\");
 
@@ -71,23 +71,23 @@ fn test_simple_select() {
 
                    num_from_b += 1;
 
                }
 
            }
 
        }
 
    }
 

	
 
    primitive sender(out<u32> tx, u32 num_sends) {
 
    comp sender(out<u32> tx, u32 num_sends) {
 
        auto index = 0;
 
        while (index < num_sends) {
 
            sync {
 
                put(tx, index);
 
                index += 1;
 
            }
 
        }
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        auto num_sends = 1;
 
        channel tx_a -> rx_a;
 
        channel tx_b -> rx_b;
 
        new sender(tx_a, num_sends);
 
        new receiver(rx_a, rx_b, num_sends);
 
        new sender(tx_b, num_sends);
 
@@ -97,21 +97,21 @@ fn test_simple_select() {
 
    create_component(&rt, "", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_unguarded_select() {
 
    let pd = ProtocolDescription::parse(b"
 
    primitive constructor_outside_select() {
 
    comp constructor_outside_select() {
 
        u32 index = 0;
 
        while (index < 5) {
 
            sync select { auto v = () -> print(\"hello\"); }
 
            index += 1;
 
        }
 
    }
 

	
 
    primitive constructor_inside_select() {
 
    comp constructor_inside_select() {
 
        u32 index = 0;
 
        while (index < 5) {
 
            sync select { auto v = () -> index += 1; }
 
        }
 
    }
 
    ").expect("compilation");
 
@@ -120,13 +120,13 @@ fn test_unguarded_select() {
 
    create_component(&rt, "", "constructor_inside_select", no_args());
 
}
 

	
 
#[test]
 
fn test_empty_select() {
 
    let pd = ProtocolDescription::parse(b"
 
    primitive constructor() {
 
    comp constructor() {
 
        u32 index = 0;
 
        while (index < 5) {
 
            sync select {}
 
            index += 1;
 
        }
 
    }
 
@@ -137,23 +137,23 @@ fn test_empty_select() {
 

	
 
#[test]
 
fn test_random_u32_temporary_thingo() {
 
    let pd = ProtocolDescription::parse(b"
 
    import std.random::random_u32;
 

	
 
    primitive random_taker(in<u32> generator, u32 num_values) {
 
    comp random_taker(in<u32> generator, u32 num_values) {
 
        auto i = 0;
 
        while (i < num_values) {
 
            sync {
 
                auto a = get(generator);
 
            }
 
            i += 1;
 
        }
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel tx -> rx;
 
        auto num_values = 25;
 
        new random_u32(tx, 1, 100, num_values);
 
        new random_taker(rx, num_values);
 
    }
 
    ").expect("compilation");
 
@@ -163,13 +163,13 @@ fn test_random_u32_temporary_thingo() {
 

	
 
#[test]
 
fn test_tcp_socket_http_request() {
 
    let _pd = ProtocolDescription::parse(b"
 
    import std.internet::*;
 

	
 
    primitive requester(out<Cmd> cmd_tx, in<u8[]> data_rx) {
 
    comp requester(out<Cmd> cmd_tx, in<u8[]> data_rx) {
 
        print(\"*** TCPSocket: Sending request\");
 
        sync {
 
            put(cmd_tx, Cmd::Send(b\"GET / HTTP/1.1\\r\\n\\r\\n\"));
 
        }
 

	
 
        print(\"*** TCPSocket: Receiving response\");
 
@@ -212,13 +212,13 @@ fn test_tcp_socket_http_request() {
 
        print(\"*** TCPSocket: Requesting shutdown\");
 
        sync {
 
            put(cmd_tx, Cmd::Shutdown);
 
        }
 
    }
 

	
 
    composite main() {
 
    comp main() {
 
        channel cmd_tx -> cmd_rx;
 
        channel data_tx -> data_rx;
 
        new tcp_client({142, 250, 179, 163}, 80, cmd_rx, data_tx); // port 80 of google
 
        new requester(cmd_tx, data_rx);
 
    }
 
    ").expect("compilation");
 
@@ -234,13 +234,13 @@ fn test_sending_receiving_union() {
 
    union Cmd {
 
        Set(u8[]),
 
        Get,
 
        Shutdown,
 
    }
 

	
 
    primitive database(in<Cmd> rx, out<u8[]> tx) {
 
    comp database(in<Cmd> rx, out<u8[]> tx) {
 
        auto stored = {};
 
        auto done = false;
 
        while (!done) {
 
            sync {
 
                auto command = get(rx);
 
                if (let Cmd::Set(bytes) = command) {
 
@@ -254,13 +254,13 @@ fn test_sending_receiving_union() {
 
                    done = true;
 
                } else while (true) print(\"impossible\"); // no other case possible
 
            }
 
        }
 
    }
 

	
 
    primitive client(out<Cmd> tx, in<u8[]> rx, u32 num_rounds) {
 
    comp client(out<Cmd> tx, in<u8[]> rx, u32 num_rounds) {
 
        auto round = 0;
 
        while (round < num_rounds) {
 
            auto set_value = b\"hello there\";
 
            print(\"client: putting a value\");
 
            sync put(tx, Cmd::Set(set_value));
 

	
 
@@ -276,13 +276,13 @@ fn test_sending_receiving_union() {
 
            round += 1;
 
        }
 

	
 
        sync put(tx, Cmd::Shutdown);
 
    }
 

	
 
    composite main() {
 
    comp main() {
 
        auto num_rounds = 5;
 
        channel cmd_tx -> cmd_rx;
 
        channel data_tx -> data_rx;
 
        new database(cmd_rx, data_tx);
 
        new client(cmd_tx, data_rx, num_rounds);
 
    }
src/runtime2/tests/transfer_ports.rs
Show inline comments
 
use super::*;
 

	
 
#[test]
 
fn test_transfer_precreated_port_with_owned_peer() {
 
    compile_and_create_component("
 
    primitive port_sender(out<in<u32>> tx) {
 
    comp port_sender(out<in<u32>> tx) {
 
        channel a -> b;
 
        sync put(tx, b);
 
    }
 

	
 
    primitive port_receiver(in<in<u32>> rx) {
 
    comp port_receiver(in<in<u32>> rx) {
 
        sync auto a = get(rx);
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel a -> b;
 
        new port_sender(a);
 
        new port_receiver(b);
 
    }
 
    ", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_transfer_precreated_in_struct_with_owned_peer() {
 
    compile_and_create_component("
 
    struct PortPair<T> {
 
        out<T> tx,
 
        in<T> rx,
 
    }
 

	
 
    comp port_sender(out<PortPair<u32>> tx) {
 
        channel created_tx_a -> created_rx_a;
 
        channel created_tx_b -> created_rx_b;
 
        sync put(tx, PortPair{ tx: created_tx_a, rx: created_rx_b });
 
        sync {
 
            auto val = get(created_rx_a);
 
            put(created_tx_b, val);
 
        }
 
    }
 

	
 
    comp port_receiver(in<PortPair<u32>> rx) {
 
        channel fake_tx -> fake_rx;
 
        auto conn = PortPair{ tx: fake_tx, rx: fake_rx };
 
        sync conn = get(rx);
 
        sync {
 
            put(conn.tx, 5);
 
            auto val = get(conn.rx);
 
            while (val != 5) {}
 
        }
 
    }
 

	
 
    comp constructor() {
 
        channel tx -> rx;
 
        new port_sender(tx);
 
        new port_receiver(rx);
 
    }
 
    ", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_transfer_precreated_port_with_foreign_peer() {
 
    compile_and_create_component("
 
    primitive port_sender(out<in<u32>> tx, in<u32> to_send) {
 
    comp port_sender(out<in<u32>> tx, in<u32> to_send) {
 
        sync put(tx, to_send);
 
    }
 

	
 
    primitive port_receiver(in<in<u32>> rx) {
 
    comp port_receiver(in<in<u32>> rx) {
 
        sync auto a = get(rx);
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel tx -> rx;
 
        channel forgotten -> to_send;
 
        new port_sender(tx, to_send);
 
        new port_receiver(rx);
 
    }
 
    ", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_transfer_synccreated_port() {
 
    compile_and_create_component("
 
    primitive port_sender(out<in<u32>> tx) {
 
    comp port_sender(out<in<u32>> tx) {
 
        sync {
 
            channel a -> b;
 
            put(tx, b);
 
        }
 
    }
 

	
 
    primitive port_receiver(in<in<u32>> rx) {
 
    comp port_receiver(in<in<u32>> rx) {
 
        sync auto a = get(rx);
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel a -> b;
 
        new port_sender(a);
 
        new port_receiver(b);
 
    }
 
    ", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_transfer_precreated_port_with_owned_peer_and_communication() {
 
    compile_and_create_component("
 
    primitive port_sender(out<in<u32>> tx) {
 
    comp port_sender(out<in<u32>> tx) {
 
        channel a -> b;
 
        sync put(tx, b);
 
        sync put(a, 1337);
 
    }
 

	
 
    primitive port_receiver(in<in<u32>> rx) {
 
    comp port_receiver(in<in<u32>> rx) {
 
        channel a -> b; // this is stupid, but we need to have a variable to use
 
        sync b = get(rx);
 
        u32 value = 0;
 
        sync value = get(b);
 
        while (value != 1337) {}
 
    }
 
    composite constructor() {
 
    comp constructor() {
 
        channel a -> b;
 
        new port_sender(a);
 
        new port_receiver(b);
 
    }
 
    ", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_transfer_precreated_port_with_foreign_peer_and_communication() {
 
    compile_and_create_component("
 
    primitive port_sender(out<in<u32>> tx, in<u32> to_send) {
 
    comp port_sender(out<in<u32>> tx, in<u32> to_send) {
 
        sync put(tx, to_send);
 
    }
 

	
 
    primitive message_transmitter(out<u32> tx) {
 
    comp message_transmitter(out<u32> tx) {
 
        sync put(tx, 1337);
 
    }
 

	
 
    primitive port_receiver(in<in<u32>> rx) {
 
    comp port_receiver(in<in<u32>> rx) {
 
        channel unused -> b;
 
        sync b = get(rx);
 
        u32 value = 0;
 
        sync value = get(b);
 
        while (value != 1337) {}
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel port_tx -> port_rx;
 
        channel value_tx -> value_rx;
 
        new port_sender(port_tx, value_rx);
 
        new port_receiver(port_rx);
 
        new message_transmitter(value_tx);
 
    }
 
    ", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_transfer_precreated_port_with_owned_peer_back_and_forth() {
 
    compile_and_create_component("
 
    primitive port_send_and_receive(out<in<u32>> tx, in<in<u32>> rx) {
 
    comp port_send_and_receive(out<in<u32>> tx, in<in<u32>> rx) {
 
        channel a -> b;
 
        sync {
 
            put(tx, b);
 
            b = get(rx);
 
        }
 
    }
 

	
 
    primitive port_receive_and_send(in<in<u32>> rx, out<in<u32>> tx) {
 
    comp port_receive_and_send(in<in<u32>> rx, out<in<u32>> tx) {
 
        channel unused -> transferred; // same problem as in different tests
 
        sync {
 
            transferred = get(rx);
 
            put(tx, transferred);
 
        }
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel port_tx_forward -> port_rx_forward;
 
        channel port_tx_backward -> port_rx_backward;
 

	
 
        new port_send_and_receive(port_tx_forward, port_rx_backward);
 
        new port_receive_and_send(port_rx_forward, port_tx_backward);
 
    }", "constructor", no_args());
 
}
 

	
 
#[test]
 
fn test_transfer_precreated_port_with_foreign_peer_back_and_forth_and_communication() {
 
    compile_and_create_component("
 
    primitive port_send_and_receive(out<in<u32>> tx, in<in<u32>> rx, in<u32> to_transfer) {
 
    comp port_send_and_receive(out<in<u32>> tx, in<in<u32>> rx, in<u32> to_transfer) {
 
        sync {
 
            put(tx, to_transfer);
 
            to_transfer = get(rx);
 
        }
 
        sync {
 
            auto value = get(to_transfer);
 
            while (value != 1337) {}
 
        }
 
    }
 

	
 
    primitive port_receive_and_send(in<in<u32>> rx, out<in<u32>> tx) {
 
    comp port_receive_and_send(in<in<u32>> rx, out<in<u32>> tx) {
 
        channel unused -> transferred;
 
        sync {
 
            transferred = get(rx);
 
            put(tx, transferred);
 
        }
 
    }
 

	
 
    primitive value_sender(out<u32> tx) {
 
    comp value_sender(out<u32> tx) {
 
        sync put(tx, 1337);
 
    }
 

	
 
    composite constructor() {
 
    comp constructor() {
 
        channel port_tx_forward -> port_rx_forward;
 
        channel port_tx_backward -> port_rx_backward;
 
        channel message_tx -> message_rx;
 
        new port_send_and_receive(port_tx_forward, port_rx_backward, message_rx);
 
        new port_receive_and_send(port_rx_forward, port_tx_backward);
 
        new value_sender(message_tx);
std/std.internet.pdl
Show inline comments
 
@@ -4,18 +4,18 @@ union Cmd {
 
    Send(u8[]),
 
    Receive,
 
    Finish,
 
    Shutdown,
 
}
 

	
 
primitive tcp_client(u8[] ip, u16 port, in<Cmd> cmds, out<u8[]> rx) {
 
comp tcp_client(u8[] ip, u16 port, in<Cmd> cmds, out<u8[]> rx) {
 
    #builtin
 
}
 

	
 
struct TcpConnection {
 
    in<Cmd> tx,
 
    out<u8[]> rx,
 
    out<Cmd> tx,
 
    in<u8[]> rx,
 
}
 

	
 
/* primitive tcp_listener(u8[] ip, u16 port, out<TcpConnection> rx) {
 
/* comp tcp_listener(u8[] ip, u16 port, out<TcpConnection> rx) {
 
    #builtin
 
} */
 
\ No newline at end of file
std/std.random.pdl
Show inline comments
 
#module std.random
 

	
 
primitive random_u32(out<u32> generator, u32 min, u32 max, u32 num_sends) { #builtin }
 
comp random_u32(out<u32> generator, u32 min, u32 max, u32 num_sends) { #builtin }
testdata/basic-modules/consumer.pdl
Show inline comments
 
#module consumer
 

	
 
primitive consumer(in<u32> input) {
 
comp consumer(in<u32> input) {
 
    sync {
 
        print("C: going to receive a value");
 
        auto v = get(input);
 
        print("C: I have received a value");
 
    }
 
    print("C: I am now exiting");
testdata/basic-modules/main.pdl
Show inline comments
 
import consumer as c;
 
import producer::producer;
 

	
 
composite main() {
 
comp main() {
 
    channel output -> input;
 
    new c::consumer(input);
 
    new producer(output);
 
}
 
\ No newline at end of file
testdata/basic-modules/producer.pdl
Show inline comments
 
#module producer
 

	
 
primitive producer(out<u32> output) {
 
comp producer(out<u32> output) {
 
    sync {
 
        print("P: Going to send a value!");
 
        put(output, 1337);
 
        print("P: I just sent a value!");
 
    }
 
    print("P: I am exiting");
testdata/basic/testing.pdl
Show inline comments
 
primitive consumer(in<u32> input) {
 
comp consumer(in<u32> input) {
 
    sync {
 
        print("C: going to receive a value");
 
        auto v = get(input);
 
        print("C: I have received a value");
 
    }
 
    print("C: I am now exiting");
 
}
 

	
 
primitive producer(out<u32> output) {
 
comp producer(out<u32> output) {
 
    sync {
 
        print("P: Going to send a value!");
 
        put(output, 1337);
 
        print("P: I just sent a value!");
 
    }
 
    print("P: I am exiting");
 
}
 

	
 
composite main() {
 
comp main() {
 
    channel output -> input;
 
    new consumer(input);
 
    new producer(output);
 
}
 
\ No newline at end of file
0 comments (0 inline, 0 general)