Share My Creation Device Basic language IDE

Unfortunately without a Device IDE it is no longer possible to whip up quick and dirty programs on an Android device like we could with Basic4ppc on Windows Mobile.

I realised that my BasicLib script interpreter library only lacked one thing that stopped it being used as the basis for an interpreter for a device IDE and that was that it didn't support any means of responding to external events so all it could do was run linear code then exit. Fine for scripts but not for a user driven application that spends most of its time suspended waiting for events to happen. So I added it!

As well as being able to respond to events a program needs to be able to interact with the platform to add controls and access the GUI, file system and other OS services. Unlike previous versions of BasicIDE, which used the normal BasicLib library and relied upon the "Sys" function to call methods, version 2.2, and future, versions use a new BasicLibIDE library that "knows" about the methods in Script.bas so the platform functions are now embedded in the script language. It is important that the version of Script.bas matches that of the BasicLibIDE library as both need to be modified in parallel to add new functions to the language.

The previous Sys and CallHostSub functionality is of course still available.

The demo program here supports the most important views, and their events, for small programs and has graphics and file handling support. Look at Readme.txt for instructions and the comments in the Script module to see what is implemented there.

EDIT :- See post #7 for a suggestion to add Invalidate to the Script module

EDIT :- Version 2.0 posted. See post #8 for details.

EDIT :- Version 2.1 posted. See post #9 for details.

EDIT :- Version 2.2 posted. See post #15 for details.

EDIT :- Version 2.2a posted with the BasicLibIDE library included. See post #17 for details.

EDIT :- Version 2.3 posted. See post #18 for details.

EDIT :- Version 2.4 posted. See post #20 for details.

EDIT :- Version 2.5 posted. See post #23 for details.

EDIT :- JesseW has posted his improved version of the IDE itself, see post #32 for details. You will still need the BasicLibIDE jar and xml from the archive in this post.

EDIT :- Version 2.6 posted. See post #47 for details.

EDIT :- Version 2.7 posted. See post #51 for details.

EDIT :- Version 2.8 posted. See post #52 for details.

EDIT :- Version 2.9 posted. See post #79 for details.

EDIT :- Version 2.91 posted. See post #87 for details.

EDIT :- Version 2.92 posted. See post #92 for details.

EDIT :- Version 2.93 posted. See post #95 for details.

EDIT :- Version 2.94 posted. See post #100 for details.

EDIT :- Version 2.95 posted. See post #118 for details.

EDIT :- Version 2.96 posted. See post #138 for details.

EDIT :- Version 2.97 posted. See post #140 for details.

EDIT :- Version 1.98 of BasicLibIDE is posted below. Use this instead of the version in BasicIDE2.97.zip. It fixes a problem with Call and CallSub.
 

Attachments

  • BasicLibIDE.jpg
    BasicLibIDE.jpg
    12 KB · Views: 31,043
  • BasicIDE2.97.zip
    118 KB · Views: 2,471
  • BasicLibIDE_1.98.zip
    44.1 KB · Views: 1,333
Last edited:

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 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.

I see this too.
 
Top