Author Topic: Updating OxyScheme  (Read 7338 times)

0 Members and 1 Guest are viewing this topic.

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1993
Re: Updating OxyScheme
« Reply #30 on: November 10, 2019, 04:18:25 AM »
Hehe that's too simple an example indeed, Charles!

But what would you do with complex lists or lists of lists as arguments to a lambda? ;)
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Updating OxyScheme
« Reply #31 on: November 10, 2019, 08:58:32 AM »
Hi Charles, Mike,

at least I learned this little trick with o2scm.o2bas:

Code: [Select]
uses corewin

function fibo(quad a,b,x) as quad
  if x=0 then return a else return fibo(b,a+b,x-1)
end function

quad x = fibo(1,1,91)
' print x

char s[30]
sprintf(s, "%I64d", x)
print s

Btw: MSDN states for _strlwr, etc:

Return Value
Each of these functions returns a pointer to the converted string. Because the modification is done in place, the pointer returned is the same as the pointer passed as the input argument. No return value is reserved to indicate an error.
...
If str is a NULL pointer, the invalid parameter handler is invoked, as described in Parameter Validation. ...

Does _strlwr create side effects in o2scm.o2bas? If I use the function unprototyped I get an error e.g.: unbound variable 35467044

Roland
« Last Edit: November 10, 2019, 09:12:54 AM by Arnold »

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1993
Re: Updating OxyScheme
« Reply #32 on: November 10, 2019, 10:34:04 AM »
Do strlwr() and _strlwr() produce similar test printf() printouts when used in the OxyScheme code?

Does unprototyped strlwr() work as expected? If yes then why bother changing it to anything else?
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Updating OxyScheme
« Reply #33 on: November 10, 2019, 12:49:10 PM »
Hi Mike,

I only would like to find a reason why mark(oblist) in sub gc() does not work like in A41. Until now I can see that in A41 function atoll() was used and substituted later, strcmp was applied a bit differently with some push and mov statements and I wonder if _strlwr can play a role. For my test with o2scm of 0.2.8 I do not use nsinit.scm. I added two print statements in case OP_EVAL in about line 1390:
...
          else
printl "oblist: " oblist : printl         
            Error_1("unbound variable", code)
and in about line 1404:
...
        end if
printl "oblist: " oblist : printl
        s_return(code)
       
      case OP_E0ARGS /* eval arguments */
...

If I run o2scm with _strlwr prototyped, I get this result:
Error: unable to open "nsinit.scm"

> (define x)

oblist: 137819936
x
>

If I use _strlwr unprototyped:
  ! _strlwr             '(char* a) as char*

then I get this result:
Error: unable to open "nsinit.scm"

> (define x)

oblist: 134477528
Error: unbound variable 34035020

I do not know if this matters in any way, but I feel obliged to report the different behaviour. I am simply confused that garbage collection runs differently in A41. Garbage collection did already not work in version A43.

Roland
« Last Edit: November 10, 2019, 01:43:18 PM by Arnold »

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1993
Re: Updating OxyScheme
« Reply #34 on: November 10, 2019, 02:57:15 PM »
Hi Roland,

Re. nsinit.scm: This file contains a library (not complete yet!) of high-level macros (syntax extensions) written in the Scheme language and required as per R5RS. Without this library, you won't be able to run scripts more complicated than this rudimentary Fibonacci calc.

I wouldn't try to debug or test a program that signals an error without first fixing that error. OxyScheme usually recovers fully from all the errors it reports, but who knows... (why wouldn't you let the app load that library, after all?)

Re. value of oblist: This is a pointer to the symbol table, i.e. to the first cell in a linked list of cells that stores the names used in the language syntax, and therefore its exact value is dependent on how this particular program image is arranged in the computer RAM. The value per se is of very little use for bug tracking or anything else.

Re. 34035020: This number looks pretty much like a pointer. I think either an unprototyped _strlwr cannot treat its argument as a char* because O2 wouldn't pass it by ref (more likely) or else O2 cannot accept the _strlwr return as a char* (less likely). In which cases the function or O2 would simply default to treating the argument or return, respectively, as a mere integer value converted to a string literal. Then OxyScheme would flag it as an unbound (i.e. undefined in the code) variable.

Re. atoll: The original TinyScheme code was written to be compiled with GCC. atoll() is a Linuxoid function not available in Microsoft's msvcrt.dll runtime. So, Charles (or I?) wrote an asm macro atoll_asm to emulate this function in O2. Later on, somebody (presumably Charles again, judging by the single-quoted rem) found an original _atoi64() equivalent to atoll() in msvcrt.dll and changed the source code.

But both _atoi64() and _i64toa() use and return VC long long integers, not O2 64-bit floating point quads! Charles, please comment here whether O2 currently makes an equivalent substitution of quads in its integer registers automatically and transparently when it pushes and receives 64-bit integers to/from a DLL?

If Charles says yes, then I think such functions cannot be used unprototyped because Oxygen simply wouldn't know what integer arguments (32- or 64-bit) to push when calling the functions or what registers to use when fetching their return.
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4267
    • Oxygen Basic
Re: Updating OxyScheme
« Reply #35 on: November 10, 2019, 05:12:11 PM »
Quote
But both _atoi64() and _i64toa() use and return VC long long integers, not O2 64-bit floating point quads! Charles, please comment here whether O2 currently makes an equivalent substitution of quads in its integer registers automatically and transparently when it pushes and receives 64-bit integers to/from a DLL?

Yes, I confirm that extern functions returning quads use the edx:eax register pair in 32bit mode. And prototype definitions are necessary when returning quads.

For 64bit compiling of o2scm, I  would suggest overriding quad completely:
typedef sys quad
then you wont need dll prototypes, (and you won't be using cdecl anywhere).
« Last Edit: November 10, 2019, 05:20:12 PM by Charles Pegge »

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Updating OxyScheme
« Reply #36 on: November 11, 2019, 06:22:54 AM »
Charles example of fibo.o2bas inspired me to do this with kings_reward.o2bas too (but it does not look like Scheme):

Code: [Select]
uses corewin
uses console

sub grains(int x)
    int i
    quad j = 1
    char s[20]

    for i = 1 to x
       printl " field " i ":   number of grains:  "
       sprintf(s, "%I64u", j)
       print s
       j *= 2
    next
end sub   

printl " The reward of the King"
printl " ----------------------" + cr
grains 64

printl "Enter ..."
waitkey

I found the "%I64d" and "%I64u" format-strings for sprintf interesting. There are some more sprintf examples in \examples\Msvcrt\ and in o2tests.o2bas which can be possibly applied.

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Updating OxyScheme
« Reply #37 on: November 23, 2019, 02:30:21 AM »
Hi Charles, Mike,

is there a chance to find out why 'when' of nsinit.scm does not work? (it ran ok with o2scm.o2bas of version A41).

This does work:

(cond ((> 3 2 ) ' greater))   --> greater
(cond ((< 3 2 ) ' greater))   --> ()
      
This does not work in version 0.2.8:

(when (> 3 2) 'greater)     --> Error: unbound variable unquote
(when (< 3 2) 'greater)     --> Error: unbound variable unquote

Unfortunately it is very difficult to trace the source-code due to the many macros.

Roland

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4267
    • Oxygen Basic
Re: Updating OxyScheme
« Reply #38 on: November 23, 2019, 05:07:14 AM »
Hi Roland,

when is not included in the current o2scm.o2bas or the R5RS manual.

But it is used in Racket:
https://docs.racket-lang.org/reference/when_unless.html

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1993
Re: Updating OxyScheme
« Reply #39 on: November 23, 2019, 05:47:57 AM »
Charles, Roland,

Both when and unless are included in the current version of OxyScheme as Scheme macros defined in nsinit.scm. It is true they aren't part of R5RS. But both of them were defined in the later R6RS recommendation that was emerging at the time the o2scm.o2bas script was developed. Their implementation and syntax are simpler than those of cond, so why not include them if we can?

The macros work well in both the older OxyScheme and its FBSL nanoscheme prototype, so I presume they'll be usable again if and when other minor differences between the old and new O2 notation are tackled with.
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Updating OxyScheme
« Reply #40 on: November 23, 2019, 05:56:05 AM »
Hi Charles,

I found 'when' in nsinit.scm of Oxygenbasicprogress.zip. As Mike stated it is defined as a macro at the bottom of nsinit.scm:

;; when
(macro when (lambda (form)
     `(if ,(cadr form) (begin ,@(cddr form)))
))

The macro is used in kings_reward.scm. I noticed the misbehaviour when I applied: (grains 4) and the loop did not end. Most curiously no error is displayed when running the script. I can define the macro in 0.2.8 and call it:

>when
#<CLOSURE>

but it seems I cannot use the macro. I must admit that I do not know how to test the '(if .. part of the macro and use this instead of when in kings_reward.scm

Roland

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4267
    • Oxygen Basic
Re: Updating OxyScheme
« Reply #41 on: November 24, 2019, 06:47:41 AM »
Do we have some more elementary examples of Scheme macros? The syntax is not clear.

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Updating OxyScheme
« Reply #42 on: November 24, 2019, 07:21:22 AM »
Hi Charles,

sometimes I am completely blind. By rereading my last message and comparing with o2scm of A41 I noticed that entering when should give this result:
<macro> instead of <closure>. Macros of nsinit.scm are: quasiquote, do, unless and when.

Something must run differently in o2scm.o2bas of 0.2.8 at the moment. The app confuses macro with closure.

Roland

Mike Lobanovsky

  • Admin Support Member
  • *****
  • Posts: 1993
Re: Updating OxyScheme
« Reply #43 on: November 24, 2019, 10:39:53 AM »
Hi Roland,

when and the other macros all yield #<MACRO> in the FBSL nanoscheme equivalent of O2 OxyScheme.

As I mentioned earlier, nanoscheme was a little more advanced, and better debugged, than OxyScheme, and I admit that therefore OxyScheme might not be 100% compatible when I quit working on it because some forum members were clearly against "promoting" the alien language on a BASIC forum.

Thus, rendering OxyScheme fully compliant may take some more effort than just updating the O2 pointer notation. First of all, the cell structure itself should be made fully equivalent to C-language

struct cell{
    unsigned long _flag;
    union {
      struct {
        char* _svalue;
        long  _keynum;
      } _string;
      struct {
        union {
          __int64 _ivalue;
          double  _rvalue;
        } _value;
      } _number;
      struct {
        struct cell* _car;
        struct cell* _cdr;
      } _cons;
    } _object;
  } cell;

rather than its O2 palliation

  type cell
    sys _A    // placeholder
    sys _B    // placeholder
    sys _flag // type of cell
  end type


that was the only feasible way to declare that structure in an ancient O2 that had no unions nor genuine I64 data type at the time the translation was made.

I think the person who will happen to be able to make the OxyScheme code fully compliant to at least its nanoscheme prototype, let alone TinyScheme and/or R5RS, may definitely call himself proudly a "language developer". :D
Mike
(3.6GHz Intel Core i5 Quad w/ 16GB RAM, nVidia GTX 1060Ti w/ 6GB VRAM, Windows 7 Ultimate Sp1)

Arnold

  • Hero Member
  • *****
  • Posts: 932
Re: Updating OxyScheme
« Reply #44 on: November 25, 2019, 06:24:04 AM »
Hi Mike,

Oxyscheme worked pretty well with O2 version A41, and probably there are only minor issues currently.

I myself have lowered my goals a bit at the moment, but I intend to benefit from the tricks of o2scm.o2bas as much as possible. I found an older minischeme.c (which only applies integers) that uses a similar cell structure as the one you introduced. I added TOK_EOF, EOF_OBJ and some modifications. I can compile the file with tcc and gcc to 32-bit and 64-bit. So I think it will be a good starting point for me in many aspects. The main aspect is the learning experience.

Roland

Code: [Select]
/*      ---------- Mini-Scheme Interpreter Version 0.85 ----------
 *                coded by Atsushi Moriwaki (11/5/1989)
 *  This version has been modified by Chris Pressey.
 *    current version is 0.85 mod (as yet unreleased)
 *  This version has been modified by R.C. Secrist.
 *  This is a revised and modified version by Akira KIDA.
 
 *               THIS SOFTWARE IS IN THE PUBLIC DOMAIN
 *               ------------------------------------
*/
// only for Windows, tested with Win10
// added TOK_EOF, EOF_OBJ, OP_GENSYM, some other modifications
// works with "msinit.scm"
...

Edit:

I noticed that the 'do' macro did not work due to a missing gensym procedure. Therefore I added OP_GEN of o2scm.o2bas. The attached zip file contains miniscm.c, msinit.scm, Test_Cases.scm. Also added a 32-bit executable compiled with the gcc compiler of mingw.
« Last Edit: December 17, 2019, 04:00:57 AM by Arnold »