Live data from Hacker News

One-pass Compiler

keleshev.com

1–10 of 44 posts

Re: One-pass Compiler

#2
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 ?

Re: One-pass Compiler

#3
post #2

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 ?

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.

Re: One-pass Compiler

#5
post #2

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 ?

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…

> 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.

Re: One-pass Compiler

#6
The author states:

>"An optimizing compiler would constant-fold our expression into a single number ahead of time."

Could someone say what is meant by constant-folding here?

Re: One-pass Compiler

#7
I'm actually working on a Pascal compiler right now. Register management has been a really tricky part for me, but I didn't even thing of treating an x86 processor as a stack based machine. Very clever, especially when you just want a simple compiler an not anything super optimized.

Re: One-pass Compiler

#8
post #5

Earlier quoted context omitted.

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…

> 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 a…

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.

Re: One-pass Compiler

#9
post #6

The author states: >"An optimizing compiler would constant-fold our expression into a single number ahead of time." Could someone say what is meant by constant-folding here?

Basically you have all the info you need at compile time, so you just do the work then rather than having to do it every time while the program is running.

Ex: 4 + 4 would be condensed down to just 8 at compile time rather than writing the code to get 4 and 4 both into registers and add them at execution time.

Re: One-pass Compiler

#10
post #6

The author states: >"An optimizing compiler would constant-fold our expression into a single number ahead of time." Could someone say what is meant by constant-folding here?

https://en.wikipedia.org/wiki/Constant_folding: "Constant folding is the process of recognizing and evaluating constant expressions at compile time rather than computing them at runtime. Terms in constant expressions are typically simple literals, such as the integer literal 2, but they may also be variables whose values are known at compile time. Consider the statement:

    i = 320 * 200 * 32;
Most compilers would not actually generate two multiply instructions and a store for this statement. Instead, they identify constructs such as these and substitute the computed values at compile time (in this case, 2,048,000)."
Post reply on HN