diff --git a/src/qir/ast/QIRLambda.java b/src/qir/ast/QIRLambda.java index 48c9046a5bd7c5056b8a3aea799384063d15a271..33eb76b1c862c88ab96159712c917b28f7a56af9 100644 --- a/src/qir/ast/QIRLambda.java +++ b/src/qir/ast/QIRLambda.java @@ -8,8 +8,6 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.source.SourceSection; import qir.driver.IQIRVisitor; -import qir.types.QIRAnyType; -import qir.types.QIRType; import qir.util.QIRAny; /** @@ -20,7 +18,6 @@ public final class QIRLambda extends QIRNode { * The name of the function. {@code null} for an anonymous function. */ private final String funName; - private final QIRType type; /** * A {@link QIRVariable} that represents the argument of the function. */ @@ -35,27 +32,18 @@ public final class QIRLambda extends QIRNode { */ private MaterializedFrame env; - public QIRLambda(final SourceSection source, final String funName, final QIRType type, final QIRVariable var, final QIRNode body, final FrameDescriptor frameDescr) { + public QIRLambda(final SourceSection source, final String funName, final QIRVariable var, final QIRNode body, final FrameDescriptor frameDescr) { super(source); this.funName = funName; - this.type = type; this.var = var; this.body = body; this.target = Truffle.getRuntime().createCallTarget(new QIRRootNode(null, var != null ? frameDescr.findOrAddFrameSlot(var.id) : null, body, frameDescr)); } - public QIRLambda(final SourceSection source, final String funName, final QIRVariable var, final QIRNode body, final FrameDescriptor frameDescr) { - this(source, funName, QIRAnyType.getInstance(), var, body, frameDescr); - } - public final String getFunName() { return funName; } - public final QIRType getType() { - return type; - } - public final QIRVariable getVar() { return var; } @@ -74,7 +62,7 @@ public final class QIRLambda extends QIRNode { @Override public final String toString() { - return (funName != null ? funName : "lambda") + " : " + type.toString() + " " + var + " -> {" + body + "}"; + return (funName != null ? funName : "lambda") + " " + var + " -> {" + body + "}"; } @Override diff --git a/src/qir/ast/QIRNode.java b/src/qir/ast/QIRNode.java index edf1bbd8cb874adc2c4d106e3aa6134956ae28aa..2f22c61ab5f65246d8638c5775dec837203d65fb 100644 --- a/src/qir/ast/QIRNode.java +++ b/src/qir/ast/QIRNode.java @@ -1,5 +1,8 @@ package qir.ast; +import java.util.NoSuchElementException; +import java.util.Optional; + import com.oracle.truffle.api.dsl.ReportPolymorphism; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; @@ -18,6 +21,7 @@ import qir.ast.expression.QIRBoolean; import qir.ast.expression.QIRNumber; import qir.ast.expression.QIRString; import qir.driver.IQIRVisitor; +import qir.types.QIRType; import qir.util.QIRException; /** @@ -31,6 +35,7 @@ public abstract class QIRNode extends Node implements InstrumentableNode { * The location in the source code of the expression represented by this node. */ protected final SourceSection sourceSection; + protected Optional<QIRType> type = Optional.empty(); public QIRNode(final SourceSection sourceSection) { this.sourceSection = sourceSection; @@ -41,6 +46,21 @@ public abstract class QIRNode extends Node implements InstrumentableNode { return sourceSection; } + public final Optional<QIRType> getType() { + return type; + } + + public final QIRType getTypeUnsafe() throws NoSuchElementException { + return type.get(); + } + + public final QIRType setType(final QIRType type) { + if (this.type.isPresent()) + throw new QIRException("Type already set for " + this); + this.type = Optional.of(type); + return type; + } + @Override public int hashCode() { return super.hashCode(); diff --git a/src/qir/ast/data/QIRList.java b/src/qir/ast/data/QIRList.java index 2259b5463940f7011b40062741c09b583e7b149f..90c6d9ccdf4ceb368d9d1960f4a93c8fcf5f5cc2 100644 --- a/src/qir/ast/data/QIRList.java +++ b/src/qir/ast/data/QIRList.java @@ -10,14 +10,11 @@ import com.oracle.truffle.api.source.SourceSection; import qir.ast.QIRNode; import qir.driver.IQIRVisitor; -import qir.types.QIRType; /** * {@link QIRList} is the generic representation of a list in QIR. */ public abstract class QIRList extends QIRNode { - public QIRType type; - public QIRList(final SourceSection source) { super(source); } diff --git a/src/qir/ast/data/QIRRecord.java b/src/qir/ast/data/QIRRecord.java index 8732c73700ef68fd57d24197631eeb1c305896b9..00da67be72e030b495d78ea45ccfc0759994344d 100644 --- a/src/qir/ast/data/QIRRecord.java +++ b/src/qir/ast/data/QIRRecord.java @@ -4,14 +4,11 @@ import com.oracle.truffle.api.source.SourceSection; import qir.ast.QIRNode; import qir.driver.IQIRVisitor; -import qir.types.QIRType; /** * {@link QIRRecord} is the generic representation of a tuple in QIR. */ public abstract class QIRRecord extends QIRNode { - public QIRType type; - public QIRRecord(final SourceSection source) { super(source); } diff --git a/src/qir/parser/Parser.java b/src/qir/parser/Parser.java index 74920a97a7e89b2dddf3cceae1bc708e0b1b0a62..32cf3340dadb36d90950eb25f7067b0bc685da61 100644 --- a/src/qir/parser/Parser.java +++ b/src/qir/parser/Parser.java @@ -414,7 +414,7 @@ public class Parser { Expect(21); final Token srcToken = t; Token funName = null; - QIRType type = new QIRFunctionType(new QIRType[]{QIRAnyType.getInstance()}, QIRAnyType.getInstance()); + QIRType type = null; if (la.kind == 22) { Get(); Expect(1); @@ -427,7 +427,10 @@ public class Parser { QIRVariable var = Variable(); Expect(24); QIRNode body = QIR(); - res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, type, var, body, new FrameDescriptor()); + res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, var, body, new FrameDescriptor()); + if (type != null) + res.setType(type); + return res; } @@ -450,7 +453,7 @@ public class Parser { res = QIRRnil.getInstance(); final Token srcToken = t; Token idToken; - QIRType type = QIRAnyType.getInstance(); + QIRType type = null; if (la.kind == 1) { Get(); idToken = t; @@ -471,7 +474,8 @@ public class Parser { Get(); type = RecordType(); } - res.type = type; + if (type != null) + res.setType(type); return res; } @@ -479,7 +483,7 @@ public class Parser { QIRList res; Expect(39); res = QIRLnil.getInstance(); - QIRType type = QIRAnyType.getInstance(); + QIRType type = null; final Token srcToken = t; if (StartOf(1)) { QIRNode value = QIR(); @@ -495,7 +499,8 @@ public class Parser { Get(); type = ListType(); } - res.type = type; + if (type != null) + res.setType(type); return res; } diff --git a/src/qir/parser/qir.atg b/src/qir/parser/qir.atg index 2934101c9ef59ace663d3a7751d17ee16306a35d..2f2ff195f258fee35df9c14bc2e28f4b9deb32d5 100644 --- a/src/qir/parser/qir.atg +++ b/src/qir/parser/qir.atg @@ -153,10 +153,13 @@ identifier (. res = new QIRVariable(srcFromToken(t), t.val); .) Lambda<out QIRLambda res> = "fun" (. final Token srcToken = t; Token funName = null; - QIRType type = new QIRFunctionType(new QIRType[]{QIRAnyType.getInstance()}, QIRAnyType.getInstance()); .) + QIRType type = null; .) [ "#" identifier (. funName = t; .) ] [ ":" Type<out type> ] Variable<out QIRVariable var> "->" -QIR<out QIRNode body> (. res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, type, var, body, new FrameDescriptor()); .) +QIR<out QIRNode body> (. res = new QIRLambda(srcFromToken(srcToken), funName == null ? null : funName.val, var, body, new FrameDescriptor()); + if (type != null) + res.setType(type); + .) . Ifexpr<out QIRIf res> = @@ -169,14 +172,15 @@ Tuplecons<out QIRRecord res> = "{" (. res = QIRRnil.getInstance(); final Token srcToken = t; Token idToken; - QIRType type = QIRAnyType.getInstance(); .) + QIRType type = null; .) [ identifier (. idToken = t; .) "=" QIR<out QIRNode value> (. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .) { ";" identifier (. idToken = t; .) "=" QIR<out value> (. res = new QIRRcons(srcFromToken(srcToken), idToken.val, value, res); .) -} ] "}" [ ":" RecordType<out type> ] (. res.type = type; .) +} ] "}" [ ":" RecordType<out type> ] (. if (type != null) + res.setType(type); .) . Type<out QIRType res> = (. res = null; .) @@ -225,13 +229,14 @@ ListType<out QIRListType res> = Listcons<out QIRList res> = "[" (. res = QIRLnil.getInstance(); - QIRType type = QIRAnyType.getInstance(); + QIRType type = null; final Token srcToken = t; .) [ QIR<out QIRNode value> (. res = new QIRLcons(srcFromToken(srcToken), value, res); .) { ";" QIR<out value> (. res = new QIRLcons(srcFromToken(srcToken), value, res); .) -} ] "]" [ ":" ListType<out type> ] (. res.type = type; .) +} ] "]" [ ":" ListType<out type> ] (. if (type != null) + res.setType(type); .) . Listdestr<out QIRLdestr res> = diff --git a/src/qir/typing/QIRGenericTypeSystemVisitor.java b/src/qir/typing/QIRGenericTypeSystemVisitor.java index f75d067a5893f22e4b3b5cafb879ace0d81f4c6b..b5530e234952ab151832adda810f4697a6bf9472 100644 --- a/src/qir/typing/QIRGenericTypeSystemVisitor.java +++ b/src/qir/typing/QIRGenericTypeSystemVisitor.java @@ -64,9 +64,9 @@ public final class QIRGenericTypeSystemVisitor extends QIRTypeSystemVisitor { private static final QIRType tryTyping(final QIRNode expr) { for (Class<? extends QIRTypeSystemVisitor> specificTypeSystem : specificTypeSystems) try { - return expr.accept(specificTypeSystem.newInstance()); + return expr.setType(expr.accept(specificTypeSystem.newInstance())); } catch (final QIRTypeErrorException e) { - } catch (InstantiationException | IllegalAccessException e) { + } catch (final InstantiationException | IllegalAccessException e) { throw new QIRException("Internal error: " + specificTypeSystem.getName() + " could not be instantiated."); } throw new QIRException("No type system could type " + expr);