Given a proficient developer with 10-20 years of experience that has never built either a compiler or an emulator, which would be more of challenge?
Could you compare the issues that would be road blocks for either.
Thanks.
Given a proficient developer with 10-20 years of experience that has never built either a compiler or an emulator, which would be more of challenge?
Could you compare the issues that would be road blocks for either.
Thanks.
Writing a compiler is a LOT harder, since you're dealing with much lower level stuff (linking, assembly that's specific to your architecture, etc).
An emulator just has to perform the logic of each instruction fed to it (and I know I'm simplifying this, but I assume you have the specs for the instruction set), now, writing a FAST emulator is MUCH harder.
It depends largely on what you are emulating, and what you are compiling.
I've written both and would say that an emulator is generally easier. Of course, this depends greatly on what you are trying to emulate (emulating an IBM mainframe on an iPhone might be a bit of a challenge) and what you are trying to compile (a small C compiler is pretty easy, a full C++ compiler almost impossibly difficult.
In my opinion a complex compiler is more difficult to write than a complex emulator for the simple reason that the compiler involves much more theory.
When designing your language XX there is a whole lot of factors to consider not to mention optimizing the output of the compiler generated code which is a black art in itself. With an emulator you have an already well-defined environment with a mostly well-defined language that you want to implement.
In any case I recommend anybody to write and write a compiler because it gives you a deeper understanding of programming, just like doctor needs to know about the body anatomy even though he may not need it in his daily work.
EDIT: I think both skills are very useful and one can actually combine them - they are not XOR.
I would like to add to my opinion above is that creating a non-trivial programming language including runtime-libraries to interact with drivers, databases etc and that can evolve with future versions but still remain backwards compatible is one of the more challenging areas in CS.
I also agree that if the platform is unknown i.e. you are reverse engineering something then it is much more difficult to do an emulator, but OTOH that is not what OP's question was about, was it?
I have written both and would say that other things being equal (complexity of language or instruction set), it is way easier to write an emulator, especially if you are trying to write an interesting emulator or compiler.
The reason is that with an emulator you are trying to simulate a low-level thing with another, similar low-level thing. It's not too bad. With a compiler, you may be trying to implement very high-level ideas (e.g., objects, first-class functions, managed memory, string scanning) with very low level tools (machine words and machine instructions). This task is just a lot harder.
Of course, for gangs of fun, you can write an emulator that works by dynamic binary translation, which is the compilation of machine code for the emulated architecture into the machine code for the native architecture. This way you get to have all the fun of both---and yo produce really fast emulators like QEMU or the late lamented Digital FX!32.
Emulation and compilation are quite different, but tend to get lumped together because of both being considered "low-level".
Emulation of a simple architecture such as a 6502 or Z80 will be fairly straightforward for the CPU chunk of the work, but there will be a fair chunk of code to write since you need to have a function for each instruction. You'll want to automate this in some way, from an instruction set specification with all the timings and such, as typing this all out will be very tedious indeed :) Old CPU instruction set specs are easy to find, so this helps a lot when building emulators.
On top of that you'll need to implement some level of hardware emulation, which usually involves handling and generating interrupts (such as the vertical-blank interrupt of a display device if the emulator is for a game console, say). This again will need some level of specification and code generation, but you'll likely have to write most of this by hand as it's not going to be quite so repetitive (and hence automatable) as the instruction set code.
Compilation will involve some sort of language spec of whatever language you are going to be implementing the compiler for, and a target which you will be aiming to output code for. The output could be straight to binary, could be assembly or could even be another language (this is really just a translator, but it counts as compilation when the target is considered "sufficiently" low-level). Since you'll be running on some sort of hardware or VM platform then you will be unlikely to have to worry about interrupt handling and that sort of thing.
Stumbling blocks for both are complexity and correctness -- for the emulator you'll need to make it work very accurately unless you pick very simple things to emulate. You'll also need to create some sort of integrated debugger for the emulator, otherwise it's close to impossible to tell what is going wrong when it invariably does so. For a compiler it should be fairly straightforwward to translate a toy language or a small subset of a more complex language, and build it up as you go along.
Remember, that with both of these items you need to be able to produce input to test them, and if you cannot produce simple inputs then you'll find it very difficult to get debug from the very beginning. This alone makes compiler work easier to get into, imho (That and that you'll want to have something which emulates a full console or something straight away :)
The emulation of software is pretty straight-forward and so relatively easy, but can be tedious.
Writing a compiler can be very hard, but it is made simpler by either having a good working-knowledge or by having a good set of specifications (e.g. Backus-Naur Form notation) of the language you are writing the compiler for.
The emulation of hardware can be extremely difficult if your goal is to make the emulator work on many different platforms (e.g. running the emulation of a floppy-disk drive's timing might work under MSDOS using the correct fudge constants, but the emulation fails on a multi-tasking platform like Vista or Linux). Hardware emulation is also extremely difficult when insufficient knowledge is available about how its mode of operation is controlled by software. This forces long and annoying reverse-engineering before progress can be made.
All in all, I judge emulation to be the more difficult.
Writing an emulator for a known emulated platform is not that hard (you can also use a pre-made CPU emulator and gain some development time).
Writing an emulator for unknown emulated hardware is much harder, and shifts the difficulty to fields different from code-development: maths, cryptoanalysis, security protocols, etc. And, as a developer, you gotta have patience for the trial-and-error involved in the process.
As an example, just think of how much time CPS2 emulation required (CPS2 ROMs were encrypted).
Out of context, there can be no definite answers: it all depends on what you want to achieve, and what you're competing against.
If it's just a "proof of concept", then in both cases, it's fairly simple.
But if you're trying to emulate a complex hardware or with high accuracy, or if you want to achieve AAA compilation quality, things can quickly become of ugly complexity. The complexity will appear not just in the algorithms/theory of the "main" code, but also in all the support tools you'll have to build (debuggers, disassemblers, profilers, etc.) so you can advance to the next step.
That said, another aspect to consider is that writing a working compiler for just about any programming language out there is of reasonable complexity. On the other hand, if there is hardware out there that is trivial to emulate, there is also hardware for which writing even a basic emulator can be very complex.
So painting with a broad brush, I would say writing a compiler is easier, because you're pretty much guaranteed to succeed at getting a working version, regardless of the target hardware or language. There is no such guarantee for an emulator.