C68Port - A (LONG!) proposal

Anything QL Software or Programming Related.
User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: C68Port - A (LONG!) proposal

Post by tofro »

Norman,

yes, didn't think about recursion. (Which opens up the query what exactly you want to achieve and what limits you set with regards to what types of S*BASIC programs you can translate - I guess, "all", which might be a bit of a daunting task.)

ALlocating locals on the heap might open up a can of worms you'd better leave closed (Also, to me that looks a bit like interpreting the S*BASIC program at runtime in C). I'd rather go and add the LOCals you have in a called procedure as additional (by reference) parameters to the functions called from the proc like

Code: Select all

PROCEDURE HasLocals
  LOCAL a, b%, c$(100)
  
  a = DoStuff (c$);
 END DEF
 
FUNCTION DoStuff (x$)
   REMark uses a, b% and x$
   RETurn something
 ENDDEF
  
Translate this into

Code: Select all

void HasLocals () {
   double a;
   int b;
   char c [100];
   
   a = DoStuff (c, &b, &a);
}

double doStuff (/* "proper" parameter */ char *c, /* "shadow" parameters */ int *b, double *a) {
   /* uses a, b, c */
   return something;
}
   
This way your stack is safe and you don't have to fiddle around with dynamic memory. Obviously, every PROC and FuNction that has LOCals needs to keep a list of these and add them to the parameter list of any called function.

What you cannot achieve with this method is properly translate functions that are both called from functions that have locals and from others that don't (or have another set of locals). I see no way of doing that without providing different implementations for the same function according from where it is called:

Imagine you have a "HasLocals" that calls "DoStuff" with local variables and a "HasNoLocals" that uses global variables, you'd need to have two "DoStuff" implementations:

Code: Select all

PROCEDURE HasNoLocals
   REMark uses global variables!
   a = DoStuff (c$)
ENDDEF

Code: Select all

double a;
int b;
char c [100];

void HasNoLocals () {
   a = doStuff_cf_HasNoLocals (c);
}

void HasLocals () {
   double a;
   int b;
   char c [100];
   
   a = DoStuff_cf_HasLocals (c, &b, &a);
}

/* (cf means "called from") */
double doStuff_cf_HasLocals (/* "proper" parameter */ char *c, /* "shadow" parameters */ int *b, double *a) {
   /* uses a, b, c locals from HasLocals */
   return something;
}

double doStuff_cf_HasNoLocals (char *c) {
  /* uses a, b, c global variables */
  return something;
This looks like it would work, but might blow up programs, and might end up in a pretty ugly C program - But I see no other way. Fiddling with parameters at runtime like you intend to ends up in sort of runtime-interpreted code in C (and an ugly mess as well, I'm afraid).

The above assumes a dumb, straight-forward translation from S*BASIC to C - With some more syntactical analysis of the original program (like analysing what a procedure modifies, and what locals (own or inherited) are actually used or not), I guess you can shorten the parameter lists and reduce the amount of _cf_ implementations quite a lot. The rule would somehow be:

"If a FN or PROC ever tries to access (or modify) a LOCal of another proc, this must be added to its parameter list as a value of or a pointer to (in case of modify) that local. A function that does that and that accesses or modifies globals in different call chains should be called with the value or pointer to the global it touches"

Tobias
Last edited by tofro on Wed Mar 28, 2018 9:32 am, edited 1 time in total.


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: C68Port - A (LONG!) proposal

Post by NormanDunbar »

Morning Tobias,

My ideal intention, is to try and convert any SuperBASIC program into C. As this thought experiment continues, that ideal is looking a tad impossible.

Time for a rethink. Again.

Appreciate the input, thanks.

Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: C68Port - A (LONG!) proposal

Post by tofro »

Norman,

I still think that it's possible. The amount of syntactical analysis required on the original S*BASIC program is, however, very probably much highter than you (and me) originally thought.
For each S*Basic function and procedure you need to know a list of local and global variables it accesses and whether that access is a read or write. That also means we'd need to analyze and know all possible call chains of that program. With that knowledge, you can build a perfect translator, I think.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: C68Port - A (LONG!) proposal

Post by NormanDunbar »

Progress! :)

I set up a system as originally described, with the cability to replicate the QL's handling of LOCal variables. It even works with recursion.

So something like this:

Code: Select all

DEFine PROCedure test
  LOCal Fred%, Wilma
  ...
  Fred = 666
  Wilma = 3.14
  ...
  Test2
  ...
 END DEFine test
 
 DEFine PROCedure Test2
    ...
   PRINT Fred%
   PRINT Wilma
   ...
END DEFine Test2  
Becomes (will become!) similar to this:

Code: Select all

void test() {
  beginScope();
  SBLocalVariableNode *Fred = newLocal(SBLOCAL_INTEGER, "Fred");
  SBLocalVariableNode *Wilma = newLocal(SBLOCAL_FLOAT, "Wilma");
  setSBLocalVariableValue_i(Fred, 666);
  setSBLocalVariableValue(Wilma, 3.14);
  ...
  Test2();
  ...
  endCurrentScope();
}

void Test2 {
  ...
  printf("%d\n", getSBLocalVariableValue_i("Fred");
  printf("%lf\n", getSBLocalVariable("Wilma");
  ...
}
Not too unreadable?

I had a quick blast at lunchtime today and it seems to work, granted on a PC, I just need to check the source code compiles and works under C68. I've tested calling other PROCedures with and without locals, and recursion, and it works fine so far!

This is looking promising for the future!


Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: C68Port - A (LONG!) proposal

Post by NormanDunbar »

Sigh! Today I attempted a compile under C68 on QPC. Not good!

I forgot how "old" C68 is, and that it doesn't like ANSI style comments, // ... , so I had to edit my code to use block comments instead, /* ... */.

Then most of my variable declarations gave 'illegal storage class' errors. Took me ages to realise that with C68 you still need to define all variables at the top of the scope. Just like Visual C++ in fact, before it went all dot net!

Then I ran out of play time. More editing to do, but if it works like it does on Windosws and on Linux under gcc, things are looking up and I should have a working SuperBASIC LOCal variable scoping system!


Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
swensont
Forum Moderator
Posts: 252
Joined: Tue Dec 06, 2011 3:30 am
Location: SF Bay Area
Contact:

Re: C68Port - A (LONG!) proposal

Post by swensont »

> I forgot how "old" C68 is, and that it doesn't like ANSI style comments, // ... , so I had to edit my code to use block comments instead, /* ... */.

Interesting comment about // vs /* */. I checked by 2nd edition of K&R (first printing, 1988) and it does not support //, and it was based on ANSI C. I did some further digging and // did not come about until C99, many years after C68 was written. I'm still stick in 1st ED K&R and only dipping my foot into 2nd ED K&R. I guess I'm really old. :-)

Tim


User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: C68Port - A (LONG!) proposal

Post by tofro »

C68 does support ANSI C (and thus, C++-like comments) if you compile with

Code: Select all

-extensions=yes
The preprocessor does, however, sometimes have its problems with that.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
NormanDunbar
Forum Moderator
Posts: 2251
Joined: Tue Dec 14, 2010 9:04 am
Location: Leeds, West Yorkshire, UK
Contact:

Re: C68Port - A (LONG!) proposal

Post by NormanDunbar »

Morning Tobias,

thanks for that, but I did read the docs, honest! ;-)

It seems that using that option will only work if the actual compiler itself was compiled with some additional switch turned on. I'm not at my QL at the moment, so I can't quite remember which option it was.

Not to worry, it's a simple enough matter to generate the correct code for C68.

I'm wondering if we need to pay Dave Walker a huge sum of money to convert C68 to ANSI compatible, or, get some genius who knows a thing or two about compilers to convert LCC to generate QL object files. It usually uses the gcc preprocessor and the as assembler to do the necessary, but I suspect it could use the ones in C68. The book, A Retargetable C Compiler: Design and Implementation on Amazon (https://www.amazon.co.uk/Retargetable-C ... 0805316701) is quite interesting (and expensive!) - I have it from many years ago in pdf format. The version in the book is 3.x but the current code is 4.x and the code generation is differently implements in 4.x. There's an update pdf at https://drhanson.s3.amazonaws.com/stora ... rface4.pdf.

The source code is on Github at https://github.com/drh/lcc. (If anyone is interested?)


Cheers,
Norm.


Why do they put lightning conductors on churches?
Author of Arduino Software Internals
Author of Arduino Interrupts

No longer on Twitter, find me on https://mastodon.scot/@NormanDunbar.
User avatar
XorA
Site Admin
Posts: 1358
Joined: Thu Jun 02, 2011 11:31 am
Location: Shotts, North Lanarkshire, Scotland, UK

Re: C68Port - A (LONG!) proposal

Post by XorA »

Someone on the forum started to make vbcc work for QL, its a modern 68k C compiler!


User avatar
Dave
SandySuperQDave
Posts: 2765
Joined: Sat Jan 22, 2011 6:52 am
Location: Austin, TX
Contact:

Re: C68Port - A (LONG!) proposal

Post by Dave »

XorA wrote:Someone on the forum started to make vbcc work for QL, its a modern 68k C compiler!
[citation needed]


Post Reply