
Show HN: My Turbo Pascal compiler in JavaScript - lkesteloot
http://www.teamten.com/lawrence/projects/turbo_pascal_compiler/demo/
======
ret
Your project is great, Pascal is really underrated language.

I looked at parser (hand written are best), this part spotted my eyes
[https://github.com/lkesteloot/turbopascal/blob/master/Parser...](https://github.com/lkesteloot/turbopascal/blob/master/Parser.js#L487)
\- IMHO order of checking whatever node is identifier or not have to be
reversed. Now, such simple program:

program Test;

procedure foo; begin end;

begin foo := 10; end.

produces error 'Error: can't cast from 70 to 76 ("10", line 8)' \- whatever
this means. :)

~~~
lkesteloot
Well the error message is confusing (it's trying to cast from an integer (type
70) to a procedure (type 76)), but it's correct to fail to compile. But yeah
I'm not sure that my logic there is altogether correct. I re-wrote it a few
times as I found new cases that weren't correctly handled. Specifically, I'm
not sure whether the type of the identifier should guide the parsing. It's
similar to the "x*y" ambiguity in parsing C (multiplication or declaration of
pointer variable y).

------
pjmlp
Very nice indeed.

It was a pity that C took over the PC world as it did, Turbo Pascal could do
everything better than it, including being safe by default, modules, OO.

Why Borland, why!

~~~
pmelendez
I never liked Pascal verbosity back in school but I loved C right away...
Maybe it is just a matter of taste?

~~~
pjmlp
I never understood the complaints about verbosity in Pascal languages and the
escape to C, Perl and friends.

Why not use APL then?

Programs are to be read, not to be write-only.

~~~
kaoD
Pascal verbosity does not add information, but noise. As humans, we recognize
symbols and structures better than words. {} as delimiters make much more
sense than BEGIN/END.

~~~
JasonFruit
I always thought there was a use for something like RATFOR for Pascal; maybe
Ratscal? It could have left most of the verbosity in place, but replaced the
BEGINs and ENDs with { and }, and that would have made it an almost perfect
language from my point of view.

~~~
telephonetemp
Nimrod is a lot like a modernized Pascal with a Python-like syntax.

------
analog31
Very nice! Now I've got to see if my old floppies are still readable.

While in college, I got myself an oddball MS-DOS computer. My dad read an
article in the business pages about this guy who had the audacity to market a
complete software product for 39 bucks. Dad didn't know anything about
computers, except that there was growing interest in programming, so he got
Turbo Pascal version 1 for me as an Xmas present. That was the original
version, and I stuck with Turbo Pascal through successive revisions until 1994
when I discovered HyperCard on an Apple Mac.

In my view, among the strengths of TP, its manuals shouldn't be overlooked.
Each version came with a relatively slim yet complete manual that a person
could actually read. Of course it helped that the target platform was
relatively simple too.

~~~
lkesteloot
I agree, the manuals were great. (Though I bought them again on eBay for this
project and they actually contained a lot of errors!) But also the floppy came
with sample programs, and I learned most of Pascal from those.

------
cek
I forwarded this to Anders Hijlsberg [1]. It'd be fun if he commented on this
here.

I cut my programming teeth on Pascal and Turbo Pascal. This is hugely
nostalgic for me!

[1][http://en.wikipedia.org/wiki/Anders_Hejlsberg](http://en.wikipedia.org/wiki/Anders_Hejlsberg)

~~~
mseepgood
Maybe he will rewrite it in TypeScript?

------
optymizer
Pascal, my childhood love. I spent so many days in TP 7.1 coding games with
the graph library!

At some point I made a GUI for DOS, similar to Windows Explorer (with a
desktop, icons, start menu, context menus and obligatory clock! :) ).

I called it Winnie. Then my 386 died and I lost the code :/

Thanks for the memories!

------
soapdog
OMG!!! That was my favorite TP. I learned to program using Turbo Pascal.

Congratulations on your work and thanks for the nostalgia!

~~~
FYI
Likewise!

I started in Basic then moved to Turbo Pascal so I could compile my code &
distribute it - mostly on 5.25" floppies as cover disks on magazines.

Later by uploading them to BBSes via a 9600bps modem (yes 9.6Kbps was super
quick in those days)!

~~~
pjbrunet
Pretty much the same here. I purchased Borland TP5 in high school which was
the first version with "OOP" but I think we were using versions 3 & 4 at
school which were also nice.

The equivalent of WordPress back then was Telegard which was written in
Pascal. The sourcecode got loose which resulted in several spin-off "Telegard
hacks" and many of the "elite" BBS where essentially themed versions of that
original Telegard.

Then I heard Pascal morphed into Delphi? I never made it to Delphi. By 1994 I
was into Javascript, Java, Rexx and best of all the opposite sex ;-)

------
pjbrunet
Seriously cool. But I can't imagine ever using it ;-) Half the fun of TP was
all the libraries, like to interface Souldblaster, modems, etc. All that stuff
is long gone.

------
JasonFruit
Very slick. I'm impressed at the compilation speed, given that it's in
JavaScript and I'm on a slow machine. Pascal always was good for that — and
you've made me miss it.

------
sina
Great work, well done! Pascal was the second language I learned, after Basic.

I'm interested in studying the code and possibly replicating it for the
purpose of learning about how compilers work. Could you give a general
overview of the components, or steps you took to implement them? Thanks!

~~~
lkesteloot
Thanks! The code is on GitHub:
[https://github.com/lkesteloot/turbopascal](https://github.com/lkesteloot/turbopascal)

It's a two-pass compiler. The first pass runs the code through the Stream,
Lexer, and Parser classes to generate a parse tree (with type information).
The second pass generates bytecode using the Compiler class. The compiled
bytecode is then handed to Machine to execute. Start in IDE.js in the _run()
function. Also go into turbo.css and comment out the "display:none" line in
the .debug-output block. That'll let you see the parse tree and generated
bytecode.

~~~
paulrademacher
> see the parse tree and generated bytecode

Make that a feature!

~~~
lkesteloot
Done! Try the hidden "X" command.

------
ChuckMcM
Nice, presumably you take the x86 emulator from yesterday, and boot it with a
copy of the TurboPascal disk?

Took me a good 30 minutes to remember how to write hello world in PASCAL :-)
And I admit I forgot about the period on the End statement.

~~~
danieldk
I found more details here, including a link to the source code:

[http://www.teamten.com/lawrence/projects/turbo_pascal_compil...](http://www.teamten.com/lawrence/projects/turbo_pascal_compiler/)

Well done!

~~~
ChuckMcM
That is awesome, somewhere I've got a pretty printer I developed for
TurboPASCAL. I tried to sell all the rights to Borland in exchange for a
enough cash to buy a decent oscilloscope (I have a history of 'consulting for
toys' :-)and they weren't going for it. In hindsight (much later) I realized I
should have set the price really high, let them try a demo with a non-
refundable deposit of 10% of the price, and then feigning sadness when they
decided not to proceed :-)

------
pjmorris
Boy, does that bring back memories. Turbo Pascal was just plain wonderful
software. As for Pascal, I never got over the array length being part of the
array's type.

~~~
MilesTeg
I remember you could define an array to be indexed by an enumerated type which
was nice. I haven't seen that done elsewhere.

~~~
pjmlp
At least in Ada, Modula-2, Modula-3 it is also possible.

------
fit2rule
Nice! I still have an Atari Portfolio in my kit, running Turbo C 1.0 .. those
were the days! Everything you needed to rule the world in a single .EXE. Or ..
was it a .COM? 64k should've been enough for everyone .. ;)

------
ooooak
/* set overflow to auto */ #screen { overflow: auto; }

~~~
lkesteloot
:-)

------
paulrademacher
The examples compile super fast. How long did it use to take?

~~~
kristiandupont
..Turbo Pascal was sort of shocking, since it basically did everything that
IBM Pascal did, only it ran in about 33K of memory including the text editor.
This was nothing short of astonishing. Even more astonishing was the fact that
you could compile a small program in less than one second. It's as if a
company you had never heard of introduced a clone of the Buick LeSabre which
could go 1,000,000 MPH and drive around the world on so little gasoline than
an ant could drink it without getting sick.

[http://www.joelonsoftware.com/articles/fog0000000023.html](http://www.joelonsoftware.com/articles/fog0000000023.html)

I miss Joel's writing!

~~~
vidarh
It was only shocking to people used to complicated behemoths of multi-pass
compilers or complicated optimizing compilers with expensive internal
representations.

Turbo Pascal really mostly "only" does things the way Wirth used to: As simple
as possible. Wirth's languages are all designed for single pass compilation
with direct code generation, and if you write your compilers that way, they
will be fast. It is very, very hard not to make them fast that way.

His compiler textsbooks, all the way back to "Compilerbay" in 1977 (using PL/0
as the language) included full source code for compilers following that style,
and they're so small the entire compilers fit in a few handful pages.

(EDIT: just to make clear: I _do_ admire Turbo Pascal - I used it quite a lot,
but main the genius of Turbo Pascal was to pick the Wirth way of doing
compilers and integrate it with a simple "IDE" \- a large part of the amazing
impression of Turbo Pascal was that you did not have to write your code to
disk, exit the editor, run a compiler etc. but could do it all in one)

~~~
acqq
I remember that differently: on Z80 CPU machines, UCSD Pascal was slow. It
compiled to the p-code (it was both an "operating system and compiler" and
they wanted it portable). On the first PC's (8088 CPU), Microsoft's Pascal was
slow. It produced obj files. Turbo Pascal was lightning fast on both. It had
to be implemented contrary to beliefs common then: it was itself written in
asm, it was never just a compiler but the editor and compiler at once, kept
everything in memory if it could, produced the pure native code processor
specific and never produced obj files.

~~~
vidarh
UCSD Pascal was slow because the compiler was written in Pascal and compiled
to p-code itself (the source is available:
[http://techtransfer.universityofcalifornia.edu/NCD/19327.htm...](http://techtransfer.universityofcalifornia.edu/NCD/19327.html)
).

It was not a good benchmark. It was prevalent because it was trivial to port,
not because it was good.

(Note that UCSD Pascal was based on a part of Wirths research groups "porting
kit" \- their intent was not for p-code to be used for production systems, but
as an easy way of getting a Pascal compiler running on a new platform to be
able to then use the target platform while retargeting the code generator)

> It had to be implemented contrary to beliefs common then: it was itself
> written in asm,

That was nothing out of the ordinary at the time, though not something Wirth
himself did, as a large part of his mission was to teach the development of
compilers.

But compilers for small systems were often written in asm at the time. It'd
not be very viable to write compilers in high level languages for a C64 or
other home computers, for example, yet there were plenty of compilers for
small systems. When I wrote my first compilers on the C64 and a bit later on
the Amiga, it never even occurred to me to write them in a high level language
until a few years later (incidentally when I got HiSoft Pascal - an integrated
Pascal environment for the Amiga very much in the spirit of Turbo Pascal)

> it was never just a compiler but the editor and compiler at once, kept
> everything in memory if it could, produced the pure native code processor
> specific and never produced obj files.

That's _technically_ true, though the compiler that became Turbo Pascal was
actually originally a separate, stand alone compiler.

Combining the compiler with the editor _was_ fairly uncommon and certainly
innovative. When Kahn at Borland decided he wanted an environment like that,
though, he went out and bought an existing, standalone, commercial compiler,
from Anders Hejlsberg, and brought him to Borland.

Producing pure native code on the other hand was not unusual - UCSD's p-System
was an aberration in that respect, and it's greatest lasting legacy was in
inspiring VM based systems; e.g. Bill Joy has cited it as one of the
inspirations behind the JVM. Not producing object files was also quite common
- for many small systems there was no tradition of object files at all, as
they were too small for separate compilation to make much sense.

------
efutch
Nice, no Compile option though? Is it an interpreter? I tried a Hello, World,
and the (Input,Output) after the program name choked it. Nice job!

~~~
lkesteloot
The "Compile" option was, I think, for when you wanted to generate a .COM or
.EXE. So I don't support that. The "Run" command does compile and run, though.

~~~
dugmartin
If I remember right it was COM only until TP4.

~~~
lkesteloot
Yep!

------
pan69
This is cool. I remember having this on DOS in the late 80's. Never really got
into Pascal though.

------
kirkthejerk
Yay, I don't have to use ctrl-K codes like the original TP3 editor!

------
bowerbird
severely cool.

-bowerbird

