samiam95124 / Pascal-P6

6th version of Niklaus Wirth's original Pascal language compiler system
Other
28 stars 9 forks source link

10/10: First gen module #1

Closed samiam95124 closed 2 months ago

samiam95124 commented 6 years ago

Starting off the next project, which is a 80386 (32 bit) code generation facility for P6. This is very preliminary, and the code and the documentation are subject to change. If you would like to help, that would be encouraged. I have committed a preliminary code module, pgen_gcc_i80386.pas. The documentation has also got a new section that discusses the project, so if you want to know more, read that.

samiam95124 commented 6 months ago

Problems

I was able to see a result of Pascaline regression test. Unfortunately, while trying to commit that result, I found that the normal regression didn't run. Further investigation showed that it had failed for about 4 commits, and tracked back, via bisection, to the 0dcf3623a9a39ab53e085c6bdfe902b49cf4ada7 commit. This means it failed on psystem reset primitives. I am working to fix.

The binaries crash[1] was able to be fixed by using the cached iso7185 host binaries, stored about 2 or 3 commits ago. This is the first serious test of the admittedly ad-hoc but functional compiler loop crash system(s), and it illustrates two improvements that need to happen going forward. I clearly lost control of the regression/commit process.

  1. Need to return to (passing) regression on every commit as possible.
  2. Need to update the binaries cache on each host every time, not just occasionally.

[1] "compiler loop crash" is where the basic system needed for the compiler to generate itself are corrupted. This would be the pcom and pgen programs. The fallback for this are the binaries cache by host, and of course git commits.

samiam95124 commented 6 months ago

Update

Issue fixed, all binaries updated, regression run.

samiam95124 commented 6 months ago

Update

Pascaline tests run substantially correct in pint, fail on fh2.

samiam95124 commented 6 months ago

Update

  1. Run Pascaline tests on pint/pmach/cmach. - Complete
  2. Fix Pascaline generation in pgen.
  3. Run Pascaline tests on pgen.
  4. Run diagnostic test on pint. - Complete.

Note this message is edited in place.

samiam95124 commented 6 months ago

Commit order of operations

Here is the commit order of operations and why it needs to be done in that order:

  1. Regress (successfully).
  2. Update_iso7185. This overwrites the cached copy of the host binaries, so needs to happen only after a successful regression.
  3. Commit/push to github. This always happens last.
samiam95124 commented 6 months ago

A debug trail of tears (adventures in debug)

So on the last commit, or attempt at commit, the regression went toes up. It was failing testp4. Looking at the trace, it was running standardp.pas (cut down version of iso7185pat.pas) on p4/pint, and the output showed nan's and garbage. Yech.

Like a good little boy, I winnowed down the commit to exactly what, when merged with the code, caused the error. Turns out it was adding case statements to errorv(), the error print handler. Add a case statement, the regression falls over. At this point I was very depressed. This looks like, and probably is, a memory sensitivity bug. Move the code a bit, increase its size, and the thing dies. Its a programmer's nightmare. Usually this is caused by uninitialized locations, but p4 has been checked in self-strapped pint, which checks for use of uninitialized variables, so there is that.

This was basically all of yesterday. Wrapping up at about midnight, I decided that it was time to assembly language debug this, although because I suspected a memory error, I also assumed this would not tell me much. I cut down standardp.pas to the bare minimum:

program suite(output);

begin

   writeln(-5.565);

end.

Which prints "nan" or "not a number".

The intermediate code for this is:

l   3
 ent   1   l   4
 ent   2   l   5
 ldcr  5.565   ! load real constant
 ngr  ! negate
 ldci          20 ! load field
 lda   0       6 ! load file
 csp         wrr ! write real
i   10
 lda   0       6
 csp         wln
 retp
l   4=          9
l   5=          8
q
i    0
 mst           0
 cup   0   l   3
 stp
q

Tracing out the first part the numbers look ok, ie., 5.565 all the way, until getting to the ngr (negate real) instruction. Then we get to the meat:

# generating:    1007:   7158:  86: indr 0 r1: xmm9 t1: r12 rs: []
        movsd   0(%r12),%xmm9           # load real from address        # xmm9 = 5.5650000000000004, correct
# generating~:   1007:   7158:  86: indr 0 r1: xmm9 t1: r12 rs: []
# generating:    1007:   7159:  37: ngr  0 r1: xmm8 rs: []
        subsd   %xmm8,%xmm8             # subtract to find 0  # before this operation, xmm8 = nan
        subsd   %xmm9,%xmm8             # find 0-real

The loaded real, xmm9 was 5.565, correct. The xmm register set does not have a negate instruction, so we approximate it by clearing an xmm register to zero by subtracting it from itself then subtracting the value from that, or 0-value to get the negative. Stepping forward, xmm8, the register we want to clear, has a nan in it, because it was never loaded with anything.

Uh, oh.

Those of you who have used floating point math already know the answer don't you? I didn't need to step through to see the problem, but I did anyways. Crud.

The rules of IEC 60559 standard say that nans are special. Its basically like infinity. Any math operation involving a nan just ends up being a nan. Its designed so that an invalid result will just ripple through the calculation.

And so what is a nan minus a nan? Its.... a nan. Soooo, unlike an integer register, subtracting the register from itself won't in fact clear it. Crud.

Thus this calculation fails, and gives as a result of the negation, a nan.

Conclusion

I was right about the issue being an uninitialized value, but it was a value in a register, an xmm register. Thus running it on a pint that catches uninitialized memory values won't help. The bug was in pgen, not the program.

Fun.

samiam95124 commented 6 months ago

Update

The (mostly) complete section for Pascaline extensions support was "dry completed", meaning written but untested. The theory was that since none of the extended codes were being used in normal regressions, that the system would still be usable.

That theory lasted about 5 minutes.

The first fault was found to be a mistaken edit to the stos instruction. Still working on the second fault.

There is always an issue with code like this whether to stop and check every bit of code against a full regression or to complete large blocks of development code without stopping. I did the latter based on the idea that it is to time consuming to stop every couple of lines and test. The theory of CI/CD or continuous integration/continuous delivery is that you should test and commit constantly. I think that works well for operational code, but not so great for code under development.

samiam95124 commented 6 months ago

Alright, so using the wonderful abilities of github, the offending commit was 5b08221:

[Bring debug flag to pgen; implement overflow checks; implement dispose of nil pointer check.](https://github.com/samiam95124/Pascal-P6/commit/5b082215e067dab4ccd9ac08077a64ba49c09dad)
 Changes to be committed:
    modified:   source/AMD64/gcc/pgen.pas

1. Bring the debug flag from pcom to pgen as dodbgchk. Yes, the original was
misnamed.

2. Implement overflow checks on trc, rnd, dvr, adi, sbi, inc, dec, ngi, and mpi
instructions.

3. put INT_MAX, INT_MIN values as doubles in the constants area.

    modified:   source/AMD64/gcc/psystem.c

1. Check nil pointer on dispose.

So this was a modification to the existing (ISO 7185) code that was put in without a regression, so my bad.

The actual failure was a copy/paste error. It is referencing the right fork of a rnd instruction node, which does not have a right fork.

Lessons:

  1. Always run a regression (but that is obvious).
  2. Don't mix development commits with fixup commits.
samiam95124 commented 6 months ago

To stack or not to stack

With the start of the Pascaline extensions in pgen, the first subject is modularity. pgen uses a system that is new to gcc/Linux, but is very old with me, going back into the 1980's, which is a module stack. Each module contains, or can contain, a startup section and an ending section (in object terms this would be the contructor/destructor). Although this system gets pretty wild in C++, the most sensible implementation is to execute the startups in dependency order, and endings in reverse order. That is, the lowest level dependency, the module that calls no other module, goes first, and the module that uses other modules goes last, ie., the program module. The ending or finalization code executes in the reverse order. This means that library code gets to set up it's internal data structures before external callers use it, and the library code gets to shut down it's code after all external callers have done their shutdown.

pgen, as well as IP Pascal, and other systems I have written like embedded operating systems[2], use the "stack" method:

module1: startup call end shutdown end

module2: startup call end shutdown end

...

This means that each module performs its startup sequence, then calls the next module in the stack by calling the end of its code, literally. It just calls the last location in the module, +1. This satisfies the startup/shutdown order requirement. In practice for gcc/Linux, this means a typical stack consists of:

main shim module module ... program

The main shim is there to set Linux's idea of the entry point of the program, or the first location executed. It isn't actually true, as discussed in a second, but it is true enough for the purposes here. This is followed by the modules used by the program in dependency order. The last module, the program module, is what I call a "cap cell", meaning that it doesn't call its end to continue the chain[1]. If you are up on Pascaline structures, you would note that the process module is the odd element here, because it both executes a thread and continues the startup chain.

Who determines dependency order here? Normally the user does. However, the pc compiler integrator does that automatically. What happens if the dependency order has a loop in it, that is, two modules that reference each other? Actually, that is a big issue in Pascaline that goes back decades, and predates the Pascaline specification. The IP Pascal compiler has a loop like that[3]. Technically its an error, but in reality the programmer can work around it. The pc compiler integrator flags an error for it, but builds the stack anyways.

Wait what? Doesn't gcc already do that?

Why yes it does, and we use it. Its the __attribute system, and consists of a constructor and destructor function. The code that uses it lists a priority for the constructor and destructor, and gcc executes it before main is called (see! main is not in fact the first entry point in Linux!). This system is used in psystem.c, the pgen support module. So why doesn't pgen use this system? There are actually several reasons:

  1. It's a C level convention. pgen generates assembly code, although admittedly a way could probably be found to make that work.
  2. There is no obvious system to pick "priorities" for such attributes. We could make a system for that, but there are no guarantees we would not pick the same numbers as other C modules included in a program.
  3. It's specific to gcc.
  4. It's not always implemented correctly. Mingw emulates it, but does not interact correctly with .dll modules, resulting in serious shutdown bugs.
  5. Frankly, the stack system is just better. It accomplishes the desired function without needing to pick arbitrary "priority" numbers. It also does not have oddities, like what happens if the constructor and destructor have different priorities?

So why not use the stack method for all modules, including C written modules?

The reason is that there is no obvious way to have C modules call to their end, and even if it could be done, it would be a hack that would be different for each operating system.

As it is, the mixed system means that C modules have their startups called first, with Pascaline modules called after. Since C is mostly used to write support modules in Pascaline, this strikes me as the right order of things.

[1] In IP pascal, there actually was a cap cell module, but the only reason that would be needed is if there are multiple program modules that are executed in series, which is a useless artifact. [2] I have written about 10 such systems. The stack system is used to represent the target binaries (applications), since you just concatenate the binary files together after the operating system. [3] Its due to the need to handle lower level errors in the main program section so that it can exit cleanly. That issue is solved by exceptions, which didn't exist in the Pascaline specification before 2010.

samiam95124 commented 6 months ago

Far labels: the gateway to hell? And how to escape from them.

So pgen has been nursing type digests (type spagetti!) and far labels along for a while now. Its because far labels are required for intermodule calls, and you have to do something with overloads. It was easier to put that handling in pgen from day one than to retrofit it later.

Type digests, AKA type spagetti (my term) or name mangling (the C++ term due to Barne Stroustrup), are the addition of a type signature to symbols. The are required to overload procedures and functions in order to differentiate the overloads from each other. They can get pretty nasty. I have seen 1000 character type digests in the code for pcom.pas. You don't type those. At best you copy and paste them. C++, as I recall, has a system to compress them down to less than about 32 characters in order to fit common linker restrictions[1]. I don't do that. gcc/gas seems to handle them, so I am happy with that.

Pascal-P6 actually uses type digests to communicate type information to the back end, on account of the fact that Pascal-P didn't have any way to send type information to its back end. Its all numbers. This was all covered in messages above. So the type digest serves two purposes:

  1. Send type information to the backend (pgen).
  2. Differentiate procedure/function overloads.

Now because type digests can get so ugly, pgen has a way to avoid them, which is overload enumeration. That is, each of the overloads in the program for the same procedure/function are numbered in encounter order. The first encounter, or 1, can have its number dropped, but the rest cannot. This neat feature allows non-overloaded routines to have symbol names the same as their original names, since by definition, non-overloaded routines only have one encounter. Again, this was covered above. The numbering system allows you to use a short form to reference overloads.

Far labels

Far labels refer to labels that cross module boundaries, ie, go to other files. For those who have been around for a while, this is a joke on Intel segmented code mode. So the deal with far labels is they cannot use encounter numbering. Why? Well, it's because the programmer of the file could reshuffle the order of the overloads. If this were done, then all of the previously compiled code would break, since the overloads would go to the wrong routines. Thus far labels must carry a full type digest.

The good news is you as a programmer don't have to type the full type digest. If you go to the .s file containing the overloaded routine, you can see the enumerated form and use that. This works in pint as well.

The look... of far labels

So type digests are bad enough to understand. Guess what. pgen makes them far worse. It has to. All of the interesting punctuation in digests like ( ) , : etc., are turned into $. Why $? Because gas/gcc allows that as a character, and the program itself can't use that in a symbol (unlike _). The "theory" is that this still leaves the type digest as unique, but I guess time will tell about that. The first $ in a label is most certainly unique, because it starts the type digest. Anything after that is part of the type digest.

Conclusion

Far labels and type digests are just something you have to put up with when spelunking in the dark recesses of .s files. But a little knowledge about their function can help.

[1] I believe that was a cfront design feature.

samiam95124 commented 6 months ago

Intermodule calls

samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ compile --pgen test1 test
Compiling test1...
Compiling test...
P6 Pascal compiler vs. 0.2.x
Pascal-P6 complies with the requirements of Pascaline version 0.4
and the following annexes: A,B,C,E.

     1       -8 module test1(output); 
     2       -8  
     3       -8 procedure sayhello; 
     4      -16  
     5      -16 begin 
     6        7  
     7        7     writeln('Hello from test1') 
     8       14  
     9       14 end; 
    10       17  
    11       17 begin 
    12       17  
    13       17     writeln('Starting test1') 
    14       24  
    15       24 end; 
    16        0  
    17        0 begin 
    18        0  
    19        0     writeln('Finalizing test1') 
    20        7  
    21        7 end. 

Errors in program: 0
P6 Pascal AMD64/gcc 64 bit code generator vs. 0.2.x

Generating program

Program generation complete
P6 Pascal compiler vs. 0.2.x
Pascal-P6 complies with the requirements of Pascaline version 0.4
and the following annexes: A,B,C,E.

     1       -8 program hello(output); 
     2       -8  
     3       -8 uses test1; 
     4        0  
     5        0 begin 
     6        0    
     7        0    writeln('Hello, world'); 
     8        9    sayhello 
     9        9  
    10        9 end. 

Errors in program: 0
P6 Pascal AMD64/gcc 64 bit code generator vs. 0.2.x

Generating program

Program generation complete
/usr/bin/ld: /tmp/ccXcMwWm.o: in function `resetfn':
/home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem.c:1828: warning: the use of `tmpnam' is dangerous, better use `mkstemp'
samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ ./test
Starting test1
Hello, world
Hello from test1
Finalizing test1
samiam95124 commented 6 months ago

Adapt or die: the macro processor

You might have noticed that eliminating the macro processor (cpp[1]). Why? Well, me and Bjarne Stroustrup share something in common, which is a dislike for the macro pass. Its a slow extra pass that is not needed for a properly constructed language[2][3]. And indeed, with Pascal-P6 running Pascaline features it is no longer required.

However, the immediate reason for getting rid of it is it causes the source line numbering to no longer match the line numbering in the downstream utilities, like pgen. The reason this didn't matter as much in GPC is that cpp emits a series of "line sync" macro markers that tell the compiler what the actual line numbers are in source. I did think hard about implementing this convention in pcom. It gave me a headache. The TL;DR is that I prefer getting rid of the macro pass.

[1] No, not the C++ compiler. Linux is just chock full of naming overloads like that isn't it? I blame the three letter command convention. [2] C does not actually have an include nor any sort of modularity. Shocking, I know. [3] Am I saying Pascal should have included modularity from the getgo? Wirth's next language was called "modula". QED.

samiam95124 commented 6 months ago

Calls to external C code

How to call external C routines? The way to do this is via a thunk module:

samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ compile --pgen test1 test
Compiling test1...
Compiling test...
P6 Pascal compiler vs. 0.2.x
Pascal-P6 complies with the requirements of Pascaline version 0.4
and the following annexes: A,B,C,E.

     1       -8 module test1(output); 
     2       -8  
     3       -8 function getpid: integer; begin getpid := 42 end; 
     4       10  
     5       10 begin 
     6       10 end. 

Errors in program: 0
P6 Pascal AMD64/gcc 64 bit code generator vs. 0.2.x

Generating program

Program generation complete
P6 Pascal compiler vs. 0.2.x
Pascal-P6 complies with the requirements of Pascaline version 0.4
and the following annexes: A,B,C,E.

     1       -8 program test(output); 
     2       -8  
     3       -8 uses test1; 
     4        1  
     5        1 begin 
     6        1    
     7        1     writeln('pid of current process is: ', getpid:1) 
     8       11  
     9       11 end. 

Errors in program: 0
P6 Pascal AMD64/gcc 64 bit code generator vs. 0.2.x

Generating program

Program generation complete

Then, we substitute test1.s with test1.asm which contains an assembly thunk:

        .text

        jmp     1f          # skip stack sequence

        .globl   test1.getpid$f
        .type    test1.getpid$f@function

test1.getpid$f: 
        call    getpid
        pop     %rcx        # get return address
        add     $8,%rsp     # remove dummy function result
        jmp     *%rcx       # go return
1:

What the thunk does first is jump past all the code to the next module. The getpid routine is then wrapped with the module name and type digest (test1.getpid$f), and the thunk calls the fuction, which returns the pid in rax. Finally, because pgen allocates the result on the stack, we remove the return address from the stack, dump the dummy function result, then return to the caller.

Then the stack is compiled with the new module:

samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ gcc -g3 -DWRDSIZ64  /home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem.c -x assembler /home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem_asm.asm /home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/main.asm  test1.asm test.s -o test -lm
/usr/bin/ld: /tmp/ccZkgeOR.o: in function `resetfn':
/home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem.c:1828: warning: the use of `tmpnam' is dangerous, better use `mkstemp'
samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ ./test
pid of current process is: 4180983

Note that test1.asm has replaced test1.s in the compile, assemble and link.

Why the thunk?

The thunk code does two important jobs:

  1. Converts the qualident/module and typed name of the function to the C equivalent.
  2. Converts the stack convention.

The parameters to the external routine work from 1 to 6 parameters because of the "compatible calling convention" (or "semicompatible" if you will). pgen goes ahead and stacks the parameters, but also retains up to 6 of them in registers in the rdi, rsi, rdx, rcx, r8 and r9 ordering required by the AMD64 calling convention. Thus, as long as less than 6 parameters are needed, the calling convention is compatible. pgen also expects the function result in rax, as per AMD64, but it must create a stack location to store the function result for pgen code to use.

Note we can also use the joins method:

program test(output);

joins test1;

begin

    writeln('pid of current process is: ', test1.getpid:1)

end.

This gives you namespace isolation. getpid cannot be redefined in other code, but pgen will never define it, since all names in Pascal-P6 are coined with the module name.

Will this get better?

I believe it will. The change for that requires pcom to arrange the calling convention specifically for the AMD64 bit processor. Right now the calling convention is the same one pint/pmach/cmach used all along. If we use a AMD64 calling convention, we can arrange things like right to left parameter order, more than 6 parameters, not having to fix up return values, etc.

However, right now the system works!

samiam95124 commented 5 months ago

Where are we going? The roadmap to version 0.3

The truth is version 0.3 should have been completed last week. I completed the original prerequisites for the version, which was to run ISO 7185 with no regression errors. The reason(s) I kept going are:

  1. There isn't that much to go to a full up version of Pascaline.
  2. Frankly the ISO 7185 only version of Pascal-P6 isn't that useful.
  3. I plan to take a break after version 0.3.

Full up Pascaline is presently defined as running the Pascaline regression test. That means all features presently implemented in the Pascaline specification, if not completely tested. The completely tested part is running the existing Pascaline codebase. To me this includes running the string library and running Petit-Ami. After that, the system will be able to run real world problems, which satisfies #2 above.

What break? I have other work to do. I have been working on Pascal-P6 for more than a year now, either part time or full time. Thus its time for Pascal-P6 to go to maintenance mode, which means only fix problems with it. If I don't get to my other responsibilities, bad things happen.

The string library

it's in the ./libs directory if you want to have a look, and its also in the Pascaline specification. It is dated. Some of the things like hex conversion are now in the language specification itself. It was also written before operator overloads were implemented. The library itself was written back before the turn of the century.

Petit-ami

This is the support library for Pascaline, rewritten in C. Its pretty complete, it is only missing a few dialogs for Linux. It also needs a few adaptions in the API, like accomodating Pascaline mode string arguments.

samiam95124 commented 5 months ago

External calls redux (what does "external" do?)

That last example (Calls to external C code) put a bug in my brain, and I went back to revisit it. pint uses "external" on those externally called routines. It does two things:

  1. Suppresses warnings and errors about missing function assignments and unreferenced parameters.
  2. Tells pint to go looking for those external calls by name.

So in my original example, I cheated by putting dummy code in the external routine:

     1       -8 module test1(output); 
     2       -8  
     3       -8 function getpid: integer; begin getpid := 42 end; 
     4       10  
     5       10 begin 
     6       10 end.

Without that, you get:

     1       -8 module test1(output); 
     2       -8  
     3       -8 function getpid: integer; begin end; 
     4        8  
     5        8 begin 
     5   ****       ^193
     5   ****  193 Function does not assign to result
     6        8 end. 

Errors in program: 1

Which makes sense, the compiler does not know the routine is external, we didn't tell it.

I had assumed that pgen would do something different with "external", like strip off the coining ("test1.") and the type digest, so that you could directly reference an external routine. Of course that does not work without a thunk at present, but it could work in the future.

After thinking about it, I realized that "external" was, in fact, doing the exactly right thing, and rearranged the example to do that:

samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ compile --pgen test1 test
Compiling test1...
Compiling test...
P6 Pascal compiler vs. 0.2.x
Pascal-P6 complies with the requirements of Pascaline version 0.4
and the following annexes: A,B,C,E.

     1       -8 module test1(output); 
     2       -8  
     3       -8 function getpid: integer; external; 
     4      -16  
     5      -16 begin 
     6        7 end. 

Errors in program: 0
P6 Pascal AMD64/gcc 64 bit code generator vs. 0.2.x

Generating program

Program generation complete
P6 Pascal compiler vs. 0.2.x
Pascal-P6 complies with the requirements of Pascaline version 0.4
and the following annexes: A,B,C,E.

     1       -8 program test(output); 
     2       -8  
     3       -8 joins test1; 
     4        1  
     5        1 begin 
     6        1    
     7        1     writeln('Current process pid: ', test1.getpid) 
     8       11  
     9       11 end. 

Errors in program: 0
P6 Pascal AMD64/gcc 64 bit code generator vs. 0.2.x

Generating program

Program generation complete
/usr/bin/ld: /tmp/ccznlD6T.o: in function `resetfn':
/home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem.c:1828: warning: the use of `tmpnam' is dangerous, better use `mkstemp'
/usr/bin/ld: /tmp/ccbDDQAW.o: in function `test.3':
/home/samiam/projects/pascal/pascal-p6/test.s:350: undefined reference to `test1.getpid$f'
collect2: error: ld returned 1 exit status
samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ gcc -g3 -DWRDSIZ64  /home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem.c -x assembler /home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem_asm.asm /home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/main.asm  test1.asm test.s -o test -lm
/usr/bin/ld: /tmp/ccL0IjZD.o: in function `resetfn':
/home/samiam/projects/pascal/pascal-p6/source/AMD64/gcc/psystem.c:1828: warning: the use of `tmpnam' is dangerous, better use `mkstemp'
samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6$ ./test
Current process pid:     1014452

Now the external routine appears without errors, because pcom supresses them due to the "external" keyword. Other than that, pcom does nothing. It just flags the symbol as external, and pint does the rest.

For pgen, external already does the correct thing, which is suppress compilation errors like function result.

samiam95124 commented 5 months ago

Pgen (compiled) is now the default, and what the scripts do, the programs, and the future

Running the compiled versions is more useful to me, and I suspect everyone else as well. Thus it is now the default in the compile, run, p6 and other scripts. The run modes are (by option):

--pint - interpreter/debugger. --pmach - stripped down interpreter in Pascal. --cmach - stripped down interpreter in C. --package - packaged mode of cmach interpreter, wraps the code and interpreter into an executable binary. --pgen - compiler back end.

The intermediate files are:

.pas - source .p6 - intermediate .p6o - binaries for the Pascal-P machine .s - generated assembly files by pgen. .asm - assembly source files (hand generated).

The intermediate chains are:

-pint - .pas .p6 -pmach - .pas .p6 .p6o -cmach - .pas .p6 .p6o -package - .pas .p6 .p6o executable -pgen - .pas .p6 .s executable

What do they do?

Compile

Compile takes every source file it sees and compiles it to intermediate, .p6. It concatenates all intermediates it generates, so if you give it file1 file2 file3, it generates file1.p6, file2.p6, but the last file3.p6 will contain all the intermediates concatenated together. This is what pint, pmach and cmach and package need to run multimodules together. If pmach, cmach or package are selected, a .p6o or binary for the Pascal-P machine is generated, containing all of the intermediates concatenated and converted. If package is selected, it further runs the .p6o binary through a converter into a C static byte array, then combines that with the cmach interpreter into an executable. If cmach comes up and finds it has an executable Pascal-P machine code block resident, it executes it.

run

Run takes whatever format it is provided and runs it with the selected resource. For pmach, cmach, it converts the .p6 intermediate to .p6o Pascal-P machine binary and runs that. For pgen and package mode, it just runs the executable. Obviously run is not that useful it you already have the executable from pgen or package mode. It is mainly used by the test setup to give standard inputs and outputs.

p6

p6 is like a combined compile and run sequence. It would be that identically, but compile and run are batch mode scripts, that is, they take their input and give their output from/to files. p6 directly runs the resulting program, and thus can run interactive programs.

The programs

The basic binaries that form the compiler components are:

pcom <.pas> <.p6> - The compiler. pint <.p6> <.p6o> - The interpreter/debugger. pmach <.p6o> - The stripped interpreter in Pascal. cmach <.p6o> - The stripped interpreter in C. pgen <.p6> <.s> - The intermediate to assembly code generator.

Note that all of these open two files at the start of the program, the input and output data files, which must be present on the command line. The options for each follow, so that (for example):

pint file.p6 file.p6o [

executes the program, but the program that pint runs can open further files itself, or even other data. The exception to this is cmach, which only has one fixed file.

The future

The compiler scripts will continue to be supported, but there is a better tool, written in Pascaline, to handle compiles, the pc or "pc integrator" which will be described later. It takes a file

pc file

and does what is needed to create an executable for the file. It automatically determines what type of file it is, a program or a module, and both generates the appropriate output file. It also builds a dependency tree for the file (similar to "automake:") and makes sure all of the products needed for the file are created.

samiam95124 commented 5 months ago

Regression is dead

The regression failed on commit:

commit 5bd74bc5e948ca01f679949a57d3b8470480d445 Author: samiam95124 samiam@moorecad.com Date: Sat Apr 13 19:03:58 2024 -0700

Fix clerical in compile script; store binaries and scripts in iso7185 host; place options in run script; ran regression; moved psystem_asm.s to psystem_asm.asm

My fault, the regression output no error or listing for this test. Turns out it failed in the compiler. Will work to find the error as well as fix why it didn't show in the regression as an obvious error.

The log tends to indicate that it has been broken since the changeover to pgen based binaries. I suppose it is lucky that the system compiled at all. Another way of looking at it is it is unlucky that it worked that well, since the problem has lain low since the changeover and instead could have failed immediately. Again, my bad.

I'm aware the last month or so after the self compile things got boring in this repo, I can see the views went down. However, these kinds of dirty work are what the repo needs to gain stability. Its the nature of good software.

samiam95124 commented 5 months ago

Regression redesign

The regression as it stood had two serious issues that were corrected:

  1. Positive tests that failed to compile were being skipped in the output regression. This included pascals and prime.
  2. Runnning different modes caused the result files to be overwritten. This made it difficult to diagnose issues when they occurred.

The refactor simplifies and organizes the tests. This is detailed below.

Error returns

The individual test scripts are designed to return an error on compilation, run or generation failure. This gives the opportunity to cancel or present status. This now prints an error message in regression, but keeps running. The idea of regressions is to test everything possible.

The PRT is a special case, since it deliberately includes compilation failures. This are now ignored.

Run type binning

The regression script now features binning according to run type. These are (if it needs repeating);

pint pmach cmach package pgen

The results from tests, which include the following file types:

.lst - The run listing from the test program .dif - The difference between the .lst and .cmp for the program. .err - The output of the compiler including errors. May or may not exist depending on test type. Some tests, like Pascal-P2, Pascal-P4 and others, have multiple files and/or run target files and so the .err does not make sense.

These are binned under the test_results directory for the given test. For most tests, the binning directory is under the test directory. The exception is ./source (the general Pascal-P6 source directory), this tree is in the ./build directory.

Binning the results allows examination of the results to debug failure results after a regression.

samiam95124 commented 5 months ago

Regression is alive!

So it has taken me about a week, but I was able to get the regression back on track. Its hard to express just how scary losing control of the regression like that was. After the pgen self compile, I and Pascal-P6 is basically standing on the correctness of pgen, which is verified by the regression. If the regression is wrong, I could be in the position that Pascal-P6 is getting farther and father from a reasonable state and will eventually fail completely. This is a "loop crash", where the compiler can no longer build itself.

The regression script is now much stronger, and both does not omit details, but also does better logging. After running the new regression, I was able to see all of the faults in the regression and fix them. I did a dive into the history of commits, and found that the faults were the most part faults that existed from the time pgen bootstrapped the system. Its a reasonable question to ask: why didn't the faults bring the system down? The reason is because they were for the most part corner cases that didn't occur in most code.

The last regression failure

Still to do, of course, is the extensive Pascaline test for pgen. This means I can go back to the effort of making that work. On to version 0.3!

samiam95124 commented 5 months ago

Update (moved this forward)

  1. Run Pascaline tests on pint/pmach/cmach. - Complete
  2. Fix Pascaline generation in pgen. - Generates ok, errors in assembly.
  3. Run Pascaline tests on pgen.
  4. Run diagnostic test on pint. - Complete.

Note this message is edited in place.

samiam95124 commented 5 months ago

Operator overload coining

Operator overloads are sent to the backend with their proper labels, ie, like:

b f +@f_pi

For those up on your advanced "type spagetti technology", this is a block, function, operator overload for "+", with type function, single parameter, type pointer to integer.

The problem is that the function name, "+", gets woven into lots of names in the assembly, because, you know, qualidents. So:

b f +@f_pi s a p 40 pi pascaline.+$3.a = 40 pascaline.+$f_pi.a = 40

Which defines a, a local to operator overload function "+", etc.

What to do?

I propose coining the operator names as:

$plus

So:

b f $plus@f_pi s a p 40 pi pascaline.$plus$3.a = 40 pascaline.$plus$f_pi.a = 40

Justification

So gcc/gas only gives us three characters to work with outside of alphanumerics, which are "", ".", and "$". "" could be program generated, so that is out. "." has a very defined meaning for qualidents. So that leaves "$" for all coining uses.

Coining to "plus" fixes the assembler issue, but leaves the possibility that user code could have a "plus" id, so we have to pepper it with "$". It could be at the front, back, or anywhere really. There is also the issue that "$" demarcates the type spaghetti, but that is done before coining, so it doesn't matter. Thus I chose the front, as in "this is function is going to be a coined operator".

PS: Overlaps with user functions

A function like "not" can overlap names from the user. The compiler is not confused, since a "not" overload can only be executed in an expression. However that doesn't mean that they can't overlap as assembler names. This is likely just a "user beware" feature.

samiam95124 commented 5 months ago

Templates

Templates get forwarded to the constants area and output of the format:

templatex:
module.x:
        .quad    size
        .quad    dim1
        ...
        .quad     dimn

See the manual for template formats. We output both the "templatex" and module name labels because the code uses the module name as a local. Templates will never be far labels. The templatex format is just annotation really, to say what it does. It could be resolved in the code (and perhaps should be), but that is extra work.

Namespace pollution?

gas treats everything that is not .globl declared as local to the namespace of the file, which is what it should do. As long as they are coined as local labels, its ok, even if a bit confusing[1].

Improvements?

There is no reason templates can't use "template" coined label. By definition, templates are declared before being used (they are generated when the array type is declared). This would include marking the label entry as a template, then using the template coined label on use.

[1] If confusion is an issue, I recommend staying away from assembly language programming.

samiam95124 commented 5 months ago

Update

  1. Run Pascaline tests on pint/pmach/cmach. - Complete
  2. Fix Pascaline generation in pgen. - Complete
  3. Run Pascaline tests on pgen.
  4. Run diagnostic test on pint. - Complete.
samiam95124 commented 5 months ago

Progress on Pascaline test

*******************************************************************************

                       TEST SUITE FOR PASCALINE

                 Copyright (C) 2022 S. A. Franco - All rights reserved

*******************************************************************************

The following are implementation defined characteristics

Maxcrd: 9223372036854775807
Maxlint: 9223372036854775807
Maxlcrd: 9223372036854775807
Maxchr: 255
Maxreal:  1.79769313486231e+308
Maxsreal:  1.79769313486231e+308
Maxlreal:  1.79769313486231e+308
Bit length of cardinal appears to be: 63
Bit length of long integer without sign appears to be: 63
Bit length of long cardinal appears to be: 63
Cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long integer default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
cmt1: <nothing>
id1: 42 s/b 42
glb1: start  stop s/b start stop
nc1: 165 s/b 165
nc2: 58 s/b 58
nc3: 25 s/b 25
nc3: 123456 s/b 123456
nc4: 3418164 s/b 3418164
nc5: 107482 s/b 107482
nc6: 87 s/b 87
ext15: 9223372036854775765 s/b 9223372036854775765
ext16: 130 s/b 130
ext17: 24 s/b 24
ext18: 0.0023 s/b 0.0022
ext19: 2 s/b 2
ext20: 12 s/b 12
ext21: -76 s/b -76
ext22: 54 s/b 54
ext23: 97 s/b 97
ext24: 53 s/b 53
ext25: 106 s/b 106
ext26: 42 s/b 42
ext27: abcdz s/b abcdz
ext28: 1 2 3 4 5 12  s/b 1 2 3 4 5 12
ext29: 432 s/b 432
ext30: Q s/b Q
ext31:   1.23456000000000e+00 s/b 1.23456000e+000
ext32: hi there s/b hi there
vb1: 9223372036854775751 s/b 9223372036854775751
vb2: 8 s/b 8
vb3: 61 s/b 61
vb4: 53 s/b 53
vop1: this is a test s/b this is a test
vop2: 42 s/b 42
vop3: g s/b g
ecs1:
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
s/b
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
vcr1: 42 43 a  s/b 42 43 a
ats1: hi there ? s/b hi there ?
ats2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
sdc1: 
*** Runtime error: pascaline:1041:Container length(s) do not match
samiam95124 commented 5 months ago

Progress on Pascaline test

*******************************************************************************

                       TEST SUITE FOR PASCALINE

                 Copyright (C) 2022 S. A. Franco - All rights reserved

*******************************************************************************

The following are implementation defined characteristics

Maxcrd: 9223372036854775807
Maxlint: 9223372036854775807
Maxlcrd: 9223372036854775807
Maxchr: 255
Maxreal:  1.79769313486231e+308
Maxsreal:  1.79769313486231e+308
Maxlreal:  1.79769313486231e+308
Bit length of cardinal appears to be: 63
Bit length of long integer without sign appears to be: 63
Bit length of long cardinal appears to be: 63
Cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long integer default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
cmt1: <nothing>
id1: 42 s/b 42
glb1: start  stop s/b start stop
nc1: 165 s/b 165
nc2: 58 s/b 58
nc3: 25 s/b 25
nc3: 123456 s/b 123456
nc4: 3418164 s/b 3418164
nc5: 107482 s/b 107482
nc6: 87 s/b 87
ext15: 9223372036854775765 s/b 9223372036854775765
ext16: 130 s/b 130
ext17: 24 s/b 24
ext18: 0.0023 s/b 0.0022
ext19: 2 s/b 2
ext20: 12 s/b 12
ext21: -76 s/b -76
ext22: 54 s/b 54
ext23: 97 s/b 97
ext24: 53 s/b 53
ext25: 106 s/b 106
ext26: 42 s/b 42
ext27: abcdz s/b abcdz
ext28: 1 2 3 4 5 12  s/b 1 2 3 4 5 12
ext29: 432 s/b 432
ext30: Q s/b Q
ext31:   1.23456000000000e+00 s/b 1.23456000e+000
ext32: hi there s/b hi there
vb1: 9223372036854775751 s/b 9223372036854775751
vb2: 8 s/b 8
vb3: 61 s/b 61
vb4: 53 s/b 53
vop1: this is a test s/b this is a test
vop2: 42 s/b 42
vop3: g s/b g
ecs1:
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
s/b
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
vcr1: 42 43 a  s/b 42 43 a
ats1: hi there ? s/b hi there ?
ats2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
sdc1: hi there ? s/b hi there ?
sdc2: hi there ? s/b hi there ?
sdc3: hi there ? s/b hi there ?
sdc4: 143 276 388 412 574 622 74 83 99 1  s/b 143 276 388 412 574 622 74 83 99 1
sdc5: hi there ? s/b hi there ?
sdc6:  20 19 18 17 16 15 14 13 12 11 s/b 20 19 18 17 16 15 14 13 12 11
sdc7:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc8:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc9:  true s/b true
sdc10: false s/b false
sdc11: false s/b false
sdc12:  true s/b true
sdc13:  true s/b true
sdc14: false s/b false
sdc15: false s/b false
sdc16:  true s/b true
sdc17:  true s/b true
sdc18: false s/b false
sdc19:  true s/b true
sdc20:  true s/b true
sdc21: false s/b false
sdc22:  true s/b true
sdc23:  true s/b true
sdc24:  true s/b true
sdc25:  true s/b true
sdc26: false s/b false
sdc27: false s/b false
sdc28:  true s/b true
sdc29:  true s/b true
sdc30: false s/b false
sdc31: false s/b false
sdc32:  true s/b true
sdc33:  true s/b true
sdc34: false s/b false
sdc35:  true s/b true
sdc36:  true s/b true
sdc37: false s/b false
sdc38:  true s/b true
sdc39:  true s/b true
sdc40:  true s/b true
sdc41:  true s/b true
sdc42: false s/b false
sdc43: false s/b false
sdc44:  true s/b true
sdc45:  true s/b true
sdc46: false s/b false
sdc47: false s/b false
sdc48:  true s/b true
sdc49:  true s/b true
sdc50: false s/b false
sdc51:  true s/b true
sdc52:  true s/b true
sdc53: false s/b false
sdc54:  true s/b true
sdc55:  true s/b true
sdc56:  true s/b true
mdc1: 
Segmentation fault (core dumped)
samiam95124 commented 5 months ago

Progress on Pascaline test

*******************************************************************************

                       TEST SUITE FOR PASCALINE

                 Copyright (C) 2022 S. A. Franco - All rights reserved

*******************************************************************************

The following are implementation defined characteristics

Maxcrd: 9223372036854775807
Maxlint: 9223372036854775807
Maxlcrd: 9223372036854775807
Maxchr: 255
Maxreal:  1.79769313486231e+308
Maxsreal:  1.79769313486231e+308
Maxlreal:  1.79769313486231e+308
Bit length of cardinal appears to be: 63
Bit length of long integer without sign appears to be: 63
Bit length of long cardinal appears to be: 63
Cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long integer default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
cmt1: <nothing>
id1: 42 s/b 42
glb1: start  stop s/b start stop
nc1: 165 s/b 165
nc2: 58 s/b 58
nc3: 25 s/b 25
nc3: 123456 s/b 123456
nc4: 3418164 s/b 3418164
nc5: 107482 s/b 107482
nc6: 87 s/b 87
ext15: 9223372036854775765 s/b 9223372036854775765
ext16: 130 s/b 130
ext17: 24 s/b 24
ext18: 0.0023 s/b 0.0022
ext19: 2 s/b 2
ext20: 12 s/b 12
ext21: -76 s/b -76
ext22: 54 s/b 54
ext23: 97 s/b 97
ext24: 53 s/b 53
ext25: 106 s/b 106
ext26: 42 s/b 42
ext27: abcdz s/b abcdz
ext28: 1 2 3 4 5 12  s/b 1 2 3 4 5 12
ext29: 432 s/b 432
ext30: Q s/b Q
ext31:   1.23456000000000e+00 s/b 1.23456000e+000
ext32: hi there s/b hi there
vb1: 9223372036854775751 s/b 9223372036854775751
vb2: 8 s/b 8
vb3: 61 s/b 61
vb4: 53 s/b 53
vop1: this is a test s/b this is a test
vop2: 42 s/b 42
vop3: g s/b g
ecs1:
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
s/b
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
vcr1: 42 43 a  s/b 42 43 a
ats1: hi there ? s/b hi there ?
ats2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
sdc1: hi there ? s/b hi there ?
sdc2: hi there ? s/b hi there ?
sdc3: hi there ? s/b hi there ?
sdc4: 143 276 388 412 574 622 74 83 99 1  s/b 143 276 388 412 574 622 74 83 99 1
sdc5: hi there ? s/b hi there ?
sdc6:  20 19 18 17 16 15 14 13 12 11 s/b 20 19 18 17 16 15 14 13 12 11
sdc7:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc8:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc9:  true s/b true
sdc10: false s/b false
sdc11: false s/b false
sdc12:  true s/b true
sdc13:  true s/b true
sdc14: false s/b false
sdc15: false s/b false
sdc16:  true s/b true
sdc17:  true s/b true
sdc18: false s/b false
sdc19:  true s/b true
sdc20:  true s/b true
sdc21: false s/b false
sdc22:  true s/b true
sdc23:  true s/b true
sdc24:  true s/b true
sdc25:  true s/b true
sdc26: false s/b false
sdc27: false s/b false
sdc28:  true s/b true
sdc29:  true s/b true
sdc30: false s/b false
sdc31: false s/b false
sdc32:  true s/b true
sdc33:  true s/b true
sdc34: false s/b false
sdc35:  true s/b true
sdc36:  true s/b true
sdc37: false s/b false
sdc38:  true s/b true
sdc39:  true s/b true
sdc40:  true s/b true
sdc41:  true s/b true
sdc42: false s/b false
sdc43: false s/b false
sdc44:  true s/b true
sdc45:  true s/b true
sdc46: false s/b false
sdc47: false s/b false
sdc48:  true s/b true
sdc49:  true s/b true
sdc50: false s/b false
sdc51:  true s/b true
sdc52:  true s/b true
sdc53: false s/b false
sdc54:  true s/b true
sdc55:  true s/b true
sdc56:  true s/b true
mdc1: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc3: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc4: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
ext47: hi george s/b hi george
ext48: hi george? s/b hi george?
ext49: hi george s/b hi george
ext50:

*** Runtime error: pascaline:227:Value out of range
samiam95124 commented 5 months ago

Progress on Pascaline test

samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6/pascaline_tests$ ./pascaline headertest1 headertest2 42 123.456 hi there < pascaline.inp
*******************************************************************************

                       TEST SUITE FOR PASCALINE

                 Copyright (C) 2022 S. A. Franco - All rights reserved

*******************************************************************************

The following are implementation defined characteristics

Maxcrd: 9223372036854775807
Maxlint: 9223372036854775807
Maxlcrd: 9223372036854775807
Maxchr: 255
Maxreal:  1.79769313486231e+308
Maxsreal:  1.79769313486231e+308
Maxlreal:  1.79769313486231e+308
Bit length of cardinal appears to be: 63
Bit length of long integer without sign appears to be: 63
Bit length of long cardinal appears to be: 63
Cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long integer default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
cmt1: <nothing>
id1: 42 s/b 42
glb1: start  stop s/b start stop
nc1: 165 s/b 165
nc2: 58 s/b 58
nc3: 25 s/b 25
nc3: 123456 s/b 123456
nc4: 3418164 s/b 3418164
nc5: 107482 s/b 107482
nc6: 87 s/b 87
ext15: 9223372036854775765 s/b 9223372036854775765
ext16: 130 s/b 130
ext17: 24 s/b 24
ext18: 0.0023 s/b 0.0022
ext19: 2 s/b 2
ext20: 12 s/b 12
ext21: -76 s/b -76
ext22: 54 s/b 54
ext23: 97 s/b 97
ext24: 53 s/b 53
ext25: 106 s/b 106
ext26: 42 s/b 42
ext27: abcdz s/b abcdz
ext28: 1 2 3 4 5 12  s/b 1 2 3 4 5 12
ext29: 432 s/b 432
ext30: Q s/b Q
ext31:   1.23456000000000e+00 s/b 1.23456000e+000
ext32: hi there s/b hi there
vb1: 9223372036854775751 s/b 9223372036854775751
vb2: 8 s/b 8
vb3: 61 s/b 61
vb4: 53 s/b 53
vop1: this is a test s/b this is a test
vop2: 42 s/b 42
vop3: g s/b g
ecs1:
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
s/b
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
vcr1: 42 43 a  s/b 42 43 a
ats1: hi there ? s/b hi there ?
ats2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
sdc1: hi there ? s/b hi there ?
sdc2: hi there ? s/b hi there ?
sdc3: hi there ? s/b hi there ?
sdc4: 143 276 388 412 574 622 74 83 99 1  s/b 143 276 388 412 574 622 74 83 99 1
sdc5: hi there ? s/b hi there ?
sdc6:  20 19 18 17 16 15 14 13 12 11 s/b 20 19 18 17 16 15 14 13 12 11
sdc7:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc8:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc9:  true s/b true
sdc10: false s/b false
sdc11: false s/b false
sdc12:  true s/b true
sdc13:  true s/b true
sdc14: false s/b false
sdc15: false s/b false
sdc16:  true s/b true
sdc17:  true s/b true
sdc18: false s/b false
sdc19:  true s/b true
sdc20:  true s/b true
sdc21: false s/b false
sdc22:  true s/b true
sdc23:  true s/b true
sdc24:  true s/b true
sdc25:  true s/b true
sdc26: false s/b false
sdc27: false s/b false
sdc28:  true s/b true
sdc29:  true s/b true
sdc30: false s/b false
sdc31: false s/b false
sdc32:  true s/b true
sdc33:  true s/b true
sdc34: false s/b false
sdc35:  true s/b true
sdc36:  true s/b true
sdc37: false s/b false
sdc38:  true s/b true
sdc39:  true s/b true
sdc40:  true s/b true
sdc41:  true s/b true
sdc42: false s/b false
sdc43: false s/b false
sdc44:  true s/b true
sdc45:  true s/b true
sdc46: false s/b false
sdc47: false s/b false
sdc48:  true s/b true
sdc49:  true s/b true
sdc50: false s/b false
sdc51:  true s/b true
sdc52:  true s/b true
sdc53: false s/b false
sdc54:  true s/b true
sdc55:  true s/b true
sdc56:  true s/b true
mdc1: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc3: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc4: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
ext47: hi george s/b hi george
ext48: hi george? s/b hi george?
ext49: hi george s/b hi george
ext50:
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
ext51:
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
ext52:
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
cp1: hi there s/b hi there
ew1:
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
s/b
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
ew2:
**
*h*
*hi*
*hi *
*hi t*
*hi th*
*hi the*
*hi ther*
*hi there*
* hi there*
*  hi there*
s/b
**
*h*
*hi*
*hi *
*hi t*
*hi th*
*hi the*
*hi ther*
*hi there*
* hi there*
*  hi there*
ew3:
**
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there *
*hi there  *
s/b
**
*h*
*hi*
*hi *
*hi t*
*hi th*
*hi the*
*hi ther*
*hi there*
*hi there *
*hi there  *
ew4:
hi there<
s/b
hi there<
ew5:
*10*
*10*
*10*
*010*
*0010*
*00010*
*000010*
*0000010*
*00000010*
*000000010*
*0000000010*
s/b
*10*
*10*
*10*
*010*
*0010*
*00010*
*000010*
*0000010*
*00000010*
*000000010*
*0000000010*
ew6:
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
s/b
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
ew7: abcdef s/b abcdef
ew8: 76543 s/b 76543
ew9: 1100101 s/b 1100101
ew10:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
* 123abc*
*  123abc*
*   123abc*
*    123abc*
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
* 123abc*
*  123abc*
*   123abc*
*    123abc*
ew11:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
ew12:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*0123abc*
*00123abc*
*000123abc*
*0000123abc*
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*0123abc*
*00123abc*
*000123abc*
*0000123abc*
ew13:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
ew14:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
* 123765*
*  123765*
*   123765*
*    123765*
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
* 123765*
*  123765*
*   123765*
*    123765*
ew15:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
ew16:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*0123765*
*00123765*
*000123765*
*0000123765*
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*0123765*
*00123765*
*000123765*
*0000123765*
ew17:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
er1: hi there ? s/b hi there ?
Segmentation fault (core dumped)
samiam95124 commented 4 months ago

Progress on Pascaline test

samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6/pascaline_tests$ ./pascaline headertest1 headertest2 42 123.456 hi there < pascaline.inp
*******************************************************************************

                       TEST SUITE FOR PASCALINE

                 Copyright (C) 2022 S. A. Franco - All rights reserved

*******************************************************************************

The following are implementation defined characteristics

Maxcrd: 9223372036854775807
Maxlint: 9223372036854775807
Maxlcrd: 9223372036854775807
Maxchr: 255
Maxreal:  1.79769313486231e+308
Maxsreal:  1.79769313486231e+308
Maxlreal:  1.79769313486231e+308
Bit length of cardinal appears to be: 63
Bit length of long integer without sign appears to be: 63
Bit length of long cardinal appears to be: 63
Cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long integer default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
Long cardinal default output field
         1111111111222222222233333333334
1234567890123456789012345678901234567890
          1
cmt1: <nothing>
id1: 42 s/b 42
glb1: start  stop s/b start stop
nc1: 165 s/b 165
nc2: 58 s/b 58
nc3: 25 s/b 25
nc3: 123456 s/b 123456
nc4: 3418164 s/b 3418164
nc5: 107482 s/b 107482
nc6: 87 s/b 87
ext15: 9223372036854775765 s/b 9223372036854775765
ext16: 130 s/b 130
ext17: 24 s/b 24
ext18: 0.0023 s/b 0.0022
ext19: 2 s/b 2
ext20: 12 s/b 12
ext21: -76 s/b -76
ext22: 54 s/b 54
ext23: 97 s/b 97
ext24: 53 s/b 53
ext25: 106 s/b 106
ext26: 42 s/b 42
ext27: abcdz s/b abcdz
ext28: 1 2 3 4 5 12  s/b 1 2 3 4 5 12
ext29: 432 s/b 432
ext30: Q s/b Q
ext31:   1.23456000000000e+00 s/b 1.23456000e+000
ext32: hi there s/b hi there
vb1: 9223372036854775751 s/b 9223372036854775751
vb2: 8 s/b 8
vb3: 61 s/b 61
vb4: 53 s/b 53
vop1: this is a test s/b this is a test
vop2: 42 s/b 42
vop3: g s/b g
ecs1:
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
s/b
1: one
2: from 2 to 4
3: from 2 to 4
4: from 2 to 4
5: from 5 to 10
6: from 5 to 10
7: from 5 to 10
8: from 5 to 10
9: from 5 to 10
10: from 5 to 10
vcr1: 42 43 a  s/b 42 43 a
ats1: hi there ? s/b hi there ?
ats2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
sdc1: hi there ? s/b hi there ?
sdc2: hi there ? s/b hi there ?
sdc3: hi there ? s/b hi there ?
sdc4: 143 276 388 412 574 622 74 83 99 1  s/b 143 276 388 412 574 622 74 83 99 1
sdc5: hi there ? s/b hi there ?
sdc6:  20 19 18 17 16 15 14 13 12 11 s/b 20 19 18 17 16 15 14 13 12 11
sdc7:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc8:  30 29 28 27 26 25 24 23 22 21 s/b 30 29 28 27 26 25 24 23 22 21
sdc9:  true s/b true
sdc10: false s/b false
sdc11: false s/b false
sdc12:  true s/b true
sdc13:  true s/b true
sdc14: false s/b false
sdc15: false s/b false
sdc16:  true s/b true
sdc17:  true s/b true
sdc18: false s/b false
sdc19:  true s/b true
sdc20:  true s/b true
sdc21: false s/b false
sdc22:  true s/b true
sdc23:  true s/b true
sdc24:  true s/b true
sdc25:  true s/b true
sdc26: false s/b false
sdc27: false s/b false
sdc28:  true s/b true
sdc29:  true s/b true
sdc30: false s/b false
sdc31: false s/b false
sdc32:  true s/b true
sdc33:  true s/b true
sdc34: false s/b false
sdc35:  true s/b true
sdc36:  true s/b true
sdc37: false s/b false
sdc38:  true s/b true
sdc39:  true s/b true
sdc40:  true s/b true
sdc41:  true s/b true
sdc42: false s/b false
sdc43: false s/b false
sdc44:  true s/b true
sdc45:  true s/b true
sdc46: false s/b false
sdc47: false s/b false
sdc48:  true s/b true
sdc49:  true s/b true
sdc50: false s/b false
sdc51:  true s/b true
sdc52:  true s/b true
sdc53: false s/b false
sdc54:  true s/b true
sdc55:  true s/b true
sdc56:  true s/b true
mdc1: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc2: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc3: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
mdc4: 
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
ext47: hi george s/b hi george
ext48: hi george? s/b hi george?
ext49: hi george s/b hi george
ext50:
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
ext51:
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46 123  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
ext52:
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
s/b
 100  99  98  97  96  95  94  93  92  91
  90  89  88  87  86  85  84  83  82  81
  80  79  78  77  76  75  74  73  72  71
  70  69  68  67  66  65  64  63  62  61
  60  59  58  57  56  55  54  53  52  51
  50  49  48  47  46  45  44  43  42  41
  40  39  38  37  36  35  34  33  32  31
  30  29  28  27  26  25  24  23  22  21
  20  19  18  17  16  15  14  13  12  11
  10   9   8   7   6   5   4   3   2   1
cp1: hi there s/b hi there
ew1:
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
s/b
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
ew2:
**
*h*
*hi*
*hi *
*hi t*
*hi th*
*hi the*
*hi ther*
*hi there*
* hi there*
*  hi there*
s/b
**
*h*
*hi*
*hi *
*hi t*
*hi th*
*hi the*
*hi ther*
*hi there*
* hi there*
*  hi there*
ew3:
**
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there*
*hi there *
*hi there  *
s/b
**
*h*
*hi*
*hi *
*hi t*
*hi th*
*hi the*
*hi ther*
*hi there*
*hi there *
*hi there  *
ew4:
hi there<
s/b
hi there<
ew5:
*10*
*10*
*10*
*010*
*0010*
*00010*
*000010*
*0000010*
*00000010*
*000000010*
*0000000010*
s/b
*10*
*10*
*10*
*010*
*0010*
*00010*
*000010*
*0000010*
*00000010*
*000000010*
*0000000010*
ew6:
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
s/b
*10*
*10*
*10*
*10 *
*10  *
*10   *
*10    *
*10     *
*10      *
*10       *
*10        *
ew7: abcdef s/b abcdef
ew8: 76543 s/b 76543
ew9: 1100101 s/b 1100101
ew10:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
* 123abc*
*  123abc*
*   123abc*
*    123abc*
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
* 123abc*
*  123abc*
*   123abc*
*    123abc*
ew11:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
ew12:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*0123abc*
*00123abc*
*000123abc*
*0000123abc*
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*0123abc*
*00123abc*
*000123abc*
*0000123abc*
ew13:
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
s/b
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc*
*123abc *
*123abc  *
*123abc   *
*123abc    *
ew14:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
* 123765*
*  123765*
*   123765*
*    123765*
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
* 123765*
*  123765*
*   123765*
*    123765*
ew15:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
ew16:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*0123765*
*00123765*
*000123765*
*0000123765*
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*0123765*
*00123765*
*000123765*
*0000123765*
ew17:
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
s/b
*123765*
*123765*
*123765*
*123765*
*123765*
*123765*
*123765 *
*123765  *
*123765   *
*123765    *
er1: hi there ? s/b hi there ?
er2: lo there ? s/b lo there ?
er3: 42 92 s/b 42 92
er4: 92 421 s/b 92 421
er5: 456 s/b 456
er6: a s/b a
er7: hi there ? s/b hi there ?
er8: lo there ? s/b lo there ?
er9: bite me  ?42 s/b bite me  ?42
er10: 1234567890 s/b 1234567890
er11: 1234.5678 9876.5432 s/b 1234.5678 9876.5432
er14: hi!       < s/b hi!       <
tcr1: one two three  s/b one two three
tcr2: 53 s/b 53 
f1: 1 5 3 10 92  s/b 1 5 3 10 92
f2: ahuoz s/b ahuoz
f3: 1.1 1.2 1.3 1.4 1.5  s/b 1.1 1.2 1.3 1.4 1.5
f4: 1 3 64 2 12 31 647 21 190 32 641 243  s/b 1 3 64 2 12 31 647 21 190 32 641 243
f5: 42a1.2340 s/b 42a1.2340
f6: -42 s/b -42
fh1: hi there, bob s/b hi there, bob
fh2: hi there, bob s/b hi there, bob
fh3: false s/b false
fh4:  true s/b true
fh5: false s/b false
fh6: 1 2 3 4 5 6 7 8 9 10  s/b 1 2 3 4 5 6 7 8 9 10
fh7: 10 s/b 10
fh8: 11 s/b 11
fh9: 5 s/b 5
fh10: 6 s/b 6
fh11:  99 99 99 99 99  6  7  8  9 10 s/b  99  99  99  99  99   6   7   8   9  10
fh12: 
The rain in spain
falls mainly on the plain
The rain in spain
falls mainly on the plain
But only on tuesdays and thursdays
s/b
The rain in spain
falls mainly on the plain
The rain in spain
falls mainly on the plain
But only on tuesdays and thursdays
hbt1:
The rain in spain falls mainly on the plain.
s/b
The rain in spain falls mainly on the plain
hbt2:
1 2 3 4 5 6 7 8 9 10  s/b 1 2 3 4 5 6 7 8 9 10
hbt3: 42 s/b 42
hbt4: 123.456 s/b 123.456
hbt5: 
 hi there 
s/b
 hi there
hbt6:
This is a test of the error file
s/b
This is a test of the error file
hbt7:
Segmentation fault (core dumped)
samiam95124 commented 4 months ago

Change of direction?

I have been really fighting with the layout of strings and sets. The problem is that pgen treats them differently. pgen puts them in temps, pint keeps them onstack and does shuffling to get/keep them in order. Here is the example:

program test(output);

type
     string10 = packed array 10 of char;

function strret: string10;

begin

    result 'hi there ?'

end;

begin

   writeln('sfr3: ', strret, ' s/b hi there ?');

end.

        lca     6 'sfr3:'               ! Load constant string address          ! get string address
        lao     2                       ! Load global address                   ! get output address
        swp     8                       ! Swap tos with sos                     ! put output at bottom
        ldci    6                       ! Load constant(t)                      ! get string length
        swp     8                       ! Swap tos with sos                     ! order addr/len, output
        mpc     0 0                     ! Make fat pointer from components      !                                  
        ldci    6                       ! Load constant(t)                      ! get field
        csp     wrs                     ! Call system procedure/function: Write string to text file

! ok to here

        sfr     l test.17               ! Set function result                   !                           
l test.17=16
        cuf     l test.8 0 3 10 16      ! Call user function                    ! call strret, now 'hi there ?' on stack
:16
        lsa     0                       ! Load stack address                    ! index that                             
        ldci    10                      ! Load constant(t)                      ! load length, so now len, addr, string, output (kept from before)
        swp     8                       ! Swap tos with sos                     ! now addr/len, string(16) output
        mpc     0 0                     ! Make fat pointer from components                                      
        lsa     32                      ! Load stack address                    ! index output                                                                               
        inda    0                       ! Load indirect(t)                      ! fetch that, now output, addr/len, string(16), output
        swp     16                      ! Swap tos with sos                     ! swap output under addr/len
        ldci    10                      ! Load constant(t)                      ! load field                             
        csp     wrs                     ! Call system procedure/function: Write string to text file, now output, string(16)
        dmp     24                      ! Dump tos                              ! dump output, string(16)

So my thought was this occurred because pint and pgen and pint are going in different directions. So I am thinking that pgen should have stayed with pint's all stack method, or pint should be refactored to use temps. To illustrate this I did a test refactor by hand:

! refactor above

        sfr     l test.17               ! Set function result                   ! output on stack (held by the wrs)
        cuf     l test.8 0 3 10 16      ! Call user function                    ! call strret, move string to temp, saddr on stack, then output from above
        ldci    10                      ! Load constant(t)                      ! load length, so now len, saddr, output
        swp     8                       ! Swap tos with sos                     ! now saddr/len, output
        mpc     0 0                     ! Make fat pointer from components 
        ldci    10                      ! Load constant(t)                      ! load field 
        csp     wrs                     ! Call system procedure/function: Write string to text file, now output
        dmp     8                       ! Dump tos                              ! dump output

That's just the last part of the code. The idea is that the call to strret() ends by the cuf instruction moving the string result to a temp and replacing it on stack by the address of that temp. Then notice everything else falls into line after that. The sfr/cuf strret just acts like an lca of the string. The best thing is this is completely compatible with pgen because they work the same way.

So I am thinking pint gets the locals temp thing from pgen. Sets can also use this system just as pgen does. Sets really are a structure (array of bits). They got treated like scalars because on the CDC6000 they fit into a register like a scalar, but it will be smoother to treat them like structures (including the copy into value parameter thing), especially when they get bigger and vary in length (which is pretty much inevitable).

The drawback is that is a significant refactor. It can be broken into structures/strings first, then sets later. It will drag the schedule, but its probably the right thing to do. Pulldown displays was also a significant refactor of the old code, and that worked out.

samiam95124 commented 4 months ago

thoughts

I think leaving only pointers on the stack is a good idea. pgen works this way now, Pascal-P used to work that way, and doing so will bring the working methods of pcom and pgen together.

I also think that pcom is the place to do that. There is already one mechanisim to do that, getcbb()/putcbb(). As pgen demonstrates, it does not matter so much where you allocate stack temps, but I think its better if it starts from the beginning in pcom.

samiam95124 commented 4 months ago

More... thoughts

I think the thunk layer for external calls can be done better in C. gcc can generate frameless functions, and so I think it is worth a try. Obviously it will be more portable to do thunks in C.

samiam95124 commented 4 months ago

That LSA instruction

So the specific path I want to modify is loads of structured results, a Pascaline extension. This will solve the current issue with Pascaline, and it will form a prototype of methods going forward.

The problem

Right now, structured returns are loaded on stack and get typed (by gattr.kind) of "expr", meaning a value on the stack. Right now, there isn't much that can be done with such values. callnonstandard() converts them to addressed values via cpy2adr(), which is exactly what I want to do, but in a different way. assignment() also accepts them, but the action there is to move them to the final address, which is perfectly valid. The problem is other consumers of these expressions, like writeprocedure(). It converts the kind = expr status into the variable "onstk", and then uses that to perform various stack rearrangements, and those stack rearrangements are the issue.

proposed solution

The gettmp(), puttmp() and deltmp() functions are imported, pretty much as is, from pgen. In loadaddress(), the kind = expr case is handled by the LSA instruction. Instead we handle it by moving the onstack element to a temp, then replacing that with its temp buffer address. This is not trivial! loadaddress() needs both the length of the element AND its stack allocation (aligned to stackal) to do this. Now the downstream implications of this become:

callnonstandard() - This routine uses cpy2adr() to move the result off stack into a buffer, just as the temp system will. The alternative to doing that is calling loadaddress(). With the change to loadaddress() to move the result to a temp and return the address, this becomes a simple call to loadaddress().

writeprocedure() - This only happens with strings, and those strings that are passed on stack. Simple (ISO 7185) strings are passed by address. Thus a call to loadaddress() will fix these calls up, and result in the code shown in "change of direction" above.

assignment() - For any structured type on stack, assignment() generates a load(), which treats kind = expr as a no-op (its already loaded to stack), then generates a stom instruction, that knows how to store the structure on stack directly. The bottom line is this is more efficient than copying to a temp buffer, then transferring it later to the target variable. This is, of course, optional. It is easier just to let it go through a temp.

In all of these consumer cases, the temps must be freed, since they only span expressions. They can be reallocated from locals as long as the function/procedure is active, but are all freed to a list of simple (unallocated) entries when the function/procedure ends.

samiam95124 commented 4 months ago

Refactor

The plan above for this refactor are good. The issues with the refactor are:

  1. Its a significant bit of surgery that must leave the ISO 7185 capabilities intact. We are already dependent on pgen as a backend.
  2. It has implications beyond the refactor. As said, it implies that sets must also be refactored.
  3. I am out of time. I have a new position and new responsibilities. My time here is limited.

It's imperative that this issue gets closed out, since this is a major part of the v0.3 release. Thus the plan is to complete this and file a new issue against sets and move on.

samiam95124 commented 4 months ago

Last idea, I don't know if this will ever get implemented:

If sets are passed as addresses, the only thing left onstack that is not an address is returns, and structured returns at that. The reason for doing this is that the value of a structured return is defined as being in the locals of the returning function, so effectively needs to be transfered from the locals of the called function to the function/procedure locals of the caller.

The other way to do this is to use the sfr to pass the local address of the return value. Thus the function assignment of the called function deposits the result directly to the local buffer of the caller.

samiam95124 commented 3 months ago

Temps refactor

Almost done with the first part of this. pint runs the full suite, including Pascaline. Next pmach and cmach need to be updated, then return to pgen debugging for Pascaline.

samiam95124 commented 2 months ago

Completed temps refactor. pmach and cmach next.

If sets work without using temps, will proceed using the current system. Sets are better off using the same temps, but if this system works (as it appears it does), it goes down in priority order.

On to version 0.3, which will happen once pgen runs the regression tests.

samiam95124 commented 2 months ago

Pint, pmach and cmach all run tests complete. Next is back to pgen.

samiam95124 commented 2 months ago

pgen passes all tests but Pascaline.

Pascaline output diff is:

samiam@samiam-h-pc-2:~/projects/pascal/pascal-p6/pascaline_tests$ diff pascaline.lst pascaline.cmp 0a1,5

P6 Pascal interpreter vs. 0.2.x

Assembling/loading program Running program

277c282 < 50 49 48 47 46 123 44 43 42 41

50 49 48 47 46 45 44 43 42 41 418,424c423,429 < hi there < hi there < hi there < hi there < hi there < hi there < hi there

h hi hi hi t hi th hi the hi ther 735a741 This is a test of the error file 744c750 < sfr2: lo there ? s/b hi there ?

sfr2: hi there ? s/b hi there ? 811a818,1132 exception taken s/b before exception exception taken ex2: In try block exception not taken s/b In try block exception not taken as1: Testing negative assertion, this should not stop here linteger1: 121 s/b 121 linteger2: 35 s/b 35 linteger3: 3354 s/b 3354 linteger4: 1 s/b 1 linteger5: 35 s/b 35 linteger6: 44 s/b 44 linteger7: 42 s/b 42 linteger8: 1849 s/b 1849 linteger9: N s/b N linteger10: 43 s/b 43 linteger11: true s/b true linteger12: false s/b false linteger13: true s/b true linteger14: false s/b false linteger15: true s/b true linteger16: false s/b false linteger17: true s/b true linteger18: false s/b false linteger19: true s/b true linteger20: false s/b false linteger21: true s/b true linteger22: true s/b true linteger23: false s/b false linteger24: true s/b true linteger25: true s/b true linteger26: false s/b false linteger27: 6 s/b 6 linteger28: 6 s/b 6 linteger29: -12 s/b -12 linteger30: -46 s/b -46 linteger31: 34 s/b 34 linteger32: -52 s/b -52 linteger33: -18 s/b -18 linteger34: -280 s/b -280 linteger35: -280 s/b -280 linteger36: 448 s/b 448 linteger37: -1 s/b -1 linteger38: -1 s/b -1 linteger39: 2 s/b 2 linteger40: -13 s/b -13 linteger41: -33 s/b -33 linteger42: 196 s/b 196 linteger43: false s/b false linteger44: true s/b true linteger45: true s/b true linteger46: false s/b false linteger47: true s/b true linteger48: false s/b false linteger49: true s/b true linteger50: true s/b true linteger51: false s/b false linteger52: false s/b false linteger53: true s/b true linteger54: true s/b true linteger55: false s/b false linteger56: false s/b false linteger57: true s/b true linteger58: true s/b true linteger59: true s/b true linteger60: false s/b false linteger61: false s/b false linteger62: true s/b true linteger63: true s/b true linteger64: true s/b true linteger65: false s/b false linteger66: false s/b false linteger67: 14 s/b 14 linteger68: 0 s/b 0 linteger69: 0 s/b 0 linteger70: 0 s/b 0 cardinal1: 121 s/b 121 cardinal2: 35 s/b 35 cardinal3: 3354 s/b 3354 cardinal4: 1 s/b 1 cardinal5: 35 s/b 35 cardinal6: 44 s/b 44 cardinal7: 42 s/b 42 cardinal8: 1849 s/b 1849 cardinal9: N s/b N cardinal10: 43 s/b 43 cardinal11: true s/b true cardinal12: false s/b false cardinal13: true s/b true cardinal14: false s/b false cardinal15: true s/b true cardinal16: false s/b false cardinal17: true s/b true cardinal18: false s/b false cardinal19: true s/b true cardinal20: false s/b false cardinal21: true s/b true cardinal22: true s/b true cardinal23: false s/b false cardinal24: true s/b true cardinal25: true s/b true cardinal26: false s/b false lcardinal1: 121 s/b 121 lcardinal2: 35 s/b 35 lcardinal3: 3354 s/b 3354 lcardinal4: 1 s/b 1 lcardinal5: 35 s/b 35 lcardinal6: 44 s/b 44 lcardinal7: 42 s/b 42 lcardinal8: 1849 s/b 1849 lcardinal9: N s/b N lcardinal10: 43 s/b 43 lcardinal11: true s/b true lcardinal12: false s/b false lcardinal13: true s/b true lcardinal14: false s/b false lcardinal15: true s/b true lcardinal16: false s/b false lcardinal17: true s/b true lcardinal18: false s/b false lcardinal19: true s/b true lcardinal20: false s/b false lcardinal21: true s/b true lcardinal22: true s/b true lcardinal23: false s/b false lcardinal24: true s/b true lcardinal25: true s/b true lcardinal26: false s/b false sreal1: 1.4189000e+03 s/b 1.418900e+03 sreal2: 5.4844000e+02 s/b 5.484399e+02 sreal3: 4.2812269e+05 s/b 4.281227e+05 sreal4: 2.2601153e+00 s/b 2.260115e+00 sreal5: true s/b true sreal6: false s/b false sreal7: true s/b true sreal8: false s/b false sreal9: true s/b true sreal10: false s/b false sreal11: true s/b true sreal12: false s/b false sreal13: true s/b true sreal14: true s/b true sreal15: false s/b false sreal16: true s/b true sreal17: true s/b true sreal18: false s/b false sreal19: 4.3523000e+02 s/b 4.35230e+02 sreal20: 1.8942515e+05 s/b 1.89425e+05 sreal21: 3.1363514e+01 s/b 3.13635e+01 sreal22: -3.4430594e-01 s/b -3.44290e-01 sreal23: 1.5684987e+00 s/b 1.56850e+00 sreal24: 1.4110019e+00 s/b 1.41100e+00 sreal25: 6.0758746e+00 s/b 6.07587e+00 sreal26: 435 s/b 435 sreal27: 984 s/b 984 sreal28: 435 s/b 435 sreal29: 3.0034000e+02 s/b 3.003400e+02 sreal30: 3.0034000e+02 s/b 3.003400e+02 sreal31: -6.5999800e+03 s/b -6.599980e+03 sreal32: -8.3687200e+03 s/b -8.368720e+03 sreal33: 1.7687400e+03 s/b 1.768740e+03 sreal34: -8.6690600e+03 s/b -8.669061e+03 sreal35: -6.9003200e+03 s/b -6.900320e+03 sreal36: -7.5955927e+05 s/b -7.595593e+05 sreal37: -7.5955927e+05 s/b -7.595593e+05 sreal38: 5.6052646e+06 s/b 5.605265e+06 sreal39: -1.4090711e+00 s/b -1.409071e+00 sreal40: -7.3796277e+00 s/b -7.379627e+00 sreal41: 1.0398420e+01 s/b 1.039842e+01 sreal42: true s/b true sreal43: false s/b false sreal44: true s/b true sreal45: false s/b false sreal46: true s/b true sreal47: true s/b true sreal48: false s/b false sreal49: false s/b false sreal50: true s/b true sreal51: true s/b true sreal52: false s/b false sreal53: false s/b false sreal54: true s/b true sreal55: true s/b true sreal56: true s/b true sreal57: false s/b false sreal58: false s/b false sreal59: true s/b true sreal60: true s/b true sreal61: true s/b true sreal62: false s/b false sreal63: false s/b false sreal64: 7.3420000e+02 s/b 7.34200e+02 sreal65: 5.3904964e+05 s/b 5.39050e+05 sreal66: -4.3483206e-01 s/b -4.34850e-01 sreal67: -1.5694343e+00 s/b -1.56943e+00 sreal68: 6.8056632e-01 s/b 6.80566e-01 sreal69: -734 s/b -734 sreal70: -7635 s/b -7635 sreal71: -734 s/b -734 lreal1: 1.4189000e+03 s/b 1.418900e+03 lreal2: 5.4844000e+02 s/b 5.484399e+02 lreal3: 4.2812269e+05 s/b 4.281227e+05 lreal4: 2.2601153e+00 s/b 2.260115e+00 lreal5: true s/b true lreal6: false s/b false lreal7: true s/b true lreal8: false s/b false lreal9: true s/b true lreal10: false s/b false lreal11: true s/b true lreal12: false s/b false lreal13: true s/b true lreal14: true s/b true lreal15: false s/b false lreal16: true s/b true lreal17: true s/b true lreal18: false s/b false lreal19: 4.3523000e+02 s/b 4.35230e+02 lreal20: 1.8942515e+05 s/b 1.89425e+05 lreal21: 3.1363514e+01 s/b 3.13635e+01 lreal22: -3.4430594e-01 s/b -3.44290e-01 lreal23: 1.5684987e+00 s/b 1.56850e+00 lreal24: 1.4110019e+00 s/b 1.41100e+00 lreal25: 6.0758746e+00 s/b 6.07587e+00 lreal26: 435 s/b 435 lreal27: 984 s/b 984 lreal28: 435 s/b 435 lreal29: 3.0034000e+02 s/b 3.003400e+02 lreal30: 3.0034000e+02 s/b 3.003400e+02 lreal31: -6.5999800e+03 s/b -6.599980e+03 lreal32: -8.3687200e+03 s/b -8.368720e+03 lreal33: 1.7687400e+03 s/b 1.768740e+03 lreal34: -8.6690600e+03 s/b -8.669061e+03 lreal35: -6.9003200e+03 s/b -6.900320e+03 lreal36: -7.5955927e+05 s/b -7.595593e+05 lreal37: -7.5955927e+05 s/b -7.595593e+05 lreal38: 5.6052646e+06 s/b 5.605265e+06 lreal39: -1.4090711e+00 s/b -1.409071e+00 lreal40: -7.3796277e+00 s/b -7.379627e+00 lreal41: 1.0398420e+01 s/b 1.039842e+01 lreal42: true s/b true lreal43: false s/b false lreal44: true s/b true lreal45: false s/b false lreal46: true s/b true lreal47: true s/b true lreal48: false s/b false lreal49: false s/b false lreal50: true s/b true lreal51: true s/b true lreal52: false s/b false lreal53: false s/b false lreal54: true s/b true lreal55: true s/b true lreal56: true s/b true lreal57: false s/b false lreal58: false s/b false lreal59: true s/b true lreal60: true s/b true lreal61: true s/b true lreal62: false s/b false lreal63: false s/b false lreal64: 7.3420000e+02 s/b 7.34200e+02 lreal65: 5.3904964e+05 s/b 5.39050e+05 lreal66: -4.3483206e-01 s/b -4.34850e-01 lreal67: -1.5694343e+00 s/b -1.56943e+00 lreal68: 6.8056632e-01 s/b 6.80566e-01 lreal69: -734 s/b -734 lreal70: -7635 s/b -7635 lreal71: -734 s/b -734 um1: This is the used module: 87 s/b this is the used module: 87 ov1: This is the overriding procedure This is the abstract procedure s/b This is the overriding procedure This is the abstract procedure lm1: This is the joined module: 87 s/b this is the joined module: 87 lm2: This is zork zork: the integer is: 52 zork: the string is: hi there 42 s/b This is zork zork: the integer is: 52 zork: the string is: hi there 42 ce1: my'self s/b my'self ce2: this\one s/b thisone ce3: e s/b e ce4: o s/b o ce5: Z s/b Z ce6: I s/b I ce7: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 17 18 19 19 20 21 22 23 24 25 26 27 28 29 30 31 127 92 s/b 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 17 18 19 19 20 21 22 23 24 25 26 27 28 29 30 31 127 ce8: \ s/b \ ce9: a s/b a ht: The test should now halt 813c1134 < *** Runtime error: psystem:4481:Function not implemented

program complete

So biggest difference is exceptions are not implemented.

samiam95124 commented 2 months ago

Status

Working on exceptions.

samiam95124 commented 2 months ago

Status

samiam95124 commented 2 months ago

External variables

um1 tests access to external variables, and that fails. pgen assumes it is a local global, which is incorrect.

samiam95124 commented 2 months ago

Status

External variables was a simple issue. The new pascaline test difference file is:

277c279
<   50  49  48  47  46 123  44  43  42  41
---
>   50  49  48  47  46  45  44  43  42  41
418,424c420,426
< *hi there*
< *hi there*
< *hi there*
< *hi there*
< *hi there*
< *hi there*
< *hi there*
---
> *h*
> *hi*
> *hi *
> *hi t*
> *hi th*
> *hi the*
> *hi ther*
735a738
> This is a test of the error file
744c747
< sfr2: lo there ? s/b hi there ?
---
> sfr2: hi there ? s/b hi there ?

So down to 4 errors with this test.

samiam95124 commented 2 months ago

Status

418,424c423,429
< *hi there*
< *hi there*
< *hi there*
< *hi there*
< *hi there*
< *hi there*
< *hi there*
---
> *h*
> *hi*
> *hi *
> *hi t*
> *hi th*
> *hi the*
> *hi ther*
735a741
> This is a test of the error file
744c750
< sfr2: lo there ? s/b hi there ?
---
> sfr2: hi there ? s/b hi there ?

3 more to go.

samiam95124 commented 2 months ago

Status

735a741
> This is a test of the error file
744c750
< sfr2: lo there ? s/b hi there ?
---
> sfr2: hi there ? s/b hi there ?

Two more to go.

samiam95124 commented 2 months ago

Status

745c750
< sfr2: lo there ? s/b hi there ?
---
> sfr2: hi there ? s/b hi there ?

Last error.

samiam95124 commented 2 months ago

Tickets I want to complete for v0.3

We are nearing the end of the v0.3 round of changes. There are a few tickets I want to include in v0.3, if for no other reason that I want to not have to document some of the current kwirks of the system:

159 Using rax for returns - Because I don't want to write and discard a whole set of external wrappers for Petit-ami and other external libraries.

157 Adding header parsing - Will regularize the program format with little effort.

139 Error line output - Easy to do and will significantly aid program development.

137 Remove dependence on CPP - Easy, significantly clarifies program building, and can be removed from docs.

136 same as #137

134 Self compile macro can be removed - easy

150 Refactor local accesses for current block - Will dramatically improve the code for medium effort.

samiam95124 commented 2 months ago

Remaining tasks for v0.3

Besides the above ticket list there are:

  1. Last Pascaline error above.
  2. The debugger test failure.
  3. New round of manual changes.
samiam95124 commented 2 months ago

Status

Working on failing example:

program test(output);

type string10 = packed array 10 of char;

var ps10(10): string;

function strret: string10;

begin

    result 'hi there ?'

end;

begin

   ps10 := 'lo there ?';
   ps10 := strret;
   writeln(ps10)

end.

Output is:

lo there ?

First issue is the code is showing strret() is called twice in the program, so apparently the call tree is messed up.

samiam95124 commented 2 months ago

double execution of functions

So in one of the previous iterations on pgen, I simplified the cps instruction by copying its tree branches back to the stack and executing it immediately. It effectively treats cps as a terminal instruction, since it does not yield a result and needs no parent.

It works, but it has a side effect. If functions are used in the duplicated tree, they are duplicated as well. They "work", but double executing functions can fail if they have side effects. Its "wrong" to have a function with side effects, as in "bad practice". However, its still acceptable Pascal. My bad.

This will need to be fixed.

samiam95124 commented 2 months ago

A solution

I considered this issue of duplicate trees while blowing up other players with a well placed rocket shot in Open Arena team play[1]. I realized that the code was trying to tell me something, and I came up with a possible refactor.

The solution of duplicating trees came up as a general solution to so called "transparent operators", which are operators that take in input, give an output, but pass through their operands from input to output. The operators that do that were inserted to run checks on the operands, like checking array indexes, etc. This can work with the tree intermediate structure, but causes problems with operators that give two operands as a result. The cps operator is one such operator.

The tree duplication idea is the fact that we can easily create copies of complete subtrees in the intermediate. This allowed cps (for example) to duplicate the subtree, execute it separately from the rest of the expression, then continue. It works because expression trees are generally invariant. The fly in that ointment was that user functions can be invariant, a nasty but valid practice.

This was all done before I added a temporaries tracking feature, originally designed to handle sets, but expanded to handle other situations in the code. Now the solution to using such "split trees" in the code is to go ahead and calculate the subtree in the code, then copy the result(s) of the subtree to temps. This would solve the cps operator, as well as give a general solution to the dup operator.

The rise of the temps subsystem

So the same temps system is now in both the compiler (pcom) and the generator (pgen). How does that work? The temps system in pcom tracks temps that are known about at compile time. That allocation is built into the generated intermediate via the mst instruction. pgen has the same temps system, in fact some of the same code, but tracks temps at generation time, based on a broader view of the executed code than pcom has, namely the tree structure of the code, at least as far as expressions go.

This makes the temps allocator something of a swiss army knife in Pascal-P6.

If the plan goes forward to go from expression trees to full program graph, then the temps system forms the foundation for SSA (single static assignment) register allocation methods. At that point Pascal-P6 would move into the first class tier of compilers.

[1] Hey, sometimes you have to go relax.