From 5b961cb19e8de688092b7ff3563adcf757a2afb6 Mon Sep 17 00:00:00 2001 From: Edward Kmett Date: Fri, 1 Nov 2019 21:03:24 -0700 Subject: [PATCH] more streamlining and kotlinisms --- src/cadenza/jit/code.kt | 54 +++++++++++++++----------------- src/cadenza/jit/frame_builder.kt | 1 - src/cadenza/loc.kt | 19 +++++++++++ src/cadenza/section.kt | 21 ------------- src/cadenza/semantics/terms.kt | 17 +++++----- src/parser.kt | 4 --- 6 files changed, 53 insertions(+), 63 deletions(-) create mode 100644 src/cadenza/loc.kt delete mode 100644 src/cadenza/section.kt diff --git a/src/cadenza/jit/code.kt b/src/cadenza/jit/code.kt index df03b97..5292ee0 100644 --- a/src/cadenza/jit/code.kt +++ b/src/cadenza/jit/code.kt @@ -25,7 +25,7 @@ private inline fun isSuperCombinator(callTarget: RootCallTarget) = @GenerateWrapper @NodeInfo(language = "core", description = "core nodes") @TypeSystemReference(DataTypes::class) -abstract class Code(val section: Section = Section.default) : Node(), InstrumentableNode { +abstract class Code(val loc: Loc? = null) : Node(), InstrumentableNode { @Throws(NeutralException::class) abstract fun execute(frame: VirtualFrame): Any? @@ -45,10 +45,8 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument @Throws(NeutralException::class) open fun executeUnit(frame: VirtualFrame) { execute(frame) } - override fun getSourceSection(): SourceSection? = - (if (section.sourceCharIndex == NO_SOURCE) rootNode else null)?.sourceSection?.source?.section(section) - - override fun isInstrumentable() = section.sourceCharIndex != NO_SOURCE + override fun getSourceSection(): SourceSection? = loc?.let { rootNode?.sourceSection?.source?.section(it) } + override fun isInstrumentable() = loc !== null override fun hasTag(tag: Class?) = tag == StandardTags.ExpressionTag::class.java override fun createWrapper(probe: ProbeNode): InstrumentableNode.WrapperNode = CodeWrapper(this, probe) @@ -56,9 +54,9 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument @NodeInfo(shortName = "App") class App( @field:Child var rator: Code, - @field:Children val rands: Array - , section: Section = Section.default - ) : Code(section) { + @field:Children val rands: Array, + loc: Loc? = null + ) : Code(loc) { @Child private var indirectCallNode: IndirectCallNode = Truffle.getRuntime().createIndirectCallNode() @ExplodeLoop @@ -102,8 +100,8 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument @field:Child private var condNode: Code, @field:Child private var thenNode: Code, @field:Child private var elseNode: Code, - section: Section = Section.default - ) : Code(section) { + loc: Loc? = null + ) : Code(loc) { private val conditionProfile = ConditionProfile.createBinaryProfile() @Throws(NeutralException::class) @@ -142,8 +140,8 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument private val arity: Int, @field:Child internal var callTarget: RootCallTarget, internal val type: Type, - section: Section = Section.default - ) : Code(section) { + loc: Loc? = null + ) : Code(loc) { // do we need to capture an environment? private inline fun isSuperCombinator() = closureFrameDescriptor != null @@ -165,7 +163,7 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument @NodeInfo(shortName = "Read") - abstract class Var protected constructor(private val slot: FrameSlot, section: Section = Section.default) : Code(section) { + abstract class Var protected constructor(private val slot: FrameSlot, loc: Loc? = null) : Code(loc) { @Specialization(rewriteOn = [FrameSlotTypeException::class]) @Throws(FrameSlotTypeException::class) @@ -182,7 +180,7 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument } @Suppress("unused") - class Ann(@field:Child private var body: Code, val type: Type, section: Section = Section.default) : Code(section) { + class Ann(@field:Child private var body: Code, val type: Type, loc: Loc? = null) : Code(loc) { @Throws(NeutralException::class) override fun execute(frame: VirtualFrame): Any? = body.execute(frame) override fun executeAny(frame: VirtualFrame): Any? = body.executeAny(frame) @@ -201,8 +199,8 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument val type: Type, private val builtin: Builtin, @field:Child internal var arg: Code, - section: Section = Section.default - ) : Code(section) { + loc: Loc? = null + ) : Code(loc) { override fun executeAny(frame: VirtualFrame): Any? = try { builtin.execute(frame, arg) @@ -246,7 +244,7 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument // instrumentation @Suppress("NOTHING_TO_INLINE","unused") @NodeInfo(shortName = "LitBool") - class LitBool(val value: Boolean, section: Section = Section.default): Code(section) { + class LitBool(val value: Boolean, loc: Loc? = null): Code(loc) { @Suppress("UNUSED_PARAMETER") override fun execute(frame: VirtualFrame) = value @Suppress("UNUSED_PARAMETER") @@ -255,7 +253,7 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument @Suppress("NOTHING_TO_INLINE") @NodeInfo(shortName = "LitInt") - class LitInt(val value: Int, section: Section = Section.default): Code(section) { + class LitInt(val value: Int, loc: Loc? = null): Code(loc) { @Suppress("UNUSED_PARAMETER") override fun execute(frame: VirtualFrame) = value @Suppress("UNUSED_PARAMETER") @@ -264,7 +262,7 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument @Suppress("NOTHING_TO_INLINE","unused") @NodeInfo(shortName = "LitBigInt") - class LitBigInt(val value: BigInt, section: Section = Section.default): Code(section) { + class LitBigInt(val value: BigInt, loc: Loc? = null): Code(loc) { @Suppress("UNUSED_PARAMETER") override fun execute(frame: VirtualFrame) = value @Throws(UnexpectedResultException::class) @@ -280,31 +278,31 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument companion object { @Suppress("NOTHING_TO_INLINE") - inline fun `var`(slot: FrameSlot, section: Section = Section.default): Var = CodeFactory.VarNodeGen.create(slot, section) + inline fun `var`(slot: FrameSlot, loc: Loc? = null): Var = CodeFactory.VarNodeGen.create(slot, loc) // invariant callTarget points to a native function body with known arity @Suppress("NOTHING_TO_INLINE","UNUSED") - fun lam(callTarget: RootCallTarget, type: Type, section: Section = Section.default): Lam { + fun lam(callTarget: RootCallTarget, type: Type, loc: Loc? = null): Lam { val root = callTarget.rootNode assert(root is ClosureRootNode) - return lam((root as ClosureRootNode).arity, callTarget, type, section) + return lam((root as ClosureRootNode).arity, callTarget, type, loc) } // package a foreign root call target with known arity @Suppress("NOTHING_TO_INLINE") - fun lam(arity: Int, callTarget: RootCallTarget, type: Type, section: Section = Section.default): Lam { - return lam(null, noFrameBuilders, arity, callTarget, type, section) + fun lam(arity: Int, callTarget: RootCallTarget, type: Type, loc: Loc? = null): Lam { + return lam(null, noFrameBuilders, arity, callTarget, type, loc) } @Suppress("NOTHING_TO_INLINE","unused") - fun lam(closureFrameDescriptor: FrameDescriptor, captureSteps: Array, callTarget: RootCallTarget, type: Type, section: Section = Section.default): Lam { + fun lam(closureFrameDescriptor: FrameDescriptor, captureSteps: Array, callTarget: RootCallTarget, type: Type, loc: Loc? = null): Lam { val root = callTarget.rootNode assert(root is ClosureRootNode) - return lam(closureFrameDescriptor, captureSteps, (root as ClosureRootNode).arity, callTarget, type, section) + return lam(closureFrameDescriptor, captureSteps, (root as ClosureRootNode).arity, callTarget, type, loc) } // ensures that all the invariants for the constructor are satisfied @Suppress("NOTHING_TO_INLINE") - fun lam(closureFrameDescriptor: FrameDescriptor?, captureSteps: Array, arity: Int, callTarget: RootCallTarget, type: Type, section: Section = Section.default): Lam { + fun lam(closureFrameDescriptor: FrameDescriptor?, captureSteps: Array, arity: Int, callTarget: RootCallTarget, type: Type, loc: Loc? = null): Lam { assert(arity > 0) val hasCaptureSteps = captureSteps.isNotEmpty() assert(hasCaptureSteps == isSuperCombinator(callTarget)) { "mismatched calling convention" } @@ -314,7 +312,7 @@ abstract class Code(val section: Section = Section.default) : Node(), Instrument arity, callTarget, type, - section + loc ) } } diff --git a/src/cadenza/jit/frame_builder.kt b/src/cadenza/jit/frame_builder.kt index fac67d6..d5dfac1 100644 --- a/src/cadenza/jit/frame_builder.kt +++ b/src/cadenza/jit/frame_builder.kt @@ -37,7 +37,6 @@ abstract class FrameBuilder( } protected fun allowsBooleanSlot(frame: VirtualFrame) = allowsSlotKind(frame, FrameSlotKind.Boolean) - protected fun allowsIntegerSlot(frame: VirtualFrame) = allowsSlotKind(frame, FrameSlotKind.Int) // UnexpectedResultException lets us "accept" an answer on the slow path, but it forces me to give back an Object. small price to pay diff --git a/src/cadenza/loc.kt b/src/cadenza/loc.kt new file mode 100644 index 0000000..adacc3d --- /dev/null +++ b/src/cadenza/loc.kt @@ -0,0 +1,19 @@ +package cadenza + +import com.oracle.truffle.api.source.Source +import com.oracle.truffle.api.source.SourceSection + +sealed class Loc() { + abstract fun section(source: Source): SourceSection + object Unavailable : Loc() { + override fun section(source: Source): SourceSection = source.createUnavailableSection() + } + data class Range(val start: Int, val length: Int) : Loc() { + override fun section(source: Source): SourceSection = source.createSection(start, length) + } + data class Line(val line: Int) : Loc() { + override fun section(source: Source): SourceSection = source.createSection(line) + } +} + +fun Source.section(loc: Loc): SourceSection = loc.section(this) \ No newline at end of file diff --git a/src/cadenza/section.kt b/src/cadenza/section.kt deleted file mode 100644 index d65fcd2..0000000 --- a/src/cadenza/section.kt +++ /dev/null @@ -1,21 +0,0 @@ -package cadenza - -import com.oracle.truffle.api.source.Source -import com.oracle.truffle.api.source.SourceSection - -const val NO_SOURCE = -1 -const val UNAVAILABLE_SOURCE = -2 - -// Source + Section = SourceSection -- we are in java -data class Section(val sourceCharIndex: Int, val sourceLength: Int) { - companion object { - val default = Section(NO_SOURCE, 0) - val unavailable = Section(UNAVAILABLE_SOURCE, 0) - } -} - -fun Source.section(section: Section): SourceSection? = when (section.sourceCharIndex) { - UNAVAILABLE_SOURCE -> createUnavailableSection() - NO_SOURCE -> null - else -> createSection(section.sourceCharIndex, section.sourceLength) -} \ No newline at end of file diff --git a/src/cadenza/semantics/terms.kt b/src/cadenza/semantics/terms.kt index 1bca7ea..6b80be5 100644 --- a/src/cadenza/semantics/terms.kt +++ b/src/cadenza/semantics/terms.kt @@ -1,8 +1,7 @@ package cadenza.semantics import cadenza.jit.Code -import cadenza.Section -import cadenza.todo +import cadenza.* import com.oracle.truffle.api.frame.FrameDescriptor typealias Ctx = Env @@ -23,15 +22,15 @@ abstract class Term { companion object { @Suppress("unused") - fun tvar(name: String, section: Section = Section.default): Term = object : Term() { + fun tvar(name: String, loc: Loc? = null): Term = object : Term() { @Throws(TypeError::class) override fun infer(ctx: Ctx): Witness = object : Witness(ctx.lookup(name)) { - override fun compile(fd: FrameDescriptor): Code = Code.`var`(fd.findOrAddFrameSlot(name), section) + override fun compile(fd: FrameDescriptor): Code = Code.`var`(fd.findOrAddFrameSlot(name), loc) } } @Suppress("unused") - fun tif(cond: Term, thenTerm: Term, elseTerm: Term, section: Section = Section.default): Term = object : Term() { + fun tif(cond: Term, thenTerm: Term, elseTerm: Term, loc: Loc? = null): Term = object : Term() { @Throws(TypeError::class) override fun infer(ctx: Ctx): Witness { val condWitness = cond.check(ctx, Type.Bool) @@ -40,14 +39,14 @@ abstract class Term { val elseWitness = elseTerm.check(ctx, actualType) return object : Witness(actualType) { override fun compile(fd: FrameDescriptor): Code { - return Code.If(actualType, condWitness.compile(fd), thenWitness.compile(fd), elseWitness.compile(fd), section) + return Code.If(actualType, condWitness.compile(fd), thenWitness.compile(fd), elseWitness.compile(fd), loc) } } } } @Suppress("unused") - fun tapp(trator: Term, vararg trands: Term, section: Section = Section.default): Term = object : Term() { + fun tapp(trator: Term, vararg trands: Term, loc: Loc? = null): Term = object : Term() { @Throws(TypeError::class) override fun infer(ctx: Ctx): Witness { val wrator = trator.infer(ctx) @@ -63,7 +62,7 @@ abstract class Term { return Code.App( wrator.compile(fd), wrands.map { it.compile(fd) }.toTypedArray(), - section + loc ) } } @@ -71,6 +70,6 @@ abstract class Term { } @Suppress("UNUSED_PARAMETER","unused") - fun tlam(names: Array, body: Term, section: Section = Section.default): Term = todo + fun tlam(names: Array, body: Term, loc: Loc? = null): Term = todo } } \ No newline at end of file diff --git a/src/parser.kt b/src/parser.kt index b2d474f..b1f950d 100644 --- a/src/parser.kt +++ b/src/parser.kt @@ -6,12 +6,8 @@ import java.util.regex.Matcher import java.util.regex.Pattern class ParseError(var pos: Int, message: String? = null) : Exception(message) { - constructor(pos: Int, message: String? = null, cause: Throwable): this(pos,message) { - initCause(cause) - } override fun fillInStackTrace() = this // don't record companion object { const val serialVersionUID : Long = 1L } - override fun toString(): String = message ?: super.toString() } data class Expected(val what: Any, val next: Expected?)