All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bitbucket.inkytonik.kiama.rewriting.Cloner.scala Maven / Gradle / Ivy

The newest version!
/*
 * This file is part of Kiama.
 *
 * Copyright (C) 2008-2021 Anthony M Sloane, Macquarie University.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package org.bitbucket.inkytonik.kiama
package rewriting

/**
 * Implementation of cloning operations. These operations must be mixed in
 * to an instance of the rewriting library which will then be used as the
 * underlying rewriting behaviour.
 */
trait Cloner {

    self : Rewriter =>

    import org.bitbucket.inkytonik.kiama.relation.TreeRelation.isLeaf

    /**
     * Deep clone the term `t`. Only applicable if the base type of the tree is
     * a `Product`.
     */
    def deepclone[T <: Product](t : T) : T = {

        val deepcloner =
            everywherebu(rule[Any] {
                case n: Product if isLeaf(n) =>
                    copy(n)
            })

        rewrite(deepcloner)(t)

    }

    /**
     * Lazily deep clone the term `t`; i.e., only clone sub-trees if they occur
     * elsewhere in the tree. Only applicable if the base type of the tree is a
     * `Product`. The `bu` argument specifies the strategy to use when traversing
     * the term. It should be a bottom-up traversal, but can be tailored to skip
     * some sub-trees if desired. `bu` defaults to `everywherebu`.
     */
    def lazyclone[T <: Product](
        t : T,
        bu : Strategy => Strategy = everywherebu(_)
    ) : T = {

        import org.bitbucket.inkytonik.kiama.util.Memoiser.makeIdMemoiser

        val seen = makeIdMemoiser[Product, Boolean]()

        val lazycloner =
            bu(rule[Any] {
                case n: Product if isLeaf(n) =>
                    if (seen.getOrDefault(n, false))
                        copy(n)
                    else {
                        seen.put(n, true)
                        n
                    }
            })

        rewrite(lazycloner)(t)

    }

}

/**
 * A cloner that uses non-memoising term rewriting.
 */
object Cloner extends Rewriter with Cloner




© 2015 - 2025 Weber Informatics LLC | Privacy Policy