Author Topic: [SOLVED] Indirection in O2  (Read 3210 times)

0 Members and 2 Guests are viewing this topic.

Mike Lobanovsky

  • Guest
[SOLVED] Indirection in O2
« on: October 14, 2014, 02:16:36 PM »
Hi Charles,


Given

Code: [Select]
  type cell
    .......
    cell*  _car
    cell*  _cdr
  end type

  #define car(p)            p##._car // as you suggested
  #define cdr(p)            p##._cdr

how deep can such macros go, if at all:

Code: [Select]
  #define cadddr(p)         car(cdr(cdr(cdr(p))))
  #define cddddr(p)         cdr(cdr(cdr(cdr(p))))

In other words, what are the limits to indirection in Oxygen, if any?
« Last Edit: October 15, 2014, 01:27:12 PM by Mike Lobanovsky »

Charles Pegge

  • Guest
Re: Indirection in O2
« Reply #1 on: October 14, 2014, 07:43:17 PM »
Hi Mike,

There is no practical limit to indirection: Use stars to get the right level.

cell *c
@c=@d.cdr 'level 1 reference
@c=*(@d.cdr) level 2 reference
@c=**(@d.cdr) level 3 reference
...


PS:
Oxygen Update: further correction  for calling procedures using 'pointer' params

http://www.oxygenbasic.org/o2zips/Oxygen.zip


Mike Lobanovsky

  • Guest
Re: Indirection in O2
« Reply #2 on: October 14, 2014, 09:18:57 PM »
Thanks much for your help and the update, Charles!
« Last Edit: October 15, 2014, 06:59:23 AM by Mike Lobanovsky »

Mike Lobanovsky

  • Guest
Re: Indirection in O2
« Reply #3 on: October 15, 2014, 07:35:18 AM »
Sorry to disturb you again, Charles, but though your answer does shed some light on in-situ indirection, it doesn't help me any with my macro-centric code at hand.

Assuming the console mode and indexbase 0, the following code

Code: [Select]
type cell
  quad  _ivalue
  cell* _car
  cell* _cdr
end type

#define pointer   cell*
#define ivalue(c) c##._ivalue           // again as per your suggestion
#define car(c)    c##._car              // ???
#define cdr(c)    c##._cdr              // ???
#define cadadr(c) car(cdr(car(cdr(c)))) // ???

cell cells[4]
pointer p
int i

for i = 0 to 4
  @p = @cells[i]
  ivalue(p) = i
  print "_ivalue=" ivalue(p)
  car(p) = @p
  print " _car=" car(p) cr // show address to verify in-memory continuity
  if i < 4 then cdr(p) = @cells[i + 1]
next

@p = @cells[0]
print ivalue(cadadr(p)) cr

waitkey

runs only for the ivalue(p) in the loop. All the rest is invalid. I realize there may be some limitations to print to be able to display the test results but I absolutely must have all such "pointish" macros (or their O2 equivalents) working rock solid throughout the code. I must be able to use the cadadr() type macros (there are many of them with various combinations of car() and cdr()) and they must also be nestable within each other, similar to the trailing print above, both on the left and right sides of expressions.

Can you show me how to do it please?
« Last Edit: October 15, 2014, 10:04:51 AM by Mike Lobanovsky »

Charles Pegge

  • Guest
Re: Indirection in O2
« Reply #4 on: October 15, 2014, 10:13:37 AM »
Hi Mike,

This seems a little more functional, Cadadr needs to be a function in such a configuration. But I can't see the big picture with all the pointers. Is it like Andy Warhol? :)

Code: [Select]
include "$/inc/console.inc"
indexbase 0

type cell
  quad  _ivalue
  =
  cell* _car
  cell* _cdr
end type

typedef cell *pointer
#define ivalue(c) c##._ivalue            // again as per your suggestion
#define car(c)    @c##._car              // ???
#define cdr(c)    @c##._cdr              // ???

'#define cadadr    car(cdr(car(cdr(p)))) // ???

function cadadr(pointer p) as pointer
pointer c
@c=@p._cdr
@c=@c._car
@c=@c._cdr
@c=@c._car
return c
end function

cell cells[4]
pointer p
int i

for i = 0 to 4
  @p = @cells[i]
  ivalue(p) = i
  print "_ivalue=" ivalue(p)
  car(p) = @p
  print " _car=" car(p) cr // show address to verify in-memory continuity
  if i < 4 then cdr(p) = @cells[i + 1]
next

@p = @cells[0]
@p = cadadr(p)
print ivalue(p) cr

waitkey

May be better to turn the cell type into an anonymous blob, then use casting to obtain values. It would avoid much C type torture.


JRS

  • Guest
Re: Indirection in O2
« Reply #5 on: October 15, 2014, 10:17:04 AM »
Quote from: Charles
It would avoid much C type torture.

Thank you for calling it what it is. Like teaching a dog not to chase it's tail.

Working with C

Mike Lobanovsky

  • Guest
Re: Indirection in O2
« Reply #6 on: October 15, 2014, 11:57:33 AM »
Charles and John,

That sounds a bit unfair to C which is in fact an agglomeration of two languages - C proper, on the one hand, and its mighty macro preprocessor, on the other.

C scripts that don't make use of the PP look badly shaped, overbloated with unnecessary minute things like casts, pointer operators, function calls, etc. that blur their structure and impede perception. The same is only true about indie BASIC's as well that are very often devoid of any macro or PP functionality at all. A cleverly designed macro header file often resolves up to two thirds of the subordinate tasks in a C application making its code crystal clear and thus substantially easier to maintain.

nanoscheme's moderate set of PP macros serves this purpose fairly well. That's why I'm being so sensitive about it and insistent. nanoscheme is a serious application and not just another funny snippet to color blobs on one's screen. Suffice it to say that the TinyScheme project once also originated from this source but got bloated in the process of "communal" development almost beyond recognition, which led to triple slowdown in speed and at least quadruple excess, in size.


Charles, what I'm trying to achieve is in fact a desparate anti-Andy-Warhol effort to let you see the big picture without all the pointers. And thank you very much for guiding me in that thankless task.


P.S. This "functional" solution doesn't let me assign values to cadadr() targets. What else do we have in stock?
« Last Edit: October 15, 2014, 12:08:19 PM by Mike Lobanovsky »

Charles Pegge

  • Guest
Re: Indirection in O2
« Reply #7 on: October 15, 2014, 12:27:50 PM »
After several transforms using anonymising and reductionist principles, I arrived at this shrunken piece. I think it meets your requirements :)

Code: [Select]
include "$/inc/console.inc"
indexbase 0

type cell sys A,B,flag

#define ivalue(c) cast quad *c
#define rvalue(c) cast double *c
#define car(c)    *c
#define cdr(c)    *(c+sizeof sys)
#define cadadr(c) car(cdr(car(cdr(c))))

cell cells[4]

sys p
int i

for i = 0 to 4
  p = @cells[i]
  ivalue(p) = i
  print "ivalue=" ivalue(p)
  car(p) = p
  print " car= " car(p) cr
  if i < 4 then cdr(p) = @cells[i+1]
next

print ivalue(cadadr(@cells[0])) cr

waitkey

Mike Lobanovsky

  • Guest
[SOLVED] Re: Indirection in O2
« Reply #8 on: October 15, 2014, 01:25:11 PM »
"Dastisch fantastisch", Charles! :D

John may relax -- there won't be any pointers (well, almost) obscuring his refined BASIC-ish sight.

Thanks very much for your help!

JRS

  • Guest
Re: [SOLVED] Indirection in O2
« Reply #9 on: October 15, 2014, 01:31:00 PM »
Quote
John may relax -- there won't be any pointers (well, almost) obscuring his refined BASIC-ish sight.

The only nightmare I have is that I wake up and someone did a gcc -E on all the SB source and deleted all of Peter's macro / define work.  :)