_       _ _ _    _ _ 
| |     (_|_) |  (_) |
| | ___  _ _| | ___| |
| |/ _ \| | | |/ / | |
| | (_) | | |   <| | |
|_|\___/| |_|_|\_\_|_|
       _/ |           
      |__/           
    purveyors of fine, internet-related kipple since 1985.
    

. » p » lpn » 3 » index.txt
So, this is one of my more, uh, interesting adventures.
Basically, my laptop at work (edit: spelling; thanks Lord of the Dance!) died, and our fear-less admin (and resident Lord of the Dance) requested that I try Western Digital's hard disk analyzer. Well, interestingly enough, that utility requires a FreeDOS install, which I put on a spare 1GiB USB stick. Well, that got me thinking: what else can I do with a spare FreeDOS install? Well, I can put FreePascal on it! That would make it super useful!
So, thus armed, I set out to write some neat stuff for FreeDOS... and promptly hit a wall: the FreePascal IDE wouldn't load! I don't recall what the error was, but naturally my next step was to check if the compiler would work, which it did. "Well, that should be enough..."
My First step was a simple "hello world!" type of program:
program foo;
begin
    writeln("Hello, world");
end.


Can you spot the bug? Suffice it to say that I haven't written Pascal in some time, & forgot that Strings are ' ' delimited rather than " " delimited; the above was quickly followed by:
program bar;
begin
    writeln('Hello, world!');
end.


The fun part about this is that I wrote them line-by-line using GECHO; the built in DOS-echo didn't handle strings properly.
(Although, thinking about it, I wonder if I could have used something like TYPE CON... Have to try that later). Basically I wrote way too many lines of:
C:\WORK>\fpc\bin\go32v2\gecho "program foo;" > foo.pas
C:\WORK>\fpc\bin\go32v2\gecho "begin" >> foo.pas
...


As you may imagine, that was slow going :D
Having written a "Hello, world" that I could compile, my next thought was to write something akin to cat, where it would read from STDIN (or Input in Pascal) and write to STDOUT. I don't know if I screwed something up, but EOF was not working for me (I would hit ^Z and it would keep going; I probably mistyped something), so my cat replacement reads until it hits . byitself on a line, like ed does:
 program dog(input, output);
var s: string;
begin
    readln(s);
    while s <> '.' do 
    begin
        writeln(s);
        readln(s);
    end;
end.


The code is simple, and I hand formatted it, but mostly so that I could attempt to read it later. Personally, I like the idea of Pascal/Algol, but I do find the lack of symbols a bit disorienting at times, so I do like to have it nicely formatted.
Armed with that code, I set out to write a simple prompt test:
 program prompttest(input, output);
var
    s : string;
begin
    write('> ');
    readln(s);
    while s <> 'q' do
    begin
        writeln('s is ', s);
        write('> ');
        readln(s);
    end;
end.


Having written that, I finally set out to write a very basic editor, which I dubbed "ZDLIN". I can't tell you how many times I had to type this in; after getting the p and i commands to work, it was a devil of a time to retype the whole thing in order to add commands. I was thinking about adding a handful of other small utilities, like head and tail, to help with the process, but eventually I just soldiered on & wrote it out:
program zdlin(input, output);
uses
    Classes, SysUtils;
var
    buffer : TStringList;
    line, src : string;
    idx, tmp0, tmp1, tmp2 : integer;
begin
    buffer := TStringList.create;
    src := ParamStr(1);
    buffer.LoadFromFile(src);
    idx := buffer.count - 1;
    write('> ');
    readln(line);
    while line <> 'q' do
    begin
        if line = 'p' then
        begin
            if idx > 0 then
            begin
                for tmp0 := 0 to idx do
                begin
                    writeln(buffer[tmp0]);
                end;
            end;
        end
        else if line = 'P' then // should prompt for a range
        begin
            if idx > 0 then
            begin
                for tmp0 := 0 to idx do
                begin
                    writeln(inttostr(tmp0),': ', buffer[tmp0]);
                end;
            end;
        end
        else if line = 'd' then
        begin
            write('at: ');
            readln(line);
            Val(line, tmp0, tmp1);
            buffer.delete(tmp0);
            Dec(idx);
        end
        else if line = 'D' then
        begin
            write('start: ');
            readln(line);
            Val(line, tmp0, tmp1);
            write('end: ');
            readln(line);
            Val(line, tmp1, tmp2);
            for tmp2 := tmp0 to tmp1 do
            begin
                buffer.delete(tmp0); // buffer shrinks each time
            end;
            idx := buffer.count - 1;
        end
        else if line = 'I' then
        begin
            write('at: ');
            readln(line);
            Val(line, tmp0, tmp1);
            readln(line);
            tmp1 := tmp0;
            while line <> '.' do
            begin
                buffer.insert(tmp0, line);
                Inc(tmp0);
                readln(line);
            end;
            Inc(idx, tmp0 - tmp1);
        end
        else if line = 'i' then
        begin
            readln(line);
            while line <> '.' do
            begin
                idx := buffer.add(line);
                readln(line);
            end;
        end
        else
            writeln('Unknown command: ', line);
        write('> ');
        readln(line);
    end;
    buffer.SaveToFile(src);
    buffer.Free;
end.


As you can see, there is no command parsing what so ever; commands are simply p or P, and the user is then prompted for any other parameters as necessay. Though basic, it should be enough to implement Bigthingist's idea, and make something more visual. Of course, as I replied, I would be interested in trying to make something Sam-like as a test. And, of course, I'd like to make a Digamma Runtime; Retargetting Enyalios for FreePascal shouldn't be too difficult; I'd be more concerned about it being too large for memory though :D
The files mentioned above can be downloaded below:

Home | About | Blag | Lojikil's Programmer Notebook | Projects | Twitter | Github | BitBucket