Share My Creation Device Basic language IDE

JesseW

Active Member
Licensed User
Longtime User
Andrew... question... can blib.getarray() and blib.setarray() only work with single dimension arrays? The doc's don't say (that I can find), but I seem to remember reading something about the issue before, but can't find any reference now. I ask because if I try to use them with a multidim array (ie. dim a(100, 2)) it doesn't save the array correctly. It seems to set every item to the value of the first item (ie a(0,0)). Just trying to figure out if it's a bug that can be fixed, or if it's just that way and I need to code around it...

Thanks..
Jesse
 

agraham

Expert
Licensed User
Longtime User
All arrays are in fact single dimension arrays. In fact all global variables are actually implemented as single dimension arrays for simplicity and initialised to an empty string
B4X:
for (int i = 0; i < globalvars.Count; i++)
{
        globals[i] = new string[] { "" };
        // [0] is rightmost, [1] is middle, [2] is leftmost dimension
        globalsrank[i] = new int[] { 1, 0, 0 };
}

Multi-dimensional access is synthesised so when you Dim an array it is assigned like this
B4X:
globals[var[0]] = new string[var[2] * var[3] * var[4]];

Multi-dimensional access is similar but with bounds checking (not shown).
B4X:
// [2] is rightmost, [3] is middle, [4] is leftmost dimension
int index = dims[0] * (dims[1] * var[4] + var[3]) + var[2];
return globals[var[0]][index];
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
I am working on transcribing B4Script grammar rules into BNF for a new IDE idea I have. When I'm done, I'll upload it for your inspection...

JesseW,

I have found that one of the many libraries that I have TMS Scripting have some stuff that eventually helps me.

Since you talked about BNF, I looked on the classes and I found:

B4X:
   atBASIC_GRAMMAR  = '<program>: [({<uses>|<imports>} )] [( {<globaldecl>|<constdecl>})] [( {<subroutine>|<function>})] <main> '#13#10+
                      '<main>:[( <statement>[ :])]'#13#10+
                      '<uses>R:uses <id>[( , <id>)][ ;]'#13#10+
                      '<imports>R:imports <id>[( , <id>)][ ;]'#13#10+
                      '<subroutine>:[<subvisibility>~ ]sub <label> {<external>|<inputargs>{ <forward>|[( <statement>[ :])] end sub}}'#13#10+
                      '<function>:[<subvisibility>~ ]function <label> {<external>[ as <argtype>]|<inputargs>[ as <argtype>]{ <forward>|[( <statement>[ :])] end function}}'#13#10+
                      '<subvisibility>:{public|private}'#13#10+
                      '<external>:lib <filename>[ alias <externalName>] [<callingConvention>] <inputargs>'#13#10+
                      '<filename>:$'#13#10+
                      '<externalName>:$'#13#10+
                      '<callingConvention>:{stdcall|safecall|cdecl|pascal|register}'#13#10+
                      '<inputargs>:["(" {<byref>|<byval>}[( , {<byref>|<byval>})] ")"]'#13#10+
                      '<forward>:forward'#13#10+
                      '<byref>:byref~ <id>[ as <argtype>]'#13#10+
                      '<byval>:[byval~] <id>[ as <argtype>]'#13#10+
                      '<argtype>:{@|_}[({@|#|_})]'#13#10+
                      '<vardecl>:dim~ <varlist>[( , <varlist>)]'#13#10+
                      '<constdecl>:const~ <id> "=" <expression>'#13#10+
                      '<varlist>:<id>[( , <id>)][ "as" <argtype>][ "=" <expression>]'#13#10+
                      '<globaldecl>:<globalvisibility>~ <varlist>[( , <varlist>)]'#13#10+
                      '<globalvisibility>:{public|private|dim}'#13#10+
                      '<statement>:{<constdecl>|<vardecl>|<if>|<for>|<do_loop>|<whileend>|<assign>|<try>|<call>|<case>|<exit>|<return>|<with>}'#13#10+
                      '<call>:<id><arg_list><indexing><call_code>[.<call>]'#13#10+
                      '<call_code>:'#13#10+
                      '<data_val>:<id><arg_list><indexing><data_val_code>[.<data_val>]'#13#10+
                      '<data_val_code>:'#13#10+
                      '<data_ref>:<id><arg_list><indexing><data_ref_code>[.<data_ref>]'#13#10+
                      '<data_ref_code>:'#13#10+
                      '<new_call>:"new"~ <id><arg_list><new_call_code>'#13#10+
                      '<new_call_code>:'#13#10+
                      '<arg_list>:[ "(" [<expression> [(, <expression> )]]")"]'#13#10+
                      '<indexing>:[( "[" <expression> [(, <expression> )]"]")]'#13#10+
                      '<assign>R:["set "] <data_ref> = <expression>'#13#10+
                      '<push_output>:'#13#10+
                      '<for>:<for_control>[ step <step>][( <statement>[ :])] next'#13#10+
                      '<for_control>:for <id> = <expression> to <expression>'#13#10+
                      '<step>:[{-|+}](#)[.(#)][e[{-|+}](#)]'#13#10+
                      '<do_loop>:do~ {<test_loop>|<loop_test>}'#13#10+
                      '<test_loop>:<test_loop_expr>[( <statement>[ :])] loop'#13#10+
                      '<test_loop_expr>:{<while>|<until>} <expression>'#13#10+
                      '<loop_test>:[( <statement>[ :])] loop <loop_test_expr>'#13#10+
                      '<loop_test_expr>:{<while>|<until>} <expression>'#13#10+
                      '<while>:while'#13#10+
                      '<until>:until'#13#10+
                      '<whileend>:while <whileend_expr>[( <statement>[ :])] end while'#13#10+
                      '<whileend_expr>:<expression>'#13#10+
                      '<if>:{if <expression> <then> [{<elseif>|<else>}] end if|if ^<expression> ^<then_single>[ ^<else_single>]}'#13#10+
                      '<then>:then \( <statement>[ :])'#13#10+
                      '<then_single>:then( ^<statement>[ ^":"])'#13#10+
                      '<elseif>:elseif <expression> <then> [{<elseif>|<else>}]'#13#10+
                      '<else>:else( <statement>[ :])'#13#10+
                      '<else_single>:else( ^<statement>[ ^":"])'#13#10+
                      '<expression>:{[<unary>]{<new_call>|<data_val>|"(" <expression> ")"}|<hex>|<real>|<string>|<vector>}[( <operator> {[<Unary>]{<new_call>|<data_val>|"(" <expression> ")"}|<hex>|<real>|<string>|<vector>})]'#13#10+
                      '<operator>:{"^"|*|/|and~|+|-|or~|"<>"|">="|"<="|"="|">"|"<"|"&"|div~|mod~|xor~|shl~|shr~|is~}'#13#10+
                      '<unary>:{not~ |-|+}'#13#10+
                      '<label>:<id>'#13#10+
                      '<id>:{@|_}[({@|#|_})]'#13#10+
                      '<real>:[{-|+}](#)[<frac>][<exp>]'#13#10+
                      '<hex>:"0x"({#|a|b|c|d|e|f})'#13#10+
                      '<frac>:.(#)'#13#10+
                      '<exp>:e[{-|+}](#)'#13#10+
                      '<string>:$'#13#10+
                      '<vector>:"[" [<expression> [(, <expression> )]]"]"'#13#10+
                      '<try>:try <try_statements> {<finally>|<except>} <try_upshot> end[ try][ :]'#13#10+
                      '<finally>:finally'#13#10+
                      '<except>:{catch|except}'#13#10+
                      '<try_statements>:[( <statement>[ :])]'#13#10+
                      '<try_upshot>:[( <statement>[ :])]'#13#10+
                      '<case>:select case <case_expr> <case_branch> end select'#13#10+
                      '<case_expr>:<expression>'#13#10+
                      '<case_branch>:[{case else( <statement>[ :])|case <case_test>[( , <case_test>)] <case_match>[ <case_branch>]}]'#13#10+
                      '<case_test>:<expression>'#13#10+
                      '<case_match>:[( <statement>[ :])]'#13#10+
                      '<exit>:exit {<exit_sub>|<exit_function>|<exit_do>|<exit_for>}'#13#10+
                      '<exit_sub>:sub'#13#10+
                      '<exit_function>:function'#13#10+
                      '<exit_do>:do'#13#10+
                      '<exit_for>:for'#13#10+
                      '<return>:return[ ^<expression>]'#13#10+
                      '<with>:with <with_obj>[( <statement>[ :])] end with'#13#10+
                      '<with_obj>:{<new_call>|<data_val>}';

This is from a Delphi class, for a BNF of a Visual Basic script, it is a copy paste like it is in the original, it is creating a long string with all the BNF of the language.

I wonder if you are up to share the BNF you were willing to create for agraham scripting, since you were much more used to deal with it.

I think I could change this BNF to match the one you mentioned and make this scripting engine run the same b4a scripting code. I have possibility to add new subs that are missing, like callsub, etc.

The interesting part is that there is a whole IDE around this already.

I want to incorporate this BNF and test it and share the results.

Thanks,

Eduardo Elias
 

JesseW

Active Member
Licensed User
Longtime User
I haven't started the bnf for b4script yet (just no extra time), but I have transcribed the bnf for good old 8-bit atari basic from the atari basic source book. it's actually abml (atari basic meta language) which is one modified variant of bnf. here it is

B4X:
; ABML         Atari Basic Meta Language
;         ABML is a custom implementation of BNF
;
; This definition of the ABML grammar of Atari Basic has been modified
;   from the original because of the different techniques and algorythms
;   used in the Basic4Android ABML parser
;
;      ABML Tokens
;
; ;            Remark
; identifier   Terminal symbol, parsed literally
; <identifier>   Nonterminal definition name
; [identifier]   External subroutine call (increases parsing speed)
; =            Nonterminal definition assignment
; "identifier"   Terminal symbol when reserved characters are used
; |            AMBL alternative - OR
; #            End of nonterminal definition
; &            Accept to this point, even if failed
;                  (allows for multiple nonterminals)
; $            Hex character, 2 digit (not part of the original ABML definition)
;
; Expression
   ; Expression definition
<EXP> =      (<EXP>)<NOP>|<UNARY><EXP>|<NV><NOP>#
   ; Unary operator
<UNARY> =   +|.|NOT#
   ; Numeric value
<NV> =      <NFUN>|<NVAR>|[TNCON]|<STCOMP>#
   ; Numeric operation (optional)
<NOP> =      <OP><EXP>|&#
   ; Numeric operators
<OP> =      +|-|*|/|"<="|">="|"<>"|"<"|">"|"="|AND|OR#
   ; Numeric variable
<NVAR> =   [TNVAR]<NMAT>#
   ; Numeric array matrix optional [(x1[,x2])]
<NMAT> =   (<EXP><NMAT2>)|&#
   ; Optional second matrix (x2 in above)
<NMAT2> =   ,<EXP>|&#
   ; Numeric function
<NFUN> =   <NFNP><NFP>|<NFSP><SFP>|<NFUSR>#
   ; Numeric function parameter
<NFP> =      (<EXP>)#
   ; String function parameter
<SFP> =      (<STR>)#
   ; String compare expression
<STCOMP> =   <STR><SOP><STR>#
   ; String value
<STR> =      <SFUN>|<SVAR>|[TSCON]#
   ; String function
<SFUN> =   <SFNP><NFP>#
   ; String variable
<SVAR> =   [TSVAR]<SMAT>#
   ; String variable matrix (optional)
<SMAT> =   (<EXP><SMAT2>)|&#
   ; Optional second string variable matrix value
<SMAT2> =   ,<EXP>|&#
   ; String expression operators
<SOP> =      "<="|"<>"|">="|"<"|">"|"="#
   ; Numeric or string variable
<NSVAR> =   <NVAR>|<SVAR>#
   ; One or more numeric/string variable parameter list
<NSVRL> =   <NSVAR><NSV2>|&#
<NSV2> =   ,<NSVRL>|&#
   ; One or more comma separated expression parameters
<EXPL> =   <EXP><EXPL1>#
<EXPL1> =   ,<EXPL>|&#
   ; Numeric array / string var matrix
<NSMAT> =   [TNVAR](<EXP><NMAT2>)|[TSVAR](<EXP>)#
   ; One or more comma separated numeric array / string variable definitions
<NSML> =   <NSMAT><NSML2>|&#
<NSML2> =   ,<NSML>|&#
   ; One or more comma separated expression parameters
   ;   (seems to duplicate <EXPL><EXPL1>

; External subroutine calls (written in machine language)
[TNVAR]      Check for valid numeric variable name
[TSVAR]      Check for valid string variable name
[TNCON]      Check for valid numeric constant
[TSCON]      Check for valid string constant
[EIF]      Check for valid statement after ELSE
[EREM]      Check for valid REMark string
[EDATA]      Check for valid DATA sequence

; Functions
   ; Numeric function, numeric parameter
<NFNP> =   ATN|COS|PEEK|SIN|RND|FRE|EXP|LOG|CLOG|SQR|SGN|ABS|INT|PADDLE|
         STICK|PTRIG|STRIG#
   ; Numeric function, string parameter
<NFSP> =   ASC|VAL|ADR|LEN#
   ; String function, numeric parameter
<SFNP> =   STR|CHR#
   ; USR(...) function where 1 or more parameters are possible
<NFUSR> =   USR(<PUSR>)#
<PUSR> =   <EXP><PUSR1>#
<PUSR1> =   ,<PUSR>|&#

; Statement support
   ; End of statement - CR or :
<EOS> =      :|$0D#
   ; <EOS2> is a duplicate of <EOS> - don't know why...
<EOS2> =   <CEOS>|<CCR>#
<CEOS> =   :#
<CCR> =      $0D#
; Not sure why this is here...
<TEXP> =   <EXP>,<EXP>#

; Statement commands (in the same order as in the Atari Basic Source Book)
<STMT> =    <PUT>|<MULT1>|<MULT2>|<LET>|<FOR>|<LOCATE>|<GET>|<NEXT>|<RESTORE>|
         <INPUT>|<READ>|<PRINT>|<LPRINT>|<XIO>|<OPEN>|<CLOSE>|<MULT3>|<RUN>|
         <LIST>|<STATUS>|<MULT4>|<SOUND>|<MULT5>|<DIM>|<ON>|<IF>|<REM>|<DATA>#
;   PUT
<PUT> =      PUT<D1>,<EXP><EOS>#
;   Statements with a single expression argument
; TRAP, GOTO, GOSUB, GRAPHICS, COLOR
<MULT1> =   <MULT1A><EXP><EOS>#
<MULT1A> =   TRAP|GOTO|GOSUB|GRAPHICS|COLOR#
;   Statements with no arguments
; CSAVE, CLOAD, DOS, CLR, RETURN, END, STOP, POP, NEW, BYE, CONT, DEG, RAD
<MULT2> =   <MULT2><EOS>#
<MULT2A> =   CSAVE|CLOAD|DOS|CLR|RETURN|END|STOP|POP|NEW|BYE|CONT|DEG|RAD#
'   LET - the LET keyword itself is optional in the assignment statement
<LET> =      <LET2><LET3>#
<LET2> =   LET|&#
<LET3> =   <NVAR>=<EXP><EOS>|<SVAR>=<STR><EOS>#
;   FOR
<FOR> =      FOR[TNVAR]=<EXP>TO<EXP><FSTEP><EOS>#
<FSTEP> =   STEP<EXP>|&#
;   LOCATE
<LOCATE> =   LOCATE<EXP>,<EXP>,[TNVAR]<EOL>#
;   GET
<GET> =   GET<D1>,[TNVAR]#
;   NEXT
<NEXT> =   NEXT[TNVAR]<EOS>#
;   RESTORE
<RESTORE> =RESTORE<EXP><EOS>|<EOS>#
;   INPUT
<INPUT> =   INPUT<OPD><READ>#
<OPD> =      <D1>,|&#
;   READ
<READ> =   READ<NSVRL><EOS>#
;   PRINT
<PRINT> =   PRINT<PRINT1>#
<PRINT1> =   <D1><EOS>|<OPD><LPRINT1>#
<D1> =      <CPND><EXP>#
<CPND> =   "#"#
;   LPRINT
<LPRINT> =   LPRINT<LPRINT1>#
<LPRINT1> =   <PR1><EOS>#
<PR1> =      <PEL>|<PSL><PR2>|&#
<PR2> =      <PEL>|&#
<PEL> =      <PES><PELA>#
<PES> =      <EXP>|<STR>#
<PELA> =   <PSL><PEL>|&#
<PSL> =      <PS><PSLA>#
<PSLA> =   <PSL>|&#
<PS> =      ,|,#
;   XIO
<XIO> =      XIO<AEXP>,<DS2><FS>,<AEXP><EOS>#
<FS> =      <STR>#      ;Filespec
;   OPEN
<OPEN> =   OPEN<D1>,<EXP>,<EXP>,<FS>,<EOS>#
;   CLOSE
<CLOSE> =   CLOSE<D1><EOS>#
;   Statements with a single filename string parameter
; ENTER, LOAD, SAVE
<MULT3> =   <MULT3A><FS><EOS>#
<MULT3A> =   ENTER|LOAD|SAVE#
;   RUN
<RUN> =      RUN<RUN1>#
<RUN1> =   <FS><EOS2>|<EOS2>#
;   LIST
<LIST> =   LIST<LIST1>#
<LIST1> =   <FS><EOS>|<FS><LIS>|<LIS>#
<LIS> =      <L1><EOS>#
<L1> =      <EXP><L2>|&#
<L2> =      ,<EXP>|&#
;   STATUS
<STATUS> =   STATUS<STAT><EOS>#
<STAT> =   <D1>,<NVAR>#
;   Statements with a drive designation and a single numeric variable
; NOTE, POINT
<MULT4> =   <MULT4A><STAT>,<NVAR><EOS2>#
<MULT4A> =   NOTE|POINT#
;   SOUND
<SOUND> =   SOUND<EXP>,<EXP>,<EXP>,<EXP><EOS>#
;   Statements with two expression parameters
; POKE, PLOT, POS, DRAWTO
<MULT5> =   <MULT5A><EXP>,<EXP><EOS>#
<MULT5A> =   POKE|PLOT|POS|DRAWTO#
;   DIM
<DIM> =      DIM<NSML><EOS>#
;   ON (as in ON GOSUB and ON GOTO)
<ON> =      ON<EXP><ON1><EXPL><EOS>#
<ON1> =      GOTO|GOSUB#
;   IF
<IF> =      IF<EXP>THEN<IFA><EOS>#
<IFA> =      [TNCON]|[EIF]#
;   REM
<REM> =      [EREM]#
;   DATA
<DATA> =   [EDATA]#
 

avacondios

Active Member
Licensed User
Longtime User
Any update of this library ?

Also, can I use it on commercial projects ?

Best regards

Antonis
 

tech2k

Member
Licensed User
Longtime User
I have always liked to tinker with this on my phone and use it a lot just to create and edit msgbox files for my app. BasicIDE will no longer compile for me on B4A 4.30 giving error about a null value layout. Is this a known problem?

Thanks in advance,

Ken

Edit:
No hurry if you still mess with this project at all. I found an apk from last year and it still works fine.
 
Last edited:

JakeBullet70

Well-Known Member
Licensed User
Longtime User

I see this too.