I keep forgetting how many early machines were drum computers, back then.
That makes the PDP -1 more impressive as it used CORE memory.
Algol is harder to implement with blocks, and block variables, than fortran
making it even more impressive.
There was also the high-speed drum for the pioneering PDP-1 timesharing systems at BBN and the one by John McCarthy at MIT, based on Ed Fredkin’s idea of interleaving the backup to and from the drum (as required for user switching) with core memory access (thus zero latency). Made a reality by a young engineer going by the name of Gordon Bell. (So, these two machines were both core memory and kind of a drum computer…)
Regarding FORTRAN, the real impressive part (which also required the numerous passes) was that the compiler worked out the optimal register allocation for a given problem. I actually don’t know, if any Algol compilers tried to schieve this as well.
The Burroughs B5000 ALGOL compiler achieved optimal register allocation, but it did that by targeting an architecture that was designed specifically for ALGOL, which in turn had registers dedicated to specific purposes. In word mode (where regular ALGOL code ran) user-level software had no access to any registers except top-of-stack, which was more of a concept than a register.
In character mode, which was available in ALGOL using an extension called Stream Procedures, user-level code had direct access to several address and data registers, but character mode was very much an afterthought added to the architecture to provide better support for COBOL. It was very useful in ALGOL programs, but you had to know what you were doing and be very careful with it.
The B5000/B5500 wasn’t a perfect architecture for ALGOL – it had some serious flaws, including character mode – but most of those were fixed in it’s successor B6500/6700/7700 systems.
If by “linked list” you mean an arrangement where the stack frames were separately allocated and linked by activation history, then no. It’s possible some interpreters or virtual machines may have done so (especially JavaScript, to handle closures).
The Burroughs stack architecture used a contiguous area of memory for the stack (and non-pageable at that). In the B5000/5500, each stack frame had two control words at their base, one to link back to the base of the caller’s stack frame (to restore the address register that pointed to that frame), and one with the return address in the caller’s code segment.
Starting with the B6500, there were two linkages, one the base of the caller’s stack frame as before, and one to the base of the stack frame for the next lower lexicographical level (i.e., the stack frame for the calling procedure’s parent block). These were always in the same contiguous stack area, except in two cases:
Every running task had two stacks, one for the task itself, which was used for global and local variables, procedure call history, and push-down expression evaluation. This was termed the D2 or data stack. The second was a stack for the code file, which contained read-only values and descriptors for the various code segments. It was used only as an addressing environment and not for procedure history or expression evaluation. This was termed the D1 stack or segment dictionary. Since everything in the D1 stack was immutable, this provided implicit re-entrancy. If multiple copies of the same program (code file) ran at the same time, they all shared the same D1 stack.
In the block-structured languages such as ALGOL, a task could initiate one of its procedures as a dependent asynchonous task. The asynchronous task received its own D2 stack, but the lowest stack frame in that stack had pointers back to the frame for the initiating procedure and to the frame for the asynchronously-initiated procedure’s lexicographical parent. This was a recursive capability, so sub-tasks could initiate other sub-tasks, producing a tree of stack structures known as a “cactus stack,” after the shape of the saguaro cactus.