Oxygen Basic

Information => Open Forum => Topic started by: JRS on September 12, 2016, 09:12:35 AM

Title: SBJS
Post by: JRS on September 12, 2016, 09:12:35 AM
Thanks Charles!

That solves the position in the bit map and unmystifies the ORing of these flags. Setting them to TRUE/FALSE still has me scratching my head. I'm on the fence to try to wrap this as a C function or emulate it in Script BASIC.

I think its checking v (object pointer) to see if it exists (non-NULL) before setting a TRUE/FALSE condition.

HERE (https://github.com/cesanta/v7) is the Github project site for V7 if needed.

My plan is to create a Windows JS extension module once the Linux version is done.

I think V7 would be a cool extension to O2 as a DLL interface.

HERE (http://www.allbasic.info/forum/index.php?topic=450.0) is a thread on All BASIC about my progress embedding V7 in Script BASIC.


Title: Re: SBJS
Post by: Mike Lobanovsky on September 12, 2016, 02:46:55 PM
if v then return n or (n<<16) else return n<<16)
---->
if v then return n*0x10000 + n else return n*0x10000

Mmm, I'm afraid not exactly.

While <<16 and *0x10000 are interchangeable and we may even drop the (v7_prop_attr_desc_t) member of the macro painlessly because it's effectively just a cast of n to an unsigned long (cf.  typedef unsigned long v7_prop_attr_desc_t;) to shut up the C compiler's strict type checking, we may not substitute bitwise or with addition here.

So, both

If v Then Return (n BitwiseOr (n << 16)) Else Return (n << 16)

and

If v Then Return (n BitwiseOr (n * 0x10000)) Else Return (n * 0x10000)

are safe for any given n and their combinations be they signed or unsigned, original or cast, as long as we're shifting to the left. When shifting to the right, we must also be aware of signed or unsigned n shifts. In the case of signed negative n, C will preserve its highest-order bit (the leftmost one in Calculator's binary number representation, or the 31st one in the 0..31 bit range) in its place while right shifting. OTOH the highest-order bit of an unsigned n will be right-shifted down together with the other bits in this number. So, right shifts, if any, is where the (v7_prop_attr_desc_t) cast would also matter.

But at any rate, for such a dramatic headlong dash to the left addition is only usable up to a certain "pivot point" where the total of bits in n wouldn't exceed 0xFFFF0000, because any attempt to add yet another bit (i.e. property attribute) to the total rather than bitwise or them together would yield an entirely wrong total:

Code: C
  1. #AppType Console
  2.  
  3. ? "test 0xFFFF0000"
  4. test(0xffff0000)
  5. ? "-------------------------"
  6. ? "test 0xFFFF0001"
  7. test(0xffff0001)
  8.  
  9. DynC test(%n)
  10.   void main(int n)
  11.   {
  12.     printf("    signed + : %d\n", n + (n << 16));
  13.     printf("  unsigned + : %u\n", n + (n << 16));
  14.     printf("(unsigned) + : %u\n", (unsigned)n + ((unsigned)n << 16));
  15.     printf("    signed | : %d\n", n | (n << 16));
  16.     printf("  unsigned | : %u\n", n | (n << 16));
  17.     printf("(unsigned) | : %u\n", (unsigned)n | ((unsigned)n << 16));
  18.   }
  19. End DynC
  20.  
  21. Pause

Output:

test 0xFFFF0000
    signed + : -65536
  unsigned + : 4294901760
(unsigned) + : 4294901760
    signed | : -65536
  unsigned | : 4294901760
(unsigned) | : 4294901760
-------------------------
test 0xFFFF0001
    signed + : 1        <== All wrong! 1 means V7_PROPERTY_NON_WRITABLE!
  unsigned + : 1        <== ditto
(unsigned) + : 1        <== ditto
    signed | : -65535
  unsigned | : 4294901761
(unsigned) | : 4294901761
Title: Re: SBJS
Post by: JRS on September 12, 2016, 08:40:45 PM
Mike,

Should I try to keep this bit shift stuff in C and just pass property attribute status info to an extension module routine?  (if possible)
Title: Re: SBJS
Post by: Mike Lobanovsky on September 12, 2016, 10:08:17 PM
Exactly!

You won't be able to express the entire range of this macro's conditions in traditional BASIC without a lot of time-consuming extra compensatorial math.

If you can, prefer to leave it on the C language side of the SB:C interface.
Title: Re: SBJS
Post by: JRS on September 12, 2016, 10:19:35 PM
Thanks Mike!

I'll take your advice. The unknown (for me) is can I assign a parameter in a macro as a variable passed from a SB ext. module function call?
Title: Re: SBJS
Post by: Mike Lobanovsky on September 12, 2016, 10:37:30 PM
The macro would accept valid literal or variable v and n arguments: v should evaluate to a whole integer (0 = FALSE, otherwise TRUE), and n can be any literal or variable. The C side of the interface should explicitly cast any v that comes in from the SB side to an int, long, or BOOL, while the macro's (v7_prop_attr_desc_t) cast (i.e. (insigned long) cast) will be applied to any incoming literal or variable n automatically.
Title: Re: SBJS
Post by: JRS on September 12, 2016, 11:52:55 PM
Excellent!

I'll give it a shot and see what happens. I will make a seperate ext. module call for each property attribute option. All I should have to pass is v  (object pointer) and a true/false for the attribute state. I should be able to OR the property attribute functions results (using Charles's bit mask table values) in the SB function v7_def() call.

Code: C
  1. v7_def(v7, v, "foo", -1, (V7_PROPERTY_NON_WRITABLE | V7_OVERRIDE_ATTRIBUTES),v7_mk_number(v7, 1.0)),0);
  2.  

Code: Script BASIC
  1. rtncode = JS::DEF(jsobj, propobj, JS::V7_PROPERTY_NON_WRITABLE(1) OR JS::V7_OVERRIDE_ATTRIBUTES(0), JS::MK_NUMBER(jsobj,1.0)),0)
  2.  



Title: Re: SBJS
Post by: Charles Pegge on September 13, 2016, 01:30:35 AM
Hi Mike,

Yes, Script Basic only uses signed integers as its integer type, so one would need to ensure that only bits 0..14 were used to encode all the attributes, before using multiplication and addition.

The header section posted by John shows only bits 0..8 being used.

But I find the scheme of this header perplexing.

Title: Re: SBJS
Post by: JRS on September 13, 2016, 01:49:51 AM
Quote
But I find the scheme of this header perplexing.

Q. How many function variations can you fit in a one line macro?

First there is defining each property attribute with a shifted ORable bit driven sequence followed by property existence validation and finally attribute state assignment. (true/false)
Title: Re: SBJS
Post by: Charles Pegge on September 13, 2016, 03:00:03 AM
Perplexed because I would expect bit attributes to be handled in a simple manner:

Testing attribute n in v
if (v and n) ...

Setting attribute n in v
v or=n

Clearing attribute n in v
v and= not(n)

Inverting (toggling) attribute n in v
v xor= n
Title: Re: SBJS
Post by: Mike Lobanovsky on September 13, 2016, 06:34:26 AM
@Charles:


... so one would need to ensure that only bits 0..14 were used to encode all the attributes ...

Hi,

That's exactly what I meant by extra BASIC arith.

The header section posted by John shows only bits 0..8 being used.

That's correct but the end user's visual memory may render them an ill service elsewhere the next time they try to add high-order bit flags instead of bitwise or them. After all, John's extension module aims for BASIC, not C, end users. :)

But I find the scheme of this header perplexing.

I think that's clearly not a valid C header file but rather a mixture of snippets:

#define _V7_MK_DESC(v, n) \
  (((v7_prop_attr_desc_t)(n)) << _V7_DESC_SHIFT | ((v) ? (n) : 0))


may not precede

typedef unsigned long v7_prop_attr_desc_t;

because the C preprocessor knows nothing of such an O2 goodie as #lookahead. :D


@John:


Hi,

I seem to fail trying to find Peter's original site with full SB documentation to read up on SB's bitwise logic and stuff, and your All Basic link to the SB Reference (http://files.allbasic.info/ScriptBasic/commands.html) seems incomplete.

Perplexed because I would expect bit attributes to be handled in a simple manner:

So am I. I wouldn't expect v being anything else but n itself, tested for n != 0...

Q. How many function variations can you fit in a one line macro?

Actually, a hell of a bloody lot. :D

The C preprocessor is a language unto itself all right, a valuable extra shipped free out of the C box. Its "glue" operator ## would allow you to work miracles chopping your C code and gluing parts of it (down to separate letters' level) at will according to your very personal idea of what "readable code" means.

I've seen pieces of code rendered absolutely unmaintainable due to the author's very peculiar notion of "code readability".

But I've also seen compilable PP code that would express in a handful of lines almost the entire functionality of a library compatible with licensed zlib.dll. ;)
Title: Re: SBJS
Post by: JRS on September 13, 2016, 09:24:31 AM
HERE (http://www.scriptbasic.org/wiki/index.php?title=Main_Page) is a link to the Script BASIC wiki. It contains the user and developer guides along with docs for some of the extension modules.

Peter Verhas's (original author of Script BASIC) www.scriptbasic.com site is no longer. He is Java centric and I don't see Peter going back to C anytime soon.

Quote
The C preprocessor is a language unto itself all right,

I think C BASIC is a good example of that.
Title: Re: SBJS
Post by: Mike Lobanovsky on September 13, 2016, 03:26:25 PM
Oh, thanks John!

Developers Guide - ONLINE is exactly what I've been looking for.

(sorry for confusing Peter with Paul -- my sacrilegeous blunder's just been fixed) ;D
Title: Re: SBJS
Post by: JRS on September 13, 2016, 04:26:51 PM
Mike,

I think I have everything figured out except the OR aspect of these property attributes. I was thinking of the SB ext. module attribute functions returning the shift offset value Charles posted. Do you see that as a valid solution?

Update:

I think I'm going to use the following method for setting/clearing property attributes. If the attribute flag isn't passed it is (re)set to zero (false) unless P is passed which leaves unreferenced attributes as is.

Code: Script BASIC
  1. JS::DEF(jsobj, propobj, "my_property", 11, "WECGSP", 123)
  2.  

Title: Re: SBJS
Post by: Mike Lobanovsky on September 14, 2016, 01:50:23 AM
... I have everything figured out except the OR aspect of these property attributes.

Just in case you're still having difficulties with the C preprocessor, you may wish to use procedural equivalents of the macros on either the SB or C side of the interface. It is feasible, albeit a bit slower than inlined macros.

Consider the following SB routines (SB docs say SB would convert bitwise OR and NOT arguments to integers automatically, and trial shows any IF argument evaluates to TRUE if it is <> 0 or <> FALSE):

Code: Script BASIC
  1. FUNCTION _V7_MK_DESC(v, n)
  2.     IF v THEN
  3.         _V7_MK_DESC = (n OR (n * 0x10000))
  4.     ELSE
  5.         _V7_MK_DESC = INT(n * 0x10000)
  6.     END IF
  7. END FUNCTION

and

Code: Script BASIC
  1. FUNCTION _V7_MK_DESC_INV(v, n)
  2.     _V7_MK_DESC_INV = _V7_MK_DESC(NOT v, n)
  3. END FUNCTION

or their C language equivalents:

Code: C
  1. unsigned long _V7_MK_DESC(int v, unsigned long n) {
  2.     if (v)
  3.         return (n | (n << 16));
  4.     return (n << 16);
  5. }

and

Code: C
  1. unsigned long _V7_MK_DESC_INV(int v, unsigned long n) {
  2.     return _V7_MK_DESC(!v, n);
  3. }

then "functionalize" the other macros at the bottom of your greenish pseudo C header as calls to the two functions above, should you need them too on either side of your interface implementation at all.

Hope this helps.
Title: Re: SBJS
Post by: JRS on September 14, 2016, 08:20:54 AM
Thanks Mike!

This is helpful for the C side of the equation. I like the direction I'm going from the SB side. It's simple to understand and BASIC like.
Title: Re: SBJS
Post by: Charles Pegge on September 15, 2016, 02:34:20 AM

OxygenBasic currently does not support  E=( A>B ? C : D ) constructs. I think it will be a useful addition, especially when it turns up in C headers, such as this one. So I will include this capability in the next o2 release.
Title: Re: SBJS
Post by: Mike Lobanovsky on September 15, 2016, 03:01:05 AM
OxygenBasic currently does not support  E=( A>B ? C : D ) constructs.

It's a BASIC IIF(condition, true-result, false-result) function-like implementation of IF/THEN/ELSE with a return value.

Quote
I think it will be a useful addition, especially when it turns up in C headers ...

Try to keep it "short circuited" so that it would only "execute" the condition code and the actual result code and then it would also be usable in its command-like form -- an elegant shorthand for IF/THEN/ELSE impossible in the C language where the ?: ternary operator can only appear as the rhs member of an expression. 8)

Quote
So I will include this capability in the next o2 release.

God bless! :)
Title: Re: SBJS
Post by: JRS on September 15, 2016, 09:16:44 AM
I added Peter Verhas's  IFF example in the trial extension module to show how to create a SB COMMAND not function/sub to the JS (JavaScript) extension module as js_iif.

Code: Script BASIC
  1. IMPORT js.bas
  2.  
  3. a = "BASIC"
  4.  
  5. PRINT JS::IIF("BASIC" = a,"TRUE","FALSE"),"\n"
  6. PRINT JS::IIF(a = "CISAB","TRUE","FALSE"),"\n"
  7.  


jrs@laptop:~/sb/sb22/js$ scriba js_iif.sb
TRUE
FALSE
jrs@laptop:~/sb/sb22/js$


Here is the C extension module code for the IIF() command.

Code: C
  1. besCOMMAND(js_iif)
  2.   DIM AS NODE nItem;
  3.   DIM AS VARIABLE Op1;
  4.   DIM long ConditionValue;
  5.   USE_CALLER_MORTALS;
  6.   nItem = besPARAMETERLIST;
  7.   IF (NOT nItem) THEN
  8.     RESULT = NULL;
  9.     RETURN;
  10.   END_IF
  11.   Op1 = besEVALUATEEXPRESSION(CAR(nItem));
  12.   ASSERTOKE;
  13.   IF (Op1 EQ NULL) THEN
  14.     ConditionValue = 0;
  15.   ELSE
  16.     Op1 = besCONVERT2LONG(Op1);
  17.     ConditionValue = LONGVALUE(Op1);
  18.   END_IF
  19.   IF (NOT ConditionValue) THEN_DO nItem = CDR(nItem);
  20.   IF (NOT nItem) THEN
  21.     RESULT = NULL;
  22.     RETURN;
  23.   END_IF
  24.   nItem = CDR(nItem);
  25.   RESULT = besEVALUATEEXPRESSION(CAR(nItem));
  26.   ASSERTOKE;
  27.   RETURN;
  28. besEND_COMMAND
  29.  

Pushing the envelope a bit.

Code: Script BASIC
  1. IMPORT js.bas
  2.  
  3. FUNCTION T
  4.   T = "True"
  5. END FUNCTION  
  6.  
  7. FUNCTION F
  8.   F = "False"
  9. END FUNCTION  
  10.  
  11.  
  12. a = "BASIC"
  13.  
  14. PRINT JS::IIF("BASIC" = a,T(),F()),"\n"
  15. PRINT JS::IIF(a = "CISAB",T(),F()),"\n"
  16.  


jrs@laptop:~/sb/sb22/js$ scriba js_iif_func.sb
True
False
jrs@laptop:~/sb/sb22/js$


Title: Re: SBJS
Post by: JRS on September 16, 2016, 11:59:47 AM
Mike,

Will something like this work?

Code: Script BASIC
  1. FUNCTION _V7_MK_DESC_INV(v, n)
  2.   _V7_MK_DESC_INV = JS::IIF(v, (n OR (n * 0x10000)), INT(n * 0x10000))
  3. END FUNCTION
  4.  

How do we OR the property attribute flags with JS::DEF()? Can an ORed value be passed and the V7 function will take care of setting the appropriate attributes?

Here is the JS_DEF function for the ext. module. It stills needs the property attribute support either from SB scripting or from the ext. module function.

Code: C
  1. besFUNCTION(js_def)
  2.   DIM AS VARIABLE Argument;
  3.   DIM AS unsigned long v7;
  4.   DIM AS v7_val_t objptr, valueptr;
  5.   DIM AS const char *objname;
  6.   DIM AS size_t objnamelen;
  7.   DIM AS v7_prop_attr_desc_t attrs_desc;
  8.   DIM AS int rtnstatus, i;
  9.   IF (besARGNR < 6) THEN_DO RETURN_FUNCTION(EX_ERROR_TOO_FEW_ARGUMENTS);
  10.   DEF_FOR (i = 1 TO i <= 6 STEP INCR i)
  11.   BEGIN_FOR
  12.     Argument = besARGUMENT(i);
  13.     besDEREFERENCE(Argument);
  14.     IF (i EQ 1) THEN_DO v7 = (unsigned long)LONGVALUE(Argument);
  15.     IF (i EQ 2) THEN_DO objptr = (v7_val_t)LONGVALUE(Argument);
  16.     IF (i EQ 3) THEN_DO objname = STRINGVALUE(Argument);
  17.     IF (i EQ 4) THEN_DO objnamelen = (size_t)LONGVALUE(Argument);
  18.     IF (i EQ 5) THEN_DO attrs_desc = (v7_prop_attr_desc_t)LONGVALUE(Argument);
  19.     IF (i EQ 6) THEN_DO valueptr = (v7_val_t)LONGVALUE(Argument);      
  20.   NEXT
  21.   rtnstatus = v7_def(v7, objptr, objname, objnamelen, attrs_desc, valueptr);
  22.   besRETURN_LONG(rtnstatus);
  23. besEND
  24.  


v eval test
Code: Script BASIC
  1. IMPORT js.bas
  2.  
  3. v = 0
  4. PRINT JS::IIF(v,TRUE,FALSE),"\n"
  5. v = 1
  6. PRINT JS::IIF(v,TRUE,FALSE),"\n"
  7.  


jrs@laptop:~/sb/sb22/js$ scriba js_iif_eval.sb
0
-1
jrs@laptop:~/sb/sb22/js$



Title: Re: SBJS
Post by: Mike Lobanovsky on September 17, 2016, 02:01:36 AM
John,

Please get me right: I am willing to help but my willingness has its reasonable bounds. I don't want to dive into that V7 stuff headlong myself unless absolutely necessary. Before I can give you correct and definitive answers, please gimme yours:Until you've given me the answers, consider all your JS::/SB code just as a lego for your mind. It yields seemingly correct results but it is unnecessary. I'm telling you you'll get much faster code if you implement _V7_MK_DESC(), _V7_MK_DESC_INV(), IIF() directly in SB than on the other side of your interface where you have to pass, accept, and evaluate a dozen args instead of just two or three in SB.

Your _V7_MK_DESC_INV() is incorrect: that's what _V7_MK_DESC() should do while _V7_MK_DESC_INV() must have inverse logic for its v condition. The former is for setting a property attribute, and the latter, for clearing it. The fastest and easiest way to implement them in SB or C I've already given in my previous message. v is the condition (whose purpose I don't know) and n is obviously the property attribute you're wanting to set or clear, as described in the table Charles has given you earlier in C:

Code: C
  1. #define V7_PROPERTY_NON_WRITABLE     1
  2. #define V7_PROPERTY_NON_ENUMERABLE   2
  3. #define V7_PROPERTY_NON_CONFIGURABLE 4
  4. #define V7_PROPERTY_GETTER           8
  5. #define V7_PROPERTY_SETTER           16
  6. #define _V7_PROPERTY_HIDDEN          32
  7. #define _V7_PROPERTY_OFF_HEAP        64
  8. #define _V7_PROPERTY_USER_DATA_AND_DESTRUCTOR 128
  9. #define _V7_DESC_PRESERVE_VALUE               256
  10. #define _V7_DESC_MASK                         0xffff

or in SB as rewritten below:

Code: Script BASIC
  1. CONST V7_PROPERTY_NON_WRITABLE              = 1
  2. CONST V7_PROPERTY_NON_ENUMERABLE            = 2
  3. CONST V7_PROPERTY_NON_CONFIGURABLE          = 4
  4. CONST V7_PROPERTY_GETTER                    = 8
  5. CONST V7_PROPERTY_SETTER                    = 16
  6. CONST _V7_PROPERTY_HIDDEN                   = 32
  7. CONST _V7_PROPERTY_OFF_HEAP                 = 64
  8. CONST _V7_PROPERTY_USER_DATA_AND_DESTRUCTOR = 128
  9. CONST _V7_DESC_PRESERVE_VALUE               = 256
  10. CONST _V7_DESC_MASK                         = &HFFFF

My guess is they are to be used directly in SB for input to the header's "functionalized" macros whose output should go to v7_def() (or besFUNCTION(js_def)), if it is the entry point they are meant for.

Lastly, your IIF() is not a command, it is a typical function. It is implemented in the BASIC traditional non-short-circuited way (even if it goes to JS for evaluation) which is bug-prone and precludes its use as a command because before it yields its return, whether usable or discardable, it will execute both TRUE and FALSE of its arguments if they are fed to IIF() not as literal values but rather as the results of some external calculus or as other procedures' returns. A true short-circuited-logic command would execute only one of them -- whichever is appropriate for a given condition.

Now please answer my questions before we can proceed.
Title: Re: SBJS
Post by: JRS on September 17, 2016, 09:14:58 AM
Quote
What's the exact purpose of v7_def()? Is it some sort of an entry point to the JS module (.lib/.dll or .a/.so)?
v7_def() defines JavaScript object properties. We are unraveling the attribute argument for the function. Everything else is already written for the v7_def() function.

Quote
If yes then what's its original declaration (plain C or JS, no CBASIC for me please)?

Code: [Select]
/*
 * Property attributes bitmask
 */
typedef unsigned short v7_prop_attr_t;
#define V7_PROPERTY_NON_WRITABLE (1 << 0)
#define V7_PROPERTY_NON_ENUMERABLE (1 << 1)
#define V7_PROPERTY_NON_CONFIGURABLE (1 << 2)
#define V7_PROPERTY_GETTER (1 << 3)
#define V7_PROPERTY_SETTER (1 << 4)
#define _V7_PROPERTY_HIDDEN (1 << 5)
/* property not managed by V7 HEAP */
#define _V7_PROPERTY_OFF_HEAP (1 << 6)
/* special property holding user data and destructor cb */
#define _V7_PROPERTY_USER_DATA_AND_DESTRUCTOR (1 << 7)
/*
 * not a property attribute, but a flag for `v7_def()`. It's here in order to
 * keep all offsets in one place
 */
#define _V7_DESC_PRESERVE_VALUE (1 << 8)

/*
 * Internal helpers for `V7_DESC_...` macros
 */
#define _V7_DESC_SHIFT 16
#define _V7_DESC_MASK ((1 << _V7_DESC_SHIFT) - 1)
#define _V7_MK_DESC(v, n) \
  (((v7_prop_attr_desc_t)(n)) << _V7_DESC_SHIFT | ((v) ? (n) : 0))
#define _V7_MK_DESC_INV(v, n) _V7_MK_DESC(!(v), (n))

/*
 * Property attribute descriptors that may be given to `v7_def()`: for each
 * attribute (`v7_prop_attr_t`), there is a corresponding macro, which takes
 * param: either 1 (set attribute) or 0 (clear attribute). If some particular
 * attribute isn't mentioned at all, it's left unchanged (or default, if the
 * property is being created)
 *
 * There is additional flag: `V7_DESC_PRESERVE_VALUE`. If it is set, the
 * property value isn't changed (or set to `undefined` if the property is being
 * created)
 */
typedef unsigned long v7_prop_attr_desc_t;
#define V7_DESC_WRITABLE(v) _V7_MK_DESC_INV(v, V7_PROPERTY_NON_WRITABLE)
#define V7_DESC_ENUMERABLE(v) _V7_MK_DESC_INV(v, V7_PROPERTY_NON_ENUMERABLE)
#define V7_DESC_CONFIGURABLE(v) _V7_MK_DESC_INV(v, V7_PROPERTY_NON_CONFIGURABLE)
#define V7_DESC_GETTER(v) _V7_MK_DESC(v, V7_PROPERTY_GETTER)
#define V7_DESC_SETTER(v) _V7_MK_DESC(v, V7_PROPERTY_SETTER)
#define V7_DESC_PRESERVE_VALUE _V7_DESC_PRESERVE_VALUE

#define _V7_DESC_HIDDEN(v) _V7_MK_DESC(v, _V7_PROPERTY_HIDDEN)
#define _V7_DESC_OFF_HEAP(v) _V7_MK_DESC(v, _V7_PROPERTY_OFF_HEAP)

/*
 * Define object property, similar to JavaScript `Object.defineProperty()`.
 *
 * `name`, `name_len` specify property name, `val` is a property value.
 * `attrs_desc` is a set of flags which can affect property's attributes,
 * see comment of `v7_prop_attr_desc_t` for details.
 *
 * If `name_len` is ~0, `name` is assumed to be NUL-terminated and
 * `strlen(name)` is used.
 *
 * Returns non-zero on success, 0 on error (e.g. out of memory).
 *
 * See also `v7_set()`.
 */
int v7_def(struct v7 *v7, v7_val_t obj, const char *name, size_t name_len,
           v7_prop_attr_desc_t attrs_desc, v7_val_t v);

Quote
Is the header you provided used for compiling the V7 sources themselves or is it meant for the V7 end user to utilize it in their C sources to communicate with the precompiled V7 module?

The V7 JavaScript Engine / API is made up of two files. (v7.h and v7.c) I include both of these when building my js.so SB C extension module. This allows me to extend SB dynamically with JavaScript OOP functionality as if it were part of Script BASIC.

makefile
Code: C
  1. all : /home/jrs/sb/source/bin/mod/lib/js.a /home/jrs/sb/source/bin/mod/dll/js.so
  2.  
  3. /home/jrs/sb/source/bin/mod/lib/js.a : /home/jrs/sb/source/bin/mod/obj/js/s_interface.o /home/jrs/sb/source/bin/mod/obj/js/js.o
  4.         ar -r /home/jrs/sb/source/bin/mod/lib/js.a /home/jrs/sb/source/bin/mod/obj/js/s_interface.o /home/jrs/sb/source/bin/mod/obj/js/js.o  
  5.  
  6. /home/jrs/sb/source/bin/mod/dll/js.so : /home/jrs/sb/source/bin/mod/obj/js/interface.o /home/jrs/sb/source/bin/mod/obj/js/js.o
  7.         ld -shared -fPIC -o /home/jrs/sb/source/bin/mod/dll/js.so /home/jrs/sb/source/bin/mod/obj/js/interface.o /home/jrs/sb/source/bin/mod/obj/js/js.o -lm
  8.  
  9. /home/jrs/sb/source/bin/mod/obj/js/interface.o : interface.c v7.h
  10.         gcc -O2 -w -m64 -fPIC -c -DV7_BUILD_PROFILE=3 -DCS_ENABLE_UTF8 -DV7_ENABLE_FILE -DV7_ENABLE_SOCKET -o /home/jrs/sb/source/bin/mod/obj/js/interface.o interface.c
  11.  
  12. /home/jrs/sb/source/bin/mod/obj/js/s_interface.o : interface.c v7.h
  13.         gcc -O2 -w -m64 -fPIC -DSTATIC_LINK=1 -c -DV7_BUILD_PROFILE=3 -DCS_ENABLE_UTF8 -DV7_ENABLE_FILE -DV7_ENABLE_SOCKET -o /home/jrs/sb/source/bin/mod/obj/js/s_interface.o interface.c
  14.  
  15. /home/jrs/sb/source/bin/mod/obj/js/js.o : v7.c
  16.         gcc -O2 -w -m64 -fPIC -c -DV7_BUILD_PROFILE=3 -DCS_ENABLE_UTF8 -DV7_ENABLE_FILE -DV7_ENABLE_SOCKET -o /home/jrs/sb/source/bin/mod/obj/js/js.o v7.c
  17.  

Ideally I would like to get the property attribute parameter defined in SB and pass as an argument to JS::DEF() which is ready to roll as is. If this isn't practical then doing it just before the call in the ext. module function seeding it from SB script is plan B.

I hope this is enough for us to sync on this and not waste any of your time which I view as precious.


Title: Re: SBJS
Post by: Mike Lobanovsky on September 17, 2016, 11:22:27 AM
Thanks John, this clears things up a lot.

One more Q.: Is SB UTF8 aware?

And yet one more Q.: If yes then how do you specify in the SB code exactly what type of strings you're using for internal purposes and, most importantly, are passing to the outer world, UTF8 or ASCIIZ?
Title: Re: SBJS
Post by: JRS on September 17, 2016, 11:29:57 AM
Quote
One more Q.: Is SB UTF8 aware?

I assume so as all it's script files on Linux are in UTF8 format. (per UltraEdit Linux status line indicator)
Title: Re: SBJS
Post by: Mike Lobanovsky on September 17, 2016, 11:53:19 AM
(Pls see my edit)

I remember you were having difficulties with strings...
Title: Re: SBJS
Post by: JRS on September 17, 2016, 12:17:16 PM
That has been RESOLVED (http://www.allbasic.info/forum/index.php?topic=450.msg4821#msg4821). It was caused by a known but forgotten bug in Script BASIC's nifty variadic argument handler Peter wrote. I had to go back to the old way to get around it and for anything with more than 5 arguments.

Quote
are passing to the outer world, UTF8 or ASCIIZ?

ASCIIZ is my guess. ("z" designator)

SB can also pass binary strings (null embeded) as a "s" type.

Some info on this. (http://www.scriptbasic.org/docs/dg/devguide_4.5.269.html)



Title: Re: SBJS
Post by: Mike Lobanovsky on September 17, 2016, 12:25:13 PM
OK THNX!
Title: Re: SBJS
Post by: JRS on September 17, 2016, 01:23:07 PM
Here is where I'm at with the JS (JavaScript) extension module for Script BASIC.

interface.c
Code: C
  1. /*  V7 JavaScript Engine Extension Module */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <math.h>
  8. #include <time.h>
  9. #include <unistd.h>
  10. #include "v7.h"
  11. #include "../../basext.h"
  12. #include "../../scriba.h"
  13. #include "cbasic.h"
  14.  
  15.  
  16.  
  17. /****************************
  18.  Extension Module Functions
  19. ****************************/
  20.  
  21. besVERSION_NEGOTIATE
  22.   RETURN_FUNCTION((int)INTERFACE_VERSION);
  23. besEND
  24.  
  25. besSUB_START
  26.   DIM AS long PTR p;
  27.   besMODULEPOINTER = besALLOC(sizeof(long));
  28.   IF (besMODULEPOINTER EQ NULL) THEN_DO RETURN_FUNCTION(0);
  29.   p = (long PTR)besMODULEPOINTER;
  30.   RETURN_FUNCTION(0);
  31. besEND
  32.  
  33. besSUB_FINISH
  34.   DIM AS long PTR p;
  35.   p = (long PTR)besMODULEPOINTER;
  36.   IF (p EQ NULL) THEN_DO RETURN_FUNCTION(0);
  37.   RETURN_FUNCTION(0);
  38. besEND
  39.  
  40.  
  41. /*****************
  42.  Utility Funtions
  43. *****************/
  44.  
  45. besFUNCTION(SB_shifts)
  46.   DIM AS int bp, co, v, x, y, d, p, ar;
  47.   besARGUMENTS("ii[i]")
  48.     AT v, AT p, AT ar
  49.   besARGEND
  50.   IF (ar EQ NULL) THEN_DO ar = 0;
  51.   x = 0xffffffff & v;
  52.   IF (p >= 0) THEN
  53.     y = x << p; // bit shift left
  54.   ELSE
  55.     y = x >> (-p); // bit shift right
  56.   END_IF
  57. //
  58. // SUPPORT FOR ARITHMETIC RIGHT SHIFTS
  59. //
  60.   IF ((ar) AND (p < 0) AND (x & 0x80000000)) THEN
  61.     d = 31 + p;
  62.     IF (d < 0) THEN_DO d = 0; // LIMIT
  63.     bp = 0x80000000;
  64.     DEF_FOR (co = 31 TO co >= d STEP DECR co)
  65.     BEGIN_FOR
  66.       y = y | bp;
  67.       bp = bp >> 1;
  68.     NEXT
  69.   END_IF
  70.   besRETURN_LONG(y);
  71. besEND
  72.  
  73. besFUNCTION(SB_rotates)
  74.   DIM AS int co, v, x, y, d, p, ar;
  75.   besARGUMENTS("ii[i]")
  76.     AT v, AT p, AT ar
  77.   besARGEND
  78.   IF (ar EQ NULL) THEN_DO ar = 0;
  79.   x = 0xffffffff & v;
  80.   d = p;
  81.   IF (d < 0) THEN_DO d=-d;
  82.   DEF_FOR (co = 1 TO co <= d STEP INCR co)
  83.   BEGIN_FOR
  84.     IF (p >= 0) THEN
  85.       y = x << 1; // bit shift left
  86.       IF (x & 0x80000000) THEN_DO y |= 1;
  87.     ELSE
  88.       y = x >> 1; // bit shift right
  89.       IF (x & 1) THEN_DO y |= 0x80000000;
  90.     END_IF
  91.     x = y;
  92.   NEXT
  93.   besRETURN_LONG(y);
  94. besEND
  95.  
  96. besFUNCTION(prop_attr)
  97.   V7_DESC_WRITABLE(1);
  98.   PRINT ("V7_PROPERTY_NON_WRITABLE: %g\n", V7_PROPERTY_NON_WRITABLE);
  99.   PRINT ("V7_PROPERTY_NON_ENUMERABLE: %g\n", V7_PROPERTY_NON_ENUMERABLE);
  100.   PRINT ("V7_PROPERTY_NON_CONFIGURABLE: %g\n", V7_PROPERTY_NON_CONFIGURABLE);
  101.   PRINT ("V7_PROPERTY_GETTER: %g\n", V7_PROPERTY_GETTER);
  102.   PRINT ("V7_PROPERTY_SETTER: %g\n", V7_PROPERTY_SETTER);
  103.   PRINT ("_V7_PROPERTY_HIDDEN: %g\n", _V7_PROPERTY_HIDDEN);
  104.   PRINT ("_V7_PROPERTY_OFF_HEAP: %g\n", _V7_PROPERTY_OFF_HEAP);
  105.   PRINT ("_V7_PROPERTY_USER_DATA_AND_DESTRUCTOR: %g\n", _V7_PROPERTY_USER_DATA_AND_DESTRUCTOR);
  106.   PRINT ("_V7_DESC_PRESERVE_VALUE: %g\n", _V7_DESC_PRESERVE_VALUE);
  107.   besRETURNVALUE = NULL;
  108. besEND
  109.  
  110. besCOMMAND(js_iif)
  111.   DIM AS NODE nItem;
  112.   DIM AS VARIABLE Op1;
  113.   DIM long ConditionValue;
  114.   USE_CALLER_MORTALS;
  115.   nItem = besPARAMETERLIST;
  116.   IF (NOT nItem) THEN
  117.     RESULT = NULL;
  118.     RETURN;
  119.   END_IF
  120.   Op1 = besEVALUATEEXPRESSION(CAR(nItem));
  121.   ASSERTOKE;
  122.   IF (Op1 EQ NULL) THEN
  123.          ConditionValue = 0;
  124.   ELSE
  125.     Op1 = besCONVERT2LONG(Op1);
  126.     ConditionValue = LONGVALUE(Op1);
  127.   END_IF
  128.   IF (NOT ConditionValue) THEN_DO nItem = CDR(nItem);
  129.   IF (NOT nItem) THEN
  130.     RESULT = NULL;
  131.     RETURN;
  132.   END_IF
  133.   nItem = CDR(nItem);
  134.   RESULT = besEVALUATEEXPRESSION(CAR(nItem));
  135.   ASSERTOKE;
  136.   RETURN;
  137. besEND_COMMAND
  138.  
  139.  
  140. /*******
  141.  V7 API
  142. *******/
  143.  
  144. besFUNCTION(js_create)
  145.   struct v7 *v7 = v7_create();
  146.   besRETURN_LONG(v7);
  147. besEND
  148.  
  149. besFUNCTION(js_destroy)
  150.   DIM AS unsigned long v7;
  151.   besARGUMENTS("i")
  152.     AT v7
  153.   besARGEND
  154.   v7_destroy(v7);
  155.   besRETURNVALUE = NULL;
  156. besEND
  157.  
  158. besFUNCTION(js_exec)
  159.   VARIABLE Argument;
  160.   LEFTVALUE Lval;
  161.   unsigned long __refcount_;
  162.   DIM AS unsigned long v7;
  163.   DIM AS const char *js_code;
  164.   DIM AS v7_val_t result;
  165.   enum v7_err rcode = V7_OK;
  166.   besARGUMENTS("iz")
  167.     AT v7, AT js_code
  168.   besARGEND
  169.   rcode = v7_exec(v7, js_code, &result);
  170.   Argument = besARGUMENT(3);
  171.   besLEFTVALUE(Argument,Lval);
  172.   besRELEASE(*Lval);
  173.   *Lval = besNEWLONG;
  174.   LONGVALUE(*Lval) = rcode;
  175.   besRETURN_LONG(result);
  176. besEND
  177.  
  178. besFUNCTION(js_get_int)
  179.   DIM AS unsigned long v7;
  180.   DIM AS v7_val_t resultptr;
  181.   DIM AS int rtnval;
  182.   besARGUMENTS("ii")
  183.     AT v7, AT resultptr
  184.   besARGEND
  185.   rtnval = v7_get_int(v7, resultptr);
  186.   besRETURN_LONG(rtnval);
  187. besEND
  188.  
  189. besFUNCTION(js_get_double)
  190.   DIM AS unsigned long v7;
  191.   DIM AS v7_val_t resultptr;
  192.   DIM AS double rtnval;
  193.   besARGUMENTS("ii")
  194.     AT v7, AT resultptr
  195.   besARGEND
  196.   rtnval = v7_get_double(v7, resultptr);
  197.   besRETURN_DOUBLE(rtnval);
  198. besEND
  199.  
  200. besFUNCTION(js_get_string)
  201.   DIM AS unsigned long v7;
  202.   DIM AS v7_val_t resultptr;
  203.   DIM const char *sbstr;
  204.   DIM size_t *strsize;
  205.   besARGUMENTS("ii")
  206.     AT v7, AT resultptr
  207.   besARGEND
  208.   sbstr = v7_get_string(v7, &resultptr, NULL);
  209.   besRETURN_STRING(sbstr);
  210. besEND
  211.  
  212. besFUNCTION(js_get)
  213.   DIM AS unsigned long v7;
  214.   DIM AS v7_val_t obj, result;
  215.   DIM AS const char *name;
  216.   DIM AS size_t name_len;
  217.   besARGUMENTS("iizi")
  218.     AT v7, AT obj, AT name, AT name_len
  219.   besARGEND
  220.   result = v7_get(v7, obj, name, name_len);
  221.   besRETURN_LONG(result);
  222. besEND
  223.  
  224. besFUNCTION(js_get_global)
  225.   DIM AS unsigned long v7;
  226.   DIM AS v7_val_t result;
  227.   besARGUMENTS("i")
  228.     AT v7
  229.   besARGEND
  230.   result = v7_get_global(v7);
  231.   besRETURN_LONG(result);
  232. besEND
  233.  
  234. besFUNCTION(js_mk_array)
  235.   DIM AS unsigned long v7;
  236.   DIM AS v7_val_t result;
  237.   besARGUMENTS("i")
  238.     AT v7
  239.   besARGEND
  240.   result = v7_mk_array(v7);
  241.   besRETURN_LONG(result);
  242. besEND
  243.  
  244. besFUNCTION(js_array_push)
  245.   DIM AS unsigned long v7;
  246.   DIM AS v7_val_t arrayptr, arrayval;
  247.   DIM AS int rtncode;
  248.   besARGUMENTS("iii")
  249.     AT v7, AT arrayptr, AT arrayval
  250.   besARGEND
  251.   rtncode = v7_array_push(v7, arrayptr, arrayval);
  252.   besRETURN_LONG(rtncode);
  253. besEND
  254.  
  255. besFUNCTION(js_mk_number)
  256.   DIM AS unsigned long v7;
  257.   DIM AS double numval;
  258.   DIM AS v7_val_t result;
  259.   besARGUMENTS("ir")
  260.     AT v7, AT numval
  261.   besARGEND
  262.   result = v7_mk_number(v7, numval);
  263.   besRETURN_LONG(result);
  264. besEND
  265.  
  266. besFUNCTION(js_apply)
  267.   VARIABLE Argument;
  268.   LEFTVALUE Lval;
  269.   unsigned long __refcount_;
  270.   DIM AS unsigned long v7;
  271.   DIM AS v7_val_t funcptr, objptr, argsptr, result;
  272.   enum v7_err rtncode = V7_OK;
  273.   besARGUMENTS("iiii")
  274.     AT v7, AT funcptr, AT objptr, AT argsptr
  275.   besARGEND
  276.   IF (objptr == 0) THEN
  277.     rtncode = v7_apply(v7, funcptr, V7_UNDEFINED, argsptr, &result);
  278.   ELSE
  279.         rtncode = v7_apply(v7, funcptr, objptr, argsptr, &result);
  280.   END_IF
  281.   Argument = besARGUMENT(4);
  282.   besLEFTVALUE(Argument,Lval);
  283.   besRELEASE(*Lval);
  284.   *Lval = besNEWLONG;
  285.   LONGVALUE(*Lval) = rtncode;
  286.   besRETURN_LONG(result);
  287. besEND
  288.  
  289. besFUNCTION(js_get_this)
  290.   DIM AS unsigned long v7;
  291.   DIM AS v7_val_t result;
  292.   besARGUMENTS("i")
  293.     AT v7
  294.   besARGEND
  295.   result = v7_get_this(v7);
  296.   besRETURN_LONG(result);
  297. besEND
  298.  
  299. besFUNCTION(js_get_arguments)
  300.   DIM AS unsigned long v7;
  301.   DIM AS v7_val_t result;
  302.   besARGUMENTS("i")
  303.     AT v7
  304.   besARGEND
  305.   result = v7_get_arguments(v7);
  306.   besRETURN_LONG(result);
  307. besEND
  308.  
  309. besFUNCTION(js_arg)
  310.   DIM AS unsigned long v7, arrayidx;
  311.   DIM AS v7_val_t result;
  312.   besARGUMENTS("ii")
  313.     AT v7, AT arrayidx
  314.   besARGEND
  315.   result = v7_arg(v7, arrayidx);
  316.   besRETURN_LONG(result);
  317. besEND
  318.  
  319. besFUNCTION(js_argc)
  320.   DIM AS unsigned long v7, arglen;
  321.   besARGUMENTS("i")
  322.     AT v7
  323.   besARGEND
  324.   arglen = v7_argc(v7);
  325.   besRETURN_LONG(arglen);
  326. besEND
  327.  
  328. besFUNCTION(js_own)
  329.   DIM AS unsigned long v7;
  330.   DIM AS v7_val_t *cvar;
  331.   besARGUMENTS("ii")
  332.     AT v7, AT cvar
  333.   besARGEND
  334.   v7_own(v7, &cvar);
  335.   besRETURNVALUE = NULL;
  336. besEND
  337.  
  338. besFUNCTION(js_disown)
  339.   DIM AS unsigned long v7;
  340.   DIM AS v7_val_t *cvar;
  341.   DIM AS int found;
  342.   besARGUMENTS("ii")
  343.     AT v7, AT cvar
  344.   besARGEND
  345.   found = v7_disown(v7, &cvar);
  346.   besRETURN_LONG(found);
  347. besEND
  348.  
  349. besFUNCTION(js_get_parser_error)
  350.   DIM AS unsigned long v7;
  351.   DIM AS const char *errstr;
  352.   besARGUMENTS("i")
  353.     AT v7
  354.   besARGEND
  355.   errstr = v7_get_parser_error(v7);
  356.   besRETURN_STRING(errstr);
  357. besEND
  358.  
  359. besFUNCTION(js_is_number)
  360.   DIM AS v7_val_t varptr;
  361.   DIM AS int istrue;
  362.   besARGUMENTS("i")
  363.     AT varptr
  364.   besARGEND
  365.   istrue = v7_is_number(varptr);
  366.   besRETURN_LONG(istrue);
  367. besEND
  368.  
  369. besFUNCTION(js_mk_boolean)
  370.   DIM AS unsigned long v7;
  371.   DIM AS v7_val_t boolptr;
  372.   DIM AS int istrue;
  373.   besARGUMENTS("ii")
  374.     AT v7, AT istrue
  375.   besARGEND
  376.   boolptr = v7_mk_boolean(v7, istrue);
  377.   besRETURN_LONG(boolptr);
  378. besEND
  379.  
  380. besFUNCTION(js_get_bool)
  381.   DIM AS unsigned long v7;
  382.   DIM AS v7_val_t boolptr;
  383.   DIM AS int truefalse;
  384.   besARGUMENTS("ii")
  385.     AT v7, AT truefalse
  386.   besARGEND
  387.   truefalse = v7_get_bool(v7, boolptr);
  388.   besRETURN_LONG(truefalse);
  389. besEND
  390.  
  391. besFUNCTION(js_is_boolean)
  392.   DIM AS v7_val_t boolptr;
  393.   DIM AS int istrue;
  394.   besARGUMENTS("i")
  395.     AT boolptr
  396.   besARGEND
  397.   istrue = v7_is_boolean(boolptr);
  398.   besRETURN_LONG(istrue);
  399. besEND
  400.  
  401. besFUNCTION(js_mk_null)
  402.   DIM AS v7_val_t result;
  403.   result = V7_NULL;
  404.   besRETURN_LONG(result);
  405. besEND
  406.  
  407. besFUNCTION(js_is_null)
  408.   DIM AS v7_val_t nullptr;
  409.   DIM AS int istrue;
  410.   besARGUMENTS("i")
  411.     AT nullptr
  412.   besARGEND
  413.   istrue = v7_is_null(nullptr);
  414.   besRETURN_LONG(istrue);
  415. besEND
  416.  
  417. besFUNCTION(js_mk_undefined)
  418.   DIM AS v7_val_t result;
  419.   result = V7_UNDEFINED;
  420.   besRETURN_LONG(result);
  421. besEND
  422.  
  423. besFUNCTION(js_is_undefined)
  424.   DIM AS v7_val_t undefptr;
  425.   DIM AS int istrue;
  426.   besARGUMENTS("i")
  427.     AT undefptr
  428.   besARGEND
  429.   istrue = v7_is_undefined(undefptr);
  430.   besRETURN_LONG(istrue);
  431. besEND
  432.  
  433. /* HACK - "izii" mask broken - using old school method
  434. besFUNCTION(js_mk_string)
  435.   DIM AS unsigned long v7;
  436.   DIM AS v7_val_t rtnstrptr;
  437.   DIM AS char *jsstr;
  438.   DIM AS size_t jsstrlen;
  439.   DIM AS int jsstrcopy;
  440.   besARGUMENTS("izi")
  441. //  AT v7, AT jsstr, AT jsstrlen, AT jsstrcopy
  442.     AT v7, AT jsstr, AT jsstrlen
  443.   besARGEND
  444. //  rtnstrptr = v7_mk_string(v7, jsstr, jsstrlen, jsstrcopy);
  445.     rtnstrptr = v7_mk_string(v7, jsstr, jsstrlen, 1);
  446.   besRETURN_LONG(rtnstrptr);
  447. besEND
  448. */
  449.  
  450. besFUNCTION(js_mk_string)
  451.   DIM AS VARIABLE Argument;
  452.   DIM AS unsigned long v7;
  453.   DIM AS char *jsstr;
  454.   DIM AS size_t jsstrlen;
  455.   DIM AS int jsstrcopy, i;
  456.   DIM AS v7_val_t rtnstrptr;
  457.   IF (besARGNR < 4) THEN_DO RETURN_FUNCTION(EX_ERROR_TOO_FEW_ARGUMENTS);
  458.   DEF_FOR (i = 1 TO i <= 4 STEP INCR i)
  459.   BEGIN_FOR
  460.     Argument = besARGUMENT(i);
  461.     besDEREFERENCE(Argument);
  462.     IF (i EQ 1) THEN_DO v7 = (unsigned long)LONGVALUE(Argument);
  463.     IF (i EQ 2) THEN_DO jsstr = STRINGVALUE(Argument);
  464.     IF (i EQ 3) THEN_DO jsstrlen = (size_t)LONGVALUE(Argument);
  465.     IF (i EQ 4) THEN_DO jsstrcopy = (int)LONGVALUE(Argument);
  466.   NEXT
  467.   rtnstrptr = v7_mk_string(v7, jsstr, jsstrlen, jsstrcopy);
  468.   besRETURN_LONG(rtnstrptr);
  469. besEND
  470.  
  471. besFUNCTION(js_is_string)
  472.   DIM AS v7_val_t jsstrptr;
  473.   DIM AS int istrue;
  474.   besARGUMENTS("i")
  475.     AT jsstrptr
  476.   besARGEND
  477.   istrue = v7_is_string(jsstrptr);
  478.   besRETURN_LONG(istrue);
  479. besEND
  480.  
  481. besFUNCTION(js_get_cstring)
  482.   DIM AS unsigned long v7;
  483.   DIM AS v7_val_t cstrptr;
  484.   DIM const char *sbcstr;
  485.   DIM size_t *cstrlen;
  486.   besARGUMENTS("iii")
  487.     AT v7, AT cstrptr, AT cstrlen
  488.   besARGEND
  489.   sbcstr = v7_get_string(v7, &cstrptr, &cstrlen);
  490.   besRETURN_STRING(sbcstr);
  491. besEND
  492.  
  493. besFUNCTION(js_mk_object)
  494.   DIM AS unsigned long v7;
  495.   DIM AS v7_val_t objptr;
  496.   besARGUMENTS("i")
  497.     AT v7
  498.   besARGEND
  499.   objptr = v7_mk_object(v7);
  500.   besRETURN_STRING(objptr);
  501. besEND
  502.  
  503. besFUNCTION(js_is_object)
  504.   DIM AS v7_val_t objptr;
  505.   DIM AS int istrue;
  506.   besARGUMENTS("i")
  507.     AT objptr
  508.   besARGEND
  509.   istrue = v7_is_object(objptr);
  510.   besRETURN_LONG(istrue);
  511. besEND
  512.  
  513. besFUNCTION(js_set_proto)
  514.   DIM AS unsigned long v7;
  515.   DIM AS v7_val_t objptr, protoptr, oldprotoptr;
  516.   besARGUMENTS("iii")
  517.     AT v7, AT objptr, AT protoptr
  518.   besARGEND
  519.   oldprotoptr = v7_set_proto(v7, objptr, protoptr);
  520.   besRETURN_LONG(oldprotoptr);
  521. besEND
  522.  
  523.  
  524. besFUNCTION(js_def)
  525.   DIM AS VARIABLE Argument;
  526.   DIM AS unsigned long v7;
  527.   DIM AS v7_val_t objptr, valueptr;
  528.   DIM AS const char *objname;
  529.   DIM AS size_t objnamelen;
  530.   DIM AS v7_prop_attr_desc_t attrs_desc;
  531.   DIM AS int rtnstatus, i;
  532.   IF (besARGNR < 6) THEN_DO RETURN_FUNCTION(EX_ERROR_TOO_FEW_ARGUMENTS);
  533.   DEF_FOR (i = 1 TO i <= 6 STEP INCR i)
  534.   BEGIN_FOR
  535.     Argument = besARGUMENT(i);
  536.     besDEREFERENCE(Argument);
  537.     IF (i EQ 1) THEN_DO v7 = (unsigned long)LONGVALUE(Argument);
  538.     IF (i EQ 2) THEN_DO objptr = (v7_val_t)LONGVALUE(Argument);
  539.     IF (i EQ 3) THEN_DO objname = STRINGVALUE(Argument);
  540.     IF (i EQ 4) THEN_DO objnamelen = (size_t)LONGVALUE(Argument);
  541.     IF (i EQ 5) THEN_DO attrs_desc = (v7_prop_attr_desc_t)LONGVALUE(Argument);
  542.     IF (i EQ 6) THEN_DO valueptr = (v7_val_t)LONGVALUE(Argument);      
  543.   NEXT
  544.   rtnstatus = v7_def(v7, objptr, objname, objnamelen, attrs_desc, valueptr);
  545.   besRETURN_LONG(rtnstatus);
  546. besEND
  547.  

js.bas (SB IMPORT)
Code: Script BASIC
  1. MODULE JS
  2.                                                                    
  3. DECLARE SUB      ::CREATE               ALIAS "js_create"             LIB "js"
  4. DECLARE SUB      ::DESTROY              ALIAS "js_destroy"            LIB "js"
  5. DECLARE SUB      ::EXEC                 ALIAS "js_exec"               LIB "js"
  6. DECLARE SUB      ::APPLY                ALIAS "js_apply"              LIB "js"
  7. DECLARE SUB      ::OWN                  ALIAS "js_own"                LIB "js"
  8. DECLARE SUB      ::DISOWN               ALIAS "js_disown"             LIB "js"
  9. DECLARE SUB      ::GET_INT              ALIAS "js_get_int"            LIB "js"
  10. DECLARE SUB      ::GET_DOUBLE           ALIAS "js_get_double"         LIB "js"
  11. DECLARE SUB      ::GET_STRING           ALIAS "js_get_string"         LIB "js"
  12. DECLARE SUB      ::GET_CSTRING          ALIAS "js_get_cstring"        LIB "js"
  13. DECLARE SUB      ::GET_BOOL             ALIAS "js_get_bool"           LIB "js"
  14. DECLARE SUB      ::GET                  ALIAS "js_get"                LIB "js"
  15. DECLARE SUB      ::GET_GLOBAL           ALIAS "js_get_global"         LIB "js"
  16. DECLARE SUB      ::GET_THIS             ALIAS "js_get_this"           LIB "js"
  17. DECLARE SUB      ::GET_ARGUMENTS        ALIAS "js_get_arguments"      LIB "js"
  18. DECLARE SUB      ::ARG                  ALIAS "js_get_arg"            LIB "js"
  19. DECLARE SUB      ::ARGC                 ALIAS "js_get_argc"           LIB "js"
  20. DECLARE SUB      ::ARRAY_PUSH           ALIAS "js_array_push"         LIB "js"
  21. DECLARE SUB      ::MK_ARRAY             ALIAS "js_mk_array"           LIB "js"
  22. DECLARE SUB      ::MK_BOOLEAN           ALIAS "js_mk_boolean"         LIB "js"
  23. DECLARE SUB      ::MK_NUMBER            ALIAS "js_mk_number"          LIB "js"
  24. DECLARE SUB      ::MK_STRING            ALIAS "js_mk_string"          LIB "js"
  25. DECLARE SUB      ::MK_UNDEFINED         ALIAS "js_mk_undefined"       LIB "js"
  26. DECLARE SUB      ::MK_NULL              ALIAS "js_mk_null"            LIB "js"
  27. DECLARE SUB      ::MK_OBJECT            ALIAS "js_mk_object"          LIB "js"
  28. DECLARE SUB      ::IS_NUMBER            ALIAS "js_is_number"          LIB "js"
  29. DECLARE SUB      ::IS_STRING            ALIAS "js_is_string"          LIB "js"
  30. DECLARE SUB      ::IS_BOOLEAN           ALIAS "js_is_boolean"         LIB "js"
  31. DECLARE SUB      ::IS_NULL              ALIAS "js_is_null"            LIB "js"
  32. DECLARE SUB      ::IS_UNDEFINED         ALIAS "js_is_undefined"       LIB "js"
  33. DECLARE SUB      ::IS_OBJECT            ALIAS "js_is_object"          LIB "js"
  34. DECLARE SUB      ::SET_PROTO            ALIAS "js_set_proto"          LIB "js"
  35. DECLARE SUB      ::DEF                  ALIAS "js_def"                LIB "js"
  36. DECLARE SUB      ::GET_ERROR            ALIAS "js_get_parser_error"   LIB "js"
  37.  
  38. ' Utility Functions
  39. DECLARE SUB      ::BITSHIFT             ALIAS "SB_shifts"             LIB "js"
  40. DECLARE COMMAND  ::IIF                  ALIAS "js_iif"                LIB "js"
  41.  
  42. END MODULE
  43.  




.
Title: Re: SBJS
Post by: JRS on September 17, 2016, 01:38:04 PM
Quote
Lastly, your IIF() is not a command, it is a typical function.

Maybe Peter had it right all along. IFF (IF Function)

I wouldn't call it only a function as functions don't do evaluations within an argument. I think it's cool you can embed an IF as if it were a function.
Title: Re: SBJS
Post by: JRS on September 17, 2016, 09:29:13 PM
Quote
There is additional flag: V7_DESC_PRESERVE_VALUE. If it is set, the property value isn't changed (or set to undefined if the property is being created)

I think I misunderstood the preserve functionality. It relates to the property value not property attribute states.

HERE (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) is a helpful link in understanding what we are doing with v7_def() as if we were doing a Object.defineProperty() in JavaScript.

It seems these property attributes are referred to as keys in JavaScript terms.
Title: Re: SBJS
Post by: JRS on September 18, 2016, 08:43:04 AM
I see we are overwhelming the O2 forum with the Script BASIC JavaScript project and I would like to return the thread to All BASIC (http://www.allbasic.info/forum/index.php?topic=450.0). Both Mike and Charles are members there if you wish to participate with this effort.

Thanks Charles and Mike for all your help!