Changeset - 5e11ebce9bc0
[Not reviewed]
0 5 0
Hans-Dieter Hiep - 5 years ago 2020-02-10 11:57:19
hdh@cwi.nl
Evaluator new_component and new_channel implemented
5 files changed with 103 insertions and 23 deletions:
0 comments (0 inline, 0 general)
src/protocol/ast.rs
Show inline comments
 
@@ -1353,7 +1353,7 @@ pub struct SourceIdentifier {
 
}
 

	
 
impl SourceIdentifier {
 
    fn ident(&self) -> &[u8] {
 
    pub fn ident(&self) -> &[u8] {
 
        &self.value
 
    }
 
}
 
@@ -1827,6 +1827,12 @@ impl Declaration {
 
    pub fn is_function(&self) -> bool {
 
        self.signature().is_function()
 
    }
 
    pub fn as_defined(&self) -> &DefinedDeclaration {
 
        match self {
 
            Declaration::Defined(result) => result,
 
            _ => panic!("Unable to cast `Declaration` to `DefinedDeclaration`"),
 
        }
 
    }
 
}
 

	
 
#[derive(Debug, Clone)]
 
@@ -2178,6 +2184,7 @@ impl BlockStatement {
 
        }
 
    }
 
    pub fn first(&self) -> StatementId {
 
        // It is an invariant (guaranteed by the lexer) that block statements have at least one stmt
 
        *self.statements.first().unwrap()
 
    }
 
}
src/protocol/eval.rs
Show inline comments
 
@@ -1375,7 +1375,7 @@ impl Store {
 
        match &h[rexpr] {
 
            Expression::Variable(var) => {
 
                let var = var.declaration.unwrap();
 
                let value = self.map.get(&var).unwrap();
 
                let value = self.map.get(&var).expect(&format!("Uninitialized variable {:?}", h[h[var].identifier()]));
 
                Ok(value.clone())
 
            }
 
            _ => unimplemented!("{:?}", h[rexpr]),
 
@@ -1485,7 +1485,7 @@ pub enum EvalContinuation {
 
    Terminal,
 
    SyncBlockStart,
 
    SyncBlockEnd,
 
    NewComponent(Vec<Value>),
 
    NewComponent(DeclarationId, Vec<Value>),
 
    BlockFires(Value),
 
    BlockGet(Value),
 
    Put(Value, Value),
 
@@ -1533,7 +1533,12 @@ impl Prompt {
 
                            // Update store
 
                            self.store.initialize(h, stmt.variable.upcast(), value);
 
                        }
 
                        LocalStatement::Channel(stmt) => unimplemented!(),
 
                        LocalStatement::Channel(stmt) => {
 
                            let [from, to] = ctx.new_channel();
 
                            // Store the values in the declared variables
 
                            self.store.initialize(h, stmt.from.upcast(), from);
 
                            self.store.initialize(h, stmt.to.upcast(), to);
 
                        },
 
                    }
 
                    // Continue to next statement
 
                    self.position = stmt.next();
 
@@ -1591,6 +1596,28 @@ impl Prompt {
 
                    self.position = stmt.next;
 
                    Err(EvalContinuation::SyncBlockEnd)
 
                }
 
                Statement::Break(stmt) => {
 
                    // Continue to end of while
 
                    self.position = stmt.target.map(EndWhileStatementId::upcast);
 
                    Err(EvalContinuation::Stepping)
 
                }
 
                Statement::Continue(stmt) => {
 
                    // Continue to beginning of while
 
                    self.position = stmt.target.map(WhileStatementId::upcast);
 
                    Err(EvalContinuation::Stepping)
 
                }
 
                Statement::Assert(stmt) => {
 
                    // Evaluate expression
 
                    let value = self.store.eval(h, ctx, stmt.expression)?;
 
                    if value.as_boolean().0 {
 
                        // Continue to next statement
 
                        self.position = stmt.next;
 
                        Err(EvalContinuation::Stepping)
 
                    } else {
 
                        // Assertion failed: inconsistent
 
                        Err(EvalContinuation::Inconsistent)
 
                    }
 
                }
 
                Statement::Return(stmt) => {
 
                    // Evaluate expression
 
                    let value = self.store.eval(h, ctx, stmt.expression)?;
 
@@ -1602,7 +1629,16 @@ impl Prompt {
 
                    self.position = stmt.target.map(|x| x.upcast());
 
                    Err(EvalContinuation::Stepping)
 
                }
 
                Statement::New(stmt) => todo!(),
 
                Statement::New(stmt) => {
 
                    let expr = &h[stmt.expression];
 
                    let mut args = Vec::new();
 
                    for &arg in expr.arguments.iter() {
 
                        let value = self.store.eval(h, ctx, arg)?;
 
                        args.push(value);
 
                    }
 
                    self.position = stmt.next;
 
                    Err(EvalContinuation::NewComponent(expr.declaration.unwrap(), args))
 
                }
 
                Statement::Put(stmt) => {
 
                    // Evaluate port and message
 
                    let port = self.store.eval(h, ctx, stmt.port)?;
 
@@ -1619,7 +1655,6 @@ impl Prompt {
 
                    self.position = stmt.next;
 
                    Err(EvalContinuation::Stepping)
 
                }
 
                _ => unimplemented!("{:?}", stmt),
 
            }
 
        } else {
 
            Err(EvalContinuation::Terminal)
 
@@ -1640,7 +1675,7 @@ impl Prompt {
 
                    // Functions never encounter any blocking behavior
 
                    EvalContinuation::SyncBlockStart => unreachable!(),
 
                    EvalContinuation::SyncBlockEnd => unreachable!(),
 
                    EvalContinuation::NewComponent(args) => unreachable!(),
 
                    EvalContinuation::NewComponent(_, _) => unreachable!(),
 
                    EvalContinuation::BlockFires(val) => unreachable!(),
 
                    EvalContinuation::BlockGet(val) => unreachable!(),
 
                    EvalContinuation::Put(port, msg) => unreachable!(),
 
@@ -1669,8 +1704,7 @@ mod tests {
 
        let mut source = InputSource::from_file(&path).unwrap();
 
        let mut parser = Parser::new(&mut source);
 
        let pd = parser.parse(&mut heap).unwrap();
 
        let test = heap.get_external_identifier(b"test");
 
        let def = heap[pd].get_definition(&heap, test.upcast()).unwrap();
 
        let def = heap[pd].get_definition_ident(&heap, b"test").unwrap();
 
        let fun = heap[def].as_function().this;
 
        let args = Vec::new();
 
        let result = Prompt::compute_function(&heap, fun, &args).unwrap();
src/protocol/mod.rs
Show inline comments
 
@@ -121,8 +121,14 @@ impl ComponentState for ComponentStateImpl {
 
                    EvalContinuation::SyncBlockStart => return MonoBlocker::SyncBlockStart,
 
                    // Not possible to end sync block if never entered one
 
                    EvalContinuation::SyncBlockEnd => unreachable!(),
 
                    EvalContinuation::NewComponent(args) => {
 
                        todo!();
 
                    EvalContinuation::NewComponent(decl, args) => {
 
                        // Look up definition (TODO for now, assume it is a definition)
 
                        let h = &pd.heap;
 
                        let def = h[decl].as_defined().definition;
 
                        println!("Create component: {}",  String::from_utf8_lossy(h[h[def].identifier()].ident()));
 
                        let init_state = ComponentStateImpl { prompt: Prompt::new(h, def, &args) };
 
                        context.new_component(&args, init_state);
 
                        // Continue stepping
 
                        continue;
 
                    }
 
                    // Outside synchronous blocks, no fires/get/put happens
 
@@ -154,7 +160,7 @@ impl ComponentState for ComponentStateImpl {
 
                    EvalContinuation::SyncBlockStart => unreachable!(),
 
                    EvalContinuation::SyncBlockEnd => return PolyBlocker::SyncBlockEnd,
 
                    // Not possible to create component in sync block
 
                    EvalContinuation::NewComponent(args) => unreachable!(),
 
                    EvalContinuation::NewComponent(_, _) => unreachable!(),
 
                    EvalContinuation::BlockFires(port) => match port {
 
                        Value::Output(OutputValue(key)) => {
 
                            return PolyBlocker::CouldntCheckFiring(key);
 
@@ -214,20 +220,42 @@ impl EvalContext<'_> {
 
        match self {
 
            EvalContext::None => unreachable!(),
 
            EvalContext::Mono(context) => todo!(),
 
            EvalContext::Poly(context) => unreachable!(),
 
            EvalContext::Poly(_) => unreachable!(),
 
        }
 
    }
 
    fn channel(&mut self) -> (Value, Value) {
 
    fn new_component(&mut self, args: &[Value], init_state: ComponentStateImpl) -> () {
 
        match self {
 
            EvalContext::None => unreachable!(),
 
            EvalContext::Mono(context) => unreachable!(),
 
            EvalContext::Poly(context) => todo!(),
 
            EvalContext::Mono(context) => {
 
                let mut moved_keys = HashSet::new();
 
                for arg in args.iter() {
 
                    match arg {
 
                        Value::Output(OutputValue(key)) => { moved_keys.insert(*key); }
 
                        Value::Input(InputValue(key)) => { moved_keys.insert(*key); }
 
                        _ => {}
 
                    }
 
                }
 
                context.new_component(moved_keys, init_state)
 
            }
 
            EvalContext::Poly(_) => unreachable!(),
 
        }
 
    }
 
    fn new_channel(&mut self) -> [Value; 2] {
 
        match self {
 
            EvalContext::None => unreachable!(),
 
            EvalContext::Mono(context) => {
 
                let [from, to] = context.new_channel();
 
                let from = Value::Output(OutputValue(from));
 
                let to = Value::Input(InputValue(to));
 
                return [from, to];
 
            }
 
            EvalContext::Poly(_) => unreachable!()
 
        }
 
    }
 
    fn fires(&mut self, port: Value) -> Option<Value> {
 
        match self {
 
            EvalContext::None => unreachable!(),
 
            EvalContext::Mono(context) => unreachable!(),
 
            EvalContext::Mono(_) => unreachable!(),
 
            EvalContext::Poly(context) => match port {
 
                Value::Output(OutputValue(key)) => context.is_firing(key).map(Value::from),
 
                Value::Input(InputValue(key)) => context.is_firing(key).map(Value::from),
 
@@ -238,7 +266,7 @@ impl EvalContext<'_> {
 
    fn get(&mut self, port: Value) -> Option<Value> {
 
        match self {
 
            EvalContext::None => unreachable!(),
 
            EvalContext::Mono(context) => unreachable!(),
 
            EvalContext::Mono(_) => unreachable!(),
 
            EvalContext::Poly(context) => match port {
 
                Value::Output(OutputValue(key)) => {
 
                    context.read_msg(key).map(Value::receive_message)
src/protocol/parser.rs
Show inline comments
 
@@ -1082,7 +1082,7 @@ impl LinkStatements {
 

	
 
impl Visitor for LinkStatements {
 
    fn visit_statement(&mut self, h: &mut Heap, stmt: StatementId) -> VisitorResult {
 
        if let Some(UniqueStatementId(prev)) = std::mem::replace(&mut self.prev, None) {
 
        if let Some(UniqueStatementId(prev)) = self.prev.take() {
 
            h[prev].link_next(stmt);
 
        }
 
        recursive_statement(self, h, stmt)
 
@@ -1105,12 +1105,12 @@ impl Visitor for LinkStatements {
 
            h.alloc_end_if_statement(|this| EndIfStatement { this, position, next: None }).upcast();
 
        assert!(self.prev.is_none());
 
        self.visit_statement(h, h[stmt].true_body)?;
 
        if let Some(UniqueStatementId(prev)) = std::mem::replace(&mut self.prev, None) {
 
        if let Some(UniqueStatementId(prev)) = self.prev.take() {
 
            h[prev].link_next(pseudo);
 
        }
 
        assert!(self.prev.is_none());
 
        self.visit_statement(h, h[stmt].false_body)?;
 
        if let Some(UniqueStatementId(prev)) = std::mem::replace(&mut self.prev, None) {
 
        if let Some(UniqueStatementId(prev)) = self.prev.take() {
 
            h[prev].link_next(pseudo);
 
        }
 
        // Use the pseudo-statement as the statement where to update the next pointer
src/test/connector.rs
Show inline comments
 
@@ -524,10 +524,21 @@ fn composite_chain() {
 
    /*
 
    Alice -->sync-->sync-->A|P-->sync-->sync--> Bob
 
    */
 
    static PDL : &[u8] =
 
b"primitive sync(in i, out o) {
 
    while(true) synchronous {
 
        if (fires(i)) put(o, get(i));
 
    }
 
}
 
composite sync_2(in i, out o) {
 
    channel x -> y;
 
    new sync(i, x);
 
    new sync(y, o);
 
}";
 
    let timeout = Duration::from_millis(1_500);
 
    let addrs = [next_addr(), next_addr()];
 
    const N: usize = 1;
 
    static MSG: &[u8] = b"Hippity Hoppity";
 
    static MSG: &[u8] = b"SSS";
 
    assert!(run_connector_set(&[
 
        //
 
        &|x| {
 
@@ -543,7 +554,7 @@ fn composite_chain() {
 
        },
 
        &|x| {
 
            // Bob
 
            x.configure(PDL, b"sync_2").unwrap();
 
            x.configure(PDL, b"sync").unwrap();
 
            x.bind_port(0, Passive(addrs[0])).unwrap();
 
            x.bind_port(1, Native).unwrap();
 
            x.connect(timeout).unwrap();
0 comments (0 inline, 0 general)