NewOPL

Use this section to showcase your programming examples. Or to ask members for programming suggestions
Post Reply
amenjet
Posts: 299
Joined: Tue Jan 03, 2023 7:54 pm

NewOPL

Post by amenjet »

I thought I'd start a topic to put progress on the NewOPL into.

The latest version:

https://github.com/blackjetrock/newopl

has just run example 4 in the 'Language' section of the technical manual.

This doesn't mean it's nearly finished, as the code implements only what is needed to run this example. It does, however:

Load procedure XXX onto a stack
Execute procedure XXX which itself:
Loads procedure EX4 onto the stack as well
Executes procedure EX4 which
Writes a value to global J$ (which is defined in XXX, so the stack frames have to be traversed to find J$)
Exits and the stack is unwinds
XXX continues and also exits

The OPL:

Code: Select all

 
                XXX:
                GLOBAL J$(3)
                EX4:("RST")

Code: Select all

 
                EX4:(PPP$)
                LOCAL A$(5)
                GLOBAL B,C%(3),D$(5)
                J$=PPP$
This involves quite a lot of stack manipulation and also procedure loading. This is all quite complicated and I now know more about it than I ever thought I would.
The code also runs the original QCodes. I translated the OPL for the example in Jape and the executables on Linux run those files unchanged. The stack also matches the example almost exactly (there are some differences which I think are either typos or changes in code from when the example was made to the translator I used). So it's pretty much byte compatible.

If you want to run it (it dumps a lot of debug at the moment), then clone the newopl repo then:

Code: Select all

cd newopl/pc
./m
./newopl_exec ../examples/XXX.OB3
this will build the executables and then run example 4. XXX.OB3 is the example procedure. It loads from the file system at the moment and will load the next procedure as required. The output is debug messages and machine states at various stages of execution. The code is fairly tidy.

the result is fairly uninteresting, but correct:

Code: Select all

Stack reset
push_machine_8:pushing 00 to 3EFF
push_machine_8:pushing 00 to 3EFE
push_machine_8:pushing 00 to 3EFD
push_machine_8:pushing 00 to 3EFC
push_machine_8:pushing 00 to 3EFB
push_machine_8:pushing 00 to 3EFA
push_machine_8:pushing 00 to 3EF9
push_machine_8:pushing 00 to 3EF8
===  Exit ====
3EFF: 00 .
3EFE: 00 .
3EFD: 00 .
3EFC: 00 .
3EFB: 00 .
3EFA: 00 .
3EF9: 00 .
3EF8: 00 .
That's an empty stack with a floating point zero on it. At least I'm pretty sure that's correct.

I have arranged the code so it works on 'machines'. A machine is an OPL runtime, I did this so you could run multiple machines at once in the future without too much work...

There's lots to do, but the core of the runtime (loading procedures and executing qcodes) is largely there. Lots more qcodes to implement...
amenjet
Posts: 299
Joined: Tue Jan 03, 2023 7:54 pm

Re: NewOPL

Post by amenjet »

Something a bit more accessible:

Code: Select all


prnt1:

LOCAL A%, A1%
GLOBAL G%,G1%,GG%

A%=1
A1%=11
G%=6
GG%=66
G1%=61
PRINT A%
PRINT A1%
PRINT G%
PRINT G1%
PRINT GG%
$ ./newopl_exec ../examples/PRNT1.OB3

Gives the output:

Code: Select all

1
11
6
61
66
MartinP
Posts: 54
Joined: Wed Jan 04, 2023 7:51 pm

Re: NewOPL

Post by MartinP »

Andrew,
Looks great, but your NewOPL repo does not seem to be publicly accessible.
amenjet
Posts: 299
Joined: Tue Jan 03, 2023 7:54 pm

Re: NewOPL

Post by amenjet »

Hopefully its back again...

I've started the translater and got it generating some text from OPL programs that should be convertible into qcode moderately easily.
User avatar
Martin
Global Admin
Posts: 294
Joined: Mon Jan 02, 2023 5:18 pm

NewOPL - Documentation

Post by Martin »

Hi Andrew

So you don't think this work is falling on 'deaf ears'. I'm working through the (notes) language.txt.. Then I'll work through the examples.

You mention 'fixing up' variables.. Is this the same as 'initialising' from our basic days?

There is a lot of work in just documenting what you are doing never mind the actual coding.

Sincerely
Martin


This process is referred to as "fixing up" the variables.
amenjet
Posts: 299
Joined: Tue Jan 03, 2023 7:54 pm

Re: NewOPL

Post by amenjet »

I'm going to carry on whatever, I think. It's an interesting language and very much more advanced than BASIC. It's more of a compiled language than a simply translated one.

Fixing up is the process of filling in the odd length bytes for strings and arrays in the just zeroed variable space. The variables are all zeroed as initialization but there's a few bytes that need to non zero, that's what fixup does.

I think I nearly have skeleton code for the translator and the runtime. The obj dump is pretty good too and can dump organiser created ob3 files. The translator can't generate qcode yet but gets to an intermediate for that is close. I'm trying to get the typing of expressions correct at the moment.

Still quite a bit to do
amenjet
Posts: 299
Joined: Tue Jan 03, 2023 7:54 pm

Re: NewOPL

Post by amenjet »

It turns out that I had quite a bit of work to do on the skeleton translator as I needed to completely rewrite the auto type conversion code. That now seems to be more or less working.
The translator now converts all OPL statements from infix expression format to RPN format. It then 'executes' the RPN in order to build a tree that it uses to insert auto conversion codes into the expression where needed.

For example:

Code: Select all

UDG(1, 2. 1.3, 4,   5, 6, 7, 8, 9)
translates (with a lot of debug info) to:

Code: Select all

(dump_exp_buffer2) N1 EXP_BUFF_ID_INTEGER      i rq:i 1  0:
(dump_exp_buffer2) N2 EXP_BUFF_ID_INTEGER      i rq:i 2  0:
(dump_exp_buffer2) N3 EXP_BUFF_ID_FLT          f rq:f 1.3  0:
(dump_exp_buffer2) N11 EXP_BUFF_ID_???          v rq:v autocon f->i  0:
(dump_exp_buffer2) N4 EXP_BUFF_ID_INTEGER      i rq:i 4  0:
(dump_exp_buffer2) N5 EXP_BUFF_ID_INTEGER      i rq:i 5  0:
(dump_exp_buffer2) N6 EXP_BUFF_ID_INTEGER      i rq:i 6  0:
(dump_exp_buffer2) N7 EXP_BUFF_ID_INTEGER      i rq:i 7  0:
(dump_exp_buffer2) N8 EXP_BUFF_ID_INTEGER      i rq:i 8  0:
(dump_exp_buffer2) N9 EXP_BUFF_ID_INTEGER      i rq:i 9  0:
The UDG requires none integers, and in this example the N3 float is converted to an integer before being processed by the UDG function.

This:

B = 1 * ( 2 + A )

translates to:

Code: Select all

(dump_exp_buffer2) N1 EXP_BUFF_ID_VARIABLE     f rq:f B  0:
(dump_exp_buffer2) N2 EXP_BUFF_ID_INTEGER      i rq:i 1  0:
(dump_exp_buffer2) N8 EXP_BUFF_ID_???          f rq:f autocon i->f  2: 5 2
(dump_exp_buffer2) N3 EXP_BUFF_ID_INTEGER      i rq:i 2  0:
(dump_exp_buffer2) N6 EXP_BUFF_ID_???          f rq:f autocon i->f  2: 4 3
(dump_exp_buffer2) N4 EXP_BUFF_ID_VARIABLE     f rq:f A  0:
(dump_exp_buffer2) N5 EXP_BUFF_ID_OPERATOR     f rq:f +  2: 4 3
(dump_exp_buffer2) N7 EXP_BUFF_ID_OPERATOR     f rq:f *  2: 5 2
(dump_exp_buffer2) N9 EXP_BUFF_ID_OPERATOR     f rq:f :=  2: 7 1
This final code should be fairly straightforward to convert to QCode. that's the plan, anyway.
User avatar
Martin
Global Admin
Posts: 294
Joined: Mon Jan 02, 2023 5:18 pm

NewOPL UDG function

Post by Martin »

Andrew

Code: Select all

UDG(1, 2. 1.3, 4,   5, 6, 7, 8, 9)
Again I'm running out of talent here but I assume you put the extra space between the 4, and the 5 to see how the translator would handle it.

I tried it on my Organiser - the 2. will not translate because of the missing comma and of course the UDG function doesn't use brackets.

I'm still trying to keep up
Sincerely
Martin
amenjet
Posts: 299
Joined: Tue Jan 03, 2023 7:54 pm

Re: NewOPL

Post by amenjet »

Ah, yes, that missing comma is a typo. The spaces were just to make the multiple UDG statements in my test file line up... They are ignored though.

The brackets round the arguments make it a sub expression, commas separate sub expressions as well, but I missed the lack of brackets around the UDG statement. It looks like there really are functions and statements, so back to the drawing board again for a bit...
Post Reply