All BASIC

Message Boards => Scripting Languages => Topic started by: John on December 14, 2018, 01:37:41 AM

Title: SB *Wish List*
Post by: John on December 14, 2018, 01:37:41 AM
Quote
STRING(n, code)

Create a string of length n containing characters code. If code is a string then the first character of the string is used to fill the result. Otherwise code is converted to long and the ASCII code is used.

I would like to see code be more that one character.

Code: Script BASIC
  1. PRINT STRING(3,"ABC"),"\n"
  2.  

This prints AAA.

What I would like it to print is ABCABCABC.

Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 09:15:04 AM
Quote
STRING(n, code)

Create a string of length n containing characters code. If code is a string then the first character of the string is used to fill the result. Otherwise code is converted to long and the ASCII code is used.

I would like to see code be more that one character.

Code: Script BASIC
  1. PRINT STRING(3,"ABC"),"\n"
  2.  

This prints AAA.

What I would like it to print is ABCABCABC.

I can provide a tweak, but you will no longer be able to simply feed a number (for example, 65 for "A") and have it auto converted.  You would have to pass it as CHR$(65).
Title: Re: SB *Wish List*
Post by: John on December 14, 2018, 10:25:03 AM
That would be fine. I never use the number argument option.

Thank You!
Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 10:26:02 AM
There's an issue with CHR$ in the context of this tweak.  I'm not going to figure it out.

Anyway, is this what you you're looking for:

Code: Script BASIC
  1. print string$(3,"A"),"\n"
  2. print string$(3,"ABC"),"\n"
  3.  
  4. 'SHOULD SHOW ERROR
  5. print string$(3,66),"\n"

OUTPUT:

AAA
ABCABCABC
Invalid INTEGER Parameter: '66'. STRING$() requires a string as second argument.


AIR.
Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 10:39:25 AM
Here is the patch:

Code: Diff
  1. diff --git a/commands/string.c b/commands/string.c
  2. index 42b3705..1999faa 100644
  3. --- a/commands/string.c
  4. +++ b/commands/string.c
  5. @@ -1096,7 +1096,7 @@ NOTIMPLEMENTED;
  6.    NODE nItem;
  7.    VARIABLE Op;
  8.    long lLength;
  9. -  char cFill;
  10. +  char *cFill;
  11.    char *r;
  12.  
  13.    /* this is an operator and not a command, therefore we do not have our own mortal list */
  14. @@ -1114,18 +1114,20 @@ NOTIMPLEMENTED;
  15.      cFill = 0;
  16.    else
  17.    if( TYPE(Op) == VTYPE_STRING ){
  18. -    cFill = *(STRINGVALUE(Op));
  19. +    cFill = (STRINGVALUE(Op));
  20.      }else{
  21. -    cFill = (char)(LONGVALUE(CONVERT2LONG(Op)));
  22. -    }
  23. -
  24. -  RESULT = NEWMORTALSTRING(lLength);
  25. +    printf("Invalid INTEGER Parameter: '%lu'. STRING$() requires a string as second argument.\n",LONGVALUE(Op));
  26. +    exit(-1);
  27. +  }
  28. +
  29. +  RESULT = NEWMORTALSTRING(lLength*strlen(cFill));
  30.    ASSERTNULL(RESULT)
  31. +
  32.    r = STRINGVALUE(RESULT);
  33. -  while( lLength ){
  34. -    *r++ = cFill;
  35. -    lLength--;
  36. -    }
  37. +  if (strlen(r)) strcpy(r, "");;
  38. +  while( lLength-->0 ){
  39. +    r = strcat(r,cFill);
  40. +  }
  41.  
  42.  #endif
  43.  END

Title: Re: SB *Wish List*
Post by: John on December 14, 2018, 10:41:19 AM
That is great!

It makes the STRING() function much more usable.
Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 10:45:26 AM
The updated "commands/string.c" is in the mac-dev branch.
Title: Re: SB *Wish List*
Post by: jalih on December 14, 2018, 12:57:52 PM
PL/I supports replication factor for strings. I think it would be a great addition for Basic compiler also...

Code: [Select]
put skip list ((3)'ABC');

This outputs:

ABCABCABC
Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 01:02:25 PM
MBC already has this.

Code: [Select]
print repeat$(3, "ABC")
Outputs

ABCABCABC
Title: Re: SB *Wish List*
Post by: John on December 14, 2018, 01:03:59 PM
That makes me feel better that my wish wasn't unique.
Title: Re: SB *Wish List*
Post by: John on December 14, 2018, 04:12:19 PM
Quote from: AIR
There's an issue with CHR$ in the context of this tweak.  I'm not going to figure it out.

The only problem I see is there is no way to create strings of non-printable characters with this MOD.

Code: Script BASIC
  1. PRINT "1. ",STRING(3,"A"),"\n"
  2. PRINT "2. ",STRING(3,"ABC"),"\n"
  3. PRINT "3. ",CHR(65) & CHR(66) & CHR(67),"\n"
  4. chrstr = CHR(65) & CHR(66) & CHR(67)
  5. PRINT "4. ",chrstr,"\n"
  6. stdstr = "ABC"
  7. PRINT "5. ",STRING(3, stdstr),"\n"
  8. PRINT "6. ",STRING(3, chrstr),"\n"
  9.  


$ scriba newstr.sb
1. AAA
2. ABCABCABC
3. ABC
4. ABC
5. ABCABCABC
6. ABCABCABCABCABCABCABCABCABC
$

Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 05:19:08 PM
This is why I didn't commit to the main branch.

The interpreter object is holding a reference to the previous string; I tried clearing it but it seems that the reference is used for "other things".

So this patch is no good in the end.  Trying to unravel all the macros and then trace that back to the interpreter is a PIA, not putting any more time into this.
Title: Re: SB *Wish List*
Post by: John on December 14, 2018, 06:42:57 PM
I agree that reverting back to the original code is the best course of action.

I didn't update the scriptbasic/sb-dev project due to my findings testing.
Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 08:46:23 PM
You could stick a Module-version of the function below in your T module:

Code: C
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5.  
  6. char *repeat (int count, const char *a)
  7. {
  8.   char *strtmp = calloc(1+count*strlen(a),1);
  9.   while(count > 0) {
  10.       strtmp = strcat(strtmp, a);
  11.       count--;
  12.   }
  13.   return strtmp;
  14. }
  15.  
  16.  
  17. int main(int argc, char const *argv[])
  18. {
  19.     printf("%s\n",repeat(3,"A"));
  20.     printf("%s\n",repeat(3,"ABC"));
  21.     return 0;
  22. }
  23.  

Yes, I know it's leaking for each call to the function because the caller (main, in this case) is not freeing the return value.  But for a trivial example like this, I wanted to show how this could be done.

It's important that the strtmp variable is large enough to hold the result of the strcat loop, which is why there's a calculation performed.

Broken down, if we use the second printf statement as an example, the function allocates 3*the size of the source + 1, in this case (3*3)+1 = 10, which is the length of ABCABCABC plus room for a terminating '\0'. [Operator precedence causes the multiplication to happen first (count*strlen(a)) and then the addition of '1' to occur.]

AIR.
Title: Re: SB *Wish List*
Post by: John on December 14, 2018, 09:15:05 PM
The extension module API really is the place for this, good call!

I'm confused why SB's own string creation macros can't be used. Then you wouldn't have to worry about buffer size, destroying it and it's thread safe.


Title: Re: SB *Wish List*
Post by: AIR on December 14, 2018, 09:34:45 PM
Yes, that is what you would use.  C doesn't have those, so I used calloc.