#lang racket/base

(provide (struct-out embedded)
         map-embeddeds)

(require racket/match)
(require racket/set)
(require racket/dict)
(require "record.rkt")
(require "annotation.rkt")

(struct embedded (value) #:transparent)

(define (map-embeddeds f)
  (define (walk v)
    (match v
      [(embedded v) (f v)]
      [(annotated anns srcloc item) (annotated (map walk anns) srcloc (walk item))]
      [(record label fields) (record (walk label) (map walk fields))]
      [(? list? vs) (map walk vs)]
      [(? set? vs) (for/set [(v (in-set vs))] (walk v))]
      [(? dict? vs) (for/hash [((k v) (in-dict vs))] (values (walk k) (walk v)))]
      [other other]))
  walk)
