[Scripter]

* Bug: Use entry like use user.home &/ "mylib" are now evaluated correctly
* NEW: Added Support for --convert-script to convert a script to a project
* NEW: Scripter will now execute a project directly when directory name is provided in place of script
* NEW: Added Support for pluggin scripts, script is output as a class with _Call(...) instead of main()
* NEW: -p and --pluggin added for plugin support
This commit is contained in:
Brian G 2021-03-20 20:46:14 -07:00
parent cf7d874fa2
commit ce03b8ab3f
11 changed files with 216 additions and 55 deletions

View file

@ -1,15 +1,14 @@
# Gambas Project File 3.0
Title=gbs3
Startup=MMain
Profiling=1
Icon=icon.png
Version=3.15.90
VersionFile=1
Component=gb.eval
Description="Gambas Script"
Authors="Fabien Bodard, Benoit Minisini, Brian G"
Arguments=[["--help"],["--use","'gb.notify,gb.web'","-e","For i as Integer = 0 To 10:Print \"Hello World\":Next"],["~/bin/who"],["-c","-T","~/bin/mytest"],["-v","TestApp"],["--verbose","TestAppWithMain"],["--verbose","TestLazyApp"],["-c","~/testerror.gbs"],["~/Scripts/TestQuoteAtEnd"],["-c","~/Scripts/AForm"],["-c","-v","-w","~/Scripts/GambasHelpSearch"],["-c","-v","-w","~/Scripts/AMain"],["-c","-v","-w","~/Scripts/gshoutput"],["-c","-v","-w","~/Scripts/TestSets/TestWebApp.gbs"],["--convert-project","~/Projects/TestPrograms/testerror"],["--convert-project","~/Projects/TestPrograms/testusingtxthighlight","~/Scripts/TestSets"],["-c","-v","~/Scripts/TestSets/testusingtxthighlight.gbs"],["-l","library"],["-c","-v","-w","~/Scripts/TestScripterNoMain"],["-c","-v","-w","~/Scripts/TestGUI.gbs"],["-c","-v","-w","~/Scripts/TestSets/CPU_Test.gbs"],["-c","-v","-w","~/Scripts/TestSets/TestWebPage.gbs"]]
CurrentArgumentList=["-c","-v","-w","~/Scripts/TestSets/CPU_Test.gbs"]
Arguments=[["--help"],["--use","'gb.notify,gb.web'","-e","For i as Integer = 0 To 10:Print \"Hello World\":Next"],["~/bin/who"],["-c","-T","~/bin/mytest"],["-v","TestApp"],["--verbose","TestAppWithMain"],["--verbose","TestLazyApp"],["-c","~/testerror.gbs"],["~/Scripts/TestQuoteAtEnd"],["-c","~/Scripts/AForm"],["-c","-v","-w","~/Scripts/GambasHelpSearch"],["-c","-v","-w","~/Scripts/AMain"],["-c","-v","-w","~/Scripts/gshoutput"],["-c","-v","-w","~/Scripts/TestSets/TestWebApp.gbs"],["--convert-project","~/Projects/TestPrograms/testerror"],["--convert-project","~/Projects/TestPrograms/testusingtxthighlight","~/Scripts/TestSets"],["-c","-v","~/Scripts/TestSets/testusingtxthighlight.gbs"],["-l","library"],["-c","-v","-w","~/Scripts/TestScripterNoMain"],["-c","-v","-w","~/Scripts/TestGUI.gbs"],["-c","-v","-w","~/Scripts/TestSets/CPU_Test.gbs"],["-c","-v","-w","~/Scripts/TestSets/TestWebPage.gbs"],["-c","-v","-w","--convert-script","~/Scripts/TestSets/CPU_Test.gbs","~/Scripts"],["-c","-v","-w","~/Scripts/CPU_Test"],["-v","-w","-p","~/Scripts/TestPlugin"],["-c","-v","-w","~/Scripts/RunComponent"]]
CurrentArgumentList=["-c","-v","-w","~/Scripts/TestScripterNoMain"]
TabSize=2
Translate=1
Language=en_US

View file

@ -38,6 +38,9 @@ Public $bExport As Boolean
Public $bDebug As Boolean ' Enables the debug switch during gbc compiling
Public $bTrace As Boolean ' Turns on tracing in the compiler
Public $bTerseListing As Boolean ' limit the output from a script error
Public $bCreateProject As Boolean ' Create a project from the script file
Public $bPlugin As Boolean ' if true then generate a plugin, class with script name and _Call() as the entry point
' can be loaded with component.load followed by class.load both with the basename of the script
'' Reset all internal tables and conditions

View file

@ -50,7 +50,11 @@ Public Sub _Call($oContext As Context, Path As String, sPrjPath As String)
CompileError(Path, 1, "Script Contains Public or Sub Definitions Without Having a 'Public Sub main()' defined")
Endif
Else
$oContext.$sFinalProgram = "Public Sub main()\n" & cReader.GetProgram() & "\nEnd\n"
If $oContext.$bPlugin Then
$oContext.$sFinalProgram = "Public Sub _call(...)\n" & cReader.GetProgram() & "\nEnd\n"
Else
$oContext.$sFinalProgram = "Public Sub main()\n" & cReader.GetProgram() & "\nEnd\n"
Endif
Endif
'Endif

View file

@ -19,7 +19,13 @@ Public Sub _call(oContext As Context, Program As Reader) As String
' DefOutPut &= "Fast" & IIf(oContext.$bUnsafe, " Unsafe\n", "\n")
' Endif
Dim MainOutput As String = "Public Sub Main()\n"
Dim MainOutput As String
If oContext.$bPlugin Then
MainOutput = "Public Sub _Call(...)\n"
Else
MainOutput = "Public Sub Main()\n"
Endif
$iAdjustedOffset = 0
For Each i As Integer In Program.GlobalItemPosition
For Each s As String In Program.ProgramSymbols[i - $iAdjustedOffset]

View file

@ -6,6 +6,7 @@ Private $sPrjPath As String
Public $sArchivepath As String ' When Create Executable option is used this is the destination for the archive from gba3
Public $sMd5 As String ' Project md5 string to check if needs to rebuild or just execute
Public $aAppArgs As New String[] ' This is a list of all args on the script command line after the script name, these are passed to the executing project based on the script file
Public $bExecProjectDirectory As Boolean ' Set when the input is an actual project directory not a script
Public Sub _ResetAll()
@ -15,6 +16,7 @@ Public Sub _ResetAll()
$sPrjPath = ""
$sArchivePath = ""
$sMd5 = ""
$bExecProjectDirectory = False
End
@ -24,6 +26,7 @@ Public Sub Main() As Integer
Dim sCacheDir As String = File.Dir(File.Dir(Temp$())) &/ "script-cache"
Dim sRes As String
Dim bCompile As Boolean
Dim sDir As String
With $oContext
' System.language = "fr_FR"
@ -39,11 +42,36 @@ Public Sub Main() As Integer
Endif
'' Check if we are making a project from this script
If $oContext.$bCreateProject Then
MakeVirtualProject($oContext, $sPath, IIf($aAppArgs.count > 0, $aAppArgs[0], ""))
Quit 0
Endif
'' We are creating a temp project to execute
If $oContext.$bPlugin Then
ScriptPreProcess["Startup"] = File.BaseName($sPath)
If $aAppArgs.count > 0 Then
sCacheDir = $aAppArgs[0]
Else
sCacheDir = User.home &/ ".local/lib/gambas" & System.Version
Endif
If Not Exist(sCacheDir) Then
Try Shell "mkdir -p " & sCacheDir Wait
If Error Then
CompileError("Unable to create cache directory " & sCacheDir)
Endif
Endif
Endif
sName = File.Name($sPath)
If Not $sPath Then
verbose("Reading from default Stdin")
$sPath = Read Lof(File.In) ' This is invoked when cmd line is like ' gbs -e < filename'
$sPath = Read Lof(File.In) ' This is invoked when cmd line is like ' gbs -e < filename'
verbose(" Input read :\n" & $sPath)
If Not $sPath Then
Warning(("no input file specified"), True)
@ -60,7 +88,13 @@ Public Sub Main() As Integer
' md5sum requires the absolute path unless we are using a shell which expands it so ./ddd and ~/ can not be calculated for md5sum Process
sName = File.Name($sPath)
$sPath = File.RealPath($sPath)
If Not Exist($sPath) Then
'' Check if we are being asked to just execute a project directly
If Exist($sPath) And If Stat($sPath).Type = gb.directory Then
$bExecProjectDirectory = True
Endif
If Not $bExecProjectDirectory And Not Exist($sPath) Then
$sPath = Application.Dir &/ IIf($sPath = "", sName, $spath)
If Not Exist($sPath) Then
Warning(("input file does not exist") & ": " & sName, True)
@ -88,19 +122,33 @@ Public Sub Main() As Integer
Else
If Not Exist(sCacheDir &/ $sMd5 &/ sName) Then
Dim sCheckCachePath,sCheckFileName As String
If $oContext.$bPlugin Then
sCheckCachePath = sCacheDir &/ "plugins" &/ $sMd5
sCheckFileName = File.BaseName($sPath) & ".gambas"
Else
sCheckCachePath = sCacheDir &/ $sMd5
sCheckFileName = sName
Endif
If Not Exist(sCheckCachePath &/ sCheckFileName) Then
bCompile = True
Else
bCompile = Not IsValid(sCacheDir &/ $sMd5 & ".info")
bCompile = Not IsValid(sCheckCachePath & ".info")
Endif
If Not bCompile Then
verbose("Executing Script from Cache: " & $sPath)
verbose("Script is in Cache and will not be compiled: " & $sPath)
Endif
Endif
Endif
If bCompile Then
'' if we are executing a project then set some info up
If $bExecProjectDirectory Then
$sPrjPath = $sPath
Goto lExecuteProject
Endif
'' a normal script is being run
If $oContext.$bWebPage Then
If $oContext.$bVerbose Then Print "gbw: " & ("compiling server page")
$sPath = MServerPage.Make($sPath)
@ -119,6 +167,7 @@ Public Sub Main() As Integer
$oContext.$aIncFiles.push($sPath)
Endif
lExecuteProject:
Dim parmstring As String = "-a"
If $oContext.$bdebug Then parmstring &= "g"
If $oContext.$bWarning Then parmstring &= "w"
@ -140,15 +189,44 @@ Public Sub Main() As Integer
Return 1
Endif
Try Mkdir sCacheDir &/ $sMd5
$sArchivePath = sCacheDir &/ $sMd5 &/ sName
Dim sFileName As String
If $oContext.$bPlugin Then
If Not Exist(sCacheDir &/ "plugins") Then
Try Mkdir sCacheDir &/ "plugins"
Endif
sFileName = File.BaseName(sName) & ".gambas"
For Each sDir In Dir(sCacheDir &/ "plugins", "*", gb.Directory)
If Exist(sCacheDir &/ "plugins" &/ sDir &/ sFileName) Then
Try Kill sCacheDir &/ "plugins" &/ sDir &/ sFileName
Try Kill sCacheDir &/ "plugins" &/ sDir & ".info"
Try Rmdir sCacheDir &/ "plugins" &/ sDir
Endif
Next
$sArchivePath = sCacheDir &/ "plugins" &/ $sMd5 &/ sFileName
Try Mkdir sCacheDir &/ "plugins" &/ $sMd5
Else
Try Mkdir sCacheDir &/ $sMd5
sFileName = sName
$sArchivePath = sCacheDir &/ $sMd5 &/ sFilename
Endif
Dim ArchiveCmd As String[] = [System.Path &/ "bin/gba" & System.Version, "-o", $sArchivePath, $sPrjPath]
If $oContext.$bVerbose Then ArchiveCmd.Add("-v", 1)
Verbose(ArchiveCmd.Join(" "))
Exec ArchiveCmd To sRes
If $oContext.$bPlugin Then
Try Kill sCacheDir &/ sFileName
Try Link $sArchivePath To sCacheDir &/ sFileName
Endif
'Exec [System.Path &/ "bin/gba" & System.Version, "-o", $oContext.$sArchivePath, $oContext.$sPrjPath] To sRes
File.Save(sCacheDir &/ $sMd5 & ".info", $oContext.$aIncFiles.Join("\n"))
If $oContext.$bPlugin Then
File.Save(sCacheDir &/ "plugins" &/ $sMd5 & ".info", $oContext.$aIncFiles.Join("\n"))
Else
File.Save(sCacheDir &/ $sMd5 & ".info", $oContext.$aIncFiles.Join("\n"))
Endif
Endif

View file

@ -5,7 +5,7 @@ Public $hOutFile As File ' Main Mod
'' returns the Project path after it is created
Public Sub _Call($oContext As Context, sPath As String) As String
Public Sub _Call($oContext As Context, sPath As String, Optional sProjectLocation As String = "") As String
Dim sPrjFileContent As String
Dim RootModule As String = ""
@ -15,12 +15,28 @@ Public Sub _Call($oContext As Context, sPath As String) As String
$oContext.$sProgramHeader = ""
$oContext.$sCompilerOptions = ""
$sPrjPath = Temp("project")
If $oContext.$bCreateProject Then
Dim sPathInfo As String = File.Dir(sPath)
If sPathInfo = "" Then sPath = Env["PWD"] &/ sPath
If sProjectLocation = "" Then sProjectLocation = Env["PWD"]
$sPrjPath = sProjectLocation &/ File.BaseName(sPath)
ScriptPreProcess["Name"] = File.BaseName(sPath)
ScriptPreProcess["Title"] = File.BaseName(sPath) & " From Script" & sPath
Else
$sPrjPath = Temp("project")
Endif
Verbose(("Create project") & ": " & $sPrjPath)
Verbose(("Create project") & ": " & $sPrjPath)
Try Mkdir $sPrjPath
If Error Then
CompileError("Unable to create project directory : " & $sPrjPath & " : " & Error.text)
Endif
Try Mkdir $sPrjPath &/ ".src"
If Error Then
CompileError("Unable to create project .src directory : " & $sPrjPath & " : " & Error.text)
Endif
$oContext.$sPreambleHeader = "' Gambas module file\n"
@ -37,14 +53,20 @@ Public Sub _Call($oContext As Context, sPath As String) As String
$oContext.$sCompilerOptions &= "\n"
Endif
If $oContext.$bClassAsStartup Then
RootModule = $sPrjPath &/ ".src" &/ "ScriptInfoModule.module"
Dim sExtension As String
If $oContext.$bPlugin Then
sExtension = ".class"
Else
RootModule = $sPrjPath &/ ".src" &/ ScriptPreProcess.ProjectInfo["Startup"] & ".module"
sExtension = ".module"
Endif
If $oContext.$bClassAsStartup And If Not $oContext.$bPlugin Then
RootModule = $sPrjPath &/ ".src" &/ "ScriptInfoModule.module"
Else
RootModule = $sPrjPath &/ ".src" &/ ScriptPreProcess["Startup"] & sExtension
Endif
Try $hOutFile = Open RootModule For Write Create
If Error Then
Error.Raise("Unable to create module file")
Error.Raise("Unable to create " & Right(sExtension, -1) & " file")
Endif
sPrjFileContent &= ScriptPreProcess.GetProjectOptions()

View file

@ -1,6 +1,10 @@
' Gambas module file
Enum eVersion, eLicense, eHelp, eNoCache, eDebug, eVerbose, eExec, eFast, eUnsafe, eTrace, eUse, eWarnings, eBuildOnly, eList, eStdio, eLazyStrict, eTerseListing, eConvertProject
Enum eVersion, eLicense, eHelp, eNoCache, eDebug, eVerbose,
eExec, eFast, eUnsafe, eTrace, eUse, eWarnings, eBuildOnly,
eList, eStdio, eLazyStrict, eTerseListing, eConvertProject,
eConvertScript, ePlugin
Public $bExit As Boolean = False
Public $cPossibleArgs As Collection = [
@ -21,7 +25,9 @@ Public $cPossibleArgs As Collection = [
"-": eStdio,
"-S": eLazyStrict, "--strict": eLazyStrict,
"-T": eTerseListing, "--terse-listing": eTerseListing,
"--convert-project": eConvertProject
"--convert-project": eConvertProject,
"--convert-script": eConvertscript,
"-p": ePlugin, "--plugin": ePlugin
]
Public Function _Call(c As Context) As String
@ -41,16 +47,15 @@ Public Function _Call(c As Context) As String
Break
Endif
index = $cPossibleArgs[Args[I]]
If IsNull(index) Then
index = $cPossibleArgs[Args[I]]
If IsNull(index) Then
'' note if I raise and error here it causes a double free error in tcache
Error File.Name(Args[0]) & " : " & ("Unknown option") & " : " & Args[I]
$bExit = True
Break
Endif
On index Goto gVersion, gLicense, gHelp, gNoCache, gDebugInfo, gVerbose, gExecCommandLine, gFast, gUnsafe, gTrace, gUse, gWarnings, gBuildOnly, gList, gStdIn, gLazyStrict,
gTerseListing, gConvertProject
Endif
On index Goto gVersion, gLicense, gHelp, gNoCache, gDebugInfo, gVerbose, gExecCommandLine, gFast, gUnsafe, gTrace, gUse, gWarnings, gBuildOnly, gList, gStdIn, gLazyStrict, gTerseListing, gConvertProject, gConvertScript, gPlugin
gVersion:
@ -172,15 +177,37 @@ gTerseListing: ' only show the actual line the error was on
c.$bTerseListing = True
Continue
gConvertProject: ' do a project to script converstion
gConvertProject: ' do a project to script conversion
If i + 1 > Args.max Then
warning("Not enough Parameters for conversion - need <source> [<dest>]", True)
warning("Not enough parameters for Project conversion - need <source project Directory> [<dest>]", True)
Else
ConvertProject(Args[I + 1], IIf(i + 2 <= Args.max, Args[i + 2], ""))
Endif
$bExit = True
Break
gConvertScript: ' do a script to project conversion
If i + 1 > Args.max Or If i + 2 < Args.max Then
warning("Not enough parameters for Script conversion - need <source script> [<dest directory where project created>]", True)
$bExit = True
Break
Else
c.$bCreateProject = True
Endif
Continue
gPlugin:
If i + 1 > Args.max Or If i + 2 < Args.max Then
warning("Not enough parameters for plugin - need <source script> [<dest directory where plugin is created>]", True)
$bExit = True
Break
Endif
c.$bBuildOnly = True
c.$bPlugin = True
c.$bExport = True
c.$bClassAsStartup = True
Continue
Next
If $bExit Then Return Null

View file

@ -121,7 +121,7 @@ Private Sub TokenizeFile(SourceBuffer As String)
If symbols[0] = "PUBLIC" And types[1] = Highlight.keyword Or If types[1] = Highlight.symbol Then
If types[1] = Highlight.symbol Then MainPos = 0
If symbols[MainPos] = "SUB" Or If symbols[MainPos] = "PROCEDURE" Or If symbols[MainPos] = "FUNCTION" Then
If Upper(symbols[MainPos + 1]) = "MAIN" Then
If Upper(symbols[MainPos + 1]) = "MAIN" Or If $oContext.$bPlugin And Upper(symbols[MainPos + 1]) = "_CALL" Then
If types.count = 4 Then
Warning("Main Was Not Declared as Public, assuming public")
sLine = "Public " & sline
@ -287,7 +287,7 @@ End
Public Sub ProcessUse(Symbols As String[], aTypes As Integer[], sLine As String)
Warning("Use :" & File.Name(cIncludeStack.last & "." & CurrentLineNumber.last & ":" & sLine))
UseLibComp(cIncludeStack.last, CurrentLineNumber.last, Symbols, aTypes)
UseLibComp(cIncludeStack.last, CurrentLineNumber.last, sLine)
End

View file

@ -202,4 +202,18 @@ Public Sub GetStartup() As String
End
Public Sub _put(value As Variant, index As String)
ProjectInfo[index] = value
End
Public Sub _get(index As String) As Variant
Return ProjectInfo[index]
End

View file

@ -5,21 +5,25 @@ Public HasLibraries As Boolean = False
Public Sub _FromString(Comp As String)
Dim delta As String[] = Split(comp, ",") ' yes looks stupid....
For i As Integer = 0 To delta.Max
delta[i] = Quote(delta[i])
Next
' Dim delta As String[] = Split(comp, ",") ' yes looks stupid....
' For i As Integer = 0 To delta.Max
' delta[i] = Quote(delta[i])
' Next
Highlight.Analyze("USE " & delta.join())
_call(Comp, 0, Highlight.symbols, Highlight.types)
'Highlight.Analyze("USE " & delta.join())
_call(Comp, 0, "use " & Comp)
End
Public Sub _call(Path As String, iLine As Integer, aSym As String[], aTypes As Integer[])
For iInd As Integer = 1 To aSym.Max Step 2
If aTypes[iInd] <> Highlight.String Then
Public Sub _call(Path As String, iLine As Integer, sLine As String)
Dim aNewLines As String[] = Split(Replace(Trim(sLine), "use ", "", gb.ignorecase))
Dim sRefrence As String = ""
For iInd As Integer = 0 To aNewLines.Max
Try sRefrence = Eval(aNewLines[iInd])
If Error Then
CompileError(Path, iLine, ("Syntax error"))
Endif
Dim s As String = Mid$(aSym[iInd], 2, -1)
Dim s As String = sRefrence
If s Like "*:*" Or s Like "/*" Then
Verbose(("Use library") & " " & s)
@ -31,12 +35,12 @@ Public Sub _call(Path As String, iLine As Integer, aSym As String[], aTypes As I
HasComponents = True
Endif
If iInd < aSym.Max Then
s = aSym[iInd + 1]
If s <> "," Then
CompileError(Path, iLine, ("Comma missing"))
Endif
Endif
' If iInd < aNewLines.Max Then
' s = aSym[iInd + 1]
' If s <> "," Then
' CompileError(Path, iLine, ("Comma missing"))
' Endif
' Endif
Next

View file

@ -1,8 +1,10 @@
Compile and execute a Gambas script.
Usage: gbs3 [options][--] [<script file> | - ]
gbs3 --convert-project <input project directory> <output script directory>
Usage: gbs3 [options][--] [<script file> | <project directory> | - ]
gbs3 --convert-project <input project directory> [<output script directory>]
gbs3 --convert-script <input script> [<output directory where project directory is created>]
gbs3 --plugin <input script> [<output plugin cache directory>]
Options:
-b --buildonly process and compile the script without executing it
@ -12,6 +14,7 @@ Options:
-f --fast use just-in-time compiler
-h --help display this help
-L --license display license
-p --plugin Compile the script, no main, define the class name as script base name entry point _Call(...)
-S --strict fail if 'Public' or 'Sub' are defined without a 'main' function
-t --trace turn on tracing option during execution
-T --terse-listing only print a very terse error report on compile errors
@ -21,5 +24,6 @@ Options:
-V --version display version
-w --warnings display warnings during compilation
--convert-project convert a simple project to a script
--convert-script convert a simple script to a project
-- stop any further option processing
- read the script from standard input