_BlankPage
Jump to navigation
Jump to search
The _BlankPage serves as a skeleton for new Wiki pages.
Syntax
- _BlankSub arg1[, arg2]
- result% = _BlankFunc(arg1[, arg2])
Parameters
- arg1 is a mandatory argument
- the arg2 is optional
Description
To use this skeleton click on the Edit tab above the page, then copy the raw text of this page and paste it into your new page. Change/remove sections as needed. Use this for italic and this for bold text style. To color your writings use the Text template. It takes either a color name or a #RRGGBB 32bit color, if the color part is omitted it will default to gray.
You can inline simple code one liners like w = _WIDTH
- an askerisk marks a list point
- two askerisks will indent the list
- three askerisks will indent even more
- two askerisks will indent the list
- This is a definition list
- The first description can follow right after a colon
- or in a new line
- more descriptions can follow
- using list bullets with an askerisk
- as already seen in the syntax above, you may use desciptions without a defininition too
- you may also nest descriptions
- but at some point it's cluttering the page so please use it sparingly
- you may also nest descriptions
This is a nice piece of paper for quotes and similar things. In case of short code snippets you may use the "Cb" (code blue) template to highlight and link keywords to the Wiki pages. FOR x = 1 TO 5 PRINT "Hello World!" NEXT x END As you see, this Text block is suitable for preformatted text, but note that the browser is still allowed to wrap too long lines. If you really need your preformatted text to be shown as is, then use a fixed text block instaed, see below. |
Use this fixed text block for preformatted text, which is not even allowed to wrap long lines, such as tables etc.. As you see this very long line goes far over the display width, so please limit youself to the available space to not clutter the display too much. |
Notes
- This may be a sub-section for further notes like special behavior, required prerequisites etc.
- If used/required, then this should always be a sub-section under the Description main section
Errors
- If used/required, then this also should be a sub-section under the Description main section
- This is not intended for the regular errors a SUB/FUNCTION could throw, those should be handled in the main description section.
- Rather use it for subtle things, known mis-behavior, tendency for stack overflows and seg faults etc.
Availability
- The capability to load from memory was introduced in QB64-PE v3.5.0.
Examples
- Example 1
- Each example should have a short description.
'Place your code example here 'The "Cl" (code link) template can be used to link keywords to its 'respective Wiki page. Those words will also get highlighted. COLOR 15,4 PRINT "Hello World!" |
- The output block is available for the SCREEN 0 background colors 0-7
- Inside the output block use the "Ot" (output text) template for coloring
Hello World!
|
See also
'All variables will be of type LONG unless explicitly defined DEFLNG A-Z 'All arrays will be dynamically allocated so they can be REDIM-ed '$DYNAMIC 'We need console access to support command-line compilation via the -x command line compile option $CONSOLE 'Initially the "SCREEN" will be hidden, if the -x option is used it will never be created $SCREENHIDE $EXEICON:'./qb64pe.ico' $VERSIONINFO:CompanyName=QB64 Phoenix Edition $VERSIONINFO:FileDescription=QB64 IDE and Compiler $VERSIONINFO:InternalName=qb64pe.bas $VERSIONINFO:LegalCopyright=MIT $VERSIONINFO:LegalTrademarks= $VERSIONINFO:OriginalFilename=qb64pe.exe $VERSIONINFO:ProductName=QB64-PE $VERSIONINFO:Comments=QB64 is a modern extended BASIC programming language that retains QB4.5/QBasic compatibility and compiles native binaries for Windows, Linux and macOS. '$INCLUDE:'global\version.bas' '$INCLUDE:'global\settings.bas' '$INCLUDE:'global\constants.bas' '$INCLUDE:'subs_functions\extensions\opengl\opengl_global.bas' '$INCLUDE:'utilities\ini-manager\ini.bi' '$INCLUDE:'utilities\s-buffer\simplebuffer.bi' DEFLNG A-Z '-------- Optional IDE Component (1/2) -------- '$INCLUDE:'ide\ide_global.bas' REDIM SHARED OName(1000) AS STRING 'Operation Name REDIM SHARED PL(1000) AS INTEGER 'Priority Level REDIM SHARED PP_TypeMod(0) AS STRING, PP_ConvertedMod(0) AS STRING 'Prepass Name Conversion variables. Set_OrderOfOperations DIM SHARED NoExeSaved AS INTEGER DIM SHARED vWatchOn, vWatchRecompileAttempts, vWatchDesiredState, vWatchErrorCall$ DIM SHARED vWatchNewVariable$, vWatchVariableExclusions$ vWatchErrorCall$ = #FFB100 vWatchVariableExclusions$ = "@__LONG_VWATCH_LINENUMBER@__LONG_VWATCH_SUBLEVEL@__LONG_VWATCH_GOTO@" + _ "@__STRING_VWATCH_SUBNAME@__STRING_VWATCH_CALLSTACK@__ARRAY_BYTE_VWATCH_BREAKPOINTS" + _ "@__ARRAY_BYTE_VWATCH_SKIPLINES@__STRING_VWATCH_INTERNALSUBNAME@__ARRAY_STRING_VWATCH_STACK@" DIM SHARED nativeDataTypes$ nativeDataTypes$ = "@_OFFSET@OFFSET@_UNSIGNED _OFFSET@UNSIGNED OFFSET@_BIT@BIT@_UNSIGNED _BIT@UNSIGNED BIT@_BYTE@_UNSIGNED _BYTE@BYTE@UNSIGNED BYTE@INTEGER@_UNSIGNED INTEGER@UNSIGNED INTEGER@LONG@_UNSIGNED LONG@UNSIGNED LONG@_INTEGER64@INTEGER64@_UNSIGNED _INTEGER64@UNSIGNED INTEGER64@SINGLE@DOUBLE@_FLOAT@FLOAT@STRING@" DIM SHARED qb64prefix_set_recompileAttempts, qb64prefix_set_desiredState DIM SHARED opex_recompileAttempts, opex_desiredState DIM SHARED opexarray_recompileAttempts, opexarray_desiredState REDIM EveryCaseSet(100), SelectCaseCounter AS _UNSIGNED LONG REDIM SelectCaseHasCaseBlock(100) DIM ExecLevel(255), ExecCounter AS INTEGER REDIM SHARED UserDefine(1, 100) AS STRING '0 element is the name, 1 element is the string value REDIM SHARED InValidLine(10000) AS _BYTE DIM DefineElse(255) AS _BYTE DIM SHARED UserDefineCount AS INTEGER, UserDefineList$ UserDefineList$ = "@DEFINED@UNDEFINED@WINDOWS@WIN@LINUX@MAC@MACOSX@32BIT@64BIT@VERSION@" UserDefine(0, 0) = "WINDOWS": UserDefine(0, 1) = "WIN" UserDefine(0, 2) = "LINUX" UserDefine(0, 3) = "MAC": UserDefine(0, 4) = "MACOSX" UserDefine(0, 5) = "32BIT": UserDefine(0, 6) = "64BIT" UserDefine(0, 7) = "VERSION" IF INSTR(_OS$, "WIN") THEN UserDefine(1, 0) = "-1": UserDefine(1, 1) = "-1" ELSE UserDefine(1, 0) = "0": UserDefine(1, 1) = "0" IF INSTR(_OS$, "LINUX") THEN UserDefine(1, 2) = "-1" ELSE UserDefine(1, 2) = "0" IF INSTR(_OS$, "MAC") THEN UserDefine(1, 3) = "-1": UserDefine(1, 4) = "-1" ELSE UserDefine(1, 3) = "0": UserDefine(1, 4) = "0" IF INSTR(_OS$, "32BIT") THEN UserDefine(1, 5) = "-1": UserDefine(1, 6) = "0" ELSE UserDefine(1, 5) = "0": UserDefine(1, 6) = "-1" UserDefine(1, 7) = Version$ DIM SHARED QB64_uptime! QB64_uptime! = TIMER NoInternalFolder: IF _DIREXISTS("internal") = 0 THEN _SCREENSHOW PRINT "QB64-PE cannot locate the 'internal' folder" PRINT PRINT "Check that QB64-PE has been extracted properly." PRINT "For MacOSX, launch 'qb64pe_start.command' or enter './qb64pe' in Terminal." PRINT "For Linux, in the console enter './qb64pe'." DO _LIMIT 1 LOOP UNTIL INKEY$ <> "" SYSTEM 1 END IF DIM SHARED Include_GDB_Debugging_Info 'set using "options.bin" DIM SHARED DEPENDENCY_LAST CONST DEPENDENCY_LOADFONT = 1: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_AUDIO_CONVERSION = 2: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_AUDIO_DECODE = 3: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_AUDIO_OUT = 4: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_GL = 5: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_IMAGE_CODEC = 6: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_CONSOLE_ONLY = 7: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 #31C4C4 CONST DEPENDENCY_SOCKETS = 8: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_PRINTER = 9: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_ICON = 10: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_SCREENIMAGE = 11: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 CONST DEPENDENCY_DEVICEINPUT = 12: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 'removes support for gamepad input if not present CONST DEPENDENCY_ZLIB = 13: DEPENDENCY_LAST = DEPENDENCY_LAST + 1 'ZLIB library linkage, if desired, for compression/decompression. DIM SHARED DEPENDENCY(1 TO DEPENDENCY_LAST) DIM SHARED UseGL 'declared SUB _GL (no params) DIM SHARED OS_BITS AS LONG, WindowTitle AS STRING OS_BITS = 64: IF INSTR(_OS$, "[32BIT]") THEN OS_BITS = 32 IF OS_BITS = 32 THEN WindowTitle = "QB64 Phoenix Edition (x32)" ELSE WindowTitle = "QB64 Phoenix Edition (x64)" _TITLE WindowTitle DIM SHARED ConsoleMode, No_C_Compile_Mode, NoIDEMode DIM SHARED ShowWarnings AS _BYTE, QuietMode AS _BYTE, CMDLineFile AS STRING DIM SHARED MonochromeLoggingMode AS _BYTE TYPE usedVarList AS LONG id, linenumber, includeLevel, includedLine, scope, localIndex AS LONG arrayElementSize AS _BYTE used, watch, isarray, displayFormat 'displayFormat: 0-DEC;1-HEX;2-BIN;3-OCT AS STRING name, cname, varType, includedFile, subfunc AS STRING watchRange, indexes, elements, elementTypes 'for Arrays and UDTs AS STRING elementOffset, storage END TYPE REDIM SHARED backupUsedVariableList(1000) AS usedVarList DIM SHARED typeDefinitions$, backupTypeDefinitions$ DIM SHARED totalVariablesCreated AS LONG, totalMainVariablesCreated AS LONG DIM SHARED bypassNextVariable AS _BYTE DIM SHARED totalWarnings AS LONG, warningListItems AS LONG, lastWarningHeader AS STRING DIM SHARED duplicateConstWarning AS _BYTE, warningsissued AS _BYTE DIM SHARED emptySCWarning AS _BYTE, maxLineNumber AS LONG DIM SHARED ExeIconSet AS LONG, qb64prefix$, qb64prefix_set DIM SHARED VersionInfoSet AS _BYTE 'Variables to handle $VERSIONINFO metacommand: DIM SHARED viFileVersionNum$, viProductVersionNum$, viCompanyName$ DIM SHARED viFileDescription$, viFileVersion$, viInternalName$ DIM SHARED viLegalCopyright$, viLegalTrademarks$, viOriginalFilename$ DIM SHARED viProductName$, viProductVersion$, viComments$, viWeb$ DIM SHARED NoChecks DIM SHARED_Console DIM SHARED_ScreenHide DIM SHARED Asserts DIM SHARED OptMax AS LONG OptMax = 256 REDIM SHARED Opt(1 TO OptMax, 1 TO 10) AS STRING * 256 #31C4C4 #31C4C4 #31C4C4 REDIM SHARED OptWords(1 TO OptMax, 1 TO 10) AS INTEGER 'The number of words of each opt () element #31C4C4 #31C4C4 #31C4C4 REDIM SHARED T(1 TO OptMax) AS INTEGER 'The type of the entry ' t is 0 for ? opts ' ---------- 0 means ? , 1+ means a symbol or {}block ---------- ' t is 1 for symbol opts ' t is the number of rhs opt () index enteries for {READ¦WRITE¦READ WRITE} like opts REDIM SHARED Lev(1 TO OptMax) AS INTEGER 'The indwelling level of each opt () element (the lowest is 0) REDIM SHARED EntryLev(1 TO OptMax) AS INTEGER 'The level required from which this opt () can be validly be entered/checked-for REDIM SHARED DitchLev(1 TO OptMax) AS INTEGER 'The lowest level recorded between the previous Opt and this Opt REDIM SHARED DontPass(1 TO OptMax) AS INTEGER 'Set to 1 or 0, with 1 meaning don't pass 'Determines whether the opt () entry needs to actually be passed to the C++ sub/function REDIM SHARED TempList(1 TO OptMax) AS INTEGER REDIM SHARED PassRule(1 TO OptMax) AS LONG '0 means no pass rule 'negative values refer to an opt () element 'positive values refer to a flag value REDIM SHARED LevelEntered(OptMax) 'up to 64 levels supported REDIM SHARED separgs(OptMax + 1) AS STRING REDIM SHARED separgslayout(OptMax + 1) AS STRING REDIM SHARED separgs2(OptMax + 1) AS STRING REDIM SHARED separgslayout2(OptMax + 1) AS STRING DIM SHARED E DIM SHARED ResolveStaticFunctions REDIM SHARED ResolveStaticFunction_File(1 TO 100) AS STRING REDIM SHARED ResolveStaticFunction_Name(1 TO 100) AS STRING REDIM SHARED ResolveStaticFunction_Method(1 TO 100) AS LONG DIM SHARED Error_Happened AS LONG DIM SHARED Error_Message AS STRING DIM SHARED os AS STRING os$ = "WIN" IF INSTR(_OS$, "[LINUX]") THEN os$ = "LNX" DIM SHARED MacOSX AS LONG IF INSTR(_OS$, "[MACOSX]") THEN MacOSX = 1 DIM SHARED inline_DATA IF MacOSX THEN inline_DATA = 1 DIM SHARED BATCHFILE_EXTENSION AS STRING BATCHFILE_EXTENSION = ".bat" IF os$ = "LNX" THEN BATCHFILE_EXTENSION = ".sh" IF MacOSX THEN BATCHFILE_EXTENSION = ".command" DIM inlinedatastr(255) AS STRING FOR i = 0 TO 255 inlinedatastr(i) = str2$(i) + "," NEXT DIM SHARED extension AS STRING DIM SHARED path.exe$, path.source$, lastBinaryGenerated$ extension$ = ".exe" IF os$ = "LNX" THEN extension$ = "" 'no extension under Linux DIM SHARED pathsep AS STRING * 1 pathsep$ = "\" IF os$ = "LNX" THEN pathsep$ = "/" 'note: QB64 handles OS specific path separators automatically except under SHELL calls ON ERROR GOTO qberror_test DIM SHARED tmpdir AS STRING, tmpdir2 AS STRING IF os$ = "WIN" THEN tmpdir$ = ".\internal\temp\": tmpdir2$ = "..\\temp\\" IF os$ = "LNX" THEN tmpdir$ = "./internal/temp/": tmpdir2$ = "../temp/" IF NOT _DIREXISTS(tmpdir$) THEN MKDIR tmpdir$ DECLARE LIBRARY FUNCTION getpid& () END DECLARE thisinstancepid = getpid& DIM SHARED tempfolderindex IF INSTR(_OS$, "LINUX") THEN fh = FREEFILE OPEN ".\internal\temp\tempfoldersearch.bin" FOR RANDOM AS #fh LEN = LEN(tempfolderindex) tempfolderrecords = LOF(fh) / LEN(tempfolderindex) i = 1 IF tempfolderrecords = 0 THEN 'first run ever? PUT #fh, 1, thisinstancepid ELSE FOR i = 1 TO tempfolderrecords #31C4C4 GET #fh, i, tempfoldersearch SHELL _HIDE "ps -p " + STR$(tempfoldersearch) + " > /dev/null 2>&1; echo $? > internal/temp/checkpid.bin" fh2 = FREEFILE OPEN "internal/temp/checkpid.bin" FOR BINARY AS #fh2 LINE INPUT #fh2, checkpid$ CLOSE #fh2 IF VAL(checkpid$) = 1 THEN 'This temp folder was locked by an instance that's no longer active, so 'this will be our temp folder PUT #fh, i, thisinstancepid EXIT FOR END IF NEXT IF i > tempfolderrecords THEN 'All indexes were busy. Let's initiate a new one: PUT #fh, i, thisinstancepid END IF END IF CLOSE #fh IF i > 1 THEN tmpdir$ = "./internal/temp" + str2$(i) + "/": tmpdir2$ = "../temp" + str2$(i) + "/" IF _DIREXISTS(tmpdir$) = 0 THEN MKDIR tmpdir$ END IF END IF OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 ELSE ON ERROR GOTO qberror_test E = 0 i = 1 OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 DO WHILE E i = i + 1 IF i = 1000 THEN PRINT "Unable to locate the 'internal' folder": END 1 MKDIR ".\internal\temp" + str2$(i) IF os$ = "WIN" THEN tmpdir$ = ".\internal\temp" + str2$(i) + "\": tmpdir2$ = "..\\temp" + str2$(i) + "\\" IF os$ = "LNX" THEN tmpdir$ = "./internal/temp" + str2$(i) + "/": tmpdir2$ = "../temp" + str2$(i) + "/" E = 0 OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 LOOP END IF 'temp folder established tempfolderindex = i IF i > 1 THEN 'create modified version of qbx.cpp OPEN ".\internal\c\qbx" + str2$(i) + ".cpp" FOR OUTPUT AS #2 OPEN ".\internal\c\qbx.cpp" FOR BINARY AS #1 DO UNTIL EOF(1) LINE INPUT #1, a$ x = INSTR(a$, "..\\temp\\"): IF x THEN a$ = LEFT$(a$, x - 1) + "..\\temp" + str2$(i) + "\\" + RIGHT$(a$, LEN(a$) - (x + 9)) x = INSTR(a$, "../temp/"): IF x THEN a$ = LEFT$(a$, x - 1) + "../temp" + str2$(i) + "/" + RIGHT$(a$, LEN(a$) - (x + 7)) PRINT #2, a$ LOOP CLOSE #1, #2 END IF IF Debug THEN OPEN tmpdir$ + "debug.txt" FOR OUTPUT AS #9 ON ERROR GOTO qberror DIM SHARED tempfolderindexstr AS STRING 'appended to "Untitled" DIM SHARED tempfolderindexstr2 AS STRING IF tempfolderindex <> 1 THEN tempfolderindexstr$ = "(" + str2$(tempfolderindex) + ")": tempfolderindexstr2$ = str2$(tempfolderindex) DIM SHARED idedebuginfo DIM SHARED seperateargs_error DIM SHARED seperateargs_error_message AS STRING DIM SHARED compfailed DIM SHARED reginternalsubfunc DIM SHARED reginternalvariable DIM SHARED symboltype_size symboltype_size = 0 DIM SHARED use_global_byte_elements use_global_byte_elements = 0 'compiler-side IDE data & definitions 'SHARED variables "passed" to/from the compiler & IDE DIM SHARED idecommand AS STRING 'a 1 byte message-type code, followed by optional string data DIM SHARED idereturn AS STRING 'used to pass formatted-lines and return information back to the IDE DIM SHARED ideerror AS LONG DIM SHARED idecompiled AS LONG DIM SHARED idemode '1 if using the IDE to compile DIM SHARED ideerrorline AS LONG 'set by qb64-error(...) to the line number it would have reported, this number 'is later passed to the ide in message #8 DIM SHARED idemessage AS STRING 'set by qb64-error(...) to the error message to be reported, this 'is later passed to the ide in message #8 DIM SHARED optionexplicit AS _BYTE DIM SHARED optionexplicitarray AS _BYTE DIM SHARED optionexplicit_cmd AS _BYTE DIM SHARED ideStartAtLine AS LONG, errorLineInInclude AS LONG DIM SHARED warningInInclude AS LONG, warningInIncludeLine AS LONG DIM SHARED outputfile_cmd$ DIM SHARED compilelog$ '$INCLUDE:'global\IDEsettings.bas' DIM OutputIsRelativeToStartDir AS LONG CMDLineFile = ParseCMDLineArgs$ IF CMDLineFile <> "" AND _FILEEXISTS(_STARTDIR$ + "/" + CMDLineFile) THEN CMDLineFile = _STARTDIR$ + "/" + CMDLineFile OutputIsRelativeToStartDir = -1 END IF IF ConsoleMode THEN _DEST _CONSOLE ELSE _CONSOLE OFF _SCREENSHOW _ICON END IF #31C4C4 'is passed back in idereturn 'message code numbers: '0 no ide present (auto defined array ide() return 0) '1 launch ide & with passed filename (compiler->ide) '2 begin new compilation with returned line of code (compiler<-ide) ' [2][line of code] '3 request next line (compiler->ide) ' [3] '4 next line of code returned (compiler<-ide) ' [4][line of code] '5 no more lines of code exist (compiler<-ide) ' [5] '6 code is OK/ready (compiler->ide) ' [6] '7 repass the code from the beginning (compiler->ide) ' [7] '8 an error has occurred with 'this' message on 'this' line(compiler->ide) ' [8][error message][line as LONG] '9 C++ compile (if necessary) and run with 'this' name (compiler<-ide) ' [9][name(no path, no .bas)] '10 The line requires more time to process ' Pass-back 'line of code' using method [4] when ready ' [10][line of code] '11 ".EXE file created" message '12 The name of the exe I'll create is '...' (compiler->ide) ' [12][exe name without .exe] '255 A qb error happened in the IDE (compiler->ide) ' note: detected by the fact that ideerror was not set to 0 ' [255] 'hash table data TYPE HashListItem Flags AS LONG Reference AS LONG NextItem AS LONG PrevItem AS LONG LastItem AS LONG 'note: this value is only valid on the first item in the list 'note: name is stored in a seperate array of strings END TYPE DIM SHARED HashFind_NextListItem AS LONG DIM SHARED HashFind_Reverse AS LONG DIM SHARED HashFind_SearchFlags AS LONG DIM SHARED HashFind_Name AS STRING DIM SHARED HashRemove_LastFound AS LONG DIM SHARED HashListSize AS LONG DIM SHARED HashListNext AS LONG DIM SHARED HashListFreeSize AS LONG DIM SHARED HashListFreeLast AS LONG 'hash lookup tables DIM SHARED hash1char(255) AS INTEGER DIM SHARED hash2char(65535) AS INTEGER FOR x = 1 TO 26 hash1char(64 + x) = x hash1char(96 + x) = x NEXT hash1char(95) = 27 '_ hash1char(48) = 28 '0 hash1char(49) = 29 '1 hash1char(50) = 30 '2 hash1char(51) = 31 '3 hash1char(52) = 23 '4 'note: x, y, z and beginning alphabet letters avoided because of common usage (eg. a2, y3) hash1char(53) = 22 '5 hash1char(54) = 20 '6 hash1char(55) = 19 '7 hash1char(56) = 18 '8 hash1char(57) = 17 '9 FOR c1 = 0 TO 255 FOR c2 = 0 TO 255 hash2char(c1 + c2 * 256) = hash1char(c1) + hash1char(c2) * 32 NEXT NEXT 'init HashListSize = 65536 HashListNext = 1 HashListFreeSize = 1024 HashListFreeLast = 0 REDIM SHARED HashList(1 TO HashListSize) AS HashListItem REDIM SHARED HashListName(1 TO HashListSize) AS STRING * 256 REDIM SHARED HashListFree(1 TO HashListFreeSize) AS LONG REDIM SHARED HashTable(16777215) AS LONG '64MB lookup table with indexes to the hashlist CONST HASHFLAG_LABEL = 2 CONST HASHFLAG_TYPE = 4 CONST HASHFLAG_RESERVED = 8 CONST HASHFLAG_OPERATOR = 16 CONST HASHFLAG_CUSTOMSYNTAX = 32 CONST HASHFLAG_SUB = 64 CONST HASHFLAG_FUNCTION = 128 CONST HASHFLAG_UDT = 256 CONST HASHFLAG_UDTELEMENT = 512 CONST HASHFLAG_CONSTANT = 1024 CONST HASHFLAG_VARIABLE = 2048 CONST HASHFLAG_ARRAY = 4096 CONST HASHFLAG_XELEMENTNAME = 8192 CONST HASHFLAG_XTYPENAME = 16384 TYPE Label_Type State AS _UNSIGNED _BYTE #31C4C4 cn AS STRING * 256 Scope AS LONG Data_Offset AS _INTEGER64 'offset within data Data_Referenced AS _UNSIGNED _BYTE 'set to 1 if data is referenced (data_offset will be used to create the data offset variable) Error_Line AS LONG 'the line number to reference on errors Scope_Restriction AS LONG 'cannot exist inside this scope (post checked) SourceLineNumber AS LONG END TYPE DIM SHARED nLabels, Labels_Ubound Labels_Ubound = 100 REDIM SHARED Labels(1 TO Labels_Ubound) AS Label_Type DIM SHARED Empty_Label AS Label_Type DIM SHARED PossibleSubNameLabels AS STRING 'format: name+sp+name+sp+name <-ucase$'d DIM SHARED SubNameLabels AS STRING 'format: name+sp+name+sp+name <-ucase$'d DIM SHARED CreatingLabel AS LONG DIM SHARED AllowLocalName AS LONG DIM SHARED DataOffset DIM SHARED prepass DIM SHARED autoarray DIM SHARED ontimerid, onkeyid, onstrigid DIM SHARED revertmaymusthave(1 TO 10000) DIM SHARED revertmaymusthaven DIM SHARED linecontinuation DIM SHARED dim2typepassback AS STRING 'passes back correct case sensitive version of type DIM SHARED inclevel DIM SHARED incname(100) AS STRING 'must be full path as given DIM SHARED inclinenumber(100) AS LONG DIM SHARED incerror AS STRING DIM SHARED fix046 AS STRING fix046$ = "__" + "ASCII" + "_" + "CHR" + "_" + "046" + "__" 'broken up to avoid detection for layout reversion DIM SHARED layout AS STRING 'passed to IDE DIM SHARED layoutok AS LONG 'tracks status of entire line DIM SHARED layoutcomment AS STRING DIM SHARED tlayout AS STRING 'temporary layout string set by supporting functions DIM SHARED layoutdone AS LONG 'tracks status of single command DIM SHARED fooindwel DIM SHARED alphanumeric(255) FOR i = 48 TO 57 alphanumeric(i) = -1 NEXT FOR i = 65 TO 90 alphanumeric(i) = -1 NEXT FOR i = 97 TO 122 alphanumeric(i) = -1 NEXT '_ is treated as an alphabet letter alphanumeric(95) = -1 DIM SHARED isalpha(255) FOR i = 65 TO 90 isalpha(i) = -1 NEXT FOR i = 97 TO 122 isalpha(i) = -1 NEXT '_ is treated as an alphabet letter isalpha(95) = -1 DIM SHARED isnumeric(255) FOR i = 48 TO 57 isnumeric(i) = -1 NEXT DIM SHARED lfsinglechar(255) lfsinglechar(40) = 1 '( lfsinglechar(41) = 1 ') lfsinglechar(42) = 1 '* lfsinglechar(43) = 1 '+ lfsinglechar(45) = 1 '- lfsinglechar(47) = 1 '/ lfsinglechar(60) = 1 '< lfsinglechar(61) = 1 #31C4C4 lfsinglechar(62) = 1 '> lfsinglechar(92) = 1 '\ lfsinglechar(94) = 1 '^ lfsinglechar(44) = 1 ', lfsinglechar(46) = 1 '. lfsinglechar(58) = 1 ': lfsinglechar(59) = 1 '; lfsinglechar(35) = 1 '# (file no only) lfsinglechar(36) = 1 '$ (metacommand only) lfsinglechar(63) = 1 '? (print macro) lfsinglechar(95) = 1 '_ DIM SHARED nextrunlineindex AS LONG DIM SHARED lineinput3buffer AS STRING DIM SHARED lineinput3index AS LONG DIM SHARED dimstatic AS LONG DIM SHARED staticarraylist AS STRING DIM SHARED staticarraylistn AS LONG DIM SHARED commonarraylist AS STRING DIM SHARED commonarraylistn AS LONG 'CONST support DIM SHARED constmax AS LONG constmax = 100 DIM SHARED constlast AS LONG constlast = -1 REDIM SHARED constname(constmax) AS STRING REDIM SHARED constcname(constmax) AS STRING REDIM SHARED constnamesymbol(constmax) AS STRING 'optional name symbol ' `1 and `no-number must be handled correctly 'DIM SHARED constlastshared AS LONG 'so any defined inside a sub/function after this index can be "forgotten" when sub/function exits #31C4C4 REDIM SHARED consttype(constmax) AS LONG 'variable type number 'consttype determines storage REDIM SHARED constinteger(constmax) AS _INTEGER64 REDIM SHARED constuinteger(constmax) AS _UNSIGNED _INTEGER64 REDIM SHARED constfloat(constmax) AS _FLOAT REDIM SHARED conststring(constmax) AS STRING REDIM SHARED constsubfunc(constmax) AS LONG REDIM SHARED constdefined(constmax) AS LONG 'UDT 'names DIM SHARED lasttype AS LONG DIM SHARED lasttypeelement AS LONG TYPE idstruct n AS STRING * 256 'name cn AS STRING * 256 'case sensitive version of n arraytype AS LONG 'similar to t arrayelements AS INTEGER staticarray AS INTEGER 'set for arrays declared in the main module with static elements mayhave AS STRING * 8 'mayhave and musthave are exclusive of each other musthave AS STRING * 8 t AS LONG 'type tsize AS LONG subfunc AS INTEGER #31C4C4 Dependency AS INTEGER internal_subfunc AS INTEGER callname AS STRING * 256 ccall AS INTEGER overloaded AS _BYTE args AS INTEGER minargs AS INTEGER arg AS STRING * 400 'similar to t argsize AS STRING * 400 'similar to tsize (used for fixed length strings) specialformat AS STRING * 256 secondargmustbe AS STRING * 256 secondargcantbe AS STRING * 256 ret AS LONG 'the value it returns if it is a function (again like t) insubfunc AS STRING * 256 insubfuncn AS LONG share AS INTEGER nele AS STRING * 100 nelereq AS STRING * 100 linkid AS LONG linkarg AS INTEGER staticscope AS INTEGER 'For variables which are arguments passed to a sub/function sfid AS LONG 'id number of variable's parent sub/function sfarg AS INTEGER #31C4C4 hr_syntax AS STRING END TYPE DIM SHARED id AS idstruct DIM SHARED idn AS LONG DIM SHARED ids_max AS LONG ids_max = 1024 REDIM SHARED ids(1 TO ids_max) AS idstruct REDIM SHARED cmemlist(1 TO ids_max + 1) AS INTEGER 'variables that must be in cmem REDIM SHARED sfcmemargs(1 TO ids_max + 1) AS STRING * 100 's/f arg that must be in cmem REDIM SHARED arrayelementslist(1 TO ids_max + 1) AS INTEGER #31C4C4 'create blank id template for idclear to copy (stops strings being set to chr$(0)) DIM SHARED cleariddata AS idstruct cleariddata.cn = "" cleariddata.n = "" cleariddata.mayhave = "" cleariddata.musthave = "" cleariddata.callname = "" cleariddata.arg = "" cleariddata.argsize = "" cleariddata.specialformat = "" cleariddata.secondargmustbe = "" cleariddata.secondargcantbe = "" cleariddata.insubfunc = "" cleariddata.nele = "" cleariddata.nelereq = "" DIM SHARED ISSTRING AS LONG DIM SHARED ISFLOAT AS LONG DIM SHARED ISUNSIGNED AS LONG DIM SHARED ISPOINTER AS LONG DIM SHARED ISFIXEDLENGTH AS LONG DIM SHARED ISINCONVENTIONALMEMORY AS LONG DIM SHARED ISOFFSETINBITS AS LONG DIM SHARED ISARRAY AS LONG DIM SHARED ISREFERENCE AS LONG DIM SHARED ISUDT AS LONG DIM SHARED ISOFFSET AS LONG DIM SHARED STRINGTYPE AS LONG DIM SHARED BITTYPE AS LONG DIM SHARED UBITTYPE AS LONG DIM SHARED BYTETYPE AS LONG DIM SHARED UBYTETYPE AS LONG DIM SHARED INTEGERTYPE AS LONG DIM SHARED UINTEGERTYPE AS LONG DIM SHARED LONGTYPE AS LONG DIM SHARED ULONGTYPE AS LONG DIM SHARED INTEGER64TYPE AS LONG DIM SHARED UINTEGER64TYPE AS LONG DIM SHARED SINGLETYPE AS LONG DIM SHARED DOUBLETYPE AS LONG DIM SHARED FLOATTYPE AS LONG DIM SHARED OFFSETTYPE AS LONG DIM SHARED UOFFSETTYPE AS LONG DIM SHARED UDTTYPE AS LONG DIM SHARED gosubid AS LONG DIM SHARED redimoption AS INTEGER DIM SHARED dimoption AS INTEGER DIM SHARED arraydesc AS INTEGER DIM SHARED qberrorhappened AS INTEGER DIM SHARED qberrorcode AS INTEGER DIM SHARED qberrorline AS INTEGER 'COMMON SHARED defineaz() AS STRING 'COMMON SHARED defineextaz() AS STRING DIM SHARED sourcefile AS STRING 'the full path and filename DIM SHARED file AS STRING 'name of the file (without .bas or path) 'COMMON SHARED separgs() AS STRING DIM SHARED constequation AS INTEGER DIM SHARED DynamicMode AS INTEGER DIM SHARED findidsecondarg AS STRING DIM SHARED findanotherid AS INTEGER DIM SHARED findidinternal AS LONG DIM SHARED currentid AS LONG 'is the index of the last ID accessed DIM SHARED linenumber AS LONG, reallinenumber AS LONG, totallinenumber AS LONG, definingtypeerror AS LONG DIM SHARED wholeline AS STRING DIM SHARED firstLineNumberLabelvWatch AS LONG, lastLineNumberLabelvWatch AS LONG DIM SHARED vWatchUsedLabels AS STRING, vWatchUsedSkipLabels AS STRING DIM SHARED linefragment AS STRING 'COMMON SHARED bitmask() AS _INTEGER64 'COMMON SHARED bitmaskinv() AS _INTEGER64 DIM SHARED arrayprocessinghappened AS INTEGER DIM SHARED stringprocessinghappened AS INTEGER DIM SHARED cleanupstringprocessingcall AS STRING DIM SHARED inputfunctioncalled AS _BYTE DIM SHARED recompile AS INTEGER 'forces recompilation 'COMMON SHARED cmemlist() AS INTEGER DIM SHARED optionbase AS INTEGER DIM SHARED addmetastatic AS INTEGER DIM SHARED addmetadynamic AS INTEGER DIM SHARED addmetainclude AS STRING DIM SHARED closedmain AS INTEGER DIM SHARED module AS STRING DIM SHARED subfunc AS STRING DIM SHARED subfuncn AS LONG DIM SHARED closedsubfunc AS _BYTE DIM SHARED subfuncid AS LONG DIM SHARED defdatahandle AS INTEGER DIM SHARED dimsfarray AS INTEGER DIM SHARED dimshared AS INTEGER 'Allows passing of known elements to recompilation DIM SHARED sflistn AS INTEGER 'COMMON SHARED sfidlist() AS LONG 'COMMON SHARED sfarglist() AS INTEGER 'COMMON SHARED sfelelist() AS INTEGER DIM SHARED glinkid AS LONG DIM SHARED glinkarg AS INTEGER DIM SHARED typname2typsize AS LONG DIM SHARED uniquenumbern AS LONG 'CLEAR , , 16384 DIM SHARED bitmask(1 TO 64) AS _INTEGER64 DIM SHARED bitmaskinv(1 TO 64) AS _INTEGER64 DIM SHARED defineextaz(1 TO 27) AS STRING DIM SHARED defineaz(1 TO 27) AS STRING '27 is an underscore ISSTRING = 1073741824 ISFLOAT = 536870912 ISUNSIGNED = 268435456 ISPOINTER = 134217728 ISFIXEDLENGTH = 67108864 'only set for strings with pointer flag ISINCONVENTIONALMEMORY = 33554432 ISOFFSETINBITS = 16777216 ISARRAY = 8388608 ISREFERENCE = 4194304 ISUDT = 2097152 ISOFFSET = 1048576 STRINGTYPE = ISSTRING + ISPOINTER BITTYPE = 1& + ISPOINTER + ISOFFSETINBITS UBITTYPE = 1& + ISPOINTER + ISUNSIGNED + ISOFFSETINBITS 'QB64 will also support BIT*n, eg. DIM bitarray[10] AS _UNSIGNED _BIT*10 BYTETYPE = 8& + ISPOINTER UBYTETYPE = 8& + ISPOINTER + ISUNSIGNED INTEGERTYPE = 16& + ISPOINTER UINTEGERTYPE = 16& + ISPOINTER + ISUNSIGNED LONGTYPE = 32& + ISPOINTER ULONGTYPE = 32& + ISPOINTER + ISUNSIGNED INTEGER64TYPE = 64& + ISPOINTER UINTEGER64TYPE = 64& + ISPOINTER + ISUNSIGNED SINGLETYPE = 32& + ISFLOAT + ISPOINTER DOUBLETYPE = 64& + ISFLOAT + ISPOINTER FLOATTYPE = 256& + ISFLOAT + ISPOINTER '8-32 bytes OFFSETTYPE = 64& + ISOFFSET + ISPOINTER: IF OS_BITS = 32 THEN OFFSETTYPE = 32& + ISOFFSET + ISPOINTER UOFFSETTYPE = 64& + ISOFFSET + ISUNSIGNED + ISPOINTER: IF OS_BITS = 32 THEN UOFFSETTYPE = 32& + ISOFFSET + ISUNSIGNED + ISPOINTER UDTTYPE = ISUDT + ISPOINTER DIM SHARED statementn AS LONG DIM SHARED everycasenewcase AS LONG DIM SHARED controllevel AS INTEGER #31C4C4 DIM SHARED controltype(1000) AS INTEGER #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 #31C4C4 DIM controlid(1000) AS LONG DIM controlvalue(1000) AS LONG DIM controlstate(1000) AS INTEGER DIM SHARED controlref(1000) AS LONG 'the line number the control was created on ' ' Collection of flags indicating which unstable features should be used during compilation ' REDIM SHARED unstableFlags(1 TO 2) AS _BYTE DIM UNSTABLE_MIDI AS LONG DIM UNSTABLE_HTTP AS LONG UNSTABLE_MIDI = 1 UNSTABLE_HTTP = 2 ON ERROR GOTO qberror i2&& = 1 FOR i&& = 1 TO 64 bitmask(i&&) = i2&& bitmaskinv(i&&) = NOT i2&& i2&& = i2&& + 2 ^ i&& NEXT DIM id2 AS idstruct cleanupstringprocessingcall$ = "qbs_cleanup(qbs_tmp_base," DIM SHARED sfidlist(1000) AS LONG DIM SHARED sfarglist(1000) AS INTEGER DIM SHARED sfelelist(1000) AS INTEGER '----------------ripgl.bas-------------------------------------------------------------------------------- gl_scan_header '----------------ripgl.bas-------------------------------------------------------------------------------- '-----------------------QB64 COMPILER ONCE ONLY SETUP CODE ENDS HERE--------------------------------------- IF NoIDEMode THEN IDE_AutoPosition = 0: GOTO noide DIM FileDropEnabled AS _BYTE IF FileDropEnabled = 0 THEN FileDropEnabled = -1: _ACCEPTFILEDROP IF IDE_AutoPosition AND NOT IDE_BypassAutoPosition THEN _SCREENMOVE IDE_LeftPosition, IDE_TopPosition idemode = 1 sendc$ = "" 'no initial message IF CMDLineFile <> "" THEN sendc$ = CHR$(1) + CMDLineFile sendcommand: idecommand$ = sendc$ C = ide(0) ideerror = 0 IF C = 0 THEN idemode = 0: GOTO noide c$ = idereturn$ IF C = 2 THEN 'begin ideerrorline = 0 'addresses invalid prepass error line numbers being reported idepass = 1 GOTO fullrecompile ideret1: wholeline$ = c$ GOTO ideprepass ideret2: IF lastLineReturn THEN GOTO lastLineReturn sendc$ = CHR$(3) 'request next line GOTO sendcommand END IF IF C = 4 THEN 'next line IF idepass = 1 THEN wholeline$ = c$ GOTO ideprepass '(returns to ideret2: above) END IF 'assume idepass>1 a3$ = c$ continuelinefrom = 0 GOTO ide4 ideret4: IF lastLineReturn THEN GOTO lastLineReturn sendc$ = CHR$(3) 'request next line GOTO sendcommand END IF IF C = 5 THEN 'end of program reached lastLine = 1 lastLineReturn = 1 IF idepass = 1 THEN wholeline$ = "" GOTO ideprepass '(returns to ideret2: above, then to lastLinePrepassReturn below) END IF 'idepass>1 a3$ = "" continuelinefrom = 0 GOTO ide4 'returns to ideret4, then to lastLinePrepassReturn below lastLineReturn: lastLineReturn = 0 lastLine = 0 IF idepass = 1 THEN 'prepass complete idepass = 2 GOTO ide3 ideret3: sendc$ = CHR$(7) 'repass request firstLine = 1 GOTO sendcommand END IF #31C4C4 'finalize program GOTO ide5 ideret5: 'note: won't return here if a recompile was required! sendc$ = CHR$(6) 'ready idecompiled = 0 GOTO sendcommand END IF IF C = 9 THEN 'run IF idecompiled = 0 THEN 'exe needs to be compiled file$ = c$ 'locate accessible file and truncate f$ = file$ path.exe$ = "" IF SaveExeWithSource THEN IF LEN(ideprogname) THEN path.exe$ = idepath$ + pathsep$ END IF i = 1 nextexeindex: IF _FILEEXISTS(path.exe$ + file$ + extension$) THEN E = 0 ON ERROR GOTO qberror_test KILL path.exe$ + file$ + extension$ ON ERROR GOTO qberror IF E = 1 THEN i = i + 1 file$ = f$ + "(" + str2$(i) + ")" GOTO nextexeindex END IF END IF 'inform IDE of name change if necessary (IDE will respond with message 9 and corrected name) IF i <> 1 THEN sendc$ = CHR$(12) + file$ GOTO sendcommand END IF ideerrorline = 0 'addresses C++ comp. error's line number GOTO ide6 ideret6: idecompiled = 1 END IF IF iderunmode = 2 THEN sendc$ = CHR$(11) '.EXE file created GOTO sendcommand END IF 'execute program IF iderunmode = 1 THEN IF NoExeSaved THEN 'This is the section which deals with if the user selected to run the program without 'saving an EXE file to the disk. 'We start off by first running the EXE, and then we delete it from the drive. 'making it a temporary file when all is said and done. IF os$ = "WIN" THEN SHELL QuotedFilename$(CHR$(34) + lastBinaryGenerated$ + CHR$(34)) + ModifyCOMMAND$ 'run the newly created program SHELL _HIDE _DONTWAIT "del " + QuotedFilename$(CHR$(34) + lastBinaryGenerated$ + CHR$(34)) 'kill it END IF IF path.exe$ = "" THEN path.exe$ = "./" IF os$ = "LNX" THEN IF LEFT$(lastBinaryGenerated$, LEN(path.exe$)) = path.exe$ THEN SHELL QuotedFilename$(lastBinaryGenerated$) + ModifyCOMMAND$ KILL lastBinaryGenerated$ ELSE SHELL QuotedFilename$(path.exe$ + lastBinaryGenerated$) + ModifyCOMMAND$ KILL path.exe$ + lastBinaryGenerated$ END IF END IF IF path.exe$ = "./" THEN path.exe$ = "" NoExeSaved = 0 'reset the flag for a temp EXE sendc$ = CHR$(6) 'ready GOTO sendcommand END IF IF os$ = "WIN" THEN SHELL _DONTWAIT QuotedFilename$(CHR$(34) + lastBinaryGenerated$ + CHR$(34)) + ModifyCOMMAND$ IF path.exe$ = "" THEN path.exe$ = "./" IF os$ = "LNX" THEN IF LEFT$(lastBinaryGenerated$, LEN(path.exe$)) = path.exe$ THEN SHELL _DONTWAIT QuotedFilename$(lastBinaryGenerated$) + ModifyCOMMAND$ ELSE SHELL _DONTWAIT QuotedFilename$(path.exe$ + lastBinaryGenerated$) + ModifyCOMMAND$ END IF END IF IF path.exe$ = "./" THEN path.exe$ = "" ELSE IF os$ = "WIN" THEN SHELL QuotedFilename$(CHR$(34) + lastBinaryGenerated$ + CHR$(34)) + ModifyCOMMAND$ IF path.exe$ = "" THEN path.exe$ = "./" IF os$ = "LNX" THEN IF LEFT$(lastBinaryGenerated$, LEN(path.exe$)) = path.exe$ THEN SHELL QuotedFilename$(lastBinaryGenerated$) + ModifyCOMMAND$ ELSE SHELL QuotedFilename$(path.exe$ + lastBinaryGenerated$) + ModifyCOMMAND$ END IF END IF IF path.exe$ = "./" THEN path.exe$ = "" DO: LOOP UNTIL INKEY$ = "" DO: LOOP UNTIL _KEYHIT = 0 END IF IF idemode THEN 'Darken fg/bg colors dummy = DarkenFGBG(0) END IF IF vWatchOn THEN sendc$ = CHR$(254) 'launch debug interface ELSE sendc$ = CHR$(6) 'ready END IF GOTO sendcommand END IF PRINT "Invalid IDE message": END ideerror: IF INSTR(idemessage$, sp$) THEN 'Something went wrong here, so let's give a generic error message to the user. '(No error message should contain sp$ - that is, CHR$(13), when not in Debug mode) terrmsg$ = _ERRORMESSAGE$ IF terrmsg$ = "No error" THEN terrmsg$ = "Internal error" idemessage$ = "Compiler error (check for syntax errors) (" + terrmsg$ + ":" IF ERR THEN idemessage$ = idemessage$ + str2$(ERR) + "-" IF _ERRORLINE THEN idemessage$ = idemessage$ + str2$(_ERRORLINE) IF _INCLERRORLINE THEN idemessage$ = idemessage$ + "-" + _INCLERRORFILE$ + "-" + str2$(_INCLERRORLINE) idemessage$ = idemessage$ + ")" IF inclevel > 0 THEN idemessage$ = idemessage$ + incerror$ END IF sendc$ = CHR$(8) + idemessage$ + MKL$(ideerrorline) GOTO sendcommand noide: IF (qb64versionprinted = 0 OR ConsoleMode = 0) AND NOT QuietMode THEN qb64versionprinted = -1 PRINT "QB64-PE Compiler V" + Version$ END IF IF CMDLineFile = "" THEN LINE INPUT ; "COMPILE (.bas)>", f$ ELSE f$ = CMDLineFile END IF f$ = LTRIM$(RTRIM$(f$)) IF FileHasExtension(f$) = 0 THEN f$ = f$ + ".bas" sourcefile$ = f$ CMDLineFile = sourcefile$ 'derive name from sourcefile f$ = RemoveFileExtension$(f$) path.exe$ = "" currentdir$ = _CWD$ path.source$ = getfilepath$(sourcefile$) IF LEN(path.source$) THEN IF _DIREXISTS(path.source$) = 0 THEN PRINT PRINT "Cannot locate source file: " + sourcefile$ IF ConsoleMode THEN SYSTEM 1 END 1 END IF CHDIR path.source$ path.source$ = _CWD$ IF RIGHT$(path.source$, 1) <> pathsep$ THEN path.source$ = path.source$ + pathsep$ CHDIR currentdir$ END IF IF SaveExeWithSource THEN path.exe$ = path.source$ FOR x = LEN(f$) TO 1 STEP -1 a$ = MID$(f$, x, 1) IF a$ = "/" OR a$ = "\" THEN f$ = RIGHT$(f$, LEN(f$) - x) EXIT FOR END IF NEXT file$ = f$ 'if cmemlist(currentid+1)<>0 before calling regid the variable 'MUST be defined in cmem! fullrecompile: IF idemode = 0 AND NOT QuietMode THEN PRINT PRINT "Beginning C++ output from QB64 code... " END IF BU_DEPENDENCY_CONSOLE_ONLY = DEPENDENCY(DEPENDENCY_CONSOLE_ONLY) FOR i = 1 TO UBOUND(DEPENDENCY): DEPENDENCY(i) = 0: NEXT DEPENDENCY(DEPENDENCY_CONSOLE_ONLY) = BU_DEPENDENCY_CONSOLE_ONLY AND 2 'Restore -g switch if used Error_Happened = 0 FOR closeall = 1 TO 255: CLOSE closeall: NEXT OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 'relock bh = OpenBuffer%("O", tmpdir$ + "dyninfo.txt") IF Debug THEN CLOSE #9: OPEN tmpdir$ + "debug.txt" FOR OUTPUT AS #9 FOR i = 1 TO ids_max + 1 arrayelementslist(i) = 0 cmemlist(i) = 0 sfcmemargs(i) = "" NEXT 'erase cmemlist 'erase sfcmemargs lastunresolved = -1 'first pass sflistn = -1 'no entries SubNameLabels = sp 'QB64 will perform a repass to resolve sub names used as labels vWatchDesiredState = 0 vWatchRecompileAttempts = 0 qb64prefix_set_desiredState = 0 qb64prefix_set_recompileAttempts = 0 opex_desiredState = 0 opex_recompileAttempts = 0 opexarray_desiredState = 0 opexarray_recompileAttempts = 0 recompile: vWatchOn = vWatchDesiredState vWatchVariable "", -1 'reset internal variables list qb64prefix_set = qb64prefix_set_desiredState qb64prefix$ = "_" optionexplicit = opex_desiredState IF optionexplicit_cmd = -1 AND NoIDEMode = 1 THEN optionexplicit = -1 optionexplicitarray = opexarray_desiredState lastLineReturn = 0 lastLine = 0 firstLine = 1 _Resize = 0 Resize_Scale = 0 UseGL = 0 Error_Happened = 0 HashClear 'clear the hash table 'add reserved words to hashtable f = HASHFLAG_TYPE + HASHFLAG_RESERVED HashAdd "_UNSIGNED", f, 0 HashAdd "_BIT", f, 0 HashAdd "_BYTE", f, 0 HashAdd "INTEGER", f, 0 HashAdd "LONG", f, 0 HashAdd "_INTEGER64", f, 0 HashAdd "_OFFSET", f, 0 HashAdd "SINGLE", f, 0 HashAdd "DOUBLE", f, 0 HashAdd "_FLOAT", f, 0 HashAdd "STRING", f, 0 HashAdd "ANY", f, 0 f = HASHFLAG_OPERATOR + HASHFLAG_RESERVED HashAdd "NOT", f, 0 HashAdd "IMP", f, 0 HashAdd "EQV", f, 0 HashAdd "AND", f, 0 HashAdd "OR", f, 0 HashAdd "XOR", f, 0 HashAdd "MOD", f, 0 f = HASHFLAG_RESERVED + HASHFLAG_CUSTOMSYNTAX HashAdd "LIST", f, 0 HashAdd "BASE", f, 0 HashAdd "_EXPLICIT", f, 0 HashAdd "AS", f, 0 HashAdd "IS", f, 0 HashAdd "OFF", f, 0 HashAdd "ON", f, 0 HashAdd "STOP", f, 0 HashAdd "TO", f, 0 HashAdd "USING", f, 0 'PUT(graphics) statement: HashAdd "PRESET", f, 0 HashAdd "PSET", f, 0 'OPEN statement: HashAdd "FOR", f, 0 HashAdd "OUTPUT", f, 0 HashAdd "RANDOM", f, 0 HashAdd "BINARY", f, 0 HashAdd "APPEND", f, 0 HashAdd "SHARED", f, 0 HashAdd "ACCESS", f, 0 HashAdd "LOCK", f, 0 HashAdd "READ", f, 0 HashAdd "WRITE", f, 0 'LINE statement: HashAdd "STEP", f, 0 'WIDTH statement: HashAdd "LPRINT", f, 0 'VIEW statement: HashAdd "PRINT", f, 0 f = HASHFLAG_RESERVED + HASHFLAG_XELEMENTNAME + HASHFLAG_XTYPENAME 'A 'B 'C HashAdd "COMMON", f, 0 HashAdd "CALL", f, 0 HashAdd "CASE", f - HASHFLAG_XELEMENTNAME, 0 HashAdd "COM", f, 0 '(ON...) HashAdd "CONST", f, 0 'D HashAdd "DATA", f, 0 HashAdd "DECLARE", f, 0 HashAdd "DEF", f, 0 HashAdd "DEFDBL", f, 0 HashAdd "DEFINT", f, 0 HashAdd "DEFLNG", f, 0 HashAdd "DEFSNG", f, 0 HashAdd "DEFSTR", f, 0 HashAdd "DIM", f, 0 HashAdd "DO", f - HASHFLAG_XELEMENTNAME, 0 'E HashAdd "ERROR", f - HASHFLAG_XELEMENTNAME, 0 '(ON ...) HashAdd "ELSE", f, 0 HashAdd "ELSEIF", f, 0 HashAdd "ENDIF", f, 0 HashAdd "EXIT", f - HASHFLAG_XELEMENTNAME, 0 'F HashAdd "FIELD", f - HASHFLAG_XELEMENTNAME, 0 HashAdd "FUNCTION", f, 0 'G HashAdd "GOSUB", f, 0 HashAdd "GOTO", f, 0 'H 'I HashAdd "INPUT", f - HASHFLAG_XELEMENTNAME - HASHFLAG_XTYPENAME, 0 '(INPUT$ function exists, so conflicts if allowed as custom syntax) HashAdd "IF", f, 0 'K HashAdd "KEY", f - HASHFLAG_XELEMENTNAME - HASHFLAG_XTYPENAME, 0 '(ON...) 'L HashAdd "LET", f - HASHFLAG_XELEMENTNAME, 0 HashAdd "LOOP", f - HASHFLAG_XELEMENTNAME, 0 HashAdd "LEN", f - HASHFLAG_XELEMENTNAME, 0 '(LEN function exists, so conflicts if allowed as custom syntax) 'M 'N HashAdd "NEXT", f - HASHFLAG_XELEMENTNAME, 0 'O 'P HashAdd "PLAY", f - HASHFLAG_XELEMENTNAME - HASHFLAG_XTYPENAME, 0 '(ON...) HashAdd "PEN", f - HASHFLAG_XELEMENTNAME - HASHFLAG_XTYPENAME, 0 '(ON...) 'Q 'R HashAdd "REDIM", f, 0 HashAdd "REM", f, 0 HashAdd "RESTORE", f - HASHFLAG_XELEMENTNAME, 0 HashAdd "RESUME", f - HASHFLAG_XELEMENTNAME, 0 HashAdd "RETURN", f - HASHFLAG_XELEMENTNAME, 0 HashAdd "RUN", f - HASHFLAG_XELEMENTNAME, 0 'S HashAdd "STATIC", f, 0 HashAdd "STRIG", f, 0 '(ON...) HashAdd "SEG", f, 0 HashAdd "SELECT", f - HASHFLAG_XELEMENTNAME - HASHFLAG_XTYPENAME, 0 HashAdd "SUB", f, 0 HashAdd "SCREEN", f - HASHFLAG_XELEMENTNAME - HASHFLAG_XTYPENAME, 0 'T HashAdd "THEN", f, 0 HashAdd "TIMER", f - HASHFLAG_XELEMENTNAME - HASHFLAG_XTYPENAME, 0 '(ON...) HashAdd "TYPE", f - HASHFLAG_XELEMENTNAME, 0 'U HashAdd "UNTIL", f, 0 HashAdd "UEVENT", f, 0 'V 'W HashAdd "WEND", f, 0 HashAdd "WHILE", f, 0 'X 'Y 'Z 'clear/init variables _Console = 0 _ScreenHide = 0 Asserts = 0 ResolveStaticFunctions = 0 dynamiclibrary = 0 dimsfarray = 0 dimstatic = 0 AllowLocalName = 0 PossibleSubNameLabels = sp 'QB64 will perform a repass to resolve sub names used as labels use_global_byte_elements = 0 dimshared = 0: dimmethod = 0: dimoption = 0: redimoption = 0: commonoption = 0 mylib$ = "": mylibopt$ = "" declaringlibrary = 0 nLabels = 0 dynscope = 0 elsefollowup = 0 ontimerid = 0: onkeyid = 0: onstrigid = 0 commonarraylist = "": commonarraylistn = 0 staticarraylist = "": staticarraylistn = 0 fooindwel = 0 layout = "" layoutok = 0 NoChecks = 0 inclevel = 0 errorLineInInclude = 0 addmetainclude$ = "" nextrunlineindex = 1 lasttype = 0 lasttypeelement = 0 REDIM SHARED udtxname(1000) AS STRING * 256 REDIM SHARED udtxcname(1000) AS STRING * 256 REDIM SHARED udtxsize(1000) AS LONG REDIM SHARED udtxbytealign(1000) AS INTEGER 'first element MUST be on a byte alignment & size is a multiple of 8 REDIM SHARED udtxnext(1000) AS LONG REDIM SHARED udtxvariable(1000) AS INTEGER 'true if the udt contains variable length elements 'elements REDIM SHARED udtename(1000) AS STRING * 256 REDIM SHARED udtecname(1000) AS STRING * 256 REDIM SHARED udtebytealign(1000) AS INTEGER REDIM SHARED udtesize(1000) AS LONG REDIM SHARED udtetype(1000) AS LONG REDIM SHARED udtetypesize(1000) AS LONG REDIM SHARED udtearrayelements(1000) AS LONG REDIM SHARED udtenext(1000) AS LONG definingtype = 0 definingtypeerror = 0 constlast = -1 #31C4C4 closedmain = 0 addmetastatic = 0 addmetadynamic = 0 DynamicMode = 0 optionbase = 0 ExeIconSet = 0 VersionInfoSet = 0 viFileVersionNum$ = "": viProductVersionNum$ = "": viCompanyName$ = "" viFileDescription$ = "": viFileVersion$ = "": viInternalName$ = "" viLegalCopyright$ = "": viLegalTrademarks$ = "": viOriginalFilename$ = "" viProductName$ = "": viProductVersion$ = "": viComments$ = "": viWeb$ = "" DataOffset = 0 statementn = 0 everycasenewcase = 0 qberrorhappened = 0: qberrorcode = 0: qberrorline = 0 FOR i = 1 TO 27: defineaz(i) = "SINGLE": defineextaz(i) = "!": NEXT controllevel = 0 findidsecondarg$ = "": findanotherid = 0: findidinternal = 0: currentid = 0 linenumber = 0 wholeline$ = "" linefragment$ = "" idn = 0 arrayprocessinghappened = 0 stringprocessinghappened = 0 inputfunctioncalled = 0 subfuncn = 0 closedsubfunc = 0 subfunc = "" SelectCaseCounter = 0 ExecCounter = 0 UserDefineCount = 7 totalVariablesCreated = 0 typeDefinitions$ = "" totalMainVariablesCreated = 0 REDIM SHARED usedVariableList(1000) AS usedVarList totalWarnings = 0 duplicateConstWarning = 0 emptySCWarning = 0 warningListItems = 0 lastWarningHeader = "" vWatchUsedLabels = SPACE$(1000) vWatchUsedSkipLabels = SPACE$(1000) firstLineNumberLabelvWatch = 0 REDIM SHARED warning$(1000) REDIM SHARED warningLines(1000) AS LONG REDIM SHARED warningIncLines(1000) AS LONG REDIM SHARED warningIncFiles(1000) AS STRING maxLineNumber = 0 uniquenumbern = 0 create a type for storing memory blocks UDT names 'DIM SHARED lasttype AS LONG 'DIM SHARED udtxname(1000) AS STRING * 256 'DIM SHARED udtxcname(1000) AS STRING * 256 'DIM SHARED udtxsize(1000) AS LONG 'DIM SHARED udtxbytealign(1000) AS INTEGER 'first element MUST be on a byte alignment & size is a multiple of 8 'DIM SHARED udtxnext(1000) AS LONG elements 'DIM SHARED lasttypeelement AS LONG 'DIM SHARED udtename(1000) AS STRING * 256 'DIM SHARED udtecname(1000) AS STRING * 256 'DIM SHARED udtebytealign(1000) AS INTEGER 'DIM SHARED udtesize(1000) AS LONG 'DIM SHARED udtetype(1000) AS LONG 'DIM SHARED udtetypesize(1000) AS LONG 'DIM SHARED udtearrayelements(1000) AS LONG 'DIM SHARED udtenext(1000) AS LONG 'import _MEM type ptrsz = OS_BITS \ 8 lasttype = lasttype + 1: i = lasttype udtxname(i) = "_MEM" udtxcname(i) = "_MEM" udtxsize(i) = ((ptrsz) * 5 + (4) * 2 + (8) * 1) * 8 udtxbytealign(i) = 1 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "OFFSET" udtecname(i2) = "OFFSET" udtebytealign(i2) = 1 udtetype(i2) = OFFSETTYPE: udtesize(i2) = ptrsz * 8 udtetypesize(i2) = 0 'tsize udtxnext(i) = i2 i3 = i2 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "SIZE" udtecname(i2) = "SIZE" udtebytealign(i2) = 1 udtetype(i2) = OFFSETTYPE: udtesize(i2) = ptrsz * 8 udtetypesize(i2) = 0 'tsize udtenext(i3) = i2 i3 = i2 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "$_LOCK_ID" udtecname(i2) = "$_LOCK_ID" udtebytealign(i2) = 1 udtetype(i2) = INTEGER64TYPE: udtesize(i2) = 64 udtetypesize(i2) = 0 'tsize udtenext(i3) = i2 i3 = i2 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "$_LOCK_OFFSET" udtecname(i2) = "$_LOCK_OFFSET" udtebytealign(i2) = 1 udtetype(i2) = OFFSETTYPE: udtesize(i2) = ptrsz * 8 udtetypesize(i2) = 0 'tsize udtenext(i3) = i2 i3 = i2 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "TYPE" udtecname(i2) = "TYPE" udtebytealign(i2) = 1 udtetype(i2) = OFFSETTYPE: udtesize(i2) = ptrsz * 8 udtetypesize(i2) = 0 'tsize udtenext(i3) = i2 i3 = i2 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "ELEMENTSIZE" udtecname(i2) = "ELEMENTSIZE" udtebytealign(i2) = 1 udtetype(i2) = OFFSETTYPE: udtesize(i2) = ptrsz * 8 udtetypesize(i2) = 0 'tsize udtenext(i3) = i2 udtenext(i2) = 0 i3 = i2 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "IMAGE" udtecname(i2) = "IMAGE" udtebytealign(i2) = 1 udtetype(i2) = LONGTYPE: udtesize(i2) = 32 udtetypesize(i2) = 0 'tsize udtenext(i3) = i2 udtenext(i2) = 0 i3 = i2 lasttypeelement = lasttypeelement + 1: i2 = lasttypeelement udtename(i2) = "SOUND" udtecname(i2) = "SOUND" udtebytealign(i2) = 1 udtetype(i2) = LONGTYPE: udtesize(i2) = 32 udtetypesize(i2) = 0 'tsize udtenext(i3) = i2 udtenext(i2) = 0 ' Reset all unstable flags FOR i = 1 TO UBOUND(unstableFlags): unstableFlags(i) = 0: NEXT ' Indicates if a MIDI sound font was selected ' ' Captures both the line number and line contents for error reporting later-on ' in the compilation process MidiSoundFontSet = 0 MidiSoundFontLine$ = "" ' If MidiSoundFont$ is blank, then the default is used MidiSoundFont$ = "" 'begin compilation FOR closeall = 1 TO 255: CLOSE closeall: NEXT OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 'relock bh = OpenBuffer%("O", tmpdir$ + "icon.rc") IF Debug THEN CLOSE #9: OPEN tmpdir$ + "debug.txt" FOR APPEND AS #9 IF idemode = 0 THEN qberrorhappened = -1 OPEN sourcefile$ FOR INPUT AS #1 qberrorhappened1: IF qberrorhappened = 1 THEN PRINT PRINT "Cannot locate source file: " + sourcefile$ IF ConsoleMode THEN SYSTEM 1 END 1 ELSE CLOSE #1 END IF qberrorhappened = 0 END IF reginternal IF qb64prefix_set THEN qb64prefix$ = "" 're-add internal keywords without the "_" prefix reginternal f = HASHFLAG_TYPE + HASHFLAG_RESERVED HashAdd "UNSIGNED", f, 0 HashAdd "BIT", f, 0 HashAdd "BYTE", f, 0 HashAdd "INTEGER64", f, 0 HashAdd "OFFSET", f, 0 HashAdd "FLOAT", f, 0 f = HASHFLAG_RESERVED + HASHFLAG_CUSTOMSYNTAX HashAdd "EXPLICIT", f, 0 END IF DIM SHARED GlobTxtBuf: GlobTxtBuf = OpenBuffer%("O", tmpdir$ + "global.txt") defdatahandle = GlobTxtBuf IF iderecompile THEN iderecompile = 0 idepass = 1 'prepass must be done again sendc$ = CHR$(7) 'repass request GOTO sendcommand END IF IF idemode THEN GOTO ideret1 lineinput3load sourcefile$ DO '### STEVE EDIT FOR CONST EXPANSION 10/11/2013 wholeline$ = lineinput3$ IF wholeline$ = CHR$(13) THEN EXIT DO ideprepass: prepassLastLine: IF lastLine <> 0 OR firstLine <> 0 THEN lineBackup$ = wholeline$ 'backup the real line (will be blank when lastline is set) forceIncludeFromRoot$ = "" IF vWatchOn THEN addingvWatch = 1 IF firstLine <> 0 THEN forceIncludeFromRoot$ = "internal\support\vwatch\vwatch.bi" IF lastLine <> 0 THEN forceIncludeFromRoot$ = "internal\support\vwatch\vwatch.bm" ELSE #31C4C4 IF lastLine <> 0 THEN forceIncludeFromRoot$ = "internal\support\vwatch\vwatch_stub.bm" END IF firstLine = 0: lastLine = 0 IF LEN(forceIncludeFromRoot$) THEN GOTO forceInclude_prepass forceIncludeCompleted_prepass: addingvWatch = 0 wholeline$ = lineBackup$ END IF wholestv$ = wholeline$ '### STEVE EDIT FOR CONST EXPANSION 10/11/2013 prepass = 1 layout = "" layoutok = 0 linenumber = linenumber + 1 reallinenumber = reallinenumber + 1 DO UNTIL linenumber < UBOUND(InValidLine) 'color information flag for each line REDIM _PRESERVE InValidLine(UBOUND(InValidLine) + 1000) AS _BYTE LOOP InValidLine(linenumber) = 0 IF LEN(wholeline$) THEN IF UCASE$(_TRIM$(wholeline$)) = "$NOPREFIX" THEN qb64prefix_set_desiredState = 1 IF qb64prefix_set = 0 THEN IF qb64prefix_set_recompileAttempts = 0 THEN qb64prefix_set_recompileAttempts = qb64prefix_set_recompileAttempts + 1 GOTO do_recompile END IF END IF END IF wholeline$ = lineformat(wholeline$) IF Error_Happened THEN GOTO errmes temp$ = LTRIM$(RTRIM$(UCASE$(wholestv$))) IF temp$ = "$COLOR:0" THEN IF qb64prefix_set THEN addmetainclude$ = getfilepath$(COMMAND$(0)) + "internal" + pathsep$ + "support" + pathsep$ + "color" + pathsep$ + "color0_noprefix.bi" ELSE addmetainclude$ = getfilepath$(COMMAND$(0)) + "internal" + pathsep$ + "support" + pathsep$ + "color" + pathsep$ + "color0.bi" END IF GOTO finishedlinepp END IF IF temp$ = "$COLOR:32" THEN IF qb64prefix_set THEN addmetainclude$ = getfilepath$(COMMAND$(0)) + "internal" + pathsep$ + "support" + pathsep$ + "color" + pathsep$ + "color32_noprefix.bi" ELSE addmetainclude$ = getfilepath$(COMMAND$(0)) + "internal" + pathsep$ + "support" + pathsep$ + "color" + pathsep$ + "color32.bi" END IF GOTO finishedlinepp END IF IF temp$ = "$DEBUG" THEN vWatchDesiredState = 1 IF vWatchOn = 0 THEN IF vWatchRecompileAttempts = 0 THEN 'this is the first time a conflict has occurred, so react immediately with a full recompilation using the desired state vWatchRecompileAttempts = vWatchRecompileAttempts + 1 GOTO do_recompile ELSE 'continue compilation to retrieve the final state requested and act on that as required END IF END IF END IF IF LEFT$(temp$, 4) = "$IF " THEN IF RIGHT$(temp$, 5) <> " THEN" THEN a$ = "$IF without THEN": GOTO errmes temp$ = LTRIM$(MID$(temp$, 4)) 'strip off the $IF and extra spaces temp$ = RTRIM$(LEFT$(temp$, LEN(temp$) - 4)) 'and strip off the THEN and extra spaces temp = INSTR(temp$, #FFB100) ExecCounter = ExecCounter + 1 ExecLevel(ExecCounter) = -1 'default to a skip value DefineElse(ExecCounter) = 1 '1 says we have an $IF statement at this level result = EvalPreIF(temp$, a$) IF a$ <> "" THEN GOTO errmes IF result <> 0 THEN ExecLevel(ExecCounter) = ExecLevel(ExecCounter - 1) 'So we inherit the execlevel from above IF ExecLevel(ExecCounter) = 0 THEN DefineElse(ExecCounter) = DefineElse(ExecCounter) OR 4 'Else if used and conditon found END IF GOTO finishedlinepp 'and then we're finished -- and at this point we didn't make a match so we exit with a DONT READ type flag on our code. END IF IF temp$ = "$ELSE" THEN IF DefineElse(ExecCounter) = 0 THEN a$ = "$ELSE without $IF": GOTO errmes IF DefineElse(ExecCounter) AND 2 THEN a$ = "$IF block already has $ELSE statement in it": GOTO errmes DefineElse(ExecCounter) = DefineElse(ExecCounter) OR 2 'set the flag to declare an $ELSE already in this block IF DefineElse(ExecCounter) AND 4 THEN 'If we executed code in a previous IF or ELSE IF statement, we can't do it here ExecLevel(ExecCounter) = -1 'So we inherit the execlevel from above ELSE ExecLevel(ExecCounter) = ExecLevel(ExecCounter - 1) 'If we were processing code before, code after this segment is going to be SKIPPED END IF GOTO finishedlinepp END IF IF LEFT$(temp$, 5) = "$ELSE" THEN 'looking for $ELSE IF temp$ = LTRIM$(MID$(temp$, 6)) IF LEFT$(temp$, 3) = "IF " THEN IF DefineElse(ExecCounter) = 0 THEN a$ = "$ELSE IF without $IF": GOTO errmes IF DefineElse(ExecCounter) AND 2 THEN a$ = "$ELSE IF cannot follow $ELSE": GOTO errmes IF RIGHT$(temp$, 5) <> " THEN" THEN a$ = "$ELSE IF without THEN": GOTO errmes IF DefineElse(ExecCounter) AND 4 THEN 'If we executed code in a previous IF or ELSE IF statement, we can't do it here ExecLevel(ExecCounter) = -1 GOTO finishedlinepp END IF temp$ = LTRIM$(MID$(temp$, 3)) 'strip off the IF and extra spaces temp$ = RTRIM$(LEFT$(temp$, LEN(temp$) - 4)) 'and strip off the THEN and extra spaces result = EvalPreIF(temp$, a$) IF a$ <> "" THEN GOTO errmes IF result <> 0 THEN ExecLevel(ExecCounter) = ExecLevel(ExecCounter - 1) 'So we inherit the execlevel from above IF ExecLevel(ExecCounter) = 0 THEN DefineElse(ExecCounter) = DefineElse(ExecCounter) OR 4 'Else if used and conditon found END IF GOTO finishedlinepp 'and then we're finished -- and at this point we didn't make a match so we exit with a DONT READ type flag on our code. END IF END IF IF temp$ = "$END IF" OR temp$ = "$ENDIF" THEN IF DefineElse(ExecCounter) = 0 THEN a$ = "$END IF without $IF": GOTO errmes DefineElse(ExecCounter) = 0 'We no longer have an $IF block at this level ExecCounter = ExecCounter - 1 GOTO finishedlinepp END IF IF ExecLevel(ExecCounter) THEN DO UNTIL linenumber < UBOUND(InValidLine) REDIM _PRESERVE InValidLine(UBOUND(InValidLine) + 1000) AS _BYTE LOOP InValidLine(linenumber) = -1 GOTO finishedlinepp 'we don't check for anything inside lines that we've marked for skipping END IF IF LEFT$(temp$, 7) = "$ERROR " THEN temp$ = LTRIM$(MID$(temp$, 7)) a$ = "Compilation check failed: " + temp$ GOTO errmes END IF IF LEFT$(temp$, 5) = "$LET " THEN temp$ = LTRIM$(MID$(temp$, 5)) 'simply shorten our string to parse 'For starters, let's make certain that we have 3 elements to deal with temp = INSTR(temp$, #FFB100) #31C4C4 IF temp = 0 THEN a$ = #FFB100: GOTO errmes l$ = RTRIM$(LEFT$(temp$, temp - 1)): r$ = LTRIM$(MID$(temp$, temp + 1)) 'then validate to make certain the left side looks proper IF validname(l$) = 0 THEN a$ = "Invalid flag name": GOTO errmes IF LEFT$(r$, 1) = CHR$(34) THEN r$ = LTRIM$(MID$(r$, 2)) IF RIGHT$(r$, 1) = CHR$(34) THEN r$ = RTRIM$(LEFT$(r$, LEN(r$) - 1)) IF LEFT$(r$, 1) = "-" THEN r1$ = "-" r$ = LTRIM$(MID$(r$, 2)) ELSE r1$ = "" END IF 'then validate to make certain the left side looks proper FOR i = 1 TO LEN(r$) a = ASC(r$, i) SELECT CASE a CASE 32 CASE 46 'periods are fine. r1$ = r1$ + "." CASE IS < 48, IS > 90 a$ = "Invalid value": GOTO errmes CASE ELSE r1$ = r1$ + CHR$(a) END SELECT NEXT r$ = r1$ 'First look to see if we have an existing setting like this and if so, update it FOR i = 8 TO UserDefineCount 'UserDefineCount 1-7 are reserved for automatic OS/BIT detection & version IF UserDefine(0, i) = l$ THEN UserDefine(1, i) = r$: GOTO finishedlinepp NEXT 'Otherwise create a new setting and set the initial value for it UserDefineCount = UserDefineCount + 1 IF UserDefineCount > UBOUND(UserDefine, 2) THEN REDIM _PRESERVE UserDefine(1, UBOUND(UserDefine, 2) + 10) 'Add another 10 elements to the array so it'll expand as the user adds to it END IF UserDefine(0, UserDefineCount) = l$ UserDefine(1, UserDefineCount) = r$ GOTO finishedlinepp END IF ' We check for Unstable flags during the preprocessing step because it ' impacts what valid commands there are in all the other steps IF LEFT$(temp$, 10) = "$UNSTABLE:" THEN token$ = UCASE$(LTRIM$(RTRIM$(MID$(temp$, 11)))) SELECT CASE token$ CASE "MIDI" IF NOT UseMiniaudioBackend THEN a$ = "Midi is not supported with the old OpenAL audio backend." GOTO errmes END IF unstableFlags(UNSTABLE_MIDI) = -1 CASE "HTTP" unstableFlags(UNSTABLE_HTTP) = -1 regUnstableHttp CASE ELSE a$ = "Unrecognized unstable flag " + AddQuotes$(token$) GOTO errmes END SELECT END IF cwholeline$ = wholeline$ wholeline$ = eleucase$(wholeline$) '********REMOVE THIS LINE LATER******** addmetadynamic = 0: addmetastatic = 0 wholelinen = numelements(wholeline$) IF wholelinen THEN wholelinei = 1 'skip line number? e$ = getelement$(wholeline$, 1) IF (ASC(e$) >= 48 AND ASC(e$) <= 59) OR ASC(e$) = 46 THEN wholelinei = 2: GOTO ppskpl 'skip 'POSSIBLE' line label? IF wholelinen >= 2 THEN x2 = INSTR(wholeline$, sp + ":" + sp): x3 = x2 + 2 IF x2 = 0 THEN IF RIGHT$(wholeline$, 2) = sp + ":" THEN x2 = LEN(wholeline$) - 1: x3 = x2 + 1 END IF IF x2 THEN e$ = LEFT$(wholeline$, x2 - 1) IF validlabel(e$) THEN wholeline$ = RIGHT$(wholeline$, LEN(wholeline$) - x3) cwholeline$ = RIGHT$(cwholeline$, LEN(wholeline$) - x3) wholelinen = numelements(wholeline$) GOTO ppskpl END IF 'valid END IF 'includes ":" END IF #31C4C4 ppskpl: IF wholelinei <= wholelinen THEN '---------------------------------------- a$ = "" ca$ = "" ppblda: e$ = getelement$(wholeline$, wholelinei) ce$ = getelement$(cwholeline$, wholelinei) IF e$ = ":" OR e$ = "ELSE" OR e$ = "THEN" OR e$ = "" THEN IF LEN(a$) THEN IF Debug THEN PRINT #9, "PP[" + a$ + "]" n = numelements(a$) firstelement$ = getelement(a$, 1) secondelement$ = getelement(a$, 2) thirdelement$ = getelement(a$, 3) #31C4C4 IF n = 2 AND firstelement$ = "END" AND (secondelement$ = "SUB" OR secondelement$ = "FUNCTION") THEN closedsubfunc = -1 END IF 'declare library IF declaringlibrary THEN IF firstelement$ = "END" THEN IF n <> 2 OR secondelement$ <> "DECLARE" THEN a$ = "Expected END DECLARE": GOTO errmes declaringlibrary = 0 GOTO finishedlinepp END IF 'end declare declaringlibrary = 2 IF firstelement$ = "SUB" OR firstelement$ = "FUNCTION" THEN subfuncn = subfuncn - 1: GOTO declaresubfunc a$ = "Expected SUB/FUNCTION definition or END DECLARE (#2)": GOTO errmes END IF 'UDT TYPE definition IF definingtype THEN i = definingtype IF n >= 1 THEN IF firstelement$ = "END" THEN IF n <> 2 OR secondelement$ <> "TYPE" THEN a$ = "Expected END TYPE": GOTO errmes IF udtxnext(i) = 0 THEN a$ = "No elements defined in TYPE": GOTO errmes definingtype = 0 'create global buffer for SWAP space siz$ = str2$(udtxsize(i) \ 8) WriteBufLine GlobTxtBuf, "char *g_tmp_udt_" + RTRIM$(udtxname(i)) + #FFB100 + siz$ + ");" 'print "END TYPE";udtxsize(i);udtxbytealign(i) GOTO finishedlinepp END IF END IF IF n < 3 THEN a$ = "Expected element-name AS type, AS type element-list, or END TYPE": GOTO errmes n$ = firstelement$ IF n$ <> "AS" THEN 'traditional variable-name AS type syntax, single-element lasttypeelement = lasttypeelement + 1 i2 = lasttypeelement WHILE i2 > UBOUND(udtenext): increaseUDTArrays: WEND udtenext(i2) = 0 ii = 2 udtearrayelements(i2) = 0 IF ii >= n OR getelement$(a$, ii) <> "AS" THEN a$ = "Expected element-name AS type, AS type element-list, or END TYPE": GOTO errmes t$ = getelements$(a$, ii + 1, n) IF t$ = RTRIM$(udtxname(definingtype)) THEN a$ = "Invalid self-reference": GOTO errmes typ = typname2typ(t$) IF Error_Happened THEN GOTO errmes IF typ = 0 THEN a$ = "Undefined type": GOTO errmes typsize = typname2typsize IF validname(n$) = 0 THEN a$ = "Invalid name": GOTO errmes udtename(i2) = n$ udtecname(i2) = getelement$(ca$, 1) NormalTypeBlock: typeDefinitions$ = typeDefinitions$ + MKL$(i2) + MKL$(LEN(n$)) + n$ udtetype(i2) = typ udtetypesize(i2) = typsize hashname$ = n$ 'check for name conflicts (any similar reserved or element from current UDT) hashchkflags = HASHFLAG_RESERVED + HASHFLAG_UDTELEMENT hashres = HashFind(hashname$, hashchkflags, hashresflags, hashresref) DO WHILE hashres IF hashresflags AND HASHFLAG_UDTELEMENT THEN IF hashresref = i THEN a$ = "Name already in use (" + hashname$ + ")": GOTO errmes END IF IF hashresflags AND HASHFLAG_RESERVED THEN IF hashresflags AND (HASHFLAG_TYPE + HASHFLAG_CUSTOMSYNTAX + HASHFLAG_OPERATOR + HASHFLAG_XELEMENTNAME) THEN a$ = "Name already in use (" + hashname$ + ")": GOTO errmes END IF IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP 'add to hash table HashAdd hashname$, HASHFLAG_UDTELEMENT, i 'Calculate element's size IF typ AND ISUDT THEN u = typ AND 511 udtesize(i2) = udtxsize(u) IF udtxbytealign(u) THEN udtxbytealign(i) = 1: udtebytealign(i2) = 1 IF udtxvariable(u) THEN udtxvariable(i) = -1 ELSE IF (typ AND ISSTRING) THEN IF (typ AND ISFIXEDLENGTH) = 0 THEN udtesize(i2) = OFFSETTYPE AND 511 udtxvariable(i) = -1 ELSE udtesize(i2) = typsize * 8 END IF udtxbytealign(i) = 1: udtebytealign(i2) = 1 ELSE udtesize(i2) = typ AND 511 IF (typ AND ISOFFSETINBITS) = 0 THEN udtxbytealign(i) = 1: udtebytealign(i2) = 1 END IF END IF 'Increase block size IF udtebytealign(i2) THEN IF udtxsize(i) MOD 8 THEN udtxsize(i) = udtxsize(i) + (8 - (udtxsize(i) MOD 8)) END IF END IF udtxsize(i) = udtxsize(i) + udtesize(i2) 'Link element to previous element IF udtxnext(i) = 0 THEN udtxnext(i) = i2 ELSE udtenext(i2 - 1) = i2 END IF 'print "+"+rtrim$(udtename(i2));udtetype(i2);udtesize(i2);udtebytealign(i2);udtxsize(i) IF newAsTypeBlockSyntax THEN RETURN GOTO finishedlinepp ELSE 'new AS type variable-list syntax, multiple elements ii = 2 IF ii >= n THEN a$ = "Expected element-name AS type, AS type element-list, or END TYPE": GOTO errmes previousElement$ = "" t$ = "" lastElement$ = "" buildTypeName: lastElement$ = getelement$(a$, ii) IF lastElement$ <> "," AND lastElement$ <> "" THEN n$ = lastElement$ cn$ = getelement$(ca$, ii) IF LEN(previousElement$) THEN t$ = t$ + previousElement$ + " " previousElement$ = n$ lastElement$ = "" ii = ii + 1 GOTO buildTypeName END IF t$ = RTRIM$(t$) IF t$ = RTRIM$(udtxname(definingtype)) THEN a$ = "Invalid self-reference": GOTO errmes typ = typname2typ(t$) IF Error_Happened THEN GOTO errmes IF typ = 0 THEN a$ = "Undefined type": GOTO errmes typsize = typname2typsize previousElement$ = lastElement$ nexttypeelement: lasttypeelement = lasttypeelement + 1 i2 = lasttypeelement WHILE i2 > UBOUND(udtenext): increaseUDTArrays: WEND udtenext(i2) = 0 udtearrayelements(i2) = 0 udtename(i2) = n$ udtecname(i2) = cn$ IF validname(n$) = 0 THEN a$ = "Invalid name": GOTO errmes newAsTypeBlockSyntax = -1 GOSUB NormalTypeBlock newAsTypeBlockSyntax = 0 getNextElement: ii = ii + 1 lastElement$ = getelement$(a$, ii) IF lastElement$ = "" THEN GOTO finishedlinepp IF ii = n AND lastElement$ = "," THEN a$ = "Expected element-name": GOTO errmes IF lastElement$ = "," THEN IF previousElement$ = "," THEN a$ = "Expected element-name": GOTO errmes previousElement$ = lastElement$ GOTO getNextElement END IF n$ = lastElement$ IF previousElement$ <> "," THEN a$ = "Expected ,": GOTO errmes previousElement$ = lastElement$ cn$ = getelement$(ca$, ii) GOTO nexttypeelement END IF END IF 'definingtype IF definingtype AND n >= 1 THEN a$ = "Expected END TYPE": GOTO errmes IF n >= 1 THEN IF firstelement$ = "TYPE" THEN IF n <> 2 THEN a$ = "Expected TYPE typename": GOTO errmes lasttype = lasttype + 1 typeDefinitions$ = typeDefinitions$ + MKL$(-1) + MKL$(lasttype) definingtype = lasttype i = definingtype WHILE i > UBOUND(udtenext): increaseUDTArrays: WEND IF validname(secondelement$) = 0 THEN a$ = "Invalid name": GOTO errmes typeDefinitions$ = typeDefinitions$ + MKL$(LEN(secondelement$)) + secondelement$ udtxname(i) = secondelement$ udtxcname(i) = getelement(ca$, 2) udtxnext(i) = 0 udtxsize(i) = 0 udtxvariable(i) = 0 hashname$ = secondelement$ hashflags = HASHFLAG_UDT 'check for name conflicts (any similar reserved/sub/function/UDT name) hashchkflags = HASHFLAG_RESERVED + HASHFLAG_SUB + HASHFLAG_FUNCTION + HASHFLAG_UDT hashres = HashFind(hashname$, hashchkflags, hashresflags, hashresref) DO WHILE hashres allow = 0 IF hashresflags AND (HASHFLAG_SUB + HASHFLAG_FUNCTION) THEN allow = 1 END IF IF hashresflags AND HASHFLAG_RESERVED THEN IF (hashresflags AND (HASHFLAG_TYPE + HASHFLAG_OPERATOR + HASHFLAG_CUSTOMSYNTAX + HASHFLAG_XTYPENAME)) = 0 THEN allow = 1 END IF IF allow = 0 THEN a$ = "Name already in use (" + hashname$ + ")": GOTO errmes IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP 'add to hash table HashAdd hashname$, hashflags, i GOTO finishedlinepp END IF END IF IF n >= 1 AND firstelement$ = "CONST" THEN #31C4C4 'DEF... do not change type, the expression is stored in a suitable type 'based on its value if type isn't forced/specified IF subfuncn > 0 AND closedsubfunc <> 0 THEN a$ = "Statement cannot be placed between SUB/FUNCTIONs": GOTO errmes 'convert periods to _046_ i2 = INSTR(a$, sp + "." + sp) IF i2 THEN DO a$ = LEFT$(a$, i2 - 1) + fix046$ + RIGHT$(a$, LEN(a$) - i2 - 2) ca$ = LEFT$(ca$, i2 - 1) + fix046$ + RIGHT$(ca$, LEN(ca$) - i2 - 2) i2 = INSTR(a$, sp + "." + sp) LOOP UNTIL i2 = 0 n = numelements(a$) firstelement$ = getelement(a$, 1): secondelement$ = getelement(a$, 2): thirdelement$ = getelement(a$, 3) END IF IF n < 3 THEN a$ = #FFB100: GOTO errmes i = 2 constdefpendingpp: pending = 0 n$ = getelement$(ca$, i): i = i + 1 typeoverride = 0 s$ = removesymbol$(n$) IF Error_Happened THEN GOTO errmes IF s$ <> "" THEN typeoverride = typname2typ(s$) IF Error_Happened THEN GOTO errmes IF typeoverride AND ISFIXEDLENGTH THEN a$ = "Invalid constant type": GOTO errmes IF typeoverride = 0 THEN a$ = "Invalid constant type": GOTO errmes END IF IF getelement$(a$, i) <> #FFB100 THEN a$ = #FFB100: GOTO errmes i = i + 1 'get expression e$ = "" readable_e$ = "" B = 0 FOR i2 = i TO n e2$ = getelement$(ca$, i2) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF e2$ = "," AND B = 0 THEN pending = 1 i = i2 + 1 IF i > n - 2 THEN a$ = #FFB100: GOTO errmes EXIT FOR END IF IF LEN(e$) = 0 THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ e3$ = e2$ IF LEN(e2$) > 1 THEN IF ASC(e2$, 1) = 34 THEN removeComma = _INSTRREV(e2$, ",") e3$ = LEFT$(e2$, removeComma - 1) ELSE removeComma = INSTR(e2$, ",") e3$ = MID$(e2$, removeComma + 1) END IF END IF IF LEN(readable_e$) = 0 THEN readable_e$ = e3$ ELSE readable_e$ = readable_e$ + " " + e3$ END IF NEXT 'intercept current expression and pass it through Evaluate_Expression$ '(unless it is a literal string) IF LEFT$(readable_e$, 1) <> CHR$(34) THEN temp1$ = _TRIM$(Evaluate_Expression$(readable_e$)) IF LEFT$(temp1$, 5) <> "ERROR" AND e$ <> temp1$ THEN e$ = lineformat(temp1$) 'retrieve parseable format ELSE IF temp1$ = "ERROR - Division By Zero" THEN a$ = temp1$: GOTO errmes IF INSTR(temp1$, "Improper operations") THEN a$ = "Invalid CONST expression.14": GOTO errmes END IF END IF END IF 'Proceed as usual e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes e$ = evaluateconst(e$, t) IF Error_Happened THEN GOTO errmes IF t AND ISSTRING THEN 'string type IF typeoverride THEN IF (typeoverride AND ISSTRING) = 0 THEN a$ = "Type mismatch": GOTO errmes END IF ELSE 'not a string type IF typeoverride THEN IF typeoverride AND ISSTRING THEN a$ = "Type mismatch": GOTO errmes END IF IF t AND ISFLOAT THEN constval## = _CV(_FLOAT, e$) constval&& = constval## constval~&& = constval&& ELSE IF (t AND ISUNSIGNED) AND (t AND 511) = 64 THEN constval~&& = _CV(_UNSIGNED _INTEGER64, e$) constval&& = constval~&& constval## = constval&& ELSE constval&& = _CV(_INTEGER64, e$) constval## = constval&& constval~&& = constval&& END IF END IF 'override type? IF typeoverride THEN 'range check required here (noted in todo) t = typeoverride END IF END IF 'not a string type constlast = constlast + 1 IF constlast > constmax THEN constmax = constmax * 2 REDIM _PRESERVE constname(constmax) AS STRING REDIM _PRESERVE constcname(constmax) AS STRING REDIM _PRESERVE constnamesymbol(constmax) AS STRING 'optional name symbol REDIM _PRESERVE consttype(constmax) AS LONG 'variable type number REDIM _PRESERVE constinteger(constmax) AS _INTEGER64 REDIM _PRESERVE constuinteger(constmax) AS _UNSIGNED _INTEGER64 REDIM _PRESERVE constfloat(constmax) AS _FLOAT REDIM _PRESERVE conststring(constmax) AS STRING REDIM _PRESERVE constsubfunc(constmax) AS LONG REDIM _PRESERVE constdefined(constmax) AS LONG END IF i2 = constlast constsubfunc(i2) = subfuncn #31C4C4 IF validname(n$) = 0 THEN a$ = "Invalid name": GOTO errmes constname(i2) = UCASE$(n$) hashname$ = n$ 'check for name conflicts (any similar: reserved, sub, function, constant) allow = 0 const_recheck: hashchkflags = HASHFLAG_RESERVED + HASHFLAG_SUB + HASHFLAG_FUNCTION + HASHFLAG_CONSTANT hashres = HashFind(hashname$, hashchkflags, hashresflags, hashresref) DO WHILE hashres IF hashresflags AND HASHFLAG_CONSTANT THEN IF constsubfunc(hashresref) = subfuncn THEN 'If merely redefining a CONST with same value 'just issue a warning instead of an error issueWarning = 0 IF t AND ISSTRING THEN IF conststring(hashresref) = e$ THEN issueWarning = -1: thisconstval$ = e$ ELSE IF t AND ISFLOAT THEN IF constfloat(hashresref) = constval## THEN issueWarning = -1: thisconstval$ = STR$(constval##) ELSE IF t AND ISUNSIGNED THEN IF constuinteger(hashresref) = constval~&& THEN issueWarning = -1: thisconstval$ = STR$(constval~&&) ELSE IF constinteger(hashresref) = constval&& THEN issueWarning = -1: thisconstval$ = STR$(constval&&) END IF END IF END IF IF issueWarning THEN IF NOT IgnoreWarnings THEN addWarning linenumber, inclevel, inclinenumber(inclevel), incname$(inclevel), "duplicate constant definition", n$ + #FFB100 + thisconstval$ END IF GOTO constAddDone ELSE a$ = "Name already in use (" + hashname$ + ")": GOTO errmes END IF END IF END IF IF hashresflags AND HASHFLAG_RESERVED THEN a$ = "Name already in use (" + hashname$ + ")": GOTO errmes END IF IF hashresflags AND (HASHFLAG_SUB + HASHFLAG_FUNCTION) THEN IF ids(hashresref).internal_subfunc = 0 OR RTRIM$(ids(hashresref).musthave) <> "$" THEN a$ = "Name already in use (" + hashname$ + ")": GOTO errmes IF t AND ISSTRING THEN a$ = "Name already in use (" + hashname$ + ")": GOTO errmes END IF IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP 'add to hash table HashAdd hashname$, HASHFLAG_CONSTANT, i2 |