Skip to content

Commit

Permalink
Merge pull request #38 from m-lyons/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
nikklassen authored Mar 27, 2017
2 parents fbd32a2 + 9ed844e commit 6314120
Show file tree
Hide file tree
Showing 23 changed files with 406 additions and 87 deletions.
24 changes: 12 additions & 12 deletions src/main/antlr4/Manifold.g4
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ typevalue:
| functionTypeValue # FunctionType
;
// TODO: implement type declarations and undefined variable declarations
//declaration:
// type namespacedIdentifier # UndefinedDeclaration
// | TYPE_KEYWORD namespacedIdentifier '=' type # TypeDeclaration
// ;
undefinedTypeDeclaration: type namespacedIdentifier;
typeDeclaration: TYPE_KEYWORD namespacedIdentifier '=' type;
declaration:
typeDeclaration
| undefinedTypeDeclaration
;
reference:
tupleValue # Tuple
Expand All @@ -81,24 +83,22 @@ rvalue:
| INTEGER_VALUE # Integer
| 'infer' # Infer
| functionValue # Function
| VISIBILITY_PUBLIC? lvalue '=' rvalue # AssignmentExpression
| reference rvalue # FunctionInvocationExpression // TODO: function invocation needs to be 'reference arglist'
| reference # ReferenceExpression
| VISIBILITY_PUBLIC? lvalue '=' rvalue # AssignmentExpression
| 'primitive' 'port' typevalue (':' tupleTypeValue)? # PrimitivePortDefinitionExpression
| 'primitive' 'node' functionTypeValue # PrimitiveNodeDefinitionExpression
| 'import' STRING_VALUE #ImportExpr
;
lvalue:
// TODO: implement declarations as lvalues
// declaration # AssignmentDeclaration
reference # LValueExpression
undefinedDeclaration # AssignmentDeclaration
| reference # LValueExpression
;
// TODO: declarations as expressions
expression:
rvalue
// | declaration
declaration
| rvalue
;
EXPRESSION_TERMINATOR: ';';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.*;
import java.util.stream.Stream;

class ExpressionContextVisitor extends ManifoldBaseVisitor<ExpressionVertex> {
Expand Down Expand Up @@ -296,11 +293,27 @@ public ExpressionVertex visitNamespacedIdentifier(
private ExpressionVertex createVariableVertex(VariableIdentifier id) {
if (ReservedIdentifiers.getInstance()
.isReservedIdentifier(id)) {
// try to get previously added variable vertex to the reserved id
if (exprGraph.containsVariable(id)) {
return this.getVariableVertex(exprGraph, id);
}
// construct a constant value vertex with the identifier's value
ConstantValueVertex vReserved = new ConstantValueVertex(exprGraph,
ReservedIdentifiers.getInstance().getValue(id));
exprGraph.addVertex(vReserved);
return vReserved;

// create a variable vertex to represent this constant in the graph,
// this prevents unnecessary copies of vertices.
VariableReferenceVertex v = new VariableReferenceVertex(exprGraph, id);
try {
exprGraph.addVertex(v);
} catch (MultipleDefinitionException e) {
System.err.println("multiple definitions of reserved identifier " + id);
throw new ParseCancellationException();
}
ExpressionEdge e = new ExpressionEdge(vReserved, v);
exprGraph.addEdge(e);
return v;
} else {
// this is a variable
// TODO scope
Expand All @@ -324,6 +337,39 @@ private ExpressionVertex createVariableVertex(VariableIdentifier id) {
}
}

@Override
public ExpressionVertex visitUndefinedDeclaration(UndefinedDeclarationContext ctx) {
// get the vertex for the type
ExpressionVertex vType = ctx.type().accept(this);
VariableIdentifier id = getVariableIdentifier(ctx.namespacedIdentifier());
VariableDeclarationVertex v = new VariableDeclarationVertex(exprGraph, id, vType);
// shouldn't exist yet
try {
exprGraph.addVertex(v);
} catch (MultipleDefinitionException e) {
System.err.println("multiple declarations of variable " + id);
throw new ParseCancellationException();
}
return v;
}

@Override
public ExpressionVertex visitTypeDeclaration(TypeDeclarationContext ctx) {
ExpressionVertex vTypeKeyword = ctx.TYPE_KEYWORD().accept(this);
ExpressionVertex vType = ctx.type().accept(this);
VariableIdentifier id = getVariableIdentifier(ctx.namespacedIdentifier());
VariableDeclarationVertex v = new VariableDeclarationVertex(exprGraph, id, vTypeKeyword);
try {
exprGraph.addVertex(v);
} catch (MultipleDefinitionException e) {
System.err.println("multiple declarations of type " + id);
throw new ParseCancellationException();
}
ExpressionEdge e = new ExpressionEdge(vType, v);
exprGraph.addEdge(e);
return vType;
}

@Override
public ExpressionVertex visitImportExpr(ImportExprContext context) {
String importString = context.STRING_VALUE().getText()
Expand Down Expand Up @@ -375,6 +421,27 @@ public ExpressionVertex visitTerminal(TerminalNode node) {
new RealValue(Double.parseDouble(node.getText())));
exprGraph.addVertex(v);
return v;
} else if (node.getSymbol().getType() == ManifoldLexer.TYPE_KEYWORD) {
NamespaceIdentifier empty = new NamespaceIdentifier(Collections.emptyList());
VariableIdentifier id = new VariableIdentifier(empty, node.toString());
// try to get previously added vertex
if (exprGraph.containsVariable(id)) {
return this.getVariableVertex(exprGraph, id);
}
// construct a constant value vertex with the identifier's value
ConstantValueVertex vReserved = new ConstantValueVertex(exprGraph,
ReservedIdentifiers.getInstance().getValue(id));
exprGraph.addVertex(vReserved);
VariableReferenceVertex v = new VariableReferenceVertex(exprGraph, id);
try {
exprGraph.addVertex(v);
} catch (MultipleDefinitionException e) {
System.err.println("multiple definitions of reserved identifier " + id);
throw new ParseCancellationException();
}
ExpressionEdge e = new ExpressionEdge(vReserved, v);
exprGraph.addEdge(e);
return v;
} else {
throw new UndefinedBehaviourError(
"unknown terminal node '" + node.getSymbol().getText() + "'");
Expand Down Expand Up @@ -441,5 +508,15 @@ private String createLineError(ParserRuleContext ctx, String reason) {
.append(reason);
return sb.toString();
}

private VariableReferenceVertex getVariableVertex(ExpressionGraph exprGraph, VariableIdentifier id) {
try {
VariableReferenceVertex v = exprGraph.getVariableVertex(id);
return v;
} catch (VariableNotDefinedException e) {
// cannot actually happen
throw Throwables.propagate(e);
}
}
}

18 changes: 15 additions & 3 deletions src/main/java/org/manifold/compiler/front/ExpressionGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ public ExpressionGraph() {
* @param subGraphOutput Exit vertex in subGraph
*/
public void addFunctionExpressionGraph(ExpressionGraph subGraph,
ExpressionEdge mainGraphInput, ExpressionVertex subGraphInput,
ExpressionEdge mainGraphOutput, ExpressionVertex subGraphOutput,
ExpressionEdge mainGraphInput, TupleValueVertex subGraphInput,
ExpressionEdge mainGraphOutput, TupleValueVertex subGraphOutput,
Map<VariableReferenceVertex, VariableReferenceVertex> variableRenamingMap) {

// Sanity checks
Expand Down Expand Up @@ -284,7 +284,19 @@ public void addFunctionExpressionGraph(ExpressionGraph subGraph,
exprVertexMap.put(subGraphInput, inputVertex);

// Connect the function output vertex to the main graph
ExpressionEdge outputEdge = new ExpressionEdge(exprVertexMap.get(subGraphOutput), mainGraphOutput.getTarget());
ExpressionVertex outputVertex = exprVertexMap.get(subGraphOutput);
if (subGraphOutput.getValueEdges().size() == 1) {
// Remove the output tuple from the expression graph
this.allVertices.remove(outputVertex);
this.nonVariableVertices.remove(outputVertex);

// Find the single value in the tuple and assign connect it to the output
ExpressionEdge functionReturnEdge = subGraphOutput.getValueEdges().get(0);
subGraph.removeEdge(functionReturnEdge);

outputVertex = exprVertexMap.get(functionReturnEdge.getSource());
}
ExpressionEdge outputEdge = new ExpressionEdge(outputVertex, mainGraphOutput.getTarget());
this.edges.add(outputEdge);

// each edge in subgraph -> edge in main graph should refer to the same source/target
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,19 @@ public Value getValue() {

@Override
public void verify() throws Exception {
// TODO Auto-generated method stub

// Elaborate function
ExpressionVertex vFunction = functionEdge.getSource();
vFunction.elaborate();
// now find out what kind of function we are about to invoke
Value function = vFunction.getValue();
if (function instanceof FunctionValue) {
// verify all the variables in the function body
FunctionValue functionValue = (FunctionValue) function;
for (Map.Entry<VariableIdentifier, VariableReferenceVertex> entry
: functionValue.getBody().getVariableVertices().entrySet()) {
entry.getValue().verify();
}
}
}

@Override
Expand Down Expand Up @@ -165,8 +176,8 @@ private void elaborateNonPrimitiveFunction(Value f,

log.debug("main graph output is " + mainGraphOutput);
// identify subgraph (body) input and output vertices
ExpressionVertex subGraphInput = function.getInputVertex();
ExpressionVertex subGraphOutput = function.getOutputVertex();
TupleValueVertex subGraphInput = function.getInputVertex();
TupleValueVertex subGraphOutput = function.getOutputVertex();

// perform copy
getExpressionGraph().addFunctionExpressionGraph(function.getBody(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,29 @@ public void elaborate() throws Exception {
TupleTypeValue outputType = (TupleTypeValue) type.getOutputType();
MappedArray<String, ExpressionEdge> inputEdges = new MappedArray<>();
MappedArray<String, ExpressionEdge> outputEdges = new MappedArray<>();
for (MappedArray<String, TypeValue>.Entry argName : inputType.getSubtypes()) {
inputType.getSubtypes().forEach((argName) -> {
ExpressionEdge e = new ExpressionEdge(null, null); // I know what I'm doing
functionBody.addEdge(e);
inputEdges.put(argName.getKey(), e);
}
for (MappedArray<String, TypeValue>.Entry typeEntry : outputType.getSubtypes()) {
});
outputType.getSubtypes().forEach((typeEntry) -> {
String argName = typeEntry.getKey();
// "name resolution": look for a variable reference vertex with this name in the subgraph
for (Map.Entry<VariableIdentifier, VariableReferenceVertex> vRef
: functionBody.getVariableVertices().entrySet()) {
if (vRef.getKey() == null) {
// then the user tried to have an output tuple without named keys
throw new FrontendBuildException("The function output type is an anonymous tuple. " +
"Give the anonymous value a key to fix this.");
}
if (vRef.getKey().getName().equals(argName)) {
ExpressionEdge e = new ExpressionEdge(vRef.getValue(), null);
functionBody.addEdge(e);
outputEdges.put(argName, e);
break;
}
}
}
});
TupleValueVertex vInput = new TupleValueVertex(functionBody, inputEdges);
functionBody.addVertex(vInput);
TupleValueVertex vOutput = new TupleValueVertex(functionBody, outputEdges);
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/org/manifold/compiler/front/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static void elaborateFunctions(ExpressionGraph g) throws Exception {
log.debug("elaborating function "
+ Integer.toString(System.identityHashCode(v)));
v.elaborate();
v.verify();
log.debug("writing out expression graph at function elaboration step " +
step);
File elaboratedDot = new File("tmp.elaborated.step" + step + ".dot");
Expand Down Expand Up @@ -150,6 +151,21 @@ public static void elaborateNodes(ExpressionGraph g, Schematic s)

}

public static void verifyVariables(ExpressionGraph g) throws Exception {
// verify that variables are only assigned once and
// iterate through all the variables in the graph and verify that
// there aren't any type mismatches.
log.debug("verifying variables");

g.verifyVariablesSingleAssignment();

Map<VariableIdentifier, VariableReferenceVertex> variables = g.getVariableVertices();
for (Map.Entry<VariableIdentifier, VariableReferenceVertex> entry : variables.entrySet()) {
VariableReferenceVertex vertex = entry.getValue();
vertex.verify();
}
}

@Override
public Schematic invokeFrontend(CommandLine cmd) throws Exception {

Expand All @@ -160,15 +176,15 @@ public Schematic invokeFrontend(CommandLine cmd) throws Exception {

ExpressionGraphParser parser = new ExpressionGraphParser();
ExpressionGraph exprGraph = parser.parseFile(inputFile);
exprGraph.verifyVariablesSingleAssignment();

Schematic schematic = new Schematic(inputFile.getName());

verifyVariables(exprGraph);
elaborateFunctions(exprGraph);
log.debug("writing out expression graph after function elaboration");
File elaboratedDot = new File(inputFile.getName() + ".elaborated.dot");
exprGraph.writeDOTFile(elaboratedDot);

Schematic schematic = new Schematic(inputFile.getName());

elaborateSchematicTypes(exprGraph, schematic);
elaborateNodes(exprGraph, schematic);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ public void elaborate() throws Exception {

for (MappedArray<String, TypeValue>.Entry typeEntry : outputType.getSubtypes()) {
String outputPortName = typeEntry.getKey();
if (outputPortName == null) {
throw new FrontendBuildException("The output port name was anonymous for this node. " +
"This can be fixed by giving a name to the port");
}
PortTypeValue outputPortType = nodeType.getPorts().get(outputPortName);
FuturePortValue futurePort = new FuturePortValue(
this, outputPortName, outputPortType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class PrimitiveNodeVertex extends ExpressionVertex {
Expand Down Expand Up @@ -50,7 +49,7 @@ public String toString() {
}

private void extractPortTypes(TypeValue type,
Map<String, PortTypeValue> portMap) throws TypeMismatchException {
MappedArray<String, PortTypeValue> portMap) throws TypeMismatchException {
if (!(type instanceof TupleTypeValue)) {
MappedArray<String, TypeValue> x = new MappedArray<>();
x.put("x", TypeTypeValue.getInstance());
Expand Down Expand Up @@ -79,7 +78,7 @@ private void extractPortTypes(TypeValue type,
}

private void extractAttributes(TypeValue type,
Map<String, TypeValue> attrMap) throws TypeMismatchException {
MappedArray<String, TypeValue> attrMap) throws TypeMismatchException {
if (!(type instanceof TupleTypeValue)) {
MappedArray<String, TypeValue> x = new MappedArray<>();
x.put("x", TypeTypeValue.getInstance());
Expand Down Expand Up @@ -174,8 +173,8 @@ public void elaborate() throws Exception {
}
log.debug("elaborating primitive node");

Map<String, PortTypeValue> portTypeMap = new HashMap<>();
Map<String, TypeValue> attributesMap = new HashMap<>();
MappedArray<String, PortTypeValue> portTypeMap = new MappedArray<>();
MappedArray<String, TypeValue> attributesMap = new MappedArray<>();

ExpressionVertex portTypeVertex = signatureEdge.getSource();
portTypeVertex.elaborate();
Expand Down Expand Up @@ -209,7 +208,7 @@ public void elaborate() throws Exception {
log.debug("extracting attributes");
extractAttributes(portType.getInputType(), attributesMap);

this.node = new NodeTypeValue(attributesMap, portTypeMap);
this.node = new NodeTypeValue(MappedArray.toMap(attributesMap), MappedArray.toMap(portTypeMap));
log.debug("constructed node type " + debugNodeType(node));
this.instantiationSignature = constructInstantiationSignature(portType);
log.debug("instantiation signature is "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,14 @@ public void elaborate() throws TypeMismatchException {
if (port != null) {
return;
}
// check that the signal type is really a type

ExpressionVertex signalTypeVertex = signalTypeEdge.getSource();
try {
signalTypeVertex.elaborate();
} catch (Exception e) {
throw new TypeMismatchException(TypeTypeValue.getInstance(), signalTypeVertex.getType());
}
// check that the signal type is really a type
if (!(signalTypeVertex.getType()
.isSubtypeOf(TypeTypeValue.getInstance()))) {
throw new TypeMismatchException(
Expand Down
Loading

0 comments on commit 6314120

Please sign in to comment.