Author Topic: Building a ScriptBasic extension module  (Read 17466 times)

AIR

  • Guest
Re: Building a ScriptBasic extension module
« Reply #15 on: May 29, 2011, 12:16:42 AM »
Maybe "e" needs to be defined first?

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #16 on: May 29, 2011, 07:29:27 AM »
jrs@laptop:~/sb/test/gsl$ scriba emath.sb
(0): error &H8:The argument passed to a module function is out of the accepted range.

The error changed from not enough parameters to out of range after assigning e=0.

The original code I posted is the only way I can get this to work. It was based on the MySQL (FetchHash) function that passes a SB variable and it returns an array of the next row in the record set.

Code: [Select]
besFUNCTION(_frexp)
  VARIABLE Argument;
  LEFTVALUE Lval;
  unsigned long __refcount_;

  Argument = besARGUMENT(1);
  besDEREFERENCE(Argument);
  double x = DOUBLEVALUE(Argument);
  Argument = besARGUMENT(2);
  besLEFTVALUE(Argument,Lval);
  besRELEASE(*Lval);
  *Lval = besNEWLONG;

  besRETURN_DOUBLE(gsl_frexp(x, *Lval));
besEND

« Last Edit: May 29, 2011, 08:01:51 AM by ABB »

AIR

  • Guest
Re: Building a ScriptBasic extension module
« Reply #17 on: May 29, 2011, 09:25:47 AM »
It's actually a good thing that the error changed.

I think I goofed by suggesting that a pointer be passed via "p".  Try changing it to "i" and see what happens...

A.

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #18 on: May 29, 2011, 09:54:03 AM »
Code: [Select]
besFUNCTION(_frexp)
  double x;
  int Lval;

  besARGUMENTS("ri")
    &x,&Lval
  besARGEND
 
  besRETURN_DOUBLE(gsl_frexp(x, &Lval));
besEND

Code: [Select]
DECLARE SUB frexp ALIAS "_frexp" LIB "gsl"

x = 16.4
e = 0
fraction = frexp(x, e)
PRINT FORMAT("%g",fraction),"\n"
PRINT e,"\n"

jrs@laptop:~/sb/test/gsl$ scriba emath.sb
0.5125
0

This allowed to the frext function to return the fractional part but the exponent didn't get assigned to e.


AIR

  • Guest
Re: Building a ScriptBasic extension module
« Reply #19 on: May 29, 2011, 10:21:15 AM »
Hmmmm.

Ok, apparently SB passes variables byref, which means that the Lval variable should contain the address of "e" instead of it's value.

So perhaps you don't need the "&Lval" in the gsl function call?  Just "Lval"?


Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #20 on: May 29, 2011, 10:25:06 AM »
This works.

Code: [Select]
besFUNCTION(_frexp)
  double x;
  LEFTVALUE Lval;
  VARIABLE Argument;
  unsigned long __refcount_;

  besARGUMENTS("r")
    &x
  besARGEND
  Argument = besARGUMENT(2);
  besLEFTVALUE(Argument,Lval);
  besRELEASE(*Lval);
  *Lval = besNEWLONG;
 
  besRETURN_DOUBLE(gsl_frexp(x, *Lval));
besEND

I will try your current suggestion and see if it helps.

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #21 on: May 29, 2011, 10:30:25 AM »
This returns a segment fault.

Code: [Select]
besFUNCTION(_frexp)
  double x;
  int Lval;

  besARGUMENTS("ri")
    &x,&Lval
  besARGEND
 
  besRETURN_DOUBLE(gsl_frexp(x, Lval));
besEND

AIR

  • Guest
Re: Building a ScriptBasic extension module
« Reply #22 on: May 29, 2011, 11:39:16 AM »
Ok, I think passing Lval as an int is wrong, since you want to pass a ref to a SB object.

Code: [Select]
besFUNCTION(_frexp)
  double x;
  LEFTVALUE Lval;
  unsigned long __refcount_;

  besARGUMENTS("rp")
    &x,&Lval
  besARGEND
 
  besRETURN_DOUBLE(gsl_frexp(x, &Lval));
besEND

&Lval may need to be *Lval.  I don't have any of this installed on my laptop, so can't test.


Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #23 on: May 29, 2011, 12:10:09 PM »
No luck.
Quote
The argument passed to a module function is out of the accepted range.

What seems to be happening with what I have working is this.

* User passes a variable (can be undef)
* SB does something wih the besLEFTVALUE() function and has to have __refcount_ declared as the besLEFTVALUE macro errors without it.
* SB releases the pointer to the passed variable
* SB assigns a besNEWLONG to create a new 'mortal'
* The frexp() function then uses this newly created LONG as the storage of the exponent.

AIR

  • Guest
Re: Building a ScriptBasic extension module
« Reply #24 on: May 29, 2011, 12:20:06 PM »
Ok, without installing this myself I really can't say why it doesn't work as I think it should.

As it is, you have a working solution so it's not a big deal.

A.

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #25 on: May 29, 2011, 03:11:27 PM »
This is my last shot at this. It's as tight as I can get it and still make sense what is going on.

Code: [Select]
besFUNCTION(_frexp)
  double x;
  LEFTVALUE Lval;

  besARGUMENTS("r")
    &x
  besARGEND
  besLEFTVALUE(besARGUMENT(2),Lval);
  besRELEASE(*Lval);
  *Lval = besNEWLONG;
  
  besRETURN_DOUBLE(gsl_frexp(x, *Lval));
besEND

I put the unsigned long __refcount_; needed by the besLEFTVALUE macro in the basext.h file.
« Last Edit: May 29, 2011, 03:26:01 PM by ABB »

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #26 on: May 29, 2011, 03:36:12 PM »
This is the current source for the SB GSL extension module.

Code: [Select]
/*
   GNU Scientific Library
   Based on GSL 1.15
   Interface By: John Spikowski
   Refinements By: Armando I. Rivera (AIR)
   Version 0.01
*/

#include <stdio.h>
#include "../../basext.h"
#include <gsl/gsl_math.h>
     
besVERSION_NEGOTIATE
    return (int)INTERFACE_VERSION;
besEND

besSUB_START

besEND

besSUB_FINISH

besEND

/* Elementary Functions */

besFUNCTION(_log1p)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_log1p(x));
besEND


besFUNCTION(_expm1)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_expm1(x));
besEND


besFUNCTION(_hypot)
  double x,y;

  besARGUMENTS("rr")
    &x,&y
  besARGEND 

  besRETURN_DOUBLE(gsl_hypot(x, y));
besEND


besFUNCTION(_hypot3)
  double x,y,z;
 
  besARGUMENTS("rrr")
    &x,&y,&z
  besARGEND 

  besRETURN_DOUBLE(gsl_hypot3(x, y, z));
besEND


besFUNCTION(_acosh)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_acosh(x));
besEND


besFUNCTION(_asinh)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_asinh(x));
besEND


besFUNCTION(_atanh)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_atanh(x));
besEND


besFUNCTION(_ldexp)
  double x;
  int y;

  besARGUMENTS("ri")
    &x,&y
  besARGEND 

  besRETURN_DOUBLE(gsl_ldexp(x, y));
besEND


besFUNCTION(_frexp)
  double f;
  LEFTVALUE e;

  besARGUMENTS("r")
    &f
  besARGEND
  besLEFTVALUE(besARGUMENT(2),e);
  besRELEASE(*e);
  *e = besNEWLONG;
 
  besRETURN_DOUBLE(gsl_frexp(f, *e));
besEND

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #27 on: May 29, 2011, 04:16:29 PM »
If I assign a value to the variable used as the return for exponent, I can get away with the following. I have to use the besRELEASE and besNEWLONG if I pass it as undef.

Code: [Select]
besFUNCTION(_frexp)
  double f;
  LEFTVALUE e;

  besARGUMENTS("r")
    &f
  besARGEND
  besLEFTVALUE(besARGUMENT(2),e);
  
  besRETURN_DOUBLE(gsl_frexp(f, *e));
besEND

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #28 on: May 30, 2011, 12:06:51 AM »
I added the Small Integer Powers to the ScriptBasic GSL extension module.

Code: [Select]
/* Small integer powers */


besFUNCTION(_pow_int)
  double x;
  int n;

  besARGUMENTS("ri")
    &x,&n
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_int(x, n));
besEND


besFUNCTION(_pow_uint)
  double x;
  unsigned int n;

  besARGUMENTS("ri")
    &x,&n
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_uint(x, n));
besEND


besFUNCTION(_pow_2)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_2(x));
besEND


besFUNCTION(_pow_3)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_3(x));
besEND


besFUNCTION(_pow_4)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_4(x));
besEND


besFUNCTION(_pow_5)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_5(x));
besEND


besFUNCTION(_pow_6)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_6(x));
besEND


besFUNCTION(_pow_7)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_7(x));
besEND


besFUNCTION(_pow_8)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_8(x));
besEND


besFUNCTION(_pow_9)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND 

  besRETURN_DOUBLE(gsl_pow_9(x));
besEND

Code: [Select]
DECLARE SUB pow_4 ALIAS "_pow_4" LIB "gsl"

PRINT FORMAT ("%.16g",pow_4(3.141)),"\n"

97.335607906161

Offline John

  • Forum Support / SB Dev
  • Posts: 2747
    • ScriptBasic Open Source Project
Re: Building a ScriptBasic extension module
« Reply #29 on: May 30, 2011, 09:02:54 AM »
Testing the Sign of Numbers

Quote
Macro: GSL_SIGN (x)

    This macro returns the sign of x. It is defined as ((x) >= 0 ? 1 : -1). Note that with this definition the sign of zero is positive (regardless of its ieee sign bit).

I'm trying to figure out how to call this macro from SB. Should I declare the passed value as DOUBLE even though any positive or negative number can be used. (INT, LONG, DOUBLE, ...)

I'm sure I'm going to run into these macros (as functions) with no defined type to work with.

Update

Code: [Select]
besFUNCTION(_SIGN)
  double x;

  besARGUMENTS("r")
    &x
  besARGEND  

  besRETURN_LONG(GSL_SIGN(x));
besEND

This seems to work no matter what type of numeric value I pass.

I tried to fool it by passing a -0 but it correctly returned 1.
« Last Edit: May 30, 2011, 09:17:45 AM by ABB »