Hacker News new | ask | show | jobs
by foobar_ 2226 days ago
That was a short and epic read.

> This limited both the language features that were possible and the quality of the produced code.

What are the limitations ?

1 comments

Older versions of C had the restriction that variables could only be declared at the start of a block. Supposedly this was due to the original C compiler being one-pass. It's easier to keep track of the size of the stack frame if you see all declarations in one place. Though I think with a frame pointer you could make it work anyway. You have essentially the same complications if you allow programmers to open a block anywhere and declare variables there. I don't know if the very first versions of C allowed this.

Maybe more exotically, here is a legal Haskell program:

    compute = f x y
    x = 3
    y = 4
    f = (+)
Using typed identifiers before they are declared would not be possible in a single-pass compiler. You wouldn't know what code to emit for compute since you wouldn't even know its type until you have seen the definitions of x, y, and f.

Interestingly, this restriction does not apply to goto labels, which you can use first and define later: The compiler can just emit the label as written into the assembly code and let the assembler worry about patching up the jump target.

> Interestingly, this restriction does not apply to goto labels, which you can use first and define later: The compiler can just emit the label as written into the assembly code and let the assembler worry about patching up the jump target.

A one-pass compiler can manage this by maintaining a mapping of undefined labels to a list of goto statements that refer to them. Once the definition is located, unwind the list and fill in the jump values. Types are trickier because the size is unknown.

There is no way to "fill in the jump values" if you have already emitted the goto to a place you can't modify later. Like the featured article does, emitting its code with printf. I agree that you could emit code to an intermediate buffer, fix it up later, and still call this (a slightly more relaxed version of) one-pass compilation.
Fair point... kinda feels like passing the buck, but not having that memory overhead is nice
>Older versions of C had the restriction that variables could only be declared at the start of a block.

Pascal also has that restriction

Although Delphi does not have it anymore. But FreePascal still has it, even in Delphi compatible mode. The FreePascal developers have also said, they will keep that restriction to improve readability. The code could not be read anymore if variables were placed willy-nilly everywhere

I’ve heard the readability justification for C restriction, but it doesn’t make sense: this prevent ´constification’ of variables (make the variable contains only one value)..
I wonder if Delphi still a one pass compiler?