Skip to content
Permalink
Browse files

[compiler][runtime] Implement module declaration and initialization w…

…ith reference fields.
  • Loading branch information...
ptal committed Jan 12, 2019
1 parent e7b9e7b commit 95c9485cf71bed8c5c0f7cf6cbcc7060a6ae8b34
@@ -17,7 +17,7 @@ name = "bonsai"
doc = false

[dependencies]
oak = "^0.6.0"
oak = "^0.7.0"
oak_runtime = "^0.5.5"
partial = "^0.4.0"
clap = "^2"
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#[debug(ProcCallT.printNothing, "")]
#[debug(ProcCallT.printOne, "1")]
#[run(ProcCallT.printNothing, "")]
#[run(ProcCallT.printOne, "1")]

package test;

This file was deleted.

@@ -27,17 +27,14 @@
private Statement program;
private Environment env;
private boolean debug;
private T rootModule;

// `data` is the module from which we obtain the process to execute with `process`.
public SpaceMachine(T data, Function<T, Statement> process, boolean debug) {
Layer first = new Layer();
this.rootModule = data;
this.rootModule.__init(first);
// `rootModule` is the module from which we obtain the process to execute with `process`.
public SpaceMachine(T rootModule, Function<T, Statement> process, boolean debug) {
rootModule.__init();
this.program = process.apply(rootModule);
this.program = rootModule.__wrap_process(this.program);
this.program = rootModule.__wrap_process(true, this.program);
this.program.prepare();
this.env = new Environment(first, program.countLayers()+1);
this.env = new Environment(program.countLayers()+1);
this.debug = debug;
}

@@ -18,10 +18,9 @@

public interface Module
{
/// Enter the scope of field variables in `layer`.
public void __init(Layer layer);
/// Initialize the UIDs of field variables.
public void __init();
/// Wrap the process `proc` into variable declarations (such as `SingleSpaceVarDecl`) representing the fields of the class.
public Statement __wrap_process(Statement proc);
/// Exit the scope of field variables in `layer`.
public void __destroy(Layer layer);
/// If the current module is root (directly passed to `SpaceMachine`), then the reference fields are treated as normal fields.
public Statement __wrap_process(boolean isRoot, Statement proc);
}
@@ -0,0 +1,84 @@
// Copyright 2019 Pierre Talbot

// 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.

package bonsai.runtime.synchronous.statements;

import java.util.*;
import java.util.function.*;
import bonsai.runtime.core.*;
import bonsai.runtime.synchronous.*;
import bonsai.runtime.synchronous.expressions.*;
import bonsai.runtime.synchronous.interfaces.*;
import bonsai.runtime.synchronous.exceptions.*;
import bonsai.runtime.synchronous.env.*;

/// A module declaration does not have a UID because it is not registered in the space.
/// However, we register its reference fields.
/// The other fields are declared in `body`.
public class ModuleVarDecl extends VarDecl implements Statement
{
public static class ReferenceField {
public String uid;
public Consumer<Object> refUpdater;
public Supplier<Object> fieldAccess;
public ReferenceField(String uid, Consumer<Object> refUpdater,
Supplier<Object> fieldAccess)
{
this.uid = uid;
this.refUpdater = refUpdater;
this.fieldAccess = fieldAccess;
}
}

private final List<ReferenceField> refFields;

public ModuleVarDecl(List<ReferenceField> refFields,
Expression initValue, Statement body) {
super(initValue, body);
this.refFields = refFields;
}

protected void enterScope(Layer layer) {}

public ModuleVarDecl copy() {
return new ModuleVarDecl(refFields,
initValue.copy(), body.copy());
}

public void canInstant(int layersRemaining, Layer layer) {
if(layersRemaining == 0) {
if (state1()) {
initValue.canInstant(layer);
}
}
body.canInstant(layersRemaining, layer);
}

protected boolean executeState1(Layer layer) {
boolean executedState1 = super.executeState1(layer);
if (executedState1) {
for(ReferenceField ref : refFields) {
layer.enterScope(ref.uid, ref.fieldAccess.get(), ref.refUpdater);
}
}
return executedState1;
}

protected void terminate(Layer layer) {
super.terminate(layer);
for(ReferenceField ref : refFields) {
layer.exitScope(ref.uid);
}
}
}
@@ -31,20 +31,19 @@ public SingleSpaceVarDecl(String uid, Expression initValue, Statement body) {

public SingleSpaceVarDecl copy() {
// throw new CannotCopyException("SingleSpaceVarDecl");
return new SingleSpaceVarDecl(uid, initValue.copy(), body.copy());
return new SingleSpaceVarDecl(uid.get(), initValue.copy(), body.copy());
}

public CompletionCode endOfInstant(int layersRemaining, Layer layer) {
checkExpressionStateEOI("Var decl", state1());
return super.endOfInstant(layersRemaining, layer);
protected void enterScope(Layer layer) {
layer.enterScope(uid.get(), exprResult.unwrap(), (Object o) -> {});
}

public void canInstant(int layersRemaining, Layer layer) {
if(layersRemaining == 0) {
if (state1()) {
// System.out.println("SingleSpaceVarDecl.canInstant: register(" + uid + ")");
initValue.canInstant(layer);
layer.register(uid, false);
layer.register(uid.get(), false);
}
}
body.canInstant(layersRemaining, layer);
@@ -25,17 +25,31 @@

public class SingleTimeVarDecl extends VarDecl implements Statement
{
private Consumer<Object> refUpdater;

// For local single_time variable.
public SingleTimeVarDecl(String uid, Expression initValue, Statement body) {
this(uid, initValue, (Object o) -> {}, body);
}

// For field single_time variable.
public SingleTimeVarDecl(String uid, Expression initValue,
Consumer<Object> refUpdater, Statement body)
{
super(uid, initValue, body);
this.refUpdater = refUpdater;
}

public SingleTimeVarDecl copy() {
// throw new CannotCopyException("SingleTimeVarDecl");
return new SingleTimeVarDecl(uid, initValue.copy(), body.copy());
return new SingleTimeVarDecl(uid.get(), initValue.copy(), body.copy());
}

protected void enterScope(Layer layer) {
layer.enterScope(uid.get(), exprResult.unwrap(), refUpdater);
}

public CompletionCode endOfInstant(int layersRemaining, Layer layer) {
checkExpressionStateEOI("Var decl", state1());
CompletionCode k = super.endOfInstant(layersRemaining, layer);
if (layersRemaining == 0 && state2()) {
terminate(layer);
@@ -46,7 +60,7 @@ public CompletionCode endOfInstant(int layersRemaining, Layer layer) {
public void canInstant(int layersRemaining, Layer layer) {
if(layersRemaining == 0) {
// System.out.println("SingleTimeVarDecl.canInstant: register " + uid);
layer.register(uid, true);
layer.register(uid.get(), true);
initValue.canInstant(layer);
exprResult = new ExprResult();
}
@@ -24,20 +24,26 @@

public abstract class VarDecl extends ASTNode implements Statement
{
protected String uid;
// Module variable does not have an UID, thus must not be registered in the space.
protected Optional<String> uid;
protected Expression initValue;
protected Statement body;

protected StmtResult res;
protected ExprResult exprResult;

public VarDecl(String uid, Expression initValue, Statement body) {
this.uid = uid;
public VarDecl(Expression initValue, Statement body) {
this.initValue = initValue;
this.body = body;
this.uid = Optional.empty();
init();
}

public VarDecl(String uid, Expression initValue, Statement body) {
this(initValue, body);
this.uid = Optional.of(uid);
}

private void init() {
this.res = new StmtResult(CompletionCode.WAIT);
this.exprResult = new ExprResult();
@@ -53,6 +59,7 @@ private void init() {
}

public CompletionCode endOfInstant(int layersRemaining, Layer layer) {
checkExpressionStateEOI("Var decl", state1());
checkNonTerminatedEOI("Var decl", res.k);
if (state2()) {
return body.endOfInstant(layersRemaining, layer);
@@ -79,7 +86,9 @@ protected boolean state3() {

protected void terminate(Layer layer) {
// System.out.println("VarDecl.terminate");
layer.exitScope(uid);
if (uid.isPresent()) {
layer.exitScope(uid.get());
}
// Free the pointed value of the variable.
exprResult = new ExprResult();
}
@@ -133,15 +142,20 @@ public StmtResult execute(int layersRemaining, Layer layer) {
}
}

private void executeState1(Layer layer) {
protected abstract void enterScope(Layer layer);

// Return `true` if we moved from state1 to state2.
protected boolean executeState1(Layer layer) {
if (state1()) {
// System.out.println("VarDecl.executeState1");
exprResult = initValue.execute(layer);
if (!exprResult.isSuspended()) {
initValue.terminate(layer);
layer.enterScope(uid, exprResult.unwrap(), (Object o) -> {});
enterScope(layer);
return true;
}
}
return false;
}

private void executeState2(Layer layer) {
@@ -32,17 +32,12 @@ public WorldLineVarDecl(String uid, Expression initValue, Statement body) {

public WorldLineVarDecl copy() {
// throw new CannotCopyException("WorldLineVarDecl");
return new WorldLineVarDecl(uid, initValue.copy(), body.copy());
}

public CompletionCode endOfInstant(int layersRemaining, Layer layer) {
checkExpressionStateEOI("Var decl", state1());
return super.endOfInstant(layersRemaining, layer);
return new WorldLineVarDecl(uid.get(), initValue.copy(), body.copy());
}

public StmtResult execute(int layersRemaining, Layer layer) {
// Save the current variable before we remove it in case the body terminates (we still need to add it in the StmtResult).
Variable v = layer.lookUpVar(uid);
Variable v = layer.lookUpVar(uid.get());
StmtResult res = super.execute(layersRemaining, layer);
if (layersRemaining == 0 && !res.k.isInternal()) {
res.registerWL(layer.currentQueue(), v, state3());
@@ -632,10 +632,6 @@ impl Variable {
Self::new(span, path, 0, permission)
}

// pub fn proc_arg(span: Span, path: VarPath) -> Self {
// Self::new(span, path, 0, None)
// }

pub fn first(&self) -> Ident {
self.path.first()
}
@@ -135,7 +135,7 @@ impl<'a> ExpressionCompiler<'a>
let access_class =
if free_access { format!("FreeAccess") }
else {
match var.permission.expect("All variables must have a permission at generation stage.") {
match var.permission.expect(&format!("All variables must have a permission at generation stage ({}).", var)) {
Permission::Read => format!("ReadAccess"),
Permission::Write => format!("WriteAccess"),
Permission::ReadWrite => format!("ReadWriteAccess")
@@ -185,17 +185,22 @@ impl<'a> ExpressionCompiler<'a>
}
Call(call) => {
if let Some(target) = call.target {
let uid = target.first_uid();
let uid = target.last_uid();
// Host variables can only appear as fields, and thus do not need to be retrieved from the environment.
if !self.context.var_by_uid(uid).is_host() {
if self.context.var_by_uid(uid).is_spacetime() {
variables.push(target);
}
}
for arg in call.args {
self.collect_variables(variables, arg);
}
}
Var(var) => { variables.push(var); }
Var(var) => {
let var_info = self.context.var_by_uid(var.last_uid());
if var_info.is_spacetime() {
variables.push(var);
}
}
And(e1, e2)
| Or(e1, e2) => {
self.collect_variables(variables, *e1);

0 comments on commit 95c9485

Please sign in to comment.
You can’t perform that action at this time.