Domain-Specific Languages (DSLs) have the potential to make it dramatically easier to produce high-quality software in a timely and cost-effective manner. This potential has been difficult to realize, however, because DSLs require so much work to build. One way to mitigate this cost is to embed the DSL in a general-purpose host language. Embedded DSL programs are compiled down to the host language, where a complete suite of tools already exists. The problem with this strategy is that the host tools work at the host language's level of abstraction, essentially forcing the programmer to perform tasks such as debugging and profiling on the implementation of the DSL, which is often totally unrecognizable. The goal of this project was to develop a set of techniques and tools that make it easier for DSL designers to build first-class domain-specific languages, which come equipped with a full suite of support tools that operate at the level of abstraction of the domain. Users of these DSLs will get the productivity and code quality benefits of DSLs throughout the development lifecycle, from editing and compiling to debugging and profiling. Our approach uses an embedding strategy in order to continue to obtain other benefits from the host language, including general-purpose programming, access to existing libraries, and the possibility of employing multiple embedded DSLs within a single application.