Request: improved Import command

BlitzMax Forums/BlitzMax Programming/Request: improved Import command

Hi,

Currently there's only one way to use the Import command concerning modules:
Import modulescope.modulename
So if you want to import all modules in a scope you've to write one Import statement for each module in the scope. For example if you want to import all modules in brl scope you've to write: (If you're using the default BMX modules)
Import brl.appstub
Import brl.audio
Import brl.audiosample
Import brl.bank
Import brl.bankstream
Import brl.basic
Import brl.blitz
Import brl.bmploader
Import brl.d3d7max2d
Import brl.data
Import brl.dxgraphics
Import brl.endianstream
Import brl.event
Import brl.eventqueue
Import brl.filesystem
Import brl.font
Import brl.freeaudioaudio
Import brl.freetypefont
Import brl.glgraphics
Import brl.glmax2d
Import brl.gnet
Import brl.graphics
Import brl.hook
Import brl.httpstream
Import brl.jpgloader
Import brl.keycodes
Import brl.linkedlist
Import brl.map
Import brl.math
Import brl.max2d
Import brl.maxutil
Import brl.oggloader
Import brl.pixmap
Import brl.pngloader
Import brl.polledinput
Import brl.ramstream
Import brl.random
Import brl.retro
Import brl.socket
Import brl.socketstream
Import brl.standardio
Import brl.stream
Import brl.system
Import brl.textstream
Import brl.tgaloader
Import brl.timer
Import brl.wavloader
I request that you simply can write
Import brl.*
instead of that big list of Import statements I posted above.
Another nice feature would be if you could import all modules in a scope excluding some modules you can specify; it could be implemented like this:
Import + brl.*         'Import all brl modules,
Import - brl.max2d     'but exclude brl.max2d
Import - brl.glmax2d   'and brl.glmax2d
Import - brl.d3d7max2d 'and brl.d3d7max2d.
Or if you could do more accurate imports like this:
Import + *.*             'Import all modules in all scopes,
Import - pub.*           'but exclude the pub scope,
Import + pub.freeprocess 'however import pub.freeprocess
Import + pub.freejoy     'and pub.freejoy.
I wrote a simple function just to illustrate how this could be compiled:
Strict

Local arr$ [] [] = [.. 'This array represents the tokenized collection of Import statements
[ "Import" , "+" , "*.*" ] ,..             'Import + *.*
[ "Import" , "-" , "pub.*" ] ,..           'Import - pub.*
[ "Import" , "+" , "pub.freeprocess" ] ,.. 'Import + pub.freeprocess
[ "Import" , "+" , "pub.freejoy" ] ]       'Import + pub.freejoy
Print CompileImport ( arr , "C:\Programs" )

Function CompileImport$ ( TokenizedImportStatements$ [] [] , BlitzMaxDirectory$ )
  Local Array$ []
  Local Path$ = BlitzMaxDirectory + "/mod"
  For Local Line$ [] = EachIn TokenizedImportStatements
    If Len Line = 3 And Line [ 0 ].ToLower ( ) = "import" And ( Line [ 1 ] = "+" Or Line [ 1 ] = "-" ) And Line [ 2 ].Contains ( "." )
      Local Scope$ = Line [ 2 ] [.. Line [ 2 ].Find ( "." ) ]
      Local Name$ = Line [ 2 ] [ Line [ 2 ].Find ( "." ) + 1 ..]
      If Scope = "*"
        For Local Sub$ = EachIn LoadDir ( Path )
          Local Scope$ = Sub [.. Len Sub - 4 ]
          If Name = "*"
            For Local Sub$ = EachIn LoadDir ( Path + "/" + Scope + ".mod" )
              Local Name$ = StripAll ( CasedFileName ( Path + "/" + Scope + ".mod" + "/" + Sub + "/" + Sub [.. Len Sub - 3 ] + "bmx" ) )
              Local Text$ = "Import " + Scope + "." + Name
              If Line [ 1 ] = "+"
                Local I = Len Array
                Array = Array [.. I + 1 ]
                Array [ I ] = Text
              Else
                For Local I = 0 Until Len Array
                  If Array [ I ].ToLower ( ) = Text.ToLower ( )
                    Array [ I ] = ""
                  EndIf
                Next
              EndIf
            Next
          Else
              Local Text$ = "Import " + Scope + "." + Name
              If Line [ 1 ] = "+"
                Local I = Len Array
                Array = Array [.. I + 1 ]
                Array [ I ] = Text
              Else
                For Local I = 0 Until Len Array
                  If Array [ I ].ToLower ( ) = Text.ToLower ( )
                    Array [ I ] = ""
                  EndIf
                Next
              EndIf
          EndIf
        Next
      Else
          If Name = "*"
            For Local Sub$ = EachIn LoadDir ( Path + "/" + Scope + ".mod" )
              Local Name$ = StripAll ( CasedFileName ( Path + "/" + Scope + ".mod" + "/" + Sub + "/" + Sub [.. Len Sub - 3 ] + "bmx" ) )
              Local Text$ = "Import " + Scope + "." + Name
              If Line [ 1 ] = "+"
                Local I = Len Array
                Array = Array [.. I + 1 ]
                Array [ I ] = Text
              Else
                For Local I = 0 Until Len Array
                  If Array [ I ].ToLower ( ) = Text.ToLower ( )
                    Array [ I ] = ""
                  EndIf
                Next
              EndIf
            Next
          Else
              Local Text$ = "Import " + Scope + "." + Name
              If Line [ 1 ] = "+"
                Local I = Len Array
                Array = Array [.. I + 1 ]
                Array [ I ] = Text
              Else
                For Local I = 0 Until Len Array
                  If Array [ I ].ToLower ( ) = Text.ToLower ( )
                    Array [ I ] = ""
                  EndIf
                Next
              EndIf
          EndIf
      EndIf
    EndIf
  Next
  Local Text$
  For Local I = 0 Until Len Array
    If Array [ I ]
      If I
        Text :+ "~n"
      EndIf
      Text :+ Array [ I ]
    EndIf
  Next
  Return Text
EndFunction

The first parameter is a list of Import statement as I described, the second is the BlitzMax installation path. It returns a list of all Import statements you have to write without this feature.
You'll see that you can save much typing time with these extended Import statements.

I like the wildcards. I don't much care for the plus and minus stuff. It's decidedly unreadable.

The problem I can see is that different people have different modules and so when they post source code, it's pretty unclear what modules you need but don't have.

What you do is run Framework assistant, and then just CUT AND PASTE, saves loads of typeing

the wild card idea is great

the plus and minus stuff is annoying, an exclude command to go with import would be a lot cleaner

Agree with Gabrial and Link

Wildcard + exclude would definitely be a good thing.

Ok, I agree +/- isn't really readable, it would need a new keyword like Link said.

woot, i actualy had a good idea for a new keyword!!!

Just like java namespaces :)
But most editor has a fix imports that automatically import those you use :)

im with H&K on this one.

then just CUT AND PASTE, saves loads of typeing
This produces unreadable code.

For the time this feature isn't implemented yet, I wrote a special module scope named "all", which contains lists of all modules and scopes. But this shouldn't be the final solution.
Strict

Import brl.filesystem

Incbin "update.bmx"

Function UpdateModuleScopeAll ( )
  Local Path$ = getenv_ ( "BMXPATH" ).Replace ( "/" , "" )
  If Not Path
    Return
  EndIf
  If Path [ Len Path - 1 ] <> Asc ""
    Path :+ ""
  EndIf
  Path :+ "mod"
  DeleteDir Path + "\all.mod" , True
  Local Scopes$ []
  Local Modules$ [] []
  For Local File$ = EachIn LoadDir ( Path )
    If File [ Len File - 4 ..].ToLower ( ) = ".mod"
      Scopes = Scopes [.. Len Scopes + 1 ]
      Scopes [ Len Scopes - 1 ] = File [.. Len File - 4 ]
      Modules = Modules [.. Len Modules + 1 ]
      For Local Sub$ = EachIn LoadDir ( Path + "" + File )
        If Sub [ Len Sub - 4 ..].ToLower ( ) = ".mod"
          For Local S$ = EachIn LoadDir ( Path + "" + File + "" + Sub )
            If Sub [.. Len Sub - 4 ].ToLower ( ) + ".bmx" = S.ToLower ( )
              If File.ToLower ( ) <> "pub.mod" Or Sub.ToLower ( ) <> "all.mod"
                Modules [ Len Modules - 1 ] = Modules [ Len Modules - 1 ] [.. Len Modules [ Len Modules - 1 ] + 1 ]
                Modules [ Len Modules - 1 ] [ Len Modules [ Len Modules - 1 ] - 1 ] = S [.. Len S - 4 ]
              EndIf
              Exit
            EndIf
          Next
        EndIf
      Next
    EndIf
  Next
  CreateDir Path + "\all.mod"
  CreateDir Path + "\all.mod\all.mod"
  Local Stream:TStream = WriteStream ( Path + "\all.mod\all.mod\all.bmx" )
  WriteString Stream , "Strict~nModule all.all~n"
  For Local Scope$ = EachIn Scopes
    WriteString Stream , "~nImport all." + Scope
  Next
  CloseStream Stream
  Stream = WriteStream ( Path + "\all.mod\all.mod\update.bmx" )
  WriteString Stream , String.FromBytes ( IncbinPtr "update.bmx" , IncbinLen "update.bmx" )
  CloseStream Stream
  For Local I = 0 Until Len Scopes
    CreateDir Path + "\all.mod" + Scopes [ I ] + ".mod"
    Stream = WriteStream ( Path + "\all.mod" + Scopes [ I ] + ".mod" + Scopes [ I ] + ".bmx" )
    WriteString Stream , "Strict~nModule all." + Scopes [ I ] + "~n"
    For Local ModName$ = EachIn Modules [ I ]
      WriteString Stream , "~nImport " + Scopes [ I ] + "." + ModName
    Next
    CloseStream Stream
  Next
EndFunction

Rem
Strict
Framework brl.blitz

Import "..\mod\all.mod\all.mod\update.bmx"

UpdateModuleScopeAll

To install it create a folder "all.mod" in the BMX mod folder, then create "all.mod/all.mod", finally create the file "all.mod/all.mod/update.bmx" and copy the code into it. then create a new untitled document in the MaxIDE and copy the code after the Rem-statement into it and run it.
Rebuild the module and you're finish.

So for now you can write "Import all.pub" instead of "Import pub.*" and "Import all.all" instead of "Import *.*"

What you do is run Framework assistant, and then just CUT AND PASTE, saves loads of typeing
This produces unreadable code.
Please explain why it produces unreadable code? I dont think you know what Framework assistant does. It doesnt give you imports for mods already imported by something else.

And more importantly doesnt import mods you dont use

I prefer to write my code myself - but why should I do something which could be done by the compiler as well?

Or maybe I should ask this question different: why do people writting their code in other modern languages not simply do like you suggested? why does something like this exist in java? because this is simply a very useful technique to save typing without using an external tool manipulating the source code, which we would need in BMX, too.

Right so instead of an external tool (and its a plugin for BLide users), you want to use your external code, which does a worse job. Ok, go on then.

you want to use your external code
no, not at all; all code I previously posted, was just to show you how something could work or could be done by the compiler. The module scope "all" is not the durable solution; it's just to have something doing it as long as the compiler isn't improved.

I agree that an improvment is needed, and I for one never touched framework until I found the framework assistant. However, saying the it produces "Unreadable Code" as you did is inaccurate.

Also, as Ive pointed out, although its only a windows solution, BLide has FA as a toolbox addon. For whereas you seem to feel its a compiler problem, there is a good IDE solution. I have posted in the past that FA should be part of the official IDE, or at the least a Link in the IDE start/help page.

Framework Assistant rules.

I thought you could say something like
Import brl
Import pub

Maybe I dreamed this but who knows maybe it will work :D