$CONSOLE $SCREENHIDE '### STEVE WAS HERE 10/11/2013 ### $RESIZE:ON '### STEVE WAS HERE 10/17/2013 ### REDIM SHARED OName(0) AS STRING 'Operation Name REDIM SHARED PL(0) AS INTEGER 'Priority Level REDIM SHARED vars(26) AS STRING ' 0 is previous answer, 1 - 26 is A - Z DIM SHARED FileName AS STRING, DirName AS STRING DIM SHARED QuickReturn AS INTEGER DirName = "internal/MathEval/" FileName = "internal/MathEval/Math Evaluator User Variables.bin" Set_OrderOfOperations 'This will also make certain our directories are valid, and if not make them. '### END OF STEVE EDIT '$DYNAMIC DEFLNG A-Z DIM SHARED MakeAndroid 'build an Android project (refer to SUB UseAndroid) DIM SHARED AllowUpdates DIM SHARED IDEBuildModeChanged 'refactor patch DIM SHARED Refactor_Source AS STRING DIM SHARED Refactor_Dest AS STRING IF _FILEEXISTS("refactor.txt") THEN fh = FREEFILE OPEN "refactor.txt" FOR INPUT AS #fh LINE INPUT #fh, Refactor_Source LINE INPUT #fh, Refactor_Dest CLOSE fh END IF IF _DIREXISTS("internal") = 0 THEN _SCREENSHOW PRINT "QB64 cannot locate the 'internal' folder" PRINT PRINT "Check that QB64 has been extracted properly." PRINT "For MacOSX, launch 'qb64_start.command' or enter './qb64' in Terminal." PRINT "For Linux, in the console enter './qb64'." DO _LIMIT 1 LOOP UNTIL INKEY$ <> "" SYSTEM 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 DIM SHARED DEPENDENCY(1 TO DEPENDENCY_LAST) DIM SHARED UseGL 'declared SUB _GL (no params) DIM SHARED Version AS STRING DIM SHARED C_Core AS LONG '0=SDL, 1=GLUT+OpenGL DIM SHARED Debug AS LONG 'debug logging is off by default Version$ = "0.980": Debug = 0: C_Core = 1 _TITLE "QB64" '----------------ripgl.bas-------------------------------------------------------------------------------- TYPE GL_idstruct cn AS STRING * 64 'case sensitive version of n subfunc AS INTEGER 'if function=1, sub=2 callname AS STRING * 64 args AS INTEGER arg AS STRING * 80 'similar to t ret AS LONG 'the value it returns if it is a function (again like t) END TYPE REDIM SHARED GL_COMMANDS(2000) AS GL_idstruct DIM SHARED GL_HELPER_CODE AS STRING DIM SHARED GL_COMMANDS_LAST REDIM SHARED GL_DEFINES(2000) AS STRING 'average ~600 entries REDIM SHARED GL_DEFINES_VALUE(2000) AS _INTEGER64 DIM SHARED GL_DEFINES_LAST DIM SHARED GL_KIT: GL_KIT = 0 '----------------ripgl.bas-------------------------------------------------------------------------------- DIM SHARED Cloud 'set by the -q switch for building a restricted QB64 QLOUD app Cloud = 0 DIM SHARED OS_BITS AS LONG OS_BITS = 64: IF INSTR(_OS$, "[32BIT]") THEN OS_BITS = 32 DIM SHARED command2$ command2$ = COMMAND$ DIM SHARED ConsoleMode DIM SHARED No_C_Compile_Mode a$ = LTRIM$(RTRIM$(command2$)) a2$ = LCASE$(LEFT$(a$, 2)) IF a2$ = "-q" THEN command2$ = "-x" + RIGHT$(a$, LEN(a$) - 2): Cloud = 1: a2$ = "-x" IF a2$ = "-z" THEN command2$ = "-c" + RIGHT$(a$, LEN(a$) - 2): No_C_Compile_Mode = 1: ConsoleMode = 1 IF a2$ = "-x" THEN command2$ = "-c" + RIGHT$(a$, LEN(a$) - 2): ConsoleMode = 1 IF ConsoleMode THEN _DEST _CONSOLE ELSE _CONSOLE OFF _SCREENSHOW _ICON END IF DIM SHARED NoChecks DIM SHARED Console DIM SHARED ScreenHide DIM SHARED OptMax AS LONG OptMax = 256 REDIM SHARED Opt(1 TO OptMax, 1 TO 10) AS STRING * 256 ' (1,1)="READ" ' (1,2)="WRITE" ' (1,3)="READ WRITE" REDIM SHARED OptWords(1 TO OptMax, 1 TO 10) AS INTEGER 'The number of words of each opt () element ' (1,1)=1 '"READ" ' (1,2)=1 '"WRITE" ' (1,3)=2 '"READ WRITE" 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 _CONTROLCHR OFF DIM SHARED IdeInfo AS STRING 'QB64 Help DIM SHARED Cache_Folder AS STRING Cache_Folder$ = "internal\help" IF _DIREXISTS(Cache_Folder$) = 0 THEN MKDIR Cache_Folder$ DIM SHARED Help_sx, Help_sy, Help_cx, Help_cy DIM SHARED Help_Select, Help_cx1, Help_cy1, Help_SelX1, Help_SelX2, Help_SelY1, Help_SelY2 DIM SHARED Help_MSelect Help_sx = 1: Help_sy = 1: Help_cx = 1: Help_cy = 1 DIM SHARED Help_wx1, Help_wy1, Help_wx2, Help_wy2 'defines the text section of the help window on-screen DIM SHARED Help_ww, Help_wh 'width & height of text region DIM SHARED help_h, help_w 'width & height DIM SHARED Help_Txt$ '[chr][col][link-byte1][link-byte2] DIM SHARED Help_Txt_Len DIM SHARED Help_Line$ 'index of first txt element of a line DIM SHARED Help_Link$ 'the link info [sep][type:]...[sep] DIM SHARED Help_Link_Sep$: Help_Link_Sep$ = CHR$(13) DIM SHARED Help_LinkN DIM SHARED Help_NewLineIndent DIM SHARED Help_Underline 'Link Types: ' PAGE:wikipagename DIM SHARED Help_Pos, Help_Wrap_Pos DIM SHARED Help_BG_Col DIM SHARED Help_Col_Normal: Help_Col_Normal = 7 DIM SHARED Help_Col_Link: Help_Col_Link = 9 DIM SHARED Help_Col_Bold: Help_Col_Bold = 15 DIM SHARED Help_Col_Italic: Help_Col_Italic = 15 DIM SHARED Help_Col_Section: Help_Col_Section = 8 DIM SHARED Help_Bold, Help_Italic DIM SHARED Help_LockWrap REDIM SHARED Help_LineLen(1) REDIM SHARED Back$(1) REDIM SHARED Back_Name$(1) TYPE Help_Back_Type sx AS LONG sy AS LONG cx AS LONG cy AS LONG END TYPE REDIM SHARED Help_Back(1) AS Help_Back_Type Back$(1) = "QB64 Help Menu" Back_Name$(1) = Back2BackName$(Back$(1)) Help_Back(1).sx = 1: Help_Back(1).sy = 1: Help_Back(1).cx = 1: Help_Back(1).cy = 1 DIM SHARED Help_Back_Pos Help_Back_Pos = 1 DIM SHARED Help_Search_Time AS DOUBLE DIM SHARED Help_Search_Str AS STRING DIM SHARED Help_PageLoaded AS STRING DIM SHARED Help_Recaching, Help_IgnoreCache DIM SHARED E DIM SHARED IdeSystem AS LONG '1=Entering text into the main IDE window '2=Entering text into the quick search bar '3=Scrolling within the help window IdeSystem = 1 DIM SHARED IdeRecentLink(1 TO 4, 1 TO 2) AS STRING DIM SHARED IdeOpenFile AS STRING 'makes IdeOpen directly open the file passed TYPE IdeBmkType y AS LONG 'the vertical line x AS LONG 'the horizontal position to move cursor to reserved AS LONG reserved2 AS LONG END TYPE REDIM SHARED IdeBmk(1) AS IdeBmkType DIM SHARED IdeBmkN 'GetInput global variables DIM SHARED iCHECKLATER 'the values will be checked later DIM SHARED iCHANGED DIM SHARED mX, mY DIM SHARED mB, mB2 DIM SHARED mOB, mOB2 DIM SHARED mCLICK, mCLICK2 DIM SHARED mRELEASE, mRELEASE2 DIM SHARED mWHEEL DIM SHARED KB '_KEYHIT value (or 0) DIM SHARED K$ 'INKEY$ equivalent of _KEYHIT's return (or "") DIM SHARED KSTATECHANGED DIM SHARED KSHIFT DIM SHARED KCTRL 'the control key DIM SHARED KCONTROL 'PC-CTRL or MAC-APPLE KEY DIM SHARED KALT, KOALT, KALTPRESS, KALTRELEASE CONST ASC_BACKSLASH = 92 CONST ASC_FORWARDSLASH = 47 CONST ASC_LEFTBRACKET = 40 CONST ASC_RIGHTBRACKET = 41 CONST ASC_FULLSTOP = 46 CONST ASC_COLON = 58 CONST ASC_SEMICOLON = 59 CONST ASC_UNDERSCORE = 95 CONST ASC_QUOTE = 34 CONST ASC_LEFTSQUAREBRACKET = 91 CONST ASC_RIGHTSQUAREBRACKET = 93 CONST ASC_QUESTIONMARK = 63 DIM SHARED CHR_QUOTE AS STRING: CHR_QUOTE = CHR$(34) CONST KEY_LSHIFT = 100304 CONST KEY_RSHIFT = 100303 CONST KEY_LCTRL = 100306 CONST KEY_RCTRL = 100305 CONST KEY_LALT = 100308 CONST KEY_RALT = 100307 CONST KEY_LAPPLE = 100310 CONST KEY_RAPPLE = 100309 CONST KEY_F1 = 15104 CONST KEY_F2 = 15360 CONST KEY_F3 = 15616 CONST KEY_F4 = 15872 CONST KEY_F5 = 16128 CONST KEY_F6 = 16384 CONST KEY_F7 = 16640 CONST KEY_F8 = 16896 CONST KEY_F9 = 17152 CONST KEY_F10 = 17408 CONST KEY_F11 = 34048 CONST KEY_F12 = 34304 CONST KEY_INSERT = 20992 CONST KEY_DELETE = 21248 CONST KEY_HOME = 18176 CONST KEY_END = 20224 CONST KEY_PAGEUP = 18688 CONST KEY_PAGEDOWN = 20736 CONST KEY_LEFT = 19200 CONST KEY_RIGHT = 19712 CONST KEY_UP = 18432 CONST KEY_DOWN = 20480 CONST KEY_ESC = 27 CONST KEY_ENTER = 13 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 sp AS STRING * 1, sp2 AS STRING * 1, sp3 AS STRING * 1 sp = CHR$(13): sp2 = CHR$(10): sp3 = CHR$(26) DIM SHARED sp_asc AS LONG, sp2_asc AS LONG, sp3_asc AS LONG sp_asc = ASC(sp): sp2_asc = ASC(sp2): sp3_asc = ASC(sp3) IF Debug THEN sp = CHR$(250): sp2 = CHR$(249): sp3 = "³" 'makes debug output more readable 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 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/" DIM SHARED tempfolderindex 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 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 '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 INPUT 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 block_chr(255) AS INTEGER block_chr(10) = 1 block_chr(13) = 1 DIM SHARED crlf AS STRING crlf = CHR$(13) + CHR$(10) DIM SHARED chr_tab AS STRING chr_tab = CHR$(9) 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 'setup optional codepages DIM SHARED idecpindex CONST idecpnum& = 27 DIM SHARED idecpname(1 TO idecpnum) AS STRING DIM SHARED idecp(1 TO idecpnum) AS STRING ' idecpname$(1) = "micsft_pc_cp437" idecp$(1) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000E4000000E0000000E5000000E7000000EA000000EB000000E8000000EF000000EE000000EC000000C4000000C5000000C9000000E6000000C6000000F4000000F6000000F2000000FB000000F9000000FF000000D6000000DC000000A2000000A3000000A5000020A700000192000000E1000000ED000000F3000000FA000000F1000000D1000000AA000000BA000000BF00002310000000AC000000BD000000BC000000A1000000AB000000BB0000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000003B1000000DF00000393000003C0000003A3000003C3000000B5000003C4000003A600000398000003A9000003B40000221E000003C6000003B50000222900002261000000B100002265000022640000232000002321000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" idecpname$(2) = "micsft_pc_cp737" idecp$(2) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F0000039100000392000003930000039400000395000003960000039700000398000003990000039A0000039B0000039C0000039D0000039E0000039F000003A0000003A1000003A3000003A4000003A5000003A6000003A7000003A8000003A9000003B1000003B2000003B3000003B4000003B5000003B6000003B7000003B8000003B9000003BA000003BB000003BC000003BD000003BE000003BF000003C0000003C1000003C3000003C2000003C4000003C5000003C6000003C7000003C80000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000003C9000003AC000003AD000003AE000003CA000003AF000003CC000003CD000003CB000003CE0000038600000388000003890000038A0000038C0000038E0000038F000000B10000226500002264000003AA000003AB000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" idecpname$(3) = "micsft_pc_cp775" idecp$(3) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F00000106000000FC000000E900000101000000E400000123000000E500000107000001420000011300000156000001570000012B00000179000000C4000000C5000000C9000000E6000000C60000014D000000F600000122000000A20000015A0000015B000000D6000000DC000000F8000000A3000000D8000000D7000000A4000001000000012A000000F30000017B0000017C0000017A0000201D000000A6000000A9000000AE000000AC000000BD000000BC00000141000000AB000000BB0000259100002592000025930000250200002524000001040000010C00000118000001160000256300002551000025570000255D0000012E000001600000251000002514000025340000252C0000251C000025000000253C000001720000016A0000255A00002554000025690000256600002560000025500000256C0000017D000001050000010D00000119000001170000012F00000161000001730000016B0000017E000025180000250C00002588000025840000258C0000259000002580000000D3000000DF0000014C00000143000000F5000000D5000000B50000014400000136000001370000013B0000013C00000146000001120000014500002019000000AD000000B10000201C000000BE000000B6000000A7000000F70000201E000000B000002219000000B7000000B9000000B3000000B2000025A0000000A0" idecpname$(4) = "micsft_pc_cp850" idecp$(4) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000E4000000E0000000E5000000E7000000EA000000EB000000E8000000EF000000EE000000EC000000C4000000C5000000C9000000E6000000C6000000F4000000F6000000F2000000FB000000F9000000FF000000D6000000DC000000F8000000A3000000D8000000D700000192000000E1000000ED000000F3000000FA000000F1000000D1000000AA000000BA000000BF000000AE000000AC000000BD000000BC000000A1000000AB000000BB0000259100002592000025930000250200002524000000C1000000C2000000C0000000A90000256300002551000025570000255D000000A2000000A50000251000002514000025340000252C0000251C000025000000253C000000E3000000C30000255A00002554000025690000256600002560000025500000256C000000A4000000F0000000D0000000CA000000CB000000C800000131000000CD000000CE000000CF000025180000250C0000258800002584000000A6000000CC00002580000000D3000000DF000000D4000000D2000000F5000000D5000000B5000000FE000000DE000000DA000000DB000000D9000000FD000000DD000000AF000000B4000000AD000000B100002017000000BE000000B6000000A7000000F7000000B8000000B0000000A8000000B7000000B9000000B3000000B2000025A0000000A0" idecpname$(5) = "micsft_pc_cp852" idecp$(5) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000E40000016F00000107000000E700000142000000EB0000015000000151000000EE00000179000000C400000106000000C9000001390000013A000000F4000000F60000013D0000013E0000015A0000015B000000D6000000DC000001640000016500000141000000D70000010D000000E1000000ED000000F3000000FA00000104000001050000017D0000017E0000011800000119000000AC0000017A0000010C0000015F000000AB000000BB0000259100002592000025930000250200002524000000C1000000C20000011A0000015E0000256300002551000025570000255D0000017B0000017C0000251000002514000025340000252C0000251C000025000000253C00000102000001030000255A00002554000025690000256600002560000025500000256C000000A400000111000001100000010E000000CB0000010F00000147000000CD000000CE0000011B000025180000250C0000258800002584000001620000016E00002580000000D3000000DF000000D4000001430000014400000148000001600000016100000154000000DA0000015500000170000000FD000000DD00000163000000B4000000AD000002DD000002DB000002C7000002D8000000A7000000F7000000B8000000B0000000A8000002D9000001710000015800000159000025A0000000A0" idecpname$(6) = "micsft_pc_cp855" idecp$(6) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F0000045200000402000004530000040300000451000004010000045400000404000004550000040500000456000004060000045700000407000004580000040800000459000004090000045A0000040A0000045B0000040B0000045C0000040C0000045E0000040E0000045F0000040F0000044E0000042E0000044A0000042A0000043000000410000004310000041100000446000004260000043400000414000004350000041500000444000004240000043300000413000000AB000000BB0000259100002592000025930000250200002524000004450000042500000438000004180000256300002551000025570000255D00000439000004190000251000002514000025340000252C0000251C000025000000253C0000043A0000041A0000255A00002554000025690000256600002560000025500000256C000000A40000043B0000041B0000043C0000041C0000043D0000041D0000043E0000041E0000043F000025180000250C00002588000025840000041F0000044F000025800000042F0000044000000420000004410000042100000442000004220000044300000423000004360000041600000432000004120000044C0000042C00002116000000AD0000044B0000042B000004370000041700000448000004280000044D0000042D00000449000004290000044700000427000000A7000025A0000000A0" idecpname$(7) = "micsft_pc_cp857" idecp$(7) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000E4000000E0000000E5000000E7000000EA000000EB000000E8000000EF000000EE00000131000000C4000000C5000000C9000000E6000000C6000000F4000000F6000000F2000000FB000000F900000130000000D6000000DC000000F8000000A3000000D80000015E0000015F000000E1000000ED000000F3000000FA000000F1000000D10000011E0000011F000000BF000000AE000000AC000000BD000000BC000000A1000000AB000000BB0000259100002592000025930000250200002524000000C1000000C2000000C0000000A90000256300002551000025570000255D000000A2000000A50000251000002514000025340000252C0000251C000025000000253C000000E3000000C30000255A00002554000025690000256600002560000025500000256C000000A4000000BA000000AA000000CA000000CB000000C800000000000000CD000000CE000000CF000025180000250C0000258800002584000000A6000000CC00002580000000D3000000DF000000D4000000D2000000F5000000D5000000B500000000000000D7000000DA000000DB000000D9000000EC000000FF000000AF000000B4000000AD000000B100000000000000BE000000B6000000A7000000F7000000B8000000B0000000A8000000B7000000B9000000B3000000B2000025A0000000A0" idecpname$(8) = "micsft_pc_cp860" idecp$(8) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000E3000000E0000000C1000000E7000000EA000000CA000000E8000000CD000000D4000000EC000000C3000000C2000000C9000000C0000000C8000000F4000000F5000000F2000000DA000000F9000000CC000000D5000000DC000000A2000000A3000000D9000020A7000000D3000000E1000000ED000000F3000000FA000000F1000000D1000000AA000000BA000000BF000000D2000000AC000000BD000000BC000000A1000000AB000000BB0000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000003B1000000DF00000393000003C0000003A3000003C3000000B5000003C4000003A600000398000003A9000003B40000221E000003C6000003B50000222900002261000000B100002265000022640000232000002321000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" idecpname$(9) = "micsft_pc_cp861" idecp$(9) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000E4000000E0000000E5000000E7000000EA000000EB000000E8000000D0000000F0000000DE000000C4000000C5000000C9000000E6000000C6000000F4000000F6000000FE000000FB000000DD000000FD000000D6000000DC000000F8000000A3000000D8000020A700000192000000E1000000ED000000F3000000FA000000C1000000CD000000D3000000DA000000BF00002310000000AC000000BD000000BC000000A1000000AB000000BB0000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000003B1000000DF00000393000003C0000003A3000003C3000000B5000003C4000003A600000398000003A9000003B40000221E000003C6000003B50000222900002261000000B100002265000022640000232000002321000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" idecpname$(10) = "micsft_pc_cp862" idecp$(10) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000005D0000005D1000005D2000005D3000005D4000005D5000005D6000005D7000005D8000005D9000005DA000005DB000005DC000005DD000005DE000005DF000005E0000005E1000005E2000005E3000005E4000005E5000005E6000005E7000005E8000005E9000005EA000000A2000000A3000000A5000020A700000192000000E1000000ED000000F3000000FA000000F1000000D1000000AA000000BA000000BF00002310000000AC000000BD000000BC000000A1000000AB000000BB0000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000003B1000000DF00000393000003C0000003A3000003C3000000B5000003C4000003A600000398000003A9000003B40000221E000003C6000003B50000222900002261000000B100002265000022640000232000002321000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" idecpname$(11) = "micsft_pc_cp863" idecp$(11) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000C2000000E0000000B6000000E7000000EA000000EB000000E8000000EF000000EE00002017000000C0000000A7000000C9000000C8000000CA000000F4000000CB000000CF000000FB000000F9000000A4000000D4000000DC000000A2000000A3000000D9000000DB00000192000000A6000000B4000000F3000000FA000000A8000000B8000000B3000000AF000000CE00002310000000AC000000BD000000BC000000BE000000AB000000BB0000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000003B1000000DF00000393000003C0000003A3000003C3000000B5000003C4000003A600000398000003A9000003B40000221E000003C6000003B50000222900002261000000B100002265000022640000232000002321000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" idecpname$(12) = "micsft_pc_cp864" idecp$(12) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F00000020000000210000002200000023000000240000066A000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000B0000000B7000022190000221A0000259200002500000025020000253C000025240000252C0000251C00002534000025100000250C0000251400002518000003B20000221E000003C6000000B1000000BD000000BC00002248000000AB000000BB0000FEF70000FEF800000000000000000000FEFB0000FEFC00000000000000A0000000AD0000FE82000000A3000000A40000FE8400000000000000000000FE8E0000FE8F0000FE950000FE990000060C0000FE9D0000FEA10000FEA5000006600000066100000662000006630000066400000665000006660000066700000668000006690000FED10000061B0000FEB10000FEB50000FEB90000061F000000A20000FE800000FE810000FE830000FE850000FECA0000FE8B0000FE8D0000FE910000FE930000FE970000FE9B0000FE9F0000FEA30000FEA70000FEA90000FEAB0000FEAD0000FEAF0000FEB30000FEB70000FEBB0000FEBF0000FEC10000FEC50000FECB0000FECF000000A6000000AC000000F7000000D70000FEC9000006400000FED30000FED70000FEDB0000FEDF0000FEE30000FEE70000FEEB0000FEED0000FEEF0000FEF30000FEBD0000FECC0000FECE0000FECD0000FEE10000FE7D000006510000FEE50000FEE90000FEEC0000FEF00000FEF20000FED00000FED50000FEF50000FEF60000FEDD0000FED90000FEF1000025A000000000" idecpname$(13) = "micsft_pc_cp865" idecp$(13) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000000C7000000FC000000E9000000E2000000E4000000E0000000E5000000E7000000EA000000EB000000E8000000EF000000EE000000EC000000C4000000C5000000C9000000E6000000C6000000F4000000F6000000F2000000FB000000F9000000FF000000D6000000DC000000F8000000A3000000D8000020A700000192000000E1000000ED000000F3000000FA000000F1000000D1000000AA000000BA000000BF00002310000000AC000000BD000000BC000000A1000000AB000000A40000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000003B1000000DF00000393000003C0000003A3000003C3000000B5000003C4000003A600000398000003A9000003B40000221E000003C6000003B50000222900002261000000B100002265000022640000232000002321000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" idecpname$(14) = "micsft_pc_cp866" idecp$(14) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000004100000041100000412000004130000041400000415000004160000041700000418000004190000041A0000041B0000041C0000041D0000041E0000041F000004200000042100000422000004230000042400000425000004260000042700000428000004290000042A0000042B0000042C0000042D0000042E0000042F000004300000043100000432000004330000043400000435000004360000043700000438000004390000043A0000043B0000043C0000043D0000043E0000043F0000259100002592000025930000250200002524000025610000256200002556000025550000256300002551000025570000255D0000255C0000255B0000251000002514000025340000252C0000251C000025000000253C0000255E0000255F0000255A00002554000025690000256600002560000025500000256C00002567000025680000256400002565000025590000255800002552000025530000256B0000256A000025180000250C00002588000025840000258C0000259000002580000004400000044100000442000004430000044400000445000004460000044700000448000004490000044A0000044B0000044C0000044D0000044E0000044F0000040100000451000004040000045400000407000004570000040E0000045E000000B000002219000000B70000221A00002116000000A4000025A0000000A0" idecpname$(15) = "micsft_pc_cp869" idecp$(15) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F0000000000000000000000000000000000000000000000000000038600000000000000B7000000AC000000A600002018000020190000038800002015000003890000038A000003AA0000038C00000000000000000000038E000003AB000000A90000038F000000B2000000B3000003AC000000A3000003AD000003AE000003AF000003CA00000390000003CC000003CD00000391000003920000039300000394000003950000039600000397000000BD0000039800000399000000AB000000BB00002591000025920000259300002502000025240000039A0000039B0000039C0000039D0000256300002551000025570000255D0000039E0000039F0000251000002514000025340000252C0000251C000025000000253C000003A0000003A10000255A00002554000025690000256600002560000025500000256C000003A3000003A4000003A5000003A6000003A7000003A8000003A9000003B1000003B2000003B3000025180000250C0000258800002584000003B4000003B500002580000003B6000003B7000003B8000003B9000003BA000003BB000003BC000003BD000003BE000003BF000003C0000003C1000003C3000003C2000003C400000384000000AD000000B1000003C5000003C6000003C7000000A7000003C800000385000000B0000000A8000003C9000003CB000003B0000003CE000025A0000000A0" idecpname$(16) = "micsft_pc_cp874" idecp$(16) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC0000000000000000000000000000000000002026000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002018000020190000201C0000201D0000202200002013000020140000000000000000000000000000000000000000000000000000000000000000000000A000000E0100000E0200000E0300000E0400000E0500000E0600000E0700000E0800000E0900000E0A00000E0B00000E0C00000E0D00000E0E00000E0F00000E1000000E1100000E1200000E1300000E1400000E1500000E1600000E1700000E1800000E1900000E1A00000E1B00000E1C00000E1D00000E1E00000E1F00000E2000000E2100000E2200000E2300000E2400000E2500000E2600000E2700000E2800000E2900000E2A00000E2B00000E2C00000E2D00000E2E00000E2F00000E3000000E3100000E3200000E3300000E3400000E3500000E3600000E3700000E3800000E3900000E3A0000000000000000000000000000000000000E3F00000E4000000E4100000E4200000E4300000E4400000E4500000E4600000E4700000E4800000E4900000E4A00000E4B00000E4C00000E4D00000E4E00000E4F00000E5000000E5100000E5200000E5300000E5400000E5500000E5600000E5700000E5800000E5900000E5A00000E5B00000000000000000000000000000000" idecpname$(17) = "micsft_windows_cp1250" idecp$(17) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC000000000000201A000000000000201E000020260000202000002021000000000000203000000160000020390000015A000001640000017D000001790000000000002018000020190000201C0000201D0000202200002013000020140000000000002122000001610000203A0000015B000001650000017E0000017A000000A0000002C7000002D800000141000000A400000104000000A6000000A7000000A8000000A90000015E000000AB000000AC000000AD000000AE0000017B000000B0000000B1000002DB00000142000000B4000000B5000000B6000000B7000000B8000001050000015F000000BB0000013D000002DD0000013E0000017C00000154000000C1000000C200000102000000C40000013900000106000000C70000010C000000C900000118000000CB0000011A000000CD000000CE0000010E000001100000014300000147000000D3000000D400000150000000D6000000D7000001580000016E000000DA00000170000000DC000000DD00000162000000DF00000155000000E1000000E200000103000000E40000013A00000107000000E70000010D000000E900000119000000EB0000011B000000ED000000EE0000010F000001110000014400000148000000F3000000F400000151000000F6000000F7000001590000016F000000FA00000171000000FC000000FD00000163000002D9" idecpname$(18) = "micsft_windows_cp1251" idecp$(18) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F00000402000004030000201A000004530000201E000020260000202000002021000020AC0000203000000409000020390000040A0000040C0000040B0000040F0000045200002018000020190000201C0000201D0000202200002013000020140000000000002122000004590000203A0000045A0000045C0000045B0000045F000000A00000040E0000045E00000408000000A400000490000000A6000000A700000401000000A900000404000000AB000000AC000000AD000000AE00000407000000B0000000B1000004060000045600000491000000B5000000B6000000B7000004510000211600000454000000BB00000458000004050000045500000457000004100000041100000412000004130000041400000415000004160000041700000418000004190000041A0000041B0000041C0000041D0000041E0000041F000004200000042100000422000004230000042400000425000004260000042700000428000004290000042A0000042B0000042C0000042D0000042E0000042F000004300000043100000432000004330000043400000435000004360000043700000438000004390000043A0000043B0000043C0000043D0000043E0000043F000004400000044100000442000004430000044400000445000004460000044700000448000004490000044A0000044B0000044C0000044D0000044E0000044F" idecpname$(19) = "micsft_windows_cp1252" idecp$(19) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC000000000000201A000001920000201E000020260000202000002021000002C600002030000001600000203900000152000000000000017D000000000000000000002018000020190000201C0000201D000020220000201300002014000002DC00002122000001610000203A00000153000000000000017E00000178000000A0000000A1000000A2000000A3000000A4000000A5000000A6000000A7000000A8000000A9000000AA000000AB000000AC000000AD000000AE000000AF000000B0000000B1000000B2000000B3000000B4000000B5000000B6000000B7000000B8000000B9000000BA000000BB000000BC000000BD000000BE000000BF000000C0000000C1000000C2000000C3000000C4000000C5000000C6000000C7000000C8000000C9000000CA000000CB000000CC000000CD000000CE000000CF000000D0000000D1000000D2000000D3000000D4000000D5000000D6000000D7000000D8000000D9000000DA000000DB000000DC000000DD000000DE000000DF000000E0000000E1000000E2000000E3000000E4000000E5000000E6000000E7000000E8000000E9000000EA000000EB000000EC000000ED000000EE000000EF000000F0000000F1000000F2000000F3000000F4000000F5000000F6000000F7000000F8000000F9000000FA000000FB000000FC000000FD000000FE000000FF" idecpname$(20) = "micsft_windows_cp1253" idecp$(20) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC000000000000201A000001920000201E00002026000020200000202100000000000020300000000000002039000000000000000000000000000000000000000000002018000020190000201C0000201D0000202200002013000020140000000000002122000000000000203A00000000000000000000000000000000000000A00000038500000386000000A3000000A4000000A5000000A6000000A7000000A8000000A900000000000000AB000000AC000000AD000000AE00002015000000B0000000B1000000B2000000B300000384000000B5000000B6000000B700000388000003890000038A000000BB0000038C000000BD0000038E0000038F000003900000039100000392000003930000039400000395000003960000039700000398000003990000039A0000039B0000039C0000039D0000039E0000039F000003A0000003A100000000000003A3000003A4000003A5000003A6000003A7000003A8000003A9000003AA000003AB000003AC000003AD000003AE000003AF000003B0000003B1000003B2000003B3000003B4000003B5000003B6000003B7000003B8000003B9000003BA000003BB000003BC000003BD000003BE000003BF000003C0000003C1000003C2000003C3000003C4000003C5000003C6000003C7000003C8000003C9000003CA000003CB000003CC000003CD000003CE00000000" idecpname$(21) = "micsft_windows_cp1254" idecp$(21) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC000000000000201A000001920000201E000020260000202000002021000002C6000020300000016000002039000001520000000000000000000000000000000000002018000020190000201C0000201D000020220000201300002014000002DC00002122000001610000203A00000153000000000000000000000178000000A0000000A1000000A2000000A3000000A4000000A5000000A6000000A7000000A8000000A9000000AA000000AB000000AC000000AD000000AE000000AF000000B0000000B1000000B2000000B3000000B4000000B5000000B6000000B7000000B8000000B9000000BA000000BB000000BC000000BD000000BE000000BF000000C0000000C1000000C2000000C3000000C4000000C5000000C6000000C7000000C8000000C9000000CA000000CB000000CC000000CD000000CE000000CF0000011E000000D1000000D2000000D3000000D4000000D5000000D6000000D7000000D8000000D9000000DA000000DB000000DC000001300000015E000000DF000000E0000000E1000000E2000000E3000000E4000000E5000000E6000000E7000000E8000000E9000000EA000000EB000000EC000000ED000000EE000000EF0000011F000000F1000000F2000000F3000000F4000000F5000000F6000000F7000000F8000000F9000000FA000000FB000000FC000001310000015F000000FF" idecpname$(22) = "micsft_windows_cp1255" idecp$(22) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC000000000000201A000001920000201E000020260000202000002021000002C6000020300000000000002039000000000000000000000000000000000000000000002018000020190000201C0000201D000020220000201300002014000002DC00002122000000000000203A00000000000000000000000000000000000000A0000000A1000000A2000000A3000020AA000000A5000000A6000000A7000000A8000000A9000000D7000000AB000000AC000000AD000000AE000000AF000000B0000000B1000000B2000000B3000000B4000000B5000000B6000000B7000000B8000000B9000000F7000000BB000000BC000000BD000000BE000000BF000005B0000005B1000005B2000005B3000005B4000005B5000005B6000005B7000005B8000005B900000000000005BB000005BC000005BD000005BE000005BF000005C0000005C1000005C2000005C3000005F0000005F1000005F2000005F3000005F400000000000000000000000000000000000000000000000000000000000005D0000005D1000005D2000005D3000005D4000005D5000005D6000005D7000005D8000005D9000005DA000005DB000005DC000005DD000005DE000005DF000005E0000005E1000005E2000005E3000005E4000005E5000005E6000005E7000005E8000005E9000005EA00000000000000000000200E0000200F00000000" idecpname$(23) = "micsft_windows_cp1256" idecp$(23) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC0000067E0000201A000001920000201E000020260000202000002021000002C600002030000006790000203900000152000006860000069800000688000006AF00002018000020190000201C0000201D000020220000201300002014000006A900002122000006910000203A000001530000200C0000200D000006BA000000A00000060C000000A2000000A3000000A4000000A5000000A6000000A7000000A8000000A9000006BE000000AB000000AC000000AD000000AE000000AF000000B0000000B1000000B2000000B3000000B4000000B5000000B6000000B7000000B8000000B90000061B000000BB000000BC000000BD000000BE0000061F000006C10000062100000622000006230000062400000625000006260000062700000628000006290000062A0000062B0000062C0000062D0000062E0000062F00000630000006310000063200000633000006340000063500000636000000D70000063700000638000006390000063A00000640000006410000064200000643000000E000000644000000E200000645000006460000064700000648000000E7000000E8000000E9000000EA000000EB000006490000064A000000EE000000EF0000064B0000064C0000064D0000064E000000F40000064F00000650000000F700000651000000F900000652000000FB000000FC0000200E0000200F000006D2" idecpname$(24) = "micsft_windows_cp1257" idecp$(24) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC000000000000201A000000000000201E0000202600002020000020210000000000002030000000000000203900000000000000A8000002C7000000B80000000000002018000020190000201C0000201D0000202200002013000020140000000000002122000000000000203A00000000000000AF000002DB00000000000000A000000000000000A2000000A3000000A400000000000000A6000000A7000000D8000000A900000156000000AB000000AC000000AD000000AE000000C6000000B0000000B1000000B2000000B3000000B4000000B5000000B6000000B7000000F8000000B900000157000000BB000000BC000000BD000000BE000000E6000001040000012E0000010000000106000000C4000000C500000118000001120000010C000000C9000001790000011600000122000001360000012A0000013B000001600000014300000145000000D30000014C000000D5000000D6000000D700000172000001410000015A0000016A000000DC0000017B0000017D000000DF000001050000012F0000010100000107000000E4000000E500000119000001130000010D000000E90000017A0000011700000123000001370000012B0000013C000001610000014400000146000000F30000014D000000F5000000F6000000F700000173000001420000015B0000016B000000FC0000017C0000017E000002D9" idecpname$(25) = "micsft_windows_cp1258" idecp$(25) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC000000000000201A000001920000201E000020260000202000002021000002C6000020300000000000002039000001520000000000000000000000000000000000002018000020190000201C0000201D000020220000201300002014000002DC00002122000000000000203A00000153000000000000000000000178000000A0000000A1000000A2000000A3000000A4000000A5000000A6000000A7000000A8000000A9000000AA000000AB000000AC000000AD000000AE000000AF000000B0000000B1000000B2000000B3000000B4000000B5000000B6000000B7000000B8000000B9000000BA000000BB000000BC000000BD000000BE000000BF000000C0000000C1000000C200000102000000C4000000C5000000C6000000C7000000C8000000C9000000CA000000CB00000300000000CD000000CE000000CF00000110000000D100000309000000D3000000D4000001A0000000D6000000D7000000D8000000D9000000DA000000DB000000DC000001AF00000303000000DF000000E0000000E1000000E200000103000000E4000000E5000000E6000000E7000000E8000000E9000000EA000000EB00000301000000ED000000EE000000EF00000111000000F100000323000000F3000000F4000001A1000000F6000000F7000000F8000000F9000000FA000000FB000000FC000001B0000020AB000000FF" idecpname$(26) = "micsft_windows_cp874" idecp$(26) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000020AC0000000000000000000000000000000000002026000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002018000020190000201C0000201D0000202200002013000020140000000000000000000000000000000000000000000000000000000000000000000000A000000E0100000E0200000E0300000E0400000E0500000E0600000E0700000E0800000E0900000E0A00000E0B00000E0C00000E0D00000E0E00000E0F00000E1000000E1100000E1200000E1300000E1400000E1500000E1600000E1700000E1800000E1900000E1A00000E1B00000E1C00000E1D00000E1E00000E1F00000E2000000E2100000E2200000E2300000E2400000E2500000E2600000E2700000E2800000E2900000E2A00000E2B00000E2C00000E2D00000E2E00000E2F00000E3000000E3100000E3200000E3300000E3400000E3500000E3600000E3700000E3800000E3900000E3A0000000000000000000000000000000000000E3F00000E4000000E4100000E4200000E4300000E4400000E4500000E4600000E4700000E4800000E4900000E4A00000E4B00000E4C00000E4D00000E4E00000E4F00000E5000000E5100000E5200000E5300000E5400000E5500000E5600000E5700000E5800000E5900000E5A00000E5B00000000000000000000000000000000" idecpname$(27) = "MIK" idecp$(27) = "000000000000000100000002000000030000000400000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000160000001700000018000000190000001A0000001B0000001C0000001D0000001E0000001F000000200000002100000022000000230000002400000025000000260000002700000028000000290000002A0000002B0000002C0000002D0000002E0000002F000000300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000004400000045000000460000004700000048000000490000004A0000004B0000004C0000004D0000004E0000004F000000500000005100000052000000530000005400000055000000560000005700000058000000590000005A0000005B0000005C0000005D0000005E0000005F000000600000006100000062000000630000006400000065000000660000006700000068000000690000006A0000006B0000006C0000006D0000006E0000006F000000700000007100000072000000730000007400000075000000760000007700000078000000790000007A0000007B0000007C0000007D0000007E0000007F000004100000041100000412000004130000041400000415000004160000041700000418000004190000041A0000041B0000041C0000041D0000041E0000041F000004200000042100000422000004230000042400000425000004260000042700000428000004290000042A0000042B0000042C0000042D0000042E0000042F000004300000043100000432000004330000043400000435000004360000043700000438000004390000043A0000043B0000043C0000043D0000043E0000043F000004400000044100000442000004430000044400000445000004460000044700000448000004490000044A0000044B0000044C0000044D0000044E0000044F00002514000025340000252C0000251C000025000000253C00002563000025510000255A00002554000025690000256600002560000025500000256C00002510000025910000259200002593000025020000252400002116000000A7000025570000255D000025180000250C00002588000025840000258C0000259000002580000003B1000000DF00000393000003C0000003A3000003C3000000B5000003C4000003A600000398000003A9000003B40000221E000003C6000003B50000222900002261000000B100002265000022640000232000002321000000F700002248000000B000002219000000B70000221A0000207F000000B2000025A0000000A0" '######## update.bas: init ######## 'data for managing multiple file downloading CONST Maxdls = 1 DIM SHARED DLs AS LONG TYPE Download_Type State AS LONG '-1=failed '0=inactive '1=connected and reading data '2=finished! Handle AS LONG END TYPE DIM SHARED DL(1 TO Maxdls) AS Download_Type DIM SHARED DL_Data(1 TO Maxdls) AS STRING DIM SHARED Download_String AS STRING 'compress/decompress shared variables DIM SHARED huff_count(0 TO 255) AS LONG DIM SHARED huff_weight(0 TO 1000) AS LONG DIM SHARED huff_branch(0 TO 255) AS LONG DIM SHARED huff_parent(0 TO 1000) AS LONG DIM SHARED huff_bit(0 TO 1000) AS LONG DIM SHARED huff_bit0link(0 TO 1000) AS LONG DIM SHARED huff_bit1link(0 TO 1000) AS LONG DIM SHARED huff_mask(32 * 8 * 256) AS _UNSIGNED _BYTE DIM SHARED huff_mask_bytes(0 TO 7, 0 TO 255) AS LONG 'number of bytes in mask (at offset 0-7) DIM SHARED huff_mask_bits(0 TO 255) AS LONG 'number of bits in mask DIM SHARED huff_bitval(0 TO 7) AS LONG huff_bitval(0) = 1: huff_bitval(1) = 2: huff_bitval(2) = 4: huff_bitval(3) = 8 huff_bitval(4) = 16: huff_bitval(5) = 32: huff_bitval(6) = 64: huff_bitval(7) = 128 DIM SHARED huff_branch0(1000) AS LONG DIM SHARED huff_branch1(1000) AS LONG '(end of compress/decompress shared variables) REDIM SHARED chksums_name(1 TO 1) AS STRING REDIM SHARED chksums_valstr(1 TO 1) AS STRING DIM SHARED update_error DIM SHARED UpdateHandle GOTO skip_update_error_handler update_error_handler: update_error = 1 RESUME NEXT skip_update_error_handler: 'compiler-side IDE data & definitions DIM SHARED idecurrentlinelayout AS STRING DIM SHARED idecurrentlinelayouti AS LONG DIM SHARED idelayoutallow AS LONG DIM SHARED idecommand AS STRING DIM SHARED idereturn AS STRING DIM SHARED ideerror AS LONG DIM SHARED idecompiled AS LONG DIM SHARED idemode 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 'the function ?=ide(?) should always be passed 0, it returns a message code number, any further information '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] 'IDE MODULE: shared data & definitions DIM SHARED mousex AS INTEGER DIM SHARED mousey AS INTEGER DIM SHARED mousewheel AS INTEGER DIM SHARED mousebutton1 AS INTEGER DIM SHARED mousebutton2 AS INTEGER DIM SHARED mousevisible AS INTEGER DIM SHARED mousepassed AS INTEGER '--------------------------------------------------- DIM SHARED idesubwindow, idehelp DIM SHARED ideexit DIM SHARED idet AS STRING, idel, ideli, iden DIM SHARED ideundopos, ideundobase, ideundoflag DIM SHARED idelaunched, idecompiling DIM SHARED idecompiledline 'stores the number of the last line sent to the compiler, used only to know which line to send next DIM SHARED idecompiledline$ 'stores the last line sent to the compiler DIM SHARED idesx, idesy, idecx, idecy DIM SHARED ideselect, ideselectx1, ideselecty1, idemouseselect, idembmonitor DIM SHARED ideunsaved DIM SHARED ideroot AS STRING DIM SHARED idetxt(1000) AS STRING DIM SHARED idetxtlast AS INTEGER DIM SHARED idehl DIM SHARED idealtcode(255) AS INTEGER DIM SHARED ideprogname AS STRING DIM SHARED idepath AS STRING DIM SHARED idefindtext AS STRING DIM SHARED idefindcasesens AS INTEGER DIM SHARED idefindwholeword AS INTEGER DIM SHARED idefindbackwards AS INTEGER DIM SHARED idefindinvert AS INTEGER DIM SHARED idechangeto AS STRING DIM SHARED idechangemade AS INTEGER DIM SHARED ideinsert AS INTEGER DIM SHARED idepathsep AS STRING * 1 '-------------------------------------------------------------------------------- TYPE idedbptype x AS LONG y AS LONG w AS LONG h AS LONG nam AS LONG END TYPE '-------------------------------------------------------------------------------- TYPE idedbotype par AS idedbptype x AS LONG y AS LONG w AS LONG h AS LONG typ AS LONG nam AS LONG txt AS LONG dft AS LONG cx AS LONG cy AS LONG foc AS LONG sel AS LONG 'selected item no. stx AS LONG 'selected item in string form v1 AS LONG num AS LONG END TYPE '-------------------------------------------------------------------------------- DIM SHARED idefocusline 'simply stores the location of the line to highlight in red DIM SHARED ideautorun DIM SHARED menu$(1 TO 10, 0 TO 20) DIM SHARED menusize(1 TO 10) DIM SHARED menus AS INTEGER DIM SHARED menubar$ DIM SHARED ideundocombo, ideundocombochr, idenoundo, idemergeundo DIM SHARED idealthighlight, ideentermenu DIM SHARED ideautolayout, ideautoindent, ideautoindentsize, idebackupsize DIM SHARED idewx, idewy, idecustomfont, idecustomfontfile$, idecustomfontheight, idecustomfonthandle DIM SHARED iderunmode 'IDE MODULE SECTION END: shared data & definitions 'update settings DIM SHARED ideupdatecheck, ideupdatedaily, ideupdateauto, ideupdatelast, idedebuginfo DIM SHARED ideupdatetimerval AS SINGLE DIM SHARED IdeAndroidMenu DIM SHARED IdeAndroidStartScript AS STRING DIM SHARED IdeAndroidMakeScript AS STRING 'ref: options.bin 'SEEK 1 '[2] ideautolayout(=1) '[2] ideautoindent(=1) '[2] ideautoindentsize(=4) 'SEEK 7 '[2] idewx(=80) '[2] idewy(=25) '[2] idecustomfont(=0) '[1024]idecustomfontfile(=c:\windows\fonts\lucon.ttf) '[2] idecustomfontheight(=21) 'SEEK 1039 '[2] ideupdatecheck(=1) '[2] ideupdatedaily(=1) '[2] ideupdateauto(=0) '[4] ideupdatelast(=0) 'SEEK 1049 '[2] codepage(=0) 'SEEK 1051 '[4] backupsize(=100) 'SEEK 1055 '[2] embed debug info 'total bytes: 1056 OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 'remake options with defaults? IF LOF(150) < 1048 THEN CLOSE #150 OPEN ".\internal\temp\options.bin" FOR OUTPUT AS #150: CLOSE #150 OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 v% = 1: PUT #150, , v% 'layout v% = 1: PUT #150, , v% 'indent v% = 4: PUT #150, , v% 'indentsize v% = 80: PUT #150, , v% 'w v% = 25: PUT #150, , v% 'h v% = 0: PUT #150, , v% 'use custom font? v$ = SPACE$(1024): MID$(v$, 1) = "c:\windows\fonts\lucon.ttf": PUT #150, , v$ v% = 21: PUT #150, , v% 'custom font height v% = 1: PUT #150, , v% 'update-check v% = 1: PUT #150, , v% 'update-daily v% = 0: PUT #150, , v% 'update-autoapply ideupdatelast& = 0: PUT #150, , ideupdatelast& 'update-datestamp(last) END IF IF LOF(150) < 1050 THEN SEEK #150, 1049 v% = 0: PUT #150, , v% 'codepage END IF IF LOF(150) < 1054 THEN SEEK #150, 1051 v& = 100: PUT #150, , v& 'backup-size(mb) END IF IF LOF(150) < 1056 THEN SEEK #150, 1055 v% = 0: PUT #150, , v% 'idedebuginfo END IF '@1056 IF LOF(150) < 1056 + 2 + 256 + 256 THEN SEEK #150, 1057 v% = 0: PUT #150, , v% 'IdeAndroidMenu a$ = "programs\android\start_android.bat" a$ = a$ + SPACE$(256 - LEN(a$)) PUT #150, , a$ 'IdeAndroidStartScript a$ = "programs\android\make_android.bat" a$ = a$ + SPACE$(256 - LEN(a$)) PUT #150, , a$ 'IdeAndroidMakeScript END IF 'load options SEEK #150, 1 'layout: GET #150, , v%: IF v% <> 0 THEN v% = 1 ideautolayout = v% GET #150, , v%: IF v% <> 0 THEN v% = 1 ideautoindent = v% GET #150, , v%: IF v% < 0 OR v% > 64 THEN v% = 4 ideautoindentsize = v% 'display: GET #150, , v%: IF v% < 80 OR v% > 1000 THEN v% = 80 idewx = v% GET #150, , v%: IF v% < 25 OR v% > 1000 THEN v% = 25 idewy = v% GET #150, , v%: IF v% <> 0 THEN v% = 1 idecustomfont = v% v$ = SPACE$(1024): GET #150, , v$: idecustomfontfile$ = RTRIM$(v$) GET #150, , v%: IF v% < 8 OR v% > 100 THEN v% = 21 idecustomfontheight = v% GET #150, , v%: IF v% < 0 OR v% > 1 THEN v% = 1 ideupdatecheck = v% GET #150, , v%: IF v% < 0 OR v% > 1 THEN v% = 1 ideupdatedaily = v% GET #150, , v%: IF v% < 0 OR v% > 1 THEN v% = 1 ideupdateauto = v% GET #150, , v& ideupdatelast = v& GET #150, , v%: IF v% < 0 OR v% > idecpnum THEN v% = 0 idecpindex = v% GET #150, , v&: IF v& < 10 OR v& > 2000 THEN v& = 100 idebackupsize = v& GET #150, , v%: IF v% < 0 OR v% > 1 THEN v% = 0 idedebuginfo = v% Include_GDB_Debugging_Info = idedebuginfo GET #150, , v%: IF v% < 0 OR v% > 1 THEN v% = 0 IdeAndroidMenu = v% a$ = SPACE$(256) GET #150, , a$ a$ = RTRIM$(a$) IdeAndroidStartScript = a$ a$ = SPACE$(256) GET #150, , a$ a$ = RTRIM$(a$) IdeAndroidMakeScript = a$ CLOSE #150 IF os$ = "WIN" AND AllowUpdates <> 0 THEN 'begin update check IF ideupdatecheck THEN a$ = DATE$: dateval = VAL(MID$(a$, 4, 2)) + VAL(MID$(a$, 1, 2)) * 32 + VAL(MID$(a$, 7, 4)) * 416 'create unique date value IF ideupdatedaily = 0 OR dateval <> ideupdatelast THEN 'note: regardless of success or failure, daily checks are attempted once, so the 'last' value is updated here ideupdatelast = dateval OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 IF LOF(150) >= 1048 THEN SEEK #150, 1045 PUT #150, , ideupdatelast END IF CLOSE #150 'connect UpdateHandle = BeginDownload("www.qb64.net/update2.txt") ideupdatetimerval = TIMER END IF 'update check required END IF 'ideupdatecheck on END IF 'win '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 '0=label referenced, 1=label created 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) 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 '= 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 'constlastshared = -1 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 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 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 'if function=1, sub=2 (max 100 arguments) Dependency AS INTEGER internal_subfunc AS INTEGER callname AS STRING * 256 ccall AS INTEGER args 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 'argument/parameter # within call (1=first) NoCloud AS INTEGER 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 'arrayelementslist (like cmemlist) helps to resolve the number of elements in arrays with an unknown number of elements. Note: arrays with an unknown number of elements have .arrayelements=-1 '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 DIM SHARED wholeline 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 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 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 56) AS _INTEGER64 DIM SHARED bitmaskinv(1 TO 56) 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 controllevel AS INTEGER '0=not in a control block DIM controltype(1000) AS INTEGER '1=IF (awaiting END IF) '2=FOR (awaiting NEXT) '3=DO (awaiting LOOP [UNTIL|WHILE param]) '4=DO WHILE/UNTIL (awaiting LOOP) '5=WHILE (awaiting WEND) '10=SELECT CASE qbs (awaiting END SELECT/CASE) '11=SELECT CASE int64 (awaiting END SELECT/CASE) '12=SELECT CASE uint64 (awaiting END SELECT/CASE) '13=SELECT CASE LONG double (awaiting END SELECT/CASE/CASE ELSE) '14=SELECT CASE float ... '15=SELECT CASE double '16=SELECT CASE int32 '17=SELECT CASE uint32 '18=CASE (awaiting END SELECT/CASE/CASE ELSE) '19=CASE ELSE (awaiting END SELECT) DIM controlid(1000) AS LONG DIM controlvalue(1000) AS LONG DIM controlstate(1000) AS INTEGER DIM controlref(1000) AS LONG 'the line number the control was created on ON ERROR GOTO qberror i2&& = 1 FOR i&& = 1 TO 56 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--------------------------------------- a$ = LTRIM$(RTRIM$(command2$)) a2$ = LCASE$(LEFT$(a$, 2)) IF a2$ = "-c" THEN command2$ = LTRIM$(RIGHT$(a$, LEN(a$) - 2)): GOTO noide 'assume command2$ contains the name of a file to load/compile idemode = 1 sendc$ = "" 'no initial message IF command2$ <> "" THEN sendc$ = CHR$(1) + command2$ 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: 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: sendc$ = CHR$(3) 'request next line GOTO sendcommand END IF IF c = 5 THEN 'end of program reached IF idepass = 1 THEN 'prepass complete idepass = 2 GOTO ide3 ideret3: sendc$ = CHR$(7) 'repass request GOTO sendcommand END IF 'assume idepass=2 '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$ i = 1 nextexeindex: IF _FILEEXISTS(file$ + extension$) THEN E = 0 ON ERROR GOTO qberror_test KILL 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 MakeAndroid THEN 'generate program name pf$ = "programs\android\" + file$ IF _DIREXISTS(pf$) = 0 THEN 'once only setup COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window LOCATE idewy - 3, 2: PRINT "Initializing project [programs\android\" + file$ + "]..."; PCOPY 3, 0 MKDIR pf$ SHELL _HIDE "cmd /c xcopy /e programs\android\project_template\*.* " + pf$ SHELL _HIDE "cmd /c xcopy /e programs\android\eclipse_template\*.* " + pf$ 'modify templates fr_fh = FREEFILE OPEN pf$ + "\AndroidManifest.xml" FOR BINARY AS #fr_fh a$ = SPACE$(LOF(fr_fh)) GET #fr_fh, , a$ CLOSE fr_fh OPEN pf$ + "\AndroidManifest.xml" FOR OUTPUT AS #fr_fh ss$ = CHR$(34) + "com.example.native_activity" + CHR$(34) file_namespace$ = LCASE$(file$) a = ASC(file_namespace$) IF a >= 48 AND a <= 57 THEN file_namespace$ = "ns_" + file_namespace$ i = INSTR(a$, ss$) a$ = LEFT$(a$, i - 1) + CHR$(34) + "com.example." + file_namespace$ + CHR$(34) + RIGHT$(a$, LEN(a$) - i - LEN(ss$) + 1) PRINT #fr_fh, a$; CLOSE fr_fh fr_fh = FREEFILE OPEN pf$ + "\res\values\strings.xml" FOR BINARY AS #fr_fh a$ = SPACE$(LOF(fr_fh)) GET #fr_fh, , a$ CLOSE fr_fh OPEN pf$ + "\res\values\strings.xml" FOR OUTPUT AS #fr_fh ss$ = ">NativeActivity<" i = INSTR(a$, ss$) a$ = LEFT$(a$, i - 1) + ">" + file$ + "<" + RIGHT$(a$, LEN(a$) - i - LEN(ss$) + 1) PRINT #fr_fh, a$; CLOSE fr_fh fr_fh = FREEFILE OPEN pf$ + "\.project" FOR BINARY AS #fr_fh a$ = SPACE$(LOF(fr_fh)) GET #fr_fh, , a$ CLOSE fr_fh OPEN pf$ + "\.project" FOR OUTPUT AS #fr_fh ss$ = "NativeActivity" i = INSTR(a$, ss$) a$ = LEFT$(a$, i - 1) + "" + file$ + "" + RIGHT$(a$, LEN(a$) - i - LEN(ss$) + 1) PRINT #fr_fh, a$; CLOSE fr_fh IF _DIREXISTS(pf$ + "\jni\temp") = 0 THEN MKDIR pf$ + "\jni\temp" IF _DIREXISTS(pf$ + "\jni\c") = 0 THEN MKDIR pf$ + "\jni\c" 'c ex_fh = FREEFILE OPEN "internal\temp\xcopy_exclude.txt" FOR OUTPUT AS #ex_fh PRINT #ex_fh, "c_compiler\" CLOSE ex_fh SHELL _HIDE "cmd /c xcopy /e /EXCLUDE:internal\temp\xcopy_exclude.txt internal\c\*.* " + pf$ + "\jni\c" ELSE COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window LOCATE idewy - 3, 2: PRINT "Updating project [programs\android\" + file$ + "]..."; PCOPY 3, 0 END IF 'temp SHELL _HIDE "cmd /c del " + pf$ + "\jni\temp\*.txt" SHELL _HIDE "cmd /c copy " + tmpdir$ + "*.txt " + pf$ + "\jni\temp" 'touch main.cpp (for ndk) fr_fh = FREEFILE OPEN pf$ + "\jni\main.cpp" FOR BINARY AS #fr_fh a$ = SPACE$(LOF(fr_fh)) GET #fr_fh, , a$ CLOSE fr_fh OPEN pf$ + "\jni\main.cpp" FOR OUTPUT AS #fr_fh IF ASC(a$, LEN(a$)) <> 32 THEN a$ = a$ + " " ELSE a$ = LEFT$(a$, LEN(a$) - 1) PRINT #fr_fh, a$; CLOSE fr_fh 'note: .bat files affect the directory they are called from CHDIR pf$ IF INSTR(IdeAndroidStartScript, ":") THEN SHELL _HIDE IdeAndroidMakeScript ELSE SHELL _HIDE "..\..\..\" + IdeAndroidMakeScript END IF CHDIR "..\..\.." ''touch manifest (for Eclipse) 'fr_fh = FREEFILE 'OPEN pf$ + "\AndroidManifest.xml" FOR BINARY AS #fr_fh 'a$ = SPACE$(LOF(fr_fh)) 'GET #fr_fh, , a$ 'CLOSE fr_fh 'OPEN pf$ + "\AndroidManifest.xml" FOR OUTPUT AS #fr_fh 'IF ASC(a$, LEN(a$)) <> 32 THEN a$ = a$ + " " ELSE a$ = LEFT$(a$, LEN(a$) - 1) 'PRINT #fr_fh, a$; 'CLOSE fr_fh '^^^^above inconsistent^^^^ 'clear the gen folder (for Eclipse) IF _DIREXISTS(pf$ + "\gen") THEN SHELL _HIDE "cmd /c rmdir /s /q " + pf$ + "\gen" SHELL _HIDE "cmd /c md " + pf$ + "\gen" END IF sendc$ = CHR$(11) '".EXE file created" aka "Android project created" GOTO sendcommand END IF IF iderunmode = 2 THEN sendc$ = CHR$(11) '.EXE file created GOTO sendcommand END IF 'hack! (a new message should be sent to the IDE stating C++ compilation was successful) COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window LOCATE idewy - 3, 2: PRINT "Starting program..."; PCOPY 3, 0 'execute program IF iderunmode = 1 THEN IF os$ = "WIN" THEN SHELL _DONTWAIT idezfilename$(CHR$(34) + file$ + extension$ + CHR$(34)) IF os$ = "LNX" THEN SHELL _DONTWAIT idezfilename$("./" + file$ + extension$) ELSE IF os$ = "WIN" THEN SHELL idezfilename$(CHR$(34) + file$ + extension$ + CHR$(34)) IF os$ = "LNX" THEN SHELL idezfilename$("./" + file$ + extension$) END IF sendc$ = CHR$(6) 'ready GOTO sendcommand END IF PRINT "Invalid IDE message": END ideerror: sendc$ = CHR$(8) + idemessage$ + MKL$(ideerrorline) GOTO sendcommand noide: PRINT "QB64 COMPILER V" + Version$ IF command2$ = "" THEN LINE INPUT ; "COMPILE (.bas)>", f$ ELSE f$ = command2$ END IF f$ = LTRIM$(RTRIM$(f$)) IF FileHasExtension(f$) = 0 THEN f$ = f$ + ".bas" sourcefile$ = f$ 'derive name from sourcefile f$ = RemoveFileExtension$(f$) 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: FOR i = 1 TO UBOUND(DEPENDENCY): DEPENDENCY(i) = 0: NEXT Error_Happened = 0 FOR closeall = 1 TO 255: CLOSE closeall: NEXT OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 'relock fh = FREEFILE: OPEN tmpdir$ + "dyninfo.txt" FOR OUTPUT AS #fh: CLOSE #fh 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 recompile: 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 "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 "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 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 addmetainclude$ = "" nextrunlineindex = 1 lasttype = 0 lasttypeelement = 0 definingtype = 0 constlast = -1 'constlastshared = -1 defdatahandle = 18 closedmain = 0 addmetastatic = 0 addmetadynamic = 0 DynamicMode = 0 optionbase = 0 DataOffset = 0 statementn = 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 subfuncn = 0 subfunc = "" ''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 IF Cloud = 0 THEN lasttype = lasttype + 1: i = lasttype udtxname(i) = "_MEM" udtxcname(i) = "_MEM" udtxsize(i) = ((ptrsz) * 4 + (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) = LONGTYPE: udtesize(i2) = 32 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 END IF 'cloud = 0 'begin compilation FOR closeall = 1 TO 255: CLOSE closeall: NEXT OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 'relock 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 OPEN tmpdir$ + "global.txt" FOR OUTPUT AS #18 IF Cloud THEN PRINT #18, "int32 cloud_app=1;" ELSE PRINT #18, "int32 cloud_app=0;" 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 stevewashere: '### STEVE EDIT FOR CONST EXPANSION 10/11/2013 wholeline$ = lineinput3$ IF wholeline$ = CHR$(13) THEN EXIT DO ideprepass: wholestv$ = wholeline$ '### STEVE EDIT FOR CONST EXPANSION 10/11/2013 prepass = 1 layout = "" layoutok = 0 linenumber = linenumber + 1 IF LEN(wholeline$) THEN wholeline$ = lineformat(wholeline$) IF Error_Happened THEN GOTO errmes 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 'wholelinen>=2 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) '======================================== '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) PRINT #18, "char *g_tmp_udt_" + RTRIM$(udtxname(i)) + "=(char*)malloc(" + siz$ + ");" 'print "END TYPE";udtxsize(i);udtxbytealign(i) GOTO finishedlinepp END IF END IF lasttypeelement = lasttypeelement + 1 i2 = lasttypeelement udtenext(i2) = 0 IF n < 3 THEN a$ = "Expected variablename AS type or END TYPE": GOTO errmes n$ = firstelement$ ii = 2 udtearrayelements(i2) = 0 IF ii >= n OR getelement$(a$, ii) <> "AS" THEN a$ = "Expected variablename AS type or END TYPE": GOTO errmes t$ = getelements$(a$, ii + 1, n) 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) 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": 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": 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 ELSE IF (typ AND ISSTRING) THEN IF (typ AND ISFIXEDLENGTH) = 0 THEN a$ = "Expected STRING *": GOTO errmes udtesize(i2) = typsize * 8 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));udtesize(i2);udtebytealign(i2);udtxsize(i) GOTO finishedlinepp 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 definingtype = lasttype i = definingtype IF validname(secondelement$) = 0 THEN a$ = "Invalid name": GOTO errmes udtxname(i) = secondelement$ udtxcname(i) = getelement(ca$, 2) udtxnext(i) = 0 udtxsize(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": 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 stevewashere2: ' ### STEVE EDIT ON 10/11/2013 (Const Expansion) IF n >= 1 AND firstelement$ = "CONST" THEN 'l$ = "CONST" 'DEF... do not change type, the expression is stored in a suitable type 'based on its value if type isn't forced/specified '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 'Steve Tweak to add _RGB32 and _MATH support to CONST 'Our alteration to allow for multiple uses of RGB and RGBA inside a CONST //SMcNeill altered = 0 DO finished = -1 l = INSTR(l + 1, UCASE$(wholestv$), " _RGBA") IF l > 0 THEN altered = -1 l$ = LEFT$(wholestv$, l - 1) vp = INSTR(l, wholestv$, "(") IF vp > 0 THEN E = INSTR(vp + 1, wholestv$, ")") IF E > 0 THEN 'get our 3 colors or 4 if we need RGBA values first = INSTR(vp, wholestv$, ",") second = INSTR(first + 1, wholestv$, ",") third = INSTR(second + 1, wholestv$, ",") fourth = INSTR(third + 1, wholestv$, ",") 'If we need RGBA we need this one as well red$ = MID$(wholestv$, vp + 1, first - vp - 1) green$ = MID$(wholestv$, first + 1, second - first - 1) blue$ = MID$(wholestv$, second + 1, third - second - 1) alpha$ = MID$(wholestv$, third + 1, fourth - third - 1) val$ = MID$(wholestv$, fourth + 1) SELECT CASE VAL(val$) CASE 0, 1, 2, 7, 8, 9, 10, 11, 12, 13, 256 wi& = _NEWIMAGE(240, 120, VAL(val$)) clr = _RGBA(VAL(red$), VAL(green$), VAL(blue$), VAL(alpha$), wi&) _FREEIMAGE wi& CASE 32 clr = _RGBA32(VAL(red$), VAL(green$), VAL(blue$), VAL(alpha$)) CASE ELSE a$ = "Invalid Screen Mode.": GOTO errmes END SELECT wholestv$ = l$ + STR$(clr) + RIGHT$(wholestv$, LEN(wholestv$) - E) finished = 0 ELSE 'no finishing bracket a$ = ") Expected": GOTO errmes END IF ELSE 'no starting bracket a$ = "( Expected": GOTO errmes END IF END IF LOOP UNTIL finished DO finished = -1 l = INSTR(l + 1, UCASE$(wholestv$), " _RGB") IF l > 0 THEN altered = -1 l$ = LEFT$(wholestv$, l - 1) vp = INSTR(l, wholestv$, "(") IF vp > 0 THEN E = INSTR(vp + 1, wholestv$, ")") IF E > 0 THEN first = INSTR(vp, wholestv$, ",") second = INSTR(first + 1, wholestv$, ",") third = INSTR(second + 1, wholestv$, ",") red$ = MID$(wholestv$, vp + 1, first - vp - 1) green$ = MID$(wholestv$, first + 1, second - first - 1) blue$ = MID$(wholestv$, second + 1, third - second - 1) val$ = MID$(wholestv$, third + 1) SELECT CASE VAL(val$) CASE 0, 1, 2, 7, 8, 9, 10, 11, 12, 13, 256 wi& = _NEWIMAGE(240, 120, VAL(val$)) clr = _RGB(VAL(red$), VAL(green$), VAL(blue$), wi&) _FREEIMAGE wi& CASE 32 clr = _RGB32(VAL(red$), VAL(green$), VAL(blue$)) CASE ELSE a$ = "Invalid Screen Mode.": GOTO errmes END SELECT wholestv$ = l$ + STR$(clr) + RIGHT$(wholestv$, LEN(wholestv$) - E) finished = 0 ELSE a$ = ") Expected": GOTO errmes END IF ELSE a$ = "( Expected": GOTO errmes END IF END IF LOOP UNTIL finished IF altered THEN altered = 0 wholeline$ = wholestv$ linenumber = linenumber - 1 GOTO ideprepass END IF ' ### END OF STEVE EDIT FOR EXPANDED CONST SUPPORT ### IF n < 3 THEN a$ = "Expected CONST name = value/expression": GOTO errmes i = 2 constdefpendingpp: pending = 0 n$ = getelement$(ca$, i): i = i + 1 'l$ = l$ + sp + n$ + sp + "=" 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) <> "=" THEN a$ = "Expected =": GOTO errmes i = i + 1 'get expression 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$ = "Expected CONST ... , name = value/expression": GOTO errmes EXIT FOR END IF IF LEN(e$) = 0 THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ NEXT e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes 'l$ = l$ + sp + tlayout$ 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 'IF subfunc = "" THEN constlastshared = i2 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 a$ = "Name already in use": GOTO errmes END IF IF hashresflags AND HASHFLAG_RESERVED THEN a$ = "Name already in use": 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": GOTO errmes IF t AND ISSTRING THEN a$ = "Name already in use": 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 constdefined(i2) = 1 constcname(i2) = n$ constnamesymbol(i2) = typevalue2symbol$(t) IF Error_Happened THEN GOTO errmes consttype(i2) = t IF t AND ISSTRING THEN conststring(i2) = e$ ELSE IF t AND ISFLOAT THEN constfloat(i2) = constval## ELSE IF t AND ISUNSIGNED THEN constuinteger(i2) = constval~&& ELSE constinteger(i2) = constval&& END IF END IF END IF IF pending THEN 'l$ = l$ + sp2 + "," GOTO constdefpendingpp END IF 'layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedlinepp END IF 'DEFINE d = 0 IF firstelement$ = "DEFINT" THEN d = 1 IF firstelement$ = "DEFLNG" THEN d = 1 IF firstelement$ = "DEFSNG" THEN d = 1 IF firstelement$ = "DEFDBL" THEN d = 1 IF firstelement$ = "DEFSTR" THEN d = 1 IF firstelement$ = "_DEFINE" THEN d = 1 IF d THEN predefining = 1: GOTO predefine predefined: predefining = 0 GOTO finishedlinepp END IF 'declare library IF firstelement$ = "DECLARE" THEN IF secondelement$ = "LIBRARY" OR secondelement$ = "DYNAMIC" OR secondelement$ = "CUSTOMTYPE" OR secondelement$ = "STATIC" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** declaringlibrary = 1 indirectlibrary = 0 IF secondelement$ = "CUSTOMTYPE" OR secondelement$ = "DYNAMIC" THEN indirectlibrary = 1 GOTO finishedlinepp END IF END IF 'SUB/FUNCTION dynamiclibrary = 0 declaresubfunc: firstelement$ = getelement$(a$, 1) sf = 0 IF firstelement$ = "FUNCTION" THEN sf = 1 IF firstelement$ = "SUB" THEN sf = 2 IF sf THEN subfuncn = subfuncn + 1 IF n = 1 THEN a$ = "Expected name after SUB/FUNCTION": 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 n$ = getelement$(ca$, 2) symbol$ = removesymbol$(n$) IF Error_Happened THEN GOTO errmes IF sf = 2 AND symbol$ <> "" THEN a$ = "Type symbols after a SUB name are invalid": GOTO errmes 'remove STATIC (which is ignored) e$ = getelement$(a$, n): IF e$ = "STATIC" THEN a$ = LEFT$(a$, LEN(a$) - 7): ca$ = LEFT$(ca$, LEN(ca$) - 7): n = n - 1 'check for ALIAS aliasname$ = n$ 'use given name by default IF n > 2 THEN e$ = getelement$(a$, 3) IF e$ = "ALIAS" THEN IF declaringlibrary = 0 THEN a$ = "ALIAS can only be used with DECLARE LIBRARY": GOTO errmes IF n = 3 THEN a$ = "Expected ALIAS name-in-library": GOTO errmes e$ = getelement$(ca$, 4) 'strip string content (optional) IF LEFT$(e$, 1) = CHR$(34) THEN e$ = RIGHT$(e$, LEN(e$) - 1) x = INSTR(e$, CHR$(34)): IF x = 0 THEN a$ = "Expected " + CHR$(34): GOTO errmes e$ = LEFT$(e$, x - 1) END IF 'strip fix046$ (created by unquoted periods) DO WHILE INSTR(e$, fix046$) x = INSTR(e$, fix046$): e$ = LEFT$(e$, x - 1) + "." + RIGHT$(e$, LEN(e$) - x + 1 - LEN(fix046$)) LOOP 'validate alias name IF LEN(e$) = 0 THEN a$ = "Expected ALIAS name-in-library": GOTO errmes FOR x = 1 TO LEN(e$) a = ASC(e$, x) IF alphanumeric(a) = 0 AND a <> ASC_FULLSTOP AND a <> ASC_COLON THEN a$ = "Expected ALIAS name-in-library": GOTO errmes NEXT aliasname$ = e$ 'remove ALIAS section from line IF n <= 4 THEN a$ = getelements(a$, 1, 2) IF n >= 5 THEN a$ = getelements(a$, 1, 2) + sp + getelements(a$, 5, n) IF n <= 4 THEN ca$ = getelements(ca$, 1, 2) IF n >= 5 THEN ca$ = getelements(ca$, 1, 2) + sp + getelements(ca$, 5, n) n = n - 2 END IF END IF IF declaringlibrary THEN IF indirectlibrary THEN aliasname$ = n$ 'override the alias name END IF END IF params = 0 params$ = "" paramsize$ = "" nele$ = "" nelereq$ = "" IF n > 2 THEN e$ = getelement$(a$, 3) IF e$ <> "(" THEN a$ = "Expected (": GOTO errmes e$ = getelement$(a$, n) IF e$ <> ")" THEN a$ = "Expected )": GOTO errmes IF n < 4 THEN a$ = "Expected ( ... )": GOTO errmes IF n = 4 THEN GOTO nosfparams B = 0 a2$ = "" FOR i = 4 TO n - 1 e$ = getelement$(a$, i) IF e$ = "(" THEN B = B + 1 IF e$ = ")" THEN B = B - 1 IF e$ = "," AND B = 0 THEN IF i = n - 1 THEN a$ = "Expected , ... )": GOTO errmes getlastparam: IF a2$ = "" THEN a$ = "Expected ... ,": GOTO errmes a2$ = LEFT$(a2$, LEN(a2$) - 1) 'possible format: [BYVAL]a[%][(1)][AS][type] n2 = numelements(a2$) array = 0 t2$ = "" i2 = 1 e$ = getelement$(a2$, i2): i2 = i2 + 1 byvalue = 0 IF e$ = "BYVAL" THEN IF declaringlibrary = 0 THEN a$ = "BYVAL can currently only be used with DECLARE LIBRARY": GOTO errmes e$ = getelement$(a2$, i2): i2 = i2 + 1: byvalue = 1 END IF n2$ = e$ symbol2$ = removesymbol$(n2$) IF validname(n2$) = 0 THEN a$ = "Invalid name": GOTO errmes IF Error_Happened THEN GOTO errmes m = 0 FOR i2 = i2 TO n2 e$ = getelement$(a2$, i2) IF e$ = "(" THEN IF m <> 0 THEN a$ = "Syntax error": GOTO errmes m = 1 array = 1 GOTO gotaa END IF IF e$ = ")" THEN IF m <> 1 THEN a$ = "Syntax error": GOTO errmes m = 2 GOTO gotaa END IF IF e$ = "AS" THEN IF m <> 0 AND m <> 2 THEN a$ = "Syntax error": GOTO errmes m = 3 GOTO gotaa END IF IF m = 1 THEN GOTO gotaa 'ignore contents of bracket IF m <> 3 THEN a$ = "Syntax error": GOTO errmes IF t2$ = "" THEN t2$ = e$ ELSE t2$ = t2$ + " " + e$ gotaa: NEXT i2 params = params + 1: IF params > 100 THEN a$ = "SUB/FUNCTION exceeds 100 parameter limit": GOTO errmes argnelereq = 0 IF symbol2$ <> "" AND t2$ <> "" THEN a$ = "Syntax error": GOTO errmes IF t2$ = "" THEN t2$ = symbol2$ IF t2$ = "" THEN IF LEFT$(n2$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(n2$)) - 64 t2$ = defineaz(v) END IF paramsize = 0 IF array = 1 THEN t = typname2typ(t2$) IF Error_Happened THEN GOTO errmes IF t = 0 THEN a$ = "Illegal SUB/FUNCTION parameter": GOTO errmes IF (t AND ISFIXEDLENGTH) THEN paramsize = typname2typsize t = t + ISARRAY 'check for recompilation override FOR i10 = 0 TO sflistn IF sfidlist(i10) = idn + 1 THEN IF sfarglist(i10) = params THEN argnelereq = sfelelist(i10) END IF END IF NEXT ELSE t = typname2typ(t2$) IF Error_Happened THEN GOTO errmes IF t = 0 THEN a$ = "Illegal SUB/FUNCTION parameter": GOTO errmes IF (t AND ISFIXEDLENGTH) THEN paramsize = typname2typsize IF byvalue THEN IF t AND ISPOINTER THEN t = t - ISPOINTER END IF END IF nelereq$ = nelereq$ + CHR$(argnelereq) 'consider changing 0 in following line too! nele$ = nele$ + CHR$(0) paramsize$ = paramsize$ + MKL$(paramsize) params$ = params$ + MKL$(t) a2$ = "" ELSE a2$ = a2$ + e$ + sp IF i = n - 1 THEN GOTO getlastparam END IF NEXT i END IF 'n>2 nosfparams: IF sf = 1 THEN 'function clearid id.n = n$ id.subfunc = 1 id.callname = "FUNC_" + UCASE$(n$) IF declaringlibrary THEN id.ccall = 1 IF indirectlibrary = 0 THEN id.callname = aliasname$ END IF id.args = params id.arg = params$ id.argsize = paramsize$ id.nele = nele$ id.nelereq = nelereq$ IF symbol$ <> "" THEN id.ret = typname2typ(symbol$) IF Error_Happened THEN GOTO errmes ELSE IF LEFT$(n$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(n$)) - 64 symbol$ = defineaz(v) id.ret = typname2typ(symbol$) IF Error_Happened THEN GOTO errmes END IF IF id.ret = 0 THEN a$ = "Invalid FUNCTION return type": GOTO errmes IF declaringlibrary THEN ctype$ = typ2ctyp$(id.ret, "") IF Error_Happened THEN GOTO errmes IF ctype$ = "qbs" THEN ctype$ = "char*" id.callname = "( " + ctype$ + " )" + RTRIM$(id.callname) END IF s$ = LEFT$(symbol$, 1) IF s$ <> "~" AND s$ <> "`" AND s$ <> "%" AND s$ <> "&" AND s$ <> "!" AND s$ <> "#" AND s$ <> "$" THEN symbol$ = type2symbol$(symbol$) IF Error_Happened THEN GOTO errmes END IF id.mayhave = symbol$ IF id.ret AND ISPOINTER THEN IF (id.ret AND ISSTRING) = 0 THEN id.ret = id.ret - ISPOINTER END IF regid IF Error_Happened THEN GOTO errmes ELSE 'sub clearid id.n = n$ id.subfunc = 2 id.callname = "SUB_" + UCASE$(n$) IF declaringlibrary THEN id.ccall = 1 IF indirectlibrary = 0 THEN id.callname = aliasname$ END IF id.args = params id.arg = params$ id.argsize = paramsize$ id.nele = nele$ id.nelereq = nelereq$ IF UCASE$(n$) = "_GL" AND params = 0 AND UseGL = 0 THEN reginternalsubfunc = 1: UseGL = 1: id.n = "_GL": DEPENDENCY(DEPENDENCY_GL) = 1 regid reginternalsubfunc = 0 IF Error_Happened THEN GOTO errmes END IF END IF '======================================== finishedlinepp: END IF a$ = "" ca$ = "" ELSE IF a$ = "" THEN a$ = e$: ca$ = ce$ ELSE a$ = a$ + sp + e$: ca$ = ca$ + sp + ce$ END IF IF wholelinei <= wholelinen THEN wholelinei = wholelinei + 1: GOTO ppblda '---------------------------------------- END IF 'wholelinei<=wholelinen END IF 'wholelinen END IF 'len(wholeline$) 'Include Manager #1 IF LEN(addmetainclude$) THEN IF Debug THEN PRINT #9, "Pre-pass:INCLUDE$-ing file:'" + addmetainclude$ + "':On line"; linenumber a$ = addmetainclude$: addmetainclude$ = "" 'read/clear message IF inclevel = 100 THEN a$ = "Too many indwelling INCLUDE files": GOTO errmes '1. Verify file exists (location is either (a)relative to source file or (b)absolute) fh = 99 + inclevel + 1 FOR try = 1 TO 2 IF try = 1 THEN IF inclevel = 0 THEN IF idemode THEN p$ = idepath$ + pathsep$ ELSE p$ = getfilepath$(sourcefile$) ELSE p$ = getfilepath$(incname(inclevel)) END IF f$ = p$ + a$ END IF IF try = 2 THEN f$ = a$ IF _FILEEXISTS(f$) THEN qberrorhappened = -3 OPEN f$ FOR INPUT AS #fh qberrorhappened3: IF qberrorhappened = -3 THEN EXIT FOR END IF qberrorhappened = 0 NEXT IF qberrorhappened <> -3 THEN qberrorhappened = 0: a$ = "File " + a$ + " not found": GOTO errmes inclevel = inclevel + 1: incname$(inclevel) = f$: inclinenumber(inclevel) = 0 END IF 'fall through to next section... '-------------------- DO WHILE inclevel fh = 99 + inclevel '2. Feed next line IF EOF(fh) = 0 THEN LINE INPUT #fh, x$ wholeline$ = x$ inclinenumber(inclevel) = inclinenumber(inclevel) + 1 'create extended error string 'incerror$' e$ = " in line " + str2(inclinenumber(inclevel)) + " of " + incname$(inclevel) + " included" IF inclevel > 1 THEN e$ = e$ + " (through " FOR x = 1 TO inclevel - 1 STEP 1 e$ = e$ + incname$(x) IF x < inclevel - 1 THEN 'a sep is req IF x = inclevel - 2 THEN e$ = e$ + " then " ELSE e$ = e$ + ", " END IF END IF NEXT e$ = e$ + ")" END IF incerror$ = e$ linenumber = linenumber - 1 'lower official linenumber to counter later increment IF Debug THEN PRINT #9, "Pre-pass:Feeding INCLUDE$ line:[" + wholeline$ + "]" IF idemode THEN sendc$ = CHR$(10) + wholeline$: GOTO sendcommand 'passback GOTO ideprepass END IF '3. Close & return control CLOSE #fh inclevel = inclevel - 1 LOOP '(end manager) IF idemode THEN GOTO ideret2 LOOP IF definingtype THEN definingtype = 0 'ignore this error so that auto-formatting can be performed and catch it again later IF declaringlibrary THEN declaringlibrary = 0 'ignore this error so that auto-formatting can be performed and catch it again later 'prepass finished lineinput3index = 1 'reset input line 'ide specific ide3: addmetainclude$ = "" 'reset stray meta-includes 'reset altered variables DataOffset = 0 inclevel = 0 subfuncn = 0 FOR i = 0 TO constlast: constdefined(i) = 0: NEXT 'undefine constants FOR i = 1 TO 27: defineaz(i) = "SINGLE": defineextaz(i) = "!": NEXT OPEN tmpdir$ + "data.bin" FOR OUTPUT AS #16: CLOSE #16 OPEN tmpdir$ + "data.bin" FOR BINARY AS #16 OPEN tmpdir$ + "main.txt" FOR OUTPUT AS #12 OPEN tmpdir$ + "maindata.txt" FOR OUTPUT AS #13 OPEN tmpdir$ + "regsf.txt" FOR OUTPUT AS #17 OPEN tmpdir$ + "mainfree.txt" FOR OUTPUT AS #19 OPEN tmpdir$ + "runline.txt" FOR OUTPUT AS #21 OPEN tmpdir$ + "mainerr.txt" FOR OUTPUT AS #14 'main error handler 'i. check the value of error_line 'ii. jump to the appropriate label errorlabels = 0 PRINT #14, "if (error_occurred){ error_occurred=0;" OPEN tmpdir$ + "chain.txt" FOR OUTPUT AS #22: CLOSE #22 'will be appended to as necessary OPEN tmpdir$ + "inpchain.txt" FOR OUTPUT AS #23: CLOSE #23 'will be appended to as necessary '*** #22 & #23 are reserved for usage by chain & inpchain *** OPEN tmpdir$ + "ontimer.txt" FOR OUTPUT AS #24 OPEN tmpdir$ + "ontimerj.txt" FOR OUTPUT AS #25 '*****#26 used for locking qb64 OPEN tmpdir$ + "onkey.txt" FOR OUTPUT AS #27 OPEN tmpdir$ + "onkeyj.txt" FOR OUTPUT AS #28 OPEN tmpdir$ + "onstrig.txt" FOR OUTPUT AS #29 OPEN tmpdir$ + "onstrigj.txt" FOR OUTPUT AS #30 gosubid = 1 'to be included whenever return without a label is called 'return [label] in QBASIC was not possible in a sub/function, but QB64 will support this 'special codes will represent special return conditions: '0=return from main to calling sub/function/proc by return [NULL]; '1... a global number representing a return point after a gosub 'note: RETURN [label] should fail if a "return [NULL];" type return is required OPEN tmpdir$ + "ret0.txt" FOR OUTPUT AS #15 PRINT #15, "if (next_return_point){" PRINT #15, "next_return_point--;" PRINT #15, "switch(return_point[next_return_point]){" PRINT #15, "case 0:" IF C_Core = 0 THEN PRINT #15, "return NULL;" IF C_Core = 1 THEN PRINT #15, "return;" PRINT #15, "break;" continueline = 0 endifs = 0 lineelseused = 0 continuelinefrom = 0 linenumber = 0 declaringlibrary = 0 PRINT #12, "S_0:;" 'note: REQUIRED by run statement IF UseGL THEN gl_include_content 'ide specific IF idemode THEN GOTO ideret3 DO ide4: includeline: prepass = 0 stringprocessinghappened = 0 IF continuelinefrom THEN start = continuelinefrom continuelinefrom = 0 GOTO contline END IF 'begin a new line impliedendif = 0 THENGOTO = 0 continueline = 0 endifs = 0 lineelseused = 0 newif = 0 'apply metacommands from previous line IF addmetadynamic = 1 THEN addmetadynamic = 0: DynamicMode = 1 IF addmetastatic = 1 THEN addmetastatic = 0: DynamicMode = 0 'a3$ is passed in idemode and when using $include IF idemode = 0 AND inclevel = 0 THEN a3$ = lineinput3$ IF a3$ = CHR$(13) THEN EXIT DO linenumber = linenumber + 1 layout = "" layoutok = 1 IF idemode = 0 THEN IF LEN(a3$) THEN dotlinecount = dotlinecount + 1: IF dotlinecount >= 100 THEN dotlinecount = 0: PRINT "."; END IF END IF a3$ = LTRIM$(RTRIM$(a3$)) wholeline = a3$ layoutoriginal$ = a3$ layoutcomment$ = "" 'clear any previous layout comment lhscontrollevel = controllevel linefragment = "[INFORMATION UNAVAILABLE]" IF LEN(a3$) = 0 THEN GOTO finishednonexec IF Debug THEN PRINT #9, "########" + a3$ + "########" layoutdone = 1 'validates layout of any following goto finishednonexec/finishedline 'QB64 Metacommands IF ASC(a3$) = 36 THEN '$ a3u$ = UCASE$(a3$) IF a3u$ = "$CHECKING:OFF" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** layout$ = "$CHECKING:OFF" NoChecks = 1 GOTO finishednonexec END IF IF a3u$ = "$CHECKING:ON" THEN layout$ = "$CHECKING:ON" NoChecks = 0 GOTO finishednonexec END IF IF a3u$ = "$CONSOLE" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** layout$ = "$CONSOLE" Console = 1 GOTO finishednonexec END IF IF a3u$ = "$SCREENHIDE" THEN layout$ = "$SCREENHIDE" ScreenHide = 1 GOTO finishednonexec END IF IF a3u$ = "$SCREENSHOW" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** layout$ = "$SCREENSHOW" ScreenHide = 0 GOTO finishednonexec END IF IF a3u$ = "$RESIZE:OFF" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** layout$ = "$RESIZE:OFF" Resize = 0: Resize_Scale = 0 GOTO finishednonexec END IF IF a3u$ = "$RESIZE:ON" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** layout$ = "$RESIZE:ON" Resize = 1: Resize_Scale = 0 GOTO finishednonexec END IF IF a3u$ = "$RESIZE:STRETCH" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** layout$ = "$RESIZE:STRETCH" Resize = 1: Resize_Scale = 1 GOTO finishednonexec END IF IF a3u$ = "$RESIZE:SMOOTH" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** layout$ = "$RESIZE:SMOOTH" Resize = 1: Resize_Scale = 2 GOTO finishednonexec END IF END IF 'QB64 Metacommands linedataoffset = DataOffset entireline$ = lineformat(a3$): IF LEN(entireline$) = 0 THEN GOTO finishednonexec IF Error_Happened THEN GOTO errmes u$ = UCASE$(entireline$) newif = 0 'Convert "CASE ELSE" to "CASE C-EL" to avoid confusing compiler 'note: CASE does not have to begin on a new line s = 1 i = INSTR(s, u$, "CASE" + sp + "ELSE") DO WHILE i skip = 0 IF i <> 1 THEN IF MID$(u$, i - 1, 1) <> sp THEN skip = 1 END IF IF i <> LEN(u$) - 8 THEN IF MID$(u$, i + 9, 1) <> sp THEN skip = 1 END IF IF skip = 0 THEN MID$(entireline$, i) = "CASE" + sp + "C-EL" u$ = UCASE$(entireline$) END IF s = i + 9 i = INSTR(s, u$, "CASE" + sp + "ELSE") LOOP n = numelements(entireline$) 'line number? a = ASC(entireline$) IF (a >= 48 AND a <= 57) OR a = 46 THEN 'numeric label$ = getelement(entireline$, 1) IF validlabel(label$) THEN v = HashFind(label$, HASHFLAG_LABEL, ignore, r) addlabchk100: IF v THEN s = Labels(r).Scope IF s = subfuncn OR s = -1 THEN 'same scope? IF s = -1 THEN Labels(r).Scope = subfuncn 'acquire scope IF Labels(r).State = 1 THEN a$ = "Duplicate label": GOTO errmes 'aquire state 0 types tlayout$ = RTRIM$(Labels(r).cn) GOTO addlabaq100 END IF 'same scope IF v = 2 THEN v = HashFindCont(ignore, r): GOTO addlabchk100 END IF 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd label$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).cn = tlayout$ Labels(r).Scope = subfuncn addlabaq100: Labels(r).State = 1 Labels(r).Data_Offset = linedataoffset layout$ = tlayout$ PRINT #12, "LABEL_" + label$ + ":;" IF INSTR(label$, "p") THEN MID$(label$, INSTR(label$, "p"), 1) = "." IF RIGHT$(label$, 1) = "d" OR RIGHT$(label$, 1) = "s" THEN label$ = LEFT$(label$, LEN(label$) - 1) PRINT #12, "last_line=" + label$ + ";" IF NoChecks = 0 THEN PRINT #12, "if(qbevent){evnt(" + str2$(linenumber) + ");r=0;}" END IF IF n = 1 THEN GOTO finishednonexec entireline$ = getelements(entireline$, 2, n): u$ = UCASE$(entireline$): n = n - 1 'note: fall through, numeric labels can be followed by alphanumeric label END IF 'validlabel END IF 'numeric 'it wasn't a line number 'label? 'note: ignores possibility that this could be a single command SUB/FUNCTION (as in QBASIC?) IF n >= 2 THEN x2 = INSTR(entireline$, sp + ":") IF x2 THEN IF x2 = LEN(entireline$) - 1 THEN x3 = x2 + 1 ELSE x3 = x2 + 2 a$ = LEFT$(entireline$, x2 - 1) CreatingLabel = 1 IF validlabel(a$) THEN IF validname(a$) = 0 THEN a$ = "Invalid name": GOTO errmes v = HashFind(a$, HASHFLAG_LABEL, ignore, r) addlabchk: IF v THEN s = Labels(r).Scope IF s = subfuncn OR s = -1 THEN 'same scope? IF s = -1 THEN Labels(r).Scope = subfuncn 'acquire scope IF Labels(r).State = 1 THEN a$ = "Duplicate label": GOTO errmes 'aquire state 0 types tlayout$ = RTRIM$(Labels(r).cn) GOTO addlabaq END IF 'same scope IF v = 2 THEN v = HashFindCont(ignore, r): GOTO addlabchk END IF 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd a$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).cn = tlayout$ Labels(r).Scope = subfuncn addlabaq: Labels(r).State = 1 Labels(r).Data_Offset = linedataoffset IF LEN(layout$) THEN layout$ = layout$ + sp + tlayout$ + ":" ELSE layout$ = tlayout$ + ":" PRINT #12, "LABEL_" + a$ + ":;" IF NoChecks = 0 THEN PRINT #12, "if(qbevent){evnt(" + str2$(linenumber) + ");r=0;}" END IF entireline$ = RIGHT$(entireline$, LEN(entireline$) - x3): u$ = UCASE$(entireline$) n = numelements(entireline$): IF n = 0 THEN GOTO finishednonexec END IF 'valid END IF 'includes sp+":" END IF 'n>=2 'remove leading ":" DO WHILE ASC(u$) = 58 '":" IF LEN(layout$) THEN layout$ = layout$ + sp2 + ":" ELSE layout$ = ":" IF LEN(u$) = 1 THEN GOTO finishednonexec entireline$ = getelements(entireline$, 2, n): u$ = UCASE$(entireline$): n = n - 1 LOOP 'ELSE at the beginning of a line IF ASC(u$) = 69 THEN '"E" e1$ = getelement(u$, 1) IF e1$ = "ELSE" THEN a$ = "ELSE" IF n > 1 THEN continuelinefrom = 2 GOTO gotcommand END IF IF e1$ = "ELSEIF" THEN IF n < 3 THEN a$ = "Expected ... THEN": GOTO errmes IF getelement(u$, n) = "THEN" THEN a$ = entireline$: GOTO gotcommand FOR i = 3 TO n - 1 IF getelement(u$, i) = "THEN" THEN a$ = getelements(entireline$, 1, i) continuelinefrom = i + 1 GOTO gotcommand END IF NEXT a$ = "Expected THEN": GOTO errmes END IF END IF '"E" start = 1 GOTO skipcontinit contline: n = numelements(entireline$) u$ = UCASE$(entireline$) skipcontinit: 'jargon: 'lineelseused - counts how many line ELSEs can POSSIBLY follow 'endifs - how many C++ endifs "}" need to be added at the end of the line 'lineelseused - counts the number of indwelling ELSE statements on a line 'impliedendif - stops autoformat from adding "END IF" a$ = "" FOR i = start TO n e$ = getelement(u$, i) IF e$ = ":" THEN IF i = start THEN layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp2 + ":" ELSE layout$ = ":" IF i <> n THEN continuelinefrom = i + 1 GOTO finishednonexec END IF IF i <> n THEN continuelinefrom = i GOTO gotcommand END IF 'begin scanning an 'IF' statement IF e$ = "IF" AND a$ = "" THEN newif = 1 IF e$ = "THEN" OR (e$ = "GOTO" AND newif = 1) THEN IF newif = 0 THEN a$ = "THEN without IF": GOTO errmes newif = 0 IF lineelseused > 0 THEN lineelseused = lineelseused - 1 IF e$ = "GOTO" THEN IF i = n THEN a$ = "Expected IF expression GOTO label": GOTO errmes i = i - 1 END IF a$ = a$ + sp + e$ '+"THEN"/"GOTO" IF i <> n THEN continuelinefrom = i + 1: endifs = endifs + 1 GOTO gotcommand END IF IF e$ = "ELSE" THEN IF start = i THEN IF lineelseused >= 1 THEN 'note: more than one else used (in a row) on this line, so close first if with an 'END IF' first 'note: parses 'END IF' then (after continuelinefrom) parses 'ELSE' 'consider the following: (square brackets make reading easier) 'eg. if a=1 then [if b=2 then c=2 else d=2] else e=3 impliedendif = 1: a$ = "END" + sp + "IF" endifs = endifs - 1 continuelinefrom = i lineelseused = lineelseused - 1 GOTO gotcommand END IF 'follow up previously encountered 'ELSE' by applying 'ELSE' a$ = "ELSE": continuelinefrom = i + 1 lineelseused = lineelseused + 1 GOTO gotcommand END IF 'start=i 'apply everything up to (but not including) 'ELSE' continuelinefrom = i GOTO gotcommand END IF '"ELSE" e$ = getelement(entireline$, i): IF a$ = "" THEN a$ = e$ ELSE a$ = a$ + sp + e$ NEXT 'we're reached the end of the line IF endifs > 0 THEN endifs = endifs - 1 impliedendif = 1: entireline$ = entireline$ + sp + ":" + sp + "END" + sp + "IF": n = n + 3 i = i + 1 'skip the ":" (i is now equal to n+2) continuelinefrom = i GOTO gotcommand END IF gotcommand: dynscope = 0 ca$ = a$ a$ = eleucase$(ca$) '***REVISE THIS SECTION LATER*** layoutdone = 0 linefragment = a$ IF Debug THEN PRINT #9, a$ n = numelements(a$) IF n = 0 THEN GOTO finishednonexec 'convert non-UDT dimensioned periods to _046_ IF INSTR(ca$, sp + "." + sp) THEN a3$ = getelement(ca$, 1) except = 0 aa$ = a3$ + sp 'rebuilt a$ (always has a trailing spacer) lastfuse = -1 FOR x = 2 TO n a2$ = getelement(ca$, x) IF except = 1 THEN except = 2: GOTO udtperiod 'skip element name IF a2$ = "." AND x <> n THEN IF except = 2 THEN except = 1: GOTO udtperiod 'sub-element of UDT IF a3$ = ")" THEN 'assume it was something like typevar(???).x and treat as a UDT except = 1 GOTO udtperiod END IF 'find an ID of that type try = findid(UCASE$(a3$)) IF Error_Happened THEN GOTO errmes DO WHILE try IF ((id.t AND ISUDT) <> 0) OR ((id.arraytype AND ISUDT) <> 0) THEN except = 1 GOTO udtperiod END IF IF try = 2 THEN findanotherid = 1: try = findid(UCASE$(a3$)) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP 'not a udt; fuse lhs & rhs with _046_ IF isalpha(ASC(a3$)) = 0 AND lastfuse <> x - 2 THEN a$ = "Invalid '.'": GOTO errmes aa$ = LEFT$(aa$, LEN(aa$) - 1) + fix046$ lastfuse = x GOTO periodfused END IF '"." except = 0 udtperiod: aa$ = aa$ + a2$ + sp periodfused: a3$ = a2$ NEXT a$ = LEFT$(aa$, LEN(aa$) - 1) ca$ = a$ a$ = eleucase$(ca$) n = numelements(a$) END IF arrayprocessinghappened = 0 firstelement$ = getelement(a$, 1) secondelement$ = getelement(a$, 2) thirdelement$ = getelement(a$, 3) 'non-executable section IF n = 1 THEN IF firstelement$ = "'" THEN layoutdone = 1: GOTO finishednonexec 'nop END IF IF n <= 2 THEN IF firstelement$ = "DATA" THEN l$ = firstelement$ IF n = 2 THEN e$ = SPACE$((LEN(secondelement$) - 1) \ 2) FOR x = 1 TO LEN(e$) v1 = ASC(secondelement$, x * 2) v2 = ASC(secondelement$, x * 2 + 1) IF v1 < 65 THEN v1 = v1 - 48 ELSE v1 = v1 - 55 IF v2 < 65 THEN v2 = v2 - 48 ELSE v2 = v2 - 55 ASC(e$, x) = v1 + v2 * 16 NEXT l$ = l$ + sp + e$ END IF 'n=2 layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF 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 l$ = "END" + sp + "DECLARE" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF 'end declare declaringlibrary = 2 IF firstelement$ = "SUB" OR firstelement$ = "FUNCTION" THEN GOTO declaresubfunc2 END IF a$ = "Expected SUB/FUNCTION definition or END DECLARE": GOTO errmes END IF 'declaringlibrary 'check TYPE declarations (created on prepass) IF definingtype THEN IF firstelement$ = "END" THEN IF n <> 2 OR secondelement$ <> "TYPE" THEN a$ = "Expected END TYPE": GOTO errmes definingtype = 0 l$ = "END" + sp + "TYPE" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF IF n < 3 OR secondelement$ <> "AS" THEN a$ = "Expected element-name AS type-name": GOTO errmes definingtype = 2 l$ = getelement(ca$, 1) + sp + "AS" t$ = getelements$(a$, 3, n) typ = typname2typ(t$) IF Error_Happened THEN GOTO errmes IF typ = 0 THEN a$ = "Undefined type": GOTO errmes IF typ AND ISUDT THEN t$ = RTRIM$(udtxcname(typ AND 511)) END IF l$ = l$ + sp + t$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF 'defining type IF firstelement$ = "TYPE" THEN IF n <> 2 THEN a$ = "Expected TYPE type-name": GOTO errmes l$ = "TYPE" + sp + getelement(ca$, 2) layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ definingtype = 1 definingtypeerror = linenumber GOTO finishednonexec END IF 'skip DECLARE SUB/FUNCTION IF n >= 1 THEN IF firstelement$ = "DECLARE" THEN IF secondelement$ = "LIBRARY" OR secondelement$ = "DYNAMIC" OR secondelement$ = "CUSTOMTYPE" OR secondelement$ = "STATIC" THEN declaringlibrary = 1 dynamiclibrary = 0 customtypelibrary = 0 indirectlibrary = 0 staticlinkedlibrary = 0 x = 3 l$ = "DECLARE" + sp + "LIBRARY" IF secondelement$ = "DYNAMIC" THEN e$ = getelement$(a$, 3): IF e$ <> "LIBRARY" THEN a$ = "Expected DYNAMIC LIBRARY " + CHR$(34) + "..." + CHR$(34): GOTO errmes dynamiclibrary = 1 x = 4 l$ = "DECLARE" + sp + "DYNAMIC" + sp + "LIBRARY" IF n = 3 THEN a$ = "Expected DECLARE DYNAMIC LIBRARY " + CHR$(34) + "..." + CHR$(34): GOTO errmes indirectlibrary = 1 END IF IF secondelement$ = "CUSTOMTYPE" THEN e$ = getelement$(a$, 3): IF e$ <> "LIBRARY" THEN a$ = "Expected CUSTOMTYPE LIBRARY": GOTO errmes customtypelibrary = 1 x = 4 l$ = "DECLARE" + sp + "CUSTOMTYPE" + sp + "LIBRARY" indirectlibrary = 1 END IF IF secondelement$ = "STATIC" THEN e$ = getelement$(a$, 3): IF e$ <> "LIBRARY" THEN a$ = "Expected STATIC LIBRARY": GOTO errmes x = 4 l$ = "DECLARE" + sp + "STATIC" + sp + "LIBRARY" staticlinkedlibrary = 1 END IF sfdeclare = 0: sfheader = 0 IF n >= x THEN sfdeclare = 1 addlibrary: libname$ = "" headername$ = "" 'assume library name in double quotes follows 'assume library is in main qb64 folder x$ = getelement$(ca$, x) IF ASC(x$) <> 34 THEN a$ = "Expected LIBRARY " + CHR$(34) + "..." + CHR$(34): GOTO errmes x$ = RIGHT$(x$, LEN(x$) - 1) z = INSTR(x$, CHR$(34)) IF z = 0 THEN a$ = "Expected LIBRARY " + CHR$(34) + "..." + CHR$(34): GOTO errmes x$ = LEFT$(x$, z - 1) IF dynamiclibrary <> 0 AND LEN(x$) = 0 THEN a$ = "Expected DECLARE DYNAMIC LIBRARY " + CHR$(34) + "..." + CHR$(34): GOTO errmes IF customtypelibrary <> 0 AND LEN(x$) = 0 THEN a$ = "Expected DECLARE CUSTOMTYPE LIBRARY " + CHR$(34) + "..." + CHR$(34): GOTO errmes 'convert '\\' to '\' WHILE INSTR(x$, "\\") z = INSTR(x$, "\\") x$ = LEFT$(x$, z - 1) + RIGHT$(x$, LEN(x$) - z) WEND autoformat_x$ = x$ 'used for autolayout purposes 'Remove version number from library name 'Eg. libname:1.0 becomes libname <-> 1.0 which later becomes libname.so.1.0 v$ = "" striplibver: FOR z = LEN(x$) TO 1 STEP -1 a = ASC(x$, z) IF a = ASC_BACKSLASH OR a = ASC_FORWARDSLASH THEN EXIT FOR IF a = ASC_FULLSTOP OR a = ASC_COLON THEN IF isuinteger(RIGHT$(x$, LEN(x$) - z)) THEN IF LEN(v$) THEN v$ = RIGHT$(x$, LEN(x$) - z) + "." + v$ ELSE v$ = RIGHT$(x$, LEN(x$) - z) x$ = LEFT$(x$, z - 1) IF a = ASC_COLON THEN EXIT FOR GOTO striplibver ELSE EXIT FOR END IF END IF NEXT libver$ = v$ IF os$ = "WIN" THEN 'convert forward-slashes to back-slashes DO WHILE INSTR(x$, "/") z = INSTR(x$, "/") x$ = LEFT$(x$, z - 1) + "\" + RIGHT$(x$, LEN(x$) - z) LOOP END IF IF os$ = "LNX" THEN 'convert any back-slashes to forward-slashes DO WHILE INSTR(x$, "\") z = INSTR(x$, "\") x$ = LEFT$(x$, z - 1) + "/" + RIGHT$(x$, LEN(x$) - z) LOOP END IF 'Seperate path from name libpath$ = "" FOR z = LEN(x$) TO 1 STEP -1 a = ASC(x$, z) IF a = 47 OR a = 92 THEN '\ or / libpath$ = LEFT$(x$, z) x$ = RIGHT$(x$, LEN(x$) - z) EXIT FOR END IF NEXT 'Create a path which can be used for inline code (uses \\ instead of \) libpath_inline$ = "" FOR z = 1 TO LEN(libpath$) a = ASC(libpath$, z) libpath_inline$ = libpath_inline$ + CHR$(a) IF a = 92 THEN libpath_inline$ = libpath_inline$ + "\" NEXT IF LEN(x$) THEN IF dynamiclibrary = 0 THEN 'Static library IF os$ = "WIN" THEN 'check for .lib IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + x$ + ".lib") THEN libname$ = libpath$ + x$ + ".lib" inlinelibname$ = libpath_inline$ + x$ + ".lib" END IF END IF 'check for .a IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + x$ + ".a") THEN libname$ = libpath$ + x$ + ".a" inlinelibname$ = libpath_inline$ + x$ + ".a" END IF END IF 'check for .o IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + x$ + ".o") THEN libname$ = libpath$ + x$ + ".o" inlinelibname$ = libpath_inline$ + x$ + ".o" END IF END IF 'check for .lib IF LEN(libname$) = 0 THEN IF _FILEEXISTS(x$ + ".lib") THEN libname$ = x$ + ".lib" inlinelibname$ = x$ + ".lib" END IF END IF 'check for .a IF LEN(libname$) = 0 THEN IF _FILEEXISTS(x$ + ".a") THEN libname$ = x$ + ".a" inlinelibname$ = x$ + ".a" END IF END IF 'check for .o IF LEN(libname$) = 0 THEN IF _FILEEXISTS(x$ + ".o") THEN libname$ = x$ + ".o" inlinelibname$ = x$ + ".o" END IF END IF END IF 'Windows IF os$ = "LNX" THEN IF staticlinkedlibrary = 0 THEN IF MacOSX THEN 'dylib support 'check for .dylib (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = libpath$ + "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = libpath_inline$ + "lib" + x$ + "." + libver$ + ".dylib" IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath " + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".dylib") THEN libname$ = libpath$ + "lib" + x$ + ".dylib" inlinelibname$ = libpath_inline$ + "lib" + x$ + ".dylib" IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath " + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF END IF 'check for .so (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".so." + libver$) THEN libname$ = libpath$ + "lib" + x$ + ".so." + libver$ inlinelibname$ = libpath_inline$ + "lib" + x$ + ".so." + libver$ IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath " + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".so") THEN libname$ = libpath$ + "lib" + x$ + ".so" inlinelibname$ = libpath_inline$ + "lib" + x$ + ".so" IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath " + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF END IF 'check for .a (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".a") THEN libname$ = libpath$ + "lib" + x$ + ".a" inlinelibname$ = libpath_inline$ + "lib" + x$ + ".a" END IF END IF 'check for .o (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".o") THEN libname$ = libpath$ + "lib" + x$ + ".o" inlinelibname$ = libpath_inline$ + "lib" + x$ + ".o" END IF END IF IF staticlinkedlibrary = 0 THEN 'check for .so (usr/lib64) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + libpath$ + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib64/" + libpath$ + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib64/" + libpath_inline$ + "lib" + x$ + ".so." + libver$ IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib64/" + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib64/ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + libpath$ + "lib" + x$ + ".so") THEN libname$ = "/usr/lib64/" + libpath$ + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib64/" + libpath_inline$ + "lib" + x$ + ".so" IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib64/" + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib64/ " END IF END IF END IF 'check for .a (usr/lib64) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + libpath$ + "lib" + x$ + ".a") THEN libname$ = "/usr/lib64/" + libpath$ + "lib" + x$ + ".a" inlinelibname$ = "/usr/lib64/" + libpath_inline$ + "lib" + x$ + ".a" END IF END IF IF staticlinkedlibrary = 0 THEN IF MacOSX THEN 'dylib support 'check for .dylib (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + "." + libver$ + ".dylib" IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/" + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + ".dylib") THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + ".dylib" inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + ".dylib" IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/" + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/ " END IF END IF END IF 'check for .so (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + ".so." + libver$ IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/" + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + ".so") THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + ".so" IF LEN(libpath$) THEN mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/" + libpath$ + " " ELSE mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/ " END IF END IF END IF 'check for .a (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + ".a") THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + ".a" inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + ".a" END IF END IF '--------------------------(without path)------------------------------ IF staticlinkedlibrary = 0 THEN IF MacOSX THEN 'dylib support 'check for .dylib (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = "lib" + x$ + "." + libver$ + ".dylib" mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".dylib") THEN libname$ = "lib" + x$ + ".dylib" inlinelibname$ = "lib" + x$ + ".dylib" mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF END IF 'check for .so (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".so." + libver$) THEN libname$ = "lib" + x$ + ".so." + libver$ inlinelibname$ = "lib" + x$ + ".so." + libver$ mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".so") THEN libname$ = "lib" + x$ + ".so" inlinelibname$ = "lib" + x$ + ".so" mylibopt$ = mylibopt$ + " -Wl,-rpath ./ " END IF END IF END IF 'check for .a (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".a") THEN libname$ = "lib" + x$ + ".a" inlinelibname$ = "lib" + x$ + ".a" END IF END IF 'check for .o (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".o") THEN libname$ = "lib" + x$ + ".o" inlinelibname$ = "lib" + x$ + ".o" END IF END IF IF staticlinkedlibrary = 0 THEN 'check for .so (usr/lib64) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib64/" + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib64/" + "lib" + x$ + ".so." + libver$ mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib64/ " END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + "lib" + x$ + ".so") THEN libname$ = "/usr/lib64/" + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib64/" + "lib" + x$ + ".so" mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib64/ " END IF END IF END IF 'check for .a (usr/lib64) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + "lib" + x$ + ".a") THEN libname$ = "/usr/lib64/" + "lib" + x$ + ".a" inlinelibname$ = "/usr/lib64/" + "lib" + x$ + ".a" END IF END IF IF staticlinkedlibrary = 0 THEN IF MacOSX THEN 'dylib support 'check for .dylib (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = "/usr/lib/" + "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = "/usr/lib/" + "lib" + x$ + "." + libver$ + ".dylib" END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + ".dylib") THEN libname$ = "/usr/lib/" + "lib" + x$ + ".dylib" inlinelibname$ = "/usr/lib/" + "lib" + x$ + ".dylib" mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/ " END IF END IF END IF 'check for .so (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib/" + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib/" + "lib" + x$ + ".so." + libver$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + ".so") THEN libname$ = "/usr/lib/" + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib/" + "lib" + x$ + ".so" mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/ " END IF END IF END IF 'check for .a (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + ".a") THEN libname$ = "/usr/lib/" + "lib" + x$ + ".a" inlinelibname$ = "/usr/lib/" + "lib" + x$ + ".a" mylibopt$ = mylibopt$ + " -Wl,-rpath /usr/lib/ " END IF END IF END IF 'Linux 'check for header IF LEN(headername$) = 0 THEN IF os$ = "WIN" THEN IF _FILEEXISTS(libpath$ + x$ + ".h") THEN headername$ = libpath_inline$ + x$ + ".h" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS(libpath$ + x$ + ".hpp") THEN headername$ = libpath_inline$ + x$ + ".hpp" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF '--------------------------(without path)------------------------------ IF _FILEEXISTS(x$ + ".h") THEN headername$ = x$ + ".h" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS(x$ + ".hpp") THEN headername$ = x$ + ".hpp" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF END IF 'Windows IF os$ = "LNX" THEN IF _FILEEXISTS(libpath$ + x$ + ".h") THEN headername$ = libpath_inline$ + x$ + ".h" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS(libpath$ + x$ + ".hpp") THEN headername$ = libpath_inline$ + x$ + ".hpp" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS("/usr/include/" + libpath$ + x$ + ".h") THEN headername$ = "/usr/include/" + libpath_inline$ + x$ + ".h" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS("/usr/include/" + libpath$ + x$ + ".hpp") THEN headername$ = "/usr/include/" + libpath_inline$ + x$ + ".hpp" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF '--------------------------(without path)------------------------------ IF _FILEEXISTS(x$ + ".h") THEN headername$ = x$ + ".h" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS(x$ + ".hpp") THEN headername$ = x$ + ".hpp" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS("/usr/include/" + x$ + ".h") THEN headername$ = "/usr/include/" + x$ + ".h" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF IF _FILEEXISTS("/usr/include/" + x$ + ".hpp") THEN headername$ = "/usr/include/" + x$ + ".hpp" IF customtypelibrary = 0 THEN sfdeclare = 0 sfheader = 1 GOTO GotHeader END IF END IF 'Linux GotHeader: END IF ELSE 'dynamic library IF os$ = "WIN" THEN 'check for .dll (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + x$ + ".dll") THEN libname$ = libpath$ + x$ + ".dll" inlinelibname$ = libpath_inline$ + x$ + ".dll" END IF END IF 'check for .dll (system32) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(ENVIRON$("SYSTEMROOT") + "\System32\" + libpath$ + x$ + ".dll") THEN libname$ = libpath$ + x$ + ".dll" inlinelibname$ = libpath_inline$ + x$ + ".dll" END IF END IF '--------------------------(without path)------------------------------ 'check for .dll (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(x$ + ".dll") THEN libname$ = x$ + ".dll" inlinelibname$ = x$ + ".dll" END IF END IF 'check for .dll (system32) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(ENVIRON$("SYSTEMROOT") + "\System32\" + x$ + ".dll") THEN libname$ = x$ + ".dll" inlinelibname$ = x$ + ".dll" END IF END IF END IF 'Windows IF os$ = "LNX" THEN 'Note: STATIC libraries (.a/.o) cannot be loaded as dynamic objects IF MacOSX THEN 'dylib support 'check for .dylib (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = libpath$ + "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = libpath_inline$ + "lib" + x$ + "." + libver$ + ".dylib" IF LEFT$(libpath$, 1) <> "/" THEN libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".dylib") THEN libname$ = libpath$ + "lib" + x$ + ".dylib" inlinelibname$ = libpath_inline$ + "lib" + x$ + ".dylib" IF LEFT$(libpath$, 1) <> "/" THEN libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF END IF 'check for .so (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".so." + libver$) THEN libname$ = libpath$ + "lib" + x$ + ".so." + libver$ inlinelibname$ = libpath_inline$ + "lib" + x$ + ".so." + libver$ IF LEFT$(libpath$, 1) <> "/" THEN libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS(libpath$ + "lib" + x$ + ".so") THEN libname$ = libpath$ + "lib" + x$ + ".so" inlinelibname$ = libpath_inline$ + "lib" + x$ + ".so" IF LEFT$(libpath$, 1) <> "/" THEN libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF 'check for .so (usr/lib64) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + libpath$ + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib64/" + libpath$ + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib64/" + libpath_inline$ + "lib" + x$ + ".so." + libver$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + libpath$ + "lib" + x$ + ".so") THEN libname$ = "/usr/lib64/" + libpath$ + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib64/" + libpath_inline$ + "lib" + x$ + ".so" END IF END IF IF MacOSX THEN 'dylib support 'check for .dylib (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + "." + libver$ + ".dylib" END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + ".dylib") THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + ".dylib" inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + ".dylib" END IF END IF END IF 'check for .so (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + ".so." + libver$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + libpath$ + "lib" + x$ + ".so") THEN libname$ = "/usr/lib/" + libpath$ + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib/" + libpath_inline$ + "lib" + x$ + ".so" END IF END IF '--------------------------(without path)------------------------------ IF MacOSX THEN 'dylib support 'check for .dylib (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = "lib" + x$ + "." + libver$ + ".dylib" libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".dylib") THEN libname$ = "lib" + x$ + ".dylib" inlinelibname$ = "lib" + x$ + ".dylib" libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF END IF 'check for .so (direct) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".so." + libver$) THEN libname$ = "lib" + x$ + ".so." + libver$ inlinelibname$ = "lib" + x$ + ".so." + libver$ libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("lib" + x$ + ".so") THEN libname$ = "lib" + x$ + ".so" inlinelibname$ = "lib" + x$ + ".so" libname$ = "./" + libname$: inlinelibname$ = "./" + inlinelibname$ END IF END IF 'check for .so (usr/lib64) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib64/" + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib64/" + "lib" + x$ + ".so." + libver$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib64/" + "lib" + x$ + ".so") THEN libname$ = "/usr/lib64/" + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib64/" + "lib" + x$ + ".so" END IF END IF IF MacOSX THEN 'dylib support 'check for .dylib (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + "." + libver$ + ".dylib") THEN libname$ = "/usr/lib/" + "lib" + x$ + "." + libver$ + ".dylib" inlinelibname$ = "/usr/lib/" + "lib" + x$ + "." + libver$ + ".dylib" END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + ".dylib") THEN libname$ = "/usr/lib/" + "lib" + x$ + ".dylib" inlinelibname$ = "/usr/lib/" + "lib" + x$ + ".dylib" END IF END IF END IF 'check for .so (usr/lib) IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + ".so." + libver$) THEN libname$ = "/usr/lib/" + "lib" + x$ + ".so." + libver$ inlinelibname$ = "/usr/lib/" + "lib" + x$ + ".so." + libver$ END IF END IF IF LEN(libname$) = 0 THEN IF _FILEEXISTS("/usr/lib/" + "lib" + x$ + ".so") THEN libname$ = "/usr/lib/" + "lib" + x$ + ".so" inlinelibname$ = "/usr/lib/" + "lib" + x$ + ".so" END IF END IF END IF 'Linux END IF 'Dynamic 'library found? IF dynamiclibrary <> 0 AND LEN(libname$) = 0 THEN a$ = "DYNAMIC LIBRARY not found": GOTO errmes IF LEN(libname$) = 0 AND LEN(headername$) = 0 THEN a$ = "LIBRARY not found": GOTO errmes '***actual method should cull redundant header and library entries*** IF dynamiclibrary = 0 THEN 'static IF LEN(libname$) THEN IF os$ = "WIN" THEN mylib$ = mylib$ + " ..\..\" + libname$ + " " END IF IF os$ = "LNX" THEN IF LEFT$(libname$, 1) = "/" THEN mylib$ = mylib$ + " " + libname$ + " " ELSE mylib$ = mylib$ + " ../../" + libname$ + " " END IF END IF END IF ELSE 'dynamic IF LEN(headername$) = 0 THEN 'no header IF subfuncn THEN f = FREEFILE OPEN tmpdir$ + "maindata.txt" FOR APPEND AS #f ELSE f = 13 END IF 'make name a C-appropriate variable name 'by converting everything except numbers and 'letters to underscores x2$ = x$ FOR x2 = 1 TO LEN(x2$) IF ASC(x2$, x2) < 48 THEN ASC(x2$, x2) = 95 IF ASC(x2$, x2) > 57 AND ASC(x2$, x2) < 65 THEN ASC(x2$, x2) = 95 IF ASC(x2$, x2) > 90 AND ASC(x2$, x2) < 97 THEN ASC(x2$, x2) = 95 IF ASC(x2$, x2) > 122 THEN ASC(x2$, x2) = 95 NEXT DLLname$ = x2$ IF sfdeclare THEN IF os$ = "WIN" THEN PRINT #17, "HINSTANCE DLL_" + x2$ + "=NULL;" PRINT #f, "if (!DLL_" + x2$ + "){" PRINT #f, "DLL_" + x2$ + "=LoadLibrary(" + CHR$(34) + inlinelibname$ + CHR$(34) + ");" PRINT #f, "if (!DLL_" + x2$ + ") error(259);" PRINT #f, "}" END IF IF os$ = "LNX" THEN PRINT #17, "void *DLL_" + x2$ + "=NULL;" PRINT #f, "if (!DLL_" + x2$ + "){" PRINT #f, "DLL_" + x2$ + "=dlopen(" + CHR$(34) + inlinelibname$ + CHR$(34) + ",RTLD_LAZY);" PRINT #f, "if (!DLL_" + x2$ + ") error(259);" PRINT #f, "}" END IF END IF IF subfuncn THEN CLOSE #f END IF 'no header END IF 'dynamiclibrary IF LEN(headername$) THEN IF os$ = "WIN" THEN PRINT #17, "#include " + CHR$(34) + "..\\..\\" + headername$ + CHR$(34) END IF IF os$ = "LNX" THEN IF LEFT$(headername$, 1) = "/" THEN PRINT #17, "#include " + CHR$(34) + headername$ + CHR$(34) ELSE PRINT #17, "#include " + CHR$(34) + "../../" + headername$ + CHR$(34) END IF END IF END IF END IF l$ = l$ + sp + CHR$(34) + autoformat_x$ + CHR$(34) IF n > x THEN IF dynamiclibrary THEN a$ = "Cannot specify multiple DYNAMIC LIBRARY names in a single DECLARE statement": GOTO errmes x = x + 1: x2$ = getelement$(a$, x): IF x2$ <> "," THEN a$ = "Expected ,": GOTO errmes l$ = l$ + sp2 + "," x = x + 1: IF x > n THEN a$ = "Expected , ...": GOTO errmes GOTO addlibrary END IF END IF 'n>=x layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF GOTO finishednonexec 'note: no layout required END IF END IF 'begin SUB/FUNCTION IF n >= 1 THEN dynamiclibrary = 0 declaresubfunc2: sf = 0 IF firstelement$ = "FUNCTION" THEN sf = 1 IF firstelement$ = "SUB" THEN sf = 2 IF sf THEN IF declaringlibrary = 0 THEN IF LEN(subfunc) THEN a$ = "Expected END SUB/FUNCTION before " + firstelement$: GOTO errmes END IF IF n = 1 THEN a$ = "Expected name after SUB/FUNCTION": GOTO errmes e$ = getelement$(ca$, 2) symbol$ = removesymbol$(e$) '$,%,etc. IF Error_Happened THEN GOTO errmes IF sf = 2 AND symbol$ <> "" THEN a$ = "Type symbols after a SUB name are invalid": GOTO errmes try = findid(e$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.subfunc = sf THEN GOTO createsf IF try = 2 THEN findanotherid = 1: try = findid(e$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP a$ = "Unregistered SUB/FUNCTION encountered": GOTO errmes createsf: IF UCASE$(e$) = "_GL" THEN e$ = "_GL" l$ = firstelement$ + sp + e$ + symbol$ id2 = id targetid = currentid 'check for ALIAS aliasname$ = RTRIM$(id.cn) IF n > 2 THEN ee$ = getelement$(a$, 3) IF ee$ = "ALIAS" THEN IF declaringlibrary = 0 THEN a$ = "ALIAS can only be used with DECLARE LIBRARY": GOTO errmes IF n = 3 THEN a$ = "Expected ALIAS name-in-library": GOTO errmes ee$ = getelement$(ca$, 4) 'strip string content (optional) IF LEFT$(ee$, 1) = CHR$(34) THEN ee$ = RIGHT$(ee$, LEN(ee$) - 1) x = INSTR(ee$, CHR$(34)): IF x = 0 THEN a$ = "Expected " + CHR$(34): GOTO errmes ee$ = LEFT$(ee$, x - 1) l$ = l$ + sp + "ALIAS" + sp + CHR_QUOTE + ee$ + CHR_QUOTE ELSE l$ = l$ + sp + "ALIAS" + sp + ee$ END IF 'strip fix046$ (created by unquoted periods) DO WHILE INSTR(ee$, fix046$) x = INSTR(ee$, fix046$): ee$ = LEFT$(ee$, x - 1) + "." + RIGHT$(ee$, LEN(ee$) - x + 1 - LEN(fix046$)) LOOP aliasname$ = ee$ 'remove ALIAS section from line IF n <= 4 THEN a$ = getelements(a$, 1, 2) IF n >= 5 THEN a$ = getelements(a$, 1, 2) + sp + getelements(a$, 5, n) IF n <= 4 THEN ca$ = getelements(ca$, 1, 2) IF n >= 5 THEN ca$ = getelements(ca$, 1, 2) + sp + getelements(ca$, 5, n) n = n - 2 END IF END IF IF declaringlibrary THEN GOTO declibjmp1 IF closedmain = 0 THEN closemain 'check for open controls (copy #2) IF controllevel THEN x = controltype(controllevel) IF x = 1 THEN a$ = "IF without END IF" IF x = 2 THEN a$ = "FOR without NEXT" IF x = 3 OR x = 4 THEN a$ = "DO without LOOP" IF x = 5 THEN a$ = "WHILE without WEND" IF (x >= 10 AND x <= 17) OR x = 18 OR x = 19 THEN a$ = "SELECT CASE without END SELECT" linenumber = controlref(controllevel) GOTO errmes END IF subfunc = RTRIM$(id.callname) 'SUB_..." subfuncn = subfuncn + 1 subfuncid = targetid subfuncret$ = "" CLOSE #13: OPEN tmpdir$ + "data" + str2$(subfuncn) + ".txt" FOR OUTPUT AS #13 CLOSE #19: OPEN tmpdir$ + "free" + str2$(subfuncn) + ".txt" FOR OUTPUT AS #19 CLOSE #15: OPEN tmpdir$ + "ret" + str2$(subfuncn) + ".txt" FOR OUTPUT AS #15 PRINT #15, "if (next_return_point){" PRINT #15, "next_return_point--;" PRINT #15, "switch(return_point[next_return_point]){" PRINT #15, "case 0:" PRINT #15, "error(3);" 'return without gosub! PRINT #15, "break;" defdatahandle = 13 declibjmp1: IF declaringlibrary THEN IF sfdeclare = 0 AND indirectlibrary = 0 THEN CLOSE #17 OPEN tmpdir$ + "regsf_ignore.txt" FOR OUTPUT AS #17 END IF IF sfdeclare = 1 AND customtypelibrary = 0 AND dynamiclibrary = 0 AND indirectlibrary = 0 THEN PRINT #17, "#include " + CHR$(34) + "externtype" + str2(ResolveStaticFunctions + 1) + ".txt" + CHR$(34) fh = FREEFILE: OPEN tmpdir$ + "externtype" + str2(ResolveStaticFunctions + 1) + ".txt" FOR OUTPUT AS #fh: CLOSE #fh END IF END IF IF sf = 1 THEN rettyp = id.ret t$ = typ2ctyp$(id.ret, "") IF Error_Happened THEN GOTO errmes IF t$ = "qbs" THEN t$ = "qbs*" IF declaringlibrary THEN IF rettyp AND ISSTRING THEN t$ = "char*" END IF END IF IF declaringlibrary <> 0 AND dynamiclibrary <> 0 THEN IF os$ = "WIN" THEN PRINT #17, "typedef " + t$ + " (CALLBACK* DLLCALL_" + removecast$(RTRIM$(id.callname)) + ")("; END IF IF os$ = "LNX" THEN PRINT #17, "typedef " + t$ + " (*DLLCALL_" + removecast$(RTRIM$(id.callname)) + ")("; END IF ELSEIF declaringlibrary <> 0 AND customtypelibrary <> 0 THEN PRINT #17, "typedef " + t$ + " CUSTOMCALL_" + removecast$(RTRIM$(id.callname)) + "("; ELSE PRINT #17, t$ + " " + removecast$(RTRIM$(id.callname)) + "("; END IF IF declaringlibrary THEN GOTO declibjmp2 PRINT #12, t$ + " " + removecast$(RTRIM$(id.callname)) + "("; 'create variable to return result 'if type wasn't specified, define it IF symbol$ = "" THEN a = ASC(UCASE$(e$)): IF a = 95 THEN a = 91 a = a - 64 'so A=1, Z=27 and _=28 symbol$ = defineextaz(a) END IF reginternalvariable = 1 ignore = dim2(e$, symbol$, 0, "") IF Error_Happened THEN GOTO errmes reginternalvariable = 0 'the following line stops the return variable from being free'd before being returned CLOSE #19: OPEN tmpdir$ + "free" + str2$(subfuncn) + ".txt" FOR OUTPUT AS #19 'create return IF (rettyp AND ISSTRING) THEN r$ = refer$(str2$(currentid), id.t, 1) IF Error_Happened THEN GOTO errmes subfuncret$ = subfuncret$ + "qbs_maketmp(" + r$ + ");" subfuncret$ = subfuncret$ + "return " + r$ + ";" ELSE r$ = refer$(str2$(currentid), id.t, 0) IF Error_Happened THEN GOTO errmes subfuncret$ = "return " + r$ + ";" END IF ELSE IF declaringlibrary <> 0 AND dynamiclibrary <> 0 THEN IF os$ = "WIN" THEN PRINT #17, "typedef void (CALLBACK* DLLCALL_" + removecast$(RTRIM$(id.callname)) + ")("; END IF IF os$ = "LNX" THEN PRINT #17, "typedef void (*DLLCALL_" + removecast$(RTRIM$(id.callname)) + ")("; END IF ELSEIF declaringlibrary <> 0 AND customtypelibrary <> 0 THEN PRINT #17, "typedef void CUSTOMCALL_" + removecast$(RTRIM$(id.callname)) + "("; ELSE PRINT #17, "void " + removecast$(RTRIM$(id.callname)) + "("; END IF IF declaringlibrary THEN GOTO declibjmp2 PRINT #12, "void " + removecast$(RTRIM$(id.callname)) + "("; END IF declibjmp2: addstatic2layout = 0 staticsf = 0 e$ = getelement$(a$, n) IF e$ = "STATIC" THEN IF declaringlibrary THEN a$ = "STATIC cannot be used in a library declaration": GOTO errmes addstatic2layout = 1 staticsf = 2 a$ = LEFT$(a$, LEN(a$) - 7): n = n - 1 'remove STATIC END IF 'check items to pass params = 0 AllowLocalName = 1 IF n > 2 THEN e$ = getelement$(a$, 3) IF e$ <> "(" THEN a$ = "Expected (": GOTO errmes e$ = getelement$(a$, n) IF e$ <> ")" THEN a$ = "Expected )": GOTO errmes l$ = l$ + sp + "(" IF n = 4 THEN GOTO nosfparams2 IF n < 4 THEN a$ = "Expected ( ... )": GOTO errmes B = 0 a2$ = "" FOR i = 4 TO n - 1 e$ = getelement$(ca$, i) IF e$ = "(" THEN B = B + 1 IF e$ = ")" THEN B = B - 1 IF e$ = "," AND B = 0 THEN IF i = n - 1 THEN a$ = "Expected , ... )": GOTO errmes getlastparam2: IF a2$ = "" THEN a$ = "Expected ... ,": GOTO errmes a2$ = LEFT$(a2$, LEN(a2$) - 1) 'possible format: [BYVAL]a[%][(1)][AS][type] params = params + 1 glinkid = targetid glinkarg = params IF params > 1 THEN PRINT #17, ","; IF declaringlibrary = 0 THEN PRINT #12, ","; END IF END IF n2 = numelements(a2$) array = 0 t2$ = "" e$ = getelement$(a2$, 1) byvalue = 0 IF UCASE$(e$) = "BYVAL" THEN IF declaringlibrary = 0 THEN a$ = "BYVAL can currently only be used with DECLARE LIBRARY": GOTO errmes byvalue = 1: a2$ = RIGHT$(a2$, LEN(a2$) - 6) IF RIGHT$(l$, 1) = "(" THEN l$ = l$ + sp2 + "BYVAL" ELSE l$ = l$ + sp + "BYVAL" n2 = numelements(a2$): e$ = getelement$(a2$, 1) END IF IF RIGHT$(l$, 1) = "(" THEN l$ = l$ + sp2 + e$ ELSE l$ = l$ + sp + e$ n2$ = e$ dimmethod = 0 symbol2$ = removesymbol$(n2$) IF validname(n2$) = 0 THEN a$ = "Invalid name": GOTO errmes IF Error_Happened THEN GOTO errmes IF symbol2$ <> "" THEN dimmethod = 1 m = 0 FOR i2 = 2 TO n2 e$ = getelement$(a2$, i2) IF e$ = "(" THEN IF m <> 0 THEN a$ = "Syntax error": GOTO errmes m = 1 array = 1 l$ = l$ + sp2 + "(" GOTO gotaa2 END IF IF e$ = ")" THEN IF m <> 1 THEN a$ = "Syntax error": GOTO errmes m = 2 l$ = l$ + sp2 + ")" GOTO gotaa2 END IF IF UCASE$(e$) = "AS" THEN IF m <> 0 AND m <> 2 THEN a$ = "Syntax error": GOTO errmes m = 3 l$ = l$ + sp + "AS" GOTO gotaa2 END IF IF m = 1 THEN l$ = l$ + sp + e$: GOTO gotaa2 'ignore contents of option bracket telling how many dimensions (add to layout as is) IF m <> 3 THEN a$ = "Syntax error": GOTO errmes IF t2$ = "" THEN t2$ = e$ ELSE t2$ = t2$ + " " + e$ gotaa2: NEXT i2 IF symbol2$ <> "" AND t2$ <> "" THEN a$ = "Syntax error": GOTO errmes IF LEN(t2$) THEN 'add type-name after AS t2$ = UCASE$(t2$) t3$ = t2$ typ = typname2typ(t3$) IF Error_Happened THEN GOTO errmes IF typ = 0 THEN a$ = "Undefined type": GOTO errmes IF typ AND ISUDT THEN t3$ = RTRIM$(udtxcname(typ AND 511)) ELSE FOR t3i = 1 TO LEN(t3i) IF ASC(t3$, t3i) = 32 THEN ASC(t3$, t3i) = ASC(sp) NEXT END IF l$ = l$ + sp + t3$ END IF IF t2$ = "" THEN t2$ = symbol2$ IF t2$ = "" THEN IF LEFT$(n2$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(n2$)) - 64 t2$ = defineaz(v) dimmethod = 1 END IF IF array = 1 THEN IF declaringlibrary THEN a$ = "Arrays cannot be passed to a library": GOTO errmes dimsfarray = 1 'note: id2.nele is currently 0 nelereq = ASC(MID$(id2.nelereq, params, 1)) IF nelereq THEN nele = nelereq MID$(id2.nele, params, 1) = CHR$(nele) ids(targetid) = id2 ignore = dim2(n2$, t2$, dimmethod, str2$(nele)) IF Error_Happened THEN GOTO errmes ELSE nele = 1 MID$(id2.nele, params, 1) = CHR$(nele) ids(targetid) = id2 ignore = dim2(n2$, t2$, dimmethod, "?") IF Error_Happened THEN GOTO errmes END IF dimsfarray = 0 r$ = refer$(str2$(currentid), id.t, 1) IF Error_Happened THEN GOTO errmes PRINT #17, "ptrszint*" + r$; PRINT #12, "ptrszint*" + r$; ELSE IF declaringlibrary THEN 'is it a udt? FOR xx = 1 TO lasttype IF t2$ = RTRIM$(udtxname(xx)) THEN PRINT #17, "void*" GOTO decudt END IF NEXT t$ = typ2ctyp$(0, t2$) IF Error_Happened THEN GOTO errmes IF t$ = "qbs" THEN t$ = "char*" IF byvalue = 1 THEN a$ = "STRINGs cannot be passed using BYVAL": GOTO errmes byvalue = 1 'use t$ as is END IF IF byvalue THEN PRINT #17, t$; ELSE PRINT #17, t$ + "*"; decudt: GOTO declibjmp3 END IF dimsfarray = 1 ignore = dim2(n2$, t2$, dimmethod, "") IF Error_Happened THEN GOTO errmes dimsfarray = 0 t$ = "" typ = id.t 'the typ of the ID created by dim2 t$ = typ2ctyp$(typ, "") IF Error_Happened THEN GOTO errmes IF t$ = "" THEN a$ = "Cannot find C type to return array data": GOTO errmes 'searchpoint 'get the name of the variable r$ = refer$(str2$(currentid), id.t, 1) IF Error_Happened THEN GOTO errmes PRINT #17, t$ + "*" + r$; PRINT #12, t$ + "*" + r$; IF t$ = "qbs" THEN u$ = str2$(uniquenumber) PRINT #13, "qbs*oldstr" + u$ + "=NULL;" PRINT #13, "if(" + r$ + "->tmp||" + r$ + "->fixed||" + r$ + "->readonly){" PRINT #13, "oldstr" + u$ + "=" + r$ + ";" PRINT #13, "if (oldstr" + u$ + "->cmem_descriptor){" PRINT #13, r$ + "=qbs_new_cmem(oldstr" + u$ + "->len,0);" PRINT #13, "}else{" PRINT #13, r$ + "=qbs_new(oldstr" + u$ + "->len,0);" PRINT #13, "}" PRINT #13, "memcpy(" + r$ + "->chr,oldstr" + u$ + "->chr,oldstr" + u$ + "->len);" PRINT #13, "}" PRINT #19, "if(oldstr" + u$ + "){" PRINT #19, "if(oldstr" + u$ + "->fixed)qbs_set(oldstr" + u$ + "," + r$ + ");" PRINT #19, "qbs_free(" + r$ + ");" PRINT #19, "}" END IF END IF declibjmp3: IF i <> n - 1 THEN l$ = l$ + sp2 + "," a2$ = "" ELSE a2$ = a2$ + e$ + sp IF i = n - 1 THEN GOTO getlastparam2 END IF NEXT i nosfparams2: l$ = l$ + sp2 + ")" END IF 'n>2 AllowLocalName = 0 IF addstatic2layout THEN l$ = l$ + sp + "STATIC" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ PRINT #17, ");" IF declaringlibrary THEN GOTO declibjmp4 PRINT #12, "){" PRINT #12, "qbs *tqbs;" PRINT #12, "ptrszint tmp_long;" PRINT #12, "int32 tmp_fileno;" PRINT #12, "uint32 qbs_tmp_base=qbs_tmp_list_nexti;" PRINT #12, "uint8 *tmp_mem_static_pointer=mem_static_pointer;" PRINT #12, "uint32 tmp_cmem_sp=cmem_sp;" PRINT #12, "#include " + CHR$(34) + "data" + str2$(subfuncn) + ".txt" + CHR$(34) 'create new _MEM lock for this scope PRINT #12, "mem_lock *sf_mem_lock;" 'MUST not be static for recursion reasons PRINT #12, "new_mem_lock();" PRINT #12, "sf_mem_lock=mem_lock_tmp;" PRINT #12, "sf_mem_lock->type=3;" PRINT #12, "if (new_error) goto exit_subfunc;" 'statementn = statementn + 1 'if nochecks=0 then PRINT #12, "S_" + str2$(statementn) + ":;" dimstatic = staticsf declibjmp4: IF declaringlibrary THEN IF customtypelibrary THEN callname$ = removecast$(RTRIM$(id2.callname)) PRINT #17, "CUSTOMCALL_" + callname$ + " *" + callname$ + "=NULL;" IF subfuncn THEN f = FREEFILE OPEN tmpdir$ + "maindata.txt" FOR APPEND AS #f ELSE f = 13 END IF PRINT #f, callname$ + "=(CUSTOMCALL_" + callname$ + "*)&" + aliasname$ + ";" IF subfuncn THEN CLOSE #f 'if no header exists to make the external function available, the function definition must be found IF sfheader = 0 AND sfdeclare <> 0 THEN ResolveStaticFunctions = ResolveStaticFunctions + 1 'expand array if necessary IF ResolveStaticFunctions > UBOUND(ResolveStaticFunction_Name) THEN REDIM _PRESERVE ResolveStaticFunction_Name(1 TO ResolveStaticFunctions + 100) AS STRING REDIM _PRESERVE ResolveStaticFunction_File(1 TO ResolveStaticFunctions + 100) AS STRING REDIM _PRESERVE ResolveStaticFunction_Method(1 TO ResolveStaticFunctions + 100) AS LONG END IF ResolveStaticFunction_File(ResolveStaticFunctions) = libname$ ResolveStaticFunction_Name(ResolveStaticFunctions) = aliasname$ ResolveStaticFunction_Method(ResolveStaticFunctions) = 1 END IF 'sfheader=0 END IF IF dynamiclibrary THEN IF sfdeclare THEN PRINT #17, "DLLCALL_" + removecast$(RTRIM$(id2.callname)) + " " + removecast$(RTRIM$(id2.callname)) + "=NULL;" IF subfuncn THEN f = FREEFILE OPEN tmpdir$ + "maindata.txt" FOR APPEND AS #f ELSE f = 13 END IF PRINT #f, "if (!" + removecast$(RTRIM$(id2.callname)) + "){" IF os$ = "WIN" THEN PRINT #f, removecast$(RTRIM$(id2.callname)) + "=(DLLCALL_" + removecast$(RTRIM$(id2.callname)) + ")GetProcAddress(DLL_" + DLLname$ + "," + CHR$(34) + aliasname$ + CHR$(34) + ");" PRINT #f, "if (!" + removecast$(RTRIM$(id2.callname)) + ") error(260);" END IF IF os$ = "LNX" THEN PRINT #f, removecast$(RTRIM$(id2.callname)) + "=(DLLCALL_" + removecast$(RTRIM$(id2.callname)) + ")dlsym(DLL_" + DLLname$ + "," + CHR$(34) + aliasname$ + CHR$(34) + ");" PRINT #f, "if (dlerror()) error(260);" END IF PRINT #f, "}" IF subfuncn THEN CLOSE #f END IF 'sfdeclare END IF 'dynamic IF sfdeclare = 1 AND customtypelibrary = 0 AND dynamiclibrary = 0 AND indirectlibrary = 0 THEN ResolveStaticFunctions = ResolveStaticFunctions + 1 'expand array if necessary IF ResolveStaticFunctions > UBOUND(ResolveStaticFunction_Name) THEN REDIM _PRESERVE ResolveStaticFunction_Name(1 TO ResolveStaticFunctions + 100) AS STRING REDIM _PRESERVE ResolveStaticFunction_File(1 TO ResolveStaticFunctions + 100) AS STRING REDIM _PRESERVE ResolveStaticFunction_Method(1 TO ResolveStaticFunctions + 100) AS LONG END IF ResolveStaticFunction_File(ResolveStaticFunctions) = libname$ ResolveStaticFunction_Name(ResolveStaticFunctions) = aliasname$ ResolveStaticFunction_Method(ResolveStaticFunctions) = 2 END IF IF sfdeclare = 0 AND indirectlibrary = 0 THEN CLOSE #17 OPEN tmpdir$ + "regsf.txt" FOR APPEND AS #17 END IF END IF 'declaring library GOTO finishednonexec END IF END IF 'END SUB/FUNCTION IF n = 2 THEN IF firstelement$ = "END" THEN sf = 0 IF secondelement$ = "FUNCTION" THEN sf = 1 IF secondelement$ = "SUB" THEN sf = 2 IF sf THEN IF LEN(subfunc) = 0 THEN a$ = "END " + secondelement$ + " without " + secondelement$: GOTO errmes 'check for open controls (copy #3) IF controllevel THEN x = controltype(controllevel) IF x = 1 THEN a$ = "IF without END IF" IF x = 2 THEN a$ = "FOR without NEXT" IF x = 3 OR x = 4 THEN a$ = "DO without LOOP" IF x = 5 THEN a$ = "WHILE without WEND" IF (x >= 10 AND x <= 17) OR x = 18 OR x = 19 THEN a$ = "SELECT CASE without END SELECT" linenumber = controlref(controllevel) GOTO errmes END IF l$ = firstelement$ + sp + secondelement$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ staticarraylist = "": staticarraylistn = 0 'remove previously listed arrays dimstatic = 0 PRINT #12, "exit_subfunc:;" 'release _MEM lock for this scope PRINT #12, "free_mem_lock(sf_mem_lock);" PRINT #12, "#include " + CHR$(34) + "free" + str2$(subfuncn) + ".txt" + CHR$(34) PRINT #12, "if ((tmp_mem_static_pointer>=mem_static)&&(tmp_mem_static_pointer<=mem_static_limit)) mem_static_pointer=tmp_mem_static_pointer; else mem_static_pointer=mem_static;" PRINT #12, "cmem_sp=tmp_cmem_sp;" IF subfuncret$ <> "" THEN PRINT #12, subfuncret$ PRINT #12, "}" 'skeleton sub 'ret???.txt PRINT #15, "}" 'end case PRINT #15, "}" PRINT #15, "error(3);" 'no valid return possible subfunc = "" 'unshare temp. shared variables FOR i = 1 TO idn IF ids(i).share AND 2 THEN ids(i).share = ids(i).share - 2 NEXT FOR i = 1 TO revertmaymusthaven x = revertmaymusthave(i) SWAP ids(x).musthave, ids(x).mayhave NEXT revertmaymusthaven = 0 'undeclare constants in sub/function's scope 'constlast = constlastshared GOTO finishednonexec END IF END IF END IF IF n >= 1 AND firstelement$ = "CONST" THEN l$ = "CONST" 'DEF... do not change type, the expression is stored in a suitable type 'based on its value if type isn't forced/specified IF n < 3 THEN a$ = "Expected CONST name = value/expression": GOTO errmes i = 2 constdefpending: pending = 0 n$ = getelement$(ca$, i): i = i + 1 l$ = l$ + sp + n$ + sp + "=" 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) <> "=" THEN a$ = "Expected =": GOTO errmes i = i + 1 'get expression 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$ = "Expected CONST ... , name = value/expression": GOTO errmes EXIT FOR END IF IF LEN(e$) = 0 THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ NEXT e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ 'Note: Actual CONST definition handled in prepass 'Set CONST as defined hashname$ = n$ hashchkflags = HASHFLAG_CONSTANT hashres = HashFind(hashname$, hashchkflags, hashresflags, hashresref) DO WHILE hashres IF constsubfunc(hashresref) = subfuncn THEN constdefined(hashresref) = 1: EXIT DO IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP IF pending THEN l$ = l$ + sp2 + ",": GOTO constdefpending layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF predefine: IF n >= 2 THEN asreq = 0 IF firstelement$ = "DEFINT" THEN a$ = a$ + sp + "AS" + sp + "INTEGER": n = n + 2: GOTO definetype IF firstelement$ = "DEFLNG" THEN a$ = a$ + sp + "AS" + sp + "LONG": n = n + 2: GOTO definetype IF firstelement$ = "DEFSNG" THEN a$ = a$ + sp + "AS" + sp + "SINGLE": n = n + 2: GOTO definetype IF firstelement$ = "DEFDBL" THEN a$ = a$ + sp + "AS" + sp + "DOUBLE": n = n + 2: GOTO definetype IF firstelement$ = "DEFSTR" THEN a$ = a$ + sp + "AS" + sp + "STRING": n = n + 2: GOTO definetype IF firstelement$ = "_DEFINE" THEN asreq = 1 definetype: l$ = firstelement$ 'get type from rhs typ$ = "" typ2$ = "" t$ = "" FOR i = n TO 2 STEP -1 t$ = getelement$(a$, i) IF t$ = "AS" THEN EXIT FOR typ$ = t$ + " " + typ$ typ2$ = t$ + sp + typ2$ NEXT typ$ = RTRIM$(typ$) IF t$ <> "AS" THEN a$ = "_DEFINE: Expected ... AS ...": GOTO errmes IF i = n OR i = 2 THEN a$ = "_DEFINE: Expected ... AS ...": GOTO errmes n = i - 1 'the data is from element 2 to element n i = 2 - 1 definenext: 'expects an alphabet letter or underscore i = i + 1: e$ = getelement$(a$, i): E = ASC(UCASE$(e$)) IF LEN(e$) > 1 THEN a$ = "_DEFINE: Expected an alphabet letter or the underscore character (_)": GOTO errmes IF E <> 95 AND (E > 90 OR E < 65) THEN a$ = "_DEFINE: Expected an alphabet letter or the underscore character (_)": GOTO errmes IF E = 95 THEN E = 27 ELSE E = E - 64 defineaz(E) = typ$ defineextaz(E) = type2symbol(typ$) IF Error_Happened THEN GOTO errmes firste = E l$ = l$ + sp + e$ IF i = n THEN IF predefining = 1 THEN GOTO predefined IF asreq THEN l$ = l$ + sp + "AS" + sp + typ2$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF 'expects "-" or "," i = i + 1: e$ = getelement$(a$, i) IF e$ <> "-" AND e$ <> "," THEN a$ = "_DEFINE: Expected - or ,": GOTO errmes IF e$ = "-" THEN l$ = l$ + sp2 + "-" IF i = n THEN a$ = "_DEFINE: Syntax incomplete": GOTO errmes 'expects an alphabet letter or underscore i = i + 1: e$ = getelement$(a$, i): E = ASC(UCASE$(e$)) IF LEN(e$) > 1 THEN a$ = "_DEFINE: Expected an alphabet letter or the underscore character (_)": GOTO errmes IF E <> 95 AND (E > 90 OR E < 65) THEN a$ = "_DEFINE: Expected an alphabet letter or the underscore character (_)": GOTO errmes IF E = 95 THEN E = 27 ELSE E = E - 64 IF firste > E THEN SWAP E, firste FOR e2 = firste TO E defineaz(e2) = typ$ defineextaz(e2) = type2symbol(typ$) IF Error_Happened THEN GOTO errmes NEXT l$ = l$ + sp2 + e$ IF i = n THEN IF predefining = 1 THEN GOTO predefined IF asreq THEN l$ = l$ + sp + "AS" + sp + typ2$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec END IF 'expects "," i = i + 1: e$ = getelement$(a$, i) IF e$ <> "," THEN a$ = "_DEFINE: Expected ,": GOTO errmes END IF l$ = l$ + sp2 + "," GOTO definenext END IF '_DEFINE END IF '2 IF predefining = 1 THEN GOTO predefined IF closedmain <> 0 AND subfunc = "" THEN a$ = "Statement cannot be placed between SUB/FUNCTIONs": GOTO errmes 'executable section: statementn = statementn + 1 IF n >= 1 THEN IF firstelement$ = "NEXT" THEN l$ = "NEXT" IF n = 1 THEN GOTO simplenext v$ = "" FOR i = 2 TO n a2$ = getelement(ca$, i) IF a2$ = "," THEN lastnextele: e$ = fixoperationorder(v$) IF Error_Happened THEN GOTO errmes IF LEN(l$) = 4 THEN l$ = l$ + sp + tlayout$ ELSE l$ = l$ + sp2 + "," + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN getid VAL(e$) IF Error_Happened THEN GOTO errmes IF (id.t AND ISPOINTER) THEN IF (id.t AND ISSTRING) = 0 THEN IF (id.t AND ISOFFSETINBITS) = 0 THEN IF (id.t AND ISARRAY) = 0 THEN GOTO fornextfoundvar2 END IF END IF END IF END IF END IF a$ = "Unsupported variable after NEXT": GOTO errmes fornextfoundvar2: simplenext: IF controltype(controllevel) <> 2 THEN a$ = "NEXT without FOR": GOTO errmes IF n <> 1 AND controlvalue(controllevel) <> currentid THEN a$ = "Incorrect variable after NEXT": GOTO errmes PRINT #12, "}" PRINT #12, "fornext_exit_" + str2$(controlid(controllevel)) + ":;" controllevel = controllevel - 1 IF n = 1 THEN EXIT FOR v$ = "" ELSE IF LEN(v$) THEN v$ = v$ + sp + a2$ ELSE v$ = a2$ IF i = n THEN GOTO lastnextele END IF NEXT layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec '***no error causing code, event checking done by FOR*** END IF END IF IF n >= 1 THEN IF firstelement$ = "WHILE" THEN IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 controllevel = controllevel + 1 controlref(controllevel) = linenumber controltype(controllevel) = 5 controlid(controllevel) = uniquenumber IF n >= 2 THEN e$ = fixoperationorder(getelements$(ca$, 2, n)) IF Error_Happened THEN GOTO errmes l$ = "WHILE" + sp + tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN e$ = refer$(e$, typ, 0) IF Error_Happened THEN GOTO errmes IF stringprocessinghappened THEN e$ = cleanupstringprocessingcall$ + e$ + ")" IF (typ AND ISSTRING) THEN a$ = "WHILE ERROR! Cannot accept a STRING type.": GOTO errmes PRINT #12, "while((" + e$ + ")||new_error){" ELSE a$ = "WHILE ERROR! Expected expression after WHILE.": GOTO errmes END IF GOTO finishedline END IF END IF IF n = 1 THEN IF firstelement$ = "WEND" THEN IF controltype(controllevel) <> 5 THEN a$ = "WEND without WHILE": GOTO errmes PRINT #12, "}" PRINT #12, "ww_exit_" + str2$(controlid(controllevel)) + ":;" controllevel = controllevel - 1 l$ = "WEND" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec '***no error causing code, event checking done by WHILE*** END IF END IF IF n >= 1 THEN IF firstelement$ = "DO" THEN IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 controllevel = controllevel + 1 controlref(controllevel) = linenumber l$ = "DO" IF n >= 2 THEN whileuntil = 0 IF secondelement$ = "WHILE" THEN whileuntil = 1: l$ = l$ + sp + "WHILE" IF secondelement$ = "UNTIL" THEN whileuntil = 2: l$ = l$ + sp + "UNTIL" IF whileuntil = 0 THEN a$ = "DO ERROR! Expected WHILE or UNTIL after DO.": GOTO errmes e$ = fixoperationorder(getelements$(ca$, 3, n)) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN e$ = refer$(e$, typ, 0) IF Error_Happened THEN GOTO errmes IF stringprocessinghappened THEN e$ = cleanupstringprocessingcall$ + e$ + ")" IF (typ AND ISSTRING) THEN a$ = "DO ERROR! Cannot accept a STRING type.": GOTO errmes IF whileuntil = 1 THEN PRINT #12, "while((" + e$ + ")||new_error){" ELSE PRINT #12, "while((!(" + e$ + "))||new_error){" controltype(controllevel) = 4 ELSE controltype(controllevel) = 3 PRINT #12, "do{" END IF controlid(controllevel) = uniquenumber layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF IF n >= 1 THEN IF firstelement$ = "LOOP" THEN l$ = "LOOP" IF controltype(controllevel) <> 3 AND controltype(controllevel) <> 4 THEN a$ = "PROGRAM FLOW ERROR!": GOTO errmes IF n >= 2 THEN IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 IF controltype(controllevel) = 4 THEN a$ = "PROGRAM FLOW ERROR!": GOTO errmes whileuntil = 0 IF secondelement$ = "WHILE" THEN whileuntil = 1: l$ = l$ + sp + "WHILE" IF secondelement$ = "UNTIL" THEN whileuntil = 2: l$ = l$ + sp + "UNTIL" IF whileuntil = 0 THEN a$ = "LOOP ERROR! Expected WHILE or UNTIL after LOOP.": GOTO errmes e$ = fixoperationorder(getelements$(ca$, 3, n)) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN e$ = refer$(e$, typ, 0) IF Error_Happened THEN GOTO errmes IF stringprocessinghappened THEN e$ = cleanupstringprocessingcall$ + e$ + ")" IF (typ AND ISSTRING) THEN a$ = "LOOP ERROR! Cannot accept a STRING type.": GOTO errmes IF whileuntil = 1 THEN PRINT #12, "}while((" + e$ + ")&&(!new_error));" ELSE PRINT #12, "}while((!(" + e$ + "))&&(!new_error));" ELSE IF controltype(controllevel) = 4 THEN PRINT #12, "}" ELSE PRINT #12, "}while(1);" 'infinite loop! END IF END IF PRINT #12, "dl_exit_" + str2$(controlid(controllevel)) + ":;" controllevel = controllevel - 1 layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ IF n = 1 THEN GOTO finishednonexec '***no error causing code, event checking done by DO*** GOTO finishedline END IF END IF IF n >= 1 THEN IF firstelement$ = "FOR" THEN IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 l$ = "FOR" controllevel = controllevel + 1 controlref(controllevel) = linenumber controltype(controllevel) = 2 controlid(controllevel) = uniquenumber v$ = "" startvalue$ = "" p3$ = "1": stepused = 0 p2$ = "" mode = 0 E = 0 FOR i = 2 TO n e$ = getelement$(a$, i) IF e$ = "=" THEN IF mode <> 0 THEN E = 1: EXIT FOR mode = 1 v$ = getelements$(ca$, 2, i - 1) equpos = i END IF IF e$ = "TO" THEN IF mode <> 1 THEN E = 1: EXIT FOR mode = 2 startvalue$ = getelements$(ca$, equpos + 1, i - 1) topos = i END IF IF e$ = "STEP" THEN IF mode <> 2 THEN E = 1: EXIT FOR mode = 3 stepused = 1 p2$ = getelements$(ca$, topos + 1, i - 1) p3$ = getelements$(ca$, i + 1, n) EXIT FOR END IF NEXT IF mode < 2 THEN E = 1 IF p2$ = "" THEN p2$ = getelements$(ca$, topos + 1, n) IF LEN(v$) = 0 OR LEN(startvalue$) = 0 OR LEN(p2$) = 0 THEN E = 1 IF E <> 0 AND mode < 3 THEN a$ = "Expected FOR name = start TO end": GOTO errmes IF E THEN a$ = "Expected FOR name = start TO end STEP increment": GOTO errmes e$ = fixoperationorder(v$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN getid VAL(e$) IF Error_Happened THEN GOTO errmes IF (id.t AND ISPOINTER) THEN IF (id.t AND ISSTRING) = 0 THEN IF (id.t AND ISOFFSETINBITS) = 0 THEN IF (id.t AND ISARRAY) = 0 THEN GOTO fornextfoundvar END IF END IF END IF END IF END IF a$ = "Unsupported variable used in FOR statement": GOTO errmes fornextfoundvar: controlvalue(controllevel) = currentid v$ = e$ 'find C++ datatype to match variable 'markup to cater for greater range/accuracy ctype$ = "" ctyp = typ - ISPOINTER bits = typ AND 511 IF (typ AND ISFLOAT) THEN IF bits = 32 THEN ctype$ = "double": ctyp = 64& + ISFLOAT IF bits = 64 THEN ctype$ = "long double": ctyp = 256& + ISFLOAT IF bits = 256 THEN ctype$ = "long double": ctyp = 256& + ISFLOAT ELSE IF bits = 8 THEN ctype$ = "int16": ctyp = 16& IF bits = 16 THEN ctype$ = "int32": ctyp = 32& IF bits = 32 THEN ctype$ = "int64": ctyp = 64& IF bits = 64 THEN ctype$ = "int64": ctyp = 64& END IF IF ctype$ = "" THEN a$ = "Unsupported variable used in FOR statement": GOTO errmes u$ = str2(uniquenumber) IF subfunc = "" THEN PRINT #13, "static " + ctype$ + " fornext_value" + u$ + ";" PRINT #13, "static " + ctype$ + " fornext_finalvalue" + u$ + ";" PRINT #13, "static " + ctype$ + " fornext_step" + u$ + ";" PRINT #13, "static uint8 fornext_step_negative" + u$ + ";" ELSE PRINT #13, ctype$ + " fornext_value" + u$ + ";" PRINT #13, ctype$ + " fornext_finalvalue" + u$ + ";" PRINT #13, ctype$ + " fornext_step" + u$ + ";" PRINT #13, "uint8 fornext_step_negative" + u$ + ";" END IF 'calculate start e$ = fixoperationorder$(startvalue$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + "=" + sp + tlayout$ e$ = evaluatetotyp$(e$, ctyp) IF Error_Happened THEN GOTO errmes PRINT #12, "fornext_value" + u$ + "=" + e$ + ";" 'final e$ = fixoperationorder$(p2$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + "TO" + sp + tlayout$ e$ = evaluatetotyp(e$, ctyp) IF Error_Happened THEN GOTO errmes PRINT #12, "fornext_finalvalue" + u$ + "=" + e$ + ";" 'step e$ = fixoperationorder$(p3$) IF Error_Happened THEN GOTO errmes IF stepused = 1 THEN l$ = l$ + sp + "STEP" + sp + tlayout$ e$ = evaluatetotyp(e$, ctyp) IF Error_Happened THEN GOTO errmes PRINT #12, "fornext_step" + u$ + "=" + e$ + ";" PRINT #12, "if (fornext_step" + u$ + "<0) fornext_step_negative" + u$ + "=1; else fornext_step_negative" + u$ + "=0;" PRINT #12, "if (new_error) goto fornext_error" + u$ + ";" PRINT #12, "goto fornext_entrylabel" + u$ + ";" PRINT #12, "while(1){" typbak = typ PRINT #12, "fornext_value" + u$ + "=fornext_step" + u$ + "+(" + refer$(v$, typ, 0) + ");" IF Error_Happened THEN GOTO errmes typ = typbak PRINT #12, "fornext_entrylabel" + u$ + ":" setrefer v$, typ, "fornext_value" + u$, 1 IF Error_Happened THEN GOTO errmes PRINT #12, "if (fornext_step_negative" + u$ + "){" PRINT #12, "if (fornext_value" + u$ + "fornext_finalvalue" + u$ + ") break;" PRINT #12, "}" PRINT #12, "fornext_error" + u$ + ":;" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF IF n = 1 THEN IF firstelement$ = "ELSE" THEN FOR i = controllevel TO 1 STEP -1 t = controltype(i) IF t = 1 THEN IF controlstate(controllevel) = 2 THEN a$ = "IF-THEN already contains an ELSE statement": GOTO errmes PRINT #12, "}else{" controlstate(controllevel) = 2 IF lineelseused = 0 THEN lhscontrollevel = lhscontrollevel - 1 l$ = "ELSE" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec '***no error causing code, event checking done by IF*** END IF NEXT a$ = "ELSE without IF": GOTO errmes END IF END IF IF n >= 3 THEN IF firstelement$ = "ELSEIF" THEN IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 FOR i = controllevel TO 1 STEP -1 t = controltype(i) IF t = 1 THEN IF controlstate(controllevel) = 2 THEN a$ = "ELSEIF invalid after ELSE": GOTO errmes controlstate(controllevel) = 1 controlvalue(controllevel) = controlvalue(controllevel) + 1 e$ = getelement$(a$, n) IF e$ <> "THEN" THEN a$ = "Expected ELSEIF expression THEN": GOTO errmes PRINT #12, "}else{" e$ = fixoperationorder$(getelements$(ca$, 2, n - 1)) IF Error_Happened THEN GOTO errmes l$ = "ELSEIF" + sp + tlayout$ + sp + "THEN" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN e$ = refer$(e$, typ, 0) IF Error_Happened THEN GOTO errmes IF typ AND ISSTRING THEN a$ = "Expected ELSEIF LEN(stringexpression) THEN": GOTO errmes END IF IF stringprocessinghappened THEN PRINT #12, "if (" + cleanupstringprocessingcall$ + e$ + ")){" ELSE PRINT #12, "if (" + e$ + "){" END IF lhscontrollevel = lhscontrollevel - 1 GOTO finishedline END IF NEXT a$ = "ELSEIF without IF": GOTO errmes END IF END IF IF n >= 3 THEN IF firstelement$ = "IF" THEN IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 e$ = getelement(a$, n) iftype = 0 IF e$ = "THEN" THEN iftype = 1 IF e$ = "GOTO" THEN iftype = 2 IF iftype = 0 THEN a$ = "Expected IF expression THEN/GOTO": GOTO errmes controllevel = controllevel + 1 controlref(controllevel) = linenumber controltype(controllevel) = 1 controlvalue(controllevel) = 0 'number of extra closing } required at END IF controlstate(controllevel) = 0 e$ = fixoperationorder$(getelements(ca$, 2, n - 1)) IF Error_Happened THEN GOTO errmes l$ = "IF" + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN e$ = refer$(e$, typ, 0) IF Error_Happened THEN GOTO errmes IF typ AND ISSTRING THEN a$ = "Expected IF LEN(stringexpression) THEN": GOTO errmes END IF IF stringprocessinghappened THEN PRINT #12, "if ((" + cleanupstringprocessingcall$ + e$ + "))||new_error){" ELSE PRINT #12, "if ((" + e$ + ")||new_error){" END IF IF iftype = 1 THEN l$ = l$ + sp + "THEN" 'note: 'GOTO' will be added when iftype=2 layoutdone = 1: IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ IF iftype = 2 THEN 'IF ... GOTO GOTO finishedline END IF THENGOTO = 1 'possible: IF a=1 THEN 10 GOTO finishedline2 END IF END IF 'END IF IF n = 2 THEN IF getelement(a$, 1) = "END" AND getelement(a$, 2) = "IF" THEN IF controltype(controllevel) <> 1 THEN a$ = "END IF without IF": GOTO errmes layoutdone = 1 IF impliedendif = 0 THEN l$ = "END" + sp + "IF" IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ END IF PRINT #12, "}" FOR i = 1 TO controlvalue(controllevel) PRINT #12, "}" NEXT controllevel = controllevel - 1 GOTO finishednonexec '***no error causing code, event checking done by IF*** END IF END IF 'SELECT CASE IF n >= 1 THEN IF firstelement$ = "SELECT" THEN IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 IF n = 1 OR secondelement$ <> "CASE" THEN a$ = "Expected CASE": GOTO errmes IF n = 2 THEN a$ = "Expected SELECT CASE expression": GOTO errmes e$ = fixoperationorder(getelements$(ca$, 3, n)) IF Error_Happened THEN GOTO errmes l$ = "SELECT" + sp + "CASE" + sp + tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes u = uniquenumber controllevel = controllevel + 1 controlvalue(controllevel) = 0 'id t$ = "" IF (typ AND ISSTRING) THEN t = 0 IF (typ AND ISUDT) = 0 AND (typ AND ISARRAY) = 0 AND (typ AND ISREFERENCE) <> 0 THEN controlvalue(controllevel) = VAL(e$) ELSE IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN GOTO errmes PRINT #13, "static qbs *sc_" + str2$(u) + "=qbs_new(0,0);" PRINT #12, "qbs_set(sc_" + str2$(u) + "," + e$ + ");" IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);" END IF ELSE IF (typ AND ISFLOAT) THEN IF (typ AND 511) > 64 THEN t = 3: t$ = "long double" IF (typ AND 511) = 32 THEN t = 4: t$ = "float" IF (typ AND 511) = 64 THEN t = 5: t$ = "double" IF (typ AND ISUDT) = 0 AND (typ AND ISARRAY) = 0 AND (typ AND ISREFERENCE) <> 0 THEN controlvalue(controllevel) = VAL(e$) ELSE IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN GOTO errmes PRINT #13, "static " + t$ + " sc_" + str2$(u) + ";" PRINT #12, "sc_" + str2$(u) + "=" + e$ + ";" IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);" END IF ELSE 'non-float t = 1: t$ = "int64" IF (typ AND ISUNSIGNED) THEN IF (typ AND 511) <= 32 THEN t = 7: t$ = "uint32" IF (typ AND 511) > 32 THEN t = 2: t$ = "uint64" ELSE IF (typ AND 511) <= 32 THEN t = 6: t$ = "int32" IF (typ AND 511) > 32 THEN t = 1: t$ = "int64" END IF IF (typ AND ISUDT) = 0 AND (typ AND ISARRAY) = 0 AND (typ AND ISREFERENCE) <> 0 THEN controlvalue(controllevel) = VAL(e$) ELSE IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN GOTO errmes PRINT #13, "static " + t$ + " sc_" + str2$(u) + ";" PRINT #12, "sc_" + str2$(u) + "=" + e$ + ";" IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);" END IF END IF END IF controlref(controllevel) = linenumber controltype(controllevel) = 10 + t controlid(controllevel) = u GOTO finishedline END IF END IF 'END SELECT IF n = 2 THEN IF firstelement$ = "END" AND secondelement$ = "SELECT" THEN 'complete current case if necessary '18=CASE (awaiting END SELECT/CASE/CASE ELSE) '19=CASE ELSE (awaiting END SELECT) IF controltype(controllevel) = 18 THEN controllevel = controllevel - 1 PRINT #12, "goto sc_" + str2$(controlid(controllevel)) + "_end;" PRINT #12, "}" END IF IF controltype(controllevel) = 19 THEN controllevel = controllevel - 1 END IF PRINT #12, "sc_" + str2$(controlid(controllevel)) + "_end:;" IF controltype(controllevel) < 10 OR controltype(controllevel) > 17 THEN a$ = "END SELECT without SELECT CASE": GOTO errmes controllevel = controllevel - 1 l$ = "END" + sp + "SELECT" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec '***no error causing code, event checking done by SELECT CASE*** END IF END IF 'CASE IF n >= 1 THEN IF firstelement$ = "CASE" THEN l$ = "CASE" 'complete current case if necessary '18=CASE (awaiting END SELECT/CASE/CASE ELSE) '19=CASE ELSE (awaiting END SELECT) IF controltype(controllevel) = 19 THEN a$ = "Expected END SELECT": GOTO errmes IF controltype(controllevel) = 18 THEN lhscontrollevel = lhscontrollevel - 1 controllevel = controllevel - 1 PRINT #12, "goto sc_" + str2$(controlid(controllevel)) + "_end;" PRINT #12, "}" 'following line fixes problem related to RESUME after error 'statementn = statementn + 1 'if nochecks=0 then PRINT #12, "S_" + str2$(statementn) + ":;" END IF IF controltype(controllevel) < 10 OR controltype(controllevel) > 17 THEN a$ = "CASE without SELECT CASE": GOTO errmes IF n = 1 THEN a$ = "Expected CASE expression": GOTO errmes 'upgrade: '#1: variables can be referred to directly by storing an id in 'controlref' ' (but not if part of an array etc.) 'DIM controlvalue(1000) AS LONG '#2: more types will be available ' +SINGLE ' +DOUBLE ' -LONG DOUBLE ' +INT32 ' +UINT32 '14=SELECT CASE float ... '15=SELECT CASE double '16=SELECT CASE int32 '17=SELECT CASE uint32 '10=SELECT CASE qbs (awaiting END SELECT/CASE) '11=SELECT CASE int64 (awaiting END SELECT/CASE) '12=SELECT CASE uint64 (awaiting END SELECT/CASE) '13=SELECT CASE LONG double (awaiting END SELECT/CASE/CASE ELSE) '14=SELECT CASE float ... '15=SELECT CASE double '16=SELECT CASE int32 '17=SELECT CASE uint32 ' bits = targettyp AND 511 ' IF bits <= 16 THEN e$ = "qbr_float_to_long(" + e$ + ")" ' IF bits > 16 AND bits < 32 THEN e$ = "qbr_double_to_long(" + e$ + ")" ' IF bits >= 32 THEN e$ = "qbr(" + e$ + ")" t = controltype(controllevel) - 10 'get required type cast, and float options flt = 0 IF t = 0 THEN tc$ = "" IF t = 1 THEN tc$ = "" IF t = 2 THEN tc$ = "" IF t = 3 THEN tc$ = "": flt = 1 IF t = 4 THEN tc$ = "(float)": flt = 1 IF t = 5 THEN tc$ = "(double)": flt = 1 IF t = 6 THEN tc$ = "" IF t = 7 THEN tc$ = "" n$ = "sc_" + str2$(controlid(controllevel)) cv = controlvalue(controllevel) IF cv THEN n$ = refer$(str2$(cv), 0, 0) IF Error_Happened THEN GOTO errmes END IF 'CASE ELSE IF n = 2 THEN IF getelement$(a$, 2) = "C-EL" THEN controllevel = controllevel + 1: controltype(controllevel) = 19 controlref(controllevel) = controlref(controllevel - 1) l$ = l$ + sp + "ELSE" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishednonexec '***no error causing code, event checking done by SELECT CASE*** END IF END IF IF NoChecks = 0 THEN PRINT #12, "S_" + str2$(statementn) + ":;": dynscope = 1 f12$ = "" nexp = 0 B = 0 e$ = "" FOR i = 2 TO n e2$ = getelement$(ca$, i) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF i = n THEN e$ = e$ + sp + e2$ IF i = n OR (e2$ = "," AND B = 0) THEN IF nexp <> 0 THEN l$ = l$ + sp2 + ",": f12$ = f12$ + "||" IF e$ = "" THEN a$ = "Expected expression": GOTO errmes e$ = RIGHT$(e$, LEN(e$) - 1) 'TYPE 1? ... TO ... n2 = numelements(e$) b2 = 0 el$ = "": er$ = "" usedto = 0 FOR i2 = 1 TO n2 e3$ = getelement$(e$, i2) IF e3$ = "(" THEN b2 = b2 + 1 IF e3$ = ")" THEN b2 = b2 - 1 IF b2 = 0 AND UCASE$(e3$) = "TO" THEN usedto = 1 ELSE IF usedto = 0 THEN el$ = el$ + sp + e3$ ELSE er$ = er$ + sp + e3$ END IF NEXT IF usedto = 1 THEN IF el$ = "" OR er$ = "" THEN a$ = "Expected expression TO expression": GOTO errmes el$ = RIGHT$(el$, LEN(el$) - 1): er$ = RIGHT$(er$, LEN(er$) - 1) 'evaluate each side FOR i2 = 1 TO 2 IF i2 = 1 THEN e$ = el$ ELSE e$ = er$ e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes IF i2 = 1 THEN l$ = l$ + sp + tlayout$ ELSE l$ = l$ + sp + "TO" + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN GOTO errmes IF t = 0 THEN IF (typ AND ISSTRING) = 0 THEN a$ = "Expected string expression": GOTO errmes IF i2 = 1 THEN f12$ = f12$ + "(qbs_greaterorequal(" + n$ + "," + e$ + ")&&qbs_lessorequal(" + n$ + "," IF i2 = 2 THEN f12$ = f12$ + e$ + "))" ELSE IF (typ AND ISSTRING) THEN a$ = "Expected numeric expression": GOTO errmes 'round to integer? IF (typ AND ISFLOAT) THEN IF t = 1 THEN e$ = "qbr(" + e$ + ")" IF t = 2 THEN e$ = "qbr_longdouble_to_uint64(" + e$ + ")" IF t = 6 OR t = 7 THEN e$ = "qbr_double_to_long(" + e$ + ")" END IF 'cast result? IF LEN(tc$) THEN e$ = tc$ + "(" + e$ + ")" IF i2 = 1 THEN f12$ = f12$ + "((" + n$ + ">=(" + e$ + "))&&(" + n$ + "<=(" IF i2 = 2 THEN f12$ = f12$ + e$ + ")))" END IF NEXT GOTO addedexp END IF '10=SELECT CASE qbs (awaiting END SELECT/CASE) '11=SELECT CASE int64 (awaiting END SELECT/CASE) '12=SELECT CASE uint64 (awaiting END SELECT/CASE) '13=SELECT CASE LONG double (awaiting END SELECT/CASE/CASE ELSE) '14=SELECT CASE float ... '15=SELECT CASE double '16=SELECT CASE int32 '17=SELECT CASE uint32 ' bits = targettyp AND 511 ' IF bits <= 16 THEN e$ = "qbr_float_to_long(" + e$ + ")" ' IF bits > 16 AND bits < 32 THEN e$ = "qbr_double_to_long(" + e$ + ")" ' IF bits >= 32 THEN e$ = "qbr(" + e$ + ")" o$ = "==" 'used by type 3 'TYPE 2? x$ = getelement$(e$, 1) IF isoperator(x$) THEN 'non-standard usage correction IF x$ = "=" OR x$ = "<>" OR x$ = ">" OR x$ = "<" OR x$ = ">=" OR x$ = "<=" THEN e$ = "IS" + sp + e$ x$ = "IS" END IF END IF IF UCASE$(x$) = "IS" THEN n2 = numelements(e$) IF n2 < 3 THEN a$ = "Expected IS =,<>,>,<,>=,<= expression": GOTO errmes o$ = getelement$(e$, 2) o2$ = o$ o = 0 IF o$ = "=" THEN o$ = "==": o = 1 IF o$ = "<>" THEN o$ = "!=": o = 1 IF o$ = ">" THEN o = 1 IF o$ = "<" THEN o = 1 IF o$ = ">=" THEN o = 1 IF o$ = "<=" THEN o = 1 IF o <> 1 THEN a$ = "Expected IS =,<>,>,<,>=,<= expression": GOTO errmes l$ = l$ + sp + "IS" + sp + o2$ e$ = getelements$(e$, 3, n2) 'fall through to type 3 using modified e$ & o$ END IF 'TYPE 3? simple expression e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN GOTO errmes IF t = 0 THEN 'string comparison IF (typ AND ISSTRING) = 0 THEN a$ = "Expected string expression": GOTO errmes IF o$ = "==" THEN o$ = "qbs_equal" IF o$ = "!=" THEN o$ = "qbs_notequal" IF o$ = ">" THEN o$ = "qbs_greaterthan" IF o$ = "<" THEN o$ = "qbs_lessthan" IF o$ = ">=" THEN o$ = "qbs_greaterorequal" IF o$ = "<=" THEN o$ = "qbs_lessorequal" f12$ = f12$ + o$ + "(" + n$ + "," + e$ + ")" ELSE 'numeric IF (typ AND ISSTRING) THEN a$ = "Expected numeric expression": GOTO errmes 'round to integer? IF (typ AND ISFLOAT) THEN IF t = 1 THEN e$ = "qbr(" + e$ + ")" IF t = 2 THEN e$ = "qbr_longdouble_to_uint64(" + e$ + ")" IF t = 6 OR t = 7 THEN e$ = "qbr_double_to_long(" + e$ + ")" END IF 'cast result? IF LEN(tc$) THEN e$ = tc$ + "(" + e$ + ")" f12$ = f12$ + "(" + n$ + o$ + "(" + e$ + "))" END IF addedexp: e$ = "" nexp = nexp + 1 ELSE e$ = e$ + sp + e2$ END IF NEXT IF stringprocessinghappened THEN PRINT #12, "if ((" + cleanupstringprocessingcall$ + f12$ + "))||new_error){" ELSE PRINT #12, "if ((" + f12$ + ")||new_error){" END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ controllevel = controllevel + 1 controlref(controllevel) = controlref(controllevel - 1) controltype(controllevel) = 18 GOTO finishedline END IF END IF 'static scope commands: IF NoChecks = 0 THEN PRINT #12, "do{" 'PRINT #12, "S_" + str2$(statementn) + ":;" END IF IF n > 1 THEN IF firstelement$ = "PALETTE" THEN IF secondelement$ = "USING" THEN l$ = "PALETTE" + sp + "USING" + sp IF n < 3 THEN a$ = "Expected PALETTE USING array-name": GOTO errmes 'check array e$ = getelement$(ca$, 3) IF FindArray(e$) THEN IF Error_Happened THEN GOTO errmes z = 1 t = id.arraytype IF (t AND 511) <> 16 AND (t AND 511) <> 32 THEN z = 0 IF t AND ISFLOAT THEN z = 0 IF t AND ISOFFSETINBITS THEN z = 0 IF t AND ISSTRING THEN z = 0 IF t AND ISUDT THEN z = 0 IF t AND ISUNSIGNED THEN z = 0 IF z = 0 THEN a$ = "Array must be of type INTEGER or LONG": GOTO errmes bits = t AND 511 GOTO pu_gotarray END IF IF Error_Happened THEN GOTO errmes a$ = "Expected PALETTE USING array-name": GOTO errmes pu_gotarray: 'add () if index not specified IF n = 3 THEN e$ = e$ + sp + "(" + sp + ")" ELSE IF n = 4 OR getelement$(a$, 4) <> "(" OR getelement$(a$, n) <> ")" THEN a$ = "Expected PALETTE USING array-name(...)": GOTO errmes e$ = e$ + sp + getelements$(ca$, 4, n) END IF e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ e$ = evaluatetotyp(e$, -2) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_paletteusing(" + e$ + "," + str2(bits) + ");" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF 'using END IF 'palette END IF 'n>1 IF firstelement$ = "KEY" THEN IF n = 1 THEN a$ = "Expected KEY ...": GOTO errmes l$ = "KEY" + sp IF secondelement$ = "OFF" THEN IF n > 2 THEN a$ = "Expected KEY OFF only": GOTO errmes l$ = l$ + "OFF": layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ PRINT #12, "key_off();" GOTO finishedline END IF IF secondelement$ = "ON" THEN IF n > 2 THEN a$ = "Expected KEY ON only": GOTO errmes l$ = l$ + "ON": layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ PRINT #12, "key_on();" GOTO finishedline END IF IF secondelement$ = "LIST" THEN IF n > 2 THEN a$ = "Expected KEY LIST only": GOTO errmes l$ = l$ + "LIST": layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ PRINT #12, "key_list();" GOTO finishedline END IF 'search for comma to indicate assignment B = 0: e$ = "" FOR i = 2 TO n e2$ = getelement(ca$, i) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF e2$ = "," AND B = 0 THEN i = i + 1: GOTO key_assignment END IF IF LEN(e$) THEN e$ = e$ + sp + e2$ ELSE e$ = e2$ NEXT 'assume KEY(x) ON/OFF/STOP and handle as a sub GOTO key_fallthrough key_assignment: 'KEY x, "string" 'index e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ + sp2 + "," + sp e$ = evaluatetotyp(e$, 32&) IF Error_Happened THEN GOTO errmes PRINT #12, "key_assign(" + e$ + ","; 'string e$ = getelements$(ca$, i, n) e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ e$ = evaluatetotyp(e$, ISSTRING) IF Error_Happened THEN GOTO errmes PRINT #12, e$ + ");" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF 'KEY key_fallthrough: IF firstelement$ = "FIELD" THEN 'get filenumber B = 0: e$ = "" FOR i = 2 TO n e2$ = getelement(ca$, i) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF e2$ = "," AND B = 0 THEN i = i + 1: GOTO fieldgotfn END IF IF LEN(e$) THEN e$ = e$ + sp + e2$ ELSE e$ = e2$ NEXT GOTO fielderror fieldgotfn: IF e$ = "#" OR LEN(e$) = 0 THEN GOTO fielderror IF LEFT$(e$, 2) = "#" + sp THEN e$ = RIGHT$(e$, LEN(e$) - 2): l$ = "FIELD" + sp + "#" + sp2 ELSE l$ = "FIELD" + sp e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ + sp2 + "," + sp e$ = evaluatetotyp(e$, 32&) IF Error_Happened THEN GOTO errmes PRINT #12, "field_new(" + e$ + ");" fieldnext: 'get fieldwidth IF i > n THEN GOTO fielderror B = 0: e$ = "" FOR i = i TO n e2$ = getelement(ca$, i) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF UCASE$(e2$) = "AS" AND B = 0 THEN i = i + 1: GOTO fieldgotfw END IF IF LEN(e$) THEN e$ = e$ + sp + e2$ ELSE e$ = e2$ NEXT GOTO fielderror fieldgotfw: IF LEN(e$) = 0 THEN GOTO fielderror e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ + sp + "AS" + sp sizee$ = evaluatetotyp(e$, 32&) IF Error_Happened THEN GOTO errmes 'get variable name IF i > n THEN GOTO fielderror B = 0: e$ = "" FOR i = i TO n e2$ = getelement(ca$, i) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF (i = n OR e2$ = ",") AND B = 0 THEN IF e2$ = "," THEN i = i - 1 IF i = n THEN IF LEN(e$) THEN e$ = e$ + sp + e2$ ELSE e$ = e2$ END IF GOTO fieldgotfname END IF IF LEN(e$) THEN e$ = e$ + sp + e2$ ELSE e$ = e2$ NEXT GOTO fielderror fieldgotfname: IF LEN(e$) = 0 THEN GOTO fielderror 'evaluate it to check it is a STRING e$ = fixoperationorder(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISSTRING) = 0 THEN GOTO fielderror IF typ AND ISFIXEDLENGTH THEN a$ = "Fixed length strings cannot be used in a FIELD statement": GOTO errmes IF (typ AND ISREFERENCE) = 0 THEN GOTO fielderror e$ = refer(e$, typ, 0) IF Error_Happened THEN GOTO errmes PRINT #12, "field_add(" + e$ + "," + sizee$ + ");" IF i < n THEN i = i + 1 e$ = getelement(a$, i) IF e$ <> "," THEN a$ = "Expected ,": GOTO errmes l$ = l$ + sp2 + "," + sp i = i + 1 GOTO fieldnext END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline fielderror: a$ = "Expected FIELD #filenumber, characters AS variable$, ...": GOTO errmes END IF '1=IF (awaiting END IF) '2=FOR (awaiting NEXT) '3=DO (awaiting LOOP [UNTIL|WHILE param]) '4=DO WHILE/UNTIL (awaiting LOOP) '5=WHILE (awaiting WEND) IF n = 2 THEN IF firstelement$ = "EXIT" THEN l$ = firstelement$ + sp + secondelement$ IF secondelement$ = "DO" THEN 'scan backwards until previous control level reached FOR i = controllevel TO 1 STEP -1 t = controltype(i) IF t = 3 OR t = 4 THEN PRINT #12, "goto dl_exit_" + str2$(controlid(i)) + ";" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF NEXT a$ = "EXIT DO without DO": GOTO errmes END IF IF secondelement$ = "FOR" THEN 'scan backwards until previous control level reached FOR i = controllevel TO 1 STEP -1 t = controltype(i) IF t = 2 THEN PRINT #12, "goto fornext_exit_" + str2$(controlid(i)) + ";" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF NEXT a$ = "EXIT FOR without FOR": GOTO errmes END IF IF secondelement$ = "WHILE" THEN 'scan backwards until previous control level reached FOR i = controllevel TO 1 STEP -1 t = controltype(i) IF t = 5 THEN PRINT #12, "goto ww_exit_" + str2$(controlid(i)) + ";" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF NEXT a$ = "EXIT WHILE without WHILE": GOTO errmes END IF END IF END IF IF n >= 2 THEN IF firstelement$ = "ON" AND secondelement$ = "STRIG" THEN i = 3 IF i > n THEN a$ = "Expected (": GOTO errmes a2$ = getelement$(ca$, i): i = i + 1 IF a2$ <> "(" THEN a$ = "Expected (": GOTO errmes l$ = "ON" + sp + "STRIG" + sp2 + "(" IF i > n THEN a$ = "Expected ...": GOTO errmes B = 0 x = 0 e2$ = "" e3$ = "" FOR i = i TO n e$ = getelement$(ca$, i) a = ASC(e$) IF a = 40 THEN B = B + 1 IF a = 41 THEN B = B - 1 IF B = -1 THEN GOTO onstriggotarg IF a = 44 AND B = 0 THEN x = x + 1 IF x > 1 THEN a$ = "Expected )": GOTO errmes IF e2$ = "" THEN a$ = "Expected ... ,": GOTO errmes e3$ = e2$ e2$ = "" ELSE IF LEN(e2$) THEN e2$ = e2$ + sp + e$ ELSE e2$ = e$ END IF NEXT a$ = "Expected )": GOTO errmes onstriggotarg: IF e2$ = "" THEN a$ = "Expected ... )": GOTO errmes PRINT #12, "onstrig_setup("; 'sort scanned results IF LEN(e3$) THEN optI$ = e3$ optController$ = e2$ optPassed$ = "1" ELSE optI$ = e2$ optController$ = "0" optPassed$ = "0" END IF 'i e$ = fixoperationorder$(optI$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + tlayout$ e$ = evaluatetotyp(e$, 32&): IF Error_Happened THEN GOTO errmes PRINT #12, e$ + ","; 'controller , passed IF optPassed$ = "1" THEN e$ = fixoperationorder$(optController$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ e$ = evaluatetotyp(e$, 32&): IF Error_Happened THEN GOTO errmes ELSE e$ = optController$ END IF PRINT #12, e$ + "," + optPassed$ + ","; l$ = l$ + sp2 + ")" + sp 'close brackets i = i + 1 IF i > n THEN a$ = "Expected GOSUB/sub-name": GOTO errmes a2$ = getelement$(a$, i): i = i + 1 onstrigid = onstrigid + 1 PRINT #12, str2$(onstrigid) + ","; IF a2$ = "GOSUB" THEN IF i > n THEN a$ = "Expected linenumber/label": GOTO errmes a2$ = getelement$(ca$, i): i = i + 1 PRINT #12, "0);" IF validlabel(a2$) = 0 THEN a$ = "Invalid label": GOTO errmes v = HashFind(a2$, HASHFLAG_LABEL, ignore, r) x = 1 labchk60z: IF v THEN s = Labels(r).Scope IF s = 0 OR s = -1 THEN 'main scope? IF s = -1 THEN Labels(r).Scope = 0 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) Labels(r).Scope_Restriction = subfuncn Labels(r).Error_Line = linenumber ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk60z END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd a2$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = 0 Labels(r).Error_Line = linenumber Labels(r).Scope_Restriction = subfuncn END IF 'x l$ = l$ + "GOSUB" + sp + tlayout$ PRINT #30, "if(strig_event_id==" + str2$(onstrigid) + ")goto LABEL_" + a2$ + ";" PRINT #29, "case " + str2$(onstrigid) + ":" PRINT #29, "strig_event_occurred++;" PRINT #29, "strig_event_id=" + str2$(onstrigid) + ";" PRINT #29, "strig_event_occurred++;" PRINT #29, "return_point[next_return_point++]=0;" PRINT #29, "if (next_return_point>=return_points) more_return_points();" PRINT #29, "QBMAIN(NULL);" PRINT #29, "break;" IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ layoutdone = 1 GOTO finishedline ELSE 'establish whether sub a2$ exists using try x = 0 try = findid(a2$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.subfunc = 2 THEN x = 1: EXIT DO IF try = 2 THEN findanotherid = 1: try = findid(a2$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP IF x = 0 THEN a$ = "Expected GOSUB/sub": GOTO errmes l$ = l$ + RTRIM$(id.cn) PRINT #29, "case " + str2$(onstrigid) + ":" PRINT #29, RTRIM$(id.callname) + "("; IF id.args > 1 THEN a$ = "SUB requires more than one argument": GOTO errmes IF i > n THEN IF id.args = 1 THEN a$ = "Expected argument after SUB": GOTO errmes PRINT #12, "0);" PRINT #29, ");" ELSE IF id.args = 0 THEN a$ = "SUB has no arguments": GOTO errmes t = CVL(id.arg) B = t AND 511 IF B = 0 OR (t AND ISARRAY) <> 0 OR (t AND ISFLOAT) <> 0 OR (t AND ISSTRING) <> 0 OR (t AND ISOFFSETINBITS) <> 0 THEN a$ = "Only SUB arguments of integer-type allowed": GOTO errmes IF B = 8 THEN ct$ = "int8" IF B = 16 THEN ct$ = "int16" IF B = 32 THEN ct$ = "int32" IF B = 64 THEN ct$ = "int64" IF t AND ISOFFSET THEN ct$ = "ptrszint" IF t AND ISUNSIGNED THEN ct$ = "u" + ct$ PRINT #29, "(" + ct$ + "*)&i64);" e$ = getelements$(ca$, i, n) e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluatetotyp(e$, INTEGER64TYPE - ISPOINTER) IF Error_Happened THEN GOTO errmes PRINT #12, e$ + ");" END IF PRINT #29, "break;" IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ layoutdone = 1 GOTO finishedline END IF END IF END IF IF n >= 2 THEN IF firstelement$ = "ON" AND secondelement$ = "TIMER" THEN i = 3 IF i > n THEN a$ = "Expected (": GOTO errmes a2$ = getelement$(ca$, i): i = i + 1 IF a2$ <> "(" THEN a$ = "Expected (": GOTO errmes l$ = "ON" + sp + "TIMER" + sp2 + "(" IF i > n THEN a$ = "Expected ...": GOTO errmes B = 0 x = 0 e2$ = "" e3$ = "" FOR i = i TO n e$ = getelement$(ca$, i) a = ASC(e$) IF a = 40 THEN B = B + 1 IF a = 41 THEN B = B - 1 IF B = -1 THEN GOTO ontimgotarg IF a = 44 AND B = 0 THEN x = x + 1 IF x > 1 THEN a$ = "Expected )": GOTO errmes IF e2$ = "" THEN a$ = "Expected ... ,": GOTO errmes e3$ = e2$ e2$ = "" ELSE IF LEN(e2$) THEN e2$ = e2$ + sp + e$ ELSE e2$ = e$ END IF NEXT a$ = "Expected )": GOTO errmes ontimgotarg: IF e2$ = "" THEN a$ = "Expected ... )": GOTO errmes PRINT #12, "ontimer_setup("; 'i IF LEN(e3$) THEN e$ = fixoperationorder$(e3$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + tlayout$ + "," + sp e$ = evaluatetotyp(e$, 32&) IF Error_Happened THEN GOTO errmes PRINT #12, e$ + ","; ELSE PRINT #12, "0,"; l$ = l$ + sp2 END IF 'sec e$ = fixoperationorder$(e2$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ + sp2 + ")" + sp e$ = evaluatetotyp(e$, DOUBLETYPE - ISPOINTER) IF Error_Happened THEN GOTO errmes PRINT #12, e$ + ","; i = i + 1 IF i > n THEN a$ = "Expected GOSUB/sub-name": GOTO errmes a2$ = getelement$(a$, i): i = i + 1 ontimerid = ontimerid + 1 PRINT #12, str2$(ontimerid) + ","; IF a2$ = "GOSUB" THEN IF i > n THEN a$ = "Expected linenumber/label": GOTO errmes a2$ = getelement$(ca$, i): i = i + 1 PRINT #12, "0);" IF validlabel(a2$) = 0 THEN a$ = "Invalid label": GOTO errmes v = HashFind(a2$, HASHFLAG_LABEL, ignore, r) x = 1 labchk60: IF v THEN s = Labels(r).Scope IF s = 0 OR s = -1 THEN 'main scope? IF s = -1 THEN Labels(r).Scope = 0 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) Labels(r).Scope_Restriction = subfuncn Labels(r).Error_Line = linenumber ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk60 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd a2$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = 0 Labels(r).Error_Line = linenumber Labels(r).Scope_Restriction = subfuncn END IF 'x l$ = l$ + "GOSUB" + sp + tlayout$ PRINT #25, "if(timer_event_id==" + str2$(ontimerid) + ")goto LABEL_" + a2$ + ";" PRINT #24, "case " + str2$(ontimerid) + ":" PRINT #24, "timer_event_occurred++;" PRINT #24, "timer_event_id=" + str2$(ontimerid) + ";" PRINT #24, "timer_event_occurred++;" PRINT #24, "return_point[next_return_point++]=0;" PRINT #24, "if (next_return_point>=return_points) more_return_points();" PRINT #24, "QBMAIN(NULL);" PRINT #24, "break;" 'call validlabel (to validate the label) [see goto] 'increment ontimerid 'use ontimerid to generate the jumper routine 'etc. IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ layoutdone = 1 GOTO finishedline ELSE 'establish whether sub a2$ exists using try x = 0 try = findid(a2$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.subfunc = 2 THEN x = 1: EXIT DO IF try = 2 THEN findanotherid = 1: try = findid(a2$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP IF x = 0 THEN a$ = "Expected GOSUB/sub": GOTO errmes l$ = l$ + RTRIM$(id.cn) PRINT #24, "case " + str2$(ontimerid) + ":" PRINT #24, RTRIM$(id.callname) + "("; IF id.args > 1 THEN a$ = "SUB requires more than one argument": GOTO errmes IF i > n THEN IF id.args = 1 THEN a$ = "Expected argument after SUB": GOTO errmes PRINT #12, "0);" PRINT #24, ");" ELSE IF id.args = 0 THEN a$ = "SUB has no arguments": GOTO errmes t = CVL(id.arg) B = t AND 511 IF B = 0 OR (t AND ISARRAY) <> 0 OR (t AND ISFLOAT) <> 0 OR (t AND ISSTRING) <> 0 OR (t AND ISOFFSETINBITS) <> 0 THEN a$ = "Only SUB arguments of integer-type allowed": GOTO errmes IF B = 8 THEN ct$ = "int8" IF B = 16 THEN ct$ = "int16" IF B = 32 THEN ct$ = "int32" IF B = 64 THEN ct$ = "int64" IF t AND ISOFFSET THEN ct$ = "ptrszint" IF t AND ISUNSIGNED THEN ct$ = "u" + ct$ PRINT #24, "(" + ct$ + "*)&i64);" e$ = getelements$(ca$, i, n) e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluatetotyp(e$, INTEGER64TYPE - ISPOINTER) IF Error_Happened THEN GOTO errmes PRINT #12, e$ + ");" END IF PRINT #24, "break;" IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ layoutdone = 1 GOTO finishedline END IF END IF END IF IF n >= 2 THEN IF firstelement$ = "ON" AND secondelement$ = "KEY" THEN i = 3 IF i > n THEN a$ = "Expected (": GOTO errmes a2$ = getelement$(ca$, i): i = i + 1 IF a2$ <> "(" THEN a$ = "Expected (": GOTO errmes l$ = "ON" + sp + "KEY" + sp2 + "(" IF i > n THEN a$ = "Expected ...": GOTO errmes B = 0 x = 0 e2$ = "" FOR i = i TO n e$ = getelement$(ca$, i) a = ASC(e$) IF a = 40 THEN B = B + 1 IF a = 41 THEN B = B - 1 IF B = -1 THEN EXIT FOR IF LEN(e2$) THEN e2$ = e2$ + sp + e$ ELSE e2$ = e$ NEXT IF i = n + 1 THEN a$ = "Expected )": GOTO errmes IF e2$ = "" THEN a$ = "Expected ... )": GOTO errmes e$ = fixoperationorder$(e2$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ + sp2 + ")" + sp e$ = evaluatetotyp(e$, DOUBLETYPE - ISPOINTER) IF Error_Happened THEN GOTO errmes PRINT #12, "onkey_setup(" + e$ + ","; i = i + 1 IF i > n THEN a$ = "Expected GOSUB/sub-name": GOTO errmes a2$ = getelement$(a$, i): i = i + 1 onkeyid = onkeyid + 1 PRINT #12, str2$(onkeyid) + ","; IF a2$ = "GOSUB" THEN IF i > n THEN a$ = "Expected linenumber/label": GOTO errmes a2$ = getelement$(ca$, i): i = i + 1 PRINT #12, "0);" IF validlabel(a2$) = 0 THEN a$ = "Invalid label": GOTO errmes v = HashFind(a2$, HASHFLAG_LABEL, ignore, r) x = 1 labchk61: IF v THEN s = Labels(r).Scope IF s = 0 OR s = -1 THEN 'main scope? IF s = -1 THEN Labels(r).Scope = 0 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) Labels(r).Scope_Restriction = subfuncn Labels(r).Error_Line = linenumber ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk61 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd a2$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = 0 Labels(r).Error_Line = linenumber Labels(r).Scope_Restriction = subfuncn END IF 'x l$ = l$ + "GOSUB" + sp + tlayout$ PRINT #28, "if(key_event_id==" + str2$(onkeyid) + ")goto LABEL_" + a2$ + ";" PRINT #27, "case " + str2$(onkeyid) + ":" PRINT #27, "key_event_occurred++;" PRINT #27, "key_event_id=" + str2$(onkeyid) + ";" PRINT #27, "key_event_occurred++;" PRINT #27, "return_point[next_return_point++]=0;" PRINT #27, "if (next_return_point>=return_points) more_return_points();" PRINT #27, "QBMAIN(NULL);" PRINT #27, "break;" IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ layoutdone = 1 GOTO finishedline ELSE 'establish whether sub a2$ exists using try x = 0 try = findid(a2$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.subfunc = 2 THEN x = 1: EXIT DO IF try = 2 THEN findanotherid = 1: try = findid(a2$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP IF x = 0 THEN a$ = "Expected GOSUB/sub": GOTO errmes l$ = l$ + RTRIM$(id.cn) PRINT #27, "case " + str2$(onkeyid) + ":" PRINT #27, RTRIM$(id.callname) + "("; IF id.args > 1 THEN a$ = "SUB requires more than one argument": GOTO errmes IF i > n THEN IF id.args = 1 THEN a$ = "Expected argument after SUB": GOTO errmes PRINT #12, "0);" PRINT #27, ");" ELSE IF id.args = 0 THEN a$ = "SUB has no arguments": GOTO errmes t = CVL(id.arg) B = t AND 511 IF B = 0 OR (t AND ISARRAY) <> 0 OR (t AND ISFLOAT) <> 0 OR (t AND ISSTRING) <> 0 OR (t AND ISOFFSETINBITS) <> 0 THEN a$ = "Only SUB arguments of integer-type allowed": GOTO errmes IF B = 8 THEN ct$ = "int8" IF B = 16 THEN ct$ = "int16" IF B = 32 THEN ct$ = "int32" IF B = 64 THEN ct$ = "int64" IF t AND ISOFFSET THEN ct$ = "ptrszint" IF t AND ISUNSIGNED THEN ct$ = "u" + ct$ PRINT #27, "(" + ct$ + "*)&i64);" e$ = getelements$(ca$, i, n) e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluatetotyp(e$, INTEGER64TYPE - ISPOINTER) IF Error_Happened THEN GOTO errmes PRINT #12, e$ + ");" END IF PRINT #27, "break;" IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ layoutdone = 1 GOTO finishedline END IF END IF END IF 'SHARED (SUB) IF n >= 1 THEN IF firstelement$ = "SHARED" THEN IF n = 1 THEN a$ = "Expected SHARED ...": GOTO errmes i = 2 IF subfuncn = 0 THEN a$ = "SHARED must be used within a SUB/FUNCTION": GOTO errmes l$ = "SHARED" subfuncshr: 'get variable name n$ = getelement$(ca$, i): i = i + 1 IF n$ = "" THEN a$ = "Expected SHARED variable-name": GOTO errmes s$ = removesymbol(n$) IF Error_Happened THEN GOTO errmes l2$ = s$ 'either symbol or nothing 'array? a = 0 IF getelement$(a$, i) = "(" THEN IF getelement$(a$, i + 1) <> ")" THEN a$ = "Expected ()": GOTO errmes i = i + 2 a = 1 l2$ = l2$ + sp2 + "(" + sp2 + ")" END IF method = 1 'specific type? t$ = "" ts$ = "" t3$ = "" IF getelement$(a$, i) = "AS" THEN l2$ = l2$ + sp + "AS" getshrtyp: i = i + 1 t2$ = getelement$(a$, i) IF t2$ <> "," AND t2$ <> "" THEN IF t$ = "" THEN t$ = t2$ ELSE t$ = t$ + " " + t2$ IF t3$ = "" THEN t3$ = t2$ ELSE t3$ = t3$ + sp + t2$ GOTO getshrtyp END IF IF t$ = "" THEN a$ = "Expected AS type": GOTO errmes t = typname2typ(t$) IF Error_Happened THEN GOTO errmes IF t AND ISINCONVENTIONALMEMORY THEN t = t - ISINCONVENTIONALMEMORY IF t AND ISPOINTER THEN t = t - ISPOINTER IF t AND ISREFERENCE THEN t = t - ISREFERENCE tsize = typname2typsize method = 0 IF (t AND ISUDT) = 0 THEN ts$ = type2symbol$(t$) ELSE t3$ = RTRIM$(udtxcname(t AND 511)) IF Error_Happened THEN GOTO errmes l2$ = l2$ + sp + t3$ END IF 'as IF LEN(s$) <> 0 AND LEN(t$) <> 0 THEN a$ = "Expected symbol or AS type after variable name": GOTO errmes 'no symbol of type specified, apply default IF s$ = "" AND t$ = "" THEN IF LEFT$(n$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(n$)) - 64 s$ = defineextaz(v) END IF 'switch to main module oldsubfunc$ = subfunc$ subfunc$ = "" defdatahandle = 18 CLOSE #13: OPEN tmpdir$ + "maindata.txt" FOR APPEND AS #13 CLOSE #19: OPEN tmpdir$ + "mainfree.txt" FOR APPEND AS #19 'use 'try' to locate the variable (if it already exists) n2$ = n$ + s$ + ts$ 'note: either ts$ or s$ will exist unless it is a UDT try = findid(n2$) IF Error_Happened THEN GOTO errmes DO WHILE try IF a THEN 'an array IF id.arraytype THEN IF LEN(t$) = 0 THEN GOTO shrfound t2 = id.arraytype: t2size = id.tsize IF t2 AND ISINCONVENTIONALMEMORY THEN t2 = t2 - ISINCONVENTIONALMEMORY IF t2 AND ISPOINTER THEN t2 = t2 - ISPOINTER IF t2 AND ISREFERENCE THEN t2 = t2 - ISREFERENCE IF t = t2 AND tsize = t2size THEN GOTO shrfound END IF ELSE 'not an array IF id.t THEN IF LEN(t$) = 0 THEN GOTO shrfound t2 = id.t: t2size = id.tsize IF t2 AND ISINCONVENTIONALMEMORY THEN t2 = t2 - ISINCONVENTIONALMEMORY IF t2 AND ISPOINTER THEN t2 = t2 - ISPOINTER IF t2 AND ISREFERENCE THEN t2 = t2 - ISREFERENCE IF Debug THEN PRINT #9, "SHARED:comparing:"; t; t2, tsize; t2size IF t = t2 AND tsize = t2size THEN GOTO shrfound END IF END IF IF try = 2 THEN findanotherid = 1: try = findid(n2$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP 'unknown variable IF a THEN a$ = "Array not defined": GOTO errmes 'create variable IF LEN(s$) THEN typ$ = s$ ELSE typ$ = t$ retval = dim2(n$, typ$, method, "") IF Error_Happened THEN GOTO errmes 'note: variable created! shrfound: l$ = l$ + sp + RTRIM$(id.cn) + l2$ ids(currentid).share = ids(currentid).share OR 2 'set as temporarily shared 'method must apply to the current sub/function regardless of how the variable was defined in 'main' lmay = LEN(RTRIM$(id.mayhave)): lmust = LEN(RTRIM$(id.musthave)) IF lmay <> 0 OR lmust <> 0 THEN IF (method = 1 AND lmust = 0) OR (method = 0 AND lmay = 0) THEN revertmaymusthaven = revertmaymusthaven + 1 revertmaymusthave(revertmaymusthaven) = currentid SWAP ids(currentid).musthave, ids(currentid).mayhave END IF END IF 'switch back to sub/func subfunc$ = oldsubfunc$ defdatahandle = 13 CLOSE #13: OPEN tmpdir$ + "data" + str2$(subfuncn) + ".txt" FOR APPEND AS #13 CLOSE #19: OPEN tmpdir$ + "free" + str2$(subfuncn) + ".txt" FOR APPEND AS #19 IF getelement$(a$, i) = "," THEN i = i + 1: l$ = l$ + sp2 + ",": GOTO subfuncshr IF getelement$(a$, i) <> "" THEN a$ = "Expected ,": GOTO errmes layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF 'EXIT SUB/FUNCTION IF n = 2 THEN IF firstelement$ = "EXIT" THEN sf = 0 IF secondelement$ = "FUNCTION" THEN sf = 1 IF secondelement$ = "SUB" THEN sf = 2 IF sf THEN IF LEN(subfunc) = 0 THEN a$ = "EXIT " + secondelement$ + " must be used within a SUB/FUNCTION": GOTO errmes PRINT #12, "goto exit_subfunc;" l$ = firstelement$ + sp + secondelement$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF END IF 'ASC statement (fully inline) IF n >= 1 THEN IF firstelement$ = "ASC" THEN IF getelement$(a$, 2) <> "(" THEN a$ = "Expected ( after ASC": GOTO errmes 'calculate 3 parts useposition = 0 part = 1 i = 3 a3$ = "" stringvariable$ = "" position$ = "" B = 0 DO IF i > n THEN 'got part 3 IF part <> 3 OR LEN(a3$) = 0 THEN a$ = "Expected ASC ( ... , ... ) = ...": GOTO errmes expression$ = a3$ EXIT DO END IF a2$ = getelement$(ca$, i) IF a2$ = "(" THEN B = B + 1 IF a2$ = ")" THEN B = B - 1 IF B = -1 THEN IF part = 1 THEN 'eg. ASC(a$)=65 IF getelement$(a$, i + 1) <> "=" THEN a$ = "Expected =": GOTO errmes stringvariable$ = a3$ position$ = "1" part = 3: a3$ = "": i = i + 1: GOTO ascgotpart END IF IF part = 2 THEN 'eg. ASC(a$,i)=65 IF getelement$(a$, i + 1) <> "=" THEN a$ = "Expected =": GOTO errmes useposition = 1 position$ = a3$ part = 3: a3$ = "": i = i + 1: GOTO ascgotpart END IF 'fall through, already in part 3 END IF IF a2$ = "," AND B = 0 THEN IF part = 1 THEN stringvariable$ = a3$: part = 2: a3$ = "": GOTO ascgotpart END IF IF LEN(a3$) THEN a3$ = a3$ + sp + a2$ ELSE a3$ = a2$ ascgotpart: i = i + 1 LOOP IF LEN(stringvariable$) = 0 OR LEN(position$) = 0 THEN a$ = "Expected ASC ( ... , ... ) = ...": GOTO errmes 'validate stringvariable$ stringvariable$ = fixoperationorder$(stringvariable$) IF Error_Happened THEN GOTO errmes l$ = "ASC" + sp2 + "(" + sp2 + tlayout$ e$ = evaluate(stringvariable$, sourcetyp) IF Error_Happened THEN GOTO errmes IF (sourcetyp AND ISREFERENCE) = 0 OR (sourcetyp AND ISSTRING) = 0 THEN a$ = "Expected ASC ( string-variable , ...": GOTO errmes stringvariable$ = evaluatetotyp(stringvariable$, ISSTRING) IF Error_Happened THEN GOTO errmes IF position$ = "1" THEN IF useposition THEN l$ = l$ + sp2 + "," + sp + "1" + sp2 + ")" + sp + "=" ELSE l$ = l$ + sp2 + ")" + sp + "=" PRINT #12, "tqbs=" + stringvariable$ + "; if (!new_error){" e$ = fixoperationorder$(expression$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluatetotyp(e$, 32&) IF Error_Happened THEN GOTO errmes PRINT #12, "tmp_long=" + e$ + "; if (!new_error){" PRINT #12, "if (tqbs->len){tqbs->chr[0]=tmp_long;}else{error(5);}" PRINT #12, "}}" ELSE PRINT #12, "tqbs=" + stringvariable$ + "; if (!new_error){" e$ = fixoperationorder$(position$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ + sp2 + ")" + sp + "=" e$ = evaluatetotyp(e$, 32&) IF Error_Happened THEN GOTO errmes PRINT #12, "tmp_fileno=" + e$ + "; if (!new_error){" e$ = fixoperationorder$(expression$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ e$ = evaluatetotyp(e$, 32&) IF Error_Happened THEN GOTO errmes PRINT #12, "tmp_long=" + e$ + "; if (!new_error){" PRINT #12, "if ((tmp_fileno>0)&&(tmp_fileno<=tqbs->len)){tqbs->chr[tmp_fileno-1]=tmp_long;}else{error(5);}" PRINT #12, "}}}" END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF 'MID$ statement IF n >= 1 THEN IF firstelement$ = "MID$" THEN IF getelement$(a$, 2) <> "(" THEN a$ = "Expected ( after MID$": GOTO errmes 'calculate 4 parts length$ = "" part = 1 i = 3 a3$ = "" stringvariable$ = "" start$ = "" B = 0 DO IF i > n THEN IF part <> 4 OR a3$ = "" THEN a$ = "Expected MID$(...)=...": GOTO errmes stringexpression$ = a3$ EXIT DO END IF a2$ = getelement$(ca$, i) IF a2$ = "(" THEN B = B + 1 IF a2$ = ")" THEN B = B - 1 IF B = -1 THEN IF part = 2 THEN IF getelement$(a$, i + 1) <> "=" THEN a$ = "Expected = after )": GOTO errmes start$ = a3$: part = 4: a3$ = "": i = i + 1: GOTO midgotpart END IF IF part = 3 THEN IF getelement$(a$, i + 1) <> "=" THEN a$ = "Expected = after )": GOTO errmes IF a3$ = "" THEN a$ = "Omit , before ) if omitting length in MID$ statement": GOTO errmes length$ = a3$: part = 4: a3$ = "": i = i + 1: GOTO midgotpart END IF END IF IF a2$ = "," AND B = 0 THEN IF part = 1 THEN stringvariable$ = a3$: part = 2: a3$ = "": GOTO midgotpart IF part = 2 THEN start$ = a3$: part = 3: a3$ = "": GOTO midgotpart END IF IF LEN(a3$) THEN a3$ = a3$ + sp + a2$ ELSE a3$ = a2$ midgotpart: i = i + 1 LOOP IF stringvariable$ = "" THEN a$ = "Syntax error": GOTO errmes IF start$ = "" THEN a$ = "Syntax error": GOTO errmes 'check if it is a valid source string stringvariable$ = fixoperationorder$(stringvariable$) IF Error_Happened THEN GOTO errmes l$ = "MID$" + sp2 + "(" + sp2 + tlayout$ e$ = evaluate(stringvariable$, sourcetyp) IF Error_Happened THEN GOTO errmes IF (sourcetyp AND ISREFERENCE) = 0 OR (sourcetyp AND ISSTRING) = 0 THEN a$ = "MID$ expects a string variable/array-element as its first argument": GOTO errmes stringvariable$ = evaluatetotyp(stringvariable$, ISSTRING) IF Error_Happened THEN GOTO errmes start$ = evaluatetotyp(fixoperationorder$(start$), 32&) IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ stringexpression$ = fixoperationorder$(stringexpression$) IF Error_Happened THEN GOTO errmes l2$ = tlayout$ stringexpression$ = evaluatetotyp(stringexpression$, ISSTRING) IF Error_Happened THEN GOTO errmes IF LEN(length$) THEN length$ = fixoperationorder$(length$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ length$ = evaluatetotyp(length$, 32&) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_mid(" + stringvariable$ + "," + start$ + "," + length$ + "," + stringexpression$ + ",1);" ELSE PRINT #12, "sub_mid(" + stringvariable$ + "," + start$ + ",0," + stringexpression$ + ",0);" END IF l$ = l$ + sp2 + ")" + sp + "=" + sp + l2$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF IF n >= 2 THEN IF firstelement$ = "ERASE" THEN i = 2 l$ = "ERASE" erasenextarray: var$ = getelement$(ca$, i) x$ = var$: ls$ = removesymbol(x$) IF Error_Happened THEN GOTO errmes IF FindArray(var$) THEN IF Error_Happened THEN GOTO errmes l$ = l$ + sp + RTRIM$(id.cn) + ls$ 'erase the array clearerase: n$ = RTRIM$(id.callname) bytesperelement$ = str2((id.arraytype AND 511) \ 8) IF id.arraytype AND ISSTRING THEN bytesperelement$ = str2(id.tsize) IF id.arraytype AND ISOFFSETINBITS THEN bytesperelement$ = str2((id.arraytype AND 511)) + "/8+1" IF id.arraytype AND ISUDT THEN bytesperelement$ = str2(udtxsize(id.arraytype AND 511) \ 8) END IF PRINT #12, "if (" + n$ + "[2]&1){" 'array is defined PRINT #12, "if (" + n$ + "[2]&2){" 'array is static IF (id.arraytype AND ISSTRING) <> 0 AND (id.arraytype AND ISFIXEDLENGTH) = 0 THEN PRINT #12, "tmp_long="; FOR i2 = 1 TO ABS(id.arrayelements) IF i2 <> 1 THEN PRINT #12, "*"; PRINT #12, n$ + "[" + str2(i2 * 4 - 4 + 5) + "]"; NEXT PRINT #12, ";" PRINT #12, "while(tmp_long--){" PRINT #12, "((qbs*)(((uint64*)(" + n$ + "[0]))[tmp_long]))->len=0;" PRINT #12, "}" ELSE 'numeric 'clear array PRINT #12, "memset((void*)(" + n$ + "[0]),0,"; FOR i2 = 1 TO ABS(id.arrayelements) IF i2 <> 1 THEN PRINT #12, "*"; PRINT #12, n$ + "[" + str2(i2 * 4 - 4 + 5) + "]"; NEXT PRINT #12, "*" + bytesperelement$ + ");" END IF PRINT #12, "}else{" 'array is dynamic '1. free memory & any allocated strings IF (id.arraytype AND ISSTRING) <> 0 AND (id.arraytype AND ISFIXEDLENGTH) = 0 THEN 'free strings PRINT #12, "tmp_long="; FOR i2 = 1 TO ABS(id.arrayelements) IF i2 <> 1 THEN PRINT #12, "*"; PRINT #12, n$ + "[" + str2(i2 * 4 - 4 + 5) + "]"; NEXT PRINT #12, ";" PRINT #12, "while(tmp_long--){" PRINT #12, "qbs_free((qbs*)(((uint64*)(" + n$ + "[0]))[tmp_long]));" PRINT #12, "}" 'free memory PRINT #12, "free((void*)(" + n$ + "[0]));" ELSE 'free memory PRINT #12, "if (" + n$ + "[2]&4){" 'cmem array PRINT #12, "cmem_dynamic_free((uint8*)(" + n$ + "[0]));" PRINT #12, "}else{" 'non-cmem array PRINT #12, "free((void*)(" + n$ + "[0]));" PRINT #12, "}" END IF '2. set array (and its elements) as undefined PRINT #12, n$ + "[2]^=1;" 'remove defined flag, keeping other flags (such as cmem) 'set dimensions as undefined FOR i2 = 1 TO ABS(id.arrayelements) B = i2 * 4 PRINT #12, n$ + "[" + str2(B) + "]=2147483647;" 'base PRINT #12, n$ + "[" + str2(B + 1) + "]=0;" 'num. index PRINT #12, n$ + "[" + str2(B + 2) + "]=0;" 'multiplier NEXT IF (id.arraytype AND ISSTRING) <> 0 AND (id.arraytype AND ISFIXEDLENGTH) = 0 THEN PRINT #12, n$ + "[0]=(ptrszint)¬hingstring;" ELSE PRINT #12, n$ + "[0]=(ptrszint)nothingvalue;" END IF PRINT #12, "}" 'static/dynamic PRINT #12, "}" 'array is defined IF clearerasereturn = 1 THEN clearerasereturn = 0: GOTO clearerasereturned GOTO erasedarray END IF IF Error_Happened THEN GOTO errmes a$ = "Undefined array passed to ERASE": GOTO errmes erasedarray: IF i < n THEN i = i + 1: n$ = getelement$(a$, i): IF n$ <> "," THEN a$ = "Expected ,": GOTO errmes l$ = l$ + sp2 + "," i = i + 1: IF i > n THEN a$ = "Expected , ...": GOTO errmes GOTO erasenextarray END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF 'DIM/REDIM/STATIC IF n >= 2 THEN dimoption = 0: redimoption = 0: commonoption = 0 IF firstelement$ = "DIM" THEN dimoption = 1 IF firstelement$ = "REDIM" THEN dimoption = 2: redimoption = 1 IF secondelement$ = "_PRESERVE" THEN redimoption = 2 IF n = 2 THEN a$ = "Expected REDIM _PRESERVE ...": GOTO errmes END IF END IF IF firstelement$ = "STATIC" THEN dimoption = 3 IF firstelement$ = "COMMON" THEN dimoption = 1: commonoption = 1 IF dimoption THEN l$ = firstelement$ IF dimoption = 3 AND subfuncn = 0 THEN a$ = "STATIC must be used within a SUB/FUNCTION": GOTO errmes IF commonoption = 1 AND subfuncn <> 0 THEN a$ = "COMMON cannot be used within a SUB/FUNCTION": GOTO errmes i = 2 IF redimoption = 2 THEN i = 3: l$ = l$ + sp + "_PRESERVE" IF dimoption <> 3 THEN 'shared cannot be static a2$ = getelement(a$, i) IF a2$ = "SHARED" THEN IF subfuncn <> 0 THEN a$ = "DIM/REDIM SHARED invalid within a SUB/FUNCTION": GOTO errmes dimshared = 1 i = i + 1 l$ = l$ + sp + a2$ END IF END IF IF dimoption = 3 THEN dimstatic = 1: AllowLocalName = 1 dimnext: notype = 0 listarray = 0 'old chain code 'chaincommonarray=0 varname$ = getelement(ca$, i): i = i + 1 IF varname$ = "" THEN a$ = "Expected variable-name": GOTO errmes 'get the next element IF i >= n + 1 THEN e$ = "" ELSE e$ = getelement(a$, i): i = i + 1 'check if next element is a ( to create an array elements$ = "" IF e$ = "(" THEN B = 1 FOR i = i TO n e$ = getelement(ca$, i) IF e$ = "(" THEN B = B + 1 IF e$ = ")" THEN B = B - 1 IF B = 0 THEN EXIT FOR IF LEN(elements$) THEN elements$ = elements$ + sp + e$ ELSE elements$ = e$ NEXT IF B <> 0 THEN a$ = "Expected )": GOTO errmes i = i + 1 'set i to point to the next element IF commonoption THEN elements$ = "?" IF Debug THEN PRINT #9, "DIM2:array:elements$:[" + elements$ + "]" 'arrayname() means list array to it will automatically be static when it is formally dimensioned later 'note: listed arrays are always created in dynamic memory, but their contents are not erased ' this differs from static arrays from SUB...STATIC and the unique QB64 method -> STATIC arrayname(100) IF dimoption = 3 THEN 'STATIC used IF LEN(elements$) = 0 THEN 'nothing between brackets listarray = 1 'add to static list END IF END IF 'last element was ")" 'get next element IF i >= n + 1 THEN e$ = "" ELSE e$ = getelement(a$, i): i = i + 1 END IF 'e$="(" d$ = e$ dimmethod = 0 appendname$ = "" 'the symbol to append to name returned by dim2 appendtype$ = "" 'eg. sp+AS+spINTEGER dim2typepassback$ = "" 'does varname have an appended symbol? s$ = removesymbol$(varname$) IF Error_Happened THEN GOTO errmes IF validname(varname$) = 0 THEN a$ = "Invalid variable name": GOTO errmes IF s$ <> "" THEN typ$ = s$ dimmethod = 1 appendname$ = typ$ GOTO dimgottyp END IF IF d$ = "AS" THEN appendtype$ = sp + "AS" typ$ = "" FOR i = i TO n d$ = getelement(a$, i) IF d$ = "," THEN i = i + 1: EXIT FOR typ$ = typ$ + d$ + " " appendtype$ = appendtype$ + sp + d$ d$ = "" NEXT appendtype$ = UCASE$(appendtype$) 'capitalise default types (udt override this later if necessary) typ$ = RTRIM$(typ$) GOTO dimgottyp END IF 'auto-define type based on name notype = 1 IF LEFT$(varname$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(varname$)) - 64 typ$ = defineaz(v) dimmethod = 1 GOTO dimgottyp dimgottyp: IF d$ <> "" AND d$ <> "," THEN a$ = "DIM: Expected comma!": GOTO errmes 'In QBASIC, if no type info is given it can refer to an expeicit/formally defined array IF notype <> 0 AND dimoption <> 3 AND dimoption <> 1 THEN 'not DIM or STATIC which only create new content IF LEN(elements$) THEN 'an array IF FindArray(varname$) THEN IF LEN(RTRIM$(id.mayhave)) THEN 'explict/formally defined typ$ = id2fulltypename$ 'adopt type dimmethod = 0 'set as formally defined END IF END IF END IF END IF IF dimoption = 3 AND LEN(elements$) THEN 'eg. STATIC a(100) 'does a conflicting array exist? (use findarray) if so again this should lead to duplicate definition typ2$ = symbol2fulltypename$(typ$) t = typname2typ(typ2$): ts = typname2typsize 'try name without any extension IF FindArray(varname$) THEN 'name without any symbol IF id.insubfuncn = subfuncn THEN 'global cannot conflict with static IF LEN(RTRIM$(id.musthave)) THEN 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF ELSE IF dimmethod = 0 THEN a$ = "Name already in use": GOTO errmes 'explicit over explicit ELSE 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF END IF END IF END IF END IF 'add extension (if possible) IF (t AND ISUDT) = 0 THEN s2$ = type2symbol$(typ2$) IF Error_Happened THEN GOTO errmes IF FindArray(varname$ + s2$) THEN IF id.insubfuncn = subfuncn THEN 'global cannot conflict with static IF LEN(RTRIM$(id.musthave)) THEN 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF ELSE IF dimmethod = 0 THEN a$ = "Name already in use": GOTO errmes 'explicit over explicit ELSE 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF END IF END IF END IF END IF END IF 'not a UDT END IF IF listarray THEN 'eg. STATIC a() 'note: list is cleared by END SUB/FUNCTION 'is a conflicting array already listed? if so this should cause a duplicate definition error 'check for conflict within list: xi = 1 FOR x = 1 TO staticarraylistn varname2$ = getelement$(staticarraylist, xi): xi = xi + 1 typ2$ = getelement$(staticarraylist, xi): xi = xi + 1 dimmethod2 = VAL(getelement$(staticarraylist, xi)): xi = xi + 1 'check if they are similar IF UCASE$(varname$) = UCASE$(varname2$) THEN IF dimmethod2 = 1 THEN 'old using symbol IF symbol2fulltypename$(typ$) = typ2$ THEN a$ = "Name already in use": GOTO errmes ELSE 'old using AS IF dimmethod = 0 THEN a$ = "Name already in use": GOTO errmes ELSE IF symbol2fulltypename$(typ$) = typ2$ THEN a$ = "Name already in use": GOTO errmes END IF END IF END IF NEXT 'does a conflicting array exist? (use findarray) if so again this should lead to duplicate definition typ2$ = symbol2fulltypename$(typ$) t = typname2typ(typ2$): ts = typname2typsize 'try name without any extension IF FindArray(varname$) THEN 'name without any symbol IF id.insubfuncn = subfuncn THEN 'global cannot conflict with static IF LEN(RTRIM$(id.musthave)) THEN 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF ELSE IF dimmethod = 0 THEN a$ = "Name already in use": GOTO errmes 'explicit over explicit ELSE 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF END IF END IF END IF END IF 'add extension (if possible) IF (t AND ISUDT) = 0 THEN s2$ = type2symbol$(typ2$) IF Error_Happened THEN GOTO errmes IF FindArray(varname$ + s2$) THEN IF id.insubfuncn = subfuncn THEN 'global cannot conflict with static IF LEN(RTRIM$(id.musthave)) THEN 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF ELSE IF dimmethod = 0 THEN a$ = "Name already in use": GOTO errmes 'explicit over explicit ELSE 'if types match then fail IF (id.arraytype AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) = (t AND (ISFLOAT + ISUDT + 511 + ISUNSIGNED + ISSTRING + ISFIXEDLENGTH)) THEN IF ts = id.tsize THEN a$ = "Name already in use": GOTO errmes END IF END IF END IF END IF END IF END IF END IF 'not a UDT 'note: static list arrays cannot be created until they are formally [or informally] (RE)DIM'd later IF LEN(staticarraylist) THEN staticarraylist = staticarraylist + sp staticarraylist = staticarraylist + varname$ + sp + symbol2fulltypename$(typ$) + sp + str2(dimmethod) IF Error_Happened THEN GOTO errmes staticarraylistn = staticarraylistn + 1 l$ = l$ + sp + varname$ + appendname$ + sp2 + "(" + sp2 + ")" + appendtype$ 'note: none of the following code is run, dim2 call is also skipped ELSE olddimstatic = dimstatic 'check if varname is on the static list IF LEN(elements$) THEN 'it's an array IF subfuncn THEN 'it's in a sub/function xi = 1 FOR x = 1 TO staticarraylistn varname2$ = getelement$(staticarraylist, xi): xi = xi + 1 typ2$ = getelement$(staticarraylist, xi): xi = xi + 1 dimmethod2 = VAL(getelement$(staticarraylist, xi)): xi = xi + 1 'check if they are similar IF UCASE$(varname$) = UCASE$(varname2$) THEN IF symbol2fulltypename$(typ$) = typ2$ THEN IF Error_Happened THEN GOTO errmes IF dimmethod = dimmethod2 THEN 'match found! varname$ = varname2$ dimstatic = 3 IF dimoption = 3 THEN a$ = "Array already listed as STATIC": GOTO errmes END IF END IF 'typ END IF 'varname NEXT END IF END IF 'COMMON exception 'note: COMMON alone does not imply SHARED ' if either(or both) COMMON & later DIM have SHARED, variable becomes shared IF commonoption THEN IF LEN(elements$) THEN 'add array to list IF LEN(commonarraylist) THEN commonarraylist = commonarraylist + sp 'note: dimmethod distinguishes between a%(...) vs a(...) AS INTEGER commonarraylist = commonarraylist + varname$ + sp + symbol2fulltypename$(typ$) + sp + str2(dimmethod) + sp + str2(dimshared) IF Error_Happened THEN GOTO errmes commonarraylistn = commonarraylistn + 1 IF Debug THEN PRINT #9, "common listed:" + varname$ + sp + symbol2fulltypename$(typ$) + sp + str2(dimmethod) + sp + str2(dimshared) IF Error_Happened THEN GOTO errmes x = 0 v$ = varname$ IF dimmethod = 1 THEN v$ = v$ + typ$ try = findid(v$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.arraytype THEN t = typname2typ(typ$) IF Error_Happened THEN GOTO errmes s = typname2typsize match = 1 'note: dimmethod 2 is already matched IF dimmethod = 0 THEN t2 = id.arraytype s2 = id.tsize IF (t AND ISFLOAT) <> (t2 AND ISFLOAT) THEN match = 0 IF (t AND ISUNSIGNED) <> (t2 AND ISUNSIGNED) THEN match = 0 IF (t AND ISSTRING) <> (t2 AND ISSTRING) THEN match = 0 IF (t AND ISFIXEDLENGTH) <> (t2 AND ISFIXEDLENGTH) THEN match = 0 IF (t AND ISOFFSETINBITS) <> (t2 AND ISOFFSETINBITS) THEN match = 0 IF (t AND ISUDT) <> (t2 AND ISUDT) THEN match = 0 IF (t AND 511) <> (t2 AND 511) THEN match = 0 IF s <> s2 THEN match = 0 'check for implicit/explicit declaration match oldmethod = 0: IF LEN(RTRIM$(id.musthave)) THEN oldmethod = 1 IF oldmethod <> dimmethod THEN match = 0 END IF IF match THEN x = currentid IF dimshared THEN ids(x).share = 1 'share if necessary tlayout$ = RTRIM$(id.cn) + sp + "(" + sp2 + ")" IF dimmethod = 0 THEN IF t AND ISUDT THEN dim2typepassback$ = RTRIM$(udtxcname(t AND 511)) ELSE dim2typepassback$ = typ$ DO WHILE INSTR(dim2typepassback$, " ") ASC(dim2typepassback$, INSTR(dim2typepassback$, " ")) = ASC(sp) LOOP dim2typepassback$ = UCASE$(dim2typepassback$) END IF END IF 'method 0 EXIT DO END IF 'match END IF 'arraytype IF try = 2 THEN findanotherid = 1: try = findid(v$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP IF x = 0 THEN x = idn + 1 'note: the following code only adds include directives, everything else is defered OPEN tmpdir$ + "chain.txt" FOR APPEND AS #22 'include directive PRINT #22, "#include " + CHR$(34) + "chain" + str2$(x) + ".txt" + CHR$(34) CLOSE #22 'create/clear include file OPEN tmpdir$ + "chain" + str2$(x) + ".txt" FOR OUTPUT AS #22: CLOSE #22 OPEN tmpdir$ + "inpchain.txt" FOR APPEND AS #22 'include directive PRINT #22, "#include " + CHR$(34) + "inpchain" + str2$(x) + ".txt" + CHR$(34) CLOSE #22 'create/clear include file OPEN tmpdir$ + "inpchain" + str2$(x) + ".txt" FOR OUTPUT AS #22: CLOSE #22 'note: elements$="?" IF x <> idn + 1 THEN GOTO skipdim 'array already exists GOTO dimcommonarray END IF END IF 'is varname on common list? '****** IF LEN(elements$) THEN 'it's an array IF subfuncn = 0 THEN 'not in a sub/function IF Debug THEN PRINT #9, "common checking:" + varname$ xi = 1 FOR x = 1 TO commonarraylistn varname2$ = getelement$(commonarraylist, xi): xi = xi + 1 typ2$ = getelement$(commonarraylist, xi): xi = xi + 1 dimmethod2 = VAL(getelement$(commonarraylist, xi)): xi = xi + 1 dimshared2 = VAL(getelement$(commonarraylist, xi)): xi = xi + 1 IF Debug THEN PRINT #9, "common checking against:" + varname2$ + sp + typ2$ + sp + str2(dimmethod2) + sp + str2(dimshared2) 'check if they are similar IF varname$ = varname2$ THEN IF symbol2fulltypename$(typ$) = typ2$ THEN IF Error_Happened THEN GOTO errmes IF dimmethod = dimmethod2 THEN 'match found! 'enforce shared status (if necessary) IF dimshared2 THEN dimshared = dimshared OR 2 'temp force SHARED 'old chain code 'chaincommonarray=x END IF 'method END IF 'typ END IF 'varname NEXT END IF END IF dimcommonarray: retval = dim2(varname$, typ$, dimmethod, elements$) IF Error_Happened THEN GOTO errmes skipdim: IF dimshared >= 2 THEN dimshared = dimshared - 2 'non-array COMMON variable IF commonoption <> 0 AND LEN(elements$) = 0 THEN 'CHAIN.TXT (save) use_global_byte_elements = 1 'switch output from main.txt to chain.txt CLOSE #12 OPEN tmpdir$ + "chain.txt" FOR APPEND AS #12 l2$ = tlayout$ PRINT #12, "int32val=1;" 'simple variable PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" t = id.t bits = t AND 511 IF t AND ISUDT THEN bits = udtxsize(t AND 511) IF t AND ISSTRING THEN IF t AND ISFIXEDLENGTH THEN bits = id.tsize * 8 ELSE PRINT #12, "int64val=__STRING_" + RTRIM$(id.n) + "->len*8;" bits = 0 END IF END IF IF bits THEN PRINT #12, "int64val=" + str2$(bits) + ";" 'size in bits END IF PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" 'put the variable e$ = RTRIM$(id.n) IF (t AND ISUDT) = 0 THEN IF t AND ISFIXEDLENGTH THEN e$ = e$ + "$" + str2$(id.tsize) ELSE e$ = e$ + typevalue2symbol$(t) IF Error_Happened THEN GOTO errmes END IF END IF e$ = evaluatetotyp(fixoperationorder$(e$), -4) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_put(FF,NULL," + e$ + ",0);" tlayout$ = l2$ 'revert output to main.txt CLOSE #12 OPEN tmpdir$ + "main.txt" FOR APPEND AS #12 'INPCHAIN.TXT (load) 'switch output from main.txt to chain.txt CLOSE #12 OPEN tmpdir$ + "inpchain.txt" FOR APPEND AS #12 l2$ = tlayout$ PRINT #12, "if (int32val==1){" 'get the size in bits PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" '***assume correct size*** e$ = RTRIM$(id.n) t = id.t IF (t AND ISUDT) = 0 THEN IF t AND ISFIXEDLENGTH THEN e$ = e$ + "$" + str2$(id.tsize) ELSE e$ = e$ + typevalue2symbol$(t) IF Error_Happened THEN GOTO errmes END IF END IF IF t AND ISSTRING THEN IF (t AND ISFIXEDLENGTH) = 0 THEN PRINT #12, "tqbs=qbs_new(int64val>>3,1);" PRINT #12, "qbs_set(__STRING_" + RTRIM$(id.n) + ",tqbs);" 'now that the string is the correct size, the following GET command will work correctly... END IF END IF e$ = evaluatetotyp(fixoperationorder$(e$), -4) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_get(FF,NULL," + e$ + ",0);" PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" 'get next command PRINT #12, "}" tlayout$ = l2$ 'revert output to main.txt CLOSE #12 OPEN tmpdir$ + "main.txt" FOR APPEND AS #12 use_global_byte_elements = 0 END IF commonarraylisted: n2 = numelements(tlayout$) l$ = l$ + sp + getelement$(tlayout$, 1) + appendname$ IF n2 > 1 THEN l$ = l$ + sp2 + getelements$(tlayout$, 2, n2) END IF IF LEN(appendtype$) THEN IF LEN(dim2typepassback$) THEN appendtype$ = sp + "AS" + sp + dim2typepassback$ l$ = l$ + appendtype$ END IF 'modify first element name to include symbol dimstatic = olddimstatic END IF 'listarray=0 IF d$ = "," THEN l$ = l$ + sp2 + ",": GOTO dimnext dimoption = 0 dimshared = 0 redimoption = 0 IF dimstatic = 1 THEN dimstatic = 0 AllowLocalName = 0 layoutdone = 1 IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ GOTO finishedline END IF END IF 'THEN [GOTO] linenumber? IF THENGOTO = 1 THEN IF n = 1 THEN l$ = "" a = ASC(LEFT$(firstelement$, 1)) IF a = 46 OR (a >= 48 AND a <= 57) THEN a2$ = ca$: GOTO THENGOTO END IF END IF 'goto IF n = 2 THEN IF getelement$(a$, 1) = "GOTO" THEN l$ = "GOTO" a2$ = getelement$(ca$, 2) THENGOTO: IF validlabel(a2$) = 0 THEN a$ = "Invalid label!": GOTO errmes v = HashFind(a2$, HASHFLAG_LABEL, ignore, r) x = 1 labchk2: IF v THEN s = Labels(r).Scope IF s = subfuncn OR s = -1 THEN 'same scope? IF s = -1 THEN Labels(r).Scope = subfuncn 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk2 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd a2$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = subfuncn Labels(r).Error_Line = linenumber END IF 'x IF LEN(l$) THEN l$ = l$ + sp + tlayout$ ELSE l$ = tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ PRINT #12, "goto LABEL_" + a2$ + ";" GOTO finishedline END IF END IF IF firstelement$ = "RUN" THEN 'RUN l$ = "RUN" IF n = 1 THEN 'no parameters PRINT #12, "sub_run_init();" 'note: called first to free up screen-locked image handles PRINT #12, "sub_clear(NULL,NULL,NULL,NULL);" 'use functionality of CLEAR IF LEN(subfunc$) THEN PRINT #12, "QBMAIN(NULL);" ELSE PRINT #12, "goto S_0;" END IF ELSE 'parameter passed e$ = getelements$(ca$, 2, n) e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l2$ = tlayout$ ignore$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF n = 2 AND ((typ AND ISSTRING) = 0) THEN 'assume it's a label or line number lbl$ = getelement$(ca$, 2) IF validlabel(lbl$) = 0 THEN a$ = "Invalid label!": GOTO errmes 'invalid label v = HashFind(lbl$, HASHFLAG_LABEL, ignore, r) x = 1 labchk501: IF v THEN s = Labels(r).Scope IF s = 0 OR s = -1 THEN 'main scope? IF s = -1 THEN Labels(r).Scope = 0 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) Labels(r).Scope_Restriction = subfuncn Labels(r).Error_Line = linenumber ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk501 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd lbl$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = 0 Labels(r).Error_Line = linenumber Labels(r).Scope_Restriction = subfuncn END IF 'x l$ = l$ + sp + tlayout$ PRINT #12, "sub_run_init();" 'note: called first to free up screen-locked image handles PRINT #12, "sub_clear(NULL,NULL,NULL,NULL);" 'use functionality of CLEAR IF LEN(subfunc$) THEN PRINT #21, "if (run_from_line==" + str2(nextrunlineindex) + "){run_from_line=0;goto LABEL_" + lbl$ + ";}" PRINT #12, "run_from_line=" + str2(nextrunlineindex) + ";" nextrunlineindex = nextrunlineindex + 1 PRINT #12, "QBMAIN(NULL);" ELSE PRINT #12, "goto LABEL_" + lbl$ + ";" END IF ELSE 'assume it's a string containing a filename to execute IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** e$ = evaluatetotyp(e$, ISSTRING) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_run(" + e$ + ");" l$ = l$ + sp + l2$ END IF 'isstring END IF 'n=1 layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF 'run IF firstelement$ = "END" THEN l$ = "END" IF n > 1 THEN e$ = getelements$(ca$, 2, n) e$ = fixoperationorder$(e$): IF Error_Happened THEN GOTO errmes l2$ = tlayout$ e$ = evaluatetotyp(e$, ISINTEGER64): IF Error_Happened THEN GOTO errmes PRINT #12, "if(qbevent){evnt(" + str2$(linenumber) + ");}" 'non-resumable error check (cannot exit without handling errors) PRINT #12, "exit_code=" + e$ + ";" l$ = l$ + sp + l2$ END IF xend layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF IF firstelement$ = "SYSTEM" THEN l$ = "SYSTEM" IF n > 1 THEN e$ = getelements$(ca$, 2, n) e$ = fixoperationorder$(e$): IF Error_Happened THEN GOTO errmes l2$ = tlayout$ e$ = evaluatetotyp(e$, ISINTEGER64): IF Error_Happened THEN GOTO errmes PRINT #12, "if(qbevent){evnt(" + str2$(linenumber) + ");}" 'non-resumable error check (cannot exit without handling errors) PRINT #12, "exit_code=" + e$ + ";" l$ = l$ + sp + l2$ END IF PRINT #12, "if (sub_gl_called) error(271);" PRINT #12, "close_program=1;" PRINT #12, "end();" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF IF n >= 1 THEN IF firstelement$ = "STOP" THEN l$ = "STOP" IF n > 1 THEN e$ = getelements$(ca$, 2, n) e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = "STOP" + sp + tlayout$ e$ = evaluatetotyp(e$, 64) IF Error_Happened THEN GOTO errmes 'note: this value is currently ignored but evaluated for checking reasons END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ PRINT #12, "close_program=1;" PRINT #12, "end();" GOTO finishedline END IF END IF IF n = 2 THEN IF firstelement$ = "GOSUB" THEN xgosub ca$, n IF Error_Happened THEN GOTO errmes 'note: layout implemented in xgosub GOTO finishedline END IF END IF IF n >= 1 THEN IF firstelement$ = "RETURN" THEN IF n = 1 THEN PRINT #12, "#include " + CHR$(34) + "ret" + str2$(subfuncn) + ".txt" + CHR$(34) l$ = "RETURN" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline ELSE 'label/linenumber follows IF subfuncn <> 0 THEN a$ = "RETURN linelabel/linenumber invalid within a SUB/FUNCTION": GOTO errmes IF n > 2 THEN a$ = "Expected linelabel/linenumber after RETURN": GOTO errmes PRINT #12, "if (!next_return_point) error(3);" 'check return point available PRINT #12, "next_return_point--;" 'destroy return point a2$ = getelement$(ca$, 2) IF validlabel(a2$) = 0 THEN a$ = "Invalid label!": GOTO errmes v = HashFind(a2$, HASHFLAG_LABEL, ignore, r) x = 1 labchk505: IF v THEN s = Labels(r).Scope IF s = subfuncn OR s = -1 THEN 'same scope? IF s = -1 THEN Labels(r).Scope = subfuncn 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk505 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd a2$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = subfuncn Labels(r).Error_Line = linenumber END IF 'x PRINT #12, "goto LABEL_" + a2$ + ";" l$ = "RETURN" + sp + tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF END IF IF n >= 1 THEN IF firstelement$ = "RESUME" THEN l$ = "RESUME" IF n = 1 THEN resumeprev: IF C_Core = 0 THEN PRINT #12, "if (!error_handling){error(20);}else{error_retry=1; qbevent=1; error_handling=0; error_err=0; return NULL;}" IF C_Core = 1 THEN PRINT #12, "if (!error_handling){error(20);}else{error_retry=1; qbevent=1; error_handling=0; error_err=0; return;}" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF IF n > 2 THEN a$ = "Too many parameters": GOTO errmes s$ = getelement$(ca$, 2) IF UCASE$(s$) = "NEXT" THEN IF C_Core = 0 THEN PRINT #12, "if (!error_handling){error(20);}else{error_handling=0; error_err=0; return NULL;}" IF C_Core = 1 THEN PRINT #12, "if (!error_handling){error(20);}else{error_handling=0; error_err=0; return;}" l$ = l$ + sp + "NEXT" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF IF s$ = "0" THEN l$ = l$ + sp + "0": GOTO resumeprev IF validlabel(s$) = 0 THEN a$ = "Invalid label passed to RESUME": GOTO errmes v = HashFind(s$, HASHFLAG_LABEL, ignore, r) x = 1 labchk506: IF v THEN s = Labels(r).Scope IF s = subfuncn OR s = -1 THEN 'same scope? IF s = -1 THEN Labels(r).Scope = subfuncn 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk506 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd s$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = subfuncn Labels(r).Error_Line = linenumber END IF 'x l$ = l$ + sp + tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ PRINT #12, "if (!error_handling){error(20);}else{error_handling=0; error_err=0; goto LABEL_" + s$ + ";}" GOTO finishedline END IF END IF IF n = 4 THEN IF getelements(a$, 1, 3) = "ON" + sp + "ERROR" + sp + "GOTO" THEN l$ = "ON" + sp + "ERROR" + sp + "GOTO" lbl$ = getelement$(ca$, 4) IF lbl$ = "0" THEN PRINT #12, "error_goto_line=0;" l$ = l$ + sp + "0" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF IF validlabel(lbl$) = 0 THEN a$ = "Invalid label": GOTO errmes v = HashFind(lbl$, HASHFLAG_LABEL, ignore, r) x = 1 labchk6: IF v THEN s = Labels(r).Scope IF s = 0 OR s = -1 THEN 'main scope? IF s = -1 THEN Labels(r).Scope = 0 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) Labels(r).Scope_Restriction = subfuncn Labels(r).Error_Line = linenumber ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk6 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd lbl$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = 0 Labels(r).Error_Line = linenumber Labels(r).Scope_Restriction = subfuncn END IF 'x l$ = l$ + sp + tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ errorlabels = errorlabels + 1 PRINT #12, "error_goto_line=" + str2(errorlabels) + ";" PRINT #14, "if (error_goto_line==" + str2(errorlabels) + "){error_handling=1; goto LABEL_" + lbl$ + ";}" GOTO finishedline END IF END IF IF n >= 1 THEN IF firstelement$ = "RESTORE" THEN l$ = "RESTORE" IF n = 1 THEN PRINT #12, "data_offset=0;" ELSE IF n > 2 THEN a$ = "Syntax error": GOTO errmes lbl$ = getelement$(ca$, 2) IF validlabel(lbl$) = 0 THEN a$ = "Invalid label": GOTO errmes 'rule: a RESTORE label has no scope, therefore, only one instance of that label may exist 'how: enforced by a post check for duplicates v = HashFind(lbl$, HASHFLAG_LABEL, ignore, r) x = 1 IF v THEN 'already defined x = 0 tlayout$ = RTRIM$(Labels(r).cn) Labels(r).Data_Referenced = 1 'make sure the data referenced flag is set IF Labels(r).Error_Line = 0 THEN Labels(r).Error_Line = linenumber END IF IF x THEN nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd lbl$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = -1 'modifyable scope Labels(r).Error_Line = linenumber Labels(r).Data_Referenced = 1 END IF 'x l$ = l$ + sp + tlayout$ PRINT #12, "data_offset=data_at_LABEL_" + lbl$ + ";" END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF 'ON ... GOTO/GOSUB IF n >= 1 THEN IF firstelement$ = "ON" THEN xongotogosub a$, ca$, n IF Error_Happened THEN GOTO errmes GOTO finishedline END IF END IF '(_MEM) _MEMPUT _MEMGET IF n >= 1 THEN IF firstelement$ = "_MEMGET" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** 'get expressions e$ = "" B = 0 ne = 0 FOR i2 = 2 TO n e2$ = getelement$(ca$, i2) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF e2$ = "," AND B = 0 THEN ne = ne + 1 IF ne = 1 THEN blk$ = e$: e$ = "" IF ne = 2 THEN offs$ = e$: e$ = "" IF ne = 3 THEN a$ = "Syntax error": GOTO errmes ELSE IF LEN(e$) = 0 THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ END IF NEXT var$ = e$ IF e$ = "" OR ne <> 2 THEN a$ = "Expected _MEMGET mem-reference,offset,variable": GOTO errmes l$ = "_MEMGET" + sp e$ = fixoperationorder$(blk$): IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ test$ = evaluate(e$, typ): IF Error_Happened THEN GOTO errmes IF (typ AND ISUDT) = 0 OR (typ AND 511) <> 1 THEN a$ = "Expected _MEM type": GOTO errmes blkoffs$ = evaluatetotyp(e$, -6) ' IF typ AND ISREFERENCE THEN e$ = refer(e$, typ, 0) 'PRINT #12, blkoffs$ '??? e$ = fixoperationorder$(offs$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ e$ = evaluatetotyp(e$, OFFSETTYPE - ISPOINTER): IF Error_Happened THEN GOTO errmes offs$ = e$ 'PRINT #12, e$ '??? e$ = fixoperationorder$(var$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ varsize$ = evaluatetotyp(e$, -5): IF Error_Happened THEN GOTO errmes varoffs$ = evaluatetotyp(e$, -6): IF Error_Happened THEN GOTO errmes 'PRINT #12, varoffs$ '??? 'PRINT #12, varsize$ '??? 'what do we do next 'need to know offset of variable and its size 'known sizes will be handled by designated command casts, otherwise use memmove s = 0 IF varsize$ = "1" THEN s = 1: st$ = "int8" IF varsize$ = "2" THEN s = 2: st$ = "int16" IF varsize$ = "4" THEN s = 4: st$ = "int32" IF varsize$ = "8" THEN s = 8: st$ = "int64" IF NoChecks THEN 'fast version: IF s THEN PRINT #12, "*(" + st$ + "*)" + varoffs$ + "=*(" + st$ + "*)(" + offs$ + ");" ELSE PRINT #12, "memmove(" + varoffs$ + ",(void*)" + offs$ + "," + varsize$ + ");" END IF ELSE 'safe version: PRINT #12, "tmp_long=" + offs$ + ";" 'is mem block init? PRINT #12, "if ( ((mem_block*)(" + blkoffs$ + "))->lock_offset ){" 'are region and id valid? PRINT #12, "if (" PRINT #12, "tmp_long < ((mem_block*)(" + blkoffs$ + "))->offset ||" PRINT #12, "(tmp_long+(" + varsize$ + ")) > ( ((mem_block*)(" + blkoffs$ + "))->offset + ((mem_block*)(" + blkoffs$ + "))->size) ||" PRINT #12, "((mem_lock*)((mem_block*)(" + blkoffs$ + "))->lock_offset)->id != ((mem_block*)(" + blkoffs$ + "))->lock_id ){" 'diagnose error PRINT #12, "if (" + "((mem_lock*)((mem_block*)(" + blkoffs$ + "))->lock_offset)->id != ((mem_block*)(" + blkoffs$ + "))->lock_id" + ") error(308); else error(300);" PRINT #12, "}else{" IF s THEN PRINT #12, "*(" + st$ + "*)" + varoffs$ + "=*(" + st$ + "*)tmp_long;" ELSE PRINT #12, "memmove(" + varoffs$ + ",(void*)tmp_long," + varsize$ + ");" END IF PRINT #12, "}" PRINT #12, "}else error(309);" END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF IF n >= 1 THEN IF firstelement$ = "_MEMPUT" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** 'get expressions typ$ = "" e$ = "" B = 0 ne = 0 FOR i2 = 2 TO n e2$ = getelement$(ca$, i2) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF (e2$ = "," OR UCASE$(e2$) = "AS") AND B = 0 THEN ne = ne + 1 IF ne = 1 THEN blk$ = e$: e$ = "" IF ne = 2 THEN offs$ = e$: e$ = "" IF ne = 3 THEN var$ = e$: e$ = "" IF (UCASE$(e2$) = "AS" AND ne <> 3) OR (ne = 3 AND UCASE$(e2$) <> "AS") OR ne = 4 THEN a$ = "Expected _MEMPUT mem-reference,offset,variable|value[AS type]": GOTO errmes ELSE IF LEN(e$) = 0 THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ END IF NEXT IF ne < 2 OR e$ = "" THEN a$ = "Expected _MEMPUT mem-reference,offset,variable|value[AS type]": GOTO errmes IF ne = 2 THEN var$ = e$ ELSE typ$ = UCASE$(e$) l$ = "_MEMPUT" + sp e$ = fixoperationorder$(blk$): IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ test$ = evaluate(e$, typ): IF Error_Happened THEN GOTO errmes IF (typ AND ISUDT) = 0 OR (typ AND 511) <> 1 THEN a$ = "Expected _MEM type": GOTO errmes blkoffs$ = evaluatetotyp(e$, -6) e$ = fixoperationorder$(offs$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ e$ = evaluatetotyp(e$, OFFSETTYPE - ISPOINTER): IF Error_Happened THEN GOTO errmes offs$ = e$ IF ne = 2 THEN e$ = fixoperationorder$(var$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ test$ = evaluate(e$, t) IF (t AND ISREFERENCE) = 0 AND (t AND ISSTRING) THEN PRINT #12, "g_tmp_str=" + test$ + ";" varsize$ = "g_tmp_str->len" varoffs$ = "g_tmp_str->chr" ELSE varsize$ = evaluatetotyp(e$, -5): IF Error_Happened THEN GOTO errmes varoffs$ = evaluatetotyp(e$, -6): IF Error_Happened THEN GOTO errmes END IF 'known sizes will be handled by designated command casts, otherwise use memmove s = 0 IF varsize$ = "1" THEN s = 1: st$ = "int8" IF varsize$ = "2" THEN s = 2: st$ = "int16" IF varsize$ = "4" THEN s = 4: st$ = "int32" IF varsize$ = "8" THEN s = 8: st$ = "int64" IF NoChecks THEN 'fast version: IF s THEN PRINT #12, "*(" + st$ + "*)(" + offs$ + ")=*(" + st$ + "*)" + varoffs$ + ";" ELSE PRINT #12, "memmove((void*)" + offs$ + "," + varoffs$ + "," + varsize$ + ");" END IF ELSE 'safe version: PRINT #12, "tmp_long=" + offs$ + ";" 'is mem block init? PRINT #12, "if ( ((mem_block*)(" + blkoffs$ + "))->lock_offset ){" 'are region and id valid? PRINT #12, "if (" PRINT #12, "tmp_long < ((mem_block*)(" + blkoffs$ + "))->offset ||" PRINT #12, "(tmp_long+(" + varsize$ + ")) > ( ((mem_block*)(" + blkoffs$ + "))->offset + ((mem_block*)(" + blkoffs$ + "))->size) ||" PRINT #12, "((mem_lock*)((mem_block*)(" + blkoffs$ + "))->lock_offset)->id != ((mem_block*)(" + blkoffs$ + "))->lock_id ){" 'diagnose error PRINT #12, "if (" + "((mem_lock*)((mem_block*)(" + blkoffs$ + "))->lock_offset)->id != ((mem_block*)(" + blkoffs$ + "))->lock_id" + ") error(308); else error(300);" PRINT #12, "}else{" IF s THEN PRINT #12, "*(" + st$ + "*)tmp_long=*(" + st$ + "*)" + varoffs$ + ";" ELSE PRINT #12, "memmove((void*)tmp_long," + varoffs$ + "," + varsize$ + ");" END IF PRINT #12, "}" PRINT #12, "}else error(309);" END IF ELSE '... AS type method 'FUNCTION typname2typ& (t2$) 'typname2typsize = 0 'the default t = typname2typ(typ$) IF t = 0 THEN a$ = "Invalid type": GOTO errmes IF (t AND ISOFFSETINBITS) <> 0 OR (t AND ISUDT) <> 0 OR (t AND ISSTRING) THEN a$ = "_MEMPUT requires numeric type": GOTO errmes IF (t AND ISPOINTER) THEN t = t - ISPOINTER 'attempt conversion... e$ = fixoperationorder$(var$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ + sp + "AS" + sp + typ$ e$ = evaluatetotyp(e$, t): IF Error_Happened THEN GOTO errmes st$ = typ2ctyp$(t, "") varsize$ = str2((t AND 511) \ 8) IF NoChecks THEN 'fast version: PRINT #12, "*(" + st$ + "*)(" + offs$ + ")=" + e$ + ";" ELSE 'safe version: PRINT #12, "tmp_long=" + offs$ + ";" 'is mem block init? PRINT #12, "if ( ((mem_block*)(" + blkoffs$ + "))->lock_offset ){" 'are region and id valid? PRINT #12, "if (" PRINT #12, "tmp_long < ((mem_block*)(" + blkoffs$ + "))->offset ||" PRINT #12, "(tmp_long+(" + varsize$ + ")) > ( ((mem_block*)(" + blkoffs$ + "))->offset + ((mem_block*)(" + blkoffs$ + "))->size) ||" PRINT #12, "((mem_lock*)((mem_block*)(" + blkoffs$ + "))->lock_offset)->id != ((mem_block*)(" + blkoffs$ + "))->lock_id ){" 'diagnose error PRINT #12, "if (" + "((mem_lock*)((mem_block*)(" + blkoffs$ + "))->lock_offset)->id != ((mem_block*)(" + blkoffs$ + "))->lock_id" + ") error(308); else error(300);" PRINT #12, "}else{" PRINT #12, "*(" + st$ + "*)tmp_long=" + e$ + ";" PRINT #12, "}" PRINT #12, "}else error(309);" END IF END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF IF n >= 1 THEN IF firstelement$ = "_MEMFILL" THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** 'get expressions typ$ = "" e$ = "" B = 0 ne = 0 FOR i2 = 2 TO n e2$ = getelement$(ca$, i2) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF (e2$ = "," OR UCASE$(e2$) = "AS") AND B = 0 THEN ne = ne + 1 IF ne = 1 THEN blk$ = e$: e$ = "" IF ne = 2 THEN offs$ = e$: e$ = "" IF ne = 3 THEN bytes$ = e$: e$ = "" IF ne = 4 THEN var$ = e$: e$ = "" IF (UCASE$(e2$) = "AS" AND ne <> 4) OR (ne = 4 AND UCASE$(e2$) <> "AS") OR ne = 5 THEN a$ = "Expected _MEMFILL mem-reference,offset,bytes,variable|value[AS type]": GOTO errmes ELSE IF LEN(e$) = 0 THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ END IF NEXT IF ne < 3 OR e$ = "" THEN a$ = "Expected _MEMFILL mem-reference,offset,bytes,variable|value[AS type]": GOTO errmes IF ne = 3 THEN var$ = e$ ELSE typ$ = UCASE$(e$) l$ = "_MEMFILL" + sp e$ = fixoperationorder$(blk$): IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ test$ = evaluate(e$, typ): IF Error_Happened THEN GOTO errmes IF (typ AND ISUDT) = 0 OR (typ AND 511) <> 1 THEN a$ = "Expected _MEM type": GOTO errmes blkoffs$ = evaluatetotyp(e$, -6) e$ = fixoperationorder$(offs$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ e$ = evaluatetotyp(e$, OFFSETTYPE - ISPOINTER): IF Error_Happened THEN GOTO errmes offs$ = e$ e$ = fixoperationorder$(bytes$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ e$ = evaluatetotyp(e$, OFFSETTYPE - ISPOINTER): IF Error_Happened THEN GOTO errmes bytes$ = e$ IF ne = 3 THEN 'no AS e$ = fixoperationorder$(var$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ test$ = evaluate(e$, t) IF (t AND ISREFERENCE) = 0 AND (t AND ISSTRING) THEN PRINT #12, "tmp_long=(ptrszint)" + test$ + ";" varsize$ = "((qbs*)tmp_long)->len" varoffs$ = "((qbs*)tmp_long)->chr" ELSE varsize$ = evaluatetotyp(e$, -5): IF Error_Happened THEN GOTO errmes varoffs$ = evaluatetotyp(e$, -6): IF Error_Happened THEN GOTO errmes END IF IF NoChecks THEN PRINT #12, "sub__memfill_nochecks(" + offs$ + "," + bytes$ + ",(ptrszint)" + varoffs$ + "," + varsize$ + ");" ELSE PRINT #12, "sub__memfill((mem_block*)" + blkoffs$ + "," + offs$ + "," + bytes$ + ",(ptrszint)" + varoffs$ + "," + varsize$ + ");" END IF ELSE '... AS type method t = typname2typ(typ$) IF t = 0 THEN a$ = "Invalid type": GOTO errmes IF (t AND ISOFFSETINBITS) <> 0 OR (t AND ISUDT) <> 0 OR (t AND ISSTRING) THEN a$ = "_MEMFILL requires numeric type": GOTO errmes IF (t AND ISPOINTER) THEN t = t - ISPOINTER 'attempt conversion... e$ = fixoperationorder$(var$): IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ + sp + "AS" + sp + typ$ e$ = evaluatetotyp(e$, t): IF Error_Happened THEN GOTO errmes c$ = "sub__memfill_" IF NoChecks THEN c$ = "sub__memfill_nochecks_" IF t AND ISOFFSET THEN c$ = c$ + "OFFSET" ELSE IF t AND ISFLOAT THEN IF (t AND 511) = 32 THEN c$ = c$ + "SINGLE" IF (t AND 511) = 64 THEN c$ = c$ + "DOUBLE" IF (t AND 511) = 256 THEN c$ = c$ + "FLOAT" 'padded variable ELSE c$ = c$ + str2((t AND 511) \ 8) END IF END IF c$ = c$ + "(" IF NoChecks = 0 THEN c$ = c$ + "(mem_block*)" + blkoffs$ + "," PRINT #12, c$ + offs$ + "," + bytes$ + "," + e$ + ");" END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF 'note: ABSOLUTE cannot be used without CALL cispecial = 0 IF n > 1 THEN IF firstelement$ = "INTERRUPT" OR firstelement$ = "INTERRUPTX" THEN a$ = "CALL" + sp + firstelement$ + sp + "(" + sp + getelements$(a$, 2, n) + sp + ")" ca$ = "CALL" + sp + firstelement$ + sp + "(" + sp + getelements$(ca$, 2, n) + sp + ")" n = n + 3 firstelement$ = "CALL" cispecial = 1 'fall through END IF END IF usecall = 0 IF firstelement$ = "CALL" THEN usecall = 1 IF n = 1 THEN a$ = "Expected CALL sub-name [(...)]": GOTO errmes cn$ = getelement$(ca$, 2): n$ = UCASE$(cn$) IF n > 2 THEN IF n <= 4 THEN a$ = "Expected CALL sub-name (...)": GOTO errmes IF getelement$(a$, 3) <> "(" OR getelement$(a$, n) <> ")" THEN a$ = "Expected CALL sub-name (...)": GOTO errmes a$ = n$ + sp + getelements$(a$, 4, n - 1) ca$ = cn$ + sp + getelements$(ca$, 4, n - 1) IF n$ = "INTERRUPT" OR n$ = "INTERRUPTX" THEN 'assume CALL INTERRUPT[X] request 'print "CI: call interrupt command reached":sleep 1 IF n$ = "INTERRUPT" THEN PRINT #12, "call_interrupt("; ELSE PRINT #12, "call_interruptx("; argn = 0 n = numelements(a$) B = 0 e$ = "" FOR i = 2 TO n e2$ = getelement$(ca$, i) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF (e2$ = "," AND B = 0) OR i = n THEN IF i = n THEN IF e$ = "" THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ END IF argn = argn + 1 IF argn = 1 THEN 'interrupt number e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = "CALL" + sp + n$ + sp2 + "(" + sp2 + tlayout$ IF cispecial = 1 THEN l$ = n$ + sp + tlayout$ e$ = evaluatetotyp(e$, 64&) IF Error_Happened THEN GOTO errmes 'print "CI: evaluated interrupt number as ["+e$+"]":sleep 1 PRINT #12, e$; END IF IF argn = 2 OR argn = 3 THEN 'inregs, outregs e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ e2$ = e$ e$ = evaluatetotyp(e$, -2) 'offset+size IF Error_Happened THEN GOTO errmes 'print "CI: evaluated in/out regs ["+e2$+"] as ["+e$+"]":sleep 1 PRINT #12, "," + e$; END IF e$ = "" ELSE IF e$ = "" THEN e$ = e2$ ELSE e$ = e$ + sp + e2$ END IF NEXT IF argn <> 3 THEN a$ = "Expected CALL INTERRUPT (interrupt-no, inregs, outregs)": GOTO errmes PRINT #12, ");" IF cispecial = 0 THEN l$ = l$ + sp2 + ")" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ 'print "CI: done":sleep 1 GOTO finishedline END IF 'call interrupt 'call to CALL ABSOLUTE beyond reasonable doubt IF n$ = "ABSOLUTE" THEN l$ = "CALL" + sp + "ABSOLUTE" + sp2 + "(" + sp2 argn = 0 n = numelements(a$) B = 0 e$ = "" FOR i = 2 TO n e2$ = getelement$(ca$, i) IF e2$ = "(" THEN B = B + 1 IF e2$ = ")" THEN B = B - 1 IF (e2$ = "," AND B = 0) OR i = n THEN IF i < n THEN IF e$ = "" THEN a$ = "Expected expression before , or )": GOTO errmes '1. variable or value? e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ + sp2 + "," + sp ignore$ = evaluate(e$, typ) IF Error_Happened THEN GOTO errmes IF (typ AND ISPOINTER) <> 0 AND (typ AND ISREFERENCE) <> 0 THEN 'assume standard variable 'assume not string/array/udt/etc e$ = "VARPTR" + sp + "(" + sp + e$ + sp + ")" e$ = evaluatetotyp(e$, UINTEGERTYPE - ISPOINTER) IF Error_Happened THEN GOTO errmes ELSE 'assume not string 'single, double or integer64? IF typ AND ISFLOAT THEN IF (typ AND 511) = 32 THEN e$ = evaluatetotyp(e$, SINGLETYPE - ISPOINTER) IF Error_Happened THEN GOTO errmes v$ = "pass" + str2$(uniquenumber) PRINT #defdatahandle, "float *" + v$ + "=NULL;" PRINT #13, "if(" + v$ + "==NULL){" PRINT #13, "cmem_sp-=4;" PRINT #13, v$ + "=(float*)(dblock+cmem_sp);" PRINT #13, "if (cmem_sp2 a$ = n$ ca$ = cn$ usecall = 2 END IF 'n>2 n = numelements(a$) firstelement$ = getelement$(a$, 1) 'valid SUB name validsub = 0 findidsecondarg = "": IF n >= 2 THEN findidsecondarg = getelement$(a$, 2) try = findid(firstelement$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.subfunc = 2 THEN validsub = 1: EXIT DO IF try = 2 THEN findidsecondarg = "": IF n >= 2 THEN findidsecondarg = getelement$(a$, 2) findanotherid = 1 try = findid(firstelement$) IF Error_Happened THEN GOTO errmes ELSE try = 0 END IF LOOP IF validsub = 0 THEN a$ = "Expected CALL sub-name [(...)]": GOTO errmes END IF 'sub? IF n >= 1 THEN IF firstelement$ = "?" THEN firstelement$ = "PRINT" findidsecondarg = "": IF n >= 2 THEN findidsecondarg = getelement$(a$, 2) try = findid(firstelement$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.subfunc = 2 THEN 'check symbol s$ = removesymbol$(firstelement$ + "") IF Error_Happened THEN GOTO errmes IF ASC(id.musthave) = 36 THEN '="$" IF s$ <> "$" THEN GOTO notsubcall 'missing musthave "$" ELSE IF LEN(s$) THEN GOTO notsubcall 'unrequired symbol added END IF 'check for variable assignment IF n > 1 THEN IF ASC(id.specialformat) <> 61 THEN '<>"=" IF ASC(getelement$(a$, 2)) = 61 THEN GOTO notsubcall 'assignment, not sub call END IF END IF 'check for array assignment IF n > 2 THEN IF getelement$(a$, 2) = "(" THEN B = 1 FOR i = 3 TO n e$ = getelement$(a$, i) IF e$ = "(" THEN B = B + 1 IF e$ = ")" THEN B = B - 1 IF B = 0 THEN IF i = n THEN EXIT FOR IF getelement$(a$, i + 1) = "=" THEN GOTO notsubcall END IF END IF NEXT END IF END IF IF id.NoCloud THEN IF Cloud THEN a$ = "Feature not supported on QLOUD": GOTO errmes '***NOCLOUD*** END IF 'generate error on driect _GL call IF firstelement$ = "_GL" THEN a$ = "Cannot call SUB _GL directly": GOTO errmes IF firstelement$ = "OPEN" THEN 'gwbasic or qbasic version? B = 0 FOR x = 2 TO n a2$ = getelement$(a$, x) IF a2$ = "(" THEN B = B + 1 IF a2$ = ")" THEN B = B - 1 IF a2$ = "FOR" OR a2$ = "AS" THEN EXIT FOR 'qb style open verified IF B = 0 AND a2$ = "," THEN 'the gwbasic version includes a comma after the first string expression findanotherid = 1 try = findid(firstelement$) 'id of sub_open_gwbasic IF Error_Happened THEN GOTO errmes EXIT FOR END IF NEXT END IF 'IF findid(firstelement$) THEN 'IF id.subfunc = 2 THEN IF firstelement$ = "CLOSE" OR firstelement$ = "RESET" THEN IF firstelement$ = "RESET" THEN IF n > 1 THEN a$ = "Syntax error": GOTO errmes END IF l$ = firstelement$ IF n = 1 THEN PRINT #12, "sub_close(NULL,0);" 'closes all files ELSE l$ = l$ + sp B = 0 s = 0 a3$ = "" FOR x = 2 TO n a2$ = getelement$(ca$, x) IF a2$ = "(" THEN B = B + 1 IF a2$ = ")" THEN B = B - 1 IF a2$ = "#" AND B = 0 THEN IF s = 0 THEN s = 1 ELSE a$ = "Unexpected #": GOTO errmes l$ = l$ + "#" + sp2 GOTO closenexta END IF IF a2$ = "," AND B = 0 THEN IF s = 2 THEN e$ = fixoperationorder$(a3$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ + sp2 + "," + sp e$ = evaluatetotyp(e$, 64&) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_close(" + e$ + ",1);" a3$ = "" s = 0 GOTO closenexta ELSE a$ = "Expected expression before ,": GOTO errmes END IF END IF s = 2 IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ closenexta: NEXT IF s = 2 THEN e$ = fixoperationorder$(a3$) IF Error_Happened THEN GOTO errmes l$ = l$ + tlayout$ e$ = evaluatetotyp(e$, 64&) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_close(" + e$ + ",1);" ELSE l$ = LEFT$(l$, LEN(l$) - 1) END IF END IF layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF 'close 'data, restore, read IF firstelement$ = "READ" THEN 'file input xread ca$, n IF Error_Happened THEN GOTO errmes 'note: layout done in xread sub GOTO finishedline END IF 'read lineinput = 0 IF n >= 2 THEN IF firstelement$ = "LINE" AND secondelement$ = "INPUT" THEN lineinput = 1 a$ = RIGHT$(a$, LEN(a$) - 5): ca$ = RIGHT$(ca$, LEN(ca$) - 5): n = n - 1 'remove "LINE" firstelement$ = "INPUT" END IF END IF IF firstelement$ = "INPUT" THEN 'file input IF n > 1 THEN IF getelement$(a$, 2) = "#" THEN l$ = "INPUT" + sp + "#": IF lineinput THEN l$ = "LINE" + sp + l$ u$ = str2$(uniquenumber) 'which file? IF n = 2 THEN a$ = "Expected # ... , ...": GOTO errmes a3$ = "" B = 0 FOR i = 3 TO n a2$ = getelement$(ca$, i) IF a2$ = "(" THEN B = B + 1 IF a2$ = ")" THEN B = B - 1 IF a2$ = "," AND B = 0 THEN IF a3$ = "" THEN a$ = "Expected # ... , ...": GOTO errmes GOTO inputgotfn END IF IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ NEXT inputgotfn: e$ = fixoperationorder$(a3$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + tlayout$ e$ = evaluatetotyp(e$, 64&) IF Error_Happened THEN GOTO errmes PRINT #12, "tmp_fileno=" + e$ + ";" PRINT #12, "if (new_error) goto skip" + u$ + ";" i = i + 1 IF i > n THEN a$ = "Expected , ...": GOTO errmes a3$ = "" B = 0 FOR i = i TO n a2$ = getelement$(ca$, i) IF a2$ = "(" THEN B = B + 1 IF a2$ = ")" THEN B = B - 1 IF i = n THEN IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ a2$ = ",": B = 0 END IF IF a2$ = "," AND B = 0 THEN IF a3$ = "" THEN a$ = "Expected , ...": GOTO errmes e$ = fixoperationorder$(a3$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp2 + "," + sp + tlayout$ e$ = evaluate(e$, t) IF Error_Happened THEN GOTO errmes IF (t AND ISREFERENCE) = 0 THEN a$ = "Expected variable-name": GOTO errmes IF (t AND ISSTRING) THEN e$ = refer(e$, t, 0) IF Error_Happened THEN GOTO errmes IF lineinput THEN PRINT #12, "sub_file_line_input_string(tmp_fileno," + e$ + ");" PRINT #12, "if (new_error) goto skip" + u$ + ";" ELSE PRINT #12, "sub_file_input_string(tmp_fileno," + e$ + ");" PRINT #12, "if (new_error) goto skip" + u$ + ";" END IF stringprocessinghappened = 1 ELSE IF lineinput THEN a$ = "Expected string-variable": GOTO errmes 'numeric variable IF (t AND ISFLOAT) <> 0 OR (t AND 511) <> 64 THEN IF (t AND ISOFFSETINBITS) THEN setrefer e$, t, "((int64)func_file_input_float(tmp_fileno," + str2(t) + "))", 1 IF Error_Happened THEN GOTO errmes ELSE setrefer e$, t, "func_file_input_float(tmp_fileno," + str2(t) + ")", 1 IF Error_Happened THEN GOTO errmes END IF ELSE IF t AND ISUNSIGNED THEN setrefer e$, t, "func_file_input_uint64(tmp_fileno)", 1 IF Error_Happened THEN GOTO errmes ELSE setrefer e$, t, "func_file_input_int64(tmp_fileno)", 1 IF Error_Happened THEN GOTO errmes END IF END IF PRINT #12, "if (new_error) goto skip" + u$ + ";" END IF IF i = n THEN EXIT FOR IF lineinput THEN a$ = "Too many variables": GOTO errmes a3$ = "": a2$ = "" END IF IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ NEXT PRINT #12, "skip" + u$ + ":" PRINT #12, "revert_input_check();" IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF END IF END IF 'input# IF firstelement$ = "INPUT" THEN l$ = "INPUT": IF lineinput THEN l$ = "LINE" + sp + l$ commaneeded = 0 i = 2 newline = 1: IF getelement$(a$, i) = ";" THEN newline = 0: i = i + 1: l$ = l$ + sp + ";" a2$ = getelement$(ca$, i) IF LEFT$(a2$, 1) = CHR$(34) THEN e$ = fixoperationorder$(a2$): l$ = l$ + sp + tlayout$ IF Error_Happened THEN GOTO errmes PRINT #12, "qbs_print(qbs_new_txt_len(" + a2$ + "),0);" i = i + 1 'MUST be followed by a ; or , a2$ = getelement$(ca$, i) i = i + 1 l$ = l$ + sp2 + a2$ IF a2$ = ";" THEN IF lineinput THEN GOTO finishedpromptstring PRINT #12, "qbs_print(qbs_new_txt(" + CHR$(34) + "? " + CHR$(34) + "),0);" GOTO finishedpromptstring END IF IF a2$ = "," THEN GOTO finishedpromptstring END IF a$ = "INPUT STATEMENT: SYNTAX ERROR!": GOTO errmes END IF 'there was no promptstring, so print a ? IF lineinput = 0 THEN PRINT #12, "qbs_print(qbs_new_txt(" + CHR$(34) + "? " + CHR$(34) + "),0);" finishedpromptstring: numvar = 0 FOR i = i TO n IF commaneeded = 1 THEN a2$ = getelement$(ca$, i) IF a2$ <> "," THEN a$ = "INPUT STATEMENT: SYNTAX ERROR! (COMMA EXPECTED)": GOTO errmes ELSE B = 0 e$ = "" 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 i2 = i2 - 1: EXIT FOR e$ = e$ + sp + e2$ NEXT i = i2: IF i > n THEN i = n IF e$ = "" THEN a$ = "Expected variable": GOTO errmes e$ = RIGHT$(e$, LEN(e$) - 1) e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$: IF i <> n THEN l$ = l$ + sp2 + "," e$ = evaluate(e$, t) IF Error_Happened THEN GOTO errmes IF (t AND ISREFERENCE) = 0 THEN a$ = "Expected variable": GOTO errmes IF (t AND ISSTRING) THEN e$ = refer(e$, t, 0) IF Error_Happened THEN GOTO errmes numvar = numvar + 1 IF lineinput THEN PRINT #12, "qbs_input_variabletypes[" + str2(numvar) + "]=ISSTRING+512;" ELSE PRINT #12, "qbs_input_variabletypes[" + str2(numvar) + "]=ISSTRING;" END IF PRINT #12, "qbs_input_variableoffsets[" + str2(numvar) + "]=" + e$ + ";" GOTO gotinputvar END IF IF lineinput THEN a$ = "Expected string variable": GOTO errmes IF (t AND ISARRAY) THEN IF (t AND ISOFFSETINBITS) THEN a$ = "INPUT cannot handle BIT array elements yet": GOTO errmes END IF END IF e$ = "&(" + refer(e$, t, 0) + ")" IF Error_Happened THEN GOTO errmes 'remove assumed/unnecessary flags IF (t AND ISPOINTER) THEN t = t - ISPOINTER IF (t AND ISINCONVENTIONALMEMORY) THEN t = t - ISINCONVENTIONALMEMORY IF (t AND ISREFERENCE) THEN t = t - ISREFERENCE 'IF (t AND ISOFFSETINBITS) THEN 'numvar = numvar + 1 'consider storing the bit offset in unused bits of t 'PRINT #12, "qbs_input_variabletypes[" + str2(numvar) + "]=" + str2(t) + ";" 'PRINT #12, "qbs_input_variableoffsets[" + str2(numvar) + "]=" + refer(ref$, typ, 1) + ";" 'GOTO gotinputvar 'END IF 'assume it is a regular variable numvar = numvar + 1 PRINT #12, "qbs_input_variabletypes[" + str2(numvar) + "]=" + str2$(t) + ";" PRINT #12, "qbs_input_variableoffsets[" + str2(numvar) + "]=" + e$ + ";" GOTO gotinputvar END IF gotinputvar: commaneeded = commaneeded + 1: IF commaneeded = 2 THEN commaneeded = 0 NEXT IF numvar = 0 THEN a$ = "INPUT STATEMENT: SYNTAX ERROR! (NO VARIABLES LISTED FOR INPUT)": GOTO errmes IF lineinput = 1 AND numvar > 1 THEN a$ = "Too many variables": GOTO errmes PRINT #12, "qbs_input(" + str2(numvar) + "," + str2$(newline) + ");" PRINT #12, "if (stop_program) end();" PRINT #12, cleanupstringprocessingcall$ + "0);" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF IF firstelement$ = "WRITE" THEN 'file write IF n > 1 THEN IF getelement$(a$, 2) = "#" THEN xfilewrite ca$, n IF Error_Happened THEN GOTO errmes GOTO finishedline END IF '# END IF 'n>1 END IF '"write" IF firstelement$ = "WRITE" THEN 'write xwrite ca$, n IF Error_Happened THEN GOTO errmes GOTO finishedline END IF '"write" IF firstelement$ = "PRINT" THEN 'file print IF n > 1 THEN IF getelement$(a$, 2) = "#" THEN xfileprint a$, ca$, n IF Error_Happened THEN GOTO errmes l$ = tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF '# END IF 'n>1 END IF '"print" IF firstelement$ = "PRINT" OR firstelement$ = "LPRINT" THEN xprint a$, ca$, n IF Error_Happened THEN GOTO errmes l$ = tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF IF firstelement$ = "CLEAR" THEN IF subfunc$ <> "" THEN a$ = "CLEAR cannot be used inside a SUB/FUNCTION": GOTO errmes END IF 'LSET/RSET IF firstelement$ = "LSET" OR firstelement$ = "RSET" THEN IF n = 1 THEN a$ = "Expected " + firstelement$ + " ...": GOTO errmes l$ = firstelement$ dest$ = "" source$ = "" part = 1 i = 2 a3$ = "" B = 0 DO IF i > n THEN IF part <> 2 OR a3$ = "" THEN a$ = "Expected LSET/RSET stringvariable=string": GOTO errmes source$ = a3$ EXIT DO END IF a2$ = getelement$(ca$, i) IF a2$ = "(" THEN B = B + 1 IF a2$ = ")" THEN B = B - 1 IF a2$ = "=" AND B = 0 THEN IF part = 1 THEN dest$ = a3$: part = 2: a3$ = "": GOTO lrsetgotpart END IF IF LEN(a3$) THEN a3$ = a3$ + sp + a2$ ELSE a3$ = a2$ lrsetgotpart: i = i + 1 LOOP IF dest$ = "" THEN a$ = "Expected LSET/RSET stringvariable=string": GOTO errmes 'check if it is a valid source string f$ = fixoperationorder$(dest$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ + sp + "=" e$ = evaluate(f$, sourcetyp) IF Error_Happened THEN GOTO errmes IF (sourcetyp AND ISREFERENCE) = 0 OR (sourcetyp AND ISSTRING) = 0 THEN a$ = "LSET/RSET expects a string variable/array-element as its first argument": GOTO errmes dest$ = evaluatetotyp(f$, ISSTRING) IF Error_Happened THEN GOTO errmes source$ = fixoperationorder$(source$) IF Error_Happened THEN GOTO errmes l$ = l$ + sp + tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ source$ = evaluatetotyp(source$, ISSTRING) IF Error_Happened THEN GOTO errmes IF firstelement$ = "LSET" THEN PRINT #12, "sub_lset(" + dest$ + "," + source$ + ");" ELSE PRINT #12, "sub_rset(" + dest$ + "," + source$ + ");" END IF GOTO finishedline END IF 'SWAP IF firstelement$ = "SWAP" THEN IF n < 4 THEN a$ = "Expected SWAP ... , ...": GOTO errmes B = 0 ele = 1 e1$ = "" e2$ = "" FOR i = 2 TO n e$ = getelement$(ca$, i) IF e$ = "(" THEN B = B + 1 IF e$ = ")" THEN B = B - 1 IF e$ = "," AND B = 0 THEN IF ele = 2 THEN a$ = "Expected SWAP ... , ...": GOTO errmes ele = 2 ELSE IF ele = 1 THEN e1$ = e1$ + sp + e$ ELSE e2$ = e2$ + sp + e$ END IF NEXT IF e2$ = "" THEN a$ = "Expected SWAP ... , ...": GOTO errmes e1$ = RIGHT$(e1$, LEN(e1$) - 1): e2$ = RIGHT$(e2$, LEN(e2$) - 1) e1$ = fixoperationorder(e1$) IF Error_Happened THEN GOTO errmes e1l$ = tlayout$ e2$ = fixoperationorder(e2$) IF Error_Happened THEN GOTO errmes e2l$ = tlayout$ e1$ = evaluate(e1$, e1typ): e2$ = evaluate(e2$, e2typ) IF Error_Happened THEN GOTO errmes IF (e1typ AND ISREFERENCE) = 0 OR (e2typ AND ISREFERENCE) = 0 THEN a$ = "Expected variable": GOTO errmes layoutdone = 1 l$ = "SWAP" + sp + e1l$ + sp2 + "," + sp + e2l$ IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ 'swap strings? IF (e1typ AND ISSTRING) THEN IF (e2typ AND ISSTRING) = 0 THEN a$ = "Type mismatch": GOTO errmes e1$ = refer(e1$, e1typ, 0): e2$ = refer(e2$, e2typ, 0) IF Error_Happened THEN GOTO errmes PRINT #12, "swap_string(" + e1$ + "," + e2$ + ");" GOTO finishedline END IF 'swap UDT? 'note: entire UDTs, unlike thier elements cannot be swapped like standard variables ' as UDT sizes may vary, and to avoid a malloc operation, QB64 should allocate a buffer ' in global.txt for the purpose of swapping each UDT type IF e1typ AND ISUDT THEN a$ = e1$ 'retrieve ID i = INSTR(a$, sp3) IF i THEN idnumber = VAL(LEFT$(a$, i - 1)): a$ = RIGHT$(a$, LEN(a$) - i) getid idnumber IF Error_Happened THEN GOTO errmes u = VAL(a$) i = INSTR(a$, sp3): a$ = RIGHT$(a$, LEN(a$) - i): E = VAL(a$) i = INSTR(a$, sp3): o$ = RIGHT$(a$, LEN(a$) - i) n$ = "UDT_" + RTRIM$(id.n): IF id.t = 0 THEN n$ = "ARRAY_" + n$ + "[0]" IF E = 0 THEN 'not an element of UDT u lhsscope$ = scope$ e$ = e2$: t2 = e2typ IF (t2 AND ISUDT) = 0 THEN a$ = "Expected SWAP with similar user defined type": GOTO errmes idnumber2 = VAL(e$) getid idnumber2 IF Error_Happened THEN GOTO errmes n2$ = "UDT_" + RTRIM$(id.n): IF id.t = 0 THEN n2$ = "ARRAY_" + n2$ + "[0]" i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i): u2 = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i): e2 = VAL(e$) i = INSTR(e$, sp3): o2$ = RIGHT$(e$, LEN(e$) - i) 'WARNING: u2 may need minor modifications based on e to see if they are the same IF u <> u2 OR e2 <> 0 THEN a$ = "Expected SWAP with similar user defined type": GOTO errmes dst$ = "(((char*)" + lhsscope$ + n$ + ")+(" + o$ + "))" src$ = "(((char*)" + scope$ + n2$ + ")+(" + o2$ + "))" B = udtxsize(u) \ 8 siz$ = str2$(B) IF B = 1 THEN PRINT #12, "swap_8(" + src$ + "," + dst$ + ");" IF B = 2 THEN PRINT #12, "swap_16(" + src$ + "," + dst$ + ");" IF B = 4 THEN PRINT #12, "swap_32(" + src$ + "," + dst$ + ");" IF B = 8 THEN PRINT #12, "swap_64(" + src$ + "," + dst$ + ");" IF B <> 1 AND B <> 2 AND B <> 4 AND B <> 8 THEN PRINT #12, "swap_block(" + src$ + "," + dst$ + "," + siz$ + ");" GOTO finishedline END IF 'e=0 END IF 'i END IF 'isudt 'cull irrelavent flags to make comparison possible e1typc = e1typ IF e1typc AND ISPOINTER THEN e1typc = e1typc - ISPOINTER IF e1typc AND ISINCONVENTIONALMEMORY THEN e1typc = e1typc - ISINCONVENTIONALMEMORY IF e1typc AND ISARRAY THEN e1typc = e1typc - ISARRAY IF e1typc AND ISUNSIGNED THEN e1typc = e1typc - ISUNSIGNED IF e1typc AND ISUDT THEN e1typc = e1typc - ISUDT e2typc = e2typ IF e2typc AND ISPOINTER THEN e2typc = e2typc - ISPOINTER IF e2typc AND ISINCONVENTIONALMEMORY THEN e2typc = e2typc - ISINCONVENTIONALMEMORY IF e2typc AND ISARRAY THEN e2typc = e2typc - ISARRAY IF e2typc AND ISUNSIGNED THEN e2typc = e2typc - ISUNSIGNED IF e2typc AND ISUDT THEN e2typc = e2typc - ISUDT IF e1typc <> e2typc THEN a$ = "Type mismatch": GOTO errmes t = e1typ IF t AND ISOFFSETINBITS THEN a$ = "Cannot SWAP bit-length variables": GOTO errmes B = t AND 511 t$ = str2$(B): IF B > 64 THEN t$ = "longdouble" PRINT #12, "swap_" + t$ + "(&" + refer(e1$, e1typ, 0) + ",&" + refer(e2$, e2typ, 0) + ");" IF Error_Happened THEN GOTO errmes GOTO finishedline END IF IF firstelement$ = "OPTION" THEN IF n <> 3 THEN a$ = "Expected OPTION BASE 0 or 1": GOTO errmes IF getelement$(a$, 2) <> "BASE" THEN a$ = "Expected OPTION BASE 0 or 1": GOTO errmes l$ = getelement$(a$, 3) IF l$ <> "0" AND l$ <> "1" THEN a$ = "Expected OPTION BASE 0 or 1": GOTO errmes IF l$ = "1" THEN optionbase = 1 ELSE optionbase = 0 l$ = "OPTION" + sp + "BASE" + sp + l$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ GOTO finishedline END IF 'any other "unique" subs can be processed above id2 = id targetid = currentid IF RTRIM$(id2.callname) = "sub_stub" THEN a$ = "Command not implemented": GOTO errmes IF n > 1 THEN IF id2.args = 0 THEN a$ = "SUB does not require any arguments": GOTO errmes END IF SetDependency id2.Dependency seperateargs_error = 0 passedneeded = seperateargs(getelements(a$, 2, n), getelements(ca$, 2, n), passed&) IF seperateargs_error THEN a$ = seperateargs_error_message: GOTO errmes 'backup args to local string array space before calling evaluate FOR i = 1 TO OptMax: separgs2(i) = "": NEXT 'save space! FOR i = 1 TO OptMax + 1: separgslayout2(i) = "": NEXT FOR i = 1 TO id2.args: separgs2(i) = separgs(i): NEXT FOR i = 1 TO id2.args + 1: separgslayout2(i) = separgslayout(i): NEXT IF Debug THEN PRINT #9, "separgs:": FOR i = 1 TO id2.args: PRINT #9, i, separgs2(i): NEXT PRINT #9, "separgslayout:": FOR i = 1 TO id2.args + 1: PRINT #9, i, separgslayout2(i): NEXT END IF 'note: seperateargs finds the arguments to pass and sets passed& as necessary ' FIXOPERTIONORDER is not called on these args yet ' what we need it to do is build a second array of layout info at the same time ' ref:DIM SHARED separgslayout(100) AS STRING ' the above array stores what layout info (if any) goes BEFORE the arg in question ' it has one extra index which is the arg after IF usecall THEN IF usecall = 1 THEN l$ = "CALL" + sp + RTRIM$(id.cn) + RTRIM$(id.musthave) + sp2 + "(" + sp2 IF usecall = 2 THEN l$ = "CALL" + sp + RTRIM$(id.cn) + RTRIM$(id.musthave) + sp 'sp at end for easy parsing ELSE l$ = RTRIM$(id.cn) + RTRIM$(id.musthave) + sp END IF subcall$ = RTRIM$(id.callname) + "(" addedlayout = 0 fieldcall = 0 'GET/PUT field exception IF RTRIM$(id2.callname) = "sub_get" OR RTRIM$(id2.callname) = "sub_put" THEN IF passed AND 2 THEN 'regular GET/PUT call with variable provided passed = passed - 2 'for complience with existing methods, remove 'passed' flag for the passing of a variable ELSE 'FIELD GET/PUT call with variable omited IF RTRIM$(id2.callname) = "sub_get" THEN fieldcall = 1 subcall$ = "field_get(" ELSE fieldcall = 2 subcall$ = "field_put(" END IF END IF END IF 'field exception IF RTRIM$(id2.callname) = "sub_timer" OR RTRIM$(id2.callname) = "sub_key" THEN 'spacing exception IF usecall = 0 THEN l$ = LEFT$(l$, LEN(l$) - 1) + sp2 END IF END IF FOR i = 1 TO id2.args targettyp = CVL(MID$(id2.arg, -3 + i * 4, 4)) nele = ASC(MID$(id2.nele, i, 1)) nelereq = ASC(MID$(id2.nelereq, i, 1)) addlayout = 1 'omits option values in layout (eg. BINARY="2") convertspacing = 0 'if an 'equation' is next, it will be preceeded by a space x$ = separgslayout2$(i) DO WHILE LEN(x$) x = ASC(x$) IF x THEN convertspacing = 0 x2$ = MID$(x$, 2, x) x$ = RIGHT$(x$, LEN(x$) - x - 1) s = 0 an = 0 x3$ = RIGHT$(l$, 1) IF x3$ = sp THEN s = 1 IF x3$ = sp2 THEN s = 2 IF alphanumeric(ASC(RIGHT$(l$, 2))) THEN an = 1 ELSE IF alphanumeric(ASC(x3$)) THEN an = 1 END IF s1 = s IF alphanumeric(ASC(x2$)) THEN convertspacing = 1 IF x2$ = "LPRINT" THEN 'x2$="LPRINT" 'x$=CHR$(0) 'x3$=[sp] from WIDTH[sp] 'therefore... 's=1 'an=0 'convertspacing=1 'if debug=1 then 'print #9,"LPRINT:" 'print #9,s 'print #9,an 'print #9,l$ 'print #9,x2$ 'end if END IF IF (an = 1 OR addedlayout = 1) AND alphanumeric(ASC(x2$)) <> 0 THEN s = 1 'force space x2$ = x2$ + sp2 GOTO customlaychar END IF IF x2$ = "=" THEN s = 1 x2$ = x2$ + sp GOTO customlaychar END IF IF x2$ = "#" THEN s = 1 x2$ = x2$ + sp2 GOTO customlaychar END IF IF x2$ = "," THEN x2$ = x2$ + sp: GOTO customlaychar IF x$ = CHR$(0) THEN 'substitution IF x2$ = "STEP" THEN x2$ = x2$ + sp2: GOTO customlaychar x2$ = x2$ + sp: GOTO customlaychar END IF 'default solution sp2+?+sp2 x2$ = x2$ + sp2 customlaychar: IF s = 0 THEN s = 2 IF s <> s1 THEN IF s1 THEN l$ = LEFT$(l$, LEN(l$) - 1) IF s = 1 THEN l$ = l$ + sp IF s = 2 THEN l$ = l$ + sp2 END IF IF (RTRIM$(id2.callname) = "sub_timer" OR RTRIM$(id2.callname) = "sub_key") AND i = id2.args THEN 'spacing exception IF x2$ <> ")" + sp2 THEN l$ = LEFT$(l$, LEN(l$) - 1) + sp END IF END IF l$ = l$ + x2$ ELSE addlayout = 0 x$ = RIGHT$(x$, LEN(x$) - 1) END IF addedlayout = 0 LOOP '---better sub syntax checking begins here--- IF targettyp = -3 THEN IF separgs2(i) = "NULL" THEN a$ = "Expected array name": GOTO errmes 'names of numeric arrays have ( ) automatically appended (nothing else) e$ = separgs2(i) IF INSTR(e$, sp) = 0 THEN 'one element only try_string$ = e$ try = findid(try_string$) IF Error_Happened THEN GOTO errmes DO IF try THEN IF id.arraytype THEN IF (id.arraytype AND ISSTRING) = 0 THEN e$ = e$ + sp + "(" + sp + ")" EXIT DO END IF END IF '--- IF try = 2 THEN findanotherid = 1: try = findid(try_string$) ELSE try = 0 IF Error_Happened THEN GOTO errmes END IF 'if try IF try = 0 THEN 'add symbol? IF LEN(removesymbol$(try_string$)) = 0 THEN IF Error_Happened THEN GOTO errmes a = ASC(try_string$) IF a >= 97 AND a <= 122 THEN a = a - 32 IF a = 95 THEN a = 91 a = a - 64 IF LEN(defineextaz(a)) THEN try_string$ = try_string$ + defineextaz(a): try = findid(try_string$) IF Error_Happened THEN GOTO errmes END IF END IF 'try=0 LOOP UNTIL try = 0 END IF 'one element only e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes IF convertspacing = 1 AND addlayout = 1 THEN l$ = LEFT$(l$, LEN(l$) - 1) + sp IF addlayout THEN l$ = l$ + tlayout$: addedlayout = 1 e$ = evaluatetotyp(e$, -2) IF Error_Happened THEN GOTO errmes GOTO sete END IF '-3 IF targettyp = -2 THEN e$ = fixoperationorder$(e$) IF Error_Happened THEN GOTO errmes IF convertspacing = 1 AND addlayout = 1 THEN l$ = LEFT$(l$, LEN(l$) - 1) + sp IF addlayout THEN l$ = l$ + tlayout$: addedlayout = 1 e$ = evaluatetotyp(e$, -2) IF Error_Happened THEN GOTO errmes GOTO sete END IF '-2 IF targettyp = -4 THEN IF fieldcall THEN i = id2.args + 1 EXIT FOR END IF IF separgs2(i) = "NULL" THEN a$ = "Expected variable name/array element": GOTO errmes e$ = fixoperationorder$(separgs2(i)) IF Error_Happened THEN GOTO errmes IF convertspacing = 1 AND addlayout = 1 THEN l$ = LEFT$(l$, LEN(l$) - 1) + sp IF addlayout THEN l$ = l$ + tlayout$: addedlayout = 1 'GET/PUT RANDOM-ACCESS override IF firstelement$ = "GET" OR firstelement$ = "PUT" THEN e2$ = e$ 'backup e$ = evaluate(e$, sourcetyp) IF Error_Happened THEN GOTO errmes IF (sourcetyp AND ISSTRING) THEN IF (sourcetyp AND ISFIXEDLENGTH) = 0 THEN 'replace name of sub to call subcall$ = RIGHT$(subcall$, LEN(subcall$) - 7) 'delete original name 'note: GET2 & PUT2 take differing input, following code is correct IF firstelement$ = "GET" THEN subcall$ = "sub_get2" + subcall$ e$ = refer(e$, sourcetyp, 0) 'pass a qbs pointer instead IF Error_Happened THEN GOTO errmes GOTO sete ELSE subcall$ = "sub_put2" + subcall$ 'no goto sete required, fall through END IF END IF END IF e$ = e2$ 'restore END IF 'override e$ = evaluatetotyp(e$, -4) IF Error_Happened THEN GOTO errmes GOTO sete END IF '-4 IF separgs2(i) = "NULL" THEN e$ = "NULL" ELSE e2$ = fixoperationorder$(separgs2(i)) IF Error_Happened THEN GOTO errmes IF convertspacing = 1 AND addlayout = 1 THEN l$ = LEFT$(l$, LEN(l$) - 1) + sp IF addlayout THEN l$ = l$ + tlayout$: addedlayout = 1 e$ = evaluate(e2$, sourcetyp) IF Error_Happened THEN GOTO errmes IF sourcetyp AND ISOFFSET THEN IF (targettyp AND ISOFFSET) = 0 THEN IF id2.internal_subfunc = 0 THEN a$ = "Cannot convert _OFFSET type to other types": GOTO errmes END IF END IF IF RTRIM$(id2.callname) = "sub_paint" THEN IF i = 3 THEN IF (sourcetyp AND ISSTRING) THEN targettyp = ISSTRING END IF END IF END IF IF LEFT$(separgs2(i), 2) = "(" + sp THEN dereference = 1 ELSE dereference = 0 'pass by reference IF (targettyp AND ISPOINTER) THEN IF dereference = 0 THEN 'check deferencing wasn't used 'note: array pointer IF (targettyp AND ISARRAY) THEN IF (sourcetyp AND ISREFERENCE) = 0 THEN a$ = "Expected arrayname()": GOTO errmes IF (sourcetyp AND ISARRAY) = 0 THEN a$ = "Expected arrayname()": GOTO errmes IF Debug THEN PRINT #9, "sub:array reference:[" + e$ + "]" 'check arrays are of same type targettyp2 = targettyp: sourcetyp2 = sourcetyp targettyp2 = targettyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISSTRING + ISFIXEDLENGTH + ISFLOAT) sourcetyp2 = sourcetyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISSTRING + ISFIXEDLENGTH + ISFLOAT) IF sourcetyp2 <> targettyp2 THEN a$ = "Incorrect array type passed to sub": GOTO errmes 'check arrayname was followed by '()' IF targettyp AND ISUDT THEN IF Debug THEN PRINT #9, "sub:array reference:udt reference:[" + e$ + "]" 'get UDT info udtrefid = VAL(e$) getid udtrefid IF Error_Happened THEN GOTO errmes udtrefi = INSTR(e$, sp3) 'end of id udtrefi2 = INSTR(udtrefi + 1, e$, sp3) 'end of u udtrefu = VAL(MID$(e$, udtrefi + 1, udtrefi2 - udtrefi - 1)) udtrefi3 = INSTR(udtrefi2 + 1, e$, sp3) 'skip e udtrefe = VAL(MID$(e$, udtrefi2 + 1, udtrefi3 - udtrefi2 - 1)) o$ = RIGHT$(e$, LEN(e$) - udtrefi3) 'note: most of the UDT info above is not required IF LEFT$(o$, 4) <> "(0)*" THEN a$ = "Expected arrayname()": GOTO errmes ELSE IF RIGHT$(e$, 2) <> sp3 + "0" THEN a$ = "Expected arrayname()": GOTO errmes END IF idnum = VAL(LEFT$(e$, INSTR(e$, sp3) - 1)) getid idnum IF Error_Happened THEN GOTO errmes IF targettyp AND ISFIXEDLENGTH THEN targettypsize = CVL(MID$(id2.argsize, i * 4 - 4 + 1, 4)) IF id.tsize <> targettypsize THEN a$ = "Incorrect array type passed to sub": GOTO errmes END IF IF MID$(sfcmemargs(targetid), i, 1) = CHR$(1) THEN 'cmem required? IF cmemlist(idnum) = 0 THEN cmemlist(idnum) = 1 recompile = 1 END IF END IF IF id.linkid = 0 THEN 'if id.linkid is 0, it means the number of array elements is definietly 'known of the array being passed, this is not some "fake"/unknown array. 'using the numer of array elements of a fake array would be dangerous! IF nelereq = 0 THEN 'only continue if the number of array elements required is unknown 'and it needs to be set IF id.arrayelements > 0 THEN '2009 nelereq = id.arrayelements MID$(id2.nelereq, i, 1) = CHR$(nelereq) END IF 'print rtrim$(id2.n)+">nelereq=";nelereq ids(targetid) = id2 ELSE 'the number of array elements required is known AND 'the number of elements in the array to be passed is known IF id.arrayelements <> nelereq THEN a$ = "Passing arrays with a differing number of elements to a SUB/FUNCTION is not supported (yet)": GOTO errmes END IF END IF e$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN GOTO errmes GOTO sete END IF 'target is an array 'note: not an array... 'target is not an array IF (targettyp AND ISSTRING) = 0 THEN IF (sourcetyp AND ISREFERENCE) THEN idnum = VAL(LEFT$(e$, INSTR(e$, sp3) - 1)) 'id# of sourcetyp targettyp2 = targettyp: sourcetyp2 = sourcetyp 'get info about source/target arr = 0: IF (sourcetyp2 AND ISARRAY) THEN arr = 1 passudtelement = 0: IF (targettyp2 AND ISUDT) = 0 AND (sourcetyp2 AND ISUDT) <> 0 THEN passudtelement = 1: sourcetyp2 = sourcetyp2 - ISUDT 'remove flags irrelevant for comparison... ISPOINTER,ISREFERENCE,ISINCONVENTIONALMEMORY,ISARRAY targettyp2 = targettyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISFLOAT + ISSTRING) sourcetyp2 = sourcetyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISFLOAT + ISSTRING) 'compare types IF sourcetyp2 = targettyp2 THEN IF sourcetyp AND ISUDT THEN 'udt/udt array 'get info udtrefid = VAL(e$) getid udtrefid IF Error_Happened THEN GOTO errmes udtrefi = INSTR(e$, sp3) 'end of id udtrefi2 = INSTR(udtrefi + 1, e$, sp3) 'end of u udtrefu = VAL(MID$(e$, udtrefi + 1, udtrefi2 - udtrefi - 1)) udtrefi3 = INSTR(udtrefi2 + 1, e$, sp3) 'skip e udtrefe = VAL(MID$(e$, udtrefi2 + 1, udtrefi3 - udtrefi2 - 1)) o$ = RIGHT$(e$, LEN(e$) - udtrefi3) 'note: most of the UDT info above is not required IF arr THEN n$ = scope$ + "ARRAY_UDT_" + RTRIM$(id.n) + "[0]" ELSE n$ = scope$ + "UDT_" + RTRIM$(id.n) END IF e$ = "(void*)( ((char*)(" + n$ + ")) + (" + o$ + ") )" 'convert void* to target type* IF passudtelement THEN e$ = "(" + typ2ctyp$(targettyp2 + (targettyp AND ISUNSIGNED), "") + "*)" + e$ IF Error_Happened THEN GOTO errmes ELSE 'not a udt IF arr THEN IF (sourcetyp2 AND ISOFFSETINBITS) THEN a$ = "Cannot pass BIT array offsets yet": GOTO errmes e$ = "(&(" + refer(e$, sourcetyp, 0) + "))" IF Error_Happened THEN GOTO errmes ELSE e$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN GOTO errmes END IF 'note: signed/unsigned mismatch requires casting IF (sourcetyp AND ISUNSIGNED) <> (targettyp AND ISUNSIGNED) THEN e$ = "(" + typ2ctyp$(targettyp2 + (targettyp AND ISUNSIGNED), "") + "*)" + e$ IF Error_Happened THEN GOTO errmes END IF END IF 'udt? IF MID$(sfcmemargs(targetid), i, 1) = CHR$(1) THEN 'cmem required? IF cmemlist(idnum) = 0 THEN cmemlist(idnum) = 1 recompile = 1 END IF END IF GOTO sete END IF 'similar END IF 'reference ELSE 'not a string 'its a string IF (sourcetyp AND ISREFERENCE) THEN idnum = VAL(LEFT$(e$, INSTR(e$, sp3) - 1)) 'id# of sourcetyp IF MID$(sfcmemargs(targetid), i, 1) = CHR$(1) THEN 'cmem required? IF cmemlist(idnum) = 0 THEN cmemlist(idnum) = 1 recompile = 1 END IF END IF END IF 'reference END IF 'its a string END IF 'dereference check END IF 'target is a pointer 'note: Target is not a pointer... 'String-numeric mismatch? IF targettyp AND ISSTRING THEN IF (sourcetyp AND ISSTRING) = 0 THEN nth = i IF ids(targetid).args = 1 THEN a$ = "String required for sub": GOTO errmes a$ = str_nth$(nth) + " sub argument requires a string": GOTO errmes END IF END IF IF (targettyp AND ISSTRING) = 0 THEN IF sourcetyp AND ISSTRING THEN nth = i IF ids(targetid).args = 1 THEN a$ = "Number required for sub": GOTO errmes a$ = str_nth$(nth) + " sub argument requires a number": GOTO errmes END IF END IF 'change to "non-pointer" value IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN GOTO errmes END IF IF explicitreference = 0 THEN IF targettyp AND ISUDT THEN nth = i x$ = "'" + RTRIM$(udtxcname(targettyp AND 511)) + "'" IF ids(targetid).args = 1 THEN a$ = "TYPE " + x$ + " required for sub": GOTO errmes a$ = str_nth$(nth) + " sub argument requires TYPE " + x$: GOTO errmes END IF ELSE IF sourcetyp AND ISUDT THEN a$ = "Number required for sub": GOTO errmes END IF 'round to integer if required IF (sourcetyp AND ISFLOAT) THEN IF (targettyp AND ISFLOAT) = 0 THEN '**32 rounding fix bits = targettyp AND 511 IF bits <= 16 THEN e$ = "qbr_float_to_long(" + e$ + ")" IF bits > 16 AND bits < 32 THEN e$ = "qbr_double_to_long(" + e$ + ")" IF bits >= 32 THEN e$ = "qbr(" + e$ + ")" END IF END IF IF (targettyp AND ISPOINTER) THEN 'pointer required IF (targettyp AND ISSTRING) THEN GOTO sete 'no changes required t$ = typ2ctyp$(targettyp, "") IF Error_Happened THEN GOTO errmes v$ = "pass" + str2$(uniquenumber) 'assume numeric type IF MID$(sfcmemargs(targetid), i, 1) = CHR$(1) THEN 'cmem required? bytesreq = ((targettyp AND 511) + 7) \ 8 PRINT #defdatahandle, t$ + " *" + v$ + "=NULL;" PRINT #13, "if(" + v$ + "==NULL){" PRINT #13, "cmem_sp-=" + str2(bytesreq) + ";" PRINT #13, v$ + "=(" + t$ + "*)(dblock+cmem_sp);" PRINT #13, "if (cmem_spchr" END IF IF LTRIM$(RTRIM$(e$)) = "0" THEN e$ = "NULL" END IF IF i <> 1 THEN subcall$ = subcall$ + "," subcall$ = subcall$ + e$ NEXT 'note: i=id.args+1 x$ = separgslayout2$(i) DO WHILE LEN(x$) x = ASC(x$) IF x THEN x2$ = MID$(x$, 2, x) x$ = RIGHT$(x$, LEN(x$) - x - 1) s = 0 an = 0 x3$ = RIGHT$(l$, 1) IF x3$ = sp THEN s = 1 IF x3$ = sp2 THEN s = 2 IF alphanumeric(ASC(RIGHT$(l$, 2))) THEN an = 1 'if asc(right$(l$,2))=34 then an=1 ELSE IF alphanumeric(ASC(x3$)) THEN an = 1 'if asc(x3$)=34 then an=1 END IF s1 = s IF (an = 1 OR addedlayout = 1) AND alphanumeric(ASC(x2$)) <> 0 THEN s = 1 'force space x2$ = x2$ + sp2 GOTO customlaychar2 END IF IF x2$ = "=" THEN s = 1 x2$ = x2$ + sp GOTO customlaychar2 END IF IF x2$ = "#" THEN s = 1 x2$ = x2$ + sp2 GOTO customlaychar2 END IF IF x2$ = "," THEN x2$ = x2$ + sp: GOTO customlaychar2 IF x$ = CHR$(0) THEN 'substitution IF x2$ = "STEP" THEN x2$ = x2$ + sp2: GOTO customlaychar2 x2$ = x2$ + sp: GOTO customlaychar2 END IF 'default solution sp2+?+sp2 x2$ = x2$ + sp2 customlaychar2: IF s = 0 THEN s = 2 IF s <> s1 THEN IF s1 THEN l$ = LEFT$(l$, LEN(l$) - 1) IF s = 1 THEN l$ = l$ + sp IF s = 2 THEN l$ = l$ + sp2 END IF l$ = l$ + x2$ ELSE addlayout = 0 x$ = RIGHT$(x$, LEN(x$) - 1) END IF addedlayout = 0 LOOP IF passedneeded THEN subcall$ = subcall$ + "," + str2$(passed&) END IF subcall$ = subcall$ + ");" PRINT #12, subcall$ subcall$ = "" IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);" layoutdone = 1 x$ = RIGHT$(l$, 1): IF x$ = sp OR x$ = sp2 THEN l$ = LEFT$(l$, LEN(l$) - 1) IF usecall = 1 THEN l$ = l$ + sp2 + ")" IF Debug THEN PRINT #9, "SUB layout:[" + l$ + "]" IF LEN(layout$) = 0 THEN layout$ = l$ ELSE layout$ = layout$ + sp + l$ GOTO finishedline END IF IF try = 2 THEN findidsecondarg = "": IF n >= 2 THEN findidsecondarg = getelement$(a$, 2) findanotherid = 1 try = findid(firstelement$) IF Error_Happened THEN GOTO errmes ELSE try = 0 END IF LOOP END IF notsubcall: IF n >= 1 THEN IF firstelement$ = "LET" THEN IF n = 1 THEN a$ = "Syntax error": GOTO errmes ca$ = RIGHT$(ca$, LEN(ca$) - 4) n = n - 1 l$ = "LET" IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ 'note: layoutdone=1 will be set later GOTO letused END IF END IF 'LET ???=??? IF n >= 3 THEN IF INSTR(a$, sp + "=" + sp) THEN letused: assign ca$, n IF Error_Happened THEN GOTO errmes layoutdone = 1 IF LEN(layout$) = 0 THEN layout$ = tlayout$ ELSE layout$ = layout$ + sp + tlayout$ GOTO finishedline END IF END IF '>=3 IF RIGHT$(a$, 2) = sp + "=" THEN a$ = "Expected ... = expression": GOTO errmes 'Syntax error a$ = "Syntax error": GOTO errmes finishedline: THENGOTO = 0 finishedline2: IF arrayprocessinghappened = 1 THEN arrayprocessinghappened = 0 IF NoChecks = 0 THEN IF dynscope THEN dynscope = 0 PRINT #12, "if(qbevent){evnt(" + str2$(linenumber) + ");if(r)goto S_" + str2$(statementn) + ";}" ELSE PRINT #12, "if(!qbevent)break;evnt(" + str2$(linenumber) + ");}while(r);" END IF END IF finishednonexec: IF layoutdone = 0 THEN layoutok = 0 'invalidate layout if not handled IF continuelinefrom = 0 THEN 'note: manager #2 requires this condition 'Include Manager #2 '*** IF LEN(addmetainclude$) THEN IF inclevel = 0 THEN 'backup line formatting layoutcomment_backup$ = layoutcomment$ layoutok_backup = layoutok layout_backup$ = layout$ END IF a$ = addmetainclude$: addmetainclude$ = "" 'read/clear message IF inclevel = 100 THEN a$ = "Too many indwelling INCLUDE files": GOTO errmes '1. Verify file exists (location is either (a)relative to source file or (b)absolute) fh = 99 + inclevel + 1 FOR try = 1 TO 2 IF try = 1 THEN IF inclevel = 0 THEN IF idemode THEN p$ = idepath$ + pathsep$ ELSE p$ = getfilepath$(sourcefile$) ELSE p$ = getfilepath$(incname(inclevel)) END IF f$ = p$ + a$ END IF IF try = 2 THEN f$ = a$ IF _FILEEXISTS(f$) THEN qberrorhappened = -2 '*** OPEN f$ FOR INPUT AS #fh qberrorhappened2: '*** IF qberrorhappened = -2 THEN EXIT FOR '*** END IF qberrorhappened = 0 NEXT IF qberrorhappened <> -2 THEN qberrorhappened = 0: a$ = "File " + a$ + " not found": GOTO errmes inclevel = inclevel + 1: incname$(inclevel) = f$: inclinenumber(inclevel) = 0 END IF 'fall through to next section... '-------------------- DO WHILE inclevel fh = 99 + inclevel '2. Feed next line IF EOF(fh) = 0 THEN LINE INPUT #fh, x$ a3$ = x$ continuelinefrom = 0 inclinenumber(inclevel) = inclinenumber(inclevel) + 1 'create extended error string 'incerror$' e$ = " in line " + str2(inclinenumber(inclevel)) + " of " + incname$(inclevel) + " included" IF inclevel > 1 THEN e$ = e$ + " (through " FOR x = 1 TO inclevel - 1 STEP 1 e$ = e$ + incname$(x) IF x < inclevel - 1 THEN 'a sep is req IF x = inclevel - 2 THEN e$ = e$ + " then " ELSE e$ = e$ + ", " END IF END IF NEXT e$ = e$ + ")" END IF incerror$ = e$ linenumber = linenumber - 1 'lower official linenumber to counter later increment IF idemode THEN sendc$ = CHR$(10) + a3$: GOTO sendcommand 'passback GOTO includeline END IF '3. Close & return control CLOSE #fh inclevel = inclevel - 1 IF inclevel = 0 THEN 'restore line formatting layoutok = layoutok_backup layout$ = layout_backup$ layoutcomment$ = layoutcomment_backup$ END IF LOOP 'fall through to next section... '(end manager) END IF 'continuelinefrom=0 IF Debug THEN PRINT #9, "[layout check]" PRINT #9, "[" + layoutoriginal$ + "]" PRINT #9, "[" + layout$ + "]" PRINT #9, layoutok PRINT #9, "[end layout check]" END IF IF idemode THEN IF continuelinefrom <> 0 THEN GOTO ide4 'continue processing other commands on line IF LEN(layoutcomment$) THEN IF LEN(layout$) THEN layout$ = layout$ + sp + layoutcomment$ ELSE layout$ = layoutcomment$ END IF IF layoutok = 0 THEN layout$ = layoutoriginal$ ELSE 'reverse '046' changes present in autolayout 'replace fix046$ with . i = INSTR(layout$, fix046$) DO WHILE i layout$ = LEFT$(layout$, i - 1) + "." + RIGHT$(layout$, LEN(layout$) - (i + LEN(fix046$) - 1)) i = INSTR(layout$, fix046$) LOOP END IF x = lhscontrollevel: IF controllevel < lhscontrollevel THEN x = controllevel IF definingtype = 2 THEN x = x + 1 IF declaringlibrary = 2 THEN x = x + 1 layout$ = SPACE$(x) + layout$ IF linecontinuation THEN layout$ = "" GOTO ideret4 'return control to IDE END IF 'layout is not currently used by the compiler (as appose to the IDE), if it was it would be used here LOOP ide5: linenumber = 0 IF closedmain = 0 THEN closemain IF definingtype THEN linenumber = definingtypeerror: a$ = "TYPE without END TYPE": GOTO errmes 'check for open controls (copy #1) IF controllevel THEN x = controltype(controllevel) IF x = 1 THEN a$ = "IF without END IF" IF x = 2 THEN a$ = "FOR without NEXT" IF x = 3 OR x = 4 THEN a$ = "DO without LOOP" IF x = 5 THEN a$ = "WHILE without WEND" IF (x >= 10 AND x <= 17) OR x = 18 OR x = 19 THEN a$ = "SELECT CASE without END SELECT" linenumber = controlref(controllevel) GOTO errmes END IF IF LEN(subfunc) THEN a$ = "SUB/FUNCTION without END SUB/FUNCTION": GOTO errmes 'close the error handler (cannot be put in 'closemain' because subs/functions can also add error jumps to this file) PRINT #14, "exit(99);" 'in theory this line should never be run! PRINT #14, "}" 'close error jump handler 'create CLEAR method "CLEAR" CLOSE #12 'close code handle OPEN tmpdir$ + "clear.txt" FOR OUTPUT AS #12 'direct code to clear.txt FOR i = 1 TO idn IF ids(i).staticscope THEN 'static scope? subfunc = RTRIM$(ids(i).insubfunc) 'set static scope GOTO clearstaticscope END IF a = ASC(ids(i).insubfunc) IF a = 0 OR a = 32 THEN 'global scope? subfunc = "" 'set global scope clearstaticscope: IF ids(i).arraytype THEN 'an array getid i IF Error_Happened THEN GOTO errmes IF id.arrayelements = -1 THEN GOTO clearerasereturned 'cannot erase non-existant array clearerasereturn = 1: GOTO clearerase END IF 'array IF ids(i).t THEN 'non-array variable getid i IF Error_Happened THEN GOTO errmes bytes$ = variablesize$(-1) IF Error_Happened THEN GOTO errmes 'create a reference typ = id.t + ISREFERENCE IF typ AND ISUDT THEN e$ = str2(i) + sp3 + str2(typ AND 511) + sp3 + "0" + sp3 + "0" ELSE e$ = str2(i) END IF e$ = refer$(e$, typ, 1) IF Error_Happened THEN GOTO errmes IF typ AND ISSTRING THEN IF typ AND ISFIXEDLENGTH THEN PRINT #12, "memset((void*)(" + e$ + "->chr),0," + bytes$ + ");" GOTO cleared ELSE PRINT #12, e$ + "->len=0;" GOTO cleared END IF END IF IF typ AND ISUDT THEN PRINT #12, "memset((void*)" + e$ + ",0," + bytes$ + ");" ELSE PRINT #12, "*" + e$ + "=0;" END IF GOTO cleared END IF 'non-array variable END IF 'scope cleared: clearerasereturned: NEXT CLOSE #12 IF Debug THEN PRINT #9, "finished making program!" PRINT #9, "recompile="; recompile END IF 'Set cmem flags for subs/functions requiring data passed in cmem FOR i = 1 TO idn IF cmemlist(i) THEN 'must be in cmem getid i IF Error_Happened THEN GOTO errmes IF Debug THEN PRINT #9, "recompiling cmem sf! checking:"; RTRIM$(id.n) IF id.sfid THEN 'it is an argument of a sub/function IF Debug THEN PRINT #9, "recompiling cmem sf! It's a sub/func arg!" i2 = id.sfid x = id.sfarg IF Debug THEN PRINT #9, "recompiling cmem sf! values:"; i2; x 'check if cmem flag is set, if not then set it & force recompile IF MID$(sfcmemargs(i2), x, 1) <> CHR$(1) THEN MID$(sfcmemargs(i2), x, 1) = CHR$(1) IF Debug THEN PRINT #9, "recompiling cmem sf! setting:"; i2; x recompile = 1 END IF END IF END IF NEXT i unresolved = 0 FOR i = 1 TO idn getid i IF Error_Happened THEN GOTO errmes IF Debug THEN PRINT #9, "checking id named:"; id.n IF id.subfunc THEN FOR i2 = 1 TO id.args t = CVL(MID$(id.arg, i2 * 4 - 3, 4)) IF t > 0 THEN IF (t AND ISPOINTER) THEN IF (t AND ISARRAY) THEN IF Debug THEN PRINT #9, "checking argument "; i2; " of "; id.args nele = ASC(MID$(id.nele, i2, 1)) nelereq = ASC(MID$(id.nelereq, i2, 1)) IF Debug THEN PRINT #9, "nele="; nele IF Debug THEN PRINT #9, "nelereq="; nelereq IF nele <> nelereq THEN IF Debug THEN PRINT #9, "mismatch detected!" unresolved = unresolved + 1 sflistn = sflistn + 1 sfidlist(sflistn) = i sfarglist(sflistn) = i2 sfelelist(sflistn) = nelereq '0 means still unknown END IF END IF END IF END IF NEXT END IF NEXT 'is recompilation required to resolve this? IF unresolved > 0 THEN IF lastunresolved = -1 THEN 'first pass recompile = 1 IF Debug THEN PRINT #9, "recompiling to resolve array elements (first time)" PRINT #9, "sflistn="; sflistn PRINT #9, "oldsflistn="; oldsflistn END IF ELSE 'not first pass IF unresolved < lastunresolved THEN recompile = 1 IF Debug THEN PRINT #9, "recompiling to resolve array elements (not first time)" PRINT #9, "sflistn="; sflistn PRINT #9, "oldsflistn="; oldsflistn END IF END IF END IF END IF 'unresolved lastunresolved = unresolved 'IDEA! 'have a flag to record if anything gets resolved in a pass 'if not then it's time to stop 'the problem is the same amount of new problems may be created by a 'resolve as those that get fixed 'also/or.. could it be that previous fixes are overridden in a recompile ' by a new fix? if so, it would give these effects 'could recompilation resolve this? 'IF sflistn <> -1 THEN 'IF sflistn <> oldsflistn THEN 'recompile = 1 ' 'if debug then 'print #9,"recompile set to 1 to resolve array elements" 'print #9,"sflistn=";sflistn 'print #9,"oldsflistn=";oldsflistn 'end if ' 'END IF 'END IF IF Debug THEN PRINT #9, "Beginning COMMON array list check..." xi = 1 FOR x = 1 TO commonarraylistn varname$ = getelement$(commonarraylist, xi): xi = xi + 1 typ$ = getelement$(commonarraylist, xi): xi = xi + 1 dimmethod2 = VAL(getelement$(commonarraylist, xi)): xi = xi + 1 dimshared2 = VAL(getelement$(commonarraylist, xi)): xi = xi + 1 'find the array ID (try method) t = typname2typ(typ$) IF Error_Happened THEN GOTO errmes IF (t AND ISUDT) = 0 THEN varname$ = varname$ + type2symbol$(typ$) IF Error_Happened THEN GOTO errmes IF Debug THEN PRINT #9, "Checking for array '" + varname$ + "'..." try = findid(varname$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.arraytype THEN GOTO foundcommonarray2 IF try = 2 THEN findanotherid = 1: try = findid(varname$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP foundcommonarray2: IF Debug THEN PRINT #9, "Found array '" + varname$ + "!" IF id.arrayelements = -1 THEN IF arrayelementslist(currentid) <> 0 THEN recompile = 1 IF Debug THEN PRINT #9, "Recompiling to resolve elements of:" + varname$ END IF NEXT IF Debug THEN PRINT #9, "Finished COMMON array list check!" IF recompile THEN do_recompile: IF Debug THEN PRINT #9, "Recompile required!" recompile = 0 IF idemode THEN iderecompile = 1 FOR closeall = 1 TO 255: CLOSE closeall: NEXT OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 'relock GOTO recompile END IF IF Debug THEN PRINT #9, "Beginning label check..." FOR r = 1 TO nLabels IF Labels(r).Scope_Restriction THEN a$ = RTRIM$(Labels(r).cn) ignore = validlabel(a$) v = HashFind(a$, HASHFLAG_LABEL, ignore, r2) addlabchk7: IF v THEN IF Labels(r2).Scope = Labels(r).Scope_Restriction THEN linenumber = Labels(r).Error_Line: a$ = "Common label within a SUB/FUNCTION": GOTO errmes END IF IF v = 2 THEN v = HashFindCont(ignore, r2): GOTO addlabchk7 END IF 'v END IF 'restriction 'check for undefined labels IF Labels(r).State = 0 THEN IF INSTR(PossibleSubNameLabels$, sp + UCASE$(RTRIM$(Labels(r).cn)) + sp) THEN IF INSTR(SubNameLabels$, sp + UCASE$(RTRIM$(Labels(r).cn)) + sp) = 0 THEN 'not already added SubNameLabels$ = SubNameLabels$ + UCASE$(RTRIM$(Labels(r).cn)) + sp IF Debug THEN PRINT #9, "Recompiling to resolve label:"; RTRIM$(Labels(r).cn) GOTO do_recompile END IF END IF linenumber = Labels(r).Error_Line: a$ = "Label not defined": GOTO errmes END IF IF Labels(r).Data_Referenced THEN 'check for ambiguous RESTORE reference x = 0 a$ = RTRIM$(Labels(r).cn) ignore = validlabel(a$) v = HashFind(a$, HASHFLAG_LABEL, ignore, r2) addlabchk4: IF v THEN x = x + 1 IF v = 2 THEN v = HashFindCont(ignore, r2): GOTO addlabchk4 END IF 'v IF x <> 1 THEN linenumber = Labels(r).Error_Line: a$ = "Ambiguous DATA label": GOTO errmes 'add global data offset variable PRINT #18, "ptrszint data_at_LABEL_" + a$ + "=" + str2(Labels(r).Data_Offset) + ";" END IF 'data referenced NEXT IF Debug THEN PRINT #9, "Finished check!" 'if targettyp=-4 or targettyp=-5 then '? -> byte_element(offset,element size in bytes) ' IF (sourcetyp AND ISREFERENCE) = 0 THEN a$ = "Expected variable name/array element": GOTO errmes 'create include files for COMMON arrays CLOSE #12 'return to 'main' subfunc$ = "" defdatahandle = 18 CLOSE #13: OPEN tmpdir$ + "maindata.txt" FOR APPEND AS #13 CLOSE #19: OPEN tmpdir$ + "mainfree.txt" FOR APPEND AS #19 IF Console THEN PRINT #18, "int32 console=1;" ELSE PRINT #18, "int32 console=0;" END IF IF ScreenHide THEN PRINT #18, "int32 screen_hide_startup=1;" ELSE PRINT #18, "int32 screen_hide_startup=0;" END IF fh = FREEFILE OPEN tmpdir$ + "dyninfo.txt" FOR APPEND AS #fh IF Resize THEN PRINT #fh, "ScreenResize=1;" END IF IF Resize_Scale THEN PRINT #fh, "ScreenResizeScale=" + str2(Resize_Scale) + ";" END IF CLOSE #fh 'DATA_finalize PRINT #18, "ptrszint data_size=" + str2(DataOffset) + ";" IF DataOffset = 0 THEN PRINT #18, "uint8 *data=(uint8*)calloc(1,1);" ELSE IF inline_DATA = 0 THEN IF os$ = "WIN" THEN x$ = CHR$(0): PUT #16, , x$ PRINT #18, "extern " + CHR$(34) + "C" + CHR$(34) + "{" PRINT #18, "extern char *binary_____temp" + tempfolderindexstr2$ + "__data_bin_start;" PRINT #18, "}" PRINT #18, "uint8 *data=(uint8*)&binary_____temp" + tempfolderindexstr2$ + "__data_bin_start;" END IF IF os$ = "LNX" THEN x$ = CHR$(0): PUT #16, , x$ PRINT #18, "extern " + CHR$(34) + "C" + CHR$(34) + "{" PRINT #18, "extern char *_binary____temp" + tempfolderindexstr2$ + "_data_bin_start;" PRINT #18, "}" PRINT #18, "uint8 *data=(uint8*)&_binary____temp" + tempfolderindexstr2$ + "_data_bin_start;" END IF ELSE 'inline data CLOSE #16 ff = FREEFILE OPEN tmpdir$ + "data.bin" FOR BINARY AS #ff x$ = SPACE$(LOF(ff)) GET #ff, , x$ CLOSE #ff x2$ = "uint8 inline_data[]={" FOR i = 1 TO LEN(x$) x2$ = x2$ + inlinedatastr$(ASC(x$, i)) NEXT x2$ = x2$ + "0};" PRINT #18, x2$ PRINT #18, "uint8 *data=&inline_data[0];" x$ = "": x2$ = "" END IF END IF IF Debug THEN PRINT #9, "Beginning generation of code for saving/sharing common array data..." use_global_byte_elements = 1 ncommontmp = 0 xi = 1 FOR x = 1 TO commonarraylistn varname$ = getelement$(commonarraylist, xi): xi = xi + 1 typ$ = getelement$(commonarraylist, xi): xi = xi + 1 dimmethod2 = VAL(getelement$(commonarraylist, xi)): xi = xi + 1 dimshared2 = VAL(getelement$(commonarraylist, xi)): xi = xi + 1 'find the array ID (try method) purevarname$ = varname$ t = typname2typ(typ$) IF Error_Happened THEN GOTO errmes IF (t AND ISUDT) = 0 THEN varname$ = varname$ + type2symbol$(typ$) IF Error_Happened THEN GOTO errmes try = findid(varname$) IF Error_Happened THEN GOTO errmes DO WHILE try IF id.arraytype THEN GOTO foundcommonarray IF try = 2 THEN findanotherid = 1: try = findid(varname$) ELSE try = 0 IF Error_Happened THEN GOTO errmes LOOP a$ = "COMMON array unlocatable": GOTO errmes 'should never happen foundcommonarray: IF Debug THEN PRINT #9, "Found common array '" + varname$ + "'!" i = currentid arraytype = id.arraytype arrayelements = id.arrayelements e$ = RTRIM$(id.n) IF (t AND ISUDT) = 0 THEN e$ = e$ + typevalue2symbol$(t) IF Error_Happened THEN GOTO errmes n$ = e$ n2$ = RTRIM$(id.callname) tsize = id.tsize 'select command command = 3 'fixed length elements IF t AND ISSTRING THEN IF (t AND ISFIXEDLENGTH) = 0 THEN command = 4 'var-len elements END IF END IF 'if... 'i) array elements are still undefined (ie. arrayelements=-1) pass the input content along ' if any existed or an array-placeholder 'ii) if the array's elements were defined, any input content would have been loaded so the ' array (in whatever state it currently is) should be passed. If it is currently erased ' then it should be passed as a placeholder IF arrayelements = -1 THEN 'load array (copies the array, if any, into a buffer for later) OPEN tmpdir$ + "inpchain" + str2$(i) + ".txt" FOR OUTPUT AS #12 PRINT #12, "if (int32val==2){" 'array place-holder 'create buffer to store array as-is in global.txt x$ = str2$(uniquenumber) x1$ = "chainarraybuf" + x$ x2$ = "chainarraybufsiz" + x$ PRINT #18, "static uint8 *" + x1$ + "=(uint8*)malloc(1);" PRINT #18, "static int64 " + x2$ + "=0;" 'read next command PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" IF command = 3 THEN PRINT #12, "if (int32val==3){" 'fixed-length-element array IF command = 4 THEN PRINT #12, "if (int32val==4){" 'var-length-element array PRINT #12, x2$ + "+=4; " + x1$ + "=(uint8*)realloc(" + x1$ + "," + x2$ + "); *(int32*)(" + x1$ + "+" + x2$ + "-4)=int32val;" IF command = 3 THEN 'read size in bits of one element, convert it to bytes PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" PRINT #12, x2$ + "+=8; " + x1$ + "=(uint8*)realloc(" + x1$ + "," + x2$ + "); *(int64*)(" + x1$ + "+" + x2$ + "-8)=int64val;" PRINT #12, "bytes=int64val>>3;" END IF 'com=3 IF command = 4 THEN PRINT #12, "bytes=1;" 'bytes used to calculate number of elements 'read number of dimensions PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" PRINT #12, x2$ + "+=4; " + x1$ + "=(uint8*)realloc(" + x1$ + "," + x2$ + "); *(int32*)(" + x1$ + "+" + x2$ + "-4)=int32val;" 'read size of dimensions & calculate the size of the array in bytes PRINT #12, "while(int32val--){" PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" 'lbound PRINT #12, x2$ + "+=8; " + x1$ + "=(uint8*)realloc(" + x1$ + "," + x2$ + "); *(int64*)(" + x1$ + "+" + x2$ + "-8)=int64val;" PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int64val2,8," + NewByteElement$ + "),0);" 'ubound PRINT #12, x2$ + "+=8; " + x1$ + "=(uint8*)realloc(" + x1$ + "," + x2$ + "); *(int64*)(" + x1$ + "+" + x2$ + "-8)=int64val2;" PRINT #12, "bytes*=(int64val2-int64val+1);" PRINT #12, "}" IF command = 3 THEN 'read the array data PRINT #12, x2$ + "+=bytes; " + x1$ + "=(uint8*)realloc(" + x1$ + "," + x2$ + ");" PRINT #12, "sub_get(FF,NULL,byte_element((uint64)(" + x1$ + "+" + x2$ + "-bytes),bytes," + NewByteElement$ + "),0);" END IF 'com=3 IF command = 4 THEN PRINT #12, "bytei=0;" PRINT #12, "while(bytei>3); " + x1$ + "=(uint8*)realloc(" + x1$ + "," + x2$ + ");" PRINT #12, "sub_get(FF,NULL,byte_element((uint64)(" + x1$ + "+" + x2$ + "-(int64val>>3)),(int64val>>3)," + NewByteElement$ + "),0);" PRINT #12, "bytei++;" PRINT #12, "}" END IF 'get next command PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" PRINT #12, "}" 'command=3 or 4 PRINT #12, "}" 'array place-holder CLOSE #12 'save array (saves the buffered data, if any, for later) OPEN tmpdir$ + "chain" + str2$(i) + ".txt" FOR OUTPUT AS #12 PRINT #12, "int32val=2;" 'placeholder PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" PRINT #12, "sub_put(FF,NULL,byte_element((uint64)" + x1$ + "," + x2$ + "," + NewByteElement$ + "),0);" CLOSE #12 ELSE 'note: arrayelements<>-1 'load array OPEN tmpdir$ + "inpchain" + str2$(i) + ".txt" FOR OUTPUT AS #12 PRINT #12, "if (int32val==2){" 'array place-holder PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" IF command = 3 THEN PRINT #12, "if (int32val==3){" 'fixed-length-element array IF command = 4 THEN PRINT #12, "if (int32val==4){" 'var-length-element array IF command = 3 THEN 'get size in bits PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" '***assume correct*** END IF 'get number of elements PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" '***assume correct*** e$ = "" IF command = 4 THEN PRINT #12, "bytes=1;" 'bytes counts the number of total elements FOR x2 = 1 TO arrayelements 'create 'secret' variables to assist in passing common arrays IF x2 > ncommontmp THEN ncommontmp = ncommontmp + 1 IF Debug THEN PRINT #9, "Calling DIM2(...)..." IF Error_Happened THEN GOTO errmes retval = dim2("___RESERVED_COMMON_LBOUND" + str2$(ncommontmp), "_INTEGER64", 0, "") IF Error_Happened THEN GOTO errmes retval = dim2("___RESERVED_COMMON_UBOUND" + str2$(ncommontmp), "_INTEGER64", 0, "") IF Error_Happened THEN GOTO errmes IF Debug THEN PRINT #9, "Finished calling DIM2(...)!" IF Error_Happened THEN GOTO errmes END IF PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" PRINT #12, "*__INTEGER64____RESERVED_COMMON_LBOUND" + str2$(x2) + "=int64val;" PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int64val2,8," + NewByteElement$ + "),0);" PRINT #12, "*__INTEGER64____RESERVED_COMMON_UBOUND" + str2$(x2) + "=int64val2;" IF command = 4 THEN PRINT #12, "bytes*=(int64val2-int64val+1);" IF x2 > 1 THEN e$ = e$ + sp + "," + sp e$ = e$ + "___RESERVED_COMMON_LBOUND" + str2$(x2) + sp + "TO" + sp + "___RESERVED_COMMON_UBOUND" + str2$(x2) NEXT IF Debug THEN PRINT #9, "Calling DIM2(" + purevarname$ + "," + typ$ + ",0," + e$ + ")..." IF Error_Happened THEN GOTO errmes 'Note: purevarname$ is simply varname$ without the type symbol after it redimoption = 1 retval = dim2(purevarname$, typ$, 0, e$) IF Error_Happened THEN GOTO errmes redimoption = 0 IF Debug THEN PRINT #9, "Finished calling DIM2(" + purevarname$ + "," + typ$ + ",0," + e$ + ")!" IF Error_Happened THEN GOTO errmes IF command = 3 THEN 'use get to load in the array data varname$ = varname$ + sp + "(" + sp + ")" e$ = evaluatetotyp(fixoperationorder$(varname$), -4) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_get(FF,NULL," + e$ + ",0);" END IF IF command = 4 THEN PRINT #12, "bytei=0;" PRINT #12, "while(bytei>3,1));" 'change string size PRINT #12, "sub_get(FF,NULL,byte_element((uint64)tqbs->chr,int64val>>3," + NewByteElement$ + "),0);" 'get size PRINT #12, "bytei++;" PRINT #12, "}" END IF 'get next command PRINT #12, "sub_get(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" PRINT #12, "}" PRINT #12, "}" CLOSE #12 'save array OPEN tmpdir$ + "chain" + str2$(i) + ".txt" FOR OUTPUT AS #12 PRINT #12, "int32val=2;" 'placeholder PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" PRINT #12, "if (" + n2$ + "[2]&1){" 'don't add unless defined IF command = 3 THEN PRINT #12, "int32val=3;" IF command = 4 THEN PRINT #12, "int32val=4;" PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" IF command = 3 THEN 'size of each element in bits bits = t AND 511 IF t AND ISUDT THEN bits = udtxsize(t AND 511) IF t AND ISSTRING THEN bits = tsize * 8 PRINT #12, "int64val=" + str2$(bits) + ";" 'size in bits PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" END IF 'com=3 PRINT #12, "int32val=" + str2$(arrayelements) + ";" 'number of dimensions PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int32val,4," + NewByteElement$ + "),0);" IF command = 3 THEN FOR x2 = 1 TO arrayelements 'simulate calls to lbound/ubound e$ = "LBOUND" + sp + "(" + sp + n$ + sp + "," + sp + str2$(x2) + sp + ")" e$ = evaluatetotyp(fixoperationorder$(e$), 64) IF Error_Happened THEN GOTO errmes PRINT #12, "int64val=" + e$ + ";" PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" e$ = "UBOUND" + sp + "(" + sp + n$ + sp + "," + sp + str2$(x2) + sp + ")" e$ = evaluatetotyp(fixoperationorder$(e$), 64) IF Error_Happened THEN GOTO errmes PRINT #12, "int64val=" + e$ + ";" PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" NEXT 'array data e$ = evaluatetotyp(fixoperationorder$(n$ + sp + "(" + sp + ")"), -4) IF Error_Happened THEN GOTO errmes PRINT #12, "sub_put(FF,NULL," + e$ + ",0);" END IF 'com=3 IF command = 4 THEN 'store LBOUND/UBOUND values and calculate number of total elements/strings PRINT #12, "bytes=1;" 'note: bytes is actually the total number of elements FOR x2 = 1 TO arrayelements e$ = "LBOUND" + sp + "(" + sp + n$ + sp + "," + sp + str2$(x2) + sp + ")" e$ = evaluatetotyp(fixoperationorder$(e$), 64) IF Error_Happened THEN GOTO errmes PRINT #12, "int64val=" + e$ + ";" PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" e$ = "UBOUND" + sp + "(" + sp + n$ + sp + "," + sp + str2$(x2) + sp + ")" e$ = evaluatetotyp(fixoperationorder$(e$), 64) IF Error_Happened THEN GOTO errmes PRINT #12, "int64val2=" + e$ + ";" PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int64val2,8," + NewByteElement$ + "),0);" PRINT #12, "bytes*=(int64val2-int64val+1);" NEXT PRINT #12, "bytei=0;" PRINT #12, "while(byteilen; int64val<<=3;" PRINT #12, "sub_put(FF,NULL,byte_element((uint64)&int64val,8," + NewByteElement$ + "),0);" 'size of element PRINT #12, "sub_put(FF,NULL,byte_element((uint64)tqbs->chr,tqbs->len," + NewByteElement$ + "),0);" 'element data PRINT #12, "bytei++;" PRINT #12, "}" END IF 'com=4 PRINT #12, "}" 'don't add unless defined CLOSE #12 'if chaincommonarray then 'l2$=tlayout$ 'x=chaincommonarray ' ''chain???.txt 'open tmpdir$ + "chain" + str2$(x) + ".txt" for append as #22 'if lof(22) then close #22: goto chaindone 'only add this once ''***assume non-var-len-string array*** 'print #22,"int32val=3;" 'non-var-len-element array 'print #22,"sub_put(FF,NULL,byte_element((uint64)&int32val,4,"+NewByteElement$+"),0);" 't=id.arraytype ''***check for UDT size if necessary*** ''***check for string length if necessary*** 'bits=t and 511 'print #22,"int64val="+str2$(bits)+";" 'size in bits 'print #22,"sub_put(FF,NULL,byte_element((uint64)&int64val,8,"+NewByteElement$+"),0);" 'print #22,"int32val="+str2$(id.arrayelements)+";" 'number of elements 'print #22,"sub_put(FF,NULL,byte_element((uint64)&int32val,4,"+NewByteElement$+"),0);" 'e$=rtrim$(id.n) 'if (t and ISUDT)=0 then e$=e$+typevalue2symbol$(t) 'n$=e$ 'for x2=1 to id.arrayelements ''simulate calls to lbound/ubound 'e$="LBOUND"+sp+"("+sp+n$+sp+","+sp+str2$(x2)+sp+")" 'e$=evaluatetotyp(fixoperationorder$(e$),64) 'print #22,"int64val="+e$+";"'LBOUND 'print #22,"sub_put(FF,NULL,byte_element((uint64)&int64val,8,"+NewByteElement$+"),0);" 'e$="UBOUND"+sp+"("+sp+n$+sp+","+sp+str2$(x2)+sp+")" 'e$=evaluatetotyp(fixoperationorder$(e$),64) 'print #22,"int64val="+e$+";"'LBOUND 'print #22,"sub_put(FF,NULL,byte_element((uint64)&int64val,8,"+NewByteElement$+"),0);" 'next ''add array data 'e$=evaluatetotyp(fixoperationorder$(n$+sp+"("+sp+")"),-4) 'print #22,"sub_put(FF,NULL,"+e$+",0);" 'close #22 ' ''inpchain???.txt 'open tmpdir$ + "chain" + str2$(x) + ".txt" for append as #22 'print #22,"if (int32val==1){" 'common declaration of an array 'print #22,"sub_get(FF,NULL,byte_element((uint64)&int32val,4,"+NewByteElement$+"),0);" 'print #22,"if (int32val==3){" 'fixed-length-element array ' 'print #22,"sub_get(FF,NULL,byte_element((uint64)&int64val,8,"+NewByteElement$+"),0);" ''***assume size correct and continue*** ' ''get number of elements 'print #22,"sub_get(FF,NULL,byte_element((uint64)&int32val,4,"+NewByteElement$+"),0);" ' ''call dim2 and tell it to redim an array ' ''*********this should happen BEFORE the array (above) is actually dimensioned, ''*********where the common() declaration is ' ''****although, if you never reference the array............. ''****ARGH! you can access an undimmed array just like in a sub/function ' ' ' ' 'print #22,"}" 'print #22,"}" 'close #22 ' 'chaindone: 'tlayout$=l2$ 'end if 'chaincommonarray 'OPEN tmpdir$ + "chain.txt" FOR APPEND AS #22 ''include directive 'print #22, "#include " + CHR$(34) + "chain" + str2$(x) + ".txt" + CHR$(34) 'close #22 ''create/clear include file 'open tmpdir$ + "chain" + str2$(x) + ".txt" for output as #22:close #22 ' 'OPEN tmpdir$ + "inpchain.txt" FOR APPEND AS #22 ''include directive 'print #22, "#include " + CHR$(34) + "inpchain" + str2$(x) + ".txt" + CHR$(34) 'close #22 ''create/clear include file 'open tmpdir$ + "inpchain" + str2$(x) + ".txt" for output as #22:close #22 END IF 'id.arrayelements=-1 NEXT use_global_byte_elements = 0 IF Debug THEN PRINT #9, "Finished generation of code for saving/sharing common array data!" FOR closeall = 1 TO 255: CLOSE closeall: NEXT OPEN tmpdir$ + "temp.bin" FOR OUTPUT LOCK WRITE AS #26 'relock IF idemode THEN GOTO ideret5 ide6: IF idemode = 0 AND No_C_Compile_Mode = 0 THEN PRINT IF os$ = "LNX" THEN PRINT "COMPILING C++ CODE INTO EXECUTABLE..." ELSE PRINT "COMPILING C++ CODE INTO EXE..." END IF IF _FILEEXISTS(file$ + extension$) THEN E = 0 ON ERROR GOTO qberror_test KILL file$ + extension$ ON ERROR GOTO qberror IF E = 1 THEN a$ = "CANNOT CREATE " + CHR$(34) + file$ + extension$ + CHR$(34) + " BECAUSE THE FILE IS ALREADY IN USE!": GOTO errmes END IF END IF END IF 'Update dependencies o$ = LCASE$(os$) win = 0: IF os$ = "WIN" THEN win = 1 lnx = 0: IF os$ = "LNX" THEN lnx = 1 mac = 0: IF MacOSX THEN mac = 1: o$ = "osx" defines$ = "": defines_header$ = " -D " ver$ = Version$ 'eg. "0.123" x = INSTR(ver$, "."): IF x THEN ASC(ver$, x) = 95 'change "." to "_" libs$ = "" IF DEPENDENCY(DEPENDENCY_GL) THEN IF Cloud THEN a$ = "GL not supported on QLOUD": GOTO errmes '***NOCLOUD*** defines$ = defines$ + defines_header$ + "DEPENDENCY_GL" END IF IF DEPENDENCY(DEPENDENCY_IMAGE_CODEC) THEN defines$ = defines$ + defines_header$ + "DEPENDENCY_IMAGE_CODEC" END IF IF DEPENDENCY(DEPENDENCY_LOADFONT) THEN d$ = "internal\c\parts\video\font\ttf\" 'rebuild? IF _FILEEXISTS(d$ + "os\" + o$ + "\src.o") = 0 THEN Build d$ + "os\" + o$ END IF defines$ = defines$ + defines_header$ + "DEPENDENCY_LOADFONT" libs$ = libs$ + " " + "parts\video\font\ttf\os\" + o$ + "\src.o" END IF IF DEPENDENCY(DEPENDENCY_AUDIO_DECODE) THEN DEPENDENCY(DEPENDENCY_AUDIO_CONVERSION) = 1 IF DEPENDENCY(DEPENDENCY_AUDIO_CONVERSION) THEN DEPENDENCY(DEPENDENCY_AUDIO_OUT) = 1 IF DEPENDENCY(DEPENDENCY_AUDIO_DECODE) THEN DEPENDENCY(DEPENDENCY_AUDIO_OUT) = 1 IF DEPENDENCY(DEPENDENCY_AUDIO_CONVERSION) THEN defines$ = defines$ + defines_header$ + "DEPENDENCY_AUDIO_CONVERSION" d1$ = "parts\audio\conversion" d2$ = d1$ + "\os\" + o$ d3$ = "internal\c\" + d2$ IF _FILEEXISTS(d3$ + "\src.a") = 0 THEN 'rebuild? Build d3$ END IF libs$ = libs$ + " " + d2$ + "\src.a" d1$ = "parts\audio\libresample" d2$ = d1$ + "\os\" + o$ d3$ = "internal\c\" + d2$ IF _FILEEXISTS(d3$ + "\src.a") = 0 THEN 'rebuild? Build d3$ END IF libs$ = libs$ + " " + d2$ + "\src.a" END IF IF DEPENDENCY(DEPENDENCY_AUDIO_DECODE) THEN 'General decoder defines$ = defines$ + defines_header$ + "DEPENDENCY_AUDIO_DECODE" 'MP3 decoder d1$ = "parts\audio\decode\mp3" d2$ = d1$ + "\os\" + o$ d3$ = "internal\c\" + d2$ IF _FILEEXISTS(d3$ + "\src.a") = 0 THEN 'rebuild? Build d3$ END IF libs$ = libs$ + " " + d2$ + "\src.a" 'OGG decoder d1$ = "parts\audio\decode\ogg" d2$ = d1$ + "\os\" + o$ d3$ = "internal\c\" + d2$ IF _FILEEXISTS(d3$ + "\src.o") = 0 THEN 'rebuild? Build d3$ END IF libs$ = libs$ + " " + d2$ + "\src.o" 'WAV decoder '(no action required) END IF IF DEPENDENCY(DEPENDENCY_AUDIO_OUT) THEN defines$ = defines$ + defines_header$ + "DEPENDENCY_AUDIO_OUT" d1$ = "parts\audio\out" d2$ = d1$ + "\os\" + o$ d3$ = "internal\c\" + d2$ IF _FILEEXISTS(d3$ + "\src.a") = 0 THEN 'rebuild? Build d3$ END IF libs$ = libs$ + " " + d2$ + "\src.a" END IF 'finalize libs$ and defines$ strings IF LEN(libs$) THEN libs$ = libs$ + " " PATH_SLASH_CORRECT libs$ IF LEN(defines$) THEN defines$ = defines$ + " " 'Build core? IF mac = 0 THEN 'macosx uses Apple's GLUT not FreeGLUT d1$ = "parts\core" d2$ = d1$ + "\os\" + o$ d3$ = "internal\c\" + d2$ IF _FILEEXISTS(d3$ + "\src.a") = 0 THEN 'rebuild? Build d3$ END IF END IF 'mac = 0 'Build libqb? depstr$ = ver$ + "_" FOR i = 1 TO DEPENDENCY_LAST IF DEPENDENCY(i) THEN depstr$ = depstr$ + "1" ELSE depstr$ = depstr$ + "0" NEXT libqb$ = " libqb\os\" + o$ + "\libqb_" + depstr$ + ".o " PATH_SLASH_CORRECT libqb$ IF _FILEEXISTS("internal\c\" + LTRIM$(RTRIM$(libqb$))) = 0 THEN CHDIR "internal\c" IF os$ = "WIN" THEN SHELL _HIDE GDB_Fix("cmd /c c_compiler\bin\g++ -c -s -w -Wall libqb.cpp -D FREEGLUT_STATIC " + defines$ + " -o libqb\os\" + o$ + "\libqb_" + depstr$ + ".o") ELSE IF mac THEN SHELL _HIDE GDB_Fix("g++ -c -s -w -Wall libqb.cpp " + defines$ + " -o libqb/os/" + o$ + "/libqb_" + depstr$ + ".o") ELSE SHELL _HIDE GDB_Fix("g++ -c -s -w -Wall libqb.cpp -D FREEGLUT_STATIC " + defines$ + " -o libqb/os/" + o$ + "/libqb_" + depstr$ + ".o") END IF END IF CHDIR "..\.." END IF 'link-time only defines IF DEPENDENCY(DEPENDENCY_AUDIO_OUT) THEN IF mac THEN defines$ = defines$ + " -framework AudioUnit -framework AudioToolbox " END IF IF MakeAndroid THEN GOTO Skip_Build END IF IF os$ = "WIN" THEN 'resolve static function definitions and add to global.txt FOR x = 1 TO ResolveStaticFunctions IF LEN(ResolveStaticFunction_File(x)) THEN n = 0 SHELL _HIDE "internal\c\c_compiler\bin\nm.exe " + CHR$(34) + ResolveStaticFunction_File(x) + CHR$(34) + " --demangle -g >internal\temp\nm_output.txt" fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x) + "(" OPEN "internal\temp\nm_output.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname+LEFTBRACKET x1 = INSTR(a$, s$) IF x1 THEN IF ResolveStaticFunction_Method(x) = 1 THEN x1 = x1 + 1 x2 = INSTR(x1, a$, ")") fh2 = FREEFILE OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern void " + MID$(a$, x1, x2 - x1 + 1) + ";" CLOSE #fh2 END IF n = n + 1 END IF 'x1 END IF '<>"" LOOP CLOSE #fh IF n > 1 THEN a$ = "Unable to resolve multiple instances of sub/function '" + ResolveStaticFunction_Name(x) + "' in '" + ResolveStaticFunction_File(x) + "'": GOTO errmes IF n = 0 THEN 'attempt to locate simple function name without brackets fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x) OPEN "internal\temp\nm_output.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname x1 = INSTR(a$, s$) IF RIGHT$(a$, LEN(s$)) = s$ THEN fh2 = FREEFILE IF ResolveStaticFunction_Method(x) = 1 THEN OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + "{" PRINT #fh2, "extern void " + s$ + "(void);" PRINT #fh2, "}" ELSE OPEN tmpdir$ + "externtype" + str2(x) + ".txt" FOR OUTPUT AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + " " END IF CLOSE #fh2 n = n + 1 EXIT DO END IF 'x1 END IF '<>"" LOOP CLOSE #fh END IF IF n = 0 THEN 'a C++ dynamic object library? SHELL _HIDE "internal\c\c_compiler\bin\nm " + CHR$(34) + ResolveStaticFunction_File(x) + CHR$(34) + " -D --demangle -g >.\internal\temp\nm_output_dynamic.txt" fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x) + "(" OPEN "internal\temp\nm_output_dynamic.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname+LEFTBRACKET x1 = INSTR(a$, s$) IF x1 THEN IF ResolveStaticFunction_Method(x) = 1 THEN x1 = x1 + 1 x2 = INSTR(x1, a$, ")") fh2 = FREEFILE OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern void " + MID$(a$, x1, x2 - x1 + 1) + ";" CLOSE #fh2 END IF n = n + 1 END IF 'x1 END IF '<>"" LOOP CLOSE #fh IF n > 1 THEN a$ = "Unable to resolve multiple instances of sub/function '" + ResolveStaticFunction_Name(x) + "' in '" + ResolveStaticFunction_File(x) + "'": GOTO errmes END IF IF n = 0 THEN 'a C dynamic object library? fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x) OPEN "internal\temp\nm_output_dynamic.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname x1 = INSTR(a$, s$) IF RIGHT$(a$, LEN(s$)) = s$ THEN fh2 = FREEFILE IF ResolveStaticFunction_Method(x) = 1 THEN OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + "{" PRINT #fh2, "extern void " + s$ + "(void);" PRINT #fh2, "}" ELSE OPEN tmpdir$ + "externtype" + str2(x) + ".txt" FOR OUTPUT AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + " " END IF CLOSE #fh2 n = n + 1 EXIT DO END IF 'x1 END IF '<>"" LOOP CLOSE #fh IF n = 0 THEN a$ = "Could not find sub/function '" + ResolveStaticFunction_Name(x) + "' in '" + ResolveStaticFunction_File(x) + "'": GOTO errmes END IF END IF NEXT IF inline_DATA = 0 THEN IF DataOffset THEN OPEN ".\internal\c\makedat_win.txt" FOR INPUT AS #150: LINE INPUT #150, a$: CLOSE #150 a$ = a$ + " " + tmpdir2$ + "data.bin " + tmpdir2$ + "data.o" CHDIR ".\internal\c" SHELL _HIDE a$ CHDIR "..\.." END IF END IF OPEN ".\internal\c\makeline_win.txt" FOR INPUT AS #150 LINE INPUT #150, a$: a$ = GDB_Fix(a$) CLOSE #150 IF RIGHT$(a$, 7) = " ..\..\" THEN a$ = LEFT$(a$, LEN(a$) - 6) 'makeline.txt patch (line will become unrequired in later versions) 'change qbx.cpp to qbx999.cpp? x = INSTR(a$, "qbx.cpp"): IF x <> 0 AND tempfolderindex <> 1 THEN a$ = LEFT$(a$, x - 1) + "qbx" + str2$(tempfolderindex) + ".cpp" + RIGHT$(a$, LEN(a$) - (x + 6)) IF Console THEN IF C_Core = 0 THEN x = INSTR(a$, "-mwindows"): a$ = LEFT$(a$, x - 1) + "-mconsole " + RIGHT$(a$, LEN(a$) - x + 1) END IF IF C_Core = 1 THEN x = INSTR(a$, " -s"): a$ = LEFT$(a$, x - 1) + " -mconsole" + RIGHT$(a$, LEN(a$) - x + 1) END IF END IF IF inline_DATA = 0 THEN 'add data.o? IF DataOffset THEN x = INSTR(a$, ".cpp ") IF x THEN x = x + 3 a$ = LEFT$(a$, x) + " " + tmpdir2$ + "data.o" + " " + RIGHT$(a$, LEN(a$) - x) END IF END IF END IF 'add custom libraries 'mylib$="..\..\"+x$+".lib" IF LEN(mylib$) THEN x = INSTR(a$, ".cpp ") IF x THEN x = x + 3 a$ = LEFT$(a$, x) + " " + mylib$ + " " + RIGHT$(a$, LEN(a$) - x) END IF END IF 'add dependent libraries IF LEN(libs$) THEN x = INSTR(a$, ".cpp ") IF x THEN x = x + 5 a$ = LEFT$(a$, x - 1) + libs$ + RIGHT$(a$, LEN(a$) - x + 1) END IF END IF 'add dependency defines IF LEN(defines$) THEN x = INSTR(a$, ".cpp ") IF x THEN x = x + 5 a$ = LEFT$(a$, x - 1) + defines$ + RIGHT$(a$, LEN(a$) - x + 1) END IF END IF 'add libqb x = INSTR(a$, ".cpp ") IF x THEN x = x + 5 a$ = LEFT$(a$, x - 1) + libqb$ + RIGHT$(a$, LEN(a$) - x + 1) END IF a$ = a$ + idezfilename$("..\..\" + file$ + extension$) ffh = FREEFILE OPEN tmpdir$ + "recompile_win.bat" FOR OUTPUT AS #ffh PRINT #ffh, "@echo off" PRINT #ffh, "cd %0\..\" PRINT #ffh, "echo Recompiling..." PRINT #ffh, "cd ../c" PRINT #ffh, a$ PRINT #ffh, "pause" CLOSE ffh ffh = FREEFILE OPEN tmpdir$ + "debug_win.bat" FOR OUTPUT AS #ffh PRINT #ffh, "@echo off" PRINT #ffh, "cd %0\..\" PRINT #ffh, "cd ../.." PRINT #ffh, "echo C++ Debugging: " + file$ + extension$ + " using gdb.exe" PRINT #ffh, "echo Debugger commands:" PRINT #ffh, "echo After the debugger launches type 'run' to start your program" PRINT #ffh, "echo After your program crashes type 'list' to find where the problem is and fix/report it" PRINT #ffh, "echo Type 'quit' to exit" PRINT #ffh, "echo (the GDB debugger has many other useful commands, this advice is for beginners)" PRINT #ffh, "pause" PRINT #ffh, "internal\c\c_compiler\bin\gdb.exe " + CHR$(34) + file$ + extension$ + CHR$(34) PRINT #ffh, "pause" CLOSE ffh IF No_C_Compile_Mode = 0 THEN CHDIR ".\internal\c" SHELL _HIDE a$ CHDIR "..\.." END IF 'No_C_Compile_Mode=0 END IF IF os$ = "LNX" THEN FOR x = 1 TO ResolveStaticFunctions IF LEN(ResolveStaticFunction_File(x)) THEN n = 0 IF MacOSX = 0 THEN SHELL _HIDE "nm " + CHR$(34) + ResolveStaticFunction_File(x) + CHR$(34) + " --demangle -g >./internal/temp/nm_output.txt 2>./internal/temp/nm_error.txt" IF MacOSX THEN SHELL _HIDE "nm " + CHR$(34) + ResolveStaticFunction_File(x) + CHR$(34) + " >./internal/temp/nm_output.txt 2>./internal/temp/nm_error.txt" IF MacOSX = 0 THEN 'C++ name demangling not supported in MacOSX fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x) + "(" OPEN "internal\temp\nm_output.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname+LEFTBRACKET x1 = INSTR(a$, s$) IF x1 THEN IF ResolveStaticFunction_Method(x) = 1 THEN x1 = x1 + 1 x2 = INSTR(x1, a$, ")") fh2 = FREEFILE OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern void " + MID$(a$, x1, x2 - x1 + 1) + ";" CLOSE #fh2 END IF n = n + 1 END IF 'x1 END IF '<>"" LOOP CLOSE #fh IF n > 1 THEN a$ = "Unable to resolve multiple instances of sub/function '" + ResolveStaticFunction_Name(x) + "' in '" + ResolveStaticFunction_File(x) + "'": GOTO errmes END IF 'macosx=0 IF n = 0 THEN 'attempt to locate simple function name without brackets fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x): s2$ = s$ IF MacOSX THEN s$ = " _" + ResolveStaticFunction_Name(x) 'search for C mangled name OPEN "internal\temp\nm_output.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname x1 = INSTR(a$, s$) IF RIGHT$(a$, LEN(s$)) = s$ THEN fh2 = FREEFILE IF ResolveStaticFunction_Method(x) = 1 THEN OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + "{" PRINT #fh2, "extern void " + s2$ + "(void);" PRINT #fh2, "}" ELSE OPEN tmpdir$ + "externtype" + str2(x) + ".txt" FOR OUTPUT AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + " " END IF CLOSE #fh2 n = n + 1 EXIT DO END IF 'x1 END IF '<>"" LOOP CLOSE #fh END IF IF n = 0 THEN 'a C++ dynamic object library? IF MacOSX THEN GOTO macosx_libfind_failed SHELL _HIDE "nm " + CHR$(34) + ResolveStaticFunction_File(x) + CHR$(34) + " -D --demangle -g >./internal/temp/nm_output_dynamic.txt 2>./internal/temp/nm_error.txt" fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x) + "(" OPEN "internal\temp\nm_output_dynamic.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname+LEFTBRACKET x1 = INSTR(a$, s$) IF x1 THEN IF ResolveStaticFunction_Method(x) = 1 THEN x1 = x1 + 1 x2 = INSTR(x1, a$, ")") fh2 = FREEFILE OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern void " + MID$(a$, x1, x2 - x1 + 1) + ";" CLOSE #fh2 END IF n = n + 1 END IF 'x1 END IF '<>"" LOOP CLOSE #fh IF n > 1 THEN a$ = "Unable to resolve multiple instances of sub/function '" + ResolveStaticFunction_Name(x) + "' in '" + ResolveStaticFunction_File(x) + "'": GOTO errmes END IF IF n = 0 THEN 'a C dynamic object library? fh = FREEFILE s$ = " " + ResolveStaticFunction_Name(x) OPEN "internal\temp\nm_output_dynamic.txt" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, a$ IF LEN(a$) THEN 'search for SPACE+functionname x1 = INSTR(a$, s$) IF RIGHT$(a$, LEN(s$)) = s$ THEN fh2 = FREEFILE IF ResolveStaticFunction_Method(x) = 1 THEN OPEN tmpdir$ + "global.txt" FOR APPEND AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + "{" PRINT #fh2, "extern void " + s$ + "(void);" PRINT #fh2, "}" ELSE OPEN tmpdir$ + "externtype" + str2(x) + ".txt" FOR OUTPUT AS #fh2 PRINT #fh2, "extern " + CHR$(34) + "C" + CHR$(34) + " " END IF CLOSE #fh2 n = n + 1 EXIT DO END IF 'x1 END IF '<>"" LOOP CLOSE #fh macosx_libfind_failed: IF n = 0 THEN a$ = "Could not find sub/function '" + ResolveStaticFunction_Name(x) + "' in '" + ResolveStaticFunction_File(x) + "'": GOTO errmes END IF END IF NEXT IF inline_DATA = 0 THEN IF DataOffset THEN IF INSTR(_OS$, "[32BIT]") THEN b$ = "32" ELSE b$ = "64" OPEN ".\internal\c\makedat_lnx" + b$ + ".txt" FOR INPUT AS #150: LINE INPUT #150, a$: CLOSE #150 a$ = a$ + " " + tmpdir2$ + "data.bin " + tmpdir2$ + "data.o" CHDIR ".\internal\c" SHELL _HIDE a$ CHDIR "..\.." END IF END IF IF INSTR(_OS$, "[MACOSX]") THEN OPEN "./internal/c/makeline_osx.txt" FOR INPUT AS #150 ELSE OPEN "./internal/c/makeline_lnx.txt" FOR INPUT AS #150 END IF LINE INPUT #150, a$: a$ = GDB_Fix(a$) CLOSE #150 'change qbx.cpp to qbx999.cpp? x = INSTR(a$, "qbx.cpp"): IF x <> 0 AND tempfolderindex <> 1 THEN a$ = LEFT$(a$, x - 1) + "qbx" + str2$(tempfolderindex) + ".cpp" + RIGHT$(a$, LEN(a$) - (x + 6)) IF inline_DATA = 0 THEN 'add data.o? IF DataOffset THEN x = INSTR(a$, "-lX11") IF x THEN a$ = LEFT$(a$, x - 1) + " " + tmpdir2$ + "data.o " + RIGHT$(a$, LEN(a$) - x + 1) END IF END IF END IF 'add custom libraries IF LEN(mylib$) THEN x = INSTR(a$, ".cpp ") IF x THEN x = x + 5 a$ = LEFT$(a$, x - 1) + " " + mylibopt$ + " " + mylib$ + " " + RIGHT$(a$, LEN(a$) - x + 1) END IF END IF 'add dependent libraries IF LEN(libs$) THEN x = INSTR(a$, ".cpp ") IF x THEN x = x + 5 a$ = LEFT$(a$, x - 1) + libs$ + RIGHT$(a$, LEN(a$) - x + 1) END IF END IF 'add dependency defines IF LEN(defines$) THEN x = INSTR(a$, ".cpp ") IF x THEN x = x + 5 a$ = LEFT$(a$, x - 1) + defines$ + RIGHT$(a$, LEN(a$) - x + 1) END IF END IF 'add libqb x = INSTR(a$, ".cpp ") IF x THEN x = x + 5 a$ = LEFT$(a$, x - 1) + libqb$ + RIGHT$(a$, LEN(a$) - x + 1) END IF a$ = a$ + idezfilename$("../../" + file$ + extension$) IF INSTR(_OS$, "[MACOSX]") THEN ffh = FREEFILE OPEN tmpdir$ + "recompile_osx.command" FOR OUTPUT AS #ffh PRINT #ffh, "cd " + CHR_QUOTE + "$(dirname " + CHR_QUOTE + "$0" + CHR_QUOTE + ")" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "Recompiling..." + CHR_QUOTE + CHR$(10); PRINT #ffh, "cd ../c" + CHR$(10); PRINT #ffh, a$ + CHR$(10); PRINT #ffh, "read -p " + CHR_QUOTE + "Press ENTER to exit..." + CHR_QUOTE + CHR$(10); CLOSE ffh SHELL _HIDE "chmod +x " + tmpdir$ + "recompile_osx.command" ffh = FREEFILE OPEN tmpdir$ + "debug_osx.command" FOR OUTPUT AS #ffh PRINT #ffh, "cd " + CHR_QUOTE + "$(dirname " + CHR_QUOTE + "$0" + CHR_QUOTE + ")" + CHR_QUOTE + CHR$(10); PRINT #ffh, "Pause()" + CHR$(10); PRINT #ffh, "{" + CHR$(10); PRINT #ffh, "OLDCONFIG=`stty -g`" + CHR$(10); PRINT #ffh, "stty -icanon -echo min 1 time 0" + CHR$(10); PRINT #ffh, "dd count=1 2>/dev/null" + CHR$(10); PRINT #ffh, "stty $OLDCONFIG" + CHR$(10); PRINT #ffh, "}" + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "C++ Debugging: " + file$ + extension$ + " using GDB" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "Debugger commands:" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "After the debugger launches type 'run' to start your program" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "After your program crashes type 'list' to find where the problem is and fix/report it" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "(the GDB debugger has many other useful commands, this advice is for beginners)" + CHR_QUOTE + CHR$(10); PRINT #ffh, "gdb " + CHR$(34) + "../../" + file$ + extension$ + CHR$(34) + CHR$(10); PRINT #ffh, "Pause" + CHR$(10); CLOSE ffh SHELL _HIDE "chmod +x " + tmpdir$ + "debug_osx.command" ELSE ffh = FREEFILE OPEN tmpdir$ + "recompile_lnx.sh" FOR OUTPUT AS #ffh PRINT #ffh, "#!/bin/sh" + CHR$(10); PRINT #ffh, "Pause()" + CHR$(10); PRINT #ffh, "{" + CHR$(10); PRINT #ffh, "OLDCONFIG=`stty -g`" + CHR$(10); PRINT #ffh, "stty -icanon -echo min 1 time 0" + CHR$(10); PRINT #ffh, "dd count=1 2>/dev/null" + CHR$(10); PRINT #ffh, "stty $OLDCONFIG" + CHR$(10); PRINT #ffh, "}" + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "Recompiling..." + CHR_QUOTE + CHR$(10); PRINT #ffh, "cd ../c" + CHR$(10); PRINT #ffh, a$ + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "Press ENTER to exit..." + CHR_QUOTE + CHR$(10); PRINT #ffh, "Pause" + CHR$(10); CLOSE ffh SHELL _HIDE "chmod +x " + tmpdir$ + "recompile_lnx.sh" ffh = FREEFILE OPEN tmpdir$ + "debug_lnx.sh" FOR OUTPUT AS #ffh PRINT #ffh, "#!/bin/sh" + CHR$(10); PRINT #ffh, "Pause()" + CHR$(10); PRINT #ffh, "{" + CHR$(10); PRINT #ffh, "OLDCONFIG=`stty -g`" + CHR$(10); PRINT #ffh, "stty -icanon -echo min 1 time 0" + CHR$(10); PRINT #ffh, "dd count=1 2>/dev/null" + CHR$(10); PRINT #ffh, "stty $OLDCONFIG" + CHR$(10); PRINT #ffh, "}" + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "C++ Debugging: " + file$ + extension$ + " using GDB" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "Debugger commands:" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "After the debugger launches type 'run' to start your program" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "After your program crashes type 'list' to find where the problem is and fix/report it" + CHR_QUOTE + CHR$(10); PRINT #ffh, "echo " + CHR_QUOTE + "(the GDB debugger has many other useful commands, this advice is for beginners)" + CHR_QUOTE + CHR$(10); PRINT #ffh, "gdb " + CHR$(34) + "../../" + file$ + extension$ + CHR$(34) + CHR$(10); PRINT #ffh, "Pause" + CHR$(10); CLOSE ffh SHELL _HIDE "chmod +x " + tmpdir$ + "debug_lnx.sh" END IF IF No_C_Compile_Mode = 0 THEN CHDIR "./internal/c" SHELL _HIDE a$ CHDIR "../.." END IF IF INSTR(_OS$, "[MACOSX]") THEN ff = FREEFILE OPEN file$ + extension$ + "_start.command" FOR OUTPUT AS #ff PRINT #ff, "cd " + CHR$(34) + "$(dirname " + CHR$(34) + "$0" + CHR$(34) + ")" + CHR$(34); PRINT #ff, CHR$(10); PRINT #ff, "./" + file$ + extension$; PRINT #ff, CHR$(10); CLOSE #ff SHELL _HIDE "chmod +x " + file$ + extension$ + "_start.command" END IF END IF IF No_C_Compile_Mode THEN compfailed = 0: GOTO No_C_Compile IF _FILEEXISTS(file$ + extension$) THEN compfailed = 0 ELSE compfailed = 1 'detect compilation failure IF compfailed THEN IF idemode THEN idemessage$ = "C++ Compilation failed" GOTO ideerror END IF IF compfailed THEN PRINT "C++ COMPILATION FAILED!" END IF Skip_Build: IF idemode THEN GOTO ideret6 No_C_Compile: IF UpdateHandle THEN ideupdatetimerval = TIMER DO UNTIL ABS(TIMER - ideupdatetimerval) >= 3 ContinueDownloads IF DL(UpdateHandle).State = 2 THEN 'download complete update 2 UpdateHandle = 0 GOTO qb64updated END IF _LIMIT 10 LOOP CLOSE DL(UpdateHandle).Handle: DL(UpdateHandle).State = 0: UpdateHandle = 0 qb64updated: END IF 'updatehandle IF compfailed <> 0 AND ConsoleMode = 0 THEN END 1 IF compfailed <> 0 THEN SYSTEM 1 SYSTEM 0 qberror_test: E = 1 RESUME NEXT qberror: IF ideerror THEN 'error happened inside the IDE fh = FREEFILE OPEN "internal\temp\ideerror.txt" FOR OUTPUT AS #fh PRINT #fh, ERR PRINT #fh, _ERRORLINE CLOSE #fh sendc$ = CHR$(255) 'a runtime error has occurred RESUME sendcommand 'allow IDE to handle error recovery END IF qberrorhappenedvalue = qberrorhappened qberrorhappened = 1 IF Debug THEN PRINT #9, "QB ERROR!" IF Debug THEN PRINT #9, "ERR="; ERR IF Debug THEN PRINT #9, "ERL="; ERL IF idemode AND qberrorhappenedvalue >= 0 THEN 'real qb error occurred ideerrorline = linenumber idemessage$ = "Compiler error (check for syntax errors) (Reference:" + str2$(ERR) + "-" + str2$(_ERRORLINE) + ")" IF inclevel > 0 THEN idemessage$ = idemessage$ + incerror$ RESUME ideerror END IF IF qberrorhappenedvalue >= 0 THEN a$ = "UNEXPECTED INTERNAL COMPILER ERROR!": GOTO errmes 'internal comiler error END IF qberrorcode = ERR qberrorline = ERL IF qberrorhappenedvalue = -1 THEN RESUME qberrorhappened1 IF qberrorhappenedvalue = -2 THEN RESUME qberrorhappened2 IF qberrorhappenedvalue = -3 THEN RESUME qberrorhappened3 END errmes: 'set a$ to message IF Error_Happened THEN a$ = Error_Message: Error_Happened = 0 layout$ = "": layoutok = 0 'invalidate layout IF inclevel > 0 THEN a$ = a$ + incerror$ IF idemode THEN ideerrorline = linenumber idemessage$ = a$ GOTO ideerror 'infinitely preferable to RESUME END IF 'non-ide mode output PRINT PRINT a$ FOR i = 1 TO LEN(linefragment) IF MID$(linefragment, i, 1) = sp$ THEN MID$(linefragment, i, 1) = " " NEXT FOR i = 1 TO LEN(wholeline) IF MID$(wholeline, i, 1) = sp$ THEN MID$(wholeline, i, 1) = " " NEXT PRINT "Caused by (or after):" + linefragment PRINT "LINE " + str2(linenumber) + ":" + wholeline IF UpdateHandle THEN ideupdatetimerval = TIMER DO UNTIL ABS(TIMER - ideupdatetimerval) >= 3 ContinueDownloads IF DL(UpdateHandle).State = 2 THEN 'download complete update 3 UpdateHandle = 0 GOTO qb64updated2 END IF _LIMIT 10 LOOP CLOSE DL(UpdateHandle).Handle: DL(UpdateHandle).State = 0: UpdateHandle = 0 qb64updated2: END IF 'updatehandle IF ConsoleMode THEN SYSTEM 1 END 1 FUNCTION Type2MemTypeValue (t1) t = 0 IF t1 AND ISARRAY THEN t = t + 65536 IF t1 AND ISUDT THEN IF (t1 AND 511) = 1 THEN t = t + 4096 '_MEM type ELSE t = t + 32768 END IF ELSE IF t1 AND ISSTRING THEN t = t + 512 'string ELSE IF t1 AND ISFLOAT THEN t = t + 256 'float ELSE t = t + 128 'integer IF t1 AND ISUNSIGNED THEN t = t + 1024 IF t1 AND ISOFFSET THEN t = t + 8192 'offset type END IF t1s = (t1 AND 511) \ 8 IF t1s = 1 THEN t = t + t1s IF t1s = 2 THEN t = t + t1s IF t1s = 4 THEN t = t + t1s IF t1s = 8 THEN t = t + t1s IF t1s = 16 THEN t = t + t1s IF t1s = 32 THEN t = t + t1s IF t1s = 64 THEN t = t + t1s END IF END IF Type2MemTypeValue = t END FUNCTION FUNCTION FileHasExtension (f$) FOR i = LEN(f$) TO 1 STEP -1 a = ASC(f$, i) IF a = 47 OR a = 92 THEN EXIT FOR IF a = 46 THEN FileHasExtension = -1: EXIT FUNCTION NEXT END FUNCTION FUNCTION RemoveFileExtension$ (f$) 'returns f$ without extension FOR i = LEN(f$) TO 1 STEP -1 a = ASC(f$, i) IF a = 47 OR a = 92 THEN EXIT FOR IF a = 46 THEN RemoveFileExtension$ = LEFT$(f$, i - 1): EXIT FUNCTION NEXT RemoveFileExtension$ = f$ END FUNCTION SUB ideASCIIbox 'IF INSTR(_OS$, "WIN") THEN ret% = SHELL("internal\ASCII-Picker.exe") ELSE ret% = SHELL("internal/ASCII-Picker") w = _WIDTH: h = _HEIGHT temp = _NEWIMAGE(640, 480, 32) temp1 = _NEWIMAGE(640, 480, 32) ws = _NEWIMAGE(640, 480, 32) SCREEN temp DIM CurrentASC(1 TO 16, 1 TO 16) DIM CurrentOne AS INTEGER CLS , _RGB(100, 0, 200) COLOR , _RGB(100, 0, 200) FOR x = 1 TO 16 FOR y = 1 TO 16 LINE (x * 40, 0)-(x * 40, 480), _RGB32(255, 255, 0) LINE (0, y * 30)-(640, y * 30), _RGB32(255, 255, 0) IF counter THEN _PRINTSTRING (x * 40 - 28, y * 30 - 23), CHR$(counter) counter = counter + 1 NEXT NEXT _DEST temp1 CLS , _RGB(100, 0, 200) COLOR , _RGB(100, 0, 200) counter = 0 FOR x = 1 TO 16 FOR y = 1 TO 16 LINE (x * 40, 0)-(x * 40, 480), _RGB32(255, 255, 0) LINE (0, y * 30)-(640, y * 30), _RGB32(255, 255, 0) text$ = LTRIM$(STR$(counter)) IF counter THEN _PRINTSTRING (x * 40 - 24 - (LEN(text$)) * 4, y * 30 - 23), text$ counter = counter + 1 NEXT NEXT _DEST temp x = 1: y = 1 _PUTIMAGE , temp, ws DO: LOOP WHILE _MOUSEINPUT 'clear the mouse input buffer oldmousex = _MOUSEX: oldmousey = _MOUSEY DO _LIMIT 60 DO: LOOP WHILE _MOUSEINPUT x = _MOUSEX \ 40 + 1 'If mouse moved, where are we now? y = _MOUSEY \ 30 + 1 num = (x - 1) * 16 + y - 1 IF num = 0 THEN text$ = "" ELSE flashcounter = flashcounter + 1 IF flashcounter > 30 THEN COLOR _RGB32(255, 255, 255), _RGB(100, 0, 200) text$ = CHR$(num) IF LEN(text$) = 1 THEN text$ = " " + text$ + " " ELSE COLOR _RGB32(255, 0, 0), _RGB(100, 0, 200) text$ = RTRIM$(LTRIM$(STR$(num))) END IF END IF IF flashcounter = 60 THEN flashcounter = 1 CLS IF toggle THEN _PUTIMAGE , temp1, temp ELSE _PUTIMAGE , ws, temp _PRINTSTRING (x * 40 - 24 - (LEN(text$)) * 4, y * 30 - 23), text$ LINE (x * 40 - 40, y * 30 - 30)-(x * 40, y * 30), _RGBA32(255, 255, 255, 150), BF k1 = _KEYHIT SELECT CASE k1 CASE 13: EXIT DO CASE 27 _AUTODISPLAY SCREEN 0: WIDTH w, h: _DEST 0: _DELAY .2 IF _RESIZE THEN donothing = atall EXIT SUB CASE 32: toggle = NOT toggle CASE 18432: y = y - 1 CASE 19200: x = x - 1 CASE 20480: y = y + 1 CASE 19712: x = x + 1 END SELECT IF x < 1 THEN x = 1 IF x > 16 THEN x = 16 IF y < 1 THEN y = 1 IF y > 16 THEN y = 16 _DISPLAY LOOP UNTIL _MOUSEBUTTON(1) ret% = (x - 1) * 16 + y - 1 IF ret% > 0 AND ret% < 255 THEN l = idecy a$ = idegetline(l) l$ = LEFT$(a$, idecx - 1): r$ = RIGHT$(a$, LEN(a$) - idecx + 1) text$ = l$ + CHR$(ret%) + r$ textlen = LEN(text$) l$ = LEFT$(idet$, ideli - 1) m$ = MKL$(textlen) + text$ + MKL$(textlen) r$ = RIGHT$(idet$, LEN(idet$) - ideli - LEN(a$) - 7) idet$ = l$ + m$ + r$ idecx = idecx + 1 END IF _AUTODISPLAY SCREEN 0: WIDTH w, h: _DEST 0: _DELAY .2 IF _RESIZE THEN donothing = atall END FUNCTION FUNCTION idef1box$ (lnks$, lnks) '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- '72,19 i = 0 idepar p, 40, lnks + 3, "F1" i = i + 1 o(i).typ = 2 o(i).y = 1 '68 o(i).w = 36: o(i).h = lnks o(i).txt = idenewtxt(lnks$) o(i).sel = 1 o(i).nam = idenewtxt("Which?") i = i + 1 o(i).typ = 3 o(i).y = lnks + 3 o(i).txt = idenewtxt("#OK") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(13) OR (focus = 2 AND info <> 0) OR (info = 1 AND focus = 1) THEN f$ = idetxt(o(1).stx) idef1box$ = f$ EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION Back2BackName$ (a$) IF a$ = "Keyword Reference - Alphabetical" THEN Back2BackName$ = "Alphabetical": EXIT FUNCTION IF a$ = "Keyword Reference - By usage" THEN Back2BackName$ = "By Usage": EXIT FUNCTION IF a$ = "QB64 Help Menu" THEN Back2BackName$ = "Help": EXIT FUNCTION IF a$ = "QB64 FAQ" THEN Back2BackName$ = "FAQ": EXIT FUNCTION Back2BackName$ = a$ END FUNCTION FUNCTION Wiki$ (PageName$) Help_PageLoaded$ = PageName$ PageName2$ = PageName$ DO WHILE INSTR(PageName2$, " ") ASC(PageName2$, INSTR(PageName2$, " ")) = 95 LOOP DO WHILE INSTR(PageName2$, "&") i = INSTR(PageName2$, "&") PageName2$ = LEFT$(PageName2$, i - 1) + "%26" + RIGHT$(PageName2$, LEN(PageName2$) - i) LOOP DO WHILE INSTR(PageName2$, "/") i = INSTR(PageName2$, "/") PageName2$ = LEFT$(PageName2$, i - 1) + "%2F" + RIGHT$(PageName2$, LEN(PageName2$) - i) LOOP 'Is this page in the cache? IF Help_IgnoreCache = 0 THEN IF _FILEEXISTS(Cache_Folder$ + "/" + PageName2$ + ".txt") THEN fh = FREEFILE OPEN Cache_Folder$ + "/" + PageName2$ + ".txt" FOR BINARY AS #fh a$ = SPACE$(LOF(fh)) GET #fh, , a$ CLOSE #fh Wiki$ = a$ EXIT FUNCTION END IF END IF IF Help_Recaching = 0 THEN a$ = "Downloading '" + PageName$ + "' page..." IF LEN(a$) > 60 THEN a$ = LEFT$(a$, 57) + "úúú" IF LEN(a$) < 60 THEN a$ = a$ + SPACE$(60 - LEN(a$)) COLOR 0, 3: LOCATE idewy + idesubwindow, 2 PRINT a$; PCOPY 3, 0 END IF url$ = "www.qb64.net/wiki/index.php?title=" + PageName2$ + "&action=edit" url2$ = url$ x = INSTR(url2$, "/") IF x THEN url2$ = LEFT$(url$, x - 1) c = _OPENCLIENT("TCP/IP:80:" + url2$) IF c = 0 THEN EXIT FUNCTION e$ = CHR$(13) + CHR$(10) url3$ = RIGHT$(url$, LEN(url$) - x + 1) x$ = "GET " + url3$ + " HTTP/1.1" + e$ x$ = x$ + "Host: " + url2$ + e$ + e$ PUT #c, , x$ t! = TIMER DO _DELAY 0.1 GET #c, , a2$ IF LEN(a2$) THEN a$ = a$ + a2$ IF INSTR(a$, "") THEN CLOSE #c s1$ = "readonly=" + CHR$(34) + "readonly" + CHR$(34) + ">" s2$ = "" s1 = INSTR(a$, s1$): IF s1 = 0 THEN EXIT FUNCTION s1 = s1 + LEN(s1$) s2 = INSTR(a$, s2$): IF s2 = 0 THEN EXIT FUNCTION s2 = s2 - 1 IF s1 > s2 THEN EXIT FUNCTION a$ = MID$(a$, s1, s2 - s1 + 1) fh = FREEFILE E = 0 ON ERROR GOTO qberror_test OPEN Cache_Folder$ + "/" + PageName2$ + ".txt" FOR OUTPUT AS #fh 'clear old content ON ERROR GOTO qberror IF E = 0 THEN CLOSE #fh ON ERROR GOTO qberror_test OPEN Cache_Folder$ + "/" + PageName2$ + ".txt" FOR BINARY AS #fh ON ERROR GOTO qberror IF E = 0 THEN PUT #fh, , a$ CLOSE #fh END IF END IF Wiki$ = a$ EXIT FUNCTION END IF END IF LOOP UNTIL ABS(TIMER - t!) > 20 CLOSE #c END FUNCTION SUB Help_AddTxt (t$, col, link) IF t$ = CHR$(13) THEN Help_NewLine: EXIT SUB FOR i = 1 TO LEN(t$) c = ASC(t$, i) IF Help_BG_Col = 0 AND Help_LockWrap = 0 THEN 'addtxt handles all wrapping issues IF c = 32 THEN IF Help_Pos = Help_ww THEN Help_NewLine: GOTO special Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = 32 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = col + Help_BG_Col * 16 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = link AND 255 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = link \ 256 Help_Wrap_Pos = Help_Txt_Len 'pos to backtrack to when wrapping content Help_Pos = Help_Pos + 1 GOTO special END IF IF Help_Pos > Help_ww THEN IF Help_Wrap_Pos THEN 'attempt to wrap 'backtrack, insert new line, continue b$ = MID$(Help_Txt$, Help_Wrap_Pos + 1, Help_Txt_Len - Help_Wrap_Pos) Help_Txt_Len = Help_Wrap_Pos Help_NewLine MID$(Help_Txt$, Help_Txt_Len + 1, LEN(b$)) = b$: Help_Txt_Len = Help_Txt_Len + LEN(b$) Help_Pos = Help_Pos + LEN(b$) \ 4 END IF END IF END IF 'bg_col=0 c = ASC(t$, i) Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = c Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = col + Help_BG_Col * 16 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = link AND 255 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = link \ 256 Help_Pos = Help_Pos + 1 special: NEXT END SUB SUB Help_NewLine IF Help_Pos > help_w THEN help_w = Help_Pos Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = 13 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = col + Help_BG_Col * 16 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = 0 Help_Txt_Len = Help_Txt_Len + 1: ASC(Help_Txt$, Help_Txt_Len) = 0 help_h = help_h + 1 Help_Line$ = Help_Line$ + MKL$(Help_Txt_Len + 1) Help_Wrap_Pos = 0 IF Help_Underline THEN Help_Underline = 0 w = Help_Pos Help_Pos = 1 Help_AddTxt STRING$(w - 1, 196), Help_Col, 0 Help_NewLine END IF Help_Pos = 1 IF Help_NewLineIndent THEN Help_AddTxt SPACE$(Help_NewLineIndent), Help_Col, 0 END IF END SUB SUB Help_PreView OPEN "help_preview.txt" FOR OUTPUT AS #1 FOR i = 1 TO LEN(Help_Txt$) STEP 4 c = ASC(Help_Txt$, i) c$ = CHR$(c) IF c = 13 THEN c$ = CHR$(13) + CHR$(10) PRINT #1, c$; NEXT CLOSE #1 CLS FOR i = 1 TO LEN(Help_Txt$) STEP 4 c = ASC(Help_Txt$, i) col = ASC(Help_Txt$, i + 1) IF c = 13 THEN COLOR col AND 15, col \ 16 PRINT SPACE$(help_w - POS(0)); COLOR 7, 0 PRINT SPACE$(_WIDTH - POS(0) + 1); COLOR col AND 15, col \ 16 SLEEP ELSE COLOR col AND 15, col \ 16 PRINT CHR$(c); END IF NEXT END SUB FUNCTION Help_Col 'helps to calculate the default color col = Help_Col_Normal IF Help_Italic THEN col = Help_Col_Italic IF Help_Bold THEN col = Help_Col_Bold 'Note: Bold overrides italic Help_Col = col END FUNCTION SUB WikiParse (a$) 'PRINT "Parsing...": _DISPLAY 'wiki page interpret 'clear info help_h = 0: help_w = 0: Help_Line$ = "": Help_Link$ = "": Help_LinkN = 0 Help_Txt$ = SPACE$(1000000) Help_Txt_Len = 0 Help_Pos = 1: Help_Wrap_Pos = 0 Help_Line$ = MKL$(1) Help_LockWrap = 0 Help_Bold = 0: Help_Italic = 0 Help_Underline = 0 Help_BG_Col = 0 link = 0: elink = 0: cb = 0 col = Help_Col 'Syntax Notes: ' '''=bold ' ''=italic ' {{macroname|macroparam}} or simply {{macroname}} ' eg. {{KW|PRINT}}=a key word, a link to a page ' {{Cl|PRINT}}=a key word in a code example, will be printed in bold and aqua ' {{Parameter|expression}}=a parameter, in italics ' {{PageSyntax}} {{PageDescription}} {{PageExamples}} ' {{CodeStart}} {{CodeEnd}} {{OutputStart}} {{OutputEnd}} ' {{PageSeeAlso}} {{PageNavigation}} ' [[SPACE$]]=a link to wikipage called "SPACE$" ' [[INTEGER|integer]]=a link, link's name is on left and text to appear is on right ' *=a dot point ' **=a sub(ie. further indented) dot point ' "=a quotation mark ' :=indent (if beginning a new line) ' CHR$(10)=new line character DIM c$(16) FOR ii = 1 TO 16 c$(ii) = SPACE$(ii) NEXT n = LEN(a$) i = 1 DO WHILE i <= n c = ASC(a$, i): c$ = CHR$(c) FOR i1 = 1 TO 16 ii = i FOR i2 = 1 TO i1 IF ii < n THEN ASC(c$(i1), i2) = ASC(a$, ii) ELSE ASC(c$(i1), i2) = 32 END IF ii = ii + 1 NEXT NEXT IF c = 38 THEN '"&" s$ = "<code>": IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1: GOTO Special s$ = "</code>": IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1: GOTO Special s$ = """ IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 c$ = CHR$(34): c = ASC(c$) GOTO SpecialChr END IF s$ = "&" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 c$ = "&": c = ASC(c$) GOTO SpecialChr END IF s$ = "<center>" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 GOTO Special END IF s$ = "</center>" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 GOTO Special END IF s$ = "<p style=" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 FOR ii = i TO LEN(a$) - 3 IF MID$(a$, ii, 4) = ">" THEN i = ii + 3: EXIT FOR NEXT GOTO Special END IF s$ = "</p" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 FOR ii = i TO LEN(a$) - 3 IF MID$(a$, ii, 4) = ">" THEN i = ii + 3: EXIT FOR NEXT GOTO Special END IF s$ = ">" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 c$ = ">": c = ASC(c$) GOTO SpecialChr END IF s$ = "<" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 c$ = "<": c = ASC(c$) GOTO SpecialChr END IF IF c$(2) = CHR$(194) + CHR$(160) THEN 'some kind of white-space formatting unicode combo i = i + 1 GOTO Special END IF SpecialChr: END IF 'c=38 '"&" 'Links IF c = 91 THEN '"[" IF c$(2) = "[[" AND link = 0 THEN i = i + 1 link = 1 link$ = "" GOTO Special END IF END IF IF link = 1 THEN IF c$(2) = "]]" OR c$(2) = "}}" THEN i = i + 1 link = 0 text$ = link$ i2 = INSTR(link$, "|") IF i2 THEN text$ = RIGHT$(link$, LEN(link$) - i2) link$ = LEFT$(link$, i2 - 1) END IF IF INSTR(link$, "#") THEN 'local page links not supported yet Help_AddTxt text$, 8, 0 GOTO Special END IF Help_LinkN = Help_LinkN + 1 Help_Link$ = Help_Link$ + "PAGE:" + link$ + Help_Link_Sep$ IF Help_BG_Col = 0 THEN Help_AddTxt text$, Help_Col_Link, Help_LinkN ELSE Help_AddTxt text$, Help_Col_Bold, Help_LinkN END IF GOTO Special END IF link$ = link$ + c$ GOTO Special END IF 'External links IF c = 91 THEN '"[" IF c$(6) = "[http:" AND elink = 0 THEN elink = 2 elink$ = "" GOTO Special END IF END IF IF elink = 2 THEN IF c$ = " " THEN elink = 1 GOTO Special END IF elink$ = elink$ + c$ GOTO Special END IF IF elink >= 1 THEN IF c$ = "]" THEN elink = 0 elink$ = " " + elink$ Help_LockWrap = 1: Help_Wrap_Pos = 0 Help_AddTxt elink$, 8, 0 Help_LockWrap = 0 elink$ = "" GOTO Special END IF END IF IF c = 123 THEN '"{" IF c$(5) = "{{KW|" THEN 'this is really a link! i = i + 4 link = 1 link$ = "" GOTO Special END IF IF c$(5) = "{{Cl|" THEN 'this is really a link too (in code example) i = i + 4 link = 1 link$ = "" GOTO Special END IF IF c$(2) = "{{" THEN i = i + 1 cb = 1 cb$ = "" GOTO Special END IF END IF IF cb = 1 THEN IF c$ = "|" OR c$(2) = "}}" THEN IF c$(2) = "}}" THEN i = i + 1 cb = 0 IF cb$ = "PageSyntax" THEN Help_AddTxt "Syntax:" + CHR$(13), Help_Col_Section, 0 IF cb$ = "PageDescription" THEN Help_AddTxt "Descripton:" + CHR$(13), Help_Col_Section, 0 IF cb$ = "PageExamples" THEN Help_AddTxt "Code Examples:" + CHR$(13), Help_Col_Section, 0 IF cb$ = "PageSeeAlso" THEN Help_AddTxt "See also:" + CHR$(13), Help_Col_Section, 0 IF cb$ = "CodeStart" THEN Help_NewLine Help_BG_Col = 1 'Skip non-meaningful content before section begins ws = 1 FOR ii = i + 1 TO LEN(a$) IF ASC(a$, ii) = 10 THEN EXIT FOR IF ASC(a$, ii) <> 32 AND ASC(a$, ii) <> 39 THEN ws = 0 NEXT IF ws THEN i = ii END IF IF cb$ = "CodeEnd" THEN Help_BG_Col = 0 IF cb$ = "OutputStart" THEN Help_NewLine Help_BG_Col = 2 'Skip non-meaningful content before section begins ws = 1 FOR ii = i + 1 TO LEN(a$) IF ASC(a$, ii) = 10 THEN EXIT FOR IF ASC(a$, ii) <> 32 AND ASC(a$, ii) <> 39 THEN ws = 0 NEXT IF ws THEN i = ii END IF IF cb$ = "OutputEnd" THEN Help_BG_Col = 0 GOTO Special END IF cb$ = cb$ + c$ 'reading maro name GOTO Special END IF 'cb=1 IF c$(2) = "}}" THEN 'probably the end of a text section of macro'd text i = i + 1 GOTO Special END IF IF c$(4) = " == " THEN i = i + 3 Help_Underline = 1 GOTO Special END IF IF c$(3) = "== " THEN i = i + 2 Help_Underline = 1 GOTO Special END IF IF c$(3) = " ==" THEN i = i + 2 GOTO Special END IF IF c$(2) = "==" THEN i = i + 1 Help_Underline = 1 GOTO Special END IF IF c$(3) = "'''" THEN i = i + 2 IF Help_Bold = 0 THEN Help_Bold = 1 ELSE Help_Bold = 0 col = Help_Col GOTO Special END IF IF c$(2) = "''" THEN i = i + 1 IF Help_Italic = 0 THEN Help_Italic = 1 ELSE Help_Italic = 0 col = Help_Col GOTO Special END IF IF nl = 1 THEN IF c$(3) = "** " THEN i = i + 2 Help_AddTxt " þ ", col, 0 Help_NewLineIndent = Help_NewLineIndent + 6 GOTO Special END IF IF c$(2) = "* " THEN i = i + 1 Help_AddTxt "þ ", col, 0 Help_NewLineIndent = Help_NewLineIndent + 2 GOTO Special END IF IF c$(2) = "**" THEN i = i + 1 Help_AddTxt " þ ", col, 0 Help_NewLineIndent = Help_NewLineIndent + 6 GOTO Special END IF IF c$ = "*" THEN Help_AddTxt "þ ", col, 0 Help_NewLineIndent = Help_NewLineIndent + 2 GOTO Special END IF END IF s$ = "{|" IF c$(LEN(s$)) = s$ THEN i = i + 1 FOR ii = i TO LEN(a$) - 1 IF MID$(a$, ii, 2) = "|}" THEN i = ii + 1: EXIT FOR NEXT GOTO Special END IF IF c$(3) = CHR$(226) + CHR$(128) + CHR$(166) THEN '... i = i + 2 Help_AddTxt "...", col, 0 GOTO Special END IF IF c$ = CHR$(226) THEN 'UNICODE UTF8 extender "â", it's a very good bet the following 2 characters will be 2 bytes of UNICODE i = i + 2 GOTO Special END IF IF c$ = ":" AND nl = 1 THEN Help_AddTxt " ", col, 0 Help_NewLineIndent = Help_NewLineIndent + 4 i = i + 1: GOTO special2 END IF s$ = "__NOTOC__" + CHR$(10) IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 GOTO Special END IF s$ = "__NOTOC__" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 GOTO Special END IF s$ = "<div" IF c$(LEN(s$)) = s$ THEN i = i + LEN(s$) - 1 FOR ii = i TO LEN(a$) - 1 IF MID$(a$, ii, 12) = "</div>" THEN i = ii + 11: EXIT FOR NEXT GOTO Special END IF IF c$(4) = "----" THEN i = i + 3 Help_AddTxt "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ", 8, 0 GOTO Special END IF IF c$ = CHR$(10) THEN Help_NewLineIndent = 0 IF Help_Txt_Len >= 8 THEN IF ASC(Help_Txt$, Help_Txt_Len - 3) = 13 AND ASC(Help_Txt$, Help_Txt_Len - 7) = 13 THEN GOTO skipdoubleblanks END IF Help_AddTxt CHR$(13), col, 0 skipdoubleblanks: nl = 1 i = i + 1: GOTO special2 END IF Help_AddTxt CHR$(c), col, 0 Special: i = i + 1 nl = 0 special2: LOOP 'Trim Help_Txt$ Help_Txt$ = LEFT$(Help_Txt$, Help_Txt_Len) + CHR$(13) 'chr13 stops reads past end of content 'generate preview file 'OPEN "help_preview.txt" FOR OUTPUT AS #1 'FOR i = 1 TO LEN(Help_Txt$) STEP 4 ' c = ASC(Help_Txt$, i) ' c$ = CHR$(c) ' IF c = 13 THEN c$ = CHR$(13) + CHR$(10) ' PRINT #1, c$; 'NEXT 'CLOSE #1 'PRINT "Finished parsing!": _DISPLAY IF Help_PageLoaded$ = "Keyword Reference - Alphabetical" THEN fh = FREEFILE OPEN "internal\help\links.bin" FOR OUTPUT AS #fh a$ = SPACE$(1000) FOR cy = 1 TO help_h 'isolate and REVERSE select link l = CVL(MID$(Help_Line$, (cy - 1) * 4 + 1, 4)) x = l x2 = 1 c = ASC(Help_Txt$, x) oldlnk = 0 lnkx1 = 0: lnkx2 = 0 DO UNTIL c = 13 ASC(a$, x2) = c lnk = CVI(MID$(Help_Txt$, x + 2, 2)) IF oldlnk = 0 AND lnk <> 0 THEN lnkx1 = x2 IF (lnk = 0 OR ASC(Help_Txt$, x + 4) = 13) AND lnkx1 <> 0 THEN lnkx2 = x2: IF lnk = 0 THEN lnkx2 = lnkx2 - 1 IF lnkx1 <> 3 THEN GOTO ignorelink IF ASC(a$, 1) <> 254 THEN GOTO ignorelink 'retrieve lnk info lnk2 = lnk: IF lnk2 = 0 THEN lnk2 = oldlnk l1 = 1 FOR lx = 1 TO lnk2 - 1 l1 = INSTR(l1, Help_Link$, Help_Link_Sep$) + 1 NEXT l2 = INSTR(l1, Help_Link$, Help_Link_Sep$) - 1 l$ = MID$(Help_Link$, l1, l2 - l1 + 1) 'assume PAGE l$ = RIGHT$(l$, LEN(l$) - 5) a2$ = MID$(a$, lnkx1, lnkx2 - lnkx1 + 1) IF INSTR(a2$, "(") THEN a2$ = LEFT$(a2$, INSTR(a2$, "(") - 1) IF INSTR(a2$, " ") THEN a2$ = LEFT$(a2$, INSTR(a2$, " ") - 1) IF INSTR(a2$, "...") THEN a3$ = RIGHT$(a2$, LEN(a2$) - INSTR(a2$, "...") - 2) skip = 0 IF UCASE$(LEFT$(a3$, 3)) <> "_GL" THEN FOR ci = 1 TO LEN(a3$) ca = ASC(a3$, ci) IF ca >= 97 AND ca <= 122 THEN skip = 1 IF ca = 44 THEN skip = 1 NEXT END IF IF skip = 0 THEN PRINT #fh, a3$ + "," + l$ a2$ = LEFT$(a2$, INSTR(a2$, "...") - 1) END IF skip = 0 IF UCASE$(LEFT$(a2$, 3)) <> "_GL" THEN FOR ci = 1 TO LEN(a2$) ca = ASC(a2$, ci) IF ca >= 97 AND ca <= 122 THEN skip = 1 IF ca = 44 THEN skip = 1 NEXT END IF IF skip = 0 THEN PRINT #fh, a2$ + "," + l$ oa2$ = a2$ a2$ = l$ IF INSTR(a2$, "(") THEN a2$ = LEFT$(a2$, INSTR(a2$, "(") - 1) IF INSTR(a2$, " ") THEN a2$ = LEFT$(a2$, INSTR(a2$, " ") - 1) IF INSTR(a2$, "...") THEN a3$ = RIGHT$(a2$, LEN(a2$) - INSTR(a2$, "...") - 2) skip = 0 IF UCASE$(LEFT$(a3$, 3)) <> "_GL" THEN FOR ci = 1 TO LEN(a3$) ca = ASC(a3$, ci) IF ca >= 97 AND ca <= 122 THEN skip = 1 IF ca = 44 THEN skip = 1 NEXT END IF IF skip = 0 THEN PRINT #fh, a3$ + "," + l$ a2$ = LEFT$(a2$, INSTR(a2$, "...") - 1) END IF skip = 0 IF UCASE$(LEFT$(a2$, 3)) <> "_GL" THEN FOR ci = 1 TO LEN(a2$) ca = ASC(a2$, ci) IF ca >= 97 AND ca <= 122 THEN skip = 1 IF ca = 44 THEN skip = 1 NEXT END IF IF skip = 0 AND a2$ <> oa2$ THEN PRINT #fh, a2$ + "," + l$ ignorelink: lnkx1 = 0: lnkx2 = 0 END IF x = x + 4: c = ASC(Help_Txt$, x) x2 = x2 + 1 oldlnk = lnk LOOP NEXT CLOSE #fh END IF END SUB FUNCTION idesearchedbox$ '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- ln = 0 l$ = "" fh = FREEFILE OPEN ".\internal\temp\searched.bin" FOR BINARY AS #fh: a$ = SPACE$(LOF(fh)): GET #fh, , a$ a$ = RIGHT$(a$, LEN(a$) - 2) DO WHILE LEN(a$) ai = INSTR(a$, crlf) IF ai THEN f$ = LEFT$(a$, ai - 1): IF ai = LEN(a$) - 1 THEN a$ = "" ELSE a$ = RIGHT$(a$, LEN(a$) - ai - 3) IF LEN(l$) THEN l$ = l$ + sep + f$ ELSE l$ = f$ ln = ln + 1 END IF LOOP CLOSE #fh '72,19 h = idewy + idesubwindow - 6 IF ln < h THEN h = ln IF h < 3 THEN h = 3 i = 0 idepar p, 20, h, "" p.x = idewx - 24 p.y = 3 i = i + 1 o(i).typ = 2 o(i).x = -1: o(i).y = 0 o(i).w = 22: o(i).h = h o(i).txt = idenewtxt(l$) o(i).sel = 1 o(i).nam = idenewtxt("Find") 'i = i + 1 'o(i).typ = 3 'o(i).y = idewy - 6 'o(i).txt = idenewtxt("#OK" + sep + "#Cancel") 'o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'quick exit IF mCLICK THEN IF mX < p.x - 1 OR mY < p.y OR mX > p.x + p.w + 2 OR mY > p.y + p.h + 1 THEN idesearchedbox$ = "" EXIT FUNCTION END IF END IF IF K$ = CHR$(27) THEN idesearchedbox$ = "" EXIT FUNCTION END IF IF mCLICK THEN IF mX > p.x - 1 AND mY > p.y AND mX < p.x + p.w + 2 AND mY < p.y + p.h + 1 THEN f$ = idetxt(o(1).stx) idesearchedbox$ = f$ EXIT FUNCTION END IF END IF IF K$ = CHR$(13) OR (info = 1 AND focus = 1) THEN f$ = idetxt(o(1).stx) idesearchedbox$ = f$ EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB IdeImportBookmarks (f2$) IdeBmkN = 0 f$ = crlf + f2$ + crlf fh = FREEFILE: OPEN ".\internal\temp\bookmarks.bin" FOR BINARY AS #fh: a$ = SPACE$(LOF(fh)): GET #fh, , a$: CLOSE #fh x = INSTR(UCASE$(a$), UCASE$(f$)) IF x THEN 'retrieve bookmark data l = CVL(MID$(a$, x + LEN(f$), 4)) x1 = x + LEN(f$) + 4 d$ = MID$(a$, x1, l) n = l \ 16 FOR i = 1 TO n by = CVL(MID$(d$, (i - 1) * 16 + 1, 4)) bx = CVL(MID$(d$, (i - 1) * 16 + 1 + 4, 4)) IF by <= iden THEN IdeBmkN = IdeBmkN + 1 IF IdeBmkN > UBOUND(IdeBmk) THEN x = UBOUND(IdeBmk) * 2: REDIM _PRESERVE IdeBmk(x) AS IdeBmkType IdeBmk(IdeBmkN).y = by IdeBmk(IdeBmkN).x = bx IdeBmk(IdeBmkN).reserved = 0: IdeBmk(IdeBmkN).reserved2 = 0 END IF NEXT END IF END SUB SUB IdeSaveBookmarks (f2$) f$ = crlf + f2$ + crlf fh = FREEFILE: OPEN ".\internal\temp\bookmarks.bin" FOR BINARY AS #fh: a$ = SPACE$(LOF(fh)): GET #fh, , a$: CLOSE #fh x = INSTR(UCASE$(a$), UCASE$(f$)) IF x THEN 'remove any old bookmark data l = CVL(MID$(a$, x + LEN(f$), 4)) x2 = x + LEN(f$) + 4 + l - 1 a$ = LEFT$(a$, x - 1) + RIGHT$(a$, LEN(a$) - x2) END IF 'add new bookmark data 'build bookmark data d$ = "" FOR i = 1 TO IdeBmkN d$ = d$ + MKL$(IdeBmk(i).y) + MKL$(IdeBmk(i).x) + MKL$(IdeBmk(i).reserved) + MKL$(IdeBmk(i).reserved2) NEXT a$ = f$ + MKL$(LEN(d$)) + d$ + a$ fh = FREEFILE: OPEN ".\internal\temp\bookmarks.bin" FOR OUTPUT AS #fh: CLOSE #fh fh = FREEFILE: OPEN ".\internal\temp\bookmarks.bin" FOR BINARY AS #fh: PUT #fh, , a$: CLOSE #fh END SUB FUNCTION iderecentbox$ '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- l$ = "" fh = FREEFILE OPEN ".\internal\temp\recent.bin" FOR BINARY AS #fh: a$ = SPACE$(LOF(fh)): GET #fh, , a$ a$ = RIGHT$(a$, LEN(a$) - 2) DO WHILE LEN(a$) ai = INSTR(a$, crlf) IF ai THEN f$ = LEFT$(a$, ai - 1): IF ai = LEN(a$) - 1 THEN a$ = "" ELSE a$ = RIGHT$(a$, LEN(a$) - ai - 3) IF LEN(l$) THEN l$ = l$ + sep + f$ ELSE l$ = f$ END IF LOOP CLOSE #fh '72,19 i = 0 idepar p, idewx - 8, idewy + idesubwindow - 6, "Open" i = i + 1 o(i).typ = 2 o(i).y = 1 '68 o(i).w = idewx - 12: o(i).h = idewy + idesubwindow - 9 o(i).txt = idenewtxt(l$) o(i).sel = 1 o(i).nam = idenewtxt("Recent Programs") i = i + 1 o(i).typ = 3 o(i).y = idewy + idesubwindow - 6 o(i).txt = idenewtxt("#OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) OR (focus = 3 AND info <> 0) THEN iderecentbox$ = "" EXIT FUNCTION END IF IF K$ = CHR$(13) OR (focus = 2 AND info <> 0) OR (info = 1 AND focus = 1) THEN f$ = idetxt(o(1).stx) iderecentbox$ = f$ EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB IdeMakeFileMenu m = 1: i = 0 menu$(m, i) = "File": i = i + 1 menu$(m, i) = "#New": i = i + 1 menu$(m, i) = "#Open...": i = i + 1 menu$(m, i) = "#Save": i = i + 1 menu$(m, i) = "Save #As...": i = i + 1 fh = FREEFILE OPEN ".\internal\temp\recent.bin" FOR BINARY AS #fh: a$ = SPACE$(LOF(fh)): GET #fh, , a$ a$ = RIGHT$(a$, LEN(a$) - 2) FOR r = 1 TO 5 IF r <= 4 THEN IdeRecentLink(r, 1) = "" ai = INSTR(a$, crlf) IF ai THEN IF r = 1 THEN menu$(m, i) = "-": i = i + 1 f$ = LEFT$(a$, ai - 1): IF ai = LEN(a$) - 1 THEN a$ = "" ELSE a$ = RIGHT$(a$, LEN(a$) - ai - 3) IF r <= 4 THEN IdeRecentLink(r, 2) = f$ IF r = 5 THEN f$ = "#Recent..." IF LEN(f$) > 25 THEN f$ = "úúú" + RIGHT$(f$, 22) IF r <= 4 THEN IdeRecentLink(r, 1) = f$ menu$(m, i) = f$: i = i + 1 END IF NEXT CLOSE #fh IF os$ = "WIN" AND AllowUpdates <> 0 THEN menu$(m, i) = "-": i = i + 1 menu$(m, i) = "#Update": i = i + 1 END IF menu$(m, i) = "-": i = i + 1 menu$(m, i) = "E#xit": i = i + 1 menusize(m) = i - 1 END SUB SUB IdeAddRecent (f2$) f$ = crlf + f2$ + crlf fh = FREEFILE OPEN ".\internal\temp\recent.bin" FOR BINARY AS #fh: a$ = SPACE$(LOF(fh)): GET #fh, , a$ x = INSTR(UCASE$(a$), UCASE$(f$)) IF x THEN a$ = f$ + LEFT$(a$, x - 1) + RIGHT$(a$, LEN(a$) - (x + LEN(f$) - 1)) ELSE a$ = f$ + a$ END IF PUT #fh, 1, a$ CLOSE #fh IdeMakeFileMenu END SUB SUB IdeAddSearched (s2$) s$ = crlf + s2$ + crlf fh = FREEFILE OPEN ".\internal\temp\searched.bin" FOR BINARY AS #fh: a$ = SPACE$(LOF(fh)): GET #fh, , a$ x = INSTR(UCASE$(a$), UCASE$(s$)) IF x THEN a$ = s$ + LEFT$(a$, x - 1) + RIGHT$(a$, LEN(a$) - (x + LEN(s$) - 1)) ELSE a$ = s$ + a$ END IF PUT #fh, 1, a$ CLOSE #fh END SUB FUNCTION allocarray (n2$, elements$, elementsize) dimsharedlast = dimshared: dimshared = 0 IF autoarray = 1 THEN autoarray = 0: autoary = 1 'clear global value & set local value f12$ = "" 'changelog: 'added 4 to [2] to indicate cmem array where appropriate e$ = elements$: n$ = n2$ IF elementsize = -2147483647 THEN stringarray = 1: elementsize = 8 IF ASC(e$) = 63 THEN '? l$ = "(" + sp2 + ")" undefined = -1 nume = 1 IF LEN(e$) = 1 THEN GOTO undefinedarray undefined = 1 nume = VAL(RIGHT$(e$, LEN(e$) - 1)) GOTO undefinedarray END IF 'work out how many elements there are (critical to later calculations) nume = 1 n = numelements(e$) FOR i = 1 TO n e2$ = getelement(e$, i) IF e2$ = "(" THEN b = b + 1 IF b = 0 AND e2$ = "," THEN nume = nume + 1 IF e2$ = ")" THEN b = b - 1 NEXT IF Debug THEN PRINT #9, "numelements count:"; nume descstatic = 0 IF arraydesc THEN IF id.arrayelements <> nume THEN IF id.arrayelements = -1 THEN 'unknown IF arrayelementslist(currentid) <> 0 AND nume <> arrayelementslist(currentid) THEN Give_Error "Cannot change the number of elements an array has!": EXIT FUNCTION IF nume = 1 THEN id.arrayelements = 1: ids(currentid).arrayelements = 1 'lucky guess! arrayelementslist(currentid) = nume ELSE Give_Error "Cannot change the number of elements an array has!": EXIT FUNCTION END IF END IF IF id.staticarray THEN descstatic = 1 END IF l$ = "(" + sp2 cr$ = CHR$(13) + CHR$(10) sd$ = "" constdimensions = 1 ei = 4 + nume * 4 - 4 cure = 1 e3$ = "": e3base$ = "" FOR i = 1 TO n e2$ = getelement(e$, i) IF e2$ = "(" THEN b = b + 1 IF (e2$ = "," AND b = 0) OR i = n THEN IF i = n THEN e3$ = e3$ + sp + e2$ e3$ = RIGHT$(e3$, LEN(e3$) - 1) IF e3base$ <> "" THEN e3base$ = RIGHT$(e3base$, LEN(e3base$) - 1) 'PRINT e3base$ + "[TO]" + e3$ 'set the base basegiven = 1 IF e3base$ = "" THEN e3base$ = str2$(optionbase + 0): basegiven = 0 constequation = 1 e3base$ = fixoperationorder$(e3base$) IF Error_Happened THEN EXIT FUNCTION IF basegiven THEN l$ = l$ + tlayout$ + sp + "TO" + sp e3base$ = evaluatetotyp$(e3base$, 64&) IF Error_Happened THEN EXIT FUNCTION IF constequation = 0 THEN constdimensions = 0 sd$ = sd$ + n$ + "[" + str2(ei) + "]=" + e3base$ + ";" + cr$ 'set the number of indexes constequation = 1 e3$ = fixoperationorder$(e3$) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + tlayout$ + sp2 IF i = n THEN l$ = l$ + ")" ELSE l$ = l$ + "," + sp e3$ = evaluatetotyp$(e3$, 64&) IF Error_Happened THEN EXIT FUNCTION IF constequation = 0 THEN constdimensions = 0 ei = ei + 1 sd$ = sd$ + n$ + "[" + str2(ei) + "]=(" + e3$ + ")-" + n$ + "[" + str2(ei - 1) + "]+1;" + cr$ ei = ei + 1 'calc muliplier IF cure = 1 THEN 'set only for the purpose of the calculating correct multipliers sd$ = sd$ + n$ + "[" + str2(ei) + "]=1;" + cr$ ELSE sd$ = sd$ + n$ + "[" + str2(ei) + "]=" + n$ + "[" + str2(ei + 4) + "]*" + n$ + "[" + str2(ei + 3) + "];" + cr$ END IF ei = ei + 1 ei = ei + 1 'skip reserved ei = ei - 8 cure = cure + 1 e3$ = "": e3base$ = "" GOTO aanexte END IF IF e2$ = ")" THEN b = b - 1 IF UCASE$(e2$) = "TO" AND b = 0 THEN e3base$ = e3$ e3$ = "" ELSE e3$ = e3$ + sp + e2$ END IF aanexte: NEXT sd$ = LEFT$(sd$, LEN(sd$) - 2) undefinedarray: 'calc cmem cmem = 0 IF arraydesc = 0 THEN IF cmemlist(idn + 1) THEN cmem = 1 ELSE IF cmemlist(arraydesc) THEN cmem = 1 END IF staticarray = constdimensions IF subfuncn <> 0 AND dimstatic = 0 THEN staticarray = 0 'arrays in SUBS/FUNCTIONS are DYNAMIC IF dimstatic = 3 THEN staticarray = 0 'STATIC arrayname() listed arrays keep thier values but are dynamic in memory IF DynamicMode THEN staticarray = 0 IF redimoption THEN staticarray = 0 IF dimoption = 3 THEN staticarray = 0 'STATIC a(100) arrays are still dynamic IF arraydesc THEN IF staticarray = 1 THEN IF descstatic THEN Give_Error "Cannot redefine a static array!": EXIT FUNCTION staticarray = 0 END IF END IF bytesperelement$ = str2(elementsize) IF elementsize < 0 THEN elementsize = -elementsize bytesperelement$ = str2(elementsize) + "/8+1" END IF 'Begin creation of array descriptor (if array has not been defined yet) IF arraydesc = 0 THEN PRINT #defdatahandle, "ptrszint *" + n$ + "=NULL;" PRINT #13, "if (!" + n$ + "){" PRINT #13, n$ + "=(ptrszint*)mem_static_malloc(" + str2(4 * nume + 4 + 1) + "*ptrsz);" '+1 is for the lock 'create _MEM lock PRINT #13, "new_mem_lock();" PRINT #13, "mem_lock_tmp->type=4;" PRINT #13, "((ptrszint*)" + n$ + ")[" + str2(4 * nume + 4 + 1 - 1) + "]=(ptrszint)mem_lock_tmp;" END IF 'generate sizestr$ & elesizestr$ (both are used in various places in following code) sizestr$ = "" FOR i = 1 TO nume IF i <> 1 THEN sizestr$ = sizestr$ + "*" sizestr$ = sizestr$ + n$ + "[" + str2(i * 4 - 4 + 5) + "]" NEXT elesizestr$ = sizestr$ 'elements in entire array sizestr$ = sizestr$ + "*" + bytesperelement$ 'bytes in entire array '------------------STATIC ARRAY CREATION-------------------------------- IF staticarray THEN 'STATIC memory PRINT #13, sd$ 'setup new array dimension ranges 'Example of sd$ for DIM a(10): '__ARRAY_SINGLE_A[4]= 0 ; '__ARRAY_SINGLE_A[5]=( 10 )-__ARRAY_SINGLE_A[4]+1; '__ARRAY_SINGLE_A[6]=1; IF cmem AND stringarray = 0 THEN 'Note: A string array's pointers are always stored in 64bit memory '(static)CONVENTINAL memory PRINT #13, n$ + "[0]=(ptrszint)cmem_static_pointer;" 'alloc mem & check if static memory boundry has oversteped dynamic memory boundry PRINT #13, "if ((cmem_static_pointer+=((" + sizestr$ + ")+15)&-16)>cmem_dynamic_base) error(257);" '64K check PRINT #13, "if ((" + sizestr$ + ")>65536) error(257);" 'clear array PRINT #13, "memset((void*)(" + n$ + "[0]),0," + sizestr$ + ");" 'set flags PRINT #13, n$ + "[2]=1+2+4;" 'init+static+cmem ELSE '64BIT MEMORY PRINT #13, n$ + "[0]=(ptrszint)mem_static_malloc(" + sizestr$ + ");" IF stringarray THEN 'Init string pointers in the array PRINT #13, "tmp_long=" + elesizestr$ + ";" PRINT #13, "while(tmp_long--){" IF cmem THEN PRINT #13, "((uint64*)(" + n$ + "[0]))[tmp_long]=(uint64)qbs_new_cmem(0,0);" ELSE PRINT #13, "((uint64*)(" + n$ + "[0]))[tmp_long]=(uint64)qbs_new(0,0);" END IF PRINT #13, "}" ELSE 'clear array PRINT #13, "memset((void*)(" + n$ + "[0]),0," + sizestr$ + ");" END IF PRINT #13, n$ + "[2]=1+2;" 'init+static END IF 'Close static array desc PRINT #13, "}" allocarray = nume + 65536 END IF '------------------END OF STATIC ARRAY CREATION------------------------- '------------------DYNAMIC ARRAY CREATION------------------------------- IF staticarray = 0 THEN IF undefined = 0 THEN 'Generate error if array is static f12$ = f12$ + crlf + "if (" + n$ + "[2]&2){" 'static array f12$ = f12$ + crlf + "error(10);" 'cannot redefine a static array! f12$ = f12$ + crlf + "}else{" 'Note: Array is either undefined or dynamically defined at this point 'REDIM (not DIM) must be used to redefine an array IF redimoption = 0 THEN f12$ = f12$ + crlf + "if (" + n$ + "[2]&1){" 'array is defined f12$ = f12$ + crlf + "error(10);" 'cannot redefine an array without using REDIM! f12$ = f12$ + crlf + "}else{" ELSE '--------ERASE EXISTING ARRAY IF NECESSARY-------- 'IMPORTANT: If array is not going to be preserved, it should be cleared before ' creating the new array for memory considerations 'refresh lock ID (_MEM) f12$ = f12$ + crlf + "((mem_lock*)((ptrszint*)" + n$ + ")[" + str2(4 * nume + 4 + 1 - 1) + "])->id=(++mem_lock_id);" IF redimoption = 2 THEN f12$ = f12$ + crlf + "static int32 preserved_elements;" 'must be put here for scope considerations END IF 'If array is defined, it must be destroyed first f12$ = f12$ + crlf + "if (" + n$ + "[2]&1){" 'array is defined IF redimoption = 2 THEN f12$ = f12$ + crlf + "preserved_elements=" + elesizestr$ + ";" GOTO skiperase END IF 'Note: pointers to strings must be freed before array can be freed IF stringarray THEN f12$ = f12$ + crlf + "tmp_long=" + elesizestr$ + ";" f12$ = f12$ + crlf + "while(tmp_long--) qbs_free((qbs*)((uint64*)(" + n$ + "[0]))[tmp_long]);" END IF 'Free array's memory IF stringarray THEN 'Note: String arrays are never in cmem f12$ = f12$ + crlf + "free((void*)(" + n$ + "[0]));" ELSE 'Note: Array may be in cmem! f12$ = f12$ + crlf + "if (" + n$ + "[2]&4){" 'array is in cmem f12$ = f12$ + crlf + "cmem_dynamic_free((uint8*)(" + n$ + "[0]));" f12$ = f12$ + crlf + "}else{" 'not in cmem f12$ = f12$ + crlf + "free((void*)(" + n$ + "[0]));" f12$ = f12$ + crlf + "}" END IF skiperase: f12$ = f12$ + crlf + "}" 'array was defined IF redimoption = 2 THEN f12$ = f12$ + crlf + "else preserved_elements=0;" 'if array wasn't defined, no elements are preserved END IF '--------ERASED ARRAY AS NECESSARY-------- END IF 'redim specified '--------CREATE ARRAY & CLEAN-UP CODE-------- 'Overwrite existing array dimension sizes/ranges f12$ = f12$ + crlf + sd$ IF stringarray THEN 'Note: String arrays are always created in 64bit memory IF redimoption = 2 THEN f12$ = f12$ + crlf + "if (preserved_elements){" f12$ = f12$ + crlf + "static ptrszint tmp_long2;" 'free any qbs strings which will be lost in the realloc f12$ = f12$ + crlf + "tmp_long=" + elesizestr$ + ";" f12$ = f12$ + crlf + "if (tmp_long 0 AND elements <> arrayelementslist(currentid) THEN Give_Error "Cannot change the number of elements an array has!": EXIT FUNCTION IF elements = 1 THEN id2.arrayelements = 1: ids(currentid).arrayelements = 1 'lucky guess arrayelementslist(currentid) = elements ELSE IF elements <> id2.arrayelements THEN Give_Error "Cannot change the number of elements an array has!": EXIT FUNCTION END IF curarg = 1 firsti = 1 FOR i = 1 TO n l$ = getelement(a$, i) IF l$ = "(" THEN b = b + 1 IF l$ = ")" THEN b = b - 1 IF (l$ = "," AND b = 0) OR (i = n) THEN IF i = n THEN IF l$ = "," THEN Give_Error "Array index missing": EXIT FUNCTION e$ = evaluatetotyp(getelements$(a$, firsti, i), 64&) IF Error_Happened THEN EXIT FUNCTION ELSE e$ = evaluatetotyp(getelements$(a$, firsti, i - 1), 64&) IF Error_Happened THEN EXIT FUNCTION END IF IF e$ = "" THEN Give_Error "Array index missing": EXIT FUNCTION argi = (elements - curarg) * 4 + 4 IF curarg = 1 THEN r$ = r$ + "array_check((" + e$ + ")-" + n$ + "[" + str2(argi) + "]," + n$ + "[" + str2(argi + 1) + "])+" ELSE r$ = r$ + "array_check((" + e$ + ")-" + n$ + "[" + str2(argi) + "]," + n$ + "[" + str2(argi + 1) + "])*" + n$ + "[" + str2(argi + 2) + "]+" END IF firsti = i + 1 curarg = curarg + 1 END IF NEXT r$ = LEFT$(r$, LEN(r$) - 1) 'remove trailing + gotarrayindex: r$ = idnumber$ + sp3 + r$ arrayreference$ = r$ 'PRINT "arrayreference returning:" + r$ END FUNCTION SUB assign (a$, n) FOR i = 1 TO n c = ASC(getelement$(a$, i)) IF c = 40 THEN b = b + 1 '( IF c = 41 THEN b = b - 1 ') IF c = 61 AND b = 0 THEN '= IF i = 1 THEN Give_Error "Expected ... =": EXIT SUB IF i = n THEN Give_Error "Expected = ...": EXIT SUB a2$ = fixoperationorder(getelements$(a$, 1, i - 1)) IF Error_Happened THEN EXIT SUB l$ = tlayout$ + sp + "=" + sp 'note: evaluating a2$ will fail if it is setting a function's return value without this check (as the function, not the return-variable) will be found by evaluate) IF i = 2 THEN 'lhs has only 1 element try = findid(a2$) IF Error_Happened THEN EXIT SUB DO WHILE try IF id.t THEN IF subfuncn = id.insubfuncn THEN 'avoid global before local IF (id.t AND ISUDT) = 0 THEN makeidrefer a2$, typ GOTO assignsimplevariable END IF END IF END IF IF try = 2 THEN findanotherid = 1: try = findid(a2$) ELSE try = 0 IF Error_Happened THEN EXIT SUB LOOP END IF a2$ = evaluate$(a2$, typ): IF Error_Happened THEN EXIT SUB assignsimplevariable: IF (typ AND ISREFERENCE) = 0 THEN Give_Error "Expected variable =": EXIT SUB setrefer a2$, typ, getelements$(a$, i + 1, n), 0 IF Error_Happened THEN EXIT SUB tlayout$ = l$ + tlayout$ EXIT SUB END IF '=,b=0 NEXT Give_Error "Expected =": EXIT SUB END SUB SUB clearid id = cleariddata END SUB SUB closemain xend IF C_Core = 0 THEN PRINT #12, "return NULL;" IF C_Core = 1 THEN PRINT #12, "return;" PRINT #12, "}" PRINT #15, "}" 'end case PRINT #15, "}" PRINT #15, "error(3);" 'no valid return possible closedmain = 1 END SUB FUNCTION countelements (a$) n = numelements(a$) c = 1 FOR i = 1 TO n e$ = getelement$(a$, i) IF e$ = "(" THEN b = b + 1 IF e$ = ")" THEN b = b - 1 IF b < 0 THEN Give_Error "Unexpected ) encountered": EXIT FUNCTION IF e$ = "," AND b = 0 THEN c = c + 1 NEXT countelements = c END FUNCTION FUNCTION dim2 (varname$, typ2$, method, elements$) 'notes: (DO NOT REMOVE THESE IMPORTANT USAGE NOTES) ' '(shared)dimsfarray: Creates an ID only (no C++ code) ' Adds an index/'link' to the sub/function's argument ' ID.sfid=glinkid ' ID.sfarg=glinkarg ' Sets arrayelements=-1 'unknown' (if elements$="?") otherwise val(elements$) ' ***Does not refer to arrayelementslist()*** ' '(argument)method: 0 being created by a DIM name AS type ' 1 being created by a DIM name+symbol ' or automatically without the use of DIM ' 'elements$="?": (see also dimsfarray for that special case) ' Checks arrayelementslist() and; ' if unknown(=0), creates an ID only ' if known, creates a DYNAMIC array's C++ initialization code so it can be used later typ$ = typ2$ dim2 = 1 'success IF Debug THEN PRINT #9, "dim2 called", method cvarname$ = varname$ l$ = cvarname$ varname$ = UCASE$(varname$) IF dimsfarray = 1 THEN f = 0 ELSE f = 1 IF dimstatic <> 0 AND dimshared = 0 THEN 'name will have include the sub/func name in its scope 'variable/array will be created in main on startup defdatahandle = 18 'change from 13 to 18(global.txt) CLOSE #13: OPEN tmpdir$ + "maindata.txt" FOR APPEND AS #13 CLOSE #19: OPEN tmpdir$ + "mainfree.txt" FOR APPEND AS #19 END IF scope2$ = module$ + "_" + subfunc$ + "_" 'Note: when REDIMing a SHARED array in dynamic memory scope2$ must be modified IF LEN(typ$) = 0 THEN Give_Error "DIM2: No type specified!": EXIT FUNCTION 'UDT 'is it a udt? FOR i = 1 TO lasttype IF typ$ = RTRIM$(udtxname(i)) THEN dim2typepassback$ = RTRIM$(udtxcname(i)) n$ = "UDT_" + varname$ 'array of UDTs IF elements$ <> "" THEN arraydesc = 0 IF f = 1 THEN try = findid(varname$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(varname$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ bits = udtxsize(i) IF udtxbytealign(i) THEN IF bits MOD 8 THEN bits = bits + 8 - (bits MOD 8) END IF IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, -bits) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = UDTTYPE + i IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY id.n = cvarname$ IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ regid IF Error_Happened THEN EXIT FUNCTION GOTO dim2exitfunc END IF 'not an array of UDTs bits = udtxsize(i): bytes = bits \ 8 IF bits MOD 8 THEN bytes = bytes + 1 END IF n$ = scope2$ + n$ IF f THEN PRINT #defdatahandle, "void *" + n$ + "=NULL;" clearid id.n = cvarname$ id.t = UDTTYPE + i IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f THEN PRINT #13, "if(" + n$ + "==NULL){" IF f THEN PRINT #13, "cmem_sp-=" + str2(bytes) + ";" IF f THEN PRINT #13, "if (cmem_sp 6 THEN IF LEFT$(typ$, 9) <> "STRING * " THEN Give_Error "Expected STRING * number/constant": EXIT FUNCTION c$ = RIGHT$(typ$, LEN(typ$) - 9) 'constant check 2011 hashfound = 0 hashname$ = c$ hashchkflags = HASHFLAG_CONSTANT hashres = HashFindRev(hashname$, hashchkflags, hashresflags, hashresref) DO WHILE hashres IF constsubfunc(hashresref) = subfuncn OR constsubfunc(hashresref) = 0 THEN IF constdefined(hashresref) THEN hashfound = 1 EXIT DO END IF END IF IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP IF hashfound THEN i2 = hashresref t = consttype(i2) IF t AND ISSTRING THEN Give_Error "Expected STRING * numeric-constant": EXIT FUNCTION 'convert value to general formats IF t AND ISFLOAT THEN v## = constfloat(i2) v&& = v## v~&& = v&& ELSE IF t AND ISUNSIGNED THEN v~&& = constuinteger(i2) v&& = v~&& v## = v&& ELSE v&& = constinteger(i2) v## = v&& v~&& = v&& END IF END IF IF v&& < 1 OR v&& > 9999999999 THEN Give_Error "STRING * out-of-range constant": EXIT FUNCTION bytes = v&& GOTO constantlenstr END IF IF isuinteger(c$) = 0 THEN Give_Error "Number/Constant expected after *": EXIT FUNCTION IF LEN(c$) > 10 THEN Give_Error "Too many characters in number after *": EXIT FUNCTION bytes = VAL(c$) IF bytes = 0 THEN Give_Error "Cannot create a fixed string of length 0": EXIT FUNCTION constantlenstr: n$ = "STRING" + str2(bytes) + "_" + varname$ 'array of fixed length strings IF elements$ <> "" THEN arraydesc = 0 IF f = 1 THEN try = findid(varname$ + "$") IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(varname$ + "$") ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, bytes) 'IF arraydesc THEN goto dim2exitfunc 'id already exists! 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, bytes) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = STRINGTYPE + ISFIXEDLENGTH IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY id.n = cvarname$ IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ id.tsize = bytes IF method = 0 THEN id.mayhave = "$" + str2(bytes) END IF IF method = 1 THEN id.musthave = "$" + str2(bytes) END IF regid IF Error_Happened THEN EXIT FUNCTION GOTO dim2exitfunc END IF 'standard fixed length string n$ = scope2$ + n$ IF f THEN PRINT #defdatahandle, "qbs *" + n$ + "=NULL;" IF f THEN PRINT #19, "qbs_free(" + n$ + ");" 'so descriptor can be freed clearid id.n = cvarname$ id.t = STRINGTYPE + ISFIXEDLENGTH IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f THEN PRINT #13, "if(" + n$ + "==NULL){" IF f THEN PRINT #13, "cmem_sp-=" + str2(bytes) + ";" IF f THEN PRINT #13, "if (cmem_spchr,0," + str2(bytes) + ");" IF f THEN PRINT #13, "}" ELSE IF f THEN PRINT #13, "if(" + n$ + "==NULL){" o$ = "(uint8*)mem_static_malloc(" + str2$(bytes) + ")" IF f THEN PRINT #13, n$ + "=qbs_new_fixed(" + o$ + "," + str2$(bytes) + ",0);" IF f THEN PRINT #13, "memset(" + n$ + "->chr,0," + str2$(bytes) + ");" IF f THEN PRINT #13, "}" END IF id.tsize = bytes IF method = 0 THEN id.mayhave = "$" + str2(bytes) END IF IF method = 1 THEN id.musthave = "$" + str2(bytes) END IF regid IF Error_Happened THEN EXIT FUNCTION GOTO dim2exitfunc END IF 'variable length string processing n$ = "STRING_" + varname$ 'array of variable length strings IF elements$ <> "" THEN arraydesc = 0 IF f = 1 THEN try = findid(varname$ + "$") IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(varname$ + "$") ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, -2147483647) '-2147483647=STRING 'IF arraydesc THEN goto dim2exitfunc 'id already exists! 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, -2147483647) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.n = cvarname$ id.arraytype = STRINGTYPE IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ IF method = 0 THEN id.mayhave = "$" END IF IF method = 1 THEN id.musthave = "$" END IF regid IF Error_Happened THEN EXIT FUNCTION GOTO dim2exitfunc END IF 'standard variable length string n$ = scope2$ + n$ clearid id.n = cvarname$ id.t = STRINGTYPE IF cmemlist(idn + 1) THEN IF f THEN PRINT #defdatahandle, "qbs *" + n$ + "=NULL;" IF f THEN PRINT #13, "if (!" + n$ + ")" + n$ + "=qbs_new_cmem(0,0);" id.t = id.t + ISINCONVENTIONALMEMORY ELSE IF f THEN PRINT #defdatahandle, "qbs *" + n$ + "=NULL;" IF f THEN PRINT #13, "if (!" + n$ + ")" + n$ + "=qbs_new(0,0);" END IF IF f THEN PRINT #19, "qbs_free(" + n$ + ");" IF method = 0 THEN id.mayhave = "$" END IF IF method = 1 THEN id.musthave = "$" END IF regid IF Error_Happened THEN EXIT FUNCTION GOTO dim2exitfunc END IF IF LEFT$(typ$, 4) = "_BIT" THEN IF LEN(typ$) > 4 THEN IF LEFT$(typ$, 7) <> "_BIT * " THEN Give_Error "Expected _BIT * number": EXIT FUNCTION c$ = RIGHT$(typ$, LEN(typ$) - 7) IF isuinteger(c$) = 0 THEN Give_Error "Number expected after *": EXIT FUNCTION IF LEN(c$) > 2 THEN Give_Error "Too many characters in number after *": EXIT FUNCTION bits = VAL(c$) IF bits = 0 THEN Give_Error "Cannot create a bit variable of size 0 bits": EXIT FUNCTION IF bits > 57 THEN Give_Error "Cannot create a bit variable of size > 24 bits": EXIT FUNCTION ELSE bits = 1 END IF IF bits <= 32 THEN ct$ = "int32" ELSE ct$ = "int64" IF unsgn THEN n$ = "U": ct$ = "u" + ct$ n$ = n$ + "BIT" + str2(bits) + "_" + varname$ 'array of bit-length variables IF elements$ <> "" THEN arraydesc = 0 cmps$ = varname$: IF unsgn THEN cmps$ = cmps$ + "~" cmps$ = cmps$ + "`" + str2(bits) IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, -bits) 'passing a negative element size signifies bits not bytes 'IF arraydesc THEN goto dim2exitfunc 'id already exists! 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, -bits) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.n = cvarname$ id.arraytype = BITTYPE - 1 + bits IF unsgn THEN id.arraytype = id.arraytype + ISUNSIGNED IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ IF method = 0 THEN IF unsgn THEN id.mayhave = "~`" + str2(bits) ELSE id.mayhave = "`" + str2(bits) END IF IF method = 1 THEN IF unsgn THEN id.musthave = "~`" + str2(bits) ELSE id.musthave = "`" + str2(bits) END IF regid IF Error_Happened THEN EXIT FUNCTION GOTO dim2exitfunc END IF 'standard bit-length variable n$ = scope2$ + n$ PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" PRINT #13, "if(" + n$ + "==NULL){" PRINT #13, "cmem_sp-=4;" PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$: IF unsgn THEN cmps$ = cmps$ + "~" cmps$ = cmps$ + "%%" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, 1) 'IF arraydesc THEN goto dim2exitfunc 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, 1) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = BYTETYPE: IF unsgn THEN id.arraytype = id.arraytype + ISUNSIGNED IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = BYTETYPE: IF unsgn THEN id.t = id.t + ISUNSIGNED IF f = 1 THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f = 1 THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f = 1 THEN PRINT #13, "cmem_sp-=1;" IF f = 1 THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f = 1 THEN PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$: IF unsgn THEN cmps$ = cmps$ + "~" cmps$ = cmps$ + "%" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, 2) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = INTEGERTYPE: IF unsgn THEN id.arraytype = id.arraytype + ISUNSIGNED IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = INTEGERTYPE: IF unsgn THEN id.t = id.t + ISUNSIGNED IF f = 1 THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f = 1 THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f = 1 THEN PRINT #13, "cmem_sp-=2;" IF f = 1 THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f = 1 THEN PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$: IF unsgn THEN cmps$ = cmps$ + "~" cmps$ = cmps$ + "%&" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, OS_BITS \ 8) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = OFFSETTYPE: IF unsgn THEN id.arraytype = id.arraytype + ISUNSIGNED IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = OFFSETTYPE: IF unsgn THEN id.t = id.t + ISUNSIGNED IF f = 1 THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f = 1 THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f = 1 THEN PRINT #13, "cmem_sp-=" + str2(OS_BITS \ 8) + ";" IF f = 1 THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f = 1 THEN PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$: IF unsgn THEN cmps$ = cmps$ + "~" cmps$ = cmps$ + "&" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, 4) 'IF arraydesc THEN goto dim2exitfunc 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, 4) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = LONGTYPE: IF unsgn THEN id.arraytype = id.arraytype + ISUNSIGNED IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = LONGTYPE: IF unsgn THEN id.t = id.t + ISUNSIGNED IF f = 1 THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f = 1 THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f = 1 THEN PRINT #13, "cmem_sp-=4;" IF f = 1 THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f = 1 THEN PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$: IF unsgn THEN cmps$ = cmps$ + "~" cmps$ = cmps$ + "&&" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, 8) 'IF arraydesc THEN goto dim2exitfunc 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, 8) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = INTEGER64TYPE: IF unsgn THEN id.arraytype = id.arraytype + ISUNSIGNED IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = INTEGER64TYPE: IF unsgn THEN id.t = id.t + ISUNSIGNED IF f = 1 THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f = 1 THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f = 1 THEN PRINT #13, "cmem_sp-=8;" IF f = 1 THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f = 1 THEN PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$ + "!" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, 4) 'IF arraydesc THEN goto dim2exitfunc 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, 4) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = SINGLETYPE IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = SINGLETYPE IF f = 1 THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f = 1 THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f = 1 THEN PRINT #13, "cmem_sp-=4;" IF f = 1 THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f = 1 THEN PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$ + "#" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, 8) 'IF arraydesc THEN goto dim2exitfunc 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, 8) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = DOUBLETYPE IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = DOUBLETYPE IF f = 1 THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f = 1 THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f = 1 THEN PRINT #13, "cmem_sp-=8;" IF f = 1 THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f = 1 THEN PRINT #13, "if (cmem_sp "" THEN arraydesc = 0 cmps$ = varname$ + "##" IF f = 1 THEN try = findid(cmps$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (id.arraytype) THEN l$ = RTRIM$(id.cn) arraydesc = currentid: scope2$ = scope$ EXIT DO END IF IF try = 2 THEN findanotherid = 1: try = findid(cmps$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF n$ = scope2$ + "ARRAY_" + n$ 'nume = allocarray(n$, elements$, 32) 'IF arraydesc THEN goto dim2exitfunc 'clearid IF f = 1 THEN IF LEN(elements$) = 1 AND ASC(elements$) = 63 THEN '"?" E = arrayelementslist(idn + 1): IF E THEN elements$ = elements$ + str2$(E) 'eg. "?3" for a 3 dimensional array END IF nume = allocarray(n$, elements$, 32) IF Error_Happened THEN EXIT FUNCTION l$ = l$ + sp + tlayout$ IF arraydesc THEN GOTO dim2exitfunc clearid ELSE clearid IF elements$ = "?" THEN nume = -1 id.linkid = glinkid id.linkarg = glinkarg ELSE nume = VAL(elements$) END IF END IF id.arraytype = FLOATTYPE IF cmemlist(idn + 1) THEN id.arraytype = id.arraytype + ISINCONVENTIONALMEMORY IF nume > 65536 THEN nume = nume - 65536: id.staticarray = 1 id.arrayelements = nume id.callname = n$ ELSE n$ = scope2$ + n$ clearid id.t = FLOATTYPE IF f THEN PRINT #defdatahandle, ct$ + " *" + n$ + "=NULL;" IF f THEN PRINT #13, "if(" + n$ + "==NULL){" IF cmemlist(idn + 1) THEN id.t = id.t + ISINCONVENTIONALMEMORY IF f THEN PRINT #13, "cmem_sp-=32;" IF f THEN PRINT #13, n$ + "=(" + ct$ + "*)(dblock+cmem_sp);" IF f THEN PRINT #13, "if (cmem_sp 0 AND dimshared = 0 THEN defdatahandle = 13 CLOSE #13: OPEN tmpdir$ + "data" + str2$(subfuncn) + ".txt" FOR APPEND AS #13 CLOSE #19: OPEN tmpdir$ + "free" + str2$(subfuncn) + ".txt" FOR APPEND AS #19 END IF tlayout$ = l$ END FUNCTION FUNCTION udtreference$ (o$, a$, typ AS LONG) 'UDT REFERENCE FORMAT 'idno|udtno|udtelementno|byteoffset ' ^udt of the element, not of the id obak$ = o$ 'PRINT "called udtreference!" r$ = str2$(currentid) + sp3 o = 0 'the fixed/known part of the offset incmem = 0 IF id.t THEN u = id.t AND 511 IF id.t AND ISINCONVENTIONALMEMORY THEN incmem = 1 ELSE u = id.arraytype AND 511 IF id.arraytype AND ISINCONVENTIONALMEMORY THEN incmem = 1 END IF E = 0 n = numelements(a$) IF n = 0 THEN GOTO fulludt i = 1 udtfindelenext: IF getelement$(a$, i) <> "." THEN Give_Error "Expected .": EXIT FUNCTION i = i + 1 n$ = getelement$(a$, i) nsym$ = removesymbol(n$): IF LEN(nsym$) THEN ntyp = typname2typ(nsym$): ntypsize = typname2typsize IF Error_Happened THEN EXIT FUNCTION IF n$ = "" THEN Give_Error "Expected .elementname": EXIT FUNCTION udtfindele: IF E = 0 THEN E = udtxnext(u) ELSE E = udtenext(E) IF E = 0 THEN Give_Error "Element not defined": EXIT FUNCTION n2$ = RTRIM$(udtename(E)) IF udtebytealign(E) THEN IF o MOD 8 THEN o = o + (8 - (o MOD 8)) END IF IF n$ <> n2$ THEN 'increment fixed offset o = o + udtesize(E) GOTO udtfindele END IF 'check symbol after element's name (if given) is correct IF LEN(nsym$) THEN IF udtetype(E) AND ISUDT THEN Give_Error "Invalid symbol after user defined type": EXIT FUNCTION IF ntyp <> udtetype(E) OR ntypsize <> udtetypesize(E) THEN IF nsym$ = "$" AND ((udtetype(E) AND ISFIXEDLENGTH) <> 0) THEN GOTO correctsymbol Give_Error "Incorrect symbol after element name": EXIT FUNCTION END IF END IF correctsymbol: 'Move into another UDT structure? IF i <> n THEN IF (udtetype(E) AND ISUDT) = 0 THEN Give_Error "Expected user defined type": EXIT FUNCTION u = udtetype(E) AND 511 E = 0 i = i + 1 GOTO udtfindelenext END IF 'Change e reference to u³0 reference? IF udtetype(E) AND ISUDT THEN u = udtetype(E) AND 511 E = 0 END IF fulludt: r$ = r$ + str2$(u) + sp3 + str2$(E) + sp3 IF o MOD 8 THEN Give_Error "QB64 cannot handle bit offsets within user defined types yet": EXIT FUNCTION o = o \ 8 IF o$ <> "" THEN IF o <> 0 THEN 'dont add an unnecessary 0 o$ = o$ + "+" + str2$(o) END IF ELSE o$ = str2$(o) END IF r$ = r$ + o$ udtreference$ = r$ typ = udtetype(E) + ISUDT + ISREFERENCE 'full udt override: IF E = 0 THEN typ = u + ISUDT + ISREFERENCE END IF IF obak$ <> "" THEN typ = typ + ISARRAY IF incmem THEN typ = typ + ISINCONVENTIONALMEMORY 'print "UDTREF:"+r$+","+str2$(typ) END FUNCTION FUNCTION evaluate$ (a2$, typ AS LONG) DIM block(1000) AS STRING DIM evaledblock(1000) AS INTEGER DIM blocktype(1000) AS LONG 'typ IS A RETURN VALUE '''DIM cli(15) AS INTEGER a$ = a2$ typ = -1 IF Debug THEN PRINT #9, "evaluating:[" + a2$ + "]" '''cl$ = classify(a$) blockn = 0 n = numelements(a$) b = 0 'bracketting level FOR i = 1 TO n reevaluate: l$ = getelement(a$, i) IF Debug THEN PRINT #9, "#*#*#* reevaluating:" + l$, i IF i <> n THEN nextl$ = getelement(a$, i + 1) ELSE nextl$ = "" '''getclass cl$, i, cli() IF b = 0 THEN 'don't evaluate anything within brackets IF Debug THEN PRINT #9, l$ l2$ = l$ 'pure version of l$ FOR try_method = 1 TO 4 l$ = l2$ IF try_method = 2 OR try_method = 4 THEN IF Error_Happened THEN EXIT FUNCTION dtyp$ = removesymbol(l$): IF Error_Happened THEN dtyp$ = "": Error_Happened = 0 IF LEN(dtyp$) = 0 THEN IF isoperator(l$) = 0 THEN IF isvalidvariable(l$) THEN IF LEFT$(l$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(l$)) - 64 l$ = l$ + defineextaz(v) END IF END IF ELSE l$ = l2$ END IF END IF try = findid(l$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF Debug THEN PRINT #9, try 'is l$ an array? IF nextl$ = "(" THEN IF id.arraytype THEN IF (subfuncn = id.insubfuncn AND try_method <= 2) OR try_method >= 3 THEN arrayid = currentid constequation = 0 i2 = i + 2 b2 = 0 evalnextele3: l2$ = getelement(a$, i2) IF l2$ = "(" THEN b2 = b2 + 1 IF l2$ = ")" THEN b2 = b2 - 1 IF b2 = -1 THEN c$ = arrayreference(getelements$(a$, i + 2, i2 - 1), typ2) IF Error_Happened THEN EXIT FUNCTION i = i2 'UDT IF typ2 AND ISUDT THEN 'print "arrayref returned:"+c$ getid arrayid IF Error_Happened THEN EXIT FUNCTION o$ = RIGHT$(c$, LEN(c$) - INSTR(c$, sp3)) 'change o$ to a byte offset if necessary u = typ2 AND 511 s = udtxsize(u) IF udtxbytealign(u) THEN IF s MOD 8 THEN s = s + (8 - (s MOD 8)) 'round up to nearest byte s = s \ 8 END IF o$ = "(" + o$ + ")*" + str2$(s) 'print "calling evaludt with o$:"+o$ GOTO evaludt END IF GOTO evalednextele3 END IF END IF i2 = i2 + 1 GOTO evalnextele3 evalednextele3: blockn = blockn + 1 block(blockn) = c$ evaledblock(blockn) = 2 blocktype(blockn) = typ2 IF (typ2 AND ISSTRING) THEN stringprocessinghappened = 1 GOTO evaled END IF END IF ELSE 'not followed by "(" 'is l$ a simple variable? IF id.t <> 0 AND (id.t AND ISUDT) = 0 THEN IF (subfuncn = id.insubfuncn AND try_method <= 2) OR try_method >= 3 THEN constequation = 0 blockn = blockn + 1 makeidrefer block(blockn), blocktype(blockn) IF (blocktype(blockn) AND ISSTRING) THEN stringprocessinghappened = 1 evaledblock(blockn) = 2 GOTO evaled END IF END IF 'is l$ a UDT? IF id.t AND ISUDT THEN IF (subfuncn = id.insubfuncn AND try_method <= 2) OR try_method >= 3 THEN constequation = 0 o$ = "" evaludt: b2 = 0 i3 = i + 1 FOR i2 = i3 TO n e2$ = getelement(a$, i2) IF e2$ = "(" THEN b2 = b2 + 1 IF b2 = 0 THEN IF e2$ = ")" OR isoperator(e2$) THEN i4 = i2 - 1 GOTO gotudt END IF END IF IF e2$ = ")" THEN b2 = b2 - 1 NEXT i4 = n gotudt: IF i4 < i3 THEN e$ = "" ELSE e$ = getelements$(a$, i3, i4) 'PRINT "UDTREFERENCE:";l$; e$ e$ = udtreference(o$, e$, typ2) IF Error_Happened THEN EXIT FUNCTION i = i4 blockn = blockn + 1 block(blockn) = e$ evaledblock(blockn) = 2 blocktype(blockn) = typ2 'is the following next necessary? 'IF (typ2 AND ISSTRING) THEN stringprocessinghappened = 1 GOTO evaled END IF END IF END IF '"(" or no "(" 'is l$ a function? IF id.subfunc = 1 THEN constequation = 0 IF getelement(a$, i + 1) = "(" THEN i2 = i + 2 b2 = 0 args = 1 evalnextele: l2$ = getelement(a$, i2) IF l2$ = "(" THEN b2 = b2 + 1 IF l2$ = ")" THEN b2 = b2 - 1 IF b2 = -1 THEN IF i2 = i + 2 THEN Give_Error "Expected (...)": EXIT FUNCTION c$ = evaluatefunc(getelements$(a$, i + 2, i2 - 1), args, typ2) IF Error_Happened THEN EXIT FUNCTION i = i2 GOTO evalednextele END IF END IF IF l2$ = "," AND b2 = 0 THEN args = args + 1 i2 = i2 + 1 GOTO evalnextele ELSE 'no brackets c$ = evaluatefunc("", 0, typ2) IF Error_Happened THEN EXIT FUNCTION END IF evalednextele: blockn = blockn + 1 block(blockn) = c$ evaledblock(blockn) = 2 blocktype(blockn) = typ2 IF (typ2 AND ISSTRING) THEN stringprocessinghappened = 1 GOTO evaled END IF IF try = 2 THEN findanotherid = 1: try = findid(l$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP NEXT 'try method (1-4) 'assume l$ an undefined array? IF i <> n THEN IF getelement$(a$, i + 1) = "(" THEN IF isoperator(l$) = 0 THEN IF isvalidvariable(l$) THEN IF Debug THEN PRINT #9, "**************" PRINT #9, "about to auto-create array:" + l$, i PRINT #9, "**************" END IF dtyp$ = removesymbol(l$) IF Error_Happened THEN EXIT FUNCTION 'count the number of elements nume = 1 b2 = 0 FOR i2 = i + 2 TO n e$ = getelement(a$, i2) IF e$ = "(" THEN b2 = b2 + 1 IF b2 = 0 AND e$ = "," THEN nume = nume + 1 IF e$ = ")" THEN b2 = b2 - 1 IF b2 = -1 THEN EXIT FOR NEXT fakee$ = "10": FOR i2 = 2 TO nume: fakee$ = fakee$ + sp + "," + sp + "10": NEXT IF Debug THEN PRINT #9, "evaluate:creating undefined array using dim2(" + l$ + "," + dtyp$ + ",1," + fakee$ + ")" IF Error_Happened THEN EXIT FUNCTION olddimstatic = dimstatic method = 1 IF subfuncn THEN autoarray = 1 'move dimensioning of auto array to data???.txt from inline 'static array declared by STATIC name()? 'check if varname is on the static list xi = 1 FOR x = 1 TO staticarraylistn varname2$ = getelement$(staticarraylist, xi): xi = xi + 1 typ2$ = getelement$(staticarraylist, xi): xi = xi + 1 dimmethod2 = VAL(getelement$(staticarraylist, xi)): xi = xi + 1 'check if they are similar IF UCASE$(l$) = UCASE$(varname2$) THEN l3$ = l2$: s$ = removesymbol(l3$) IF symbol2fulltypename$(dtyp$) = typ2$ OR (dimmethod2 = 0 AND s$ = "") THEN IF Error_Happened THEN EXIT FUNCTION 'adopt properties l$ = varname2$ dtyp$ = typ2$ method = dimmethod2 dimstatic = 3 END IF 'typ IF Error_Happened THEN EXIT FUNCTION END IF 'varname NEXT END IF 'subfuncn ignore = dim2(l$, dtyp$, method, fakee$) IF Error_Happened THEN EXIT FUNCTION dimstatic = olddimstatic IF Debug THEN PRINT #9, "#*#*#* dim2 has returned!!!" GOTO reevaluate END IF END IF END IF END IF l$ = l2$ 'restore l$ END IF 'b=0 IF l$ = "(" THEN IF b = 0 THEN i1 = i + 1 b = b + 1 END IF IF b = 0 THEN blockn = blockn + 1 block(blockn) = l$ evaledblock(blockn) = 0 END IF IF l$ = ")" THEN b = b - 1 IF b = 0 THEN c$ = evaluate(getelements$(a$, i1, i - 1), typ2) IF Error_Happened THEN EXIT FUNCTION IF (typ2 AND ISSTRING) THEN stringprocessinghappened = 1 blockn = blockn + 1 IF (typ2 AND ISPOINTER) THEN block(blockn) = c$ ELSE block(blockn) = "(" + c$ + ")" END IF evaledblock(blockn) = 1 blocktype(blockn) = typ2 END IF END IF evaled: NEXT r$ = "" 'return value IF Debug THEN PRINT #9, "evaluated blocks:"; FOR i = 1 TO blockn IF i <> blockn THEN IF Debug THEN PRINT #9, block(i) + CHR$(219); ELSE IF Debug THEN PRINT #9, block(i) END IF NEXT 'identify any referencable values FOR i = 1 TO blockn IF isoperator(block(i)) = 0 THEN IF evaledblock(i) = 0 THEN 'a number? c = ASC(LEFT$(block(i), 1)) IF c = 45 OR (c >= 48 AND c <= 57) THEN num$ = block(i) 'a float? f = 0 x = INSTR(num$, "E") IF x THEN f = 1: blocktype(i) = SINGLETYPE - ISPOINTER ELSE x = INSTR(num$, "D") IF x THEN f = 2: blocktype(i) = DOUBLETYPE - ISPOINTER ELSE x = INSTR(num$, "F") IF x THEN f = 3: blocktype(i) = FLOATTYPE - ISPOINTER END IF END IF END IF IF f THEN 'float IF f = 2 OR f = 3 THEN MID$(num$, x, 1) = "E" 'D,F invalid in C++ IF f = 3 THEN num$ = num$ + "L" 'otherwise number is rounded to a double ELSE 'integer blocktype(i) = typname2typ(removesymbol$(num$)) IF Error_Happened THEN EXIT FUNCTION IF blocktype(i) AND ISPOINTER THEN blocktype(i) = blocktype(i) - ISPOINTER IF (blocktype(i) AND 511) > 32 THEN IF blocktype(i) AND ISUNSIGNED THEN num$ = num$ + "ull" ELSE num$ = num$ + "ll" END IF END IF block(i) = " " + num$ + " " 'pad with spaces to avoid C++ computation errors evaledblock(i) = 1 GOTO evaledblock END IF 'number? 'fc = ASC(LEFT$(block(i), 1)) 'IF fc = 45 OR (fc >= 48 AND fc <= 57) THEN '- or 0-9 ''it's a number ''check for an extension, if none, assume integer 'blocktype(i) = INTEGER64TYPE - ISPOINTER 'tblock$ = " " + block(i) 'IF RIGHT$(tblock$, 2) = "##" THEN blocktype(i) = FLOATTYPE - ISPOINTER: block(i) = LEFT$(block(i), LEN(block$(i)) - 2): GOTO evfltnum 'IF RIGHT$(tblock$, 1) = "#" THEN blocktype(i) = DOUBLETYPE - ISPOINTER: block(i) = LEFT$(block(i), LEN(block$(i)) - 1): GOTO evfltnum 'IF RIGHT$(tblock$, 1) = "!" THEN blocktype(i) = SINGLETYPE - ISPOINTER: block(i) = LEFT$(block(i), LEN(block$(i)) - 1): GOTO evfltnum ' ''C++ 32bit unsigned to signed 64bit 'IF INSTR(block(i),".")=0 THEN ' 'negated=0 'if left$(block(i),1)="-" then block(i)=right$(block(i),len(block(i))-1):negated=1 ' 'if left$(block(i),2)="0x" then 'hex 'if len(block(i))=10 then 'if block(i)>="0x80000000" and block(i)<="0xFFFFFFFF" then block(i)="(int64)"+block(i): goto evnum 'end if 'if len(block(i))>10 then block(i)=block(i)+"ll": goto evnum 'goto evnum 'end if ' 'if left$(block(i),1)="0" then 'octal 'if len(block(i))=12 then 'if block(i)>="020000000000" and block(i)<="037777777777" then block(i)="(int64)"+block(i): goto evnum 'if block(i)>"037777777777" then block(i)=block(i)+"ll": goto evnum 'end if 'if len(block(i))>12 then block(i)=block(i)+"ll": goto evnum 'goto evnum 'end if ' ''decimal 'if len(block(i))=10 then 'if block(i)>="2147483648" and block(i)<="4294967295" then block(i)="(int64)"+block(i): goto evnum 'if block(i)>"4294967295" then block(i)=block(i)+"ll": goto evnum 'end if 'if len(block(i))>10 then block(i)=block(i)+"ll" ' 'evnum: ' 'if negated=1 then block(i)="-"+block(i) ' 'END IF ' 'evfltnum: ' 'block(i) = " " + block(i)+" " 'evaledblock(i) = 1 'GOTO evaledblock 'END IF 'a typed string in "" IF LEFT$(block(i), 1) = CHR$(34) THEN IF RIGHT$(block(i), 1) <> CHR$(34) THEN block(i) = "qbs_new_txt_len(" + block(i) + ")" ELSE block(i) = "qbs_new_txt(" + block(i) + ")" END IF blocktype(i) = ISSTRING evaledblock(i) = 1 stringprocessinghappened = 1 GOTO evaledblock END IF 'create variable IF isvalidvariable(block(i)) THEN x$ = block(i) typ$ = removesymbol$(x$) IF Error_Happened THEN EXIT FUNCTION 'add symbol extension if none given IF LEN(typ$) = 0 THEN IF LEFT$(x$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(x$)) - 64 typ$ = defineextaz(v) END IF 'check that it hasn't just been created within this loop (a=b+b) try = findid(x$ + typ$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF Debug THEN PRINT #9, try IF id.t <> 0 AND (id.t AND ISUDT) = 0 THEN 'is x$ a simple variable? GOTO simplevarfound END IF IF try = 2 THEN findanotherid = 1: try = findid(x$ + typ$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP IF Debug THEN PRINT #9, "CREATING VARIABLE:" + x$ retval = dim2(x$, typ$, 1, "") IF Error_Happened THEN EXIT FUNCTION simplevarfound: constequation = 0 makeidrefer block(i), blocktype(i) IF (blocktype(i) AND ISSTRING) THEN stringprocessinghappened = 1 IF blockn = 1 THEN IF (blocktype(i) AND ISREFERENCE) THEN GOTO returnpointer END IF 'reference value block(i) = refer(block(i), blocktype(i), 0): IF Error_Happened THEN EXIT FUNCTION evaledblock(i) = 1 GOTO evaledblock END IF Give_Error "Invalid expression": EXIT FUNCTION ELSE IF (blocktype(i) AND ISREFERENCE) THEN IF blockn = 1 THEN GOTO returnpointer 'if blocktype(i) and ISUDT then PRINT "UDT passed to refer by evaluate" block(i) = refer(block(i), blocktype(i), 0) IF Error_Happened THEN EXIT FUNCTION END IF END IF END IF evaledblock: NEXT 'return a POINTER if possible IF blockn = 1 THEN IF evaledblock(1) THEN IF (blocktype(1) AND ISREFERENCE) THEN returnpointer: IF (blocktype(1) AND ISSTRING) THEN stringprocessinghappened = 1 IF Debug THEN PRINT #9, "evaluated reference:" + block(1) typ = blocktype(1) evaluate$ = block(1) EXIT FUNCTION END IF END IF END IF 'it cannot be returned as a pointer IF Debug THEN PRINT #9, "applying operators:"; IF typ = -1 THEN typ = blocktype(1) 'init typ with first blocktype IF isoperator(block(1)) THEN 'but what if it starts with a UNARY operator? typ = blocktype(2) 'init typ with second blocktype END IF END IF nonop = 0 FOR i = 1 TO blockn IF evaledblock(i) = 0 THEN isop = isoperator(block(i)) IF isop THEN nonop = 0 constequation = 0 'operator found o$ = block(i) u = operatorusage(o$, typ, i$, lhstyp, rhstyp, result) IF u <> 5 THEN 'not unary nonop = 1 IF i = 1 OR evaledblock(i - 1) = 0 THEN IF i = 1 AND blockn = 1 AND o$ = "-" THEN Give_Error "Expected variable/value after '" + UCASE$(o$) + "'": EXIT FUNCTION 'guess - is neg in this case Give_Error "Expected variable/value before '" + UCASE$(o$) + "'": EXIT FUNCTION END IF END IF IF i = blockn OR evaledblock(i + 1) = 0 THEN Give_Error "Expected variable/value after '" + UCASE$(o$) + "'": EXIT FUNCTION 'lhstyp & rhstyp bit-field values '1=integeral '2=floating point '4=string '8=bool *only used for result oldtyp = typ newtyp = blocktype(i + 1) 'IF block(i - 1) = "6" THEN 'PRINT o$ 'PRINT oldtyp AND ISFLOAT 'PRINT blocktype(i - 1) AND ISFLOAT 'END 'END IF 'numeric->string is illegal! IF (typ AND ISSTRING) = 0 AND (newtyp AND ISSTRING) <> 0 THEN Give_Error "Cannot convert number to string": EXIT FUNCTION END IF 'Offset protection: Override conversion rules for operator as necessary offsetmode = 0 offsetcvi = 0 IF (oldtyp AND ISOFFSET) <> 0 OR (newtyp AND ISOFFSET) <> 0 THEN offsetmode = 2 IF newtyp AND ISOFFSET THEN IF (newtyp AND ISUNSIGNED) = 0 THEN offsetmode = 1 END IF IF oldtyp AND ISOFFSET THEN IF (oldtyp AND ISUNSIGNED) = 0 THEN offsetmode = 1 END IF 'depending on the operater we may do things differently 'the default method is convert both sides to integer first 'but these operators are different: * / ^ IF o$ = "*" OR o$ = "/" OR o$ = "^" THEN IF o$ = "*" OR o$ = "^" THEN 'for mult, if either side is a float cast integers to 'long double's first IF (newtyp AND ISFLOAT) <> 0 OR (oldtyp AND ISFLOAT) <> 0 THEN offsetcvi = 1 IF (oldtyp AND ISFLOAT) = 0 THEN lhstyp = 2 IF (newtyp AND ISFLOAT) = 0 THEN rhstyp = 2 END IF END IF IF o$ = "/" OR o$ = "^" THEN 'for division or exponentials, to prevent integer division cast integers to 'long double's offsetcvi = 1 IF (oldtyp AND ISFLOAT) = 0 THEN lhstyp = 2 IF (newtyp AND ISFLOAT) = 0 THEN rhstyp = 2 END IF ELSE IF lhstyp AND 2 THEN lhstyp = 1 'force lhs and rhs to be integer values IF rhstyp AND 2 THEN rhstyp = 1 END IF IF result = 2 THEN result = 1 'force integer result 'note: result=1 just sets typ&=64 if typ is a float END IF 'STEP 1: convert oldtyp and/or newtyp if required for the operator 'convert lhs IF (oldtyp AND ISSTRING) THEN IF (lhstyp AND 4) = 0 THEN Give_Error "Cannot convert string to number": EXIT FUNCTION ELSE 'oldtyp is numeric IF lhstyp = 4 THEN Give_Error "Cannot convert number to string": EXIT FUNCTION IF (oldtyp AND ISFLOAT) THEN IF (lhstyp AND 2) = 0 THEN 'convert float to int block(i - 1) = "qbr(" + block(i - 1) + ")" oldtyp = 64& END IF ELSE 'oldtyp is an int IF (lhstyp AND 1) = 0 THEN 'convert int to float block(i - 1) = "((long double)(" + block(i - 1) + "))" oldtyp = 256& + ISFLOAT END IF END IF END IF 'convert rhs IF (newtyp AND ISSTRING) THEN IF (rhstyp AND 4) = 0 THEN Give_Error "Cannot convert string to number": EXIT FUNCTION ELSE 'newtyp is numeric IF rhstyp = 4 THEN Give_Error "Cannot convert number to string": EXIT FUNCTION IF (newtyp AND ISFLOAT) THEN IF (rhstyp AND 2) = 0 THEN 'convert float to int block(i + 1) = "qbr(" + block(i + 1) + ")" newtyp = 64& END IF ELSE 'newtyp is an int IF (rhstyp AND 1) = 0 THEN 'convert int to float block(i + 1) = "((long double)(" + block(i + 1) + "))" newtyp = 256& + ISFLOAT END IF END IF END IF 'Reduce floating point values to common base for comparison? IF isop = 7 THEN 'comparitive operator 'Corrects problems encountered such as: ' S = 2.1 ' IF S = 2.1 THEN PRINT "OK" ELSE PRINT "ERROR S PRINTS AS"; S; "BUT IS SEEN BY QB64 AS..." ' IF S < 2.1 THEN PRINT "LESS THAN 2.1" 'concerns: '1. Return value from TIMER will be reduced to a SINGLE in direct comparisons 'solution: assess, and only apply to SINGLE variables/arrays '2. Comparison of a double higher/lower than single range may fail 'solution: out of range values convert to +/-1.#INF, making comparison still possible IF (oldtyp AND ISFLOAT) <> 0 AND (newtyp AND ISFLOAT) <> 0 THEN 'both floating point s1 = oldtyp AND 511: s2 = newtyp AND 511 IF s2 < s1 THEN s1 = s2 IF s1 = 32 THEN block(i - 1) = "((float)(" + block(i - 1) + "))": oldtyp = 32& + ISFLOAT block(i + 1) = "((float)(" + block(i + 1) + "))": newtyp = 32& + ISFLOAT END IF IF s1 = 64 THEN block(i - 1) = "((double)(" + block(i - 1) + "))": oldtyp = 64& + ISFLOAT block(i + 1) = "((double)(" + block(i + 1) + "))": newtyp = 64& + ISFLOAT END IF END IF 'both floating point END IF 'comparitive operator typ = newtyp 'STEP 2: markup typ ' if either side is a float, markup typ to largest float ' if either side is integer, markup typ 'Note: A markup is a GUESS of what the return type will be, ' 'result' can override this markup IF (oldtyp AND ISSTRING) = 0 AND (newtyp AND ISSTRING) = 0 THEN IF (oldtyp AND ISFLOAT) <> 0 OR (newtyp AND ISFLOAT) <> 0 THEN 'float b = 0: IF (oldtyp AND ISFLOAT) THEN b = oldtyp AND 511 IF (newtyp AND ISFLOAT) THEN b2 = newtyp AND 511: IF b2 > b THEN b = b2 END IF typ = ISFLOAT + b ELSE 'integer '***THIS IS THE IDEAL MARKUP FOR A 64-BIT SYSTEM*** 'In reality 32-bit C++ only marks-up to 32-bit integers b = oldtyp AND 511: b2 = newtyp AND 511: IF b2 > b THEN b = b2 typ = 64& IF b = 64 THEN IF (oldtyp AND ISUNSIGNED) <> 0 AND (newtyp AND ISUNSIGNED) <> 0 THEN typ = 64& + ISUNSIGNED END IF END IF END IF IF result = 1 THEN IF (typ AND ISFLOAT) <> 0 OR (typ AND ISSTRING) <> 0 THEN typ = 64 'otherwise keep markuped integer type END IF IF result = 2 THEN IF (typ AND ISFLOAT) = 0 THEN typ = ISFLOAT + 256 END IF IF result = 4 THEN typ = ISSTRING END IF IF result = 8 THEN 'bool typ = 32 END IF 'Offset protection: Force result to be an offset type with correct signage IF offsetmode THEN IF result <> 8 THEN 'boolean comparison results are allowed typ = OFFSETTYPE - ISPOINTER: IF offsetmode = 2 THEN typ = typ + ISUNSIGNED END IF END IF 'override typ=ISFLOAT+256 to typ=ISFLOAT+64 for ^ operator's result IF u = 2 THEN IF i$ = "pow2" THEN IF offsetmode THEN Give_Error "Operator '^' cannot be used with an _OFFSET": EXIT FUNCTION 'QB-like conversion of math functions returning floating point values 'reassess oldtype & newtype b = oldtyp AND 511 IF oldtyp AND ISFLOAT THEN 'no change to b ELSE IF b > 16 THEN b = 64 'larger than INTEGER? return DOUBLE IF b > 32 THEN b = 256 'larger than LONG? return FLOAT IF b <= 16 THEN b = 32 END IF b2 = newtyp AND 511 IF newtyp AND ISFLOAT THEN IF b2 > b THEN b = b2 ELSE b3 = 32 IF b2 > 16 THEN b3 = 64 'larger than INTEGER? return DOUBLE IF b2 > 32 THEN b3 = 256 'larger than LONG? return FLOAT IF b3 > b THEN b = b3 END IF typ = ISFLOAT + b END IF 'pow2 END IF 'u=2 'STEP 3: apply operator appropriately IF u = 5 THEN block(i + 1) = i$ + "(" + block(i + 1) + ")" block(i) = "": i = i + 1: GOTO operatorapplied END IF 'binary operators IF u = 1 THEN block(i + 1) = block(i - 1) + i$ + block(i + 1) block(i - 1) = "": block(i) = "": i = i + 1: GOTO operatorapplied END IF IF u = 2 THEN block(i + 1) = i$ + "(" + block(i - 1) + "," + block(i + 1) + ")" block(i - 1) = "": block(i) = "": i = i + 1: GOTO operatorapplied END IF IF u = 3 THEN block(i + 1) = "-(" + block(i - 1) + i$ + block(i + 1) + ")" block(i - 1) = "": block(i) = "": i = i + 1: GOTO operatorapplied END IF IF u = 4 THEN block(i + 1) = "~" + block(i - 1) + i$ + block(i + 1) block(i - 1) = "": block(i) = "": i = i + 1: GOTO operatorapplied END IF '...more?... Give_Error "ERROR: Operator could not be applied correctly!": EXIT FUNCTION '<--should never happen! operatorapplied: IF offsetcvi THEN block(i) = "qbr(" + block(i) + ")": offsetcvi = 0 offsetmode = 0 ELSE nonop = nonop + 1 END IF ELSE nonop = nonop + 1 END IF IF nonop > 1 THEN Give_Error "Expected operator in equation": EXIT FUNCTION NEXT IF Debug THEN PRINT #9, "" 'join blocks FOR i = 1 TO blockn r$ = r$ + block(i) NEXT IF Debug THEN PRINT #9, "evaluated:" + r$ + " AS TYPE:"; IF (typ AND ISSTRING) THEN PRINT #9, "[ISSTRING]"; IF (typ AND ISFLOAT) THEN PRINT #9, "[ISFLOAT]"; IF (typ AND ISUNSIGNED) THEN PRINT #9, "[ISUNSIGNED]"; IF (typ AND ISPOINTER) THEN PRINT #9, "[ISPOINTER]"; IF (typ AND ISFIXEDLENGTH) THEN PRINT #9, "[ISFIXEDLENGTH]"; IF (typ AND ISINCONVENTIONALMEMORY) THEN PRINT #9, "[ISINCONVENTIONALMEMORY]"; PRINT #9, "(size in bits=" + str2$(typ AND 511) + ")" END IF evaluate$ = r$ END FUNCTION FUNCTION evaluatefunc$ (a2$, args AS LONG, typ AS LONG) a$ = a2$ IF Debug THEN PRINT #9, "evaluatingfunction:" + RTRIM$(id.n) + ":" + a$ DIM id2 AS idstruct id2 = id n$ = RTRIM$(id2.n) typ = id2.ret targetid = currentid IF RTRIM$(id2.callname) = "func_stub" THEN Give_Error "Command not implemented": EXIT FUNCTION SetDependency id2.Dependency passomit = 0 omitarg_first = 0: omitarg_last = 0 f$ = RTRIM$(id2.specialformat) IF LEN(f$) THEN 'special format given 'count omittable args sqb = 0 a = 0 FOR fi = 1 TO LEN(f$) fa = ASC(f$, fi) IF fa = ASC_QUESTIONMARK THEN a = a + 1 IF sqb <> 0 AND omitarg_first = 0 THEN omitarg_first = a END IF IF fa = ASC_LEFTSQUAREBRACKET THEN sqb = 1 IF fa = ASC_RIGHTSQUAREBRACKET THEN sqb = 0: omitarg_last = a NEXT omitargs = omitarg_last - omitarg_first + 1 IF args <> id2.args - omitargs AND args <> id2.args THEN Give_Error "Incorrect number of arguments passed to function": EXIT FUNCTION passomit = 1 'pass omit flags param to function IF id2.args = args THEN omitarg_first = 0: omitarg_last = 0 'all arguments were passed! ELSE 'no special format given IF n$ = "ASC" AND args = 2 THEN GOTO skipargnumchk IF id2.args <> args THEN Give_Error "Incorrect number of arguments passed to function": EXIT FUNCTION END IF skipargnumchk: IF id2.NoCloud THEN IF Cloud THEN Give_Error "Feature not supported on QLOUD" '***NOCLOUD*** END IF r$ = RTRIM$(id2.callname) + "(" IF id2.args <> 0 THEN curarg = 1 firsti = 1 n = numelements(a$) IF n = 0 THEN i = 0: GOTO noargs FOR i = 1 TO n IF curarg >= omitarg_first AND curarg <= omitarg_last THEN noargs: targettyp = CVL(MID$(id2.arg, curarg * 4 - 4 + 1, 4)) 'IF (targettyp AND ISSTRING) THEN Give_Error "QB64 doesn't support optional string arguments for functions yet!": EXIT FUNCTION FOR fi = 1 TO omitargs - 1: r$ = r$ + "NULL,": NEXT: r$ = r$ + "NULL" curarg = curarg + omitargs IF i = n THEN EXIT FOR r$ = r$ + "," END IF l$ = getelement(a$, i) IF l$ = "(" THEN b = b + 1 IF l$ = ")" THEN b = b - 1 IF (l$ = "," AND b = 0) OR (i = n) THEN targettyp = CVL(MID$(id2.arg, curarg * 4 - 4 + 1, 4)) nele = ASC(MID$(id2.nele, curarg, 1)) nelereq = ASC(MID$(id2.nelereq, curarg, 1)) IF i = n THEN e$ = getelements$(a$, firsti, i) ELSE e$ = getelements$(a$, firsti, i - 1) END IF IF LEFT$(e$, 2) = "(" + sp THEN dereference = 1 ELSE dereference = 0 '*special case CVI,CVL,CVS,CVD,_CV (part #1) IF n$ = "_CV" THEN IF curarg = 1 THEN cvtype$ = type2symbol$(e$) IF Error_Happened THEN EXIT FUNCTION e$ = "" GOTO dontevaluate END IF END IF '*special case MKI,MKL,MKS,MKD,_MK (part #1) IF n$ = "_MK" THEN IF RTRIM$(id2.musthave) = "$" THEN IF curarg = 1 THEN mktype$ = type2symbol$(e$) IF Error_Happened THEN EXIT FUNCTION IF Debug THEN PRINT #9, "_MK:[" + e$ + "]:[" + mktype$ + "]" e$ = "" GOTO dontevaluate END IF END IF END IF IF n$ = "UBOUND" OR n$ = "LBOUND" THEN IF curarg = 1 THEN 'perform a "fake" evaluation of the array e$ = e$ + sp + "(" + sp + ")" e$ = evaluate(e$, sourcetyp) IF Error_Happened THEN EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected array-name": EXIT FUNCTION IF (sourcetyp AND ISARRAY) = 0 THEN Give_Error "Expected array-name": EXIT FUNCTION 'make a note of the array's index for later ulboundarray$ = e$ ulboundarraytyp = sourcetyp e$ = "" r$ = "" GOTO dontevaluate END IF END IF '*special case: INPUT$ function IF n$ = "INPUT" THEN IF RTRIM$(id2.musthave) = "$" THEN IF curarg = 2 THEN IF LEFT$(e$, 2) = "#" + sp THEN e$ = RIGHT$(e$, LEN(e$) - 2) END IF END IF END IF '*special case* IF n$ = "ASC" THEN IF curarg = 2 THEN e$ = evaluatetotyp$(e$, 32&) IF Error_Happened THEN EXIT FUNCTION typ& = LONGTYPE - ISPOINTER r$ = r$ + e$ + ")" GOTO evalfuncspecial END IF END IF 'PRINT #12, "n$="; n$ 'PRINT #12, "curarg="; curarg 'PRINT #12, "e$="; e$ 'PRINT #12, "r$="; r$ '*special case* IF n$ = "_MEMGET" THEN IF curarg = 1 THEN memget_blk$ = e$ END IF IF curarg = 2 THEN memget_offs$ = e$ END IF IF curarg = 3 THEN e$ = UCASE$(e$) IF INSTR(e$, sp + "*" + sp) THEN 'multiplier will have an appended %,& or && symbol IF RIGHT$(e$, 2) = "&&" THEN e$ = LEFT$(e$, LEN(e$) - 2) ELSE IF RIGHT$(e$, 1) = "&" OR RIGHT$(e$, 1) = "%" THEN e$ = LEFT$(e$, LEN(e$) - 1) END IF END IF t = typname2typ(e$) IF t = 0 THEN Give_Error "Invalid TYPE name": EXIT FUNCTION IF t AND ISOFFSETINBITS THEN Give_Error "_BIT TYPE unsupported": EXIT FUNCTION memget_size = typname2typsize IF t AND ISSTRING THEN IF (t AND ISFIXEDLENGTH) = 0 THEN Give_Error "Expected STRING * ...": EXIT FUNCTION memget_ctyp$ = "qbs*" ELSE IF t AND ISUDT THEN memget_size = udtxsize(t AND 511) \ 8 memget_ctyp$ = "void*" ELSE memget_size = (t AND 511) \ 8 memget_ctyp$ = typ2ctyp$(t, "") END IF END IF 'assume checking off offs$ = evaluatetotyp(memget_offs$, OFFSETTYPE - ISPOINTER) blkoffs$ = evaluatetotyp(memget_blk$, -6) IF NoChecks = 0 THEN 'change offs$ to be the return of the safe version offs$ = "func__memget((mem_block*)" + blkoffs$ + "," + offs$ + "," + str2(memget_size) + ")" END IF IF t AND ISSTRING THEN r$ = "qbs_new_txt_len((char*)" + offs$ + "," + str2(memget_size) + ")" ELSE IF t AND ISUDT THEN r$ = "((void*)+" + offs$ + ")" t = ISUDT + ISPOINTER + (t AND 511) ELSE r$ = "*(" + memget_ctyp$ + "*)(" + offs$ + ")" IF t AND ISPOINTER THEN t = t - ISPOINTER END IF END IF typ& = t GOTO evalfuncspecial END IF END IF '------------------------------------------------------------------------------------------------------------ e2$ = e$ e$ = evaluate(e$, sourcetyp) IF Error_Happened THEN EXIT FUNCTION '------------------------------------------------------------------------------------------------------------ '***special case*** IF n$ = "_MEM" THEN IF curarg = 1 THEN IF args = 1 THEN targettyp = -7 END IF IF args = 2 THEN r$ = RTRIM$(id2.callname) + "_at_offset" + RIGHT$(r$, LEN(r$) - LEN(RTRIM$(id2.callname))) IF (sourcetyp AND ISOFFSET) = 0 THEN Give_Error "Expected _MEM(_OFFSET-value,...)": EXIT FUNCTION END IF END IF END IF '*special case* IF n$ = "_OFFSET" THEN IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "_OFFSET expects the name of a variable/array": EXIT FUNCTION END IF IF (sourcetyp AND ISARRAY) THEN IF (sourcetyp AND ISOFFSETINBITS) THEN Give_Error "_OFFSET cannot reference _BIT type arrays": EXIT FUNCTION END IF r$ = "((uptrszint)(" + evaluatetotyp$(e2$, -6) + "))" IF Error_Happened THEN EXIT FUNCTION typ& = UOFFSETTYPE - ISPOINTER GOTO evalfuncspecial END IF '_OFFSET '*_OFFSET exceptions* IF sourcetyp AND ISOFFSET THEN IF n$ = "MKSMBF" AND RTRIM$(id2.musthave) = "$" THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION IF n$ = "MKDMBF" AND RTRIM$(id2.musthave) = "$" THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION END IF '*special case* IF n$ = "ENVIRON" THEN IF sourcetyp AND ISSTRING THEN IF sourcetyp AND ISREFERENCE THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION GOTO dontevaluate END IF END IF '*special case* IF n$ = "LEN" THEN typ& = LONGTYPE - ISPOINTER IF (sourcetyp AND ISREFERENCE) = 0 THEN 'could be a string expression IF sourcetyp AND ISSTRING THEN r$ = "((int32)(" + e$ + ")->len)" GOTO evalfuncspecial END IF Give_Error "String expression or variable name required in LEN statement": EXIT FUNCTION END IF r$ = evaluatetotyp$(e2$, -5) 'use evaluatetotyp to get 'element' size IF Error_Happened THEN EXIT FUNCTION GOTO evalfuncspecial END IF '*special case* IF n$ = "OCT" THEN IF RTRIM$(id2.musthave) = "$" THEN bits = sourcetyp AND 511 IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION wasref = 0 IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0): wasref = 1 IF Error_Happened THEN EXIT FUNCTION bits = sourcetyp AND 511 IF (sourcetyp AND ISOFFSETINBITS) THEN e$ = "func_oct(" + e$ + "," + str2$(bits) + ")" ELSE IF (sourcetyp AND ISFLOAT) THEN e$ = "func_oct_float(" + e$ + ")" ELSE IF bits = 64 THEN IF wasref = 0 THEN bits = 0 END IF e$ = "func_oct(" + e$ + "," + str2$(bits) + ")" END IF END IF typ& = STRINGTYPE - ISPOINTER r$ = e$ GOTO evalfuncspecial END IF END IF '*special case* IF n$ = "HEX" THEN IF RTRIM$(id2.musthave) = "$" THEN bits = sourcetyp AND 511 IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION wasref = 0 IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0): wasref = 1 IF Error_Happened THEN EXIT FUNCTION bits = sourcetyp AND 511 IF (sourcetyp AND ISOFFSETINBITS) THEN chars = (bits + 3) \ 4 e$ = "func_hex(" + e$ + "," + str2$(chars) + ")" ELSE IF (sourcetyp AND ISFLOAT) THEN e$ = "func_hex_float(" + e$ + ")" ELSE IF bits = 8 THEN chars = 2 IF bits = 16 THEN chars = 4 IF bits = 32 THEN chars = 8 IF bits = 64 THEN IF wasref = 1 THEN chars = 16 ELSE chars = 0 END IF e$ = "func_hex(" + e$ + "," + str2$(chars) + ")" END IF END IF typ& = STRINGTYPE - ISPOINTER r$ = e$ GOTO evalfuncspecial END IF END IF '*special case* IF n$ = "EXP" THEN bits = sourcetyp AND 511 IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION bits = sourcetyp AND 511 typ& = SINGLETYPE - ISPOINTER IF (sourcetyp AND ISFLOAT) THEN IF bits = 32 THEN e$ = "func_exp_single(" + e$ + ")" ELSE e$ = "func_exp_float(" + e$ + ")": typ& = FLOATTYPE - ISPOINTER ELSE IF (sourcetyp AND ISOFFSETINBITS) THEN e$ = "func_exp_float(" + e$ + ")": typ& = FLOATTYPE - ISPOINTER ELSE IF bits <= 16 THEN e$ = "func_exp_single(" + e$ + ")" ELSE e$ = "func_exp_float(" + e$ + ")": typ& = FLOATTYPE - ISPOINTER END IF END IF r$ = e$ GOTO evalfuncspecial END IF '*special case* IF n$ = "INT" THEN IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'establish which function (if any!) should be used IF (sourcetyp AND ISFLOAT) THEN e$ = "floor(" + e$ + ")" ELSE e$ = "(" + e$ + ")" r$ = e$ typ& = sourcetyp GOTO evalfuncspecial END IF '*special case* IF n$ = "FIX" THEN IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'establish which function (if any!) should be used bits = sourcetyp AND 511 IF (sourcetyp AND ISFLOAT) THEN IF bits > 64 THEN e$ = "func_fix_float(" + e$ + ")" ELSE e$ = "func_fix_double(" + e$ + ")" ELSE e$ = "(" + e$ + ")" END IF r$ = e$ typ& = sourcetyp GOTO evalfuncspecial END IF '*special case* IF n$ = "_ROUND" THEN IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'establish which function (if any!) should be used IF (sourcetyp AND ISFLOAT) THEN bits = sourcetyp AND 511 IF bits > 64 THEN e$ = "func_round_float(" + e$ + ")" ELSE e$ = "func_round_double(" + e$ + ")" ELSE e$ = "(" + e$ + ")" END IF r$ = e$ typ& = 64& IF (sourcetyp AND ISOFFSET) THEN IF sourcetyp AND ISUNSIGNED THEN typ& = UOFFSETTYPE - ISPOINTER ELSE typ& = OFFSETTYPE - ISPOINTER END IF GOTO evalfuncspecial END IF '*special case* IF n$ = "CDBL" THEN IF (sourcetyp AND ISOFFSET) THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'establish which function (if any!) should be used bits = sourcetyp AND 511 IF (sourcetyp AND ISFLOAT) THEN IF bits > 64 THEN e$ = "func_cdbl_float(" + e$ + ")" ELSE e$ = "((double)(" + e$ + "))" END IF r$ = e$ typ& = DOUBLETYPE - ISPOINTER GOTO evalfuncspecial END IF '*special case* IF n$ = "CSNG" THEN IF (sourcetyp AND ISOFFSET) THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'establish which function (if any!) should be used bits = sourcetyp AND 511 IF (sourcetyp AND ISFLOAT) THEN IF bits = 64 THEN e$ = "func_csng_double(" + e$ + ")" IF bits > 64 THEN e$ = "func_csng_float(" + e$ + ")" ELSE e$ = "((double)(" + e$ + "))" END IF r$ = e$ typ& = SINGLETYPE - ISPOINTER GOTO evalfuncspecial END IF '*special case* IF n$ = "CLNG" THEN IF (sourcetyp AND ISOFFSET) THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'establish which function (if any!) should be used bits = sourcetyp AND 511 IF (sourcetyp AND ISFLOAT) THEN IF bits > 64 THEN e$ = "func_clng_float(" + e$ + ")" ELSE e$ = "func_clng_double(" + e$ + ")" ELSE 'integer IF (sourcetyp AND ISUNSIGNED) THEN IF bits = 32 THEN e$ = "func_clng_ulong(" + e$ + ")" IF bits > 32 THEN e$ = "func_clng_uint64(" + e$ + ")" ELSE 'signed IF bits > 32 THEN e$ = "func_clng_int64(" + e$ + ")" END IF END IF r$ = e$ typ& = 32& GOTO evalfuncspecial END IF '*special case* IF n$ = "CINT" THEN IF (sourcetyp AND ISOFFSET) THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION IF (sourcetyp AND ISSTRING) THEN Give_Error "Expected numeric value": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'establish which function (if any!) should be used bits = sourcetyp AND 511 IF (sourcetyp AND ISFLOAT) THEN IF bits > 64 THEN e$ = "func_cint_float(" + e$ + ")" ELSE e$ = "func_cint_double(" + e$ + ")" ELSE 'integer IF (sourcetyp AND ISUNSIGNED) THEN IF bits > 15 AND bits <= 32 THEN e$ = "func_cint_ulong(" + e$ + ")" IF bits > 32 THEN e$ = "func_cint_uint64(" + e$ + ")" ELSE 'signed IF bits > 16 AND bits <= 32 THEN e$ = "func_cint_long(" + e$ + ")" IF bits > 32 THEN e$ = "func_cint_int64(" + e$ + ")" END IF END IF r$ = e$ typ& = 16& GOTO evalfuncspecial END IF '*special case MKI,MKL,MKS,MKD,_MK (part #2) mktype = 0 size = 0 IF n$ = "MKI" THEN mktype = 1: mktype$ = "%" IF n$ = "MKL" THEN mktype = 2: mktype$ = "&" IF n$ = "MKS" THEN mktype = 3: mktype$ = "!" IF n$ = "MKD" THEN mktype = 4: mktype$ = "#" IF n$ = "_MK" THEN mktype = -1 IF mktype THEN IF mktype <> -1 OR curarg = 2 THEN IF (sourcetyp AND ISOFFSET) THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION 'both _MK and trad. process the following qtyp& = 0 IF mktype$ = "%%" THEN ctype$ = "b": qtyp& = BYTETYPE - ISPOINTER IF mktype$ = "~%%" THEN ctype$ = "ub": qtyp& = UBYTETYPE - ISPOINTER IF mktype$ = "%" THEN ctype$ = "i": qtyp& = INTEGERTYPE - ISPOINTER IF mktype$ = "~%" THEN ctype$ = "ui": qtyp& = UINTEGERTYPE - ISPOINTER IF mktype$ = "&" THEN ctype$ = "l": qtyp& = LONGTYPE - ISPOINTER IF mktype$ = "~&" THEN ctype$ = "ul": qtyp& = ULONGTYPE - ISPOINTER IF mktype$ = "&&" THEN ctype$ = "i64": qtyp& = INTEGER64TYPE - ISPOINTER IF mktype$ = "~&&" THEN ctype$ = "ui64": qtyp& = UINTEGER64TYPE - ISPOINTER IF mktype$ = "!" THEN ctype$ = "s": qtyp& = SINGLETYPE - ISPOINTER IF mktype$ = "#" THEN ctype$ = "d": qtyp& = DOUBLETYPE - ISPOINTER IF mktype$ = "##" THEN ctype$ = "f": qtyp& = FLOATTYPE - ISPOINTER IF LEFT$(mktype$, 2) = "~`" THEN ctype$ = "ubit": qtyp& = UINTEGER64TYPE - ISPOINTER: size = VAL(RIGHT$(mktype$, LEN(mktype$) - 2)) IF LEFT$(mktype$, 1) = "`" THEN ctype$ = "bit": qtyp& = INTEGER64TYPE - ISPOINTER: size = VAL(RIGHT$(mktype$, LEN(mktype$) - 1)) IF qtyp& = 0 THEN Give_Error "_MK only accepts numeric types": EXIT FUNCTION IF size THEN r$ = ctype$ + "2string(" + str2(size) + "," ELSE r$ = ctype$ + "2string(" END IF nocomma = 1 targettyp = qtyp& END IF END IF '*special case CVI,CVL,CVS,CVD,_CV (part #2) cvtype = 0 IF n$ = "CVI" THEN cvtype = 1: cvtype$ = "%" IF n$ = "CVL" THEN cvtype = 2: cvtype$ = "&" IF n$ = "CVS" THEN cvtype = 3: cvtype$ = "!" IF n$ = "CVD" THEN cvtype = 4: cvtype$ = "#" IF n$ = "_CV" THEN cvtype = -1 IF cvtype THEN IF cvtype <> -1 OR curarg = 2 THEN IF (sourcetyp AND ISSTRING) = 0 THEN Give_Error n$ + " requires a STRING argument": EXIT FUNCTION IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION typ& = 0 IF cvtype$ = "%%" THEN ctype$ = "b": typ& = BYTETYPE - ISPOINTER IF cvtype$ = "~%%" THEN ctype$ = "ub": typ& = UBYTETYPE - ISPOINTER IF cvtype$ = "%" THEN ctype$ = "i": typ& = INTEGERTYPE - ISPOINTER IF cvtype$ = "~%" THEN ctype$ = "ui": typ& = UINTEGERTYPE - ISPOINTER IF cvtype$ = "&" THEN ctype$ = "l": typ& = LONGTYPE - ISPOINTER IF cvtype$ = "~&" THEN ctype$ = "ul": typ& = ULONGTYPE - ISPOINTER IF cvtype$ = "&&" THEN ctype$ = "i64": typ& = INTEGER64TYPE - ISPOINTER IF cvtype$ = "~&&" THEN ctype$ = "ui64": typ& = UINTEGER64TYPE - ISPOINTER IF cvtype$ = "!" THEN ctype$ = "s": typ& = SINGLETYPE - ISPOINTER IF cvtype$ = "#" THEN ctype$ = "d": typ& = DOUBLETYPE - ISPOINTER IF cvtype$ = "##" THEN ctype$ = "f": typ& = FLOATTYPE - ISPOINTER IF LEFT$(cvtype$, 2) = "~`" THEN ctype$ = "ubit": typ& = UINTEGER64TYPE - ISPOINTER: size = VAL(RIGHT$(cvtype$, LEN(cvtype$) - 2)) IF LEFT$(cvtype$, 1) = "`" THEN ctype$ = "bit": typ& = INTEGER64TYPE - ISPOINTER: size = VAL(RIGHT$(cvtype$, LEN(cvtype$) - 1)) IF typ& = 0 THEN Give_Error "_CV cannot return STRING type!": EXIT FUNCTION IF ctype$ = "bit" OR ctype$ = "ubit" THEN r$ = "string2" + ctype$ + "(" + e$ + "," + str2(size) + ")" ELSE r$ = "string2" + ctype$ + "(" + e$ + ")" END IF GOTO evalfuncspecial END IF END IF '*special case IF RTRIM$(id2.n) = "STRING" THEN IF curarg = 2 THEN IF (sourcetyp AND ISSTRING) THEN IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION sourcetyp = 64& e$ = "(" + e$ + "->chr[0])" END IF END IF END IF '*special case IF RTRIM$(id2.n) = "SADD" THEN IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "SADD only accepts variable-length string variables": EXIT FUNCTION END IF IF (sourcetyp AND ISFIXEDLENGTH) THEN Give_Error "SADD only accepts variable-length string variables": EXIT FUNCTION END IF IF (sourcetyp AND ISINCONVENTIONALMEMORY) = 0 THEN recompile = 1 cmemlist(VAL(e$)) = 1 r$ = "[CONVENTIONAL_MEMORY_REQUIRED]" typ& = 64& GOTO evalfuncspecial END IF r$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION r$ = "((unsigned short)(" + r$ + "->chr-&cmem[1280]))" typ& = 64& GOTO evalfuncspecial END IF '*special case IF RTRIM$(id2.n) = "VARPTR" THEN IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected reference to a variable/array": EXIT FUNCTION END IF IF RTRIM$(id2.musthave) = "$" THEN IF (sourcetyp AND ISINCONVENTIONALMEMORY) = 0 THEN recompile = 1 cmemlist(VAL(e$)) = 1 r$ = "[CONVENTIONAL_MEMORY_REQUIRED]" typ& = ISSTRING GOTO evalfuncspecial END IF IF (sourcetyp AND ISARRAY) THEN IF (sourcetyp AND ISSTRING) = 0 THEN Give_Error "VARPTR$ only accepts variable-length string arrays": EXIT FUNCTION IF (sourcetyp AND ISFIXEDLENGTH) THEN Give_Error "VARPTR$ only accepts variable-length string arrays": EXIT FUNCTION END IF 'must be a simple variable '!assuming it is in cmem in DBLOCK r$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN EXIT FUNCTION IF (sourcetyp AND ISSTRING) THEN IF (sourcetyp AND ISARRAY) THEN r$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION r$ = r$ + "->cmem_descriptor_offset" t = 3 ELSE r$ = "((unsigned short)(((uint8*)" + r$ + ")-&cmem[1280]))" '*top bit on=unsigned '*second top bit on=bit-value (lower bits indicate the size) 'BYTE=1 'INTEGER=2 'STRING=3 'SINGLE=4 'INT64=5 'FLOAT=6 'DOUBLE=8 'LONG=20 'BIT=64+n t = 0 IF (sourcetyp AND ISUNSIGNED) THEN t = t + 128 IF (sourcetyp AND ISOFFSETINBITS) THEN t = t + 64 t = t + (sourcetyp AND 63) ELSE bits = sourcetyp AND 511 IF (sourcetyp AND ISFLOAT) THEN IF bits = 32 THEN t = t + 4 IF bits = 64 THEN t = t + 8 IF bits = 256 THEN t = t + 6 ELSE IF bits = 8 THEN t = t + 1 IF bits = 16 THEN t = t + 2 IF bits = 32 THEN t = t + 20 IF bits = 64 THEN t = t + 5 END IF END IF END IF r$ = "func_varptr_helper(" + str2(t) + "," + r$ + ")" typ& = ISSTRING GOTO evalfuncspecial END IF 'end of varptr$ 'VARPTR IF (sourcetyp AND ISINCONVENTIONALMEMORY) = 0 THEN recompile = 1 cmemlist(VAL(e$)) = 1 r$ = "[CONVENTIONAL_MEMORY_REQUIRED]" typ& = 64& GOTO evalfuncspecial END IF IF (sourcetyp AND ISARRAY) THEN IF (sourcetyp AND ISOFFSETINBITS) THEN Give_Error "VARPTR cannot reference _BIT type arrays": EXIT FUNCTION 'string array? IF (sourcetyp AND ISSTRING) THEN IF (sourcetyp AND ISFIXEDLENGTH) THEN getid VAL(e$) IF Error_Happened THEN EXIT FUNCTION m = id.tsize index$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) typ = 64& r$ = "((" + index$ + ")*" + str2(m) + ")" GOTO evalfuncspecial ELSE 'return the offset of the string's descriptor r$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION r$ = r$ + "->cmem_descriptor_offset" typ = 64& GOTO evalfuncspecial END IF END IF IF sourcetyp AND ISUDT THEN e$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip idnumber e$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip u o$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip e typ = 64& r$ = "(" + o$ + ")" GOTO evalfuncspecial END IF 'non-UDT array m = (sourcetyp AND 511) \ 8 'calculate size multiplier index$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) typ = 64& r$ = "((" + index$ + ")*" + str2(m) + ")" GOTO evalfuncspecial END IF 'not an array IF sourcetyp AND ISUDT THEN r$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN EXIT FUNCTION e$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip idnumber e$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip u o$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip e typ = 64& 'if sub/func arg, may not be in DBLOCK getid VAL(e$) IF Error_Happened THEN EXIT FUNCTION IF id.sfarg THEN 'could be in DBLOCK 'note: segment could be the closest segment to UDT element or the base of DBLOCK r$ = "varptr_dblock_check(((uint8*)" + r$ + ")+(" + o$ + "))" ELSE 'definitely in DBLOCK 'give offset relative to DBLOCK r$ = "((unsigned short)(((uint8*)" + r$ + ") - &cmem[1280] + (" + o$ + ") ))" END IF GOTO evalfuncspecial END IF typ = 64& r$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN EXIT FUNCTION IF (sourcetyp AND ISSTRING) THEN IF (sourcetyp AND ISFIXEDLENGTH) THEN 'if sub/func arg, may not be in DBLOCK getid VAL(e$) IF Error_Happened THEN EXIT FUNCTION IF id.sfarg THEN 'could be in DBLOCK r$ = "varptr_dblock_check(" + r$ + "->chr)" ELSE 'definitely in DBLOCK r$ = "((unsigned short)(" + r$ + "->chr-&cmem[1280]))" END IF ELSE r$ = r$ + "->cmem_descriptor_offset" END IF GOTO evalfuncspecial END IF 'single, simple variable 'if sub/func arg, may not be in DBLOCK getid VAL(e$) IF Error_Happened THEN EXIT FUNCTION IF id.sfarg THEN 'could be in DBLOCK r$ = "varptr_dblock_check((uint8*)" + r$ + ")" ELSE 'definitely in DBLOCK r$ = "((unsigned short)(((uint8*)" + r$ + ")-&cmem[1280]))" END IF GOTO evalfuncspecial END IF '*special case* IF RTRIM$(id2.n) = "VARSEG" THEN IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected reference to a variable/array": EXIT FUNCTION END IF IF (sourcetyp AND ISINCONVENTIONALMEMORY) = 0 THEN recompile = 1 cmemlist(VAL(e$)) = 1 r$ = "[CONVENTIONAL_MEMORY_REQUIRED]" typ& = 64& GOTO evalfuncspecial END IF 'array? IF (sourcetyp AND ISARRAY) THEN IF (sourcetyp AND ISFIXEDLENGTH) = 0 THEN IF (sourcetyp AND ISSTRING) THEN r$ = "80" typ = 64& GOTO evalfuncspecial END IF END IF typ = 64& r$ = "( ( ((ptrszint)(" + refer(e$, sourcetyp, 1) + "[0])) - ((ptrszint)(&cmem[0])) ) /16)" IF Error_Happened THEN EXIT FUNCTION GOTO evalfuncspecial END IF 'single variable/(var-len)string/udt? (usually stored in DBLOCK) typ = 64& 'if sub/func arg, may not be in DBLOCK getid VAL(e$) IF Error_Happened THEN EXIT FUNCTION IF id.sfarg <> 0 AND (sourcetyp AND ISSTRING) = 0 THEN IF sourcetyp AND ISUDT THEN r$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN EXIT FUNCTION e$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip idnumber e$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip u o$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'skip e r$ = "varseg_dblock_check(((uint8*)" + r$ + ")+(" + o$ + "))" ELSE r$ = "varseg_dblock_check((uint8*)" + refer(e$, sourcetyp, 1) + ")" IF Error_Happened THEN EXIT FUNCTION END IF ELSE 'can be assumed to be in DBLOCK r$ = "80" END IF GOTO evalfuncspecial END IF 'varseg 'note: this code has already been called... '------------------------------------------------------------------------------------------------------------ 'e2$ = e$ 'e$ = evaluate(e$, sourcetyp) '------------------------------------------------------------------------------------------------------------ 'note: this comment makes no sense... 'any numeric variable, but it must be type-speficied IF targettyp = -2 THEN e$ = evaluatetotyp(e2$, -2) IF Error_Happened THEN EXIT FUNCTION GOTO dontevaluate END IF '-2 IF targettyp = -7 THEN e$ = evaluatetotyp(e2$, -7) IF Error_Happened THEN EXIT FUNCTION GOTO dontevaluate END IF '-7 IF targettyp = -8 THEN e$ = evaluatetotyp(e2$, -8) IF Error_Happened THEN EXIT FUNCTION GOTO dontevaluate END IF '-8 IF sourcetyp AND ISOFFSET THEN IF (targettyp AND ISOFFSET) = 0 THEN IF id2.internal_subfunc = 0 THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION END IF END IF 'note: this is used for functions like STR(...) which accept all types... explicitreference = 0 IF targettyp = -1 THEN explicitreference = 1 IF (sourcetyp AND ISSTRING) THEN Give_Error "Number required for function": EXIT FUNCTION targettyp = sourcetyp IF (targettyp AND ISPOINTER) THEN targettyp = targettyp - ISPOINTER END IF 'pointer? IF (targettyp AND ISPOINTER) THEN IF dereference = 0 THEN 'check deferencing wasn't used 'note: array pointer IF (targettyp AND ISARRAY) THEN IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected arrayname()": EXIT FUNCTION IF (sourcetyp AND ISARRAY) = 0 THEN Give_Error "Expected arrayname()": EXIT FUNCTION IF Debug THEN PRINT #9, "evaluatefunc:array reference:[" + e$ + "]" 'check arrays are of same type targettyp2 = targettyp: sourcetyp2 = sourcetyp targettyp2 = targettyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISSTRING + ISFIXEDLENGTH + ISFLOAT) sourcetyp2 = sourcetyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISSTRING + ISFIXEDLENGTH + ISFLOAT) IF sourcetyp2 <> targettyp2 THEN Give_Error "Incorrect array type passed to function": EXIT FUNCTION 'check arrayname was followed by '()' IF targettyp AND ISUDT THEN IF Debug THEN PRINT #9, "evaluatefunc:array reference:udt reference:[" + e$ + "]" 'get UDT info udtrefid = VAL(e$) getid udtrefid IF Error_Happened THEN EXIT FUNCTION udtrefi = INSTR(e$, sp3) 'end of id udtrefi2 = INSTR(udtrefi + 1, e$, sp3) 'end of u udtrefu = VAL(MID$(e$, udtrefi + 1, udtrefi2 - udtrefi - 1)) udtrefi3 = INSTR(udtrefi2 + 1, e$, sp3) 'skip e udtrefe = VAL(MID$(e$, udtrefi2 + 1, udtrefi3 - udtrefi2 - 1)) o$ = RIGHT$(e$, LEN(e$) - udtrefi3) 'note: most of the UDT info above is not required IF LEFT$(o$, 4) <> "(0)*" THEN Give_Error "Expected arrayname()": EXIT FUNCTION ELSE IF RIGHT$(e$, 2) <> sp3 + "0" THEN Give_Error "Expected arrayname()": EXIT FUNCTION END IF idnum = VAL(LEFT$(e$, INSTR(e$, sp3) - 1)) getid idnum IF Error_Happened THEN EXIT FUNCTION IF targettyp AND ISFIXEDLENGTH THEN targettypsize = CVL(MID$(id2.argsize, curarg * 4 - 4 + 1, 4)) IF id.tsize <> targettypsize THEN Give_Error "Incorrect array type passed to function": EXIT FUNCTION END IF IF MID$(sfcmemargs(targetid), curarg, 1) = CHR$(1) THEN 'cmem required? IF cmemlist(idnum) = 0 THEN cmemlist(idnum) = 1 recompile = 1 END IF END IF IF id.linkid = 0 THEN 'if id.linkid is 0, it means the number of array elements is definietly 'known of the array being passed, this is not some "fake"/unknown array. 'using the numer of array elements of a fake array would be dangerous! IF nelereq = 0 THEN 'only continue if the number of array elements required is unknown 'and it needs to be set IF id.arrayelements <> -1 THEN nelereq = id.arrayelements MID$(id2.nelereq, curarg, 1) = CHR$(nelereq) END IF ids(targetid) = id2 ELSE 'the number of array elements required is known AND 'the number of elements in the array to be passed is known 'REMOVE FOR TESTING PURPOSES ONLY!!! SHOULD BE UNREM'd! 'print id.arrayelements,nelereq ' 1 , 2 IF id.arrayelements <> nelereq THEN Give_Error "Passing arrays with a differing number of elements to a SUB/FUNCTION is not supported (yet)": EXIT FUNCTION END IF END IF e$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN EXIT FUNCTION GOTO dontevaluate END IF 'note: not an array... 'target is not an array IF (targettyp AND ISSTRING) = 0 THEN IF (sourcetyp AND ISREFERENCE) THEN idnum = VAL(LEFT$(e$, INSTR(e$, sp3) - 1)) 'id# of sourcetyp targettyp2 = targettyp: sourcetyp2 = sourcetyp 'get info about source/target arr = 0: IF (sourcetyp2 AND ISARRAY) THEN arr = 1 passudtelement = 0: IF (targettyp2 AND ISUDT) = 0 AND (sourcetyp2 AND ISUDT) <> 0 THEN passudtelement = 1: sourcetyp2 = sourcetyp2 - ISUDT 'remove flags irrelevant for comparison... ISPOINTER,ISREFERENCE,ISINCONVENTIONALMEMORY,ISARRAY targettyp2 = targettyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISFLOAT + ISSTRING) sourcetyp2 = sourcetyp2 AND (511 + ISOFFSETINBITS + ISUDT + ISFLOAT + ISSTRING) 'compare types IF sourcetyp2 = targettyp2 THEN IF sourcetyp AND ISUDT THEN 'udt/udt array 'get info udtrefid = VAL(e$) getid udtrefid IF Error_Happened THEN EXIT FUNCTION udtrefi = INSTR(e$, sp3) 'end of id udtrefi2 = INSTR(udtrefi + 1, e$, sp3) 'end of u udtrefu = VAL(MID$(e$, udtrefi + 1, udtrefi2 - udtrefi - 1)) udtrefi3 = INSTR(udtrefi2 + 1, e$, sp3) 'skip e udtrefe = VAL(MID$(e$, udtrefi2 + 1, udtrefi3 - udtrefi2 - 1)) o$ = RIGHT$(e$, LEN(e$) - udtrefi3) 'note: most of the UDT info above is not required IF arr THEN n2$ = scope$ + "ARRAY_UDT_" + RTRIM$(id.n) + "[0]" ELSE n2$ = scope$ + "UDT_" + RTRIM$(id.n) END IF e$ = "(void*)( ((char*)(" + n2$ + ")) + (" + o$ + ") )" 'convert void* to target type* IF passudtelement THEN e$ = "(" + typ2ctyp$(targettyp2 + (targettyp AND ISUNSIGNED), "") + "*)" + e$ IF Error_Happened THEN EXIT FUNCTION ELSE 'not a udt IF arr THEN IF (sourcetyp2 AND ISOFFSETINBITS) THEN Give_Error "Cannot pass BIT array offsets yet": EXIT FUNCTION e$ = "(&(" + refer(e$, sourcetyp, 0) + "))" IF Error_Happened THEN EXIT FUNCTION ELSE e$ = refer(e$, sourcetyp, 1) IF Error_Happened THEN EXIT FUNCTION END IF 'note: signed/unsigned mismatch requires casting IF (sourcetyp AND ISUNSIGNED) <> (targettyp AND ISUNSIGNED) THEN e$ = "(" + typ2ctyp$(targettyp2 + (targettyp AND ISUNSIGNED), "") + "*)" + e$ IF Error_Happened THEN EXIT FUNCTION END IF END IF 'udt? 'force recompile if target needs to be in cmem and the source is not IF MID$(sfcmemargs(targetid), curarg, 1) = CHR$(1) THEN 'cmem required? IF cmemlist(idnum) = 0 THEN cmemlist(idnum) = 1 recompile = 1 END IF END IF GOTO dontevaluate END IF 'similar 'IF sourcetyp2 = targettyp2 THEN 'IF arr THEN 'IF (sourcetyp2 AND ISOFFSETINBITS) THEN Give_Error "Cannot pass BIT array offsets yet": EXIT FUNCTION 'e$ = "(&(" + refer(e$, sourcetyp, 0) + "))" 'ELSE 'e$ = refer(e$, sourcetyp, 1) 'END IF 'GOTO dontevaluate 'END IF END IF 'source is a reference ELSE 'string 'its a string IF (sourcetyp AND ISREFERENCE) THEN idnum = VAL(LEFT$(e$, INSTR(e$, sp3) - 1)) 'id# of sourcetyp IF MID$(sfcmemargs(targetid), curarg, 1) = CHR$(1) THEN 'cmem required? IF cmemlist(idnum) = 0 THEN cmemlist(idnum) = 1 recompile = 1 END IF END IF END IF 'reference END IF 'string END IF 'dereference was not used END IF 'pointer 'note: Target is not a pointer... 'IF (targettyp AND ISSTRING) = 0 THEN 'IF (sourcetyp AND ISREFERENCE) THEN 'targettyp2 = targettyp: sourcetyp2 = sourcetyp - ISREFERENCE 'IF (sourcetyp2 AND ISINCONVENTIONALMEMORY) THEN sourcetyp2 = sourcetyp2 - ISINCONVENTIONALMEMORY 'IF sourcetyp2 = targettyp2 THEN e$ = refer(e$, sourcetyp, 1): GOTO dontevaluate 'END IF 'END IF 'END IF 'String-numeric mismatch? IF targettyp AND ISSTRING THEN IF (sourcetyp AND ISSTRING) = 0 THEN nth = curarg IF omitarg_last <> 0 AND nth > omitarg_last THEN nth = nth - 1 IF ids(targetid).args = 1 THEN Give_Error "String required for function": EXIT FUNCTION Give_Error str_nth$(nth) + " function argument requires a string": EXIT FUNCTION END IF END IF IF (targettyp AND ISSTRING) = 0 THEN IF sourcetyp AND ISSTRING THEN nth = curarg IF omitarg_last <> 0 AND nth > omitarg_last THEN nth = nth - 1 IF ids(targetid).args = 1 THEN Give_Error "Number required for function": EXIT FUNCTION Give_Error str_nth$(nth) + " function argument requires a number": EXIT FUNCTION END IF END IF 'change to "non-pointer" value IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION END IF IF explicitreference = 0 THEN IF targettyp AND ISUDT THEN nth = curarg IF omitarg_last <> 0 AND nth > omitarg_last THEN nth = nth - 1 x$ = "'" + RTRIM$(udtxcname(targettyp AND 511)) + "'" IF ids(targetid).args = 1 THEN Give_Error "TYPE " + x$ + " required for function": EXIT FUNCTION Give_Error str_nth$(nth) + " function argument requires TYPE " + x$: EXIT FUNCTION END IF ELSE IF sourcetyp AND ISUDT THEN Give_Error "Number required for function": EXIT FUNCTION END IF 'round to integer if required IF (sourcetyp AND ISFLOAT) THEN IF (targettyp AND ISFLOAT) = 0 THEN '**32 rounding fix bits = targettyp AND 511 IF bits <= 16 THEN e$ = "qbr_float_to_long(" + e$ + ")" IF bits > 16 AND bits < 32 THEN e$ = "qbr_double_to_long(" + e$ + ")" IF bits >= 32 THEN e$ = "qbr(" + e$ + ")" END IF END IF IF explicitreference THEN IF (targettyp AND ISOFFSETINBITS) THEN 'integer value can fit inside int64 e$ = "(int64)(" + e$ + ")" ELSE IF (targettyp AND ISFLOAT) THEN IF (targettyp AND 511) = 32 THEN e$ = "(float)(" + e$ + ")" IF (targettyp AND 511) = 64 THEN e$ = "(double)(" + e$ + ")" IF (targettyp AND 511) = 256 THEN e$ = "(long double)(" + e$ + ")" ELSE IF (targettyp AND ISUNSIGNED) THEN IF (targettyp AND 511) = 8 THEN e$ = "(uint8)(" + e$ + ")" IF (targettyp AND 511) = 16 THEN e$ = "(uint16)(" + e$ + ")" IF (targettyp AND 511) = 32 THEN e$ = "(uint32)(" + e$ + ")" IF (targettyp AND 511) = 64 THEN e$ = "(uint64)(" + e$ + ")" ELSE IF (targettyp AND 511) = 8 THEN e$ = "(int8)(" + e$ + ")" IF (targettyp AND 511) = 16 THEN e$ = "(int16)(" + e$ + ")" IF (targettyp AND 511) = 32 THEN e$ = "(int32)(" + e$ + ")" IF (targettyp AND 511) = 64 THEN e$ = "(int64)(" + e$ + ")" END IF END IF 'float? END IF 'offset in bits? END IF 'explicit? IF (targettyp AND ISPOINTER) THEN 'pointer required IF (targettyp AND ISSTRING) THEN GOTO dontevaluate 'no changes required '20090703 t$ = typ2ctyp$(targettyp, "") IF Error_Happened THEN EXIT FUNCTION v$ = "pass" + str2$(uniquenumber) 'assume numeric type IF MID$(sfcmemargs(targetid), curarg, 1) = CHR$(1) THEN 'cmem required? bytesreq = ((targettyp AND 511) + 7) \ 8 PRINT #defdatahandle, t$ + " *" + v$ + "=NULL;" PRINT #13, "if(" + v$ + "==NULL){" PRINT #13, "cmem_sp-=" + str2(bytesreq) + ";" PRINT #13, v$ + "=(" + t$ + "*)(dblock+cmem_sp);" PRINT #13, "if (cmem_spchr" END IF IF LTRIM$(RTRIM$(e$)) = "0" THEN e$ = "NULL" END IF r$ = r$ + e$ '***special case**** IF n$ = "_MEM" THEN IF args = 1 THEN IF curarg = 1 THEN r$ = r$ + ")": GOTO evalfuncspecial END IF IF args = 2 THEN IF curarg = 2 THEN r$ = r$ + ")": GOTO evalfuncspecial END IF END IF IF i <> n AND nocomma = 0 THEN r$ = r$ + "," nocomma = 0 firsti = i + 1 curarg = curarg + 1 END IF IF (curarg >= omitarg_first AND curarg <= omitarg_last) AND i = n THEN targettyp = CVL(MID$(id2.arg, curarg * 4 - 4 + 1, 4)) 'IF (targettyp AND ISSTRING) THEN Give_Error "QB64 doesn't support optional string arguments for functions yet!": EXIT FUNCTION FOR fi = 1 TO omitargs: r$ = r$ + ",NULL": NEXT curarg = curarg + omitargs END IF NEXT END IF IF n$ = "UBOUND" OR n$ = "LBOUND" THEN IF r$ = ",NULL" THEN r$ = ",1" IF n$ = "UBOUND" THEN r2$ = "func_ubound(" ELSE r2$ = "func_lbound(" e$ = refer$(ulboundarray$, sourcetyp, 1) IF Error_Happened THEN EXIT FUNCTION 'note: ID contins refer'ed array info arrayelements = id.arrayelements '2009 IF arrayelements = -1 THEN arrayelements = 1 '2009 r$ = r2$ + e$ + r$ + "," + str2$(arrayelements) + ")" typ& = INTEGER64TYPE - ISPOINTER GOTO evalfuncspecial END IF IF passomit THEN IF omitarg_first THEN r$ = r$ + ",0" ELSE r$ = r$ + ",1" END IF r$ = r$ + ")" evalfuncspecial: IF n$ = "ABS" THEN typ& = sourcetyp 'ABS Note: ABS() returns argument #1's type 'QB-like conversion of math functions returning floating point values IF n$ = "SIN" OR n$ = "COS" OR n$ = "TAN" OR n$ = "ATN" OR n$ = "SQR" OR n$ = "LOG" THEN b = sourcetyp AND 511 IF sourcetyp AND ISFLOAT THEN 'Default is FLOATTYPE IF b = 64 THEN typ& = DOUBLETYPE - ISPOINTER IF b = 32 THEN typ& = SINGLETYPE - ISPOINTER ELSE 'Default is FLOATTYPE IF b <= 32 THEN typ& = DOUBLETYPE - ISPOINTER IF b <= 16 THEN typ& = SINGLETYPE - ISPOINTER END IF END IF IF id2.ret = ISUDT + (1) THEN '***special case*** v$ = "func" + str2$(uniquenumber) PRINT #defdatahandle, "mem_block " + v$ + ";" r$ = "(" + v$ + "=" + r$ + ")" END IF IF id2.ccall THEN IF LEFT$(r$, 11) = "( char* )" THEN r$ = "qbs_new_txt(" + r$ + ")" END IF END IF IF Debug THEN PRINT #9, "evaluatefunc:out:"; r$ evaluatefunc$ = r$ END FUNCTION FUNCTION variablesize$ (i AS LONG) 'ID or -1 (if ID already 'loaded') 'Note: assumes whole bytes, no bit offsets/sizes IF i <> -1 THEN getid i IF Error_Happened THEN EXIT FUNCTION 'find base size from type t = id.t: IF t = 0 THEN t = id.arraytype bytes = (t AND 511) \ 8 IF t AND ISUDT THEN 'correct size for UDTs u = t AND 511 bytes = udtxsize(u) \ 8 END IF IF t AND ISSTRING THEN 'correct size for strings IF t AND ISFIXEDLENGTH THEN bytes = id.tsize ELSE IF id.arraytype THEN Give_Error "Cannot determine size of variable-length string array": EXIT FUNCTION variablesize$ = scope$ + "STRING_" + RTRIM$(id.n) + "->len" EXIT FUNCTION END IF END IF IF id.arraytype THEN 'multiply size for arrays n$ = RTRIM$(id.callname) s$ = str2(bytes) + "*(" + n$ + "[2]&1)" 'note: multiplying by 0 if array not currently defined (affects dynamic arrays) arrayelements = id.arrayelements: IF arrayelements = -1 THEN arrayelements = 1 '2009 FOR i2 = 1 TO arrayelements s$ = s$ + "*" + n$ + "[" + str2(i2 * 4 - 4 + 5) + "]" NEXT variablesize$ = "(" + s$ + ")" EXIT FUNCTION END IF variablesize$ = str2(bytes) END FUNCTION FUNCTION evaluatetotyp$ (a2$, targettyp AS LONG) 'note: 'evaluatetotyp' no longer performs 'fixoperationorder' on a2$ (in many cases, this has already been done) a$ = a2$ e$ = evaluate(a$, sourcetyp) IF Error_Happened THEN EXIT FUNCTION 'Offset protection: IF sourcetyp AND ISOFFSET THEN IF (targettyp AND ISOFFSET) = 0 AND targettyp >= 0 THEN Give_Error "Cannot convert _OFFSET type to other types": EXIT FUNCTION END IF END IF '-5 size '-6 offset IF targettyp = -4 OR targettyp = -5 OR targettyp = -6 THEN '? -> byte_element(offset,element size in bytes) IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected variable name/array element": EXIT FUNCTION IF (sourcetyp AND ISOFFSETINBITS) THEN Give_Error "Variable/element cannot be BIT aligned": EXIT FUNCTION ' print "-4: evaluated as ["+e$+"]":sleep 1 IF (sourcetyp AND ISUDT) THEN 'User Defined Type -> byte_element(offset,bytes) idnumber = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) u = VAL(e$) 'closest parent i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) E = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) o$ = e$ getid idnumber IF Error_Happened THEN EXIT FUNCTION n$ = "UDT_" + RTRIM$(id.n) IF id.arraytype THEN n$ = "ARRAY_" + n$ + "[0]" 'whole array reference examplename()? IF LEFT$(o$, 3) = "(0)" THEN 'use -2 type method GOTO method2usealludt END IF END IF 'determine size of element IF E = 0 THEN 'no specific element, use size of entire type bytes$ = str2(udtxsize(u) \ 8) ELSE 'a specific element bytes$ = str2(udtesize(E) \ 8) END IF dst$ = "(((char*)" + scope$ + n$ + ")+(" + o$ + "))" evaluatetotyp$ = "byte_element((uint64)" + dst$ + "," + bytes$ + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = bytes$ IF targettyp = -6 THEN evaluatetotyp$ = dst$ EXIT FUNCTION END IF IF (sourcetyp AND ISARRAY) THEN 'Array reference -> byte_element(offset,bytes) 'whole array reference examplename()? IF RIGHT$(e$, 2) = sp3 + "0" THEN 'use -2 type method IF sourcetyp AND ISSTRING THEN IF (sourcetyp AND ISFIXEDLENGTH) = 0 THEN Give_Error "Cannot pass array of variable-length strings": EXIT FUNCTION END IF END IF GOTO method2useall END IF 'assume a specific element IF sourcetyp AND ISSTRING THEN IF sourcetyp AND ISFIXEDLENGTH THEN idnumber = VAL(e$) getid idnumber IF Error_Happened THEN EXIT FUNCTION bytes$ = str2(id.tsize) e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION evaluatetotyp$ = "byte_element((uint64)" + e$ + "->chr," + bytes$ + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = bytes$ IF targettyp = -6 THEN evaluatetotyp$ = e$ + "->chr" ELSE e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION evaluatetotyp$ = "byte_element((uint64)" + e$ + "->chr," + e$ + "->len," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = e$ + "->len" IF targettyp = -6 THEN evaluatetotyp$ = e$ + "->chr" END IF EXIT FUNCTION END IF e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION e$ = "(&(" + e$ + "))" bytes$ = str2((sourcetyp AND 511) \ 8) evaluatetotyp$ = "byte_element((uint64)" + e$ + "," + bytes$ + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = bytes$ IF targettyp = -6 THEN evaluatetotyp$ = e$ EXIT FUNCTION END IF IF sourcetyp AND ISSTRING THEN 'String -> byte_element(offset,bytes) IF sourcetyp AND ISFIXEDLENGTH THEN idnumber = VAL(e$) getid idnumber IF Error_Happened THEN EXIT FUNCTION bytes$ = str2(id.tsize) e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION ELSE e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION bytes$ = e$ + "->len" END IF evaluatetotyp$ = "byte_element((uint64)" + e$ + "->chr," + bytes$ + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = bytes$ IF targettyp = -6 THEN evaluatetotyp$ = e$ + "->chr" EXIT FUNCTION END IF 'Standard variable -> byte_element(offset,bytes) e$ = refer(e$, sourcetyp, 1) 'get the variable's formal name IF Error_Happened THEN EXIT FUNCTION size = (sourcetyp AND 511) \ 8 'calculate its size in bytes evaluatetotyp$ = "byte_element((uint64)" + e$ + "," + str2(size) + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = str2(size) IF targettyp = -6 THEN evaluatetotyp$ = e$ EXIT FUNCTION END IF '-4, -5, -6 IF targettyp = -8 THEN '? -> _MEM structure helper {offset, fullsize, typeval, elementsize, sf_mem_lock|???} IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected variable name/array element": EXIT FUNCTION IF (sourcetyp AND ISOFFSETINBITS) THEN Give_Error "Variable/element cannot be BIT aligned": EXIT FUNCTION IF (sourcetyp AND ISUDT) THEN 'User Defined Type -> byte_element(offset,bytes) idnumber = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) u = VAL(e$) 'closest parent i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) E = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) o$ = e$ getid idnumber IF Error_Happened THEN EXIT FUNCTION n$ = "UDT_" + RTRIM$(id.n) IF id.arraytype THEN n$ = "ARRAY_" + n$ + "[0]" 'whole array reference examplename()? IF LEFT$(o$, 3) = "(0)" THEN 'use -7 type method GOTO method2usealludt__7 END IF END IF 'determine size of element IF E = 0 THEN 'no specific element, use size of entire type bytes$ = str2(udtxsize(u) \ 8) t1 = ISUDT + udtetype(u) ELSE 'a specific element bytes$ = str2(udtesize(E) \ 8) t1 = udtetype(E) END IF dst$ = "(((char*)" + scope$ + n$ + ")+(" + o$ + "))" 'evaluatetotyp$ = "byte_element((uint64)" + dst$ + "," + bytes$ + "," + NewByteElement$ + ")" 'IF targettyp = -5 THEN evaluatetotyp$ = bytes$ 'IF targettyp = -6 THEN evaluatetotyp$ = dst$ t = Type2MemTypeValue(t1) evaluatetotyp$ = "(ptrszint)" + dst$ + "," + bytes$ + "," + str2(t) + "," + bytes$ + ",sf_mem_lock" EXIT FUNCTION END IF IF (sourcetyp AND ISARRAY) THEN 'Array reference -> byte_element(offset,bytes) 'whole array reference examplename()? IF RIGHT$(e$, 2) = sp3 + "0" THEN 'use -7 type method IF sourcetyp AND ISSTRING THEN IF (sourcetyp AND ISFIXEDLENGTH) = 0 THEN Give_Error "Cannot pass array of variable-length strings": EXIT FUNCTION END IF END IF GOTO method2useall__7 END IF idnumber = VAL(e$) getid idnumber IF Error_Happened THEN EXIT FUNCTION n$ = RTRIM$(id.callname) lk$ = "(mem_lock*)((ptrszint*)" + n$ + ")[" + str2(4 * id.arrayelements + 4 + 1 - 1) + "]" 'assume a specific element IF sourcetyp AND ISSTRING THEN IF sourcetyp AND ISFIXEDLENGTH THEN bytes$ = str2(id.tsize) e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION 'evaluatetotyp$ = "byte_element((uint64)" + e$ + "->chr," + bytes$ + "," + NewByteElement$ + ")" 'IF targettyp = -5 THEN evaluatetotyp$ = bytes$ 'IF targettyp = -6 THEN evaluatetotyp$ = e$ + "->chr" t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + e$ + "->chr," + bytes$ + "," + str2(t) + "," + bytes$ + "," + lk$ ELSE Give_Error "_MEMELEMENT cannot reference variable-length strings": EXIT FUNCTION END IF EXIT FUNCTION END IF e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION e$ = "(&(" + e$ + "))" bytes$ = str2((sourcetyp AND 511) \ 8) 'evaluatetotyp$ = "byte_element((uint64)" + e$ + "," + bytes$ + "," + NewByteElement$ + ")" 'IF targettyp = -5 THEN evaluatetotyp$ = bytes$ 'IF targettyp = -6 THEN evaluatetotyp$ = e$ t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + e$ + "," + bytes$ + "," + str2(t) + "," + bytes$ + "," + lk$ EXIT FUNCTION END IF 'isarray IF sourcetyp AND ISSTRING THEN 'String -> byte_element(offset,bytes) IF sourcetyp AND ISFIXEDLENGTH THEN idnumber = VAL(e$) getid idnumber IF Error_Happened THEN EXIT FUNCTION bytes$ = str2(id.tsize) e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION ELSE Give_Error "_MEMELEMENT cannot reference variable-length strings": EXIT FUNCTION END IF 'evaluatetotyp$ = "byte_element((uint64)" + e$ + "->chr," + bytes$ + "," + NewByteElement$ + ")" 'IF targettyp = -5 THEN evaluatetotyp$ = bytes$ 'IF targettyp = -6 THEN evaluatetotyp$ = e$ + "->chr" t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + e$ + "->chr," + bytes$ + "," + str2(t) + "," + bytes$ + ",sf_mem_lock" EXIT FUNCTION END IF 'Standard variable -> byte_element(offset,bytes) e$ = refer(e$, sourcetyp, 1) 'get the variable's formal name IF Error_Happened THEN EXIT FUNCTION size = (sourcetyp AND 511) \ 8 'calculate its size in bytes 'evaluatetotyp$ = "byte_element((uint64)" + e$ + "," + str2(size) + "," + NewByteElement$ + ")" 'IF targettyp = -5 THEN evaluatetotyp$ = str2(size) 'IF targettyp = -6 THEN evaluatetotyp$ = e$ t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + e$ + "," + str2(size) + "," + str2(t) + "," + str2(size) + ",sf_mem_lock" EXIT FUNCTION END IF '-8 IF targettyp = -7 THEN '? -> _MEM structure helper {offset, fullsize, typeval, elementsize, sf_mem_lock|???} method2useall__7: IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected variable name/array element": EXIT FUNCTION IF (sourcetyp AND ISOFFSETINBITS) THEN Give_Error "Variable/element cannot be BIT aligned": EXIT FUNCTION 'User Defined Type IF (sourcetyp AND ISUDT) THEN ' print "CI: -2 type from a UDT":sleep 1 idnumber = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) u = VAL(e$) 'closest parent i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) E = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) o$ = e$ getid idnumber IF Error_Happened THEN EXIT FUNCTION n$ = "UDT_" + RTRIM$(id.n): IF id.arraytype THEN n$ = "ARRAY_" + n$ + "[0]" method2usealludt__7: bytes$ = variablesize$(-1) + "-(" + o$ + ")" IF Error_Happened THEN EXIT FUNCTION dst$ = "(((char*)" + scope$ + n$ + ")+(" + o$ + "))" 'evaluatetotyp$ = "byte_element((uint64)" + dst$ + "," + bytes$ + "," + NewByteElement$ + ")" 'note: myudt.myelement results in a size of 1 because it is a continuous run of no consistent granularity IF E <> 0 THEN size = 1 ELSE size = udtxsize(u) \ 8 t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + dst$ + "," + bytes$ + "," + str2(t) + "," + str2(size) + ",sf_mem_lock" EXIT FUNCTION END IF 'Array reference IF (sourcetyp AND ISARRAY) THEN IF sourcetyp AND ISSTRING THEN IF (sourcetyp AND ISFIXEDLENGTH) = 0 THEN Give_Error "_MEM cannot reference variable-length strings": EXIT FUNCTION END IF END IF idnumber = VAL(e$) getid idnumber IF Error_Happened THEN EXIT FUNCTION n$ = RTRIM$(id.callname) lk$ = "(mem_lock*)((ptrszint*)" + n$ + ")[" + str2(4 * id.arrayelements + 4 + 1 - 1) + "]" tsize = id.tsize 'used later to determine element size of fixed length strings 'note: array references consist of idnumber|unmultiplied-element-index index$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'get element index bytes$ = variablesize$(-1) IF Error_Happened THEN EXIT FUNCTION e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION IF sourcetyp AND ISSTRING THEN e$ = "((" + e$ + ")->chr)" '[2013] handle fixed string arrays differently because they are already pointers ELSE e$ = "(&(" + e$ + "))" END IF ' print "CI: array: e$["+e$+"], bytes$["+bytes$+"]":sleep 1 'calculate size of elements IF sourcetyp AND ISSTRING THEN bytes = tsize ELSE bytes = (sourcetyp AND 511) \ 8 END IF bytes$ = bytes$ + "-(" + str2(bytes) + "*(" + index$ + "))" t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + e$ + "," + bytes$ + "," + str2(t) + "," + str2(bytes) + "," + lk$ EXIT FUNCTION END IF 'String IF sourcetyp AND ISSTRING THEN IF (sourcetyp AND ISFIXEDLENGTH) = 0 THEN Give_Error "_MEM cannot reference variable-length strings": EXIT FUNCTION idnumber = VAL(e$) getid idnumber: IF Error_Happened THEN EXIT FUNCTION bytes$ = str2(id.tsize) e$ = refer(e$, sourcetyp, 0): IF Error_Happened THEN EXIT FUNCTION t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + e$ + "->chr," + bytes$ + "," + str2(t) + "," + bytes$ + ",sf_mem_lock" EXIT FUNCTION END IF 'Standard variable -> byte_element(offset,bytes) e$ = refer(e$, sourcetyp, 1) 'get the variable's formal name IF Error_Happened THEN EXIT FUNCTION size = (sourcetyp AND 511) \ 8 'calculate its size in bytes t = Type2MemTypeValue(sourcetyp) evaluatetotyp$ = "(ptrszint)" + e$ + "," + str2(size) + "," + str2(t) + "," + str2(size) + ",sf_mem_lock" EXIT FUNCTION END IF '-7 _MEM structure helper IF targettyp = -2 THEN '? -> byte_element(offset,max possible bytes) method2useall: ' print "CI: eval2typ detected target type of -2 for ["+a2$+"] evaluated as ["+e$+"]":sleep 1 IF (sourcetyp AND ISREFERENCE) = 0 THEN Give_Error "Expected variable name/array element": EXIT FUNCTION IF (sourcetyp AND ISOFFSETINBITS) THEN Give_Error "Variable/element cannot be BIT aligned": EXIT FUNCTION 'User Defined Type -> byte_element(offset,bytes) IF (sourcetyp AND ISUDT) THEN ' print "CI: -2 type from a UDT":sleep 1 idnumber = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) u = VAL(e$) 'closest parent i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) E = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i) o$ = e$ getid idnumber IF Error_Happened THEN EXIT FUNCTION n$ = "UDT_" + RTRIM$(id.n): IF id.arraytype THEN n$ = "ARRAY_" + n$ + "[0]" method2usealludt: bytes$ = variablesize$(-1) + "-(" + o$ + ")" IF Error_Happened THEN EXIT FUNCTION dst$ = "(((char*)" + scope$ + n$ + ")+(" + o$ + "))" evaluatetotyp$ = "byte_element((uint64)" + dst$ + "," + bytes$ + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = bytes$ IF targettyp = -6 THEN evaluatetotyp$ = dst$ EXIT FUNCTION END IF 'Array reference -> byte_element(offset,bytes) IF (sourcetyp AND ISARRAY) THEN 'array of variable length strings (special case, can only refer to single element) IF sourcetyp AND ISSTRING THEN IF (sourcetyp AND ISFIXEDLENGTH) = 0 THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION evaluatetotyp$ = "byte_element((uint64)" + e$ + "->chr," + e$ + "->len," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = e$ + "->len" IF targettyp = -6 THEN evaluatetotyp$ = e$ + "->chr" EXIT FUNCTION END IF END IF idnumber = VAL(e$) getid idnumber IF Error_Happened THEN EXIT FUNCTION tsize = id.tsize 'used later to determine element size of fixed length strings 'note: array references consist of idnumber|unmultiplied-element-index index$ = RIGHT$(e$, LEN(e$) - INSTR(e$, sp3)) 'get element index bytes$ = variablesize$(-1) IF Error_Happened THEN EXIT FUNCTION e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION e$ = "(&(" + e$ + "))" ' print "CI: array: e$["+e$+"], bytes$["+bytes$+"]":sleep 1 'calculate size of elements IF sourcetyp AND ISSTRING THEN bytes = tsize ELSE bytes = (sourcetyp AND 511) \ 8 END IF bytes$ = bytes$ + "-(" + str2(bytes) + "*(" + index$ + "))" evaluatetotyp$ = "byte_element((uint64)" + e$ + "," + bytes$ + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = bytes$ IF targettyp = -6 THEN evaluatetotyp$ = e$ ' print "CI: array ->["+"byte_element((uint64)" + e$ + "," + bytes$+ ","+NewByteElement$+")"+"]":sleep 1 EXIT FUNCTION END IF 'String -> byte_element(offset,bytes) IF sourcetyp AND ISSTRING THEN IF sourcetyp AND ISFIXEDLENGTH THEN idnumber = VAL(e$) getid idnumber IF Error_Happened THEN EXIT FUNCTION bytes$ = str2(id.tsize) e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION ELSE e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION bytes$ = e$ + "->len" END IF evaluatetotyp$ = "byte_element((uint64)" + e$ + "->chr," + bytes$ + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = bytes$ IF targettyp = -6 THEN evaluatetotyp$ = e$ + "->chr" EXIT FUNCTION END IF 'Standard variable -> byte_element(offset,bytes) e$ = refer(e$, sourcetyp, 1) 'get the variable's formal name IF Error_Happened THEN EXIT FUNCTION size = (sourcetyp AND 511) \ 8 'calculate its size in bytes evaluatetotyp$ = "byte_element((uint64)" + e$ + "," + str2(size) + "," + NewByteElement$ + ")" IF targettyp = -5 THEN evaluatetotyp$ = str2(size) IF targettyp = -6 THEN evaluatetotyp$ = e$ EXIT FUNCTION END IF '-2 byte_element(offset,bytes) 'string? IF (sourcetyp AND ISSTRING) <> (targettyp AND ISSTRING) THEN Give_Error "Illegal string-number conversion": EXIT FUNCTION END IF IF (sourcetyp AND ISSTRING) THEN evaluatetotyp$ = e$ IF (sourcetyp AND ISREFERENCE) THEN evaluatetotyp$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION END IF EXIT FUNCTION END IF 'pointer required? IF (targettyp AND ISPOINTER) THEN Give_Error "evaluatetotyp received a request for a pointer! (as yet unsupported)": EXIT FUNCTION '... Give_Error "Invalid pointer": EXIT FUNCTION END IF 'change to "non-pointer" value IF (sourcetyp AND ISREFERENCE) THEN e$ = refer(e$, sourcetyp, 0) IF Error_Happened THEN EXIT FUNCTION END IF 'check if successful IF (sourcetyp AND ISPOINTER) THEN Give_Error "evaluatetotyp couldn't convert pointer type!": EXIT FUNCTION END IF 'round to integer if required IF (sourcetyp AND ISFLOAT) THEN IF (targettyp AND ISFLOAT) = 0 THEN bits = targettyp AND 511 '**32 rounding fix IF bits <= 16 THEN e$ = "qbr_float_to_long(" + e$ + ")" IF bits > 16 AND bits < 32 THEN e$ = "qbr_double_to_long(" + e$ + ")" IF bits >= 32 THEN e$ = "qbr(" + e$ + ")" END IF END IF evaluatetotyp$ = e$ END FUNCTION FUNCTION findid& (n2$) n$ = UCASE$(n2$) 'case insensitive 'return all strings as 'not found' IF ASC(n$) = 34 THEN GOTO noid 'if findidsecondarg was set, it will be used for finding the name of a sub (not a func or variable) secondarg$ = findidsecondarg: findidsecondarg = "" 'if findanotherid was set, findid will continue scan from last index, otherwise, it will begin a new search findanother = findanotherid: findanotherid = 0 IF findanother <> 0 AND findidinternal <> 2 THEN Give_Error "FINDID() ERROR: Invalid repeat search requested!": EXIT FUNCTION 'cannot continue search, no more indexes left! IF Error_Happened THEN EXIT FUNCTION '(the above should never happen) findid& = 2 '2=not finished searching all indexes 'seperate symbol from name (if a symbol has been added), this is the only way symbols can be passed to findid i = 0 i = INSTR(n$, "~"): IF i THEN GOTO gotsc i = INSTR(n$, "`"): IF i THEN GOTO gotsc i = INSTR(n$, "%"): IF i THEN GOTO gotsc i = INSTR(n$, "&"): IF i THEN GOTO gotsc i = INSTR(n$, "!"): IF i THEN GOTO gotsc i = INSTR(n$, "#"): IF i THEN GOTO gotsc i = INSTR(n$, "$"): IF i THEN GOTO gotsc gotsc: IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1) IF sc$ = "`" OR sc$ = "~`" THEN sc$ = sc$ + "1" 'clarify abbreviated 1 bit reference ELSE ''' 'no symbol passed, so check what symbol could be assumed under the current DEF... ''' v = ASC(n$): IF v = 95 THEN v = 27 ELSE v = v - 64 ''' IF v >= 1 AND v <= 27 THEN 'safeguard against n$ not being a standard name ''' couldhavesc$ = defineextaz(v) ''' IF couldhavesc$ = "`" OR couldhavesc$ = "~`" THEN couldhavesc$ = couldhavesc$ + "1" 'clarify abbreviated 1 bit reference ''' END IF 'safeguard END IF 'optomizations for later comparisons insf$ = subfunc + SPACE$(256 - LEN(subfunc)) secondarg$ = secondarg$ + SPACE$(256 - LEN(secondarg$)) IF LEN(sc$) THEN scpassed = 1: sc$ = sc$ + SPACE$(8 - LEN(sc$)) ELSE scpassed = 0 '''IF LEN(couldhavesc$) THEN couldhavesc$ = couldhavesc$ + SPACE$(8 - LEN(couldhavesc$)): couldhavescpassed = 1 ELSE couldhavescpassed = 0 IF LEN(n$) < 256 THEN n$ = n$ + SPACE$(256 - LEN(n$)) 'FUNCTION HashFind (a$, searchflags, resultflags, resultreference) '(0,1,2)z=hashfind[rev]("RUMI",Hashflag_label,resflag,resref) '0=doesn't exist '1=found, no more items to scan '2=found, more items still to scan 'NEW HASH SYSTEM n$ = RTRIM$(n$) IF findanother THEN hashretry: z = HashFindCont(unrequired, i) ELSE z = HashFindRev(n$, 1, unrequired, i) END IF findidinternal = z IF z = 0 THEN GOTO noid findid = z 'continue from previous position? ''IF findanother THEN start = findidinternal ELSE start = idn ''FOR i = start TO 1 STEP -1 '' findidinternal = i - 1 '' IF findidinternal = 0 THEN findid& = 1 '1=found id, but no more to search '' IF ids(i).n = n$ THEN 'same name? 'in scope? IF ids(i).subfunc = 0 AND ids(i).share = 0 THEN 'scope check required (not a shared variable or the name of a sub/function) IF ids(i).insubfunc <> insf$ THEN GOTO findidnomatch END IF 'some subs require a second argument (eg. PUT #, DEF SEG, etc.) IF ids(i).subfunc = 2 THEN IF ASC(ids(i).secondargmustbe) <> 32 THEN 'exists? IF secondarg$ <> ids(i).secondargmustbe THEN GOTO findidnomatch END IF IF ASC(ids(i).secondargcantbe) <> 32 THEN 'exists? IF secondarg$ = ids(i).secondargcantbe THEN GOTO findidnomatch END IF END IF 'second sub argument possible 'must have symbol? 'typically for variables defined automatically or by a symbol and not the full type name imusthave = CVI(ids(i).musthave) 'speed up checks of first 2 characters amusthave = imusthave AND 255 'speed up checks of first character IF amusthave <> 32 THEN IF scpassed THEN IF sc$ = ids(i).musthave THEN GOTO findidok END IF ''' IF couldhavescpassed THEN ''' IF couldhavesc$ = ids(i).musthave THEN GOTO findidok ''' END IF 'Q: why is the above triple-commented? 'A: because if something must have a symbol to refer to it, then a could-have is ' not sufficient, and it could mask shared variables in global scope 'note: symbol defined fixed length strings cannot be referred to by $ without an extension 'note: sc$ and couldhavesc$ are already changed from ` to `1 to match stored musthave GOTO findidnomatch END IF 'may have symbol? 'typically for variables formally dim'd 'note: couldhavesc$ needn't be considered for mayhave checks IF scpassed THEN 'symbol was passed, so it must match the mayhave symbol imayhave = CVI(ids(i).mayhave) 'speed up checks of first 2 characters amayhave = imayhave AND 255 'speed up checks of first character IF amayhave = 32 THEN GOTO findidnomatch 'it cannot have the symbol passed (nb. musthave symbols have already been ok'd) 'note: variable length strings are not a problem here, as they can only have one possible extension IF amayhave = 36 THEN '"$" IF imayhave <> 8228 THEN '"$ " 'it is a fixed length string IF CVI(sc$) = 8228 THEN GOTO findidok 'allow myvariable$ to become myvariable$10 'allow later comparison to verify if extension is correct END IF END IF IF sc$ <> ids(i).mayhave THEN GOTO findidnomatch END IF 'scpassed 'return id findidok: id = ids(i) currentid = i EXIT FUNCTION 'END IF 'same name findidnomatch: 'NEXT IF z = 2 THEN GOTO hashretry 'totally unclassifiable noid: findid& = 0 currentid = -1 END FUNCTION FUNCTION FindArray (secure$) FindArray = -1 n$ = secure$ IF Debug THEN PRINT #9, "func findarray:in:" + n$ IF alphanumeric(ASC(n$)) = 0 THEN FindArray = 0: EXIT FUNCTION 'establish whether n$ includes an extension i = INSTR(n$, "~"): IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1): GOTO gotsc2 i = INSTR(n$, "`"): IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1): GOTO gotsc2 i = INSTR(n$, "%"): IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1): GOTO gotsc2 i = INSTR(n$, "&"): IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1): GOTO gotsc2 i = INSTR(n$, "!"): IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1): GOTO gotsc2 i = INSTR(n$, "#"): IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1): GOTO gotsc2 i = INSTR(n$, "$"): IF i THEN sc$ = RIGHT$(n$, LEN(n$) - i + 1): n$ = LEFT$(n$, i - 1): GOTO gotsc2 gotsc2: n2$ = n$ + sc$ IF sc$ <> "" THEN 'has an extension 'note! findid must unambiguify ` to `5 or $ to $10 where applicable try = findid(n2$): IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF id.arraytype THEN EXIT FUNCTION END IF IF try = 2 THEN findanotherid = 1: try = findid(n2$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP ELSE 'no extension '1. pass as is, without any extension (local) try = findid(n2$): IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF id.arraytype THEN IF subfuncn = 0 THEN EXIT FUNCTION IF id.insubfuncn = subfuncn THEN EXIT FUNCTION END IF IF try = 2 THEN findanotherid = 1: try = findid(n2$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP '2. that failed, so apply the _define'd extension and pass (local) a = ASC(UCASE$(n$)): IF a = 95 THEN a = 91 a = a - 64 'so A=1, Z=27 and _=28 n2$ = n$ + defineextaz(a) try = findid(n2$): IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF id.arraytype THEN IF subfuncn = 0 THEN EXIT FUNCTION IF id.insubfuncn = subfuncn THEN EXIT FUNCTION EXIT FUNCTION END IF IF try = 2 THEN findanotherid = 1: try = findid(n2$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP '3. pass as is, without any extension (global) n2$ = n$ try = findid(n2$): IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF id.arraytype THEN EXIT FUNCTION END IF IF try = 2 THEN findanotherid = 1: try = findid(n2$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP '4. that failed, so apply the _define'd extension and pass (global) a = ASC(UCASE$(n$)): IF a = 95 THEN a = 91 a = a - 64 'so A=1, Z=27 and _=28 n2$ = n$ + defineextaz(a) try = findid(n2$): IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF id.arraytype THEN EXIT FUNCTION END IF IF try = 2 THEN findanotherid = 1: try = findid(n2$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF FindArray = 0 END FUNCTION FUNCTION fixoperationorder$ (savea$) a$ = savea$ IF Debug THEN PRINT #9, "fixoperationorder:in:" + a$ fooindwel = fooindwel + 1 n = numelements(a$) 'n is maintained throughout function IF fooindwel = 1 THEN 'actions to take on initial call only '----------------A. 'Quick' mismatched brackets check---------------- b = 0 a2$ = sp + a$ + sp b1$ = sp + "(" + sp b2$ = sp + ")" + sp i = 1 findmmb: i1 = INSTR(i, a2$, b1$) i2 = INSTR(i, a2$, b2$) i3 = i1 IF i2 THEN IF i1 = 0 THEN i3 = i2 ELSE IF i2 < i1 THEN i3 = i2 END IF END IF IF i3 THEN IF i3 = i1 THEN b = b + 1 IF i3 = i2 THEN b = b - 1 i = i3 + 2 IF b < 0 THEN Give_Error "Missing (": EXIT FUNCTION GOTO findmmb END IF IF b > 0 THEN Give_Error "Missing )": EXIT FUNCTION '----------------B. 'Quick' correction of over-use of +,- ---------------- 'note: the results of this change are beneficial to foolayout a2$ = sp + a$ + sp 'rule 1: change ++ to + rule1: i = INSTR(a2$, sp + "+" + sp + "+" + sp) IF i THEN a2$ = LEFT$(a2$, i + 2) + RIGHT$(a2$, LEN(a2$) - i - 4) a$ = MID$(a2$, 2, LEN(a2$) - 2) n = n - 1 IF Debug THEN PRINT #9, "fixoperationorder:+/-:" + a$ GOTO rule1 END IF 'rule 2: change -+ to - rule2: i = INSTR(a2$, sp + "-" + sp + "+" + sp) IF i THEN a2$ = LEFT$(a2$, i + 2) + RIGHT$(a2$, LEN(a2$) - i - 4) a$ = MID$(a2$, 2, LEN(a2$) - 2) n = n - 1 IF Debug THEN PRINT #9, "fixoperationorder:+/-:" + a$ GOTO rule2 END IF 'rule 3: change anyoperator-- to anyoperator rule3: IF INSTR(a2$, sp + "-" + sp + "-" + sp) THEN FOR i = 1 TO n - 2 IF isoperator(getelement(a$, i)) THEN IF getelement(a$, i + 1) = "-" THEN IF getelement(a$, i + 2) = "-" THEN removeelements a$, i + 1, i + 2, 0 a2$ = sp + a$ + sp n = n - 2 IF Debug THEN PRINT #9, "fixoperationorder:+/-:" + a$ GOTO rule3 END IF END IF END IF NEXT END IF 'rule 3 '----------------C. 'Quick' location of negation---------------- 'note: the results of this change are beneficial to foolayout 'for numbers... 'before: anyoperator,-,number 'after: anyoperator,-number 'for variables... 'before: anyoperator,-,variable 'after: anyoperator,ñ,variable 'exception for numbers followed by ^... (they will be bracketed up along with the ^ later) 'before: anyoperator,-,number,^ 'after: anyoperator,ñ,number,^ FOR i = 1 TO n - 1 IF i > n - 1 THEN EXIT FOR 'n changes, so manually exit if required IF ASC(getelement(a$, i)) = 45 THEN '- neg = 0 IF i = 1 THEN neg = 1 ELSE a2$ = getelement(a$, i - 1) c = ASC(a2$) IF c = 40 OR c = 44 THEN '(, neg = 1 ELSE IF isoperator(a2$) THEN neg = 1 END IF '() END IF 'i=1 IF neg = 1 THEN a2$ = getelement(a$, i + 1) c = ASC(a2$) IF c >= 48 AND c <= 57 THEN c2 = 0: IF i < n - 1 THEN c2 = ASC(getelement(a$, i + 2)) IF c2 <> 94 THEN 'not ^ 'number... i2 = INSTR(a2$, ",") IF i2 AND ASC(a2$, i2 + 1) <> 38 THEN '&H/&O/&B values don't need the assumed negation a2$ = "-" + LEFT$(a2$, i2) + "-" + RIGHT$(a2$, LEN(a2$) - i2) ELSE a2$ = "-" + a2$ END IF removeelements a$, i, i + 1, 0 insertelements a$, i - 1, a2$ n = n - 1 IF Debug THEN PRINT #9, "fixoperationorder:negation:" + a$ GOTO negdone END IF END IF 'not a number (or for exceptions)... removeelements a$, i, i, 0 insertelements a$, i - 1, "ñ" IF Debug THEN PRINT #9, "fixoperationorder:negation:" + a$ END IF 'isoperator END IF '- negdone: NEXT END IF 'fooindwel=1 '----------------D. 'Quick' Add 'power of' with negation {}bracketing to bottom bracket level---------------- pownegused = 0 powneg: IF INSTR(a$, "^" + sp + "ñ") THEN 'quick check b = 0 b1 = 0 FOR i = 1 TO n a2$ = getelement(a$, i) c = ASC(a2$) IF c = 40 THEN b = b + 1 IF c = 41 THEN b = b - 1 IF b = 0 THEN IF b1 THEN IF isoperator(a2$) THEN IF a2$ <> "^" AND a2$ <> "ñ" THEN insertelements a$, i - 1, "}" insertelements a$, b1, "{" n = n + 2 IF Debug THEN PRINT #9, "fixoperationorder:^-:" + a$ GOTO powneg pownegused = 1 END IF END IF END IF IF c = 94 THEN '^ IF getelement$(a$, i + 1) = "ñ" THEN b1 = i: i = i + 1 END IF END IF 'b=0 NEXT i IF b1 THEN insertelements a$, b1, "{" a$ = a$ + sp + "}" n = n + 2 IF Debug THEN PRINT #9, "fixoperationorder:^-:" + a$ pownegused = 1 GOTO powneg END IF END IF 'quick check '----------------E. Find lowest & highest operator level in bottom bracket level---------------- NOT_recheck: lco = 255 hco = 0 b = 0 FOR i = 1 TO n a2$ = getelement(a$, i) c = ASC(a2$) IF c = 40 OR c = 123 THEN b = b + 1 IF c = 41 OR c = 125 THEN b = b - 1 IF b = 0 THEN op = isoperator(a2$) IF op THEN IF op < lco THEN lco = op IF op > hco THEN hco = op END IF END IF NEXT '----------------F. Add operator {}bracketting---------------- 'apply bracketting only if required IF hco <> 0 THEN 'operators were used IF lco <> hco THEN 'brackets needed IF lco = 6 THEN 'NOT exception 'Step 1: Add brackets as follows ~~~ ( NOT ( ~~~ NOT ~~~ NOT ~~~ NOT ~~~ )) 'Step 2: Recheck line from beginning IF n = 1 THEN Give_Error "Expected NOT ...": EXIT FUNCTION b = 0 FOR i = 1 TO n a2$ = getelement(a$, i) c = ASC(a2$) IF c = 40 OR c = 123 THEN b = b + 1 IF c = 41 OR c = 125 THEN b = b - 1 IF b = 0 THEN IF UCASE$(a2$) = "NOT" THEN IF i = n THEN Give_Error "Expected NOT ...": EXIT FUNCTION IF i = 1 THEN a$ = "NOT" + sp + "{" + sp + getelements$(a$, 2, n) + sp + "}": n = n + 2: GOTO lco_bracketting_done a$ = getelements$(a$, 1, i - 1) + sp + "{" + sp + "NOT" + sp + "{" + sp + getelements$(a$, i + 1, n) + sp + "}" + sp + "}" n = n + 4 GOTO NOT_recheck END IF 'not END IF 'b=0 NEXT END IF 'NOT exception n2 = n b = 0 a3$ = "{" n = 1 FOR i = 1 TO n2 a2$ = getelement(a$, i) c = ASC(a2$) IF c = 40 OR c = 123 THEN b = b + 1 IF c = 41 OR c = 125 THEN b = b - 1 IF b = 0 THEN op = isoperator(a2$) IF op = lco THEN IF i = 1 THEN a3$ = a2$ + sp + "{" n = 2 ELSE IF i = n2 THEN Give_Error "Expected variable/value after '" + UCASE$(a2$) + "'": EXIT FUNCTION a3$ = a3$ + sp + "}" + sp + a2$ + sp + "{" n = n + 3 END IF GOTO fixop0 END IF END IF 'b=0 a3$ = a3$ + sp + a2$ n = n + 1 fixop0: NEXT a3$ = a3$ + sp + "}" n = n + 1 a$ = a3$ lco_bracketting_done: IF Debug THEN PRINT #9, "fixoperationorder:lco bracketing["; lco; ","; hco; "]:" + a$ '--------(F)G. Remove indwelling {}bracketting from power-negation-------- IF pownegused THEN b = 0 i = 0 DO WHILE i <= n i = i + 1 c = ASC(getelement(a$, i)) IF c = 41 OR c = 125 THEN b = b - 1 IF (c = 123 OR c = 125) AND b <> 0 THEN removeelements a$, i, i, 0 n = n - 1 i = i - 1 IF Debug THEN PRINT #9, "fixoperationorder:^- {} removed:" + a$ END IF IF c = 40 OR c = 123 THEN b = b + 1 LOOP END IF 'pownegused END IF 'lco <> hco END IF 'hco <> 0 '--------Bracketting of multiple NOT/negation unary operators-------- IF LEFT$(a$, 4) = "ñ" + sp + "ñ" + sp THEN a$ = "ñ" + sp + "{" + sp + getelements$(a$, 2, n) + sp + "}": n = n + 2 END IF IF UCASE$(LEFT$(a$, 8)) = "NOT" + sp + "NOT" + sp THEN a$ = "NOT" + sp + "{" + sp + getelements$(a$, 2, n) + sp + "}": n = n + 2 END IF '----------------H. Identification/conversion of elements within bottom bracket level---------------- 'actions performed: ' ->builds f$(tlayout) ' ->adds symbols to all numbers ' ->evaluates constants to numbers f$ = "" b = 0 c = 0 lastt = 0: lastti = 0 FOR i = 1 TO n f2$ = getelement(a$, i) lastc = c c = ASC(f2$) IF c = 40 OR c = 123 THEN IF c <> 40 OR b <> 0 THEN f2$ = "" 'skip temporary & indwelling brackets b = b + 1 GOTO classdone END IF IF c = 41 OR c = 125 THEN b = b - 1 'check for "("+sp+")" after literal-string, operator, number or nothing IF b = 0 THEN 'must be within the lowest level IF c = 41 THEN IF lastc = 40 THEN IF lastti = i - 2 OR lastti = 0 THEN IF lastt >= 0 AND lastt <= 3 THEN Give_Error "Unexpected (": EXIT FUNCTION END IF END IF END IF END IF END IF IF c <> 41 OR b <> 0 THEN f2$ = "" 'skip temporary & indwelling brackets GOTO classdone END IF IF b = 0 THEN 'classifications/conversions: '1. quoted string ("....) '2. number '3. operator '4. constant '5. variable/array/udt/function (note: nothing can share the same name as a function except a label) 'quoted string? IF c = 34 THEN '" lastt = 1: lastti = i 'convert \\ to \ 'convert \??? to CHR$(&O???) x2 = 1 x = INSTR(x2, f2$, "\") DO WHILE x c2 = ASC(f2$, x + 1) IF c2 = 92 THEN '\\ f2$ = LEFT$(f2$, x) + RIGHT$(f2$, LEN(f2$) - x - 1) 'remove second \ x2 = x + 1 ELSE 'octal triplet value c3 = (ASC(f2$, x + 3) - 48) + (ASC(f2$, x + 2) - 48) * 8 + (ASC(f2$, x + 1) - 48) * 64 f2$ = LEFT$(f2$, x - 1) + CHR$(c3) + RIGHT$(f2$, LEN(f2$) - x - 3) x2 = x + 1 END IF x = INSTR(x2, f2$, "\") LOOP 'remove ',len' (if it exists) x = INSTR(2, f2$, CHR$(34) + ","): IF x THEN f2$ = LEFT$(f2$, x) GOTO classdone END IF 'number? IF (c >= 48 AND c <= 57) OR c = 45 THEN lastt = 2: lastti = i x = INSTR(f2$, ",") IF x THEN removeelements a$, i, i, 0: insertelements a$, i - 1, LEFT$(f2$, x - 1) f2$ = RIGHT$(f2$, LEN(f2$) - x) END IF IF x = 0 THEN c2 = ASC(f2$, LEN(f2$)) IF c2 < 48 OR c2 > 57 THEN x = 1 'extension given ELSE x = INSTR(f2$, "`") END IF END IF 'add appropriate integer symbol if none present IF x = 0 THEN f3$ = f2$ s$ = "" IF c = 45 THEN s$ = "&&" IF (f3$ <= "-2147483648" AND LEN(f3$) = 11) OR LEN(f3$) < 11 THEN s$ = "&" IF (f3$ <= "-32768" AND LEN(f3$) = 6) OR LEN(f3$) < 6 THEN s$ = "%" ELSE s$ = "~&&" IF (f3$ <= "9223372036854775807" AND LEN(f3$) = 19) OR LEN(f3$) < 19 THEN s$ = "&&" IF (f3$ <= "2147483647" AND LEN(f3$) = 10) OR LEN(f3$) < 10 THEN s$ = "&" IF (f3$ <= "32767" AND LEN(f3$) = 5) OR LEN(f3$) < 5 THEN s$ = "%" END IF f3$ = f3$ + s$ removeelements a$, i, i, 0: insertelements a$, i - 1, f3$ END IF 'x=0 GOTO classdone END IF 'operator? IF isoperator(f2$) THEN lastt = 3: lastti = i IF LEN(f2$) > 1 THEN IF f2$ <> UCASE$(f2$) THEN f2$ = UCASE$(f2$) removeelements a$, i, i, 0 insertelements a$, i - 1, f2$ END IF END IF 'append negation IF f2$ = "ñ" THEN f$ = f$ + sp + "-": GOTO classdone_special GOTO classdone END IF IF alphanumeric(c) THEN lastt = 4: lastti = i IF i < n THEN nextc = ASC(getelement(a$, i + 1)) ELSE nextc = 0 ' a constant? IF nextc <> 40 THEN '<>"(" (not an array) IF lastc <> 46 THEN '<>"." (not an element of a UDT) e$ = UCASE$(f2$) es$ = removesymbol$(e$) IF Error_Happened THEN EXIT FUNCTION hashfound = 0 hashname$ = e$ hashchkflags = HASHFLAG_CONSTANT hashres = HashFindRev(hashname$, hashchkflags, hashresflags, hashresref) DO WHILE hashres IF constsubfunc(hashresref) = subfuncn OR constsubfunc(hashresref) = 0 THEN IF constdefined(hashresref) THEN hashfound = 1 EXIT DO END IF END IF IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP IF hashfound THEN i2 = hashresref 'FOR i2 = constlast TO 0 STEP -1 'IF e$ = constname(i2) THEN 'is a STATIC variable overriding this constant? staticvariable = 0 try = findid(e$ + es$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF id.arraytype = 0 THEN staticvariable = 1: EXIT DO 'if it's not an array, it's probably a static variable IF try = 2 THEN findanotherid = 1: try = findid(e$ + es$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP 'add symbol and try again IF staticvariable = 0 THEN IF LEN(es$) = 0 THEN a = ASC(UCASE$(e$)): IF a = 95 THEN a = 91 a = a - 64 'so A=1, Z=27 and _=28 es2$ = defineextaz(a) try = findid(e$ + es2$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF id.arraytype = 0 THEN staticvariable = 1: EXIT DO 'if it's not an array, it's probably a static variable IF try = 2 THEN findanotherid = 1: try = findid(e$ + es2$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP END IF END IF IF staticvariable = 0 THEN t = consttype(i2) IF t AND ISSTRING THEN IF LEN(es$) > 0 AND es$ <> "$" THEN Give_Error "Type mismatch": EXIT FUNCTION e$ = conststring(i2) ELSE 'not a string IF LEN(es$) THEN et = typname2typ(es$) ELSE et = 0 IF Error_Happened THEN EXIT FUNCTION IF et AND ISSTRING THEN Give_Error "Type mismatch": EXIT FUNCTION 'convert value to general formats IF t AND ISFLOAT THEN v## = constfloat(i2) v&& = v## v~&& = v&& ELSE IF t AND ISUNSIGNED THEN v~&& = constuinteger(i2) v&& = v~&& v## = v&& ELSE v&& = constinteger(i2) v## = v&& v~&& = v&& END IF END IF 'apply type conversion if necessary IF et THEN t = et '(todo: range checking) 'convert value into string for returning IF t AND ISFLOAT THEN e$ = LTRIM$(RTRIM$(STR$(v##))) ELSE IF t AND ISUNSIGNED THEN e$ = LTRIM$(RTRIM$(STR$(v~&&))) ELSE e$ = LTRIM$(RTRIM$(STR$(v&&))) END IF END IF 'floats returned by str$ must be converted to qb64 standard format IF t AND ISFLOAT THEN t2 = t AND 511 'find E,D or F s$ = "" IF INSTR(e$, "E") THEN s$ = "E" IF INSTR(e$, "D") THEN s$ = "D" IF INSTR(e$, "F") THEN s$ = "F" IF LEN(s$) THEN 'E,D,F found x = INSTR(e$, s$) 'as incorrect type letter may have been returned by STR$, override it IF t2 = 32 THEN s$ = "E" IF t2 = 64 THEN s$ = "D" IF t2 = 256 THEN s$ = "F" MID$(e$, x, 1) = s$ IF INSTR(e$, ".") = 0 THEN e$ = LEFT$(e$, x - 1) + ".0" + RIGHT$(e$, LEN(e$) - x + 1): x = x + 2 IF LEFT$(e$, 1) = "." THEN e$ = "0" + e$ IF LEFT$(e$, 2) = "-." THEN e$ = "-0" + RIGHT$(e$, LEN(e$) - 1) IF INSTR(e$, "+") = 0 AND INSTR(e$, "-") = 0 THEN e$ = LEFT$(e$, x) + "+" + RIGHT$(e$, LEN(e$) - x) END IF ELSE 'E,D,F not found IF INSTR(e$, ".") = 0 THEN e$ = e$ + ".0" IF LEFT$(e$, 1) = "." THEN e$ = "0" + e$ IF LEFT$(e$, 2) = "-." THEN e$ = "-0" + RIGHT$(e$, LEN(e$) - 1) IF t2 = 32 THEN e$ = e$ + "E+0" IF t2 = 64 THEN e$ = e$ + "D+0" IF t2 = 256 THEN e$ = e$ + "F+0" END IF ELSE s$ = typevalue2symbol$(t) IF Error_Happened THEN EXIT FUNCTION e$ = e$ + s$ 'simply append symbol to integer END IF END IF 'not a string removeelements a$, i, i, 0 insertelements a$, i - 1, e$ 'alter f2$ here to original casing f2$ = constcname(i2) + es$ GOTO classdone END IF 'not static 'END IF 'same name 'NEXT END IF 'hashfound END IF 'not udt element END IF 'not array 'variable/array/udt? u$ = f2$ try_string$ = f2$ try_string2$ = try_string$ 'pure version of try_string$ FOR try_method = 1 TO 4 try_string$ = try_string2$ IF try_method = 2 OR try_method = 4 THEN dtyp$ = removesymbol(try_string$) IF LEN(dtyp$) = 0 THEN IF isoperator(try_string$) = 0 THEN IF isvalidvariable(try_string$) THEN IF LEFT$(try_string$, 1) = "_" THEN v = 27 ELSE v = ASC(UCASE$(try_string$)) - 64 try_string$ = try_string$ + defineextaz(v) END IF END IF ELSE try_string$ = try_string2$ END IF END IF try = findid(try_string$) IF Error_Happened THEN EXIT FUNCTION DO WHILE try IF (subfuncn = id.insubfuncn AND try_method <= 2) OR try_method >= 3 THEN IF Debug THEN PRINT #9, "found id matching " + f2$ IF nextc = 40 THEN '( 'function or array? IF id.arraytype <> 0 OR id.subfunc = 1 THEN 'note: even if it's an array of UDTs, the bracketted index will follow immediately 'correct name f3$ = f2$ s$ = removesymbol$(f3$) IF Error_Happened THEN EXIT FUNCTION f2$ = RTRIM$(id.cn) + s$ removeelements a$, i, i, 0 insertelements a$, i - 1, UCASE$(f2$) f$ = f$ + f2$ + sp + "(" + sp 'skip (but record with nothing inside them) brackets b2 = 1 'already in first bracket FOR i2 = i + 2 TO n c2 = ASC(getelement(a$, i2)) IF c2 = 40 THEN b2 = b2 + 1 IF c2 = 41 THEN b2 = b2 - 1 IF b2 = 0 THEN EXIT FOR 'note: mismatched brackets check ensures this always succeeds f$ = f$ + sp NEXT 'adjust i accordingly i = i2 f$ = f$ + ")" 'jump to UDT section if array is of UDT type (and elements are referenced) IF id.arraytype AND ISUDT THEN IF i < n THEN nextc = ASC(getelement(a$, i + 1)) ELSE nextc = 0 IF nextc = 46 THEN t = id.arraytype: GOTO fooudt END IF f$ = f$ + sp GOTO classdone_special END IF 'id.arraytype END IF 'nextc "(" IF nextc <> 40 THEN 'not "(" (this avoids confusing simple variables with arrays) IF id.t <> 0 OR id.subfunc = 1 THEN 'simple variable or function (without parameters) IF id.t AND ISUDT THEN 'note: it may or may not be followed by a period (eg. if whole udt is being referred to) 'check if next item is a period 'correct name f2$ = RTRIM$(id.cn) + removesymbol$(f2$) IF Error_Happened THEN EXIT FUNCTION removeelements a$, i, i, 0 insertelements a$, i - 1, UCASE$(f2$) f$ = f$ + f2$ IF nextc <> 46 THEN f$ = f$ + sp: GOTO classdone_special 'no sub-elements referenced t = id.t fooudt: f$ = f$ + sp + "." + sp E = udtxnext(t AND 511) 'next element to check i = i + 2 'loop '"." encountered, i must be an element IF i > n THEN Give_Error "Expected .element": EXIT FUNCTION f2$ = getelement(a$, i) s$ = removesymbol$(f2$) IF Error_Happened THEN EXIT FUNCTION u$ = UCASE$(f2$) + SPACE$(256 - LEN(f2$)) 'fast scanning 'is f$ the same as element e? fooudtnexte: IF udtename(E) = u$ THEN 'match found 'todo: check symbol(s$) matches element's type 'correct name f2$ = RTRIM$(udtecname(E)) + s$ removeelements a$, i, i, 0 insertelements a$, i - 1, UCASE$(f2$) f$ = f$ + f2$ IF i = n THEN f$ = f$ + sp: GOTO classdone_special nextc = ASC(getelement(a$, i + 1)) IF nextc <> 46 THEN f$ = f$ + sp: GOTO classdone_special 'no sub-elements referenced 'sub-element exists t = udtetype(E) IF (t AND ISUDT) = 0 THEN Give_Error "Invalid . after element": EXIT FUNCTION GOTO fooudt END IF 'match found 'no, so check next element E = udtenext(E) IF E = 0 THEN Give_Error "Element not defined": EXIT FUNCTION GOTO fooudtnexte END IF 'udt 'non array/udt based variable f3$ = f2$ s$ = removesymbol$(f3$) IF Error_Happened THEN EXIT FUNCTION f2$ = RTRIM$(id.cn) + s$ 'change was is returned to uppercase removeelements a$, i, i, 0 insertelements a$, i - 1, UCASE$(f2$) GOTO CouldNotClassify END IF 'id.t END IF 'nextc not "(" END IF IF try = 2 THEN findanotherid = 1: try = findid(try_string$) ELSE try = 0 IF Error_Happened THEN EXIT FUNCTION LOOP NEXT 'try method (1-4) CouldNotClassify: 'alphanumeric, but item name is unknown... is it an internal type? if so, use capitals f3$ = UCASE$(f2$) internaltype = 0 IF f3$ = "STRING" THEN internaltype = 1 IF f3$ = "_UNSIGNED" THEN internaltype = 1 IF f3$ = "_BIT" THEN internaltype = 1 IF f3$ = "_BYTE" THEN internaltype = 1 IF f3$ = "INTEGER" THEN internaltype = 1 IF f3$ = "LONG" THEN internaltype = 1 IF f3$ = "_INTEGER64" THEN internaltype = 1 IF f3$ = "SINGLE" THEN internaltype = 1 IF f3$ = "DOUBLE" THEN internaltype = 1 IF f3$ = "_FLOAT" THEN internaltype = 1 IF f3$ = "_OFFSET" THEN internaltype = 1 IF internaltype = 1 THEN f2$ = f3$ removeelements a$, i, i, 0 insertelements a$, i - 1, f3$ GOTO classdone END IF GOTO classdone END IF 'alphanumeric classdone: f$ = f$ + f2$ END IF 'b=0 f$ = f$ + sp classdone_special: NEXT IF LEN(f$) THEN f$ = LEFT$(f$, LEN(f$) - 1) 'remove trailing 'sp' IF Debug THEN PRINT #9, "fixoperationorder:identification:" + a$, n IF Debug THEN PRINT #9, "fixoperationorder:identification(layout):" + f$, n '----------------I. Pass (){}bracketed items (if any) to fixoperationorder & build return---------------- 'note: items seperated by commas are done seperately ff$ = "" b = 0 b2 = 0 p1 = 0 'where level 1 began aa$ = "" n = numelements(a$) FOR i = 1 TO n openbracket = 0 a2$ = getelement(a$, i) c = ASC(a2$) IF c = 40 OR c = 123 THEN '({ b = b + 1 IF b = 1 THEN p1 = i + 1 aa$ = aa$ + "(" + sp END IF openbracket = 1 GOTO foopass END IF '({ IF c = 44 THEN ', IF b = 1 THEN GOTO foopassit END IF END IF IF c = 41 OR c = 125 THEN ')} b = b - 1 IF b = 0 THEN foopassit: IF p1 <> i THEN foo$ = fixoperationorder(getelements(a$, p1, i - 1)) IF Error_Happened THEN EXIT FUNCTION IF LEN(foo$) THEN aa$ = aa$ + foo$ + sp IF c = 125 THEN ff$ = ff$ + tlayout$ + sp ELSE ff$ = ff$ + tlayout$ + sp2 'spacing between ) } , varies END IF END IF IF c = 44 THEN aa$ = aa$ + "," + sp: ff$ = ff$ + "," + sp ELSE aa$ = aa$ + ")" + sp p1 = i + 1 END IF GOTO foopass END IF ')} IF b = 0 THEN aa$ = aa$ + a2$ + sp foopass: f2$ = getelementspecial(f$, i) IF Error_Happened THEN EXIT FUNCTION IF LEN(f2$) THEN 'use sp2 to join items connected by a period IF c = 46 THEN '"." IF i > 1 AND i < n THEN 'stupidity check IF LEN(ff$) THEN MID$(ff$, LEN(ff$), 1) = sp2 'convert last spacer to a sp2 ff$ = ff$ + "." + sp2 GOTO fooloopnxt END IF END IF 'spacing just before ( IF openbracket THEN 'convert last spacer? IF i <> 1 THEN IF isoperator(getelement$(a$, i - 1)) = 0 THEN MID$(ff$, LEN(ff$), 1) = sp2 END IF END IF ff$ = ff$ + f2$ + sp2 ELSE 'not openbracket ff$ = ff$ + f2$ + sp END IF END IF 'len(f2$) fooloopnxt: NEXT IF LEN(aa$) THEN aa$ = LEFT$(aa$, LEN(aa$) - 1) IF LEN(ff$) THEN ff$ = LEFT$(ff$, LEN(ff$) - 1) IF Debug THEN PRINT #9, "fixoperationorder:return:" + aa$ IF Debug THEN PRINT #9, "fixoperationorder:layout:" + ff$ tlayout$ = ff$ fixoperationorder$ = aa$ fooindwel = fooindwel - 1 END FUNCTION FUNCTION getelementspecial$ (savea$, elenum) a$ = savea$ IF a$ = "" THEN EXIT FUNCTION 'no elements! n = 1 p = 1 getelementspecialnext: i = INSTR(p, a$, sp) 'avoid sp inside "..." i2 = INSTR(p, a$, CHR$(34)) IF i2 < i AND i2 <> 0 THEN i3 = INSTR(i2 + 1, a$, CHR$(34)): IF i3 = 0 THEN Give_Error "Expected " + CHR$(34): EXIT FUNCTION i = INSTR(i3, a$, sp) END IF IF elenum = n THEN IF i THEN getelementspecial$ = MID$(a$, p, i - p) ELSE getelementspecial$ = RIGHT$(a$, LEN(a$) - p + 1) END IF EXIT FUNCTION END IF IF i = 0 THEN EXIT FUNCTION 'no more elements! n = n + 1 p = i + 1 GOTO getelementspecialnext END FUNCTION FUNCTION getelement$ (a$, elenum) IF a$ = "" THEN EXIT FUNCTION 'no elements! n = 1 p = 1 getelementnext: i = INSTR(p, a$, sp) IF elenum = n THEN IF i THEN getelement$ = MID$(a$, p, i - p) ELSE getelement$ = RIGHT$(a$, LEN(a$) - p + 1) END IF EXIT FUNCTION END IF IF i = 0 THEN EXIT FUNCTION 'no more elements! n = n + 1 p = i + 1 GOTO getelementnext END FUNCTION FUNCTION getelements$ (a$, i1, i2) IF i2 < i1 THEN getelements$ = "": EXIT FUNCTION n = 1 p = 1 getelementsnext: i = INSTR(p, a$, sp) IF n = i1 THEN i1pos = p END IF IF n = i2 THEN IF i THEN getelements$ = MID$(a$, i1pos, i - i1pos) ELSE getelements$ = RIGHT$(a$, LEN(a$) - i1pos + 1) END IF EXIT FUNCTION END IF n = n + 1 p = i + 1 GOTO getelementsnext END FUNCTION SUB getid (i AS LONG) IF i = -1 THEN Give_Error "-1 passed to getid!": EXIT SUB id = ids(i) currentid = i END SUB SUB insertelements (a$, i, elements$) IF i = 0 THEN IF a$ = "" THEN a$ = elements$ EXIT SUB END IF a$ = elements$ + sp + a$ EXIT SUB END IF a2$ = "" n = numelements(a$) FOR i2 = 1 TO n IF i2 > 1 THEN a2$ = a2$ + sp a2$ = a2$ + getelement$(a$, i2) IF i = i2 THEN a2$ = a2$ + sp + elements$ NEXT a$ = a2$ END SUB FUNCTION isnumber (a$) IF LEN(a$) = 0 THEN EXIT FUNCTION FOR i = 1 TO LEN(a$) a = ASC(MID$(a$, i, 1)) IF a = 45 THEN IF i <> 1 THEN EXIT FUNCTION GOTO isnumok END IF IF a = 46 THEN IF dp = 1 THEN EXIT FUNCTION dp = 1 GOTO isnumok END IF IF a >= 48 AND a <= 57 THEN v = 1: GOTO isnumok EXIT FUNCTION isnumok: NEXT isnumber = 1 END FUNCTION FUNCTION isoperator (a2$) a$ = UCASE$(a2$) l = 0 l = l + 1: IF a$ = "IMP" THEN GOTO opfound l = l + 1: IF a$ = "EQV" THEN GOTO opfound l = l + 1: IF a$ = "XOR" THEN GOTO opfound l = l + 1: IF a$ = "OR" THEN GOTO opfound l = l + 1: IF a$ = "AND" THEN GOTO opfound l = l + 1: IF a$ = "NOT" THEN GOTO opfound l = l + 1 IF a$ = "=" THEN GOTO opfound IF a$ = ">" THEN GOTO opfound IF a$ = "<" THEN GOTO opfound IF a$ = "<>" THEN GOTO opfound IF a$ = "<=" THEN GOTO opfound IF a$ = ">=" THEN GOTO opfound l = l + 1 IF a$ = "+" THEN GOTO opfound IF a$ = "-" THEN GOTO opfound '!CAREFUL! could be negation l = l + 1: IF a$ = "MOD" THEN GOTO opfound l = l + 1: IF a$ = "\" THEN GOTO opfound l = l + 1 IF a$ = "*" THEN GOTO opfound IF a$ = "/" THEN GOTO opfound 'NEGATION LEVEL (MUST BE SET AFTER CALLING ISOPERATOR BY CONTEXT) l = l + 1: IF a$ = "ñ" THEN GOTO opfound l = l + 1: IF a$ = "^" THEN GOTO opfound EXIT FUNCTION opfound: isoperator = l END FUNCTION FUNCTION isuinteger (i$) IF LEN(i$) = 0 THEN EXIT FUNCTION IF ASC(i$, 1) = 48 AND LEN(i$) > 1 THEN EXIT FUNCTION FOR c = 1 TO LEN(i$) v = ASC(i$, c) IF v < 48 OR v > 57 THEN EXIT FUNCTION NEXT isuinteger = -1 END FUNCTION FUNCTION isvalidvariable (a$) FOR i = 1 TO LEN(a$) c = ASC(a$, i) t = 0 IF c >= 48 AND c <= 57 THEN t = 1 'numeric IF c >= 65 AND c <= 90 THEN t = 2 'uppercase IF c >= 97 AND c <= 122 THEN t = 2 'lowercase IF c = 95 THEN t = 2 '_ underscore IF t = 2 OR (t = 1 AND i > 1) THEN 'valid (continue) ELSE IF i = 1 THEN isvalidvariable = 0: EXIT FUNCTION EXIT FOR END IF NEXT isvalidvariable = 1 IF i > n THEN EXIT FUNCTION e$ = RIGHT$(a$, LEN(a$) - i - 1) IF e$ = "%%" OR e$ = "~%%" THEN EXIT FUNCTION IF e$ = "%" OR e$ = "~%" THEN EXIT FUNCTION IF e$ = "&" OR e$ = "~&" THEN EXIT FUNCTION IF e$ = "&&" OR e$ = "~&&" THEN EXIT FUNCTION IF e$ = "!" OR e$ = "#" OR e$ = "##" THEN EXIT FUNCTION IF e$ = "$" THEN EXIT FUNCTION IF e$ = "`" THEN EXIT FUNCTION IF LEFT$(e$, 1) <> "$" AND LEFT$(e$, 1) <> "`" THEN isvalidvariable = 0: EXIT FUNCTION e$ = RIGHT$(e$, LEN(e$) - 1) IF isuinteger(e$) THEN isvalidvariable = 1: EXIT FUNCTION isvalidvariable = 0 END FUNCTION FUNCTION lineformat$ (a$) a2$ = "" linecontinuation = 0 continueline: a$ = a$ + " " 'add 2 extra spaces to make reading next char easier ca$ = a$ a$ = UCASE$(a$) n = LEN(a$) i = 1 lineformatnext: IF i >= n THEN GOTO lineformatdone c = ASC(a$, i) c$ = CHR$(c) '***remove later*** '----------------quoted string---------------- IF c = 34 THEN '" a2$ = a2$ + sp + CHR$(34) p1 = i + 1 FOR i2 = i + 1 TO n - 2 c2 = ASC(a$, i2) IF c2 = 34 THEN a2$ = a2$ + MID$(ca$, p1, i2 - p1 + 1) + "," + str2$(i2 - (i + 1)) i = i2 + 1 EXIT FOR END IF IF c2 = 92 THEN '\ a2$ = a2$ + MID$(ca$, p1, i2 - p1) + "\\" p1 = i2 + 1 END IF IF c2 < 32 OR c2 > 126 THEN o$ = OCT$(c2) IF LEN(o$) < 3 THEN o$ = "0" + o$ IF LEN(o$) < 3 THEN o$ = "0" + o$ END IF a2$ = a2$ + MID$(ca$, p1, i2 - p1) + "\" + o$ p1 = i2 + 1 END IF NEXT IF i2 = n - 1 THEN 'no closing " a2$ = a2$ + MID$(ca$, p1, (n - 2) - p1 + 1) + CHR$(34) + "," + str2$((n - 2) - (i + 1) + 1) i = n - 1 END IF GOTO lineformatnext END IF '----------------number---------------- firsti = i IF c = 46 THEN c2$ = MID$(a$, i + 1, 1): c2 = ASC(c2$) IF (c2 >= 48 AND c2 <= 57) THEN GOTO lfnumber END IF IF (c >= 48 AND c <= 57) THEN '0-9 lfnumber: 'handle 'IF a=1 THEN a=2 ELSE 100' by assuming numeric after ELSE to be a IF RIGHT$(a2$, 5) = sp + "ELSE" THEN a2$ = a2$ + sp + "GOTO" END IF 'Number will be converted to the following format: ' 999999 . 99999 E + 999 '[whole$][dp(0/1)][frac$][ed(1/2)][pm(1/-1)][ex$] ' 0 1 2 3 <-mode mode = 0 whole$ = "" dp = 0 frac$ = "" ed = 0 'E=1, D=2, F=3 pm = 1 ex$ = "" lfreadnumber: valid = 0 IF c = 46 THEN IF mode = 0 THEN valid = 1: dp = 1: mode = 1 END IF IF c >= 48 AND c <= 57 THEN '0-9 valid = 1 IF mode = 0 THEN whole$ = whole$ + c$ IF mode = 1 THEN frac$ = frac$ + c$ IF mode = 2 THEN mode = 3 IF mode = 3 THEN ex$ = ex$ + c$ END IF IF c = 69 OR c = 68 OR c = 70 THEN 'E,D,F IF mode < 2 THEN valid = 1 IF c = 69 THEN ed = 1 IF c = 68 THEN ed = 2 IF c = 70 THEN ed = 3 mode = 2 END IF END IF IF c = 43 OR c = 45 THEN '+,- IF mode = 2 THEN valid = 1 IF c = 45 THEN pm = -1 mode = 3 END IF END IF IF valid THEN IF i <= n THEN i = i + 1: c$ = MID$(a$, i, 1): c = ASC(c$): GOTO lfreadnumber END IF 'cull leading 0s off whole$ DO WHILE LEFT$(whole$, 1) = "0": whole$ = RIGHT$(whole$, LEN(whole$) - 1): LOOP 'cull trailing 0s off frac$ DO WHILE RIGHT$(frac$, 1) = "0": frac$ = LEFT$(frac$, LEN(frac$) - 1): LOOP 'cull leading 0s off ex$ DO WHILE LEFT$(ex$, 1) = "0": ex$ = RIGHT$(ex$, LEN(ex$) - 1): LOOP IF dp <> 0 OR ed <> 0 THEN float = 1 ELSE float = 0 extused = 1 IF ed THEN e$ = "": GOTO lffoundext 'no extensions valid after E/D/F specified '3-character extensions IF i <= n - 2 THEN e$ = MID$(a$, i, 3) IF e$ = "~%%" AND float = 0 THEN i = i + 3: GOTO lffoundext IF e$ = "~&&" AND float = 0 THEN i = i + 3: GOTO lffoundext IF e$ = "~%&" AND float = 0 THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION END IF '2-character extensions IF i <= n - 1 THEN e$ = MID$(a$, i, 2) IF e$ = "%%" AND float = 0 THEN i = i + 2: GOTO lffoundext IF e$ = "~%" AND float = 0 THEN i = i + 2: GOTO lffoundext IF e$ = "&&" AND float = 0 THEN i = i + 2: GOTO lffoundext IF e$ = "~&" AND float = 0 THEN i = i + 2: GOTO lffoundext IF e$ = "%&" AND float = 0 THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION IF e$ = "##" THEN i = i + 2 ed = 3 e$ = "" GOTO lffoundext END IF IF e$ = "~`" THEN i = i + 2 GOTO lffoundbitext END IF END IF '1-character extensions IF i <= n THEN e$ = MID$(a$, i, 1) IF e$ = "%" AND float = 0 THEN i = i + 1: GOTO lffoundext IF e$ = "&" AND float = 0 THEN i = i + 1: GOTO lffoundext IF e$ = "!" THEN i = i + 1 ed = 1 e$ = "" GOTO lffoundext END IF IF e$ = "#" THEN i = i + 1 ed = 2 e$ = "" GOTO lffoundext END IF IF e$ = "`" THEN i = i + 1 lffoundbitext: bitn$ = "" DO WHILE i <= n c2 = ASC(MID$(a$, i, 1)) IF c2 >= 48 AND c2 <= 57 THEN bitn$ = bitn$ + CHR$(c2) i = i + 1 ELSE EXIT DO END IF LOOP IF bitn$ = "" THEN bitn$ = "1" 'cull leading 0s off bitn$ DO WHILE LEFT$(bitn$, 1) = "0": bitn$ = RIGHT$(bitn$, LEN(bitn$) - 1): LOOP e$ = e$ + bitn$ GOTO lffoundext END IF END IF IF float THEN 'floating point types CAN be assumed 'calculate first significant digit offset & number of significant digits IF whole$ <> "" THEN offset = LEN(whole$) - 1 sigdigits = LEN(whole$) + LEN(frac$) ELSE IF frac$ <> "" THEN offset = -1 sigdigits = LEN(frac$) FOR i2 = 1 TO LEN(frac$) IF MID$(frac$, i2, 1) <> "0" THEN EXIT FOR offset = offset - 1 sigdigits = sigdigits - 1 NEXT ELSE 'number is 0 offset = 0 sigdigits = 0 END IF END IF sigdig$ = RIGHT$(whole$ + frac$, sigdigits) 'SINGLE? IF sigdigits <= 7 THEN 'QBASIC interprets anything with more than 7 sig. digits as a DOUBLE IF offset <= 38 AND offset >= -38 THEN 'anything outside this range cannot be represented as a SINGLE IF offset = 38 THEN IF sigdig$ > "3402823" THEN GOTO lfxsingle END IF IF offset = -38 THEN IF sigdig$ < "1175494" THEN GOTO lfxsingle END IF ed = 1 e$ = "" GOTO lffoundext END IF END IF lfxsingle: 'DOUBLE? IF sigdigits <= 16 THEN 'QB64 handles DOUBLES with 16-digit precision IF offset <= 308 AND offset >= -308 THEN 'anything outside this range cannot be represented as a DOUBLE IF offset = 308 THEN IF sigdig$ > "1797693134862315" THEN GOTO lfxdouble END IF IF offset = -308 THEN IF sigdig$ < "2225073858507201" THEN GOTO lfxdouble END IF ed = 2 e$ = "" GOTO lffoundext END IF END IF lfxdouble: 'assume _FLOAT ed = 3 e$ = "": GOTO lffoundext END IF extused = 0 e$ = "" lffoundext: 'make sure a leading numberic character exists IF whole$ = "" THEN whole$ = "0" 'if a float, ensure frac$<>"" and dp=1 IF float THEN dp = 1 IF frac$ = "" THEN frac$ = "0" END IF 'if ed is specified, make sure ex$ exists IF ed <> 0 AND ex$ = "" THEN ex$ = "0" a2$ = a2$ + sp a2$ = a2$ + whole$ IF dp THEN a2$ = a2$ + "." + frac$ IF ed THEN IF ed = 1 THEN a2$ = a2$ + "E" IF ed = 2 THEN a2$ = a2$ + "D" IF ed = 3 THEN a2$ = a2$ + "F" IF pm = -1 AND ex$ <> "0" THEN a2$ = a2$ + "-" ELSE a2$ = a2$ + "+" a2$ = a2$ + ex$ END IF a2$ = a2$ + e$ IF extused THEN a2$ = a2$ + "," + MID$(a$, firsti, i - firsti) GOTO lineformatnext END IF '----------------(number)&H...---------------- 'note: the final value, not the number of hex characters, sets the default type IF c = 38 THEN '& IF MID$(a$, i + 1, 1) = "H" THEN i = i + 2 hx$ = "" lfreadhex: IF i <= n THEN c$ = MID$(a$, i, 1): c = ASC(c$) IF (c >= 48 AND c <= 57) OR (c >= 65 AND c <= 70) THEN hx$ = hx$ + c$: i = i + 1: GOTO lfreadhex END IF fullhx$ = "&H" + hx$ 'cull leading 0s off hx$ DO WHILE LEFT$(hx$, 1) = "0": hx$ = RIGHT$(hx$, LEN(hx$) - 1): LOOP IF hx$ = "" THEN hx$ = "0" bitn$ = "" '3-character extensions IF i <= n - 2 THEN e$ = MID$(a$, i, 3) IF e$ = "~%%" THEN i = i + 3: GOTO lfhxext IF e$ = "~&&" THEN i = i + 3: GOTO lfhxext IF e$ = "~%&" THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION END IF '2-character extensions IF i <= n - 1 THEN e$ = MID$(a$, i, 2) IF e$ = "%%" THEN i = i + 2: GOTO lfhxext IF e$ = "~%" THEN i = i + 2: GOTO lfhxext IF e$ = "&&" THEN i = i + 2: GOTO lfhxext IF e$ = "%&" THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION IF e$ = "~&" THEN i = i + 2: GOTO lfhxext IF e$ = "~`" THEN i = i + 2 GOTO lfhxbitext END IF END IF '1-character extensions IF i <= n THEN e$ = MID$(a$, i, 1) IF e$ = "%" THEN i = i + 1: GOTO lfhxext IF e$ = "&" THEN i = i + 1: GOTO lfhxext IF e$ = "`" THEN i = i + 1 lfhxbitext: DO WHILE i <= n c2 = ASC(MID$(a$, i, 1)) IF c2 >= 48 AND c2 <= 57 THEN bitn$ = bitn$ + CHR$(c2) i = i + 1 ELSE EXIT DO END IF LOOP IF bitn$ = "" THEN bitn$ = "1" 'cull leading 0s off bitn$ DO WHILE LEFT$(bitn$, 1) = "0": bitn$ = RIGHT$(bitn$, LEN(bitn$) - 1): LOOP GOTO lfhxext END IF END IF 'if no valid extension context was given, assume one 'note: leading 0s have been culled, so LEN(hx$) reflects its values size e$ = "&&" IF LEN(hx$) <= 8 THEN e$ = "&" 'as in QBASIC, signed values must be used IF LEN(hx$) <= 4 THEN e$ = "%" 'as in QBASIC, signed values must be used GOTO lfhxext2 lfhxext: fullhx$ = fullhx$ + e$ + bitn$ lfhxext2: 'build 8-byte unsigned integer rep. of hx$ IF LEN(hx$) > 16 THEN Give_Error "Overflow": EXIT FUNCTION v~&& = 0 FOR i2 = 1 TO LEN(hx$) v2 = ASC(MID$(hx$, i2, 1)) IF v2 <= 57 THEN v2 = v2 - 48 ELSE v2 = v2 - 65 + 10 v~&& = v~&& * 16 + v2 NEXT finishhexoctbin: num$ = str2u64$(v~&&) 'correct for unsigned values (overflow of unsigned can be checked later) IF LEFT$(e$, 1) <> "~" THEN 'note: range checking will be performed later in fixop.order 'signed IF e$ = "%%" THEN IF v~&& > 127 THEN IF v~&& > 255 THEN Give_Error "Overflow": EXIT FUNCTION v~&& = ((NOT v~&&) AND 255) + 1 num$ = "-" + sp + str2u64$(v~&&) END IF END IF IF e$ = "%" THEN IF v~&& > 32767 THEN IF v~&& > 65535 THEN Give_Error "Overflow": EXIT FUNCTION v~&& = ((NOT v~&&) AND 65535) + 1 num$ = "-" + sp + str2u64$(v~&&) END IF END IF IF e$ = "&" THEN IF v~&& > 2147483647 THEN IF v~&& > 4294967295 THEN Give_Error "Overflow": EXIT FUNCTION v~&& = ((NOT v~&&) AND 4294967295) + 1 num$ = "-" + sp + str2u64$(v~&&) END IF END IF IF e$ = "&&" THEN IF v~&& > 9223372036854775807 THEN 'note: no error checking necessary v~&& = (NOT v~&&) + 1 num$ = "-" + sp + str2u64$(v~&&) END IF END IF IF e$ = "`" THEN vbitn = VAL(bitn$) h~&& = 1: FOR i2 = 1 TO vbitn - 1: h~&& = h~&& * 2: NEXT: h~&& = h~&& - 1 'build h~&& IF v~&& > h~&& THEN h~&& = 1: FOR i2 = 1 TO vbitn: h~&& = h~&& * 2: NEXT: h~&& = h~&& - 1 'build h~&& IF v~&& > h~&& THEN Give_Error "Overflow": EXIT FUNCTION v~&& = ((NOT v~&&) AND h~&&) + 1 num$ = "-" + sp + str2u64$(v~&&) END IF END IF END IF '<>"~" a2$ = a2$ + sp + num$ + e$ + bitn$ + "," + fullhx$ GOTO lineformatnext END IF END IF '----------------(number)&O...---------------- 'note: the final value, not the number of oct characters, sets the default type IF c = 38 THEN '& IF MID$(a$, i + 1, 1) = "O" THEN i = i + 2 'note: to avoid mistakes, hx$ is used instead of 'ot$' hx$ = "" lfreadoct: IF i <= n THEN c$ = MID$(a$, i, 1): c = ASC(c$) IF c >= 48 AND c <= 55 THEN hx$ = hx$ + c$: i = i + 1: GOTO lfreadoct END IF fullhx$ = "&O" + hx$ 'cull leading 0s off hx$ DO WHILE LEFT$(hx$, 1) = "0": hx$ = RIGHT$(hx$, LEN(hx$) - 1): LOOP IF hx$ = "" THEN hx$ = "0" bitn$ = "" '3-character extensions IF i <= n - 2 THEN e$ = MID$(a$, i, 3) IF e$ = "~%%" THEN i = i + 3: GOTO lfotext IF e$ = "~&&" THEN i = i + 3: GOTO lfotext IF e$ = "~%&" THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION END IF '2-character extensions IF i <= n - 1 THEN e$ = MID$(a$, i, 2) IF e$ = "%%" THEN i = i + 2: GOTO lfotext IF e$ = "~%" THEN i = i + 2: GOTO lfotext IF e$ = "&&" THEN i = i + 2: GOTO lfotext IF e$ = "%&" THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION IF e$ = "~&" THEN i = i + 2: GOTO lfotext IF e$ = "~`" THEN i = i + 2 GOTO lfotbitext END IF END IF '1-character extensions IF i <= n THEN e$ = MID$(a$, i, 1) IF e$ = "%" THEN i = i + 1: GOTO lfotext IF e$ = "&" THEN i = i + 1: GOTO lfotext IF e$ = "`" THEN i = i + 1 lfotbitext: bitn$ = "" DO WHILE i <= n c2 = ASC(MID$(a$, i, 1)) IF c2 >= 48 AND c2 <= 57 THEN bitn$ = bitn$ + CHR$(c2) i = i + 1 ELSE EXIT DO END IF LOOP IF bitn$ = "" THEN bitn$ = "1" 'cull leading 0s off bitn$ DO WHILE LEFT$(bitn$, 1) = "0": bitn$ = RIGHT$(bitn$, LEN(bitn$) - 1): LOOP GOTO lfotext END IF END IF 'if no valid extension context was given, assume one 'note: leading 0s have been culled, so LEN(hx$) reflects its values size e$ = "&&" '37777777777 IF LEN(hx$) <= 11 THEN IF LEN(hx$) < 11 OR ASC(LEFT$(hx$, 1)) <= 51 THEN e$ = "&" END IF '177777 IF LEN(hx$) <= 6 THEN IF LEN(hx$) < 6 OR LEFT$(hx$, 1) = "1" THEN e$ = "%" END IF GOTO lfotext2 lfotext: fullhx$ = fullhx$ + e$ + bitn$ lfotext2: 'build 8-byte unsigned integer rep. of hx$ '1777777777777777777777 (22 digits) IF LEN(hx$) > 22 THEN Give_Error "Overflow": EXIT FUNCTION IF LEN(hx$) = 22 THEN IF LEFT$(hx$, 1) <> "1" THEN Give_Error "Overflow": EXIT FUNCTION END IF '********change v& to v~&&******** v~&& = 0 FOR i2 = 1 TO LEN(hx$) v2 = ASC(MID$(hx$, i2, 1)) v2 = v2 - 48 v~&& = v~&& * 8 + v2 NEXT GOTO finishhexoctbin END IF END IF '----------------(number)&B...---------------- 'note: the final value, not the number of bin characters, sets the default type IF c = 38 THEN '& IF MID$(a$, i + 1, 1) = "B" THEN i = i + 2 'note: to avoid mistakes, hx$ is used instead of 'bi$' hx$ = "" lfreadbin: IF i <= n THEN c$ = MID$(a$, i, 1): c = ASC(c$) IF c >= 48 AND c <= 49 THEN hx$ = hx$ + c$: i = i + 1: GOTO lfreadbin END IF fullhx$ = "&B" + hx$ 'cull leading 0s off hx$ DO WHILE LEFT$(hx$, 1) = "0": hx$ = RIGHT$(hx$, LEN(hx$) - 1): LOOP IF hx$ = "" THEN hx$ = "0" bitn$ = "" '3-character extensions IF i <= n - 2 THEN e$ = MID$(a$, i, 3) IF e$ = "~%%" THEN i = i + 3: GOTO lfbiext IF e$ = "~&&" THEN i = i + 3: GOTO lfbiext IF e$ = "~%&" THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION END IF '2-character extensions IF i <= n - 1 THEN e$ = MID$(a$, i, 2) IF e$ = "%%" THEN i = i + 2: GOTO lfbiext IF e$ = "~%" THEN i = i + 2: GOTO lfbiext IF e$ = "&&" THEN i = i + 2: GOTO lfbiext IF e$ = "%&" THEN Give_Error "Cannot use _OFFSET symbols after numbers": EXIT FUNCTION IF e$ = "~&" THEN i = i + 2: GOTO lfbiext IF e$ = "~`" THEN i = i + 2 GOTO lfbibitext END IF END IF '1-character extensions IF i <= n THEN e$ = MID$(a$, i, 1) IF e$ = "%" THEN i = i + 1: GOTO lfbiext IF e$ = "&" THEN i = i + 1: GOTO lfbiext IF e$ = "`" THEN i = i + 1 lfbibitext: bitn$ = "" DO WHILE i <= n c2 = ASC(MID$(a$, i, 1)) IF c2 >= 48 AND c2 <= 57 THEN bitn$ = bitn$ + CHR$(c2) i = i + 1 ELSE EXIT DO END IF LOOP IF bitn$ = "" THEN bitn$ = "1" 'cull leading 0s off bitn$ DO WHILE LEFT$(bitn$, 1) = "0": bitn$ = RIGHT$(bitn$, LEN(bitn$) - 1): LOOP GOTO lfbiext END IF END IF 'if no valid extension context was given, assume one 'note: leading 0s have been culled, so LEN(hx$) reflects its values size e$ = "&&" IF LEN(hx$) <= 32 THEN e$ = "&" IF LEN(hx$) <= 16 THEN e$ = "%" GOTO lfbiext2 lfbiext: fullhx$ = fullhx$ + e$ + bitn$ lfbiext2: 'build 8-byte unsigned integer rep. of hx$ IF LEN(hx$) > 64 THEN Give_Error "Overflow": EXIT FUNCTION v~&& = 0 FOR i2 = 1 TO LEN(hx$) v2 = ASC(MID$(hx$, i2, 1)) v2 = v2 - 48 v~&& = v~&& * 2 + v2 NEXT GOTO finishhexoctbin END IF END IF '----------------(number)&H??? error---------------- IF c = 38 THEN Give_Error "Expected &H... or &O...": EXIT FUNCTION '----------------variable/name---------------- '*trailing _ is treated as a seperate line extension* IF (c >= 65 AND c <= 90) OR c = 95 THEN 'A-Z(a-z) or _ IF c = 95 THEN p2 = 0 ELSE p2 = i FOR i2 = i + 1 TO n c2 = ASC(a$, i2) IF NOT alphanumeric(c2) THEN EXIT FOR IF c2 <> 95 THEN p2 = i2 NEXT IF p2 THEN 'not just underscores! 'char is from i to p2 n2 = p2 - i + 1 a3$ = MID$(a$, i, n2) '----(variable/name)rem---- IF n2 = 3 THEN IF a3$ = "REM" THEN i = i + n2 'note: In QBASIC 'IF cond THEN REM comment' counts as a single line IF statement, however use of ' instead of REM does not IF UCASE$(RIGHT$(a2$, 5)) = sp + "THEN" THEN a2$ = a2$ + sp + "'" 'add nop layoutcomment = "REM" GOTO comment END IF END IF '----(variable/name)data---- IF n2 = 4 THEN IF a3$ = "DATA" THEN x$ = "" i = i + n2 scan = 0 speechmarks = 0 commanext = 0 finaldata = 0 e$ = "" p1 = 0 p2 = 0 nextdatachr: IF i < n THEN c = ASC(a$, i) IF c = 9 OR c = 32 THEN IF scan = 0 THEN GOTO skipwhitespace END IF IF c = 58 THEN '":" IF speechmarks = 0 THEN finaldata = 1: GOTO adddata END IF IF c = 44 THEN '"," IF speechmarks = 0 THEN adddata: IF prepass = 0 THEN IF p1 THEN 'FOR i2 = p1 TO p2 ' DATA_add ASC(ca$, i2) 'NEXT x$ = x$ + MID$(ca$, p1, p2 - p1 + 1) END IF 'assume closing " IF speechmarks THEN 'DATA_add 34 x$ = x$ + CHR$(34) END IF 'append comma 'DATA_add 44 x$ = x$ + CHR$(44) END IF IF finaldata = 1 THEN GOTO finisheddata e$ = "" p1 = 0 p2 = 0 speechmarks = 0 scan = 0 commanext = 0 i = i + 1 GOTO nextdatachr END IF END IF '"," IF commanext = 1 THEN IF c <> 32 AND c <> 9 THEN Give_Error "Expected , after quoted string in DATA statement": EXIT FUNCTION END IF IF c = 34 THEN IF speechmarks = 1 THEN commanext = 1 speechmarks = 0 END IF IF scan = 0 THEN speechmarks = 1 END IF scan = 1 IF p1 = 0 THEN p1 = i: p2 = i IF c <> 9 AND c <> 32 THEN p2 = i skipwhitespace: i = i + 1: GOTO nextdatachr END IF 'i 40 THEN Give_Error "Identifier longer than 40 character limit": EXIT FUNCTION c3 = ASC(a$, i) m = 0 IF c3 = 126 THEN '"~" e2$ = MID$(a$, i + 1, 2) IF e2$ = "&&" THEN e2$ = "~&&": GOTO lfgetve IF e2$ = "%%" THEN e2$ = "~%%": GOTO lfgetve IF e2$ = "%&" THEN e2$ = "~%&": GOTO lfgetve e2$ = CHR$(ASC(e2$)) IF e2$ = "&" THEN e2$ = "~&": GOTO lfgetve IF e2$ = "%" THEN e2$ = "~%": GOTO lfgetve IF e2$ = "`" THEN m = 1: e2$ = "~`": GOTO lfgetve END IF IF c3 = 37 THEN c4 = ASC(a$, i + 1) IF c4 = 37 THEN e2$ = "%%": GOTO lfgetve IF c4 = 38 THEN e2$ = "%&": GOTO lfgetve e2$ = "%": GOTO lfgetve END IF IF c3 = 38 THEN c4 = ASC(a$, i + 1) IF c4 = 38 THEN e2$ = "&&": GOTO lfgetve e2$ = "&": GOTO lfgetve END IF IF c3 = 33 THEN e2$ = "!": GOTO lfgetve IF c3 = 35 THEN c4 = ASC(a$, i + 1) IF c4 = 35 THEN e2$ = "##": GOTO lfgetve e2$ = "#": GOTO lfgetve END IF IF c3 = 36 THEN m = 1: e2$ = "$": GOTO lfgetve IF c3 = 96 THEN m = 1: e2$ = "`": GOTO lfgetve '(no symbol) 'cater for unusual names/labels (eg a.0b%) IF ASC(a$, i) = 46 THEN '"." c2 = ASC(a$, i + 1) IF c2 >= 48 AND c2 <= 57 THEN 'scan until no further alphanumerics p2 = i + 1 FOR i2 = i + 2 TO n c = ASC(a$, i2) IF NOT alphanumeric(c) THEN EXIT FOR IF c <> 95 THEN p2 = i2 'don't including trailing _ NEXT a2$ = a2$ + sp + "." + sp + MID$(ca$, i + 1, p2 - (i + 1) + 1) 'case sensitive n2 = n2 + 1 + (p2 - (i + 1) + 1) i = p2 + 1 GOTO extcheck 'it may have an extension or be continued with another "." END IF END IF GOTO lineformatnext lfgetve: i = i + LEN(e2$) a2$ = a2$ + e2$ IF m THEN 'allow digits after symbol lfgetvd: IF i < n THEN c = ASC(a$, i) IF c >= 48 AND c <= 57 THEN a2$ = a2$ + CHR$(c): i = i + 1: GOTO lfgetvd END IF END IF 'm GOTO lineformatnext END IF 'p2 END IF 'variable/name '----------------variable/name end---------------- '----------------spacing---------------- IF c = 32 OR c = 9 THEN i = i + 1: GOTO lineformatnext '----------------symbols---------------- '--------single characters-------- IF lfsinglechar(c) THEN IF c = 60 THEN '< c2 = ASC(a$, i + 1) IF c2 = 61 THEN a2$ = a2$ + sp + "<=": i = i + 2: GOTO lineformatnext IF c2 = 62 THEN a2$ = a2$ + sp + "<>": i = i + 2: GOTO lineformatnext END IF IF c = 62 THEN '> c2 = ASC(a$, i + 1) IF c2 = 61 THEN a2$ = a2$ + sp + ">=": i = i + 2: GOTO lineformatnext IF c2 = 60 THEN a2$ = a2$ + sp + "<>": i = i + 2: GOTO lineformatnext '>< to <> END IF IF c = 61 THEN '= c2 = ASC(a$, i + 1) IF c2 = 62 THEN a2$ = a2$ + sp + ">=": i = i + 2: GOTO lineformatnext '=> to >= IF c2 = 60 THEN a2$ = a2$ + sp + "<=": i = i + 2: GOTO lineformatnext '=< to <= END IF IF c = 36 AND LEN(a2$) THEN GOTO badusage '$ a2$ = a2$ + sp + CHR$(c) i = i + 1 GOTO lineformatnext END IF badusage: IF c <> 39 THEN Give_Error "Unexpected character on line": EXIT FUNCTION 'invalid symbol encountered '----------------comment(')---------------- layoutcomment = "'" i = i + 1 comment: IF i >= n THEN GOTO lineformatdone2 c$ = RIGHT$(a$, LEN(a$) - i + 1) cc$ = RIGHT$(ca$, LEN(ca$) - i + 1) IF LEN(c$) = 0 THEN GOTO lineformatdone2 layoutcomment$ = RTRIM$(layoutcomment$ + cc$) c$ = LTRIM$(c$) IF LEN(c$) = 0 THEN GOTO lineformatdone2 ac = ASC(c$) IF ac <> 36 THEN GOTO lineformatdone2 nocasec$ = LTRIM$(RIGHT$(ca$, LEN(ca$) - i + 1)) memmode = 0 FOR x = 1 TO LEN(c$) mcnext: IF MID$(c$, x, 1) = "$" THEN 'note: $STATICksdcdweh$DYNAMIC is valid! IF MID$(c$, x, 7) = "$STATIC" THEN memmode = 1 xx = INSTR(x + 1, c$, "$") if xx=0 then exit for else x = xx: GOTO mcnext END IF IF MID$(c$, x, 8) = "$DYNAMIC" THEN memmode = 2 xx = INSTR(x + 1, c$, "$") IF xx = 0 THEN EXIT FOR x = xx: GOTO mcnext END IF IF MID$(c$, x, 8) = "$INCLUDE" THEN IF Cloud THEN Give_Error "Feature not supported on QLOUD": EXIT FUNCTION 'note: INCLUDE adds the file AFTER the line it is on has been processed 'note: No other metacommands can follow the INCLUDE metacommand! 'skip spaces until : FOR xx = x + 8 TO LEN(c$) ac = ASC(MID$(c$, xx, 1)) IF ac = 58 THEN EXIT FOR ': IF ac <> 32 AND ac <> 9 THEN Give_Error "Expected $INCLUDE:'filename'": EXIT FUNCTION NEXT x = xx 'skip spaces until ' FOR xx = x + 1 TO LEN(c$) ac = ASC(MID$(c$, xx, 1)) IF ac = 39 THEN EXIT FOR 'character:' IF ac <> 32 AND ac <> 9 THEN Give_Error "Expected $INCLUDE:'filename'": EXIT FUNCTION NEXT x = xx xx = INSTR(x + 1, c$, "'") IF xx = 0 THEN Give_Error "Expected $INCLUDE:'filename'": EXIT FUNCTION addmetainclude$ = MID$(nocasec$, x + 1, xx - x - 1) IF addmetainclude$ = "" THEN Give_Error "Expected $INCLUDE:'filename'": EXIT FUNCTION GOTO mcfinal END IF 'add more metacommands here END IF '$ NEXT mcfinal: IF memmode = 1 THEN addmetastatic = 1 IF memmode = 2 THEN addmetadynamic = 1 GOTO lineformatdone2 lineformatdone: 'line continuation? 'note: line continuation in idemode is illegal IF LEN(a2$) THEN IF RIGHT$(a2$, 1) = "_" THEN linecontinuation = 1 'avoids auto-format glitches layout$ = "" 'remove _ from the end of the building string IF LEN(a2$) >= 2 THEN IF RIGHT$(a2$, 2) = sp + "_" THEN a2$ = LEFT$(a2$, LEN(a2$) - 1) END IF a2$ = LEFT$(a2$, LEN(a2$) - 1) IF inclevel THEN fh = 99 + inclevel IF EOF(fh) THEN GOTO lineformatdone2 LINE INPUT #fh, a$ inclinenumber(inclevel) = inclinenumber(inclevel) + 1 GOTO includecont 'note: should not increase linenumber END IF IF idemode THEN idecommand$ = CHR$(100) ignore = ide(0) ideerror = 0 a$ = idereturn$ IF a$ = "" THEN GOTO lineformatdone2 ELSE a$ = lineinput3$ IF a$ = CHR$(13) THEN GOTO lineformatdone2 END IF linenumber = linenumber + 1 includecont: contline = 1 GOTO continueline END IF END IF lineformatdone2: IF LEFT$(a2$, 1) = sp THEN a2$ = RIGHT$(a2$, LEN(a2$) - 1) 'fix for trailing : error IF RIGHT$(a2$, 1) = ":" THEN a2$ = a2$ + sp + "'" 'add nop IF Debug THEN PRINT #9, "lineformat():return:" + a2$ IF Error_Happened THEN EXIT FUNCTION lineformat$ = a2$ END FUNCTION SUB makeidrefer (ref$, typ AS LONG) ref$ = str2$(currentid) typ = id.t + ISREFERENCE END SUB FUNCTION numelements (a$) IF a$ = "" THEN EXIT FUNCTION n = 1 p = 1 numelementsnext: i = INSTR(p, a$, sp) IF i = 0 THEN numelements = n: EXIT FUNCTION n = n + 1 p = i + 1 GOTO numelementsnext END FUNCTION FUNCTION operatorusage (operator$, typ AS LONG, info$, lhs AS LONG, rhs AS LONG, result AS LONG) lhs = 7: rhs = 7: result = 0 'return values '1 = use info$ as the operator without any other changes '2 = use the function returned in info$ to apply this operator ' upon left and right side of equation '3= bracket left and right side with negation and change operator to info$ '4= BINARY NOT l.h.s, then apply operator in info$ '5= UNARY, bracket up rhs, apply operator info$ to left, rebracket again 'lhs & rhs bit-field values '1=integeral '2=floating point '4=string '8=bool 'string operator IF (typ AND ISSTRING) THEN lhs = 4: rhs = 4 result = 4 IF operator$ = "+" THEN info$ = "qbs_add": operatorusage = 2: EXIT FUNCTION result = 8 IF operator$ = "=" THEN info$ = "qbs_equal": operatorusage = 2: EXIT FUNCTION IF operator$ = "<>" THEN info$ = "qbs_notequal": operatorusage = 2: EXIT FUNCTION IF operator$ = ">" THEN info$ = "qbs_greaterthan": operatorusage = 2: EXIT FUNCTION IF operator$ = "<" THEN info$ = "qbs_lessthan": operatorusage = 2: EXIT FUNCTION IF operator$ = ">=" THEN info$ = "qbs_greaterorequal": operatorusage = 2: EXIT FUNCTION IF operator$ = "<=" THEN info$ = "qbs_lessorequal": operatorusage = 2: EXIT FUNCTION IF Debug THEN PRINT #9, "INVALID STRING OPERATOR!": END END IF 'assume numeric operator lhs = 1 + 2: rhs = 1 + 2 IF operator$ = "^" THEN result = 2: info$ = "pow2": operatorusage = 2: EXIT FUNCTION IF operator$ = "ñ" THEN info$ = "-": operatorusage = 5: EXIT FUNCTION IF operator$ = "/" THEN info$ = "/ ": operatorusage = 1 'for / division, either the lhs or the rhs must be a float to make 'c++ return a result in floating point form IF (typ AND ISFLOAT) THEN 'lhs is a float lhs = 2 rhs = 1 + 2 ELSE 'lhs isn't a float! lhs = 1 + 2 rhs = 2 END IF result = 2 EXIT FUNCTION END IF IF operator$ = "*" THEN info$ = "*": operatorusage = 1: EXIT FUNCTION IF operator$ = "+" THEN info$ = "+": operatorusage = 1: EXIT FUNCTION IF operator$ = "-" THEN info$ = "-": operatorusage = 1: EXIT FUNCTION result = 8 IF operator$ = "=" THEN info$ = "==": operatorusage = 3: EXIT FUNCTION IF operator$ = ">" THEN info$ = ">": operatorusage = 3: EXIT FUNCTION IF operator$ = "<" THEN info$ = "<": operatorusage = 3: EXIT FUNCTION IF operator$ = "<>" THEN info$ = "!=": operatorusage = 3: EXIT FUNCTION IF operator$ = "<=" THEN info$ = "<=": operatorusage = 3: EXIT FUNCTION IF operator$ = ">=" THEN info$ = ">=": operatorusage = 3: EXIT FUNCTION lhs = 1: rhs = 1: result = 1 IF operator$ = "MOD" THEN info$ = "%": operatorusage = 1: EXIT FUNCTION IF operator$ = "\" THEN info$ = "/ ": operatorusage = 1: EXIT FUNCTION IF operator$ = "IMP" THEN info$ = "|": operatorusage = 4: EXIT FUNCTION IF operator$ = "EQV" THEN info$ = "^": operatorusage = 4: EXIT FUNCTION IF operator$ = "XOR" THEN info$ = "^": operatorusage = 1: EXIT FUNCTION IF operator$ = "OR" THEN info$ = "|": operatorusage = 1: EXIT FUNCTION IF operator$ = "AND" THEN info$ = "&": operatorusage = 1: EXIT FUNCTION lhs = 7 IF operator$ = "NOT" THEN info$ = "~": operatorusage = 5: EXIT FUNCTION IF Debug THEN PRINT #9, "INVALID NUMBERIC OPERATOR!": END END FUNCTION FUNCTION refer$ (a2$, typ AS LONG, method AS LONG) typbak = typ 'method: 0 return an equation which calculates the value of the "variable" ' 1 return the C name of the variable, typ will be left unchanged a$ = a2$ 'retrieve ID i = INSTR(a$, sp3) IF i THEN idnumber = VAL(LEFT$(a$, i - 1)): a$ = RIGHT$(a$, LEN(a$) - i) ELSE idnumber = VAL(a$) END IF getid idnumber IF Error_Happened THEN EXIT FUNCTION 'UDT? IF typ AND ISUDT THEN IF method = 1 THEN n$ = "UDT_" + RTRIM$(id.n) IF id.t = 0 THEN n$ = "ARRAY_" + n$ n$ = scope$ + n$ refer$ = n$ EXIT FUNCTION END IF 'print "UDTSUBSTRING[idX|u|e|o]:"+a$ u = VAL(a$) i = INSTR(a$, sp3): a$ = RIGHT$(a$, LEN(a$) - i): E = VAL(a$) i = INSTR(a$, sp3): o$ = RIGHT$(a$, LEN(a$) - i) n$ = "UDT_" + RTRIM$(id.n): IF id.t = 0 THEN n$ = "ARRAY_" + n$ + "[0]" IF E = 0 THEN Give_Error "User defined types in expressions are invalid": EXIT FUNCTION IF typ AND ISOFFSETINBITS THEN Give_Error "Cannot resolve bit-length variables inside user defined types yet": EXIT FUNCTION IF typ AND ISSTRING THEN o2$ = "(((uint8*)" + scope$ + n$ + ")+(" + o$ + "))" r$ = "qbs_new_fixed(" + o2$ + "," + str2(udtetypesize(E)) + ",1)" typ = STRINGTYPE + ISFIXEDLENGTH 'ISPOINTER retained, it is still a pointer! ELSE typ = typ - ISUDT - ISREFERENCE - ISPOINTER IF typ AND ISARRAY THEN typ = typ - ISARRAY t$ = typ2ctyp$(typ, "") IF Error_Happened THEN EXIT FUNCTION o2$ = "(((char*)" + scope$ + n$ + ")+(" + o$ + "))" r$ = "*" + "(" + t$ + "*)" + o2$ END IF 'print "REFER:"+r$+","+str2$(typ) refer$ = r$ EXIT FUNCTION END IF 'array? IF id.arraytype THEN n$ = RTRIM$(id.callname) IF method = 1 THEN refer$ = n$ typ = typbak EXIT FUNCTION END IF typ = typ - ISPOINTER - ISREFERENCE 'typ now looks like a regular value IF (typ AND ISSTRING) THEN IF (typ AND ISFIXEDLENGTH) THEN offset$ = "&((uint8*)(" + n$ + "[0]))[(" + a$ + ")*" + str2(id.tsize) + "]" r$ = "qbs_new_fixed(" + offset$ + "," + str2(id.tsize) + ",1)" ELSE r$ = "((qbs*)(((uint64*)(" + n$ + "[0]))[" + a$ + "]))" END IF stringprocessinghappened = 1 refer$ = r$ EXIT FUNCTION END IF IF (typ AND ISOFFSETINBITS) THEN 'IF (typ AND ISUNSIGNED) THEN r$ = "getubits_" ELSE r$ = "getbits_" 'r$ = r$ + str2(typ AND 511) + "(" IF (typ AND ISUNSIGNED) THEN r$ = "getubits" ELSE r$ = "getbits" r$ = r$ + "(" + str2(typ AND 511) + "," r$ = r$ + "(uint8*)(" + n$ + "[0])" + "," r$ = r$ + a$ + ")" refer$ = r$ EXIT FUNCTION ELSE t$ = "" IF (typ AND ISFLOAT) THEN IF (typ AND 511) = 32 THEN t$ = "float" IF (typ AND 511) = 64 THEN t$ = "double" IF (typ AND 511) = 256 THEN t$ = "long double" ELSE IF (typ AND ISUNSIGNED) THEN IF (typ AND 511) = 8 THEN t$ = "uint8" IF (typ AND 511) = 16 THEN t$ = "uint16" IF (typ AND 511) = 32 THEN t$ = "uint32" IF (typ AND 511) = 64 THEN t$ = "uint64" IF typ AND ISOFFSET THEN t$ = "uptrszint" ELSE IF (typ AND 511) = 8 THEN t$ = "int8" IF (typ AND 511) = 16 THEN t$ = "int16" IF (typ AND 511) = 32 THEN t$ = "int32" IF (typ AND 511) = 64 THEN t$ = "int64" IF typ AND ISOFFSET THEN t$ = "ptrszint" END IF END IF END IF IF t$ = "" THEN Give_Error "Cannot find C type to return array data": EXIT FUNCTION r$ = "((" + t$ + "*)(" + n$ + "[0]))[" + a$ + "]" refer$ = r$ EXIT FUNCTION END IF 'array 'variable? IF id.t THEN r$ = RTRIM$(id.n) t = id.t 'remove irrelavant flags IF (t AND ISINCONVENTIONALMEMORY) THEN t = t - ISINCONVENTIONALMEMORY 'string? IF (t AND ISSTRING) THEN IF (t AND ISFIXEDLENGTH) THEN r$ = scope$ + "STRING" + str2(id.tsize) + "_" + r$: GOTO ref END IF r$ = scope$ + "STRING_" + r$: GOTO ref END IF 'bit-length single variable? IF (t AND ISOFFSETINBITS) THEN IF (t AND ISUNSIGNED) THEN r$ = "*" + scope$ + "UBIT" + str2(t AND 511) + "_" + r$ ELSE r$ = "*" + scope$ + "BIT" + str2(t AND 511) + "_" + r$ END IF GOTO ref END IF IF t = BYTETYPE THEN r$ = "*" + scope$ + "BYTE_" + r$: GOTO ref IF t = UBYTETYPE THEN r$ = "*" + scope$ + "UBYTE_" + r$: GOTO ref IF t = INTEGERTYPE THEN r$ = "*" + scope$ + "INTEGER_" + r$: GOTO ref IF t = UINTEGERTYPE THEN r$ = "*" + scope$ + "UINTEGER_" + r$: GOTO ref IF t = LONGTYPE THEN r$ = "*" + scope$ + "LONG_" + r$: GOTO ref IF t = ULONGTYPE THEN r$ = "*" + scope$ + "ULONG_" + r$: GOTO ref IF t = INTEGER64TYPE THEN r$ = "*" + scope$ + "INTEGER64_" + r$: GOTO ref IF t = UINTEGER64TYPE THEN r$ = "*" + scope$ + "UINTEGER64_" + r$: GOTO ref IF t = SINGLETYPE THEN r$ = "*" + scope$ + "SINGLE_" + r$: GOTO ref IF t = DOUBLETYPE THEN r$ = "*" + scope$ + "DOUBLE_" + r$: GOTO ref IF t = FLOATTYPE THEN r$ = "*" + scope$ + "FLOAT_" + r$: GOTO ref IF t = OFFSETTYPE THEN r$ = "*" + scope$ + "OFFSET_" + r$: GOTO ref IF t = UOFFSETTYPE THEN r$ = "*" + scope$ + "UOFFSET_" + r$: GOTO ref ref: IF (t AND ISSTRING) THEN stringprocessinghappened = 1 IF (t AND ISPOINTER) THEN t = t - ISPOINTER typ = t IF method = 1 THEN IF LEFT$(r$, 1) = "*" THEN r$ = RIGHT$(r$, LEN(r$) - 1) typ = typbak END IF refer$ = r$ EXIT FUNCTION END IF 'variable END FUNCTION SUB regid idn = idn + 1 IF idn > ids_max THEN ids_max = ids_max * 2 REDIM _PRESERVE ids(1 TO ids_max) AS idstruct REDIM _PRESERVE cmemlist(1 TO ids_max + 1) AS INTEGER REDIM _PRESERVE sfcmemargs(1 TO ids_max + 1) AS STRING * 100 REDIM _PRESERVE arrayelementslist(1 TO ids_max + 1) AS INTEGER END IF n$ = RTRIM$(id.n) IF reginternalsubfunc = 0 THEN IF validname(n$) = 0 THEN Give_Error "Invalid name": EXIT SUB END IF 'register case sensitive name if none given IF ASC(id.cn) = 32 THEN n$ = RTRIM$(id.n) id.n = UCASE$(n$) id.cn = n$ END IF IF LEN(Refactor_Source) THEN n$ = RTRIM$(id.n) IF UCASE$(n$) = UCASE$(Refactor_Source) THEN id.cn = Refactor_Dest END IF END IF id.insubfunc = subfunc id.insubfuncn = subfuncn 'note: cannot be STATIC and SHARED at the same time IF dimshared THEN id.share = dimshared ELSE IF dimstatic THEN id.staticscope = 1 END IF ids(idn) = id currentid = idn 'prepare hash flags and check for conflicts hashflags = 1 'sub/function? 'Note: QBASIC does not allow: Internal type names (INTEGER,LONG,...) IF id.subfunc THEN ids(currentid).internal_subfunc = reginternalsubfunc IF id.subfunc = 1 THEN hashflags = hashflags + HASHFLAG_FUNCTION ELSE hashflags = hashflags + HASHFLAG_SUB IF reginternalsubfunc = 0 THEN 'allow internal definition of subs/functions without checks hashchkflags = HASHFLAG_RESERVED + HASHFLAG_CONSTANT IF id.subfunc = 1 THEN hashchkflags = hashchkflags + HASHFLAG_FUNCTION ELSE hashchkflags = hashchkflags + HASHFLAG_SUB hashres = HashFind(n$, hashchkflags, hashresflags, hashresref) DO WHILE hashres IF hashres THEN 'Note: Numeric sub/function names like 'mid' do not clash with Internal string sub/function names ' like 'MID$' because MID$ always requires a '$'. For user defined string sub/function names ' the '$' would be optional so the rule should not be applied there. allow = 0 IF hashresflags AND (HASHFLAG_FUNCTION + HASHFLAG_SUB) THEN IF RTRIM$(ids(hashresref).musthave) = "$" THEN IF INSTR(ids(currentid).mayhave, "$") = 0 THEN allow = 1 END IF END IF IF allow = 0 THEN Give_Error "Name already in use": EXIT SUB END IF 'hashres IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP END IF 'reginternalsubfunc = 0 END IF 'variable? IF id.t THEN hashflags = hashflags + HASHFLAG_VARIABLE IF reginternalvariable = 0 THEN allow = 0 var_recheck: IF ASC(id.musthave) = 32 THEN astype2 = 1 '"AS type" declaration? scope2 = subfuncn hashchkflags = HASHFLAG_RESERVED + HASHFLAG_SUB + HASHFLAG_FUNCTION + HASHFLAG_CONSTANT + HASHFLAG_VARIABLE hashres = HashFind(n$, hashchkflags, hashresflags, hashresref) DO WHILE hashres 'conflict with reserved word? IF hashresflags AND HASHFLAG_RESERVED THEN musthave$ = RTRIM$(id.musthave) IF INSTR(musthave$, "$") THEN 'All reserved words can be used as variables in QBASIC if "$" is appended to the variable name! '(allow) ELSE Give_Error "Name already in use": EXIT SUB 'Conflicts with reserved word END IF END IF 'HASHFLAG_RESERVED 'conflict with sub/function? IF hashresflags AND (HASHFLAG_FUNCTION + HASHFLAG_SUB) THEN IF ids(hashresref).internal_subfunc = 0 THEN Give_Error "Name already in use": EXIT SUB 'QBASIC doesn't allow a variable of the same name as a user-defined sub/func IF RTRIM$(id.n) = "WIDTH" AND ids(hashresref).subfunc = 2 THEN GOTO varname_exception musthave$ = RTRIM$(id.musthave) IF LEN(musthave$) = 0 THEN IF RTRIM$(ids(hashresref).musthave) = "$" THEN 'a sub/func requiring "$" can co-exist with implicit numeric variables IF INSTR(id.mayhave, "$") THEN Give_Error "Name already in use": EXIT SUB ELSE Give_Error "Name already in use": EXIT SUB 'Implicitly defined variables cannot conflict with sub/func names END IF END IF 'len(musthave$)=0 IF INSTR(musthave$, "$") THEN IF RTRIM$(ids(hashresref).musthave) = "$" THEN Give_Error "Name already in use": EXIT SUB 'A sub/function name already exists as a string '(allow) ELSE IF RTRIM$(ids(hashresref).musthave) <> "$" THEN Give_Error "Name already in use": EXIT SUB 'A non-"$" sub/func name already exists with this name END IF END IF 'HASHFLAG_FUNCTION + HASHFLAG_SUB 'conflict with constant? IF hashresflags AND HASHFLAG_CONSTANT THEN scope1 = constsubfunc(hashresref) IF (scope1 = 0 AND AllowLocalName = 0) OR scope1 = scope2 THEN Give_Error "Name already in use": EXIT SUB END IF 'conflict with variable? IF hashresflags AND HASHFLAG_VARIABLE THEN astype1 = 0: IF ASC(ids(hashresref).musthave) = 32 THEN astype1 = 1 scope1 = ids(hashresref).insubfuncn IF astype1 = 1 AND astype2 = 1 THEN IF scope1 = scope2 THEN Give_Error "Name already in use": EXIT SUB END IF 'same type? IF id.t = ids(hashresref).t THEN IF id.tsize = ids(hashresref).tsize THEN IF scope1 = scope2 THEN Give_Error "Name already in use": EXIT SUB END IF END IF 'will astype'd fixed STRING-variable mask a non-fixed string? IF id.t AND ISFIXEDLENGTH THEN IF astype2 = 1 THEN IF ids(hashresref).t AND ISSTRING THEN IF (ids(hashresref).t AND ISFIXEDLENGTH) = 0 THEN IF scope1 = scope2 THEN Give_Error "Name already in use": EXIT SUB END IF END IF END IF END IF END IF varname_exception: IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP END IF 'reginternalvariable END IF 'variable 'array? IF id.arraytype THEN hashflags = hashflags + HASHFLAG_ARRAY allow = 0 ary_recheck: scope2 = subfuncn IF ASC(id.musthave) = 32 THEN astype2 = 1 '"AS type" declaration? hashchkflags = HASHFLAG_RESERVED + HASHFLAG_SUB + HASHFLAG_FUNCTION + HASHFLAG_ARRAY hashres = HashFind(n$, hashchkflags, hashresflags, hashresref) DO WHILE hashres 'conflict with reserved word? IF hashresflags AND HASHFLAG_RESERVED THEN musthave$ = RTRIM$(id.musthave) IF INSTR(musthave$, "$") THEN 'All reserved words can be used as variables in QBASIC if "$" is appended to the variable name! '(allow) ELSE Give_Error "Name already in use": EXIT SUB 'Conflicts with reserved word END IF END IF 'HASHFLAG_RESERVED 'conflict with sub/function? IF hashresflags AND (HASHFLAG_FUNCTION + HASHFLAG_SUB) THEN IF ids(hashresref).internal_subfunc = 0 THEN Give_Error "Name already in use": EXIT SUB 'QBASIC doesn't allow a variable of the same name as a user-defined sub/func IF RTRIM$(id.n) = "WIDTH" AND ids(hashresref).subfunc = 2 THEN GOTO arrayname_exception musthave$ = RTRIM$(id.musthave) IF LEN(musthave$) = 0 THEN IF RTRIM$(ids(hashresref).musthave) = "$" THEN 'a sub/func requiring "$" can co-exist with implicit numeric variables IF INSTR(id.mayhave, "$") THEN Give_Error "Name already in use": EXIT SUB ELSE Give_Error "Name already in use": EXIT SUB 'Implicitly defined variables cannot conflict with sub/func names END IF END IF 'len(musthave$)=0 IF INSTR(musthave$, "$") THEN IF RTRIM$(ids(hashresref).musthave) = "$" THEN Give_Error "Name already in use": EXIT SUB 'A sub/function name already exists as a string '(allow) ELSE IF RTRIM$(ids(hashresref).musthave) <> "$" THEN Give_Error "Name already in use": EXIT SUB 'A non-"$" sub/func name already exists with this name END IF END IF 'HASHFLAG_FUNCTION + HASHFLAG_SUB 'conflict with array? IF hashresflags AND HASHFLAG_ARRAY THEN astype1 = 0: IF ASC(ids(hashresref).musthave) = 32 THEN astype1 = 1 scope1 = ids(hashresref).insubfuncn IF astype1 = 1 AND astype2 = 1 THEN IF scope1 = scope2 THEN Give_Error "Name already in use": EXIT SUB END IF 'same type? IF id.arraytype = ids(hashresref).arraytype THEN IF id.tsize = ids(hashresref).tsize THEN IF scope1 = scope2 THEN Give_Error "Name already in use": EXIT SUB END IF END IF 'will astype'd fixed STRING-variable mask a non-fixed string? IF id.arraytype AND ISFIXEDLENGTH THEN IF astype2 = 1 THEN IF ids(hashresref).arraytype AND ISSTRING THEN IF (ids(hashresref).arraytype AND ISFIXEDLENGTH) = 0 THEN IF scope1 = scope2 THEN Give_Error "Name already in use": EXIT SUB END IF END IF END IF END IF END IF arrayname_exception: IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP END IF 'array 'add it to the hash table HashAdd n$, hashflags, currentid END SUB SUB reginternal reginternalsubfunc = 1 'special codes: '-1 Any numeric variable (will be made explicit by a C cast) ' Typically, these are used when multiple C functions exist '-2 Offset+Size(in bytes) ' Size is the largest safe memory block available from the offset ' used for: CALL INTERRUPT[X] '-3 Offset+Size(in bytes) ' Size is the largest safe memory block available from the offset ' *Like -2, but restrictions apply ' used for: GET/PUT(graphics) '-4 Offset+Size(in bytes) ' Size is the size of the element referenced ' used for: GET/PUT(file) ' -5 Offset only ' -6 Size only '-7 '_MEM' structure referring to the passed variable 'special return codes: 'none 'stubs for internally handled commands: clearid id.n = "ASC": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "END": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "LSET": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "RSET": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "MID": id.subfunc = 2: id.callname = "sub_stub": id.musthave = "$": regid clearid id.n = "PRINT": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "OPTION": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "SWAP": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "SYSTEM": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "WRITE": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "READ": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "CLOSE": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "RESET": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "INPUT": id.subfunc = 2: id.callname = "sub_stub": regid 'stubs for unimplemented commands: clearid id.n = "TRON": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "TROFF": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "LIST": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "DEF": id.subfunc = 2: id.callname = "sub_stub": id.secondargcantbe = "SEG": regid clearid id.n = "IOCTL": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "IOCTL": id.subfunc = 1: id.callname = "func_stub": id.musthave = "$": id.args = 1: id.arg = MKL$(LONGTYPE - ISPOINTER): id.ret = STRINGTYPE - ISPOINTER: regid clearid id.n = "FRE": id.subfunc = 1: id.callname = "func_stub": id.args = 1: id.arg = MKL$(LONGTYPE - ISPOINTER): id.ret = LONGTYPE - ISPOINTER: regid clearid id.n = "SETMEM": id.subfunc = 1: id.callname = "func_stub": id.args = 1: id.arg = MKL$(LONGTYPE - ISPOINTER): id.ret = LONGTYPE - ISPOINTER: regid clearid id.n = "FILEATTR": id.subfunc = 1: id.callname = "func_stub": id.args = 2: id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER): id.ret = LONGTYPE - ISPOINTER: regid clearid id.n = "_MEMGET": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "_MEMPUT": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "_MEMFILL": id.subfunc = 2: id.callname = "sub_stub": regid clearid id.n = "_RESIZE" id.subfunc = 2 id.callname = "sub__resize" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{ON|OFF}][,{_STRETCH|_SMOOTH}]" regid clearid id.n = "_RESIZE" id.subfunc = 1 id.callname = "func__resize" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_RESIZEWIDTH" id.subfunc = 1 id.callname = "func__resizewidth" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_RESIZEHEIGHT" id.subfunc = 1 id.callname = "func__resizeheight" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_GLRENDER" id.subfunc = 2 id.callname = "sub__glrender" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "{_BEHIND|_ONTOP|_ONLY}" id.NoCloud = 1 regid clearid id.n = "_MEMGET" id.subfunc = 1 id.callname = "func__memget" id.args = 3 id.arg = MKL$(UDTTYPE + (1)) + MKL$(OFFSETTYPE - ISPOINTER) + MKL$(-1) 'x = _MEMGET(block, offset, type) id.ret = -1 id.NoCloud = 1 regid clearid id.n = "_MEM" id.subfunc = 1 id.callname = "func__mem" 'id.args = 1 'id.arg = MKL$(-7) id.args = 2 id.arg = MKL$(OFFSETTYPE - ISPOINTER) + MKL$(OFFSETTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = ISUDT + (1) 'the _MEM type is the first TYPE defined id.NoCloud = 1 regid '---special case--- clearid id.n = "_MEMELEMENT" id.subfunc = 1 id.callname = "func__mem" id.args = 1 id.arg = MKL$(-8) id.ret = ISUDT + (1) 'the _MEM type is the first TYPE defined id.NoCloud = 1 regid '---special case--- clearid id.n = "_MEMFREE" id.subfunc = 2 id.callname = "sub__memfree" id.args = 1 id.arg = MKL$(UDTTYPE + (1)) id.NoCloud = 1 regid clearid id.n = "_MEMEXISTS" id.subfunc = 1 id.callname = "func__memexists" id.args = 1 id.arg = MKL$(UDTTYPE + (1)) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_MEMNEW" id.subfunc = 1 id.callname = "func__memnew" id.args = 1 id.arg = MKL$(OFFSETTYPE - ISPOINTER) id.ret = ISUDT + (1) 'the _MEM type is the first TYPE defined id.NoCloud = 1 regid clearid id.n = "_MEMIMAGE" id.subfunc = 1 id.callname = "func__memimage" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" 'dest is default id.ret = ISUDT + (1) 'the _MEM type is the first TYPE defined id.NoCloud = 1 regid clearid '_MEMCOPY a, aoffset, bytes TO b, boffset id.n = "_MEMCOPY" id.subfunc = 2 id.callname = "sub__memcopy" id.args = 5 id.arg = MKL$(UDTTYPE + (1)) + MKL$(OFFSETTYPE - ISPOINTER) + MKL$(OFFSETTYPE - ISPOINTER) + MKL$(UDTTYPE + (1)) + MKL$(OFFSETTYPE - ISPOINTER) id.specialformat = "?,?,?{TO}?,?" 'dest is default id.NoCloud = 1 regid clearid id.n = "_CONSOLETITLE" id.subfunc = 2 id.callname = "sub__consoletitle" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SCREENSHOW" id.subfunc = 2 id.callname = "sub__screenshow" id.NoCloud = 1 regid clearid id.n = "_SCREENHIDE" id.subfunc = 2 id.callname = "sub__screenhide" id.NoCloud = 1 regid clearid id.n = "_CONSOLE" id.subfunc = 1 id.callname = "func__console" id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_CONSOLE" id.subfunc = 2 id.callname = "sub__console" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "{ON|OFF}" id.NoCloud = 1 regid clearid id.n = "_CONTROLCHR" id.subfunc = 2 id.callname = "sub__controlchr" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "{ON|OFF}" regid clearid id.n = "_FILEEXISTS" id.subfunc = 1 id.callname = "func__fileexists" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_DIREXISTS" id.subfunc = 1 id.callname = "func__direxists" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid 'QB64 DEVICE interface clearid id.n = "STICK" id.subfunc = 1 id.callname = "func_stick" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "?[,?]" regid clearid id.n = "STRIG" id.subfunc = 1 id.callname = "func_strig" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "?[,?]" regid clearid id.n = "STRIG" id.subfunc = 2 id.callname = "sub_strig" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[(?[,?])]{ON|OFF|STOP}" 'In previous versions of BASIC, the statement STRIG ON enables testing of the joystick triggers; STRIG OFF disables joystick trigger testing. QuickBASIC ignores STRIG ON and STRIG OFF statements--the statements are provided for compatibility with earlier versions. regid clearid id.n = "_DEVICES" id.subfunc = 1 id.callname = "func__devices" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_DEVICE" id.musthave = "$" id.subfunc = 1 id.callname = "func__device" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_DEVICEINPUT" id.subfunc = 1 id.callname = "func__deviceinput" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_LASTBUTTON" id.subfunc = 1 id.callname = "func__lastbutton" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_LASTAXIS" id.subfunc = 1 id.callname = "func__lastaxis" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_LASTWHEEL" id.subfunc = 1 id.callname = "func__lastwheel" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_BUTTON" id.subfunc = 1 id.callname = "func__button" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_BUTTONCHANGE" id.subfunc = 1 id.callname = "func__buttonchange" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_AXIS" id.subfunc = 1 id.callname = "func__axis" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "_WHEEL" id.subfunc = 1 id.callname = "func__wheel" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "KEY" id.subfunc = 2 id.callname = "sub_key" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "(?){ON|OFF|STOP}" regid clearid id.n = "_SCREENX" id.subfunc = 1 id.callname = "func__screenx" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_SCREENY" id.subfunc = 1 id.callname = "func__screeny" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_SCREENMOVE" id.subfunc = 2 id.callname = "sub__screenmove" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{_MIDDLE}][?,?]" regid clearid id.n = "_MOUSEMOVE" id.subfunc = 2 id.callname = "sub__mousemove" id.args = 2 id.arg = MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) regid clearid id.n = "_OS" id.musthave = "$" id.subfunc = 1 id.callname = "func__os" id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "_MAPUNICODE" id.subfunc = 2 id.callname = "sub__mapunicode" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?{TO}?" regid clearid id.n = "_MAPUNICODE" id.subfunc = 1 id.callname = "func__mapunicode" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_KEYDOWN" id.subfunc = 1 id.callname = "func__keydown" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_KEYHIT" id.subfunc = 1 id.callname = "func__keyhit" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "FILES" id.subfunc = 2 id.callname = "sub_files" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "[?]" id.NoCloud = 1 regid clearid id.n = "_PRINTIMAGE" id.subfunc = 2 id.callname = "sub__printimage" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) ''proposed version: ''id.specialformat = "[_SQUAREPIXELS][?][,(?,?)-(?,?)]" id.NoCloud = 1 regid 'remote desktop clearid id.n = "_SCREENCLICK" id.subfunc = 2 id.callname = "sub__screenclick" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SCREENPRINT" id.subfunc = 2 id.callname = "sub__screenprint" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SCREENIMAGE" id.subfunc = 1 id.callname = "func__screenimage" id.args = 4 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?,?,?,?]" id.ret = LONGTYPE - ISPOINTER id.Dependency = DEPENDENCY_IMAGE_CODEC 'used by OSX to read in screen capture files id.NoCloud = 1 regid clearid id.n = "LOCK" id.subfunc = 2 id.callname = "sub_lock" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(INTEGER64TYPE - ISPOINTER) + MKL$(INTEGER64TYPE - ISPOINTER) id.specialformat = "[#]?[,[?][{TO}?]]" id.NoCloud = 1 regid clearid id.n = "UNLOCK" id.subfunc = 2 id.callname = "sub_unlock" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(INTEGER64TYPE - ISPOINTER) + MKL$(INTEGER64TYPE - ISPOINTER) id.specialformat = "[#]?[,[?][{TO}?]]" id.NoCloud = 1 regid clearid id.n = "_FREETIMER" id.subfunc = 1 id.callname = "func__freetimer" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "TIMER" id.subfunc = 2 id.callname = "sub_timer" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[(?)]{ON|OFF|STOP|FREE}" regid clearid id.n = "_FULLSCREEN" id.subfunc = 2 id.callname = "sub__fullscreen" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{_OFF|_STRETCH|_SQUAREPIXELS}][,{_SMOOTH}]" id.NoCloud = 1 regid clearid id.n = "_FULLSCREEN" id.subfunc = 1 id.callname = "func__fullscreen" id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_CLIPBOARD" id.musthave = "$" id.subfunc = 2 id.callname = "sub__clipboard" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "=?" id.NoCloud = 1 regid clearid id.n = "_CLIPBOARD" id.musthave = "$" id.subfunc = 1 id.callname = "func__clipboard" id.ret = STRINGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_EXIT" id.subfunc = 1 id.callname = "func__exit" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_OPENHOST" id.subfunc = 1 id.callname = "func__openhost" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_CONNECTED" id.subfunc = 1 id.callname = "func__connected" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_CONNECTIONADDRESS" id.mayhave = "$" id.subfunc = 1 id.callname = "func__connectionaddress" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "_OPENCONNECTION" id.subfunc = 1 id.callname = "func__openconnection" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_OPENCLIENT" id.subfunc = 1 id.callname = "func__openclient" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "ENVIRON" id.musthave = "$" id.subfunc = 1 id.callname = "func_environ" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "ENVIRON" id.subfunc = 2 id.callname = "sub_environ" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_ERRORLINE" id.subfunc = 1 id.callname = "func__errorline" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_DISPLAY" id.subfunc = 2 id.callname = "sub__display" regid clearid id.n = "_AUTODISPLAY" id.subfunc = 2 id.callname = "sub__autodisplay" regid clearid id.n = "_LIMIT" id.subfunc = 2 id.callname = "sub__limit" id.args = 1 id.arg = MKL$(DOUBLETYPE - ISPOINTER) regid clearid id.n = "_DELAY" id.subfunc = 2 id.callname = "sub__delay" id.args = 1 id.arg = MKL$(DOUBLETYPE - ISPOINTER) regid clearid id.n = "_ICON" id.subfunc = 2 id.callname = "sub__icon" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?[,?]]" id.NoCloud = 1 regid clearid id.n = "_TITLE" id.subfunc = 2 id.callname = "sub__title" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "CLEAR" id.subfunc = 2 id.callname = "sub_clear" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?][,[?][,?]]" regid 'IMAGE CREATION/FREEING clearid id.n = "_NEWIMAGE" id.subfunc = 1 id.callname = "func__newimage" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,?[,?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_LOADIMAGE" id.subfunc = 1 id.callname = "func__loadimage" id.args = 2 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = LONGTYPE - ISPOINTER id.Dependency = DEPENDENCY_IMAGE_CODEC regid clearid id.n = "_FREEIMAGE" id.subfunc = 2 id.callname = "sub__freeimage" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" regid clearid id.n = "_COPYIMAGE" id.subfunc = 1 id.callname = "func__copyimage" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid 'IMAGE SELECTION clearid id.n = "_SOURCE" id.subfunc = 2 id.callname = "sub__source" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?" regid clearid id.n = "_DEST" id.subfunc = 2 id.callname = "sub__dest" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?" regid clearid id.n = "_SOURCE" id.subfunc = 1 id.callname = "func__source" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_DEST" id.subfunc = 1 id.callname = "func__dest" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_DISPLAY" id.subfunc = 1 id.callname = "func__display" id.ret = LONGTYPE - ISPOINTER regid 'IMAGE SETTINGS clearid id.n = "_BLEND" id.subfunc = 2 id.callname = "sub__blend" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" regid clearid id.n = "_DONTBLEND" id.subfunc = 2 id.callname = "sub__dontblend" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" regid clearid id.n = "_CLEARCOLOR" id.subfunc = 2 id.callname = "sub__clearcolor" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{_NONE}][?][,?]" regid 'USING/CHANGING A SURFACE clearid id.n = "_PUTIMAGE" id.subfunc = 2 id.callname = "sub__putimage" id.args = 10 id.arg = MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) id.specialformat = "[[{STEP}](?,?)[-[{STEP}](?,?)]][,[?][,[?][,[[{STEP}](?,?)[-[{STEP}](?,?)]]]]]" regid clearid id.n = "_MAPTRIANGLE" id.subfunc = 2 id.callname = "sub__maptriangle" id.args = 14 id.arg = MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{_SEAMLESS}](?,?)-(?,?)-(?,?)[,?]{TO}(?,?)-(?,?)-(?,?)[,?]" regid clearid id.n = "_SETALPHA" id.subfunc = 2 id.callname = "sub__setalpha" id.args = 4 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,[?[{TO}?]][,?]]" regid 'IMAGE INFO clearid id.n = "_WIDTH" id.subfunc = 1 id.callname = "func__width" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_HEIGHT" id.subfunc = 1 id.callname = "func__height" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_PIXELSIZE" id.subfunc = 1 id.callname = "func__pixelsize" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_CLEARCOLOR" id.subfunc = 1 id.callname = "func__clearcolor" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_BLEND" id.subfunc = 1 id.callname = "func__blend" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_DEFAULTCOLOR" id.subfunc = 1 id.callname = "func__defaultcolor" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = ULONGTYPE - ISPOINTER regid clearid id.n = "_BACKGROUNDCOLOR" id.subfunc = 1 id.callname = "func__backgroundcolor" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = ULONGTYPE - ISPOINTER regid '256 COLOR PALETTES clearid id.n = "_PALETTECOLOR" id.subfunc = 1 id.callname = "func__palettecolor" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_PALETTECOLOR" id.subfunc = 2 id.callname = "sub__palettecolor" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,?[,?]" regid clearid id.n = "_COPYPALETTE" id.subfunc = 2 id.callname = "sub__copypalette" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?][,?]" regid 'FONT SUPPORT clearid id.n = "_LOADFONT" id.subfunc = 1 id.callname = "func__loadfont" id.args = 3 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "?,?[,?]" id.ret = LONGTYPE - ISPOINTER id.Dependency = DEPENDENCY_LOADFONT regid clearid id.n = "_FONT" id.subfunc = 2 id.callname = "sub__font" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,?]" regid clearid id.n = "_FONTWIDTH" id.subfunc = 1 id.callname = "func__fontwidth" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_FONTHEIGHT" id.subfunc = 1 id.callname = "func__fontheight" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_FONT" id.subfunc = 1 id.callname = "func__font" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_PRINTSTRING" id.subfunc = 2 id.callname = "sub__printstring" id.args = 4 id.arg = MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?),?[,?]" regid clearid id.n = "_PRINTWIDTH" id.subfunc = 1 id.callname = "func__printwidth" id.args = 2 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_FREEFONT" id.subfunc = 2 id.callname = "sub__freefont" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?" regid clearid id.n = "_PRINTMODE" id.subfunc = 2 id.callname = "sub__printmode" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "{_FILLBACKGROUND|_KEEPBACKGROUND|_ONLYBACKGROUND}[,?]" regid clearid id.n = "_PRINTMODE" id.subfunc = 1 id.callname = "func__printmode" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = LONGTYPE - ISPOINTER regid 'WORKING WITH COLORS clearid id.n = "_RGBA" id.subfunc = 1 id.callname = "func__rgba" id.args = 5 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,?,?,?[,?]" id.ret = ULONGTYPE - ISPOINTER regid clearid id.n = "_RGB" id.subfunc = 1 id.callname = "func__rgb" id.args = 4 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,?,?[,?]" id.ret = ULONGTYPE - ISPOINTER regid clearid id.n = "_RED" id.subfunc = 1 id.callname = "func__red" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_GREEN" id.subfunc = 1 id.callname = "func__green" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_BLUE" id.subfunc = 1 id.callname = "func__blue" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_ALPHA" id.subfunc = 1 id.callname = "func__alpha" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_RGBA32" id.subfunc = 1 id.callname = "func__rgba32" id.args = 4 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = ULONGTYPE - ISPOINTER regid clearid id.n = "_RGB32" id.subfunc = 1 id.callname = "func__rgb32" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = ULONGTYPE - ISPOINTER regid clearid id.n = "_RED32" id.subfunc = 1 id.callname = "func__red32" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_GREEN32" id.subfunc = 1 id.callname = "func__green32" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_BLUE32" id.subfunc = 1 id.callname = "func__blue32" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_ALPHA32" id.subfunc = 1 id.callname = "func__alpha32" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "DRAW" id.subfunc = 2 id.callname = "sub_draw" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) regid clearid id.n = "PLAY": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub_play" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) 'id.NoCloud = 1 regid clearid id.n = "PLAY": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func_play" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid 'QB64 MOUSE clearid id.n = "_MOUSESHOW" id.subfunc = 2 id.callname = "sub__mouseshow" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "[?]" regid clearid id.n = "_MOUSEHIDE" id.subfunc = 2 id.callname = "sub__mousehide" regid clearid id.n = "_MOUSEINPUT" id.subfunc = 1 id.callname = "func__mouseinput" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_MOUSEX" id.subfunc = 1 id.callname = "func__mousex" id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "_MOUSEY" id.subfunc = 1 id.callname = "func__mousey" id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "_MOUSEMOVEMENTX" id.subfunc = 1 id.callname = "func__mousemovementx" id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "_MOUSEMOVEMENTY" id.subfunc = 1 id.callname = "func__mousemovementy" id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "_MOUSEBUTTON" id.subfunc = 1 id.callname = "func__mousebutton" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_MOUSEWHEEL" id.subfunc = 1 id.callname = "func__mousewheel" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "FREEFILE" id.subfunc = 1 id.callname = "func_freefile" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "NAME" id.subfunc = 2 id.callname = "sub_name" id.args = 2 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "?{AS}?" regid clearid id.n = "KILL" id.subfunc = 2 id.callname = "sub_kill" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) regid clearid id.n = "CHDIR" id.subfunc = 2 id.callname = "sub_chdir" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 0 'allowed so initial subfolder can be entered regid clearid id.n = "MKDIR" id.subfunc = 2 id.callname = "sub_mkdir" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "RMDIR" id.subfunc = 2 id.callname = "sub_rmdir" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "CHAIN" id.subfunc = 2 id.callname = "sub_chain" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "SHELL" id.subfunc = 2 id.callname = "sub_shell" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "[?]" 'id.secondargcantbe = "_HIDE" id.NoCloud = 1 regid clearid id.n = "SHELL" id.subfunc = 2 id.callname = "sub_shell2" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "{_HIDE}[{_DONTWAIT}][?]" id.secondargmustbe = "_HIDE" id.NoCloud = 1 regid clearid id.n = "SHELL" id.subfunc = 2 id.callname = "sub_shell3" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "{_DONTWAIT}[{_HIDE}][?]" id.secondargmustbe = "_DONTWAIT" id.NoCloud = 1 regid clearid id.n = "SHELL" id.subfunc = 1 id.callname = "func_shell" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = INTEGER64TYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SHELLHIDE" id.subfunc = 1 id.callname = "func__shellhide" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = INTEGER64TYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "COMMAND" id.musthave = "$" id.subfunc = 1 id.callname = "func_command" id.args = 0 id.ret = STRINGTYPE - ISPOINTER id.NoCloud = 1 regid 'QB64 AUDIO clearid id.n = "_SNDRATE": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndrate" id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDRAW": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndraw" id.args = 3 id.arg = MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,[?][,?]]" id.NoCloud = 1 regid clearid id.n = "_SNDRAWDONE": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndrawdone" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.NoCloud = 1 regid clearid id.n = "_SNDOPENRAW": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndopenraw" id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDRAWLEN": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndrawlen" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" id.ret = DOUBLETYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDLEN": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndlen" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDPAUSED": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndpaused" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDPLAYFILE": id.Dependency = DEPENDENCY_AUDIO_DECODE id.subfunc = 2 id.callname = "sub__sndplayfile" id.args = 3 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) id.specialformat = "?[,[?][,?]]" id.NoCloud = 1 regid clearid id.n = "_SNDPLAYCOPY": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndplaycopy" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) id.specialformat = "?[,?]" id.NoCloud = 1 regid clearid id.n = "_SNDSTOP": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndstop" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SNDLOOP": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndloop" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SNDLIMIT": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndlimit" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SNDOPEN": id.Dependency = DEPENDENCY_AUDIO_DECODE id.subfunc = 1 id.callname = "func__sndopen" id.args = 2 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = ULONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDSETPOS": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndsetpos" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SNDGETPOS": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndgetpos" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDPLAYING": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndplaying" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDPAUSE": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndpause" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SNDBAL": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndbal" id.args = 4 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) id.specialformat = "?,[?][,[?][,[?]]]" id.NoCloud = 1 regid clearid id.n = "_SNDVOL": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndvol" id.args = 2 id.arg = MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SNDPLAY": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndplay" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "_SNDCOPY": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 1 id.callname = "func__sndcopy" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.ret = ULONGTYPE - ISPOINTER id.NoCloud = 1 regid clearid id.n = "_SNDCLOSE": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub__sndclose" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "INPUT" id.musthave = "$" id.subfunc = 1 id.callname = "func_input" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "SEEK" id.subfunc = 2 id.callname = "sub_seek" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[#]?,?" regid clearid id.n = "SEEK" id.subfunc = 1 id.callname = "func_seek" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "LOC" id.subfunc = 1 id.callname = "func_loc" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "EOF" id.subfunc = 1 id.callname = "func_eof" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "LOF" id.subfunc = 1 id.callname = "func_lof" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "SCREEN" id.subfunc = 1 id.callname = "func_screen" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,?[,?]" id.ret = ULONGTYPE - ISPOINTER regid clearid id.n = "PMAP" id.subfunc = 1 id.callname = "func_pmap" id.args = 2 id.arg = MKL$(SINGLETYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "POINT" id.subfunc = 1 id.callname = "func_point" id.args = 2 id.arg = MKL$(SINGLETYPE - ISPOINTER) + MKL$(SINGLETYPE - ISPOINTER) id.specialformat = "?[,?]" id.ret = DOUBLETYPE - ISPOINTER regid clearid id.n = "TAB" id.subfunc = 1 id.callname = "func_tab" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "SPC" id.subfunc = 1 id.callname = "func_spc" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "WAIT" id.subfunc = 2 id.callname = "sub_wait" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,?[,?]" regid clearid id.n = "INP" id.subfunc = 1 id.callname = "func_inp" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "POS" id.subfunc = 1 id.callname = "func_pos" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "SGN" id.subfunc = 1 id.callname = "func_sgn" id.args = 1 id.arg = MKL$(-1) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "LBOUND" id.subfunc = 1 id.args = 2 id.arg = MKL$(-1) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "UBOUND" id.subfunc = 1 id.args = 2 id.arg = MKL$(-1) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,[?]" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "OCT" id.musthave = "$" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "HEX" id.musthave = "$" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "SLEEP" id.subfunc = 2 id.callname = "sub_sleep" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?]" regid clearid id.n = "EXP" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = -1 regid clearid id.n = "FIX" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = -1 regid clearid id.n = "INT" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = -1 regid clearid id.n = "CDBL" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = DOUBLETYPE - ISPOINTER regid clearid id.n = "CSNG" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "_ROUND" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = INTEGER64TYPE - ISPOINTER regid clearid id.n = "CINT" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = INTEGERTYPE - ISPOINTER regid clearid id.n = "CLNG" id.subfunc = 1 id.args = 1 id.arg = MKL$(-1) id.ret = INTEGERTYPE - ISPOINTER regid clearid id.n = "TIME" id.musthave = "$" id.subfunc = 2 id.callname = "sub_time" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "=?" regid clearid id.n = "TIME" id.musthave = "$" id.subfunc = 1 id.callname = "func_time" id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "DATE" id.musthave = "$" id.subfunc = 2 id.callname = "sub_date" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "=?" regid clearid id.n = "DATE" id.musthave = "$" id.subfunc = 1 id.callname = "func_date" id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "CSRLIN" id.subfunc = 1 id.callname = "func_csrlin" id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "PAINT" id.subfunc = 2 id.callname = "sub_paint" id.args = 5 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?)[,[?][,[?][,?]]]" 'PAINT [STEP] (x!,y!)[,[paint] [,[bordercolor&] [,background$]]] regid clearid id.n = "CIRCLE" id.subfunc = 2 id.callname = "sub_circle" id.args = 7 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?),?[,[?][,[?][,[?][,?]]]]" 'CIRCLE [STEP] (x!,y!),radius![,[color&] [,[start!] [,[end!] [,aspect!]]]] regid clearid id.n = "BLOAD" id.subfunc = 2 id.callname = "sub_bload" id.args = 2 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[,?]" regid clearid id.n = "BSAVE" id.subfunc = 2 id.callname = "sub_bsave" id.args = 3 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) regid clearid id.n = "GET" id.subfunc = 2 id.callname = "sub_get" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(-4) 'id.specialformat = "[#]?,[?],?" 'non field complient definition id.specialformat = "[#]?[,[?][,?]]" 'field complient definition regid clearid id.n = "PUT" id.subfunc = 2 id.callname = "sub_put" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(-4) 'id.specialformat = "[#]?,[?],?" 'non field complient definition id.specialformat = "[#]?[,[?][,?]]" 'field complient definition regid 'double definition clearid id.n = "GET" id.subfunc = 2 id.callname = "sub_graphics_get" id.args = 6 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(-3) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?)-[{STEP}](?,?),?[,?]" id.secondargmustbe = "STEP" regid clearid id.n = "GET" id.subfunc = 2 id.callname = "sub_graphics_get" id.args = 6 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(-3) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?)-[{STEP}](?,?),?[,?]" id.secondargmustbe = "(" regid 'double definition clearid id.n = "PUT" id.subfunc = 2 id.callname = "sub_graphics_put" id.args = 5 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(-3) + MKL$(LONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?),?[,[{_CLIP}][{PSET|PRESET|AND|OR|XOR}][,?]]" 'PUT [STEP] (x!,y!),arrayname# [(indexes%)] [,actionverb] 'PUT (10, 10), myimage, _CLIP, 0 id.secondargmustbe = "STEP" regid clearid id.n = "PUT" id.subfunc = 2 id.callname = "sub_graphics_put" id.args = 5 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(-3) + MKL$(LONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?),?[,[{_CLIP}][{PSET|PRESET|AND|OR|XOR}][,?]]" 'PUT [STEP] (x!,y!),arrayname# [(indexes%)] [,actionverb] 'PUT (10, 10), myimage, _CLIP, 0 id.secondargmustbe = "(" regid clearid id.n = "OPEN" id.subfunc = 2 id.callname = "sub_open_gwbasic" id.args = 4 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?,[#]?,?[,?]" regid clearid id.n = "OPEN" id.subfunc = 2 id.callname = "sub_open" id.args = 6 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "?[{FOR RANDOM|FOR BINARY|FOR INPUT|FOR OUTPUT|FOR APPEND}][{ACCESS READ WRITE|ACCESS READ|ACCESS WRITE}][{SHARED|LOCK READ WRITE|LOCK READ|LOCK WRITE}]{AS}[#]?[{LEN =}?]" regid clearid id.n = "VAL" id.subfunc = 1 id.callname = "func_val" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER regid clearid id.n = "MKSMBF" id.musthave = "$" id.subfunc = 1 id.callname = "func_mksmbf" id.args = 1 id.arg = MKL$(SINGLETYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "MKDMBF" id.musthave = "$" id.subfunc = 1 id.callname = "func_mkdmbf" id.args = 1 id.arg = MKL$(DOUBLETYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "MKI" id.musthave = "$" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(INTEGERTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "MKL" id.musthave = "$" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "MKS" id.musthave = "$" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(SINGLETYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "MKD" id.musthave = "$" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(DOUBLETYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "_MK" id.musthave = "$" id.subfunc = 1 id.callname = "" id.args = 2 id.arg = MKL$(-1) + MKL$(-1) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "CVSMBF" id.subfunc = 1 id.callname = "func_cvsmbf" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "CVDMBF" id.subfunc = 1 id.callname = "func_cvdmbf" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = DOUBLETYPE - ISPOINTER regid clearid id.n = "CVI" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = INTEGERTYPE - ISPOINTER regid clearid id.n = "CVL" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "CVS" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER regid clearid id.n = "CVD" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = DOUBLETYPE - ISPOINTER regid clearid id.n = "_CV" id.subfunc = 1 id.callname = "" id.args = 2 id.arg = MKL$(-1) + MKL$(STRINGTYPE - ISPOINTER) id.ret = -1 regid clearid id.n = "STRING" id.musthave = "$" id.subfunc = 1 id.callname = "func_string" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "SPACE" id.musthave = "$" id.subfunc = 1 id.callname = "func_space" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "INSTR" id.subfunc = 1 id.callname = "func_instr" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) + MKL$(STRINGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.specialformat = "[?],?,?" 'checked! regid clearid id.n = "MID" id.musthave = "$" id.subfunc = 1 id.callname = "func_mid" id.args = 3 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER id.specialformat = "?,?,[?]" 'checked! regid clearid id.n = "SADD" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(-1) '!this value is ignored, the qb64 compiler handles this function id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "CLS" id.subfunc = 2 id.callname = "sub_cls" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(ULONGTYPE - ISPOINTER) id.specialformat = "[?][,?]" regid clearid id.n = "SQR" id.subfunc = 1 id.callname = "func_sqr" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER regid clearid id.n = "CHR" id.musthave = "$" id.subfunc = 1 id.callname = "func_chr" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "VARPTR" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(-1) '!this value is ignored, the qb64 compiler handles this function id.ret = STRINGTYPE - ISPOINTER id.musthave = "$" regid clearid id.n = "VARPTR" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(-1) '!this value is ignored, the qb64 compiler handles this function id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "_OFFSET" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(-1) '!this value is ignored, the qb64 compiler handles this function id.ret = UOFFSETTYPE - ISPOINTER regid clearid id.n = "VARSEG" id.subfunc = 1 id.callname = "" id.args = 1 id.arg = MKL$(-1) '!this value is ignored, the qb64 compiler handles this function id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "POKE" id.subfunc = 2 id.callname = "sub_poke" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) regid clearid id.n = "PEEK" id.subfunc = 1 id.callname = "func_peek" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "DEF" id.subfunc = 2 id.callname = "sub_defseg" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.specialformat = "{SEG}[=?]" 'checked! id.secondargmustbe = "SEG" regid clearid id.n = "SIN" id.subfunc = 1 id.callname = "sin" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER regid clearid id.n = "COS" id.subfunc = 1 id.callname = "cos" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER regid clearid id.n = "TAN" id.subfunc = 1 id.callname = "tan" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER regid clearid id.n = "ATN" id.subfunc = 1 id.callname = "atan" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER regid clearid id.n = "LOG" id.subfunc = 1 id.callname = "func_log" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = FLOATTYPE - ISPOINTER regid clearid id.n = "ABS" id.subfunc = 1 id.callname = "func_abs" id.args = 1 id.arg = MKL$(-1) 'takes anything numerical id.ret = FLOATTYPE - ISPOINTER '***overridden by function evaluatefunc*** regid clearid id.n = "ERL" id.subfunc = 1 id.callname = "get_error_erl" id.args = 0 id.ret = DOUBLETYPE - ISPOINTER regid clearid id.n = "ERR" id.subfunc = 1 id.callname = "get_error_err" id.args = 0 id.ret = ULONGTYPE - ISPOINTER regid clearid id.n = "ERROR" id.subfunc = 2 id.callname = "error" id.args = 1 id.arg = MKL$(ULONGTYPE - ISPOINTER) regid clearid id.n = "LINE" id.subfunc = 2 id.callname = "sub_line" id.args = 7 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$ _ (LONGTYPE - ISPOINTER) id.specialformat = "[[{STEP}](?,?)]-[{STEP}](?,?)[,[?][,[{B|BF}][,?]]]" regid clearid id.n = "SOUND": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub_sound" id.args = 2 id.arg = MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) 'id.NoCloud = 1 regid clearid id.n = "BEEP": id.Dependency = DEPENDENCY_AUDIO_OUT id.subfunc = 2 id.callname = "sub_beep" id.args = 0 'id.NoCloud = 1 regid clearid id.n = "TIMER" id.subfunc = 1 id.callname = "func_timer" id.args = 1 id.arg = MKL$(DOUBLETYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER id.specialformat = "[?]" regid clearid id.n = "RND" id.subfunc = 1 id.callname = "func_rnd" id.args = 1 id.arg = MKL$(FLOATTYPE - ISPOINTER) id.ret = SINGLETYPE - ISPOINTER id.specialformat = "[?]" 'checked! regid clearid id.n = "RANDOMIZE" id.subfunc = 2 id.callname = "sub_randomize" id.args = 1 id.arg = MKL$(DOUBLETYPE - ISPOINTER) id.specialformat = "[[{USING}]?]" 'checked! regid clearid id.n = "OUT" id.subfunc = 2 id.callname = "sub_out" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) regid clearid id.n = "PCOPY" id.subfunc = 2 id.callname = "sub_pcopy" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) regid clearid id.n = "VIEW" id.subfunc = 2 id.callname = "qbg_sub_view" id.args = 6 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[[{SCREEN}](?,?)-(?,?)[,[?][,?]]]" id.secondargcantbe = "PRINT" regid clearid id.n = "VIEW" id.subfunc = 2 id.callname = "qbg_sub_view_print" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "{PRINT}[?{TO}?]" 'new! id.secondargmustbe = "PRINT" regid clearid id.n = "WINDOW" id.subfunc = 2 id.callname = "qbg_sub_window" id.args = 4 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) id.specialformat = "[[{SCREEN}](?,?)-(?,?)]" regid clearid id.n = "LOCATE" id.subfunc = 2 id.callname = "qbg_sub_locate" id.args = 5 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?][,[?][,[?][,[?][,?]]]]" regid clearid id.n = "COLOR" id.subfunc = 2 id.callname = "qbg_sub_color" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?][,[?][,?]]" regid clearid id.n = "PALETTE" id.subfunc = 2 id.callname = "qbg_palette" id.args = 2 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[?,?]" regid clearid id.n = "WIDTH" id.subfunc = 2 id.callname = "qbsub_width" id.args = 3 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{#|LPRINT}][?][,?]" 'new! regid clearid id.n = "SCREEN" id.subfunc = 2 id.callname = "qbg_screen" id.args = 5 id.arg = MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) 'id.specialformat = "[?][,[?][,[?][,?]]]" 'new! 'id.specialformat = "[?][,[?][,[?][,[?][,{_MANUALDISPLAY}]]]]" 'breaks compilation! 'id.specialformat = "[?][,[?][,[?][,[?][,[{_MANUALDISPLAY}]]]]]" <-pre-bulletproofing id.specialformat = "[?][,[?][,[?][,[?][,[{_MANUALDISPLAY}?]]]]]" 'a temp format for transition reasons" regid clearid id.n = "PSET" id.subfunc = 2 id.callname = "sub_pset" id.args = 3 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?)[,?]" regid clearid id.n = "PRESET" id.subfunc = 2 id.callname = "sub_preset" id.args = 3 id.arg = MKL$(FLOATTYPE - ISPOINTER) + MKL$(FLOATTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.specialformat = "[{STEP}](?,?)[,?]" regid clearid id.n = "ASC" id.subfunc = 1 id.callname = "qbs_asc" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "LEN" id.subfunc = 1 id.callname = "" 'callname is not used id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) 'note: LEN is a special case, any input is actually accepted id.ret = LONGTYPE - ISPOINTER regid clearid id.n = "INKEY" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_inkey" id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "STR" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_str" id.args = 1 id.arg = MKL$(-1) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "UCASE" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_ucase" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "LCASE" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_lcase" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "LEFT" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_left" id.args = 2 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "RIGHT" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_right" id.args = 2 id.arg = MKL$(STRINGTYPE - ISPOINTER) + MKL$(LONGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "LTRIM" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_ltrim" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "RTRIM" id.musthave = "$" id.subfunc = 1 id.callname = "qbs_rtrim" id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.ret = STRINGTYPE - ISPOINTER regid clearid id.n = "PRINT" id.subfunc = 2 id.callname = "qbs_print" 'not called directly id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) regid clearid id.n = "LPRINT" id.subfunc = 2 id.callname = "qbs_lprint" 'not called directly id.args = 1 id.arg = MKL$(STRINGTYPE - ISPOINTER) id.NoCloud = 1 regid clearid id.n = "LPOS" id.subfunc = 1 id.callname = "func_lpos" id.args = 1 id.arg = MKL$(LONGTYPE - ISPOINTER) id.ret = LONGTYPE - ISPOINTER id.NoCloud = 1 regid reginternalsubfunc = 0 END SUB 'this sub is faulty atm! 'sub replacelement (a$, i, newe$) ''note: performs no action for out of range values of i 'e=1 's=1 'do 'x=instr(s,a$,sp) 'if x then 'if e=i then 'a1$=left$(a$,s-1): a2$=right$(a$,len(a$)-x+1) 'a$=a1$+sp+newe$+a2$ 'note: a2 includes spacer 'exit sub 'end if 's=x+1 'e=e+1 'end if 'loop until x=0 'if e=i then 'a$=left$(a$,s-1)+sp+newe$ 'end if 'end sub SUB removeelements (a$, first, last, keepindexing) a2$ = "" 'note: first and last MUST be valid ' keepindexing means the number of elements will stay the same ' but some elements will be equal to "" n = numelements(a$) FOR i = 1 TO n IF i < first OR i > last THEN a2$ = a2$ + sp + getelement(a$, i) ELSE IF keepindexing THEN a2$ = a2$ + sp END IF NEXT IF LEFT$(a2$, 1) = sp THEN a2$ = RIGHT$(a2$, LEN(a2$) - 1) a$ = a2$ END SUB FUNCTION symboltype (s$) 'returns type or 0(not a valid symbol) 'note: sets symboltype_size for fixed length strings 'created: 2011 (fast & comprehensive) IF LEN(s$) = 0 THEN EXIT FUNCTION 'treat common cases first a = ASC(s$) l = LEN(s$) IF a = 37 THEN '% IF l = 1 THEN symboltype = 16: EXIT FUNCTION IF l > 2 THEN EXIT FUNCTION IF ASC(s$, 2) = 37 THEN symboltype = 8: EXIT FUNCTION IF ASC(s$, 2) = 38 THEN symboltype = OFFSETTYPE - ISPOINTER: EXIT FUNCTION '%& EXIT FUNCTION END IF IF a = 38 THEN '& IF l = 1 THEN symboltype = 32: EXIT FUNCTION IF l > 2 THEN EXIT FUNCTION IF ASC(s$, 2) = 38 THEN symboltype = 64: EXIT FUNCTION EXIT FUNCTION END IF IF a = 33 THEN '! IF l = 1 THEN symboltype = 32 + ISFLOAT: EXIT FUNCTION EXIT FUNCTION END IF IF a = 35 THEN '# IF l = 1 THEN symboltype = 64 + ISFLOAT: EXIT FUNCTION IF l > 2 THEN EXIT FUNCTION IF ASC(s$, 2) = 35 THEN symboltype = 64 + ISFLOAT: EXIT FUNCTION EXIT FUNCTION END IF IF a = 36 THEN '$ IF l = 1 THEN symboltype = ISSTRING: EXIT FUNCTION IF isuinteger(RIGHT$(s$, l - 1)) THEN IF l >= (1 + 10) THEN IF l > (1 + 10) THEN EXIT FUNCTION IF s$ > "$2147483647" THEN EXIT FUNCTION END IF symboltype_size = VAL(RIGHT$(s$, l - 1)) symboltype = ISSTRING + ISFIXEDLENGTH EXIT FUNCTION END IF EXIT FUNCTION END IF IF a = 96 THEN '` IF l = 1 THEN symboltype = 1 + ISOFFSETINBITS: EXIT FUNCTION IF isuinteger(RIGHT$(s$, l - 1)) THEN IF l > 3 THEN EXIT FUNCTION n = VAL(RIGHT$(s$, l - 1)) IF n > 56 THEN EXIT FUNCTION symboltype = n + ISOFFSETINBITS: EXIT FUNCTION END IF EXIT FUNCTION END IF IF a = 126 THEN '~ IF l = 1 THEN EXIT FUNCTION a = ASC(s$, 2) IF a = 37 THEN '% IF l = 2 THEN symboltype = 16 + ISUNSIGNED: EXIT FUNCTION IF l > 3 THEN EXIT FUNCTION IF ASC(s$, 3) = 37 THEN symboltype = 8 + ISUNSIGNED: EXIT FUNCTION IF ASC(s$, 3) = 38 THEN symboltype = UOFFSETTYPE - ISPOINTER: EXIT FUNCTION '~%& EXIT FUNCTION END IF IF a = 38 THEN '& IF l = 2 THEN symboltype = 32 + ISUNSIGNED: EXIT FUNCTION IF l > 3 THEN EXIT FUNCTION IF ASC(s$, 3) = 38 THEN symboltype = 64 + ISUNSIGNED: EXIT FUNCTION EXIT FUNCTION END IF IF a = 96 THEN '` IF l = 2 THEN symboltype = 1 + ISOFFSETINBITS + ISUNSIGNED: EXIT FUNCTION IF isuinteger(RIGHT$(s$, l - 2)) THEN IF l > 4 THEN EXIT FUNCTION n = VAL(RIGHT$(s$, l - 2)) IF n > 56 THEN EXIT FUNCTION symboltype = n + ISOFFSETINBITS + ISUNSIGNED: EXIT FUNCTION END IF EXIT FUNCTION END IF END IF '~ END FUNCTION FUNCTION removesymbol$ (varname$) i = INSTR(varname$, "~"): IF i THEN GOTO foundsymbol i = INSTR(varname$, "`"): IF i THEN GOTO foundsymbol i = INSTR(varname$, "%"): IF i THEN GOTO foundsymbol i = INSTR(varname$, "&"): IF i THEN GOTO foundsymbol i = INSTR(varname$, "!"): IF i THEN GOTO foundsymbol i = INSTR(varname$, "#"): IF i THEN GOTO foundsymbol i = INSTR(varname$, "$"): IF i THEN GOTO foundsymbol EXIT FUNCTION foundsymbol: IF i = 1 THEN Give_Error "Expected variable name before symbol": EXIT FUNCTION symbol$ = RIGHT$(varname$, LEN(varname$) - i + 1) IF symboltype(symbol$) = 0 THEN Give_Error "Invalid symbol": EXIT FUNCTION removesymbol$ = symbol$ varname$ = LEFT$(varname$, i - 1) END FUNCTION FUNCTION scope$ IF id.share THEN scope$ = module$ + "__": EXIT FUNCTION scope$ = module$ + "_" + subfunc$ + "_" END FUNCTION FUNCTION seperateargs (a$, ca$, pass&) pass& = 0 FOR i = 1 TO OptMax: separgs(i) = "": NEXT FOR i = 1 TO OptMax + 1: separgslayout(i) = "": NEXT FOR i = 1 TO OptMax Lev(i) = 0 EntryLev(i) = 0 DitchLev(i) = 0 DontPass(i) = 0 TempList(i) = 0 PassRule(i) = 0 LevelEntered(i) = 0 NEXT DIM id2 AS idstruct id2 = id IF id2.args = 0 THEN EXIT FUNCTION 'no arguments! s$ = id2.specialformat s$ = RTRIM$(s$) 'build a special format if none exists IF s$ = "" THEN FOR i = 1 TO id2.args IF i <> 1 THEN s$ = s$ + ",?" ELSE s$ = "?" NEXT END IF 'note: dim'd arrays moved to global to prevent high recreation cost PassFlag = 1 nextentrylevel = 0 nextentrylevelset = 1 level = 0 lastt = 0 ditchlevel = 0 FOR i = 1 TO LEN(s$) s2$ = MID$(s$, i, 1) IF s2$ = "[" THEN level = level + 1 LevelEntered(level) = 0 GOTO nextsymbol END IF IF s2$ = "]" THEN level = level - 1 IF level < ditchlevel THEN ditchlevel = level GOTO nextsymbol END IF IF s2$ = "{" THEN lastt = lastt + 1: Lev(lastt) = level: PassRule(lastt) = 0 DitchLev(lastt) = ditchlevel: ditchlevel = level 'store & reset ditch level i = i + 1 i2 = INSTR(i, s$, "}") numopts = 0 nextopt: numopts = numopts + 1 i3 = INSTR(i + 1, s$, "|") IF i3 <> 0 AND i3 < i2 THEN Opt(lastt, numopts) = MID$(s$, i, i3 - i) i = i3 + 1: GOTO nextopt END IF Opt(lastt, numopts) = MID$(s$, i, i2 - i) T(lastt) = numopts 'calculate words in each option FOR x = 1 TO T(lastt) w = 1 x2 = 1 newword: IF INSTR(x2, RTRIM$(Opt(lastt, x)), " ") THEN w = w + 1: x2 = INSTR(x2, RTRIM$(Opt(lastt, x)), " ") + 1: GOTO newword OptWords(lastt, x) = w NEXT i = i2 'set entry level routine EntryLev(lastt) = level 'default level when continuing a previously entered level IF LevelEntered(level) = 0 THEN EntryLev(lastt) = 0 FOR i2 = 1 TO level - 1 IF LevelEntered(i2) = 1 THEN EntryLev(lastt) = i2 NEXT END IF LevelEntered(level) = 1 GOTO nextsymbol END IF IF s2$ = "?" THEN lastt = lastt + 1: Lev(lastt) = level: PassRule(lastt) = 0 DitchLev(lastt) = ditchlevel: ditchlevel = level 'store & reset ditch level T(lastt) = 0 'set entry level routine EntryLev(lastt) = level 'default level when continuing a previously entered level IF LevelEntered(level) = 0 THEN EntryLev(lastt) = 0 FOR i2 = 1 TO level - 1 IF LevelEntered(i2) = 1 THEN EntryLev(lastt) = i2 NEXT END IF LevelEntered(level) = 1 GOTO nextsymbol END IF 'assume "special" character (like ( ) , . - etc.) lastt = lastt + 1: Lev(lastt) = level: PassRule(lastt) = 0 DitchLev(lastt) = ditchlevel: ditchlevel = level 'store & reset ditch level T(lastt) = 1: Opt(lastt, 1) = s2$: OptWords(lastt, 1) = 1: DontPass(lastt) = 1 'set entry level routine EntryLev(lastt) = level 'default level when continuing a previously entered level IF LevelEntered(level) = 0 THEN EntryLev(lastt) = 0 FOR i2 = 1 TO level - 1 IF LevelEntered(i2) = 1 THEN EntryLev(lastt) = i2 NEXT END IF LevelEntered(level) = 1 GOTO nextsymbol nextsymbol: NEXT IF Debug THEN PRINT #9, "--------SEPERATE ARGUMENTS REPORT #1:1--------" FOR i = 1 TO lastt PRINT #9, i, "OPT=" + CHR$(34) + RTRIM$(Opt(i, 1)) + CHR$(34) PRINT #9, i, "OPTWORDS="; OptWords(i, 1) PRINT #9, i, "T="; T(i) PRINT #9, i, "DONTPASS="; DontPass(i) PRINT #9, i, "PASSRULE="; PassRule(i) PRINT #9, i, "LEV="; Lev(i) PRINT #9, i, "ENTRYLEV="; EntryLev(i) NEXT END IF 'Any symbols already have dontpass() set to 1 'This sets any {}blocks with only one option/word (eg. {PRINT}) at the lowest level to dontpass()=1 'because their content is manadatory and there is no choice as to which word to use FOR x = 1 TO lastt IF Lev(x) = 0 THEN IF T(x) = 1 THEN DontPass(x) = 1 END IF NEXT IF Debug THEN PRINT #9, "--------SEPERATE ARGUMENTS REPORT #1:2--------" FOR i = 1 TO lastt PRINT #9, i, "OPT=" + CHR$(34) + RTRIM$(Opt(i, 1)) + CHR$(34) PRINT #9, i, "OPTWORDS="; OptWords(i, 1) PRINT #9, i, "T="; T(i) PRINT #9, i, "DONTPASS="; DontPass(i) PRINT #9, i, "PASSRULE="; PassRule(i) PRINT #9, i, "LEV="; Lev(i) PRINT #9, i, "ENTRYLEV="; EntryLev(i) NEXT END IF x1 = 0 'the 'x' position of the beginning element of the current levelled block MustPassOpt = 0 'the 'x' position of the FIRST opt () in the block which must be passed MustPassOptNeedsFlag = 0 '{}blocks don't need a flag, ? blocks do 'Note: For something like [{HELLO}x] a choice between passing 'hello' or passing a flag to signify x was specified ' has to be made, in such cases, a flag is preferable to wasting a full new int32 on 'hello' templistn = 0 FOR l = 1 TO 32767 scannextlevel = 0 FOR x = 1 TO lastt IF Lev(x) > l THEN scannextlevel = 1 IF x1 THEN IF EntryLev(x) < l THEN 'end of block reached IF MustPassOpt THEN 'If there's an opt () which must be passed that will be identified, 'all the 1 option {}blocks can be assumed... IF MustPassOptNeedsFlag THEN 'The MustPassOpt requires a flag, so use the same flag for everything FOR x2 = 1 TO templistn PassRule(TempList(x2)) = PassFlag NEXT PassFlag = PassFlag * 2 ELSE 'The MustPassOpt is a {}block which doesn't need a flag, so everything else needs to 'reference it FOR x2 = 1 TO templistn IF TempList(x2) <> MustPassOpt THEN PassRule(TempList(x2)) = -MustPassOpt NEXT END IF ELSE 'if not, use a unique flag for everything in this block FOR x2 = 1 TO templistn: PassRule(TempList(x2)) = PassFlag: NEXT IF templistn <> 0 THEN PassFlag = PassFlag * 2 END IF x1 = 0 END IF END IF IF Lev(x) = l THEN 'on same level IF EntryLev(x) < l THEN 'just (re)entered this level (not continuing along it) x1 = x 'set x1 to the starting element of this level MustPassOpt = 0 templistn = 0 END IF END IF IF x1 THEN IF Lev(x) = l THEN 'same level IF T(x) <> 1 THEN 'It isn't a symbol or a {}block with only one option therefore this opt () must be passed IF MustPassOpt = 0 THEN MustPassOpt = x 'Only record the first instance (it MAY require a flag) IF T(x) = 0 THEN MustPassOptNeedsFlag = 1 ELSE MustPassOptNeedsFlag = 0 ELSE 'Update current MustPassOpt to non-flag-based {}block if possible (to save flag usage) '(Consider [{A|B}?], where a flag is not required) IF MustPassOptNeedsFlag = 1 THEN IF T(x) > 1 THEN MustPassOpt = x: MustPassOptNeedsFlag = 0 END IF END IF END IF 'add to list templistn = templistn + 1: TempList(templistn) = x END IF IF T(x) = 1 THEN 'It is a symbol or a {}block with only one option 'a {}block with only one option MAY not need to be passed 'depending on if anything else is in this block could make the existance of this opt () assumed 'Note: Symbols which are not encapsulated inside a {}block never need to be passed ' Symbols already have dontpass() set to 1 IF DontPass(x) = 0 THEN templistn = templistn + 1: TempList(templistn) = x: DontPass(x) = 1 END IF END IF END IF NEXT 'scan last run (mostly just a copy of code from above) IF x1 THEN IF MustPassOpt THEN 'If there's an opt () which must be passed that will be identified, 'all the 1 option {}blocks can be assumed... IF MustPassOptNeedsFlag THEN 'The MustPassOpt requires a flag, so use the same flag for everything FOR x2 = 1 TO templistn PassRule(TempList(x2)) = PassFlag NEXT PassFlag = PassFlag * 2 ELSE 'The MustPassOpt is a {}block which doesn't need a flag, so everything else needs to 'reference it FOR x2 = 1 TO templistn IF TempList(x2) <> MustPassOpt THEN PassRule(TempList(x2)) = -MustPassOpt NEXT END IF ELSE 'if not, use a unique flag for everything in this block FOR x2 = 1 TO templistn: PassRule(TempList(x2)) = PassFlag: NEXT IF templistn <> 0 THEN PassFlag = PassFlag * 2 END IF x1 = 0 END IF IF scannextlevel = 0 THEN EXIT FOR NEXT IF Debug THEN PRINT #9, "--------SEPERATE ARGUMENTS REPORT #1:3--------" FOR i = 1 TO lastt PRINT #9, i, "OPT=" + CHR$(34) + RTRIM$(Opt(i, 1)) + CHR$(34) PRINT #9, i, "OPTWORDS="; OptWords(i, 1) PRINT #9, i, "T="; T(i) PRINT #9, i, "DONTPASS="; DontPass(i) PRINT #9, i, "PASSRULE="; PassRule(i) PRINT #9, i, "LEV="; Lev(i) PRINT #9, i, "ENTRYLEV="; EntryLev(i) NEXT END IF FOR i = 1 TO lastt: separgs(i) = "null": NEXT 'Consider: "?,[?]" 'Notes: The comma is mandatory but the second ? is entirely optional 'Consider: "[?[{B}?]{A}]?" 'Notes: As unlikely as the above is, it is still valid, but pivots on the outcome of {A} being present 'Consider: "[?]{A}" 'Consider: "[?{A}][?{B}][?{C}]?" 'Notes: The trick here is to realize {A} has greater priority than {B}, so all lines of enquiry must ' be exhausted before considering {B} 'Use inquiry approach to solve format 'Each line of inquiry must be exhausted 'An expression ("?") simply means a branch where you can scan ahead Branches = 0 DIM BranchFormatPos(1 TO 100) AS LONG DIM BranchTaken(1 TO 100) AS LONG '1=taken (this usually involves moving up a level) '0=not taken DIM BranchInputPos(1 TO 100) AS LONG DIM BranchWithExpression(1 TO 100) AS LONG 'non-zero=expression expected before next item for format item value represents '0=no expression allowed before next item DIM BranchLevel(1 TO 100) AS LONG 'Level before this branch was/wasn't taken n = numelements(ca$) i = 1 'Position within ca$ level = 0 Expression = 0 FOR x = 1 TO lastt ContinueScan: IF DitchLev(x) < level THEN 'dropping down to a lower level 'we can only go as low as the 'ditch' will allow us, which will limit our options level = DitchLev(x) END IF IF EntryLev(x) <= level THEN 'possible to enter level 'But was this optional or were we forced to be on this level? IF EntryLev(x) < Lev(x) THEN optional = 1 IF level > EntryLev(x) THEN optional = 0 ELSE 'entrylev=lev optional = 0 END IF t = T(x) IF t = 0 THEN 'A "?" expression IF Expression THEN '*********backtrack************ 'We are tracking an expression which we assumed would be present but was not GOTO Backtrack '****************************** END IF IF optional THEN Branches = Branches + 1 BranchFormatPos(Branches) = x BranchTaken(Branches) = 1 BranchInputPos(Branches) = i BranchWithExpression(Branches) = 0 BranchLevel(Branches) = level level = Lev(x) END IF Expression = x END IF 'A "?" expression IF t THEN currentlev = level 'Add new branch if new level will be entered IF optional THEN Branches = Branches + 1 BranchFormatPos(Branches) = x BranchTaken(Branches) = 1 BranchInputPos(Branches) = i BranchWithExpression(Branches) = Expression BranchLevel(Branches) = level END IF 'Scan for Opt () options i1 = i: i2 = i IF Expression THEN i2 = n 'Scan a$ for opt () x 'Note: Finding the closest opt option is necessary 'Note: This needs to be bracket sensitive OutOfRange = 2147483647 position = OutOfRange which = 0 IF i <= n THEN 'Past end of contect check FOR o = 1 TO t words = OptWords(x, o) b = 0 FOR i3 = i1 TO i2 IF i3 + words - 1 <= n THEN 'enough elements exist c$ = getelement$(a$, i3) IF b = 0 THEN 'Build comparison string (spacing elements) FOR w = 2 TO words c$ = c$ + " " + getelement$(a$, i3 + w - 1) NEXT w 'Compare IF c$ = RTRIM$(Opt(x, o)) THEN 'Record Match IF i3 < position THEN position = i3 which = o bvalue = b EXIT FOR 'Exit the i3 loop END IF 'position check END IF 'match END IF IF ASC(c$) = 44 AND b = 0 THEN EXIT FOR 'Expressions cannot contain a "," in their base level 'Because this wasn't interceppted by the above code it isn't the Opt either END IF IF ASC(c$) = 40 THEN b = b + 1 END IF IF ASC(c$) = 41 THEN b = b - 1 IF b = -1 THEN EXIT FOR 'Exited current bracketting level, making any following match invalid END IF END IF 'enough elements exist NEXT i3 NEXT o END IF 'Past end of contect check IF position <> OutOfRange THEN 'Found? 'Found... level = Lev(x) 'Adjust level IF Expression THEN 'Found...Expression... 'Has an expression been provided? IF position > i AND bvalue = 0 THEN 'Found...Expression...Provided... separgs(Expression) = getelements$(ca$, i, position - 1) Expression = 0 i = position ELSE 'Found...Expression...Omitted... '*********backtrack************ GOTO OptCheckBacktrack '****************************** END IF END IF 'Expression i = i + OptWords(x, which) separgslayout(x) = CHR$(LEN(RTRIM$(Opt(x, which)))) + RTRIM$(Opt(x, which)) separgs(x) = CHR$(0) + str2(which) ELSE 'Not Found... '*********backtrack************ OptCheckBacktrack: 'Was this optional? IF Lev(x) > EntryLev(x) THEN 'Optional Opt ()? 'Not Found...Optional... 'Simply don't enter the optional higher level and continue as normal BranchTaken(Branches) = 0 level = currentlev 'We aren't entering the level after all, so our level should remain at the opt's entrylevel ELSE Backtrack: 'Not Found...Mandatory... '1)Erase previous branches where both options have been tried FOR branch = Branches TO 1 STEP -1 'Remove branches until last taken branch is found IF BranchTaken(branch) THEN EXIT FOR Branches = Branches - 1 'Remove branch (it has already been tried with both possible combinations) NEXT IF Branches = 0 THEN 'All options have been exhausted seperateargs_error = 1 seperateargs_error_message = "Syntax error" EXIT FUNCTION END IF '2)Toggle taken branch to untaken and revert BranchTaken(Branches) = 0 'toggle branch to untaken Expression = BranchWithExpression(Branches) i = BranchInputPos(Branches) x = BranchFormatPos(Branches) level = BranchLevel(Branches) '3)Erase any content created after revert position IF Expression THEN separgs(Expression) = "null" FOR x2 = x TO lastt separgs(x2) = "null" separgslayout(x2) = "" NEXT END IF 'Optional Opt ()? '****************************** END IF 'Found? END IF 't END IF 'possible to enter level NEXT x 'Final expression? IF Expression THEN IF i <= n THEN separgs(Expression) = getelements$(ca$, i, n) 'can this be an expression? 'check it passes bracketting and comma rules b = 0 FOR i2 = i TO n c$ = getelement$(a$, i2) IF ASC(c$) = 44 AND b = 0 THEN GOTO Backtrack END IF IF ASC(c$) = 40 THEN b = b + 1 END IF IF ASC(c$) = 41 THEN b = b - 1 IF b = -1 THEN GOTO Backtrack END IF NEXT IF b <> 0 THEN GOTO Backtrack i = n + 1 'So it passes the test below ELSE GOTO Backtrack END IF END IF 'Expression IF i <> n + 1 THEN GOTO Backtrack 'Trailing content? IF Debug THEN PRINT #9, "--------SEPERATE ARGUMENTS REPORT #2--------" FOR i = 1 TO lastt PRINT #9, i, separgs(i) NEXT END IF ' DIM PassRule(1 TO 100) AS LONG ' '0 means no pass rule ' 'negative values refer to an opt () element ' 'positive values refer to a flag value ' PassFlag = 1 IF PassFlag <> 1 THEN seperateargs = 1 'Return whether a 'passed' flags variable is required pass& = 0 'The 'passed' value (shared by argument reference) 'Note: The separgs() elements will be compacted to the C++ function arguments x = 1 'The new index to move compacted content to within separgs() FOR i = 1 TO lastt IF DontPass(i) = 0 THEN IF PassRule(i) > 0 THEN IF separgs(i) <> "null" THEN pass& = pass& OR PassRule(i) 'build 'passed' flags END IF separgs(x) = separgs(i) separgslayout(x) = separgslayout(i) IF LEN(separgs(x)) THEN IF ASC(separgs(x)) = 0 THEN 'switch omit layout tag from item to layout info separgs(x) = RIGHT$(separgs(x), LEN(separgs(x)) - 1) separgslayout(x) = separgslayout(x) + CHR$(0) END IF END IF IF separgs(x) = "null" THEN separgs(x) = "NULL" x = x + 1 ELSE 'its gonna be skipped! 'add layout to the next one to be safe 'for syntax such as [{HELLO}] which uses a flag instead of being passed IF PassRule(i) > 0 THEN IF separgs(i) <> "null" THEN pass& = pass& OR PassRule(i) 'build 'passed' flags END IF separgslayout(i + 1) = separgslayout(i) + separgslayout(i + 1) END IF NEXT separgslayout(x) = separgslayout(i) 'set final layout 'x = x - 1 'PRINT "total arguments:"; x 'PRINT "pass omit (0/1):"; omit 'PRINT "pass&="; pass& END FUNCTION SUB setrefer (a2$, typ2 AS LONG, e2$, method AS LONG) a$ = a2$: typ = typ2: e$ = e2$ IF method <> 1 THEN e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB tl$ = tlayout$ 'method: 0 evaulatetotyp e$ ' 1 skip evaluation of e$ and use as is '*due to the complexity of setting a reference with a value/string ' this function handles the problem 'retrieve ID i = INSTR(a$, sp3) IF i THEN idnumber = VAL(LEFT$(a$, i - 1)): a$ = RIGHT$(a$, LEN(a$) - i) ELSE idnumber = VAL(a$) END IF getid idnumber IF Error_Happened THEN EXIT SUB 'UDT? IF typ AND ISUDT THEN 'print "setrefer-ing a UDT!" u = VAL(a$) i = INSTR(a$, sp3): a$ = RIGHT$(a$, LEN(a$) - i): E = VAL(a$) i = INSTR(a$, sp3): o$ = RIGHT$(a$, LEN(a$) - i) n$ = "UDT_" + RTRIM$(id.n): IF id.t = 0 THEN n$ = "ARRAY_" + n$ + "[0]" IF Cloud = 0 THEN IF E <> 0 AND u = 1 THEN 'Setting _MEM type elements is not allowed! Give_Error "Cannot set read-only element of _MEM TYPE": EXIT SUB END IF END IF IF E = 0 THEN 'use u and u's size IF method <> 0 THEN Give_Error "Unexpected internal code reference to UDT": EXIT SUB lhsscope$ = scope$ e$ = evaluate(e$, t2) IF Error_Happened THEN EXIT SUB IF (t2 AND ISUDT) = 0 THEN Give_Error "Expected = similar user defined type": EXIT SUB IF (t2 AND ISREFERENCE) = 0 THEN IF t2 AND ISPOINTER THEN src$ = "((char*)" + e$ + ")" e2 = 0: u2 = t2 AND 511 ELSE src$ = "((char*)&" + e$ + ")" e2 = 0: u2 = t2 AND 511 END IF GOTO directudt END IF '****problem**** idnumber2 = VAL(e$) getid idnumber2 IF Error_Happened THEN EXIT SUB n2$ = "UDT_" + RTRIM$(id.n): IF id.t = 0 THEN n2$ = "ARRAY_" + n2$ + "[0]" i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i): u2 = VAL(e$) i = INSTR(e$, sp3): e$ = RIGHT$(e$, LEN(e$) - i): e2 = VAL(e$) i = INSTR(e$, sp3): o2$ = RIGHT$(e$, LEN(e$) - i) 'WARNING: u2 may need minor modifications based on e to see if they are the same 'we have now established we have 2 pointers to similar data types! 'ASSUME BYTE TYPE!!! src$ = "(((char*)" + scope$ + n2$ + ")+(" + o2$ + "))" directudt: IF u <> u2 OR e2 <> 0 THEN Give_Error "Expected = similar user defined type": EXIT SUB dst$ = "(((char*)" + lhsscope$ + n$ + ")+(" + o$ + "))" siz$ = str2$(udtxsize(u) \ 8) PRINT #12, "memcpy(" + dst$ + "," + src$ + "," + siz$ + ");" 'print "setFULLUDTrefer!" tlayout$ = tl$ EXIT SUB END IF 'e=0 IF typ AND ISOFFSETINBITS THEN Give_Error "Cannot resolve bit-length variables inside user defined types yet": EXIT SUB IF typ AND ISSTRING THEN o2$ = "(((uint8*)" + scope$ + n$ + ")+(" + o$ + "))" r$ = "qbs_new_fixed(" + o2$ + "," + str2(udtetypesize(E)) + ",1)" IF method = 0 THEN e$ = evaluatetotyp(e$, STRINGTYPE - ISPOINTER) IF Error_Happened THEN EXIT SUB PRINT #12, "qbs_set(" + r$ + "," + e$ + ");" ELSE typ = typ - ISUDT - ISREFERENCE - ISPOINTER IF typ AND ISARRAY THEN typ = typ - ISARRAY t$ = typ2ctyp$(typ, "") IF Error_Happened THEN EXIT SUB o2$ = "(((char*)" + scope$ + n$ + ")+(" + o$ + "))" r$ = "*" + "(" + t$ + "*)" + o2$ IF method = 0 THEN e$ = evaluatetotyp(e$, typ) IF Error_Happened THEN EXIT SUB PRINT #12, r$ + "=" + e$ + ";" END IF 'print "setUDTrefer:"+r$,e$ tlayout$ = tl$ EXIT SUB END IF 'array? IF id.arraytype THEN n$ = RTRIM$(id.callname) typ = typ - ISPOINTER - ISREFERENCE 'typ now looks like a regular value IF (typ AND ISSTRING) THEN IF (typ AND ISFIXEDLENGTH) THEN offset$ = "&((uint8*)(" + n$ + "[0]))[tmp_long*" + str2(id.tsize) + "]" r$ = "qbs_new_fixed(" + offset$ + "," + str2(id.tsize) + ",1)" PRINT #12, "tmp_long=" + a$ + ";" IF method = 0 THEN l$ = "if (!new_error) qbs_set(" + r$ + "," + evaluatetotyp(e$, typ) + ");" IF Error_Happened THEN EXIT SUB ELSE l$ = "if (!new_error) qbs_set(" + r$ + "," + e$ + ");" END IF PRINT #12, l$ ELSE PRINT #12, "tmp_long=" + a$ + ";" IF method = 0 THEN l$ = "if (!new_error) qbs_set( ((qbs*)(((uint64*)(" + n$ + "[0]))[tmp_long]))," + evaluatetotyp(e$, typ) + ");" IF Error_Happened THEN EXIT SUB ELSE l$ = "if (!new_error) qbs_set( ((qbs*)(((uint64*)(" + n$ + "[0]))[tmp_long]))," + e$ + ");" END IF PRINT #12, l$ END IF stringprocessinghappened = 1 tlayout$ = tl$ EXIT SUB END IF IF (typ AND ISOFFSETINBITS) THEN 'r$ = "setbits_" + str2(typ AND 511) + "(" r$ = "setbits(" + str2(typ AND 511) + "," r$ = r$ + "(uint8*)(" + n$ + "[0])" + ",tmp_long," PRINT #12, "tmp_long=" + a$ + ";" IF method = 0 THEN l$ = "if (!new_error) " + r$ + evaluatetotyp(e$, typ) + ");" IF Error_Happened THEN EXIT SUB ELSE l$ = "if (!new_error) " + r$ + e$ + ");" END IF PRINT #12, l$ tlayout$ = tl$ EXIT SUB ELSE t$ = "" IF (typ AND ISFLOAT) THEN IF (typ AND 511) = 32 THEN t$ = "float" IF (typ AND 511) = 64 THEN t$ = "double" IF (typ AND 511) = 256 THEN t$ = "long double" ELSE IF (typ AND ISUNSIGNED) THEN IF (typ AND 511) = 8 THEN t$ = "uint8" IF (typ AND 511) = 16 THEN t$ = "uint16" IF (typ AND 511) = 32 THEN t$ = "uint32" IF (typ AND 511) = 64 THEN t$ = "uint64" IF typ AND ISOFFSET THEN t$ = "uptrszint" ELSE IF (typ AND 511) = 8 THEN t$ = "int8" IF (typ AND 511) = 16 THEN t$ = "int16" IF (typ AND 511) = 32 THEN t$ = "int32" IF (typ AND 511) = 64 THEN t$ = "int64" IF typ AND ISOFFSET THEN t$ = "ptrszint" END IF END IF END IF IF t$ = "" THEN Give_Error "Cannot find C type to return array data": EXIT SUB PRINT #12, "tmp_long=" + a$ + ";" IF method = 0 THEN l$ = "if (!new_error) ((" + t$ + "*)(" + n$ + "[0]))[tmp_long]=" + evaluatetotyp(e$, typ) + ";" IF Error_Happened THEN EXIT SUB ELSE l$ = "if (!new_error) ((" + t$ + "*)(" + n$ + "[0]))[tmp_long]=" + e$ + ";" END IF PRINT #12, l$ tlayout$ = tl$ EXIT SUB END IF 'array 'variable? IF id.t THEN r$ = RTRIM$(id.n) t = id.t 'remove irrelavant flags IF (t AND ISINCONVENTIONALMEMORY) THEN t = t - ISINCONVENTIONALMEMORY typ = t 'string variable? IF (t AND ISSTRING) THEN IF (t AND ISFIXEDLENGTH) THEN r$ = scope$ + "STRING" + str2(id.tsize) + "_" + r$ ELSE r$ = scope$ + "STRING_" + r$ END IF IF method = 0 THEN e$ = evaluatetotyp(e$, ISSTRING) IF Error_Happened THEN EXIT SUB PRINT #12, "qbs_set(" + r$ + "," + e$ + ");" PRINT #12, cleanupstringprocessingcall$ + "0);" IF arrayprocessinghappened THEN arrayprocessinghappened = 0 tlayout$ = tl$ EXIT SUB END IF 'bit-length variable? IF (t AND ISOFFSETINBITS) THEN b = t AND 511 IF (t AND ISUNSIGNED) THEN r$ = "*" + scope$ + "UBIT" + str2(t AND 511) + "_" + r$ IF method = 0 THEN e$ = evaluatetotyp(e$, 64& + ISUNSIGNED) IF Error_Happened THEN EXIT SUB l$ = r$ + "=(" + e$ + ")&" + str2(bitmask(b)) + ";" PRINT #12, l$ ELSE r$ = "*" + scope$ + "BIT" + str2(t AND 511) + "_" + r$ IF method = 0 THEN e$ = evaluatetotyp(e$, 64&) IF Error_Happened THEN EXIT SUB l$ = "if ((" + r$ + "=" + e$ + ")&" + str2(2 ^ (b - 1)) + "){" PRINT #12, l$ 'signed bit is set l$ = r$ + "|=" + str2(bitmaskinv(b)) + ";" PRINT #12, l$ PRINT #12, "}else{" 'signed bit is not set l$ = r$ + "&=" + str2(bitmask(b)) + ";" PRINT #12, l$ PRINT #12, "}" END IF IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);": stringprocessinghappened = 0 IF arrayprocessinghappened THEN arrayprocessinghappened = 0 tlayout$ = tl$ EXIT SUB END IF 'standard variable? IF t = BYTETYPE THEN r$ = "*" + scope$ + "BYTE_" + r$: GOTO sref IF t = UBYTETYPE THEN r$ = "*" + scope$ + "UBYTE_" + r$: GOTO sref IF t = INTEGERTYPE THEN r$ = "*" + scope$ + "INTEGER_" + r$: GOTO sref IF t = UINTEGERTYPE THEN r$ = "*" + scope$ + "UINTEGER_" + r$: GOTO sref IF t = LONGTYPE THEN r$ = "*" + scope$ + "LONG_" + r$: GOTO sref IF t = ULONGTYPE THEN r$ = "*" + scope$ + "ULONG_" + r$: GOTO sref IF t = INTEGER64TYPE THEN r$ = "*" + scope$ + "INTEGER64_" + r$: GOTO sref IF t = UINTEGER64TYPE THEN r$ = "*" + scope$ + "UINTEGER64_" + r$: GOTO sref IF t = SINGLETYPE THEN r$ = "*" + scope$ + "SINGLE_" + r$: GOTO sref IF t = DOUBLETYPE THEN r$ = "*" + scope$ + "DOUBLE_" + r$: GOTO sref IF t = FLOATTYPE THEN r$ = "*" + scope$ + "FLOAT_" + r$: GOTO sref IF t = OFFSETTYPE THEN r$ = "*" + scope$ + "OFFSET_" + r$: GOTO sref IF t = UOFFSETTYPE THEN r$ = "*" + scope$ + "UOFFSET_" + r$: GOTO sref sref: t2 = t - ISPOINTER IF method = 0 THEN e$ = evaluatetotyp(e$, t2) IF Error_Happened THEN EXIT SUB l$ = r$ + "=" + e$ + ";" PRINT #12, l$ IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);": stringprocessinghappened = 0 IF arrayprocessinghappened THEN arrayprocessinghappened = 0 tlayout$ = tl$ EXIT SUB END IF 'variable tlayout$ = tl$ END SUB FUNCTION str2$ (v AS LONG) str2$ = LTRIM$(RTRIM$(STR$(v))) END FUNCTION FUNCTION str2u64$ (v~&&) str2u64$ = LTRIM$(RTRIM$(STR$(v~&&))) END FUNCTION FUNCTION str2i64$ (v&&) str2i64$ = LTRIM$(RTRIM$(STR$(v&&))) END FUNCTION FUNCTION typ2ctyp$ (t AS LONG, tstr AS STRING) ctyp$ = "" 'typ can be passed as either: (the unused value is ignored) 'i. as a typ value in t 'ii. as a typ symbol (eg. "~%") in tstr 'iii. as a typ name (eg. _UNSIGNED INTEGER) in tstr IF tstr$ = "" THEN IF (t AND ISARRAY) THEN EXIT FUNCTION 'cannot return array types IF (t AND ISSTRING) THEN typ2ctyp$ = "qbs": EXIT FUNCTION b = t AND 511 IF (t AND ISUDT) THEN typ2ctyp$ = "void": EXIT FUNCTION IF (t AND ISOFFSETINBITS) THEN IF b <= 32 THEN ctyp$ = "int32" ELSE ctyp$ = "int64" IF (t AND ISUNSIGNED) THEN ctyp$ = "u" + ctyp$ typ2ctyp$ = ctyp$: EXIT FUNCTION END IF IF (t AND ISFLOAT) THEN IF b = 32 THEN ctyp$ = "float" IF b = 64 THEN ctyp$ = "double" IF b = 256 THEN ctyp$ = "long double" ELSE IF b = 8 THEN ctyp$ = "int8" IF b = 16 THEN ctyp$ = "int16" IF b = 32 THEN ctyp$ = "int32" IF b = 64 THEN ctyp$ = "int64" IF typ AND ISOFFSET THEN ctyp$ = "ptrszint" IF (t AND ISUNSIGNED) THEN ctyp$ = "u" + ctyp$ END IF IF t AND ISOFFSET THEN ctyp$ = "ptrszint": IF (t AND ISUNSIGNED) THEN ctyp$ = "uptrszint" END IF typ2ctyp$ = ctyp$: EXIT FUNCTION END IF ts$ = tstr$ 'is ts$ a symbol? IF ts$ = "$" THEN ctyp$ = "qbs" IF ts$ = "!" THEN ctyp$ = "float" IF ts$ = "#" THEN ctyp$ = "double" IF ts$ = "##" THEN ctyp$ = "long double" IF LEFT$(ts$, 1) = "~" THEN unsgn = 1: ts$ = RIGHT$(ts$, LEN(ts$) - 1) IF LEFT$(ts$, 1) = "`" THEN n$ = RIGHT$(ts$, LEN(ts$) - 1) b = 1 IF n$ <> "" THEN IF isuinteger(n$) = 0 THEN Give_Error "Invalid index after _BIT type": EXIT FUNCTION b = VAL(n$) IF b > 57 THEN Give_Error "Invalid index after _BIT type": EXIT FUNCTION END IF IF b <= 32 THEN ctyp$ = "int32" ELSE ctyp$ = "int64" IF unsgn THEN ctyp$ = "u" + ctyp$ typ2ctyp$ = ctyp$: EXIT FUNCTION END IF IF ts$ = "%&" THEN typ2ctyp$ = "ptrszint": IF (t AND ISUNSIGNED) THEN typ2ctyp$ = "uptrszint" EXIT FUNCTION END IF IF ts$ = "%%" THEN ctyp$ = "int8" IF ts$ = "%" THEN ctyp$ = "int16" IF ts$ = "&" THEN ctyp$ = "int32" IF ts$ = "&&" THEN ctyp$ = "int64" IF ctyp$ <> "" THEN IF unsgn THEN ctyp$ = "u" + ctyp$ typ2ctyp$ = ctyp$: EXIT FUNCTION END IF 'is tstr$ a named type? (eg. 'LONG') s$ = type2symbol$(tstr$) IF Error_Happened THEN EXIT FUNCTION IF LEN(s$) THEN typ2ctyp$ = typ2ctyp$(0, s$) IF Error_Happened THEN EXIT FUNCTION EXIT FUNCTION END IF Give_Error "Invalid type": EXIT FUNCTION END FUNCTION FUNCTION type2symbol$ (typ$) t$ = typ$ FOR i = 1 TO LEN(t$) IF MID$(t$, i, 1) = sp THEN MID$(t$, i, 1) = " " NEXT e$ = "Cannot convert type (" + typ$ + ") to symbol" t2$ = "_UNSIGNED _BIT": s$ = "~`1": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_UNSIGNED _BYTE": s$ = "~%%": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_UNSIGNED INTEGER": s$ = "~%": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_UNSIGNED LONG": s$ = "~&": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_UNSIGNED _INTEGER64": s$ = "~&&": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_UNSIGNED _OFFSET": s$ = "~%&": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_BIT": s$ = "`1": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_BYTE": s$ = "%%": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "INTEGER": s$ = "%": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "LONG": s$ = "&": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_INTEGER64": s$ = "&&": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_OFFSET": s$ = "%&": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "SINGLE": s$ = "!": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "DOUBLE": s$ = "#": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "_FLOAT": s$ = "##": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound t2$ = "STRING": s$ = "$": IF LEFT$(t$, LEN(t2$)) = t2$ THEN GOTO t2sfound Give_Error e$: EXIT FUNCTION t2sfound: type2symbol$ = s$ IF LEN(t2$) <> LEN(t$) THEN IF s$ <> "$" AND s$ <> "~`1" AND s$ <> "`1" THEN Give_Error e$: EXIT FUNCTION t$ = RIGHT$(t$, LEN(t$) - LEN(t2$)) IF LEFT$(t$, 3) <> " * " THEN Give_Error e$: EXIT FUNCTION t$ = RIGHT$(t$, LEN(t$) - 3) IF isuinteger(t$) = 0 THEN Give_Error e$: EXIT FUNCTION v = VAL(t$) IF v = 0 THEN Give_Error e$: EXIT FUNCTION IF s$ <> "$" AND v > 56 THEN Give_Error e$: EXIT FUNCTION IF s$ = "$" THEN s$ = s$ + str2$(v) ELSE s$ = LEFT$(s$, LEN(s$) - 1) + str2$(v) END IF type2symbol$ = s$ END IF END FUNCTION 'Strips away bits/indentifiers which make locating a variables source difficult FUNCTION typecomp (typ) typ2 = typ IF (typ2 AND ISINCONVENTIONALMEMORY) THEN typ2 = typ2 - ISINCONVENTIONALMEMORY typecomp = typ2 END FUNCTION FUNCTION typname2typ& (t2$) typname2typsize = 0 'the default t$ = t2$ 'symbol? ts$ = t$ IF ts$ = "$" THEN typname2typ& = STRINGTYPE: EXIT FUNCTION IF ts$ = "!" THEN typname2typ& = SINGLETYPE: EXIT FUNCTION IF ts$ = "#" THEN typname2typ& = DOUBLETYPE: EXIT FUNCTION IF ts$ = "##" THEN typname2typ& = FLOATTYPE: EXIT FUNCTION 'fixed length string? IF LEFT$(ts$, 1) = "$" THEN n$ = RIGHT$(ts$, LEN(ts$) - 1) IF isuinteger(n$) = 0 THEN Give_Error "Invalid index after STRING * type": EXIT FUNCTION b = VAL(n$) IF b = 0 THEN Give_Error "Invalid index after STRING * type": EXIT FUNCTION typname2typsize = b typname2typ& = STRINGTYPE + ISFIXEDLENGTH EXIT FUNCTION END IF 'unsigned? IF LEFT$(ts$, 1) = "~" THEN unsgn = 1: ts$ = RIGHT$(ts$, LEN(ts$) - 1) 'bit-type? IF LEFT$(ts$, 1) = "`" THEN n$ = RIGHT$(ts$, LEN(ts$) - 1) b = 1 IF n$ <> "" THEN IF isuinteger(n$) = 0 THEN Give_Error "Invalid index after _BIT type": EXIT FUNCTION b = VAL(n$) IF b > 56 THEN Give_Error "Invalid index after _BIT type": EXIT FUNCTION END IF IF unsgn THEN typname2typ& = UBITTYPE + (b - 1) ELSE typname2typ& = BITTYPE + (b - 1) EXIT FUNCTION END IF t = 0 IF ts$ = "%%" THEN t = BYTETYPE IF ts$ = "%" THEN t = INTEGERTYPE IF ts$ = "&" THEN t = LONGTYPE IF ts$ = "&&" THEN t = INTEGER64TYPE IF ts$ = "%&" THEN t = OFFSETTYPE IF t THEN IF unsgn THEN t = t + ISUNSIGNED typname2typ& = t: EXIT FUNCTION END IF 'not a valid symbol 'type name? FOR i = 1 TO LEN(t$) IF MID$(t$, i, 1) = sp THEN MID$(t$, i, 1) = " " NEXT IF t$ = "STRING" THEN typname2typ& = STRINGTYPE: EXIT FUNCTION IF LEFT$(t$, 9) = "STRING * " THEN n$ = RIGHT$(t$, LEN(t$) - 9) 'constant check 2011 hashfound = 0 hashname$ = n$ hashchkflags = HASHFLAG_CONSTANT hashres = HashFindRev(hashname$, hashchkflags, hashresflags, hashresref) DO WHILE hashres IF constsubfunc(hashresref) = subfuncn OR constsubfunc(hashresref) = 0 THEN IF constdefined(hashresref) THEN hashfound = 1 EXIT DO END IF END IF IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP IF hashfound THEN i2 = hashresref t = consttype(i2) IF t AND ISSTRING THEN Give_Error "Expected STRING * numeric-constant": EXIT FUNCTION 'convert value to general formats IF t AND ISFLOAT THEN v## = constfloat(i2) v&& = v## v~&& = v&& ELSE IF t AND ISUNSIGNED THEN v~&& = constuinteger(i2) v&& = v~&& v## = v&& ELSE v&& = constinteger(i2) v## = v&& v~&& = v&& END IF END IF IF v&& < 1 OR v&& > 9999999999 THEN Give_Error "STRING * out-of-range constant": EXIT FUNCTION b = v&& GOTO constantlenstr END IF IF isuinteger(n$) = 0 OR LEN(n$) > 10 THEN Give_Error "Invalid number/constant after STRING * type": EXIT FUNCTION b = VAL(n$) IF b = 0 OR LEN(n$) > 10 THEN Give_Error "Invalid number after STRING * type": EXIT FUNCTION constantlenstr: typname2typsize = b typname2typ& = STRINGTYPE + ISFIXEDLENGTH EXIT FUNCTION END IF IF t$ = "SINGLE" THEN typname2typ& = SINGLETYPE: EXIT FUNCTION IF t$ = "DOUBLE" THEN typname2typ& = DOUBLETYPE: EXIT FUNCTION IF t$ = "_FLOAT" THEN typname2typ& = FLOATTYPE: EXIT FUNCTION IF LEFT$(t$, 10) = "_UNSIGNED " THEN u = 1: t$ = RIGHT$(t$, LEN(t$) - 10) IF LEFT$(t$, 4) = "_BIT" THEN IF t$ = "_BIT" THEN IF u THEN typname2typ& = UBITTYPE ELSE typname2typ& = BITTYPE EXIT FUNCTION END IF IF LEFT$(t$, 7) <> "_BIT * " THEN Give_Error "Expected _BIT * number": EXIT FUNCTION n$ = RIGHT$(t$, LEN(t$) - 7) IF isuinteger(n$) = 0 THEN Give_Error "Invalid size after _BIT *": EXIT FUNCTION b = VAL(n$) IF b = 0 OR b > 56 THEN Give_Error "Invalid size after _BIT *": EXIT FUNCTION t = BITTYPE - 1 + b: IF u THEN t = t + ISUNSIGNED typname2typ& = t EXIT FUNCTION END IF t = 0 IF t$ = "_BYTE" THEN t = BYTETYPE IF t$ = "INTEGER" THEN t = INTEGERTYPE IF t$ = "LONG" THEN t = LONGTYPE IF t$ = "_INTEGER64" THEN t = INTEGER64TYPE IF t$ = "_OFFSET" THEN t = OFFSETTYPE IF t THEN IF u THEN t = t + ISUNSIGNED typname2typ& = t EXIT FUNCTION END IF IF u THEN EXIT FUNCTION '_UNSIGNED (nothing) 'UDT? FOR i = 1 TO lasttype IF t$ = RTRIM$(udtxname(i)) THEN typname2typ& = ISUDT + ISPOINTER + i EXIT FUNCTION END IF NEXT 'return 0 (failed) END FUNCTION FUNCTION uniquenumber& uniquenumbern = uniquenumbern + 1 uniquenumber& = uniquenumbern END FUNCTION FUNCTION validlabel (LABEL2$) create = CreatingLabel: CreatingLabel = 0 validlabel = 0 IF LEN(LABEL2$) = 0 THEN EXIT FUNCTION clabel$ = LABEL2$ label$ = UCASE$(LABEL2$) n = numelements(label$) IF n = 1 THEN 'Note: Reserved words and internal sub/function names are invalid hashres = HashFind(label$, HASHFLAG_RESERVED + HASHFLAG_SUB + HASHFLAG_FUNCTION, hashresflags, hashresref) DO WHILE hashres IF hashresflags AND (HASHFLAG_SUB + HASHFLAG_FUNCTION) THEN IF ids(hashresref).internal_subfunc THEN EXIT FUNCTION IF hashresflags AND HASHFLAG_SUB THEN 'could be a label or a sub call! 'analyze format IF ASC(ids(hashresref).specialformat) = 32 THEN IF ids(hashresref).args = 0 THEN onecommandsub = 1 ELSE onecommandsub = 0 ELSE IF ASC(ids(hashresref).specialformat) <> 91 THEN '"[" onecommandsub = 0 ELSE onecommandsub = 1 a$ = RTRIM$(ids(hashresref).specialformat) b = 1 FOR x = 2 TO LEN(a$) a = ASC(a$, x) IF a = 91 THEN b = b + 1 IF a = 93 THEN b = b - 1 IF b = 0 AND x <> LEN(a$) THEN onecommandsub = 0: EXIT FOR NEXT END IF END IF IF create <> 0 AND onecommandsub = 1 THEN IF INSTR(SubNameLabels$, sp + UCASE$(label$) + sp) = 0 THEN PossibleSubNameLabels$ = PossibleSubNameLabels$ + UCASE$(label$) + sp: EXIT FUNCTION 'treat as sub call END IF END IF 'sub name ELSE 'reserved EXIT FUNCTION END IF IF hashres <> 1 THEN hashres = HashFindCont(hashresflags, hashresref) ELSE hashres = 0 LOOP 'Numeric label? 'quasi numbers are possible, but: 'a) They may only have one decimal place 'b) They must be typed with the exact same characters to match t$ = label$ 'numeric? a = ASC(t$) IF (a >= 48 AND a <= 57) OR a = 46 THEN 'refer to original formatting if possible (eg. 1.10 not 1.1) x = INSTR(t$, CHR$(44)) IF x THEN t$ = RIGHT$(t$, LEN(t$) - x) END IF 'note: The symbols ! and # are valid trailing symbols in QBASIC, regardless of the number's size, ' so they are allowed in QB64 for compatibility reasons addsymbol$ = removesymbol$(t$) IF Error_Happened THEN EXIT FUNCTION IF LEN(addsymbol$) THEN IF INSTR(addsymbol$, "$") THEN EXIT FUNCTION IF addsymbol$ <> "#" AND addsymbol$ <> "!" THEN addsymbol$ = "" END IF IF a = 46 THEN dp = 1 FOR x = 2 TO LEN(t$) a = ASC(MID$(t$, x, 1)) IF a = 46 THEN dp = dp + 1 IF (a < 48 OR a > 57) AND a <> 46 THEN EXIT FUNCTION 'not numeric NEXT x IF dp > 1 THEN EXIT FUNCTION 'too many decimal points IF dp = 1 AND LEN(t$) = 1 THEN EXIT FUNCTION 'cant have '.' as a label tlayout$ = t$ + addsymbol$ i = INSTR(t$, "."): IF i THEN MID$(t$, i, 1) = "p" IF addsymbol$ = "#" THEN t$ = t$ + "d" IF addsymbol$ = "!" THEN t$ = t$ + "s" IF LEN(t$) > 40 THEN EXIT FUNCTION LABEL2$ = t$ validlabel = 1 EXIT FUNCTION END IF 'numeric END IF 'n=1 'Alpha-numeric label? 'Build label 'structure check (???.???.???.???) IF (n AND 1) = 0 THEN EXIT FUNCTION 'must be an odd number of elements FOR nx = 2 TO n - 1 STEP 2 a$ = getelement$(LABEL2$, nx) IF a$ <> "." THEN EXIT FUNCTION 'every 2nd element must be a period NEXT 'cannot begin with numeric c = ASC(clabel$): IF c >= 48 AND c <= 57 THEN EXIT FUNCTION 'elements check label3$ = "" FOR nx = 1 TO n STEP 2 label$ = getelement$(clabel$, nx) 'alpha-numeric? FOR x = 1 TO LEN(label$) IF alphanumeric(ASC(label$, x)) = 0 THEN EXIT FUNCTION NEXT 'build label IF label3$ = "" THEN label3$ = UCASE$(label$): tlayout$ = label$ ELSE label3$ = label3$ + fix046$ + UCASE$(label$): tlayout$ = tlayout$ + "." + label$ NEXT nx validlabel = 1 LABEL2$ = label3$ END FUNCTION SUB xend '1. locate bottomline,1 'PRINT #12, "display_page->cursor_y=print_holding_cursor=0; qbg_cursor_x=1; qbg_cursor_y=qbg_height_in_characters;" '2. print a message in the screen's width 'PRINT #12, "if (qbg_width_in_characters==80){" 'PRINT #12, "qbs_print(qbs_new_txt(" + CHR$(34) + "Press any key to continue" + SPACE$(80 - 25) + CHR$(34) + "),0);" 'PRINT #12, "}else{" 'PRINT #12, "qbs_print(qbs_new_txt(" + CHR$(34) + "Press any key to continue" + SPACE$(40 - 25) + CHR$(34) + "),0);" 'PRINT #12, "}" '3. wait for a key to be pressed 'PRINT #12, "do{" 'PRINT #12, "SDL_Delay(0);" 'PRINT #12, "if (stop_program) end();" 'PRINT #12, "}while(qbs_cleanup(qbs_tmp_base,qbs_equal(qbs_inkey(), ' qbs_new_txt(" + CHR$(34) + CHR$(34) + "))));" '4. quit 'PRINT #12, "close_program=1;" 'PRINT #12, "end();" PRINT #12, "sub_end();" END SUB SUB xfileprint (a$, ca$, n) u$ = str2$(uniquenumber) PRINT #12, "tab_spc_cr_size=2;" IF n = 2 THEN Give_Error "Expected # ... , ...": EXIT SUB a3$ = "" b = 0 FOR i = 3 TO n a2$ = getelement$(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF a2$ = "," AND b = 0 THEN IF a3$ = "" THEN Give_Error "Expected # ... , ...": EXIT SUB GOTO printgotfn END IF IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ NEXT Give_Error "Expected # ... ,": EXIT SUB printgotfn: e$ = fixoperationorder$(a3$) IF Error_Happened THEN EXIT SUB l$ = "PRINT" + sp + "#" + sp2 + tlayout$ + sp2 + "," e$ = evaluatetotyp(e$, 64&) IF Error_Happened THEN EXIT SUB PRINT #12, "tab_fileno=tmp_fileno=" + e$ + ";" PRINT #12, "if (new_error) goto skip" + u$ + ";" i = i + 1 'PRINT USING? (file) IF n >= i THEN IF getelement(a$, i) = "USING" THEN 'get format string fpujump: l$ = l$ + sp + "USING" e$ = "": b = 0: puformat$ = "" FOR i = i + 1 TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = "," THEN Give_Error "Expected PRINT USING #filenumber, formatstring ; ...": EXIT SUB IF a2$ = ";" THEN e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB l$ = l$ + sp + tlayout$ + sp2 + ";" e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB IF (typ AND ISSTRING) = 0 THEN Give_Error "Expected PRINT USING #filenumber, formatstring ; ...": EXIT SUB puformat$ = e$ EXIT FOR END IF '; END IF 'b IF LEN(e$) THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ NEXT IF puformat$ = "" THEN Give_Error "Expected PRINT USING #filenumber, formatstring ; ...": EXIT SUB IF i = n THEN Give_Error "Expected PRINT USING #filenumber, formatstring ; ...": EXIT SUB 'create build string PRINT #12, "tqbs=qbs_new(0,0);" 'set format start/index variable PRINT #12, "tmp_long=0;" 'scan format from beginning 'create string to hold format in for multiple references puf$ = "print_using_format" + u$ IF subfunc = "" THEN PRINT #13, "static qbs *" + puf$ + ";" ELSE PRINT #13, "qbs *" + puf$ + ";" END IF PRINT #12, puf$ + "=qbs_new(0,0); qbs_set(" + puf$ + "," + puformat$ + ");" PRINT #12, "if (new_error) goto skip" + u$ + ";" 'print expressions b = 0 e$ = "" last = 0 FOR i = i + 1 TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = ";" OR a2$ = "," THEN fprintulast: e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB IF last THEN l$ = l$ + sp + tlayout$ ELSE l$ = l$ + sp + tlayout$ + sp2 + a2$ e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB IF typ AND ISSTRING THEN IF LEFT$(e$, 9) = "func_tab(" OR LEFT$(e$, 9) = "func_spc(" THEN 'TAB/SPC exception 'note: position in format-string must be maintained '-print any string up until now PRINT #12, "sub_file_print(tmp_fileno,tqbs,0,0,0);" '-print e$ PRINT #12, "qbs_set(tqbs," + e$ + ");" PRINT #12, "if (new_error) goto skip_pu" + u$ + ";" PRINT #12, "sub_file_print(tmp_fileno,tqbs,0,0,0);" '-set length of tqbs to 0 PRINT #12, "tqbs->len=0;" ELSE 'regular string PRINT #12, "tmp_long=print_using(" + puf$ + ",tmp_long,tqbs," + e$ + ");" END IF ELSE 'not a string IF typ AND ISFLOAT THEN IF (typ AND 511) = 32 THEN PRINT #12, "tmp_long=print_using_single(" + puf$ + "," + e$ + ",tmp_long,tqbs);" IF (typ AND 511) = 64 THEN PRINT #12, "tmp_long=print_using_double(" + puf$ + "," + e$ + ",tmp_long,tqbs);" IF (typ AND 511) > 64 THEN PRINT #12, "tmp_long=print_using_float(" + puf$ + "," + e$ + ",tmp_long,tqbs);" ELSE IF ((typ AND 511) = 64) AND (typ AND ISUNSIGNED) <> 0 THEN PRINT #12, "tmp_long=print_using_uinteger64(" + puf$ + "," + e$ + ",tmp_long,tqbs);" ELSE PRINT #12, "tmp_long=print_using_integer64(" + puf$ + "," + e$ + ",tmp_long,tqbs);" END IF END IF END IF 'string/not string PRINT #12, "if (new_error) goto skip_pu" + u$ + ";" e$ = "" IF last THEN EXIT FOR GOTO fprintunext END IF END IF IF LEN(e$) THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ fprintunext: NEXT IF e$ <> "" THEN a2$ = "": last = 1: GOTO fprintulast PRINT #12, "skip_pu" + u$ + ":" 'check for errors PRINT #12, "if (new_error){" PRINT #12, "g_tmp_long=new_error; new_error=0; sub_file_print(tmp_fileno,tqbs,0,0,0); new_error=g_tmp_long;" PRINT #12, "}else{" IF a2$ = "," OR a2$ = ";" THEN nl = 0 ELSE nl = 1 'note: a2$ is set to the last element of a$ PRINT #12, "sub_file_print(tmp_fileno,tqbs,0,0," + str2$(nl) + ");" PRINT #12, "}" PRINT #12, "qbs_free(tqbs);" PRINT #12, "qbs_free(" + puf$ + ");" PRINT #12, "skip" + u$ + ":" PRINT #12, cleanupstringprocessingcall$ + "0);" PRINT #12, "tab_spc_cr_size=1;" tlayout$ = l$ EXIT SUB END IF END IF 'end of print using code IF i > n THEN PRINT #12, "sub_file_print(tmp_fileno,nothingstring,0,0,1);" GOTO printblankline END IF b = 0 e$ = "" last = 0 FOR i = i TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = ";" OR a2$ = "," OR UCASE$(a2$) = "USING" THEN printfilelast: IF UCASE$(a2$) = "USING" THEN IF e$ <> "" THEN gotofpu = 1 ELSE GOTO fpujump END IF IF a2$ = "," THEN usetab = 1 ELSE usetab = 0 IF last = 1 THEN newline = 1 ELSE newline = 0 extraspace = 0 IF LEN(e$) THEN ebak$ = e$ pnrtnum = 0 printfilenumber: e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB IF pnrtnum = 0 THEN IF last THEN l$ = l$ + sp + tlayout$ ELSE l$ = l$ + sp + tlayout$ + sp2 + a2$ END IF e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF (typ AND ISSTRING) = 0 THEN e$ = "STR$" + sp + "(" + sp + ebak$ + sp + ")" extraspace = 1 pnrtnum = 1 GOTO printfilenumber 'force re-evaluation END IF IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB 'format: string, (1/0) extraspace, (1/0) tab, (1/0)begin a new line PRINT #12, "sub_file_print(tmp_fileno," + e$ + ","; extraspace; ","; usetab; ","; newline; ");" ELSE 'len(e$)=0 IF a2$ = "," THEN l$ = l$ + sp + a2$ IF a2$ = ";" THEN IF RIGHT$(l$, 1) <> ";" THEN l$ = l$ + sp + a2$ 'concat ;; to ; END IF IF usetab THEN PRINT #12, "sub_file_print(tmp_fileno,nothingstring,0,1,0);" END IF 'len(e$) PRINT #12, "if (new_error) goto skip" + u$ + ";" e$ = "" IF gotofpu THEN GOTO fpujump IF last THEN EXIT FOR GOTO printfilenext END IF ', or ; END IF 'b=0 IF e$ <> "" THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ printfilenext: NEXT IF e$ <> "" THEN a2$ = "": last = 1: GOTO printfilelast printblankline: PRINT #12, "skip" + u$ + ":" PRINT #12, cleanupstringprocessingcall$ + "0);" PRINT #12, "tab_spc_cr_size=1;" tlayout$ = l$ END SUB SUB xfilewrite (ca$, n) l$ = "WRITE" + sp + "#" u$ = str2$(uniquenumber) PRINT #12, "tab_spc_cr_size=2;" IF n = 2 THEN Give_Error "Expected # ...": EXIT SUB a3$ = "" b = 0 FOR i = 3 TO n a2$ = getelement$(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF a2$ = "," AND b = 0 THEN IF a3$ = "" THEN Give_Error "Expected # ... , ...": EXIT SUB GOTO writegotfn END IF IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ NEXT Give_Error "Expected # ... ,": EXIT SUB writegotfn: e$ = fixoperationorder$(a3$) IF Error_Happened THEN EXIT SUB l$ = l$ + sp2 + tlayout$ + sp2 + "," e$ = evaluatetotyp(e$, 64&) IF Error_Happened THEN EXIT SUB PRINT #12, "tab_fileno=tmp_fileno=" + e$ + ";" PRINT #12, "if (new_error) goto skip" + u$ + ";" i = i + 1 IF i > n THEN PRINT #12, "sub_file_print(tmp_fileno,nothingstring,0,0,1);" GOTO writeblankline END IF b = 0 e$ = "" last = 0 FOR i = i TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = "," THEN writefilelast: IF last = 1 THEN newline = 1 ELSE newline = 0 ebak$ = e$ reevaled = 0 writefilenumber: e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB IF reevaled = 0 THEN l$ = l$ + sp + tlayout$ IF last = 0 THEN l$ = l$ + sp2 + "," END IF e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF reevaled = 0 THEN IF (typ AND ISSTRING) = 0 THEN e$ = "LTRIM$" + sp + "(" + sp + "STR$" + sp + "(" + sp + ebak$ + sp + ")" + sp + ")" IF last = 0 THEN e$ = e$ + sp + "+" + sp + CHR$(34) + "," + CHR$(34) + ",1" reevaled = 1 GOTO writefilenumber 'force re-evaluation ELSE e$ = CHR$(34) + "\042" + CHR$(34) + ",1" + sp + "+" + sp + ebak$ + sp + "+" + sp + CHR$(34) + "\042" + CHR$(34) + ",1" IF last = 0 THEN e$ = e$ + sp + "+" + sp + CHR$(34) + "," + CHR$(34) + ",1" reevaled = 1 GOTO writefilenumber 'force re-evaluation END IF END IF IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB 'format: string, (1/0) extraspace, (1/0) tab, (1/0)begin a new line PRINT #12, "sub_file_print(tmp_fileno," + e$ + ",0,0,"; newline; ");" PRINT #12, "if (new_error) goto skip" + u$ + ";" e$ = "" IF last THEN EXIT FOR GOTO writefilenext END IF ', END IF 'b=0 IF e$ <> "" THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ writefilenext: NEXT IF e$ <> "" THEN a2$ = ",": last = 1: GOTO writefilelast writeblankline: 'print #12, "}"'new_error PRINT #12, "skip" + u$ + ":" PRINT #12, cleanupstringprocessingcall$ + "0);" PRINT #12, "tab_spc_cr_size=1;" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ END SUB SUB xgosub (ca$, n&) a2$ = getelement(ca$, 2) IF validlabel(a2$) = 0 THEN Give_Error "Invalid label": EXIT SUB v = HashFind(a2$, HASHFLAG_LABEL, ignore, r) x = 1 labchk200: IF v THEN s = Labels(r).Scope IF s = subfuncn OR s = -1 THEN 'same scope? IF s = -1 THEN Labels(r).Scope = subfuncn 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk200 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd a2$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = subfuncn Labels(r).Error_Line = linenumber END IF 'x l$ = "GOSUB" + sp + tlayout$ layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ 'note: This code fragment also used by ON ... GOTO/GOSUB 'assume label is reachable (revise) PRINT #12, "return_point[next_return_point++]=" + str2(gosubid) + ";" PRINT #12, "if (next_return_point>=return_points) more_return_points();" PRINT #12, "goto LABEL_" + a2$ + ";" 'add return point jump PRINT #15, "case " + str2(gosubid) + ":" PRINT #15, "goto RETURN_" + str2(gosubid) + ";" PRINT #15, "break;" PRINT #12, "RETURN_" + str2(gosubid) + ":;" gosubid = gosubid + 1 END SUB SUB xongotogosub (a$, ca$, n) IF n < 4 THEN Give_Error "Expected ON expression GOTO/GOSUB label,label,...": EXIT SUB l$ = "ON" b = 0 FOR i = 2 TO n e2$ = getelement$(a$, i) IF e2$ = "(" THEN b = b + 1 IF e2$ = ")" THEN b = b - 1 IF e2$ = "GOTO" OR e2$ = "GOSUB" THEN EXIT FOR NEXT IF i >= n OR i = 2 THEN Give_Error "Expected ON expression GOTO/GOSUB label,label,...": EXIT SUB e$ = getelements$(ca$, 2, i - 1) g = 0: IF e2$ = "GOSUB" THEN g = 1 e$ = fixoperationorder(e$) IF Error_Happened THEN EXIT SUB l$ = l$ + sp + tlayout$ e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB IF (typ AND ISSTRING) THEN Give_Error "Expected numeric expression": EXIT SUB IF (typ AND ISFLOAT) THEN e$ = "qbr_float_to_long(" + e$ + ")" END IF l$ = l$ + sp + e2$ u$ = str2$(uniquenumber) PRINT #13, "static int32 ongo_" + u$ + "=0;" PRINT #12, "ongo_" + u$ + "=" + e$ + ";" ln = 1 labelwaslast = 0 FOR i = i + 1 TO n e$ = getelement$(ca$, i) IF e$ = "," THEN l$ = l$ + sp2 + "," IF i = n THEN Give_Error "Trailing , invalid": EXIT SUB ln = ln + 1 labelwaslast = 0 ELSE IF labelwaslast THEN Give_Error "Expected ,": EXIT SUB IF validlabel(e$) = 0 THEN Give_Error "Invalid label!": EXIT SUB v = HashFind(e$, HASHFLAG_LABEL, ignore, r) x = 1 labchk507: IF v THEN s = Labels(r).Scope IF s = subfuncn OR s = -1 THEN 'same scope? IF s = -1 THEN Labels(r).Scope = subfuncn 'acquire scope x = 0 'already defined tlayout$ = RTRIM$(Labels(r).cn) ELSE IF v = 2 THEN v = HashFindCont(ignore, r): GOTO labchk507 END IF END IF IF x THEN 'does not exist nLabels = nLabels + 1: IF nLabels > Labels_Ubound THEN Labels_Ubound = Labels_Ubound * 2: REDIM _PRESERVE Labels(1 TO Labels_Ubound) AS Label_Type Labels(nLabels) = Empty_Label HashAdd e$, HASHFLAG_LABEL, nLabels r = nLabels Labels(r).State = 0 Labels(r).cn = tlayout$ Labels(r).Scope = subfuncn Labels(r).Error_Line = linenumber END IF 'x l$ = l$ + sp + tlayout$ IF g THEN 'gosub lb$ = e$ PRINT #12, "if (ongo_" + u$ + "==" + str2$(ln) + "){" 'note: This code fragment also used by ON ... GOTO/GOSUB 'assume label is reachable (revise) PRINT #12, "return_point[next_return_point++]=" + str2(gosubid) + ";" PRINT #12, "if (next_return_point>=return_points) more_return_points();" PRINT #12, "goto LABEL_" + lb$ + ";" 'add return point jump PRINT #15, "case " + str2(gosubid) + ":" PRINT #15, "goto RETURN_" + str2(gosubid) + ";" PRINT #15, "break;" PRINT #12, "RETURN_" + str2(gosubid) + ":;" gosubid = gosubid + 1 PRINT #12, "goto ongo_" + u$ + "_skip;" PRINT #12, "}" ELSE 'goto PRINT #12, "if (ongo_" + u$ + "==" + str2$(ln) + ") goto LABEL_" + e$ + ";" END IF labelwaslast = 1 END IF NEXT PRINT #12, "if (ongo_" + u$ + "<0) error(5);" IF g = 1 THEN PRINT #12, "ongo_" + u$ + "_skip:;" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ END SUB SUB xprint (a$, ca$, n) u$ = str2$(uniquenumber) l$ = "PRINT" IF ASC(a$) = 76 THEN lp = 1: lp$ = "l": l$ = "LPRINT": PRINT #12, "tab_LPRINT=1;" '"L" 'PRINT USING? IF n >= 2 THEN IF getelement(a$, 2) = "USING" THEN 'get format string i = 3 pujump: l$ = l$ + sp + "USING" e$ = "": b = 0: puformat$ = "" FOR i = i TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = "," THEN Give_Error "Expected PRINT USING formatstring ; ...": EXIT SUB IF a2$ = ";" THEN e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB l$ = l$ + sp + tlayout$ + sp2 + ";" e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB IF (typ AND ISSTRING) = 0 THEN Give_Error "Expected PRINT USING formatstring ; ...": EXIT SUB puformat$ = e$ EXIT FOR END IF '; END IF 'b IF LEN(e$) THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ NEXT IF puformat$ = "" THEN Give_Error "Expected PRINT USING formatstring ; ...": EXIT SUB IF i = n THEN Give_Error "Expected PRINT USING formatstring ; ...": EXIT SUB 'create build string PRINT #12, "tqbs=qbs_new(0,0);" 'set format start/index variable PRINT #12, "tmp_long=0;" 'scan format from beginning 'create string to hold format in for multiple references puf$ = "print_using_format" + u$ IF subfunc = "" THEN PRINT #13, "static qbs *" + puf$ + ";" ELSE PRINT #13, "qbs *" + puf$ + ";" END IF PRINT #12, puf$ + "=qbs_new(0,0); qbs_set(" + puf$ + "," + puformat$ + ");" PRINT #12, "if (new_error) goto skip_pu" + u$ + ";" 'print expressions b = 0 e$ = "" last = 0 FOR i = i + 1 TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = ";" OR a2$ = "," THEN printulast: e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB IF last THEN l$ = l$ + sp + tlayout$ ELSE l$ = l$ + sp + tlayout$ + sp2 + a2$ e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB IF typ AND ISSTRING THEN IF LEFT$(e$, 9) = "func_tab(" OR LEFT$(e$, 9) = "func_spc(" THEN 'TAB/SPC exception 'note: position in format-string must be maintained '-print any string up until now PRINT #12, "qbs_" + lp$ + "print(tqbs,0);" '-print e$ PRINT #12, "qbs_set(tqbs," + e$ + ");" PRINT #12, "if (new_error) goto skip_pu" + u$ + ";" IF lp THEN PRINT #12, "lprint_makefit(tqbs);" ELSE PRINT #12, "makefit(tqbs);" PRINT #12, "qbs_" + lp$ + "print(tqbs,0);" '-set length of tqbs to 0 PRINT #12, "tqbs->len=0;" ELSE 'regular string PRINT #12, "tmp_long=print_using(" + puf$ + ",tmp_long,tqbs," + e$ + ");" END IF ELSE 'not a string IF typ AND ISFLOAT THEN IF (typ AND 511) = 32 THEN PRINT #12, "tmp_long=print_using_single(" + puf$ + "," + e$ + ",tmp_long,tqbs);" IF (typ AND 511) = 64 THEN PRINT #12, "tmp_long=print_using_double(" + puf$ + "," + e$ + ",tmp_long,tqbs);" IF (typ AND 511) > 64 THEN PRINT #12, "tmp_long=print_using_float(" + puf$ + "," + e$ + ",tmp_long,tqbs);" ELSE IF ((typ AND 511) = 64) AND (typ AND ISUNSIGNED) <> 0 THEN PRINT #12, "tmp_long=print_using_uinteger64(" + puf$ + "," + e$ + ",tmp_long,tqbs);" ELSE PRINT #12, "tmp_long=print_using_integer64(" + puf$ + "," + e$ + ",tmp_long,tqbs);" END IF END IF END IF 'string/not string PRINT #12, "if (new_error) goto skip_pu" + u$ + ";" e$ = "" IF last THEN EXIT FOR GOTO printunext END IF END IF IF LEN(e$) THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ printunext: NEXT IF e$ <> "" THEN a2$ = "": last = 1: GOTO printulast PRINT #12, "skip_pu" + u$ + ":" 'check for errors PRINT #12, "if (new_error){" PRINT #12, "g_tmp_long=new_error; new_error=0; qbs_" + lp$ + "print(tqbs,0); new_error=g_tmp_long;" PRINT #12, "}else{" IF a2$ = "," OR a2$ = ";" THEN nl = 0 ELSE nl = 1 'note: a2$ is set to the last element of a$ PRINT #12, "qbs_" + lp$ + "print(tqbs," + str2$(nl) + ");" PRINT #12, "}" PRINT #12, "qbs_free(tqbs);" PRINT #12, "qbs_free(" + puf$ + ");" PRINT #12, "skip" + u$ + ":" PRINT #12, cleanupstringprocessingcall$ + "0);" IF lp THEN PRINT #12, "tab_LPRINT=0;" tlayout$ = l$ EXIT SUB END IF END IF 'end of print using code b = 0 e$ = "" last = 0 FOR i = 2 TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = ";" OR a2$ = "," OR UCASE$(a2$) = "USING" THEN printlast: IF UCASE$(a2$) = "USING" THEN IF e$ <> "" THEN gotopu = 1 ELSE i = i + 1: GOTO pujump END IF IF LEN(e$) THEN ebak$ = e$ pnrtnum = 0 printnumber: e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB IF pnrtnum = 0 THEN IF last THEN l$ = l$ + sp + tlayout$ ELSE l$ = l$ + sp + tlayout$ + sp2 + a2$ END IF e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF (typ AND ISSTRING) = 0 THEN 'not a string expresion! e$ = "STR$" + sp + "(" + sp + ebak$ + sp + ")" + sp + "+" + sp + CHR$(34) + " " + CHR$(34) pnrtnum = 1 GOTO printnumber END IF IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB PRINT #12, "tqbs=qbs_new(0,0);" PRINT #12, "qbs_set(tqbs," + e$ + ");" PRINT #12, "if (new_error) goto skip" + u$ + ";" IF lp THEN PRINT #12, "lprint_makefit(tqbs);" ELSE PRINT #12, "makefit(tqbs);" PRINT #12, "qbs_" + lp$ + "print(tqbs,0);" PRINT #12, "qbs_free(tqbs);" ELSE IF a2$ = "," THEN l$ = l$ + sp + a2$ IF a2$ = ";" THEN IF RIGHT$(l$, 1) <> ";" THEN l$ = l$ + sp + a2$ 'concat ;; to ; END IF END IF 'len(e$) IF a2$ = "," THEN PRINT #12, "tab();" e$ = "" IF gotopu THEN i = i + 1: GOTO pujump IF last THEN PRINT #12, "qbs_" + lp$ + "print(nothingstring,1);" 'go to new line EXIT FOR END IF GOTO printnext END IF 'a2$ END IF 'b=0 IF LEN(e$) THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ printnext: NEXT IF LEN(e$) THEN a2$ = "": last = 1: GOTO printlast IF n = 1 THEN PRINT #12, "qbs_" + lp$ + "print(nothingstring,1);" PRINT #12, "skip" + u$ + ":" PRINT #12, cleanupstringprocessingcall$ + "0);" IF lp THEN PRINT #12, "tab_LPRINT=0;" tlayout$ = l$ END SUB SUB xread (ca$, n) l$ = "READ" IF n = 1 THEN Give_Error "Expected variable": EXIT SUB i = 2 IF i > n THEN Give_Error "Expected , ...": EXIT SUB a3$ = "" b = 0 FOR i = i TO n a2$ = getelement$(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF (a2$ = "," AND b = 0) OR i = n THEN IF i = n THEN IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ END IF IF a3$ = "" THEN Give_Error "Expected , ...": EXIT SUB e$ = fixoperationorder$(a3$) IF Error_Happened THEN EXIT SUB l$ = l$ + sp + tlayout$: IF i <> n THEN l$ = l$ + sp2 + "," e$ = evaluate(e$, t) IF Error_Happened THEN EXIT SUB IF (t AND ISREFERENCE) = 0 THEN Give_Error "Expected variable": EXIT SUB IF (t AND ISSTRING) THEN e$ = refer(e$, t, 0) IF Error_Happened THEN EXIT SUB PRINT #12, "sub_read_string(data,&data_offset,data_size," + e$ + ");" stringprocessinghappened = 1 ELSE 'numeric variable IF (t AND ISFLOAT) <> 0 OR (t AND 511) <> 64 THEN IF (t AND ISOFFSETINBITS) THEN setrefer e$, t, "((int64)func_read_float(data,&data_offset,data_size," + str2(t) + "))", 1 IF Error_Happened THEN EXIT SUB ELSE setrefer e$, t, "func_read_float(data,&data_offset,data_size," + str2(t) + ")", 1 IF Error_Happened THEN EXIT SUB END IF ELSE IF t AND ISUNSIGNED THEN setrefer e$, t, "func_read_uint64(data,&data_offset,data_size)", 1 IF Error_Happened THEN EXIT SUB ELSE setrefer e$, t, "func_read_int64(data,&data_offset,data_size)", 1 IF Error_Happened THEN EXIT SUB END IF END IF END IF 'string/numeric IF i = n THEN EXIT FOR a3$ = "": a2$ = "" END IF IF a3$ = "" THEN a3$ = a2$ ELSE a3$ = a3$ + sp + a2$ NEXT IF stringprocessinghappened THEN PRINT #12, cleanupstringprocessingcall$ + "0);" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ END SUB SUB xwrite (ca$, n) l$ = "WRITE" u$ = str2$(uniquenumber) IF n = 1 THEN PRINT #12, "qbs_print(nothingstring,1);" GOTO writeblankline2 END IF b = 0 e$ = "" last = 0 FOR i = 2 TO n a2$ = getelement(ca$, i) IF a2$ = "(" THEN b = b + 1 IF a2$ = ")" THEN b = b - 1 IF b = 0 THEN IF a2$ = "," THEN writelast: IF last = 1 THEN newline = 1 ELSE newline = 0 ebak$ = e$ reevaled = 0 writechecked: e$ = fixoperationorder$(e$) IF Error_Happened THEN EXIT SUB IF reevaled = 0 THEN l$ = l$ + sp + tlayout$ IF last = 0 THEN l$ = l$ + sp2 + "," END IF e$ = evaluate(e$, typ) IF Error_Happened THEN EXIT SUB IF reevaled = 0 THEN IF (typ AND ISSTRING) = 0 THEN e$ = "LTRIM$" + sp + "(" + sp + "STR$" + sp + "(" + sp + ebak$ + sp + ")" + sp + ")" IF last = 0 THEN e$ = e$ + sp + "+" + sp + CHR$(34) + "," + CHR$(34) + ",1" reevaled = 1 GOTO writechecked 'force re-evaluation ELSE e$ = CHR$(34) + "\042" + CHR$(34) + ",1" + sp + "+" + sp + ebak$ + sp + "+" + sp + CHR$(34) + "\042" + CHR$(34) + ",1" IF last = 0 THEN e$ = e$ + sp + "+" + sp + CHR$(34) + "," + CHR$(34) + ",1" reevaled = 1 GOTO writechecked 'force re-evaluation END IF END IF IF (typ AND ISREFERENCE) THEN e$ = refer(e$, typ, 0) IF Error_Happened THEN EXIT SUB 'format: string, (1/0) extraspace, (1/0) tab, (1/0)begin a new line PRINT #12, "qbs_print(" + e$ + ","; newline; ");" PRINT #12, "if (new_error) goto skip" + u$ + ";" e$ = "" IF last THEN EXIT FOR GOTO writenext END IF ', END IF 'b=0 IF e$ <> "" THEN e$ = e$ + sp + a2$ ELSE e$ = a2$ writenext: NEXT IF e$ <> "" THEN a2$ = ",": last = 1: GOTO writelast writeblankline2: PRINT #12, "skip" + u$ + ":" PRINT #12, cleanupstringprocessingcall$ + "0);" layoutdone = 1: IF LEN(layout$) THEN layout$ = layout$ + sp + l$ ELSE layout$ = l$ END SUB FUNCTION evaluateconst$ (a2$, t AS LONG) a$ = a2$ IF Debug THEN PRINT #9, "evaluateconst:in:" + a$ DIM block(1000) AS STRING DIM status(1000) AS INTEGER '0=unprocessed (can be "") '1=processed DIM btype(1000) AS LONG 'for status=1 blocks 'put a$ into blocks n = numelements(a$) FOR i = 1 TO n block(i) = getelement$(a$, i) NEXT evalconstevalbrack: 'find highest bracket level l = 0 b = 0 FOR i = 1 TO n IF block(i) = "(" THEN b = b + 1 IF block(i) = ")" THEN b = b - 1 IF b > l THEN l = b NEXT 'if brackets exist, evaluate that item first IF l THEN b = 0 e$ = "" FOR i = 1 TO n IF block(i) = ")" THEN IF b = l THEN block(i) = "": EXIT FOR b = b - 1 END IF IF b >= l THEN IF LEN(e$) = 0 THEN e$ = block(i) ELSE e$ = e$ + sp + block(i) block(i) = "" END IF IF block(i) = "(" THEN b = b + 1 IF b = l THEN i2 = i: block(i) = "" END IF NEXT i status(i) = 1 block(i) = evaluateconst$(e$, btype(i)) IF Error_Happened THEN EXIT FUNCTION GOTO evalconstevalbrack END IF 'l 'linear equation remains with some pre-calculated & non-pre-calc blocks 'problem: type QBASIC assumes and type required to store calc. value may ' differ dramatically. in qbasic, this would have caused an overflow, ' but in qb64 it MUST work. eg. 32767% * 32767% 'solution: all interger calc. will be performed using a signed _INTEGER64 ' all float calc. will be performed using a _FLOAT 'convert non-calc block numbers into binary form with QBASIC-like type FOR i = 1 TO n IF status(i) = 0 THEN IF LEN(block(i)) THEN a = ASC(block(i)) IF (a = 45 AND LEN(block(i)) > 1) OR (a >= 48 AND a <= 57) THEN 'number? 'integers e$ = RIGHT$(block(i), 3) IF e$ = "~&&" THEN btype(i) = UINTEGER64TYPE - ISPOINTER: GOTO gotconstblkityp IF e$ = "~%%" THEN btype(i) = UBYTETYPE - ISPOINTER: GOTO gotconstblkityp e$ = RIGHT$(block(i), 2) IF e$ = "&&" THEN btype(i) = INTEGER64TYPE - ISPOINTER: GOTO gotconstblkityp IF e$ = "%%" THEN btype(i) = BYTETYPE - ISPOINTER: GOTO gotconstblkityp IF e$ = "~%" THEN btype(i) = UINTEGERTYPE - ISPOINTER: GOTO gotconstblkityp IF e$ = "~&" THEN btype(i) = ULONGTYPE - ISPOINTER: GOTO gotconstblkityp e$ = RIGHT$(block(i), 1) IF e$ = "%" THEN btype(i) = INTEGERTYPE - ISPOINTER: GOTO gotconstblkityp IF e$ = "&" THEN btype(i) = LONGTYPE - ISPOINTER: GOTO gotconstblkityp 'ubit-type? IF INSTR(block(i), "~`") THEN x = INSTR(block(i), "~`") IF x = LEN(block(i)) - 1 THEN block(i) = block(i) + "1" btype(i) = UBITTYPE - ISPOINTER - 1 + VAL(RIGHT$(block(i), LEN(block(i)) - x - 1)) block(i) = _MK$(_INTEGER64, VAL(LEFT$(block(i), x - 1))) status(i) = 1 GOTO gotconstblktyp END IF 'bit-type? IF INSTR(block(i), "`") THEN x = INSTR(block(i), "`") IF x = LEN(block(i)) THEN block(i) = block(i) + "1" btype(i) = BITTYPE - ISPOINTER - 1 + VAL(RIGHT$(block(i), LEN(block(i)) - x)) block(i) = _MK$(_INTEGER64, VAL(LEFT$(block(i), x - 1))) status(i) = 1 GOTO gotconstblktyp END IF 'floats IF INSTR(block(i), "E") THEN block(i) = _MK$(_FLOAT, VAL(block(i))) btype(i) = SINGLETYPE - ISPOINTER status(i) = 1 GOTO gotconstblktyp END IF IF INSTR(block(i), "D") THEN block(i) = _MK$(_FLOAT, VAL(block(i))) btype(i) = DOUBLETYPE - ISPOINTER status(i) = 1 GOTO gotconstblktyp END IF IF INSTR(block(i), "F") THEN block(i) = _MK$(_FLOAT, VAL(block(i))) btype(i) = FLOATTYPE - ISPOINTER status(i) = 1 GOTO gotconstblktyp END IF Give_Error "Invalid CONST expression.1": EXIT FUNCTION gotconstblkityp: block(i) = LEFT$(block(i), LEN(block(i)) - LEN(e$)) block(i) = _MK$(_INTEGER64, VAL(block(i))) status(i) = 1 gotconstblktyp: END IF 'a IF a = 34 THEN 'string? 'no changes need to be made to block(i) which is of format "CHARACTERS",size btype(i) = STRINGTYPE - ISPOINTER status(i) = 1 END IF END IF 'len<>0 END IF 'status NEXT 'remove NULL blocks n2 = 0 FOR i = 1 TO n IF block(i) <> "" THEN n2 = n2 + 1 block(n2) = block(i) status(n2) = status(i) btype(n2) = btype(i) END IF NEXT n = n2 'only one block? IF n = 1 THEN IF status(1) = 0 THEN Give_Error "Invalid CONST expression.2": EXIT FUNCTION t = btype(1) evaluateconst$ = block(1) EXIT FUNCTION END IF 'n=1 'evaluate equation (equation cannot contain any STRINGs) '[negation/not][variable] e$ = block(1) IF status(1) = 0 THEN IF n <> 2 THEN Give_Error "Invalid CONST expression.4": EXIT FUNCTION IF status(2) = 0 THEN Give_Error "Invalid CONST expression.5": EXIT FUNCTION IF btype(2) AND ISSTRING THEN Give_Error "Invalid CONST expression.6": EXIT FUNCTION o$ = block(1) IF o$ = "ñ" THEN IF btype(2) AND ISFLOAT THEN r## = -_CV(_FLOAT, block(2)) evaluateconst$ = _MK$(_FLOAT, r##) ELSE r&& = -_CV(_INTEGER64, block(2)) evaluateconst$ = _MK$(_INTEGER64, r&&) END IF t = btype(2) EXIT FUNCTION END IF IF o$ = "NOT" THEN IF btype(2) AND ISFLOAT THEN r&& = _CV(_FLOAT, block(2)) ELSE r&& = _CV(_INTEGER64, block(2)) END IF r&& = NOT r&& t = btype(2) IF t AND ISFLOAT THEN t = LONGTYPE - ISPOINTER 'markdown to LONG evaluateconst$ = _MK$(_INTEGER64, r&&) EXIT FUNCTION END IF Give_Error "Invalid CONST expression.7": EXIT FUNCTION END IF '[variable][bool-operator][variable]... 'get first variable et = btype(1) ev$ = block(1) i = 2 evalconstequ: 'get operator IF i >= n THEN Give_Error "Invalid CONST expression.8": EXIT FUNCTION o$ = block(i) i = i + 1 IF isoperator(o$) = 0 THEN Give_Error "Invalid CONST expression.9": EXIT FUNCTION IF i > n THEN Give_Error "Invalid CONST expression.10": EXIT FUNCTION 'string/numeric mismatch? IF (btype(i) AND ISSTRING) <> (et AND ISSTRING) THEN Give_Error "Invalid CONST expression.11": EXIT FUNCTION IF et AND ISSTRING THEN IF o$ <> "+" THEN Give_Error "Invalid CONST expression.12": EXIT FUNCTION 'concat strings s1$ = RIGHT$(ev$, LEN(ev$) - 1) s1$ = LEFT$(s1$, INSTR(s1$, CHR$(34)) - 1) s1size = VAL(RIGHT$(ev$, LEN(ev$) - LEN(s1$) - 3)) s2$ = RIGHT$(block(i), LEN(block(i)) - 1) s2$ = LEFT$(s2$, INSTR(s2$, CHR$(34)) - 1) s2size = VAL(RIGHT$(block(i), LEN(block(i)) - LEN(s2$) - 3)) ev$ = CHR$(34) + s1$ + s2$ + CHR$(34) + "," + str2$(s1size + s2size) GOTO econstmarkedup END IF 'prepare left and right values IF et AND ISFLOAT THEN linteger = 0 l## = _CV(_FLOAT, ev$) l&& = l## ELSE linteger = 1 l&& = _CV(_INTEGER64, ev$) l## = l&& END IF IF btype(i) AND ISFLOAT THEN rinteger = 0 r## = _CV(_FLOAT, block(i)) r&& = r## ELSE rinteger = 1 r&& = _CV(_INTEGER64, block(i)) r## = r&& END IF IF linteger = 1 AND rinteger = 1 THEN IF o$ = "+" THEN r&& = l&& + r&&: GOTO econstmarkupi IF o$ = "-" THEN r&& = l&& - r&&: GOTO econstmarkupi IF o$ = "*" THEN r&& = l&& * r&&: GOTO econstmarkupi IF o$ = "^" THEN r## = l&& ^ r&&: GOTO econstmarkupf IF o$ = "/" THEN r## = l&& / r&&: GOTO econstmarkupf IF o$ = "\" THEN r&& = l&& \ r&&: GOTO econstmarkupi IF o$ = "MOD" THEN r&& = l&& MOD r&&: GOTO econstmarkupi IF o$ = "=" THEN r&& = l&& = r&&: GOTO econstmarkupi16 IF o$ = ">" THEN r&& = l&& > r&&: GOTO econstmarkupi16 IF o$ = "<" THEN r&& = l&& < r&&: GOTO econstmarkupi16 IF o$ = ">=" THEN r&& = l&& >= r&&: GOTO econstmarkupi16 IF o$ = "<=" THEN r&& = l&& <= r&&: GOTO econstmarkupi16 IF o$ = "<>" THEN r&& = l&& <> r&&: GOTO econstmarkupi16 IF o$ = "IMP" THEN r&& = l&& IMP r&&: GOTO econstmarkupi IF o$ = "EQV" THEN r&& = l&& EQV r&&: GOTO econstmarkupi IF o$ = "XOR" THEN r&& = l&& XOR r&&: GOTO econstmarkupi IF o$ = "OR" THEN r&& = l&& OR r&&: GOTO econstmarkupi IF o$ = "AND" THEN r&& = l&& AND r&&: GOTO econstmarkupi END IF IF o$ = "+" THEN r## = l## + r##: GOTO econstmarkupf IF o$ = "-" THEN r## = l## - r##: GOTO econstmarkupf IF o$ = "*" THEN r## = l## * r##: GOTO econstmarkupf IF o$ = "^" THEN r## = l## ^ r##: GOTO econstmarkupf IF o$ = "/" THEN r## = l## / r##: GOTO econstmarkupf IF o$ = "\" THEN r&& = l## \ r##: GOTO econstmarkupi32 IF o$ = "MOD" THEN r&& = l## MOD r##: GOTO econstmarkupi32 IF o$ = "=" THEN r&& = l## = r##: GOTO econstmarkupi16 IF o$ = ">" THEN r&& = l## > r##: GOTO econstmarkupi16 IF o$ = "<" THEN r&& = l## < r##: GOTO econstmarkupi16 IF o$ = ">=" THEN r&& = l## >= r##: GOTO econstmarkupi16 IF o$ = "<=" THEN r&& = l## <= r##: GOTO econstmarkupi16 IF o$ = "<>" THEN r&& = l## <> r##: GOTO econstmarkupi16 IF o$ = "IMP" THEN r&& = l## IMP r##: GOTO econstmarkupi32 IF o$ = "EQV" THEN r&& = l## EQV r##: GOTO econstmarkupi32 IF o$ = "XOR" THEN r&& = l## XOR r##: GOTO econstmarkupi32 IF o$ = "OR" THEN r&& = l## OR r##: GOTO econstmarkupi32 IF o$ = "AND" THEN r&& = l## AND r##: GOTO econstmarkupi32 Give_Error "Invalid CONST expression.13": EXIT FUNCTION econstmarkupi16: et = INTEGERTYPE - ISPOINTER ev$ = _MK$(_INTEGER64, r&&) GOTO econstmarkedup econstmarkupi32: et = LONGTYPE - ISPOINTER ev$ = _MK$(_INTEGER64, r&&) GOTO econstmarkedup econstmarkupi: IF et <> btype(i) THEN 'keep unsigned? u = 0: IF (et AND ISUNSIGNED) <> 0 AND (btype(i) AND ISUNSIGNED) <> 0 THEN u = 1 lb = et AND 511: rb = btype(i) AND 511 ob = 0 IF lb = rb THEN IF (et AND ISOFFSETINBITS) <> 0 AND (btype(i) AND ISOFFSETINBITS) <> 0 THEN ob = 1 b = lb END IF IF lb > rb THEN IF (et AND ISOFFSETINBITS) <> 0 THEN ob = 1 b = lb END IF IF lb < rb THEN IF (btype(i) AND ISOFFSETINBITS) <> 0 THEN ob = 1 b = rb END IF et = b IF ob THEN et = et + ISOFFSETINBITS IF u THEN et = et + ISUNSIGNED END IF ev$ = _MK$(_INTEGER64, r&&) GOTO econstmarkedup econstmarkupf: lfb = 0: rfb = 0 lib = 0: rib = 0 IF et AND ISFLOAT THEN lfb = et AND 511 ELSE lib = et AND 511 IF btype(i) AND ISFLOAT THEN rfb = btype(i) AND 511 ELSE rib = btype(i) AND 511 f = 32 IF lib > 16 OR rib > 16 THEN f = 64 IF lfb > 32 OR rfb > 32 THEN f = 64 IF lib > 32 OR rib > 32 THEN f = 256 IF lfb > 64 OR rfb > 64 THEN f = 256 et = ISFLOAT + f ev$ = _MK$(_FLOAT, r##) econstmarkedup: i = i + 1 IF i <= n THEN GOTO evalconstequ t = et evaluateconst$ = ev$ END FUNCTION FUNCTION typevalue2symbol$ (t) IF t AND ISSTRING THEN IF t AND ISFIXEDLENGTH THEN Give_Error "Cannot convert expression type to symbol": EXIT FUNCTION typevalue2symbol$ = "$" EXIT FUNCTION END IF s$ = "" IF t AND ISUNSIGNED THEN s$ = "~" b = t AND 511 IF t AND ISOFFSETINBITS THEN IF b > 1 THEN s$ = s$ + "`" + str2$(b) ELSE s$ = s$ + "`" typevalue2symbol$ = s$ EXIT FUNCTION END IF IF t AND ISFLOAT THEN IF b = 32 THEN s$ = "!" IF b = 64 THEN s$ = "#" IF b = 256 THEN s$ = "##" typevalue2symbol$ = s$ EXIT FUNCTION END IF IF b = 8 THEN s$ = s$ + "%%" IF b = 16 THEN s$ = s$ + "%" IF b = 32 THEN s$ = s$ + "&" IF b = 64 THEN s$ = s$ + "&&" typevalue2symbol$ = s$ END FUNCTION FUNCTION id2fulltypename$ t = id.t IF t = 0 THEN t = id.arraytype size = id.tsize bits = t AND 511 IF t AND ISUDT THEN a$ = RTRIM$(udtxcname(t AND 511)) id2fulltypename$ = a$: EXIT FUNCTION END IF IF t AND ISSTRING THEN IF t AND ISFIXEDLENGTH THEN a$ = "STRING * " + str2(size) ELSE a$ = "STRING" id2fulltypename$ = a$: EXIT FUNCTION END IF IF t AND ISOFFSETINBITS THEN IF bits > 1 THEN a$ = "_BIT * " + str2(bits) ELSE a$ = "_BIT" IF t AND ISUNSIGNED THEN a$ = "_UNSIGNED " + a$ id2fulltypename$ = a$: EXIT FUNCTION END IF IF t AND ISFLOAT THEN IF bits = 32 THEN a$ = "SINGLE" IF bits = 64 THEN a$ = "DOUBLE" IF bits = 256 THEN a$ = "_FLOAT" ELSE 'integer-based IF bits = 8 THEN a$ = "_BYTE" IF bits = 16 THEN a$ = "INTEGER" IF bits = 32 THEN a$ = "LONG" IF bits = 64 THEN a$ = "_INTEGER64" IF t AND ISUNSIGNED THEN a$ = "_UNSIGNED " + a$ END IF id2fulltypename$ = a$ END FUNCTION FUNCTION symbol2fulltypename$ (s2$) 'note: accepts both symbols and type names s$ = s2$ IF LEFT$(s$, 1) = "~" THEN u = 1 IF LEN(typ$) = 1 THEN Give_Error "Expected ~...": EXIT FUNCTION s$ = RIGHT$(s$, LEN(s$) - 1) u$ = "_UNSIGNED " END IF IF s$ = "%%" THEN t$ = u$ + "_BYTE": GOTO gotsym2typ IF s$ = "%" THEN t$ = u$ + "INTEGER": GOTO gotsym2typ IF s$ = "&" THEN t$ = u$ + "LONG": GOTO gotsym2typ IF s$ = "&&" THEN t$ = u$ + "_INTEGER64": GOTO gotsym2typ IF s$ = "%&" THEN t$ = u$ + "_OFFSET": GOTO gotsym2typ IF LEFT$(s$, 1) = "`" THEN IF LEN(s$) = 1 THEN t$ = u$ + "_BIT * 1" GOTO gotsym2typ END IF n$ = RIGHT$(s$, LEN(s$) - 1) IF isuinteger(n$) = 0 THEN Give_Error "Expected number after symbol `": EXIT FUNCTION t$ = u$ + "_BIT * " + n$ GOTO gotsym2typ END IF IF u = 1 THEN Give_Error "Expected type symbol after ~": EXIT FUNCTION IF s$ = "!" THEN t$ = "SINGLE": GOTO gotsym2typ IF s$ = "#" THEN t$ = "DOUBLE": GOTO gotsym2typ IF s$ = "##" THEN t$ = "_FLOAT": GOTO gotsym2typ IF s$ = "$" THEN t$ = "STRING": GOTO gotsym2typ IF LEFT$(s$, 1) = "$" THEN n$ = RIGHT$(s$, LEN(s$) - 1) IF isuinteger(n$) = 0 THEN Give_Error "Expected number after symbol $": EXIT FUNCTION t$ = "STRING * " + n$ GOTO gotsym2typ END IF t$ = s$ gotsym2typ: IF RIGHT$(" " + t$, 5) = " _BIT" THEN t$ = t$ + " * 1" 'clarify (_UNSIGNED) _BIT as (_UNSIGNED) _BIT * 1 FOR i = 1 TO LEN(t$) IF ASC(t$, i) = ASC(sp) THEN ASC(t$, i) = 32 NEXT symbol2fulltypename$ = t$ END FUNCTION SUB lineinput3load (f$) OPEN f$ FOR BINARY AS #1 l = LOF(1) lineinput3buffer$ = SPACE$(l) GET #1, , lineinput3buffer$ IF LEN(lineinput3buffer$) THEN IF RIGHT$(lineinput3buffer$, 1) = CHR$(26) THEN lineinput3buffer$ = LEFT$(lineinput3buffer$, LEN(lineinput3buffer$) - 1) CLOSE #1 lineinput3index = 1 END SUB FUNCTION lineinput3$ 'returns CHR$(13) if no more lines are available l = LEN(lineinput3buffer$) IF lineinput3index > l THEN lineinput3$ = CHR$(13): EXIT FUNCTION c13 = INSTR(lineinput3index, lineinput3buffer$, CHR$(13)) c10 = INSTR(lineinput3index, lineinput3buffer$, CHR$(10)) IF c10 = 0 AND c13 = 0 THEN lineinput3$ = MID$(lineinput3buffer$, lineinput3index, l - lineinput3index + 1) lineinput3index = l + 1 EXIT FUNCTION END IF IF c10 = 0 THEN c10 = 2147483647 IF c13 = 0 THEN c13 = 2147483647 IF c10 < c13 THEN '10 before 13 lineinput3$ = MID$(lineinput3buffer$, lineinput3index, c10 - lineinput3index) lineinput3index = c10 + 1 IF lineinput3index <= l THEN IF ASC(MID$(lineinput3buffer$, lineinput3index, 1)) = 13 THEN lineinput3index = lineinput3index + 1 END IF ELSE '13 before 10 lineinput3$ = MID$(lineinput3buffer$, lineinput3index, c13 - lineinput3index) lineinput3index = c13 + 1 IF lineinput3index <= l THEN IF ASC(MID$(lineinput3buffer$, lineinput3index, 1)) = 10 THEN lineinput3index = lineinput3index + 1 END IF END IF END FUNCTION FUNCTION getfilepath$ (f$) FOR i = LEN(f$) TO 1 STEP -1 a$ = MID$(f$, i, 1) IF a$ = pathsep$ THEN getfilepath$ = LEFT$(f$, i) EXIT FUNCTION END IF NEXT getfilepath$ = "" END FUNCTION FUNCTION eleucase$ (a$) 'this function upper-cases all elements except for quoted strings 'check first element IF LEN(a$) = 0 THEN EXIT FUNCTION i = 1 IF ASC(a$) = 34 THEN i2 = INSTR(a$, sp) IF i2 = 0 THEN eleucase$ = a$: EXIT FUNCTION a2$ = LEFT$(a$, i2 - 1) i = i2 END IF 'check other elements sp34$ = sp + CHR$(34) IF i < LEN(a$) THEN DO WHILE INSTR(i, a$, sp34$) i2 = INSTR(i, a$, sp34$) a2$ = a2$ + UCASE$(MID$(a$, i, i2 - i + 1)) 'everything prior including spacer i3 = INSTR(i2 + 1, a$, sp): IF i3 = 0 THEN i3 = LEN(a$) ELSE i3 = i3 - 1 a2$ = a2$ + MID$(a$, i2 + 1, i3 - (i2 + 1) + 1) 'everything from " to before next spacer or end i = i3 + 1 IF i > LEN(a$) THEN EXIT DO LOOP END IF a2$ = a2$ + UCASE$(MID$(a$, i, LEN(a$) - i + 1)) eleucase$ = a2$ END FUNCTION 'NEW IDE SPECIFIC '------------------------------ IDE MODULE ------------------------------ DEFSNG A-Z SUB getxymouse STATIC oldmousex, oldmousey, oldmousebutton1 mousewheel = 0 DO WHILE _MOUSEINPUT mousex = _MOUSEX mousey = _MOUSEY IF _MOUSEBUTTON(1) THEN mousebutton1 = 1 ELSE mousebutton1 = 0 mousewheel = mousewheel + _MOUSEWHEEL IF mousex <> oldmousex OR mousey <> oldmousey THEN IF mousebutton1 THEN change = 1 END IF IF oldmousebutton1 <> mousebutton1 THEN change = 1 IF mousewheel THEN change = 1 oldmousex = mousex oldmousey = mousey oldmousebutton1 = mousebutton1 IF change = 1 THEN EXIT SUB LOOP END SUB DEFLNG A-Z 'DIM SHARED idecommand AS STRING 'DIM SHARED idereturn AS STRING 'DIM SHARED ideerror AS LONG 'DIM SHARED idecompiled AS LONG 'DIM SHARED idemode '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 'the function ?=ide(?) should always be passed 0, it returns a message code number, any further information '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] FUNCTION ide (ignore) 'Note: ide is a function which optimizes the interaction between the IDE and compiler (ide2) ' by avoiding unnecessary bloat associated with entering the main IDE function 'ide2' IF ASC(idecommand$) = 3 THEN 'request next line (compiler->ide) IF idecompiledline < iden THEN IF idecompiledline < idesy OR idecompiledline > idesy + (idewy - 9) THEN 'off screen? IF _EXIT AND 1 THEN ideexit = 1 IF ideexit = 0 THEN GetInput 'check for new input IF iCHANGED = 0 AND mB = 0 THEN '-------------------- layout considerations -------------------- 'previous line was OK, so use layout if available IF ideautolayout <> 0 OR ideautoindent <> 0 THEN IF LEN(layout$) THEN 'calculate recommended indent level l = LEN(layout$) FOR i = 1 TO l IF ASC(layout$, i) <> 32 OR i = l THEN IF ASC(layout$, i) = 32 THEN layout$ = "": indent = i ELSE indent = i - 1 layout$ = RIGHT$(layout$, LEN(layout$) - i + 1) END IF EXIT FOR END IF NEXT IF ideautolayout THEN layout2$ = layout$: i2 = 1 ignoresp = 0 FOR i = 1 TO LEN(layout$) a = ASC(layout$, i) IF a = 34 THEN ignoresp = ignoresp + 1: IF ignoresp = 2 THEN ignoresp = 0 END IF IF ignoresp = 0 THEN IF a = sp_asc THEN ASC(layout2$, i2) = 32: i2 = i2 + 1: GOTO skipchar IF a = sp2_asc THEN GOTO skipchar END IF ASC(layout2$, i2) = a: i2 = i2 + 1 skipchar: NEXT layout$ = LEFT$(layout2$, i2 - 1) END IF IF ideautoindent = 0 THEN 'note: can assume auto-format 'calculate old indent (if any) indent = 0 l = LEN(idecompiledline$) FOR i = 1 TO l IF ASC(idecompiledline$, i) <> 32 OR i = l THEN indent = i - 1 EXIT FOR END IF NEXT indent$ = SPACE$(indent) ELSE indent$ = SPACE$(indent * ideautoindentsize) END IF IF ideautolayout = 0 THEN 'note: can assume auto-indent l = LEN(idecompiledline$) layout$ = "" FOR i = 1 TO l IF ASC(idecompiledline$, i) <> 32 OR i = l THEN layout$ = RIGHT$(idecompiledline$, l - i + 1) EXIT FOR END IF NEXT END IF IF LEN(layout$) THEN layout$ = indent$ + layout$ IF idecompiledline$ <> layout$ THEN idesetline idecompiledline, layout$ END IF END IF 'len(layout$) after modification END IF 'len(layout$) END IF 'using layout/indent '--------------------------------------------------------------- idecompiledline = idecompiledline + 1 idecompiledline$ = idegetline(idecompiledline) ide = 4 idereturn$ = idecompiledline$ EXIT FUNCTION END IF IF iCHANGED THEN iCHECKLATER = 1 END IF 'ideexit END IF 'not on screen END IF 'idecompiledline 0 THEN menu$(m, i) = "#Update...": i = i + 1 END IF menu$(m, i) = "#Backup/Undo...": i = i + 1 menu$(m, i) = "-": i = i + 1 menu$(m, i) = "#Advanced...": i = i + 1 menu$(m, i) = "-": i = i + 1 menu$(m, i) = "#Google Android...": i = i + 1 menusize(m) = i - 1 m = m + 1: i = 0 menu$(m, i) = "Help": i = i + 1 menu$(m, i) = "#View Shift+F1": i = i + 1 menu$(m, i) = "#Contents page": i = i + 1 menu$(m, i) = "Keyword #index": i = i + 1 menu$(m, i) = "#Keywords by usage": i = i + 1 menu$(m, i) = "ASCII c#hart": i = i + 1 menu$(m, i) = "#Math": i = i + 1 menu$(m, i) = "-": i = i + 1 menu$(m, i) = "#Update current page": i = i + 1 menu$(m, i) = "Update all #pages": i = i + 1 menu$(m, i) = "-": i = i + 1 menu$(m, i) = "#About...": i = i + 1 menusize(m) = i - 1 menus = m IF os$ = "WIN" THEN idepathsep$ = "\" END IF IF os$ = "LNX" THEN idepathsep$ = "/" END IF initmouse a$ = "QWERTYUIOP????ASDFGHJKL?????ZXCVBNM": x = 16: FOR i = 1 TO LEN(a$): idealtcode(ASC(MID$(a$, i, 1))) = x: x = x + 1: NEXT ideroot$ = idezgetroot$ idepath$ = ideroot$ 'new blank text field idet$ = MKL$(0) + MKL$(0): idel = 1: ideli = 1: iden = 1: IdeBmkN = 0 ideunsaved = -1 idechangemade = 1 redraweverything: idesx = 1 idesy = 1 idecx = 1 idecy = 1 redraweverything2: menubar$ = " " FOR i = 1 TO menus - 1 menubar$ = menubar$ + menu$(i, 0) + " " NEXT menubar$ = menubar$ + SPACE$(idewx - LEN(menubar$) - LEN(menu$(i, 0)) - 2) menubar$ = menubar$ + menu$(i, 0) + " " SCREEN , , 3, 0 VIEW PRINT 1 TO idewy + idesubwindow 'VIEW PRINT 1 TO _HEIGHT(0) LOCATE , , , 8, 8 'static background COLOR 0, 7: LOCATE 1, 1: PRINT menubar$; COLOR 7, 1: idebox 1, 2, idewx, idewy - 5 COLOR 7, 1: idebox 1, idewy - 4, idewx, 5 'edit corners COLOR 7, 1: LOCATE idewy - 4, 1: PRINT "Ã";: LOCATE idewy - 4, idewx: PRINT "´"; IF idehelp = 1 THEN COLOR 7, 0: idebox 1, idewy, idewx, idesubwindow + 1 COLOR 7, 0: LOCATE idewy, 1: PRINT "Ã";: LOCATE idewy, idewx: PRINT "´"; COLOR 7, 0: LOCATE idewy, idewx - 3: PRINT "´XÃ"; END IF 'add status title COLOR 7, 1: LOCATE idewy - 4, (idewx - 8) / 2: PRINT " Status " 'status bar COLOR 0, 3: LOCATE idewy + idesubwindow, 1: PRINT SPACE$(idewx); q = idevbar(idewx, idewy - 3, 3, 1, 1) q = idevbar(idewx, 3, idewy - 8, 1, 1) q = idehbar(2, idewy - 5, idewx - 2, 1, 1) DEF SEG = 0 ideshowtext IF retval = 1 THEN GOTO skipload 'restore autosave? 'undo/redo OPEN tmpdir$ + "autosave.bin" FOR BINARY AS #150 IF LOF(150) = 1 THEN CLOSE #150 r$ = iderestore$ PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF r$ = "Y" THEN 'restore OPEN tmpdir$ + "undo2.bin" FOR BINARY AS #150 IF LOF(150) THEN ideunsaved = 1 h$ = SPACE$(12): GET #150, , h$: p1 = CVL(MID$(h$, 1, 4)): p2 = CVL(MID$(h$, 5, 4)): plast = CVL(MID$(h$, 9, 4)) 'get backup SEEK #150, p2 GET #150, , l& GET #150, , idesx: GET #150, , idesy GET #150, , idecx: GET #150, , idecy GET #150, , ideselect: GET #150, , ideselectx1: GET #150, , ideselecty1 GET #150, , iden GET #150, , idel GET #150, , ideli 'bookmark info [v2] GET #150, , IdeBmkN: REDIM IdeBmk(IdeBmkN + 1) AS IdeBmkType FOR bi = 1 TO IdeBmkN: GET #150, , IdeBmk(bi).y: GET #150, , IdeBmk(bi).x: NEXT GET #150, , x&: idet$ = SPACE$(x&): GET #150, , idet$ END IF CLOSE #150 END IF ELSE CLOSE #150 END IF IF ideunsaved <> 1 THEN 'no file restored (takes priority over loading file from command line) IF LEFT$(c$, 1) = CHR$(1) THEN 'load file f$ = RIGHT$(c$, LEN(c$) - 1) IF FileHasExtension(f$) = 0 THEN f$ = f$ + ".bas" path$ = idezgetfilepath$(ideroot$, f$) '(copied from ideopen) ideerror = 2 OPEN path$ + idepathsep$ + f$ FOR INPUT AS #150: CLOSE #150 ideerror = 3 idepath$ = path$ lineinput3load path$ + idepathsep$ + f$ idet$ = SPACE$(LEN(lineinput3buffer) * 8) i2 = 1 n = 0 chrtab$ = CHR$(9) space1$ = " ": space2$ = " ": space3$ = " ": space4$ = " " chr7$ = CHR$(7): chr11$ = CHR$(11): chr12$ = CHR$(12): chr28$ = CHR$(28): chr29$ = CHR$(29): chr30$ = CHR$(30): chr31$ = CHR$(31) DO a$ = lineinput3$ l = LEN(a$) IF l THEN asca = ASC(a$) ELSE asca = -1 IF asca <> 13 THEN IF asca <> -1 THEN 'fix tabs ideopenfixtabsx: x = INSTR(a$, chrtab$) IF x THEN x2 = (x - 1) MOD 4 IF x2 = 0 THEN a$ = LEFT$(a$, x - 1) + space4$ + RIGHT$(a$, l - x): l = l + 3: GOTO ideopenfixtabsx IF x2 = 1 THEN a$ = LEFT$(a$, x - 1) + space3$ + RIGHT$(a$, l - x): l = l + 2: GOTO ideopenfixtabsx IF x2 = 2 THEN a$ = LEFT$(a$, x - 1) + space2$ + RIGHT$(a$, l - x): l = l + 1: GOTO ideopenfixtabsx IF x2 = 3 THEN a$ = LEFT$(a$, x - 1) + space1$ + RIGHT$(a$, l - x): GOTO ideopenfixtabsx END IF END IF 'asca<>-1 MID$(idet$, i2, l + 8) = MKL$(l) + a$ + MKL$(l): i2 = i2 + l + 8: n = n + 1 END IF LOOP UNTIL asca = 13 lineinput3buffer = "" iden = n: IF n = 0 THEN idet$ = MKL$(0) + MKL$(0): iden = 1 ELSE idet$ = LEFT$(idet$, i2 - 1) IdeBmkN = 0 ideerror = 1 ideprogname = f$: _TITLE ideprogname + " - QB64" IdeImportBookmarks idepath$ + idepathsep$ + ideprogname$ IdeAddRecent idepath$ + idepathsep$ + ideprogname$ END IF 'message 1 END IF 'no restore skipload: END IF 'idelaunched IF c$ = CHR$(3) THEN skipdisplay = 1 'assume .../starting already displayed sendnextline = 1 'previous line was OK, so use layout if available IF ideautolayout = 0 AND ideautoindent = 0 THEN layout$ = "" idelayoutallow = 0 ELSE IF LEN(layout$) THEN 'calculate recommended indent level FOR i = 1 TO LEN(layout$) IF ASC(layout$, i) <> 32 OR i = LEN(layout$) THEN indent = i - 1 layout$ = RIGHT$(layout$, LEN(layout$) - i + 1) EXIT FOR END IF NEXT IF ideautolayout THEN spacelayout: ignoresp = 0 FOR i = 1 TO LEN(layout$) IF ASC(layout$, i) = 34 THEN ignoresp = ignoresp + 1: IF ignoresp = 2 THEN ignoresp = 0 END IF IF ignoresp = 0 THEN IF MID$(layout$, i, 1) = sp THEN MID$(layout$, i, 1) = " " IF MID$(layout$, i, 1) = sp2 THEN layout$ = LEFT$(layout$, i - 1) + RIGHT$(layout$, LEN(layout$) - i): GOTO spacelayout END IF NEXT END IF IF ideautoindent = 0 THEN 'note: can assume auto-format 'calculate old indent (if any) a$ = idecompiledline$ indent = 0 FOR i = 1 TO LEN(a$) IF ASC(a$, i) <> 32 OR i = LEN(a$) THEN indent = i - 1 EXIT FOR END IF NEXT indent$ = SPACE$(indent) ELSE indent$ = SPACE$(indent * ideautoindentsize) END IF IF ideautolayout = 0 THEN 'note: can assume auto-indent a$ = idecompiledline$ layout$ = "" FOR i = 1 TO LEN(a$) IF ASC(a$, i) <> 32 OR i = LEN(a$) THEN layout$ = RIGHT$(a$, LEN(a$) - i + 1) EXIT FOR END IF NEXT END IF layout$ = indent$ + layout$ IF idecy <> idecompiledline OR idelayoutallow <> 0 THEN idelayoutallow = 0 IF idecompiledline$ <> layout$ THEN idesetline idecompiledline, layout$ IF idecompiledline >= idesy AND idecompiledline <= (idesy + 16) THEN skipdisplay = 0 END IF ELSE IF idecompiledline$ <> layout$ THEN idecurrentlinelayout = layout$ idecurrentlinelayouti = idecy END IF END IF END IF 'len(layout$) END IF 'using layout/indent END IF '3 IF c$ = CHR$(6) THEN idecompiling = 0 ready = 1 IF ideautorun THEN ideautorun = 0: GOTO idemrunspecial END IF IF c$ = CHR$(11) THEN idecompiling = 0 ready = 1 ideautorun = 0 showexecreated = 1 END IF IF c$ = CHR$(7) THEN skipdisplay = 1 'assume .../starting already displayed idecompiledline = 0 sendnextline = 1 END IF IF LEFT$(c$, 1) = CHR$(8) THEN idecompiling = 0 failed = 1 ideautorun = 0 END IF passback = 0 IF LEFT$(c$, 1) = CHR$(10) THEN 'passback skipdisplay = 1 'assume .../starting already displayed sendnextline = 1 idecompiledline = idecompiledline - 1 passback = 1 passback$ = RIGHT$(c$, LEN(c$) - 1) END IF IF mustdisplay THEN skipdisplay = 0 IF skipdisplay = 0 THEN LOCATE , , 0 'note: menu bar shouldn't need repairing! 'COLOR 0, 7: LOCATE 1, 1: PRINT menubar$; 'repair menu bar IF c$ <> CHR$(3) THEN COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window IF ready THEN LOCATE idewy - 3, 2: PRINT "OK"; 'report OK status IF showexecreated THEN showexecreated = 0 LOCATE idewy - 3, 2 IF MakeAndroid THEN PRINT "Project [programs\android\" + file$ + "] created"; ELSE IF os$ = "LNX" THEN PRINT "Executable file created"; ELSE PRINT ".EXE file created"; END IF END IF END IF END IF END IF 'skipdisplay idefocusline = 0 'main loop DO ideloop: '### STEVE WAS HERE 10/11/2013 ### IF _RESIZE THEN f = FREEFILE OPEN ".\internal\temp\options.bin" FOR BINARY AS #f v% = _RESIZEWIDTH \ _FONTWIDTH: IF v% < 80 OR v% > 1000 THEN v% = 80 IF v% <> idewx THEN retval = 1: idewx = v% PUT #f, 7, v% v% = _RESIZEHEIGHT \ _FONTHEIGHT: IF v% < 25 OR v% > 1000 THEN v% = 25 IF v% <> idewy THEN retval = 1: idewy = v% PUT #f, 9, v% CLOSE #f IF retval = 1 THEN 'screen dimensions have changed and everything must be redrawn/reapplied WIDTH idewx, idewy + idesubwindow GOTO redraweverything END IF END IF '### END OF STEVE EDIT idedeltxt 'removes temporary strings (typically created by guibox commands) by setting an index to 0 IF skipdisplay = 0 THEN LOCATE , , 0 'update title of main window COLOR 7, 1: LOCATE 2, 2: PRINT STRING$(idewx - 2, "Ä"); IF LEN(ideprogname) THEN a$ = ideprogname ELSE a$ = "Untitled" + tempfolderindexstr$ a$ = " " + a$ + " " COLOR 1, 7: LOCATE 2, ((idewx / 2) - 1) - (LEN(a$) - 1) \ 2: PRINT a$; 'update search bar LOCATE 2, idewx - 30 COLOR 7, 1: PRINT "´"; COLOR 3, 1: PRINT "Find[ ]"; COLOR 7, 1: PRINT "Ã"; f$ = idefindtext IF LEN(f$) > 20 THEN f$ = "úúú" + RIGHT$(f$, 17) END IF LOCATE 2, idewx - 28 + 4: COLOR 3, 1: PRINT f$ findtext$ = f$ 'alter cursor style to match insert mode IF ideinsert THEN LOCATE , , , 0, 31 ELSE LOCATE , , , 8, 8 'display error message (if necessary) IF failed THEN COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window 'scrolling unavailable, but may span multiple lines a$ = MID$(c$, 2, LEN(c$) - 5) l = CVL(RIGHT$(c$, 4)): IF l <> 0 THEN idefocusline = l x = 1 y = idewy - 3 IF l <> 0 AND idecy = l THEN a$ = a$ + " on current line" FOR i = 1 TO LEN(a$) x = x + 1: IF x = idewx THEN x = 2: y = y + 1 IF y > idewy - 1 THEN EXIT FOR LOCATE y, x PRINT CHR$(ASC(a$, i)); NEXT IF l <> 0 AND idecy <> l THEN a$ = " on line" + STR$(l) COLOR 11, 1 FOR i = 1 TO LEN(a$) x = x + 1: IF x = idewx THEN x = 2: y = y + 1 IF y > idewy - 1 THEN EXIT FOR LOCATE y, x PRINT CHR$(ASC(a$, i)); NEXT END IF END IF IF idechangemade THEN COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window LOCATE idewy - 3, 2: PRINT "..."; 'assume new compilation will begin END IF ideshowtext IF idehelp THEN Help_ShowText q = idehbar(2, idewy + idesubwindow - 1, idewx - 2, Help_cx, help_w + 1) q = idevbar(idewx, idewy + 1, idesubwindow - 2, Help_cy, help_h + 1) 'COLOR 0, 7: LOCATE idewy, (idewx - 6) / 2: PRINT " Help " 'create and draw back string Back_Str$ = STRING$(1000, 0) Back_Str_I$ = STRING$(4000, 0) top = UBOUND(back$) FOR x = 1 TO top n$ = Back_Name$(x) IF x = Help_Back_Pos THEN p = LEN(Back_Str$) Back_Str$ = Back_Str$ + " " Back_Str_I$ = Back_Str_I$ + MKL$(x) FOR x2 = 1 TO LEN(n$) Back_Str$ = Back_Str$ + CHR$(ASC(n$, x2)) Back_Str_I$ = Back_Str_I$ + MKL$(x) NEXT Back_Str$ = Back_Str$ + " " Back_Str_I$ = Back_Str_I$ + MKL$(x) IF x <> top THEN Back_Str$ = Back_Str$ + CHR$(0) Back_Str_I$ = Back_Str_I$ + MKL$(0) END IF NEXT Back_Str$ = Back_Str$ + STRING$(1000, 0) Back_Str_I$ = Back_Str_I$ + STRING$(4000, 0) Back_Str_Pos = p - idewx \ 2 + (LEN(Back_Name$(Help_Back_Pos)) + 2) \ 2 + 3 'COLOR 1, 2 'LOCATE idewy, 2: PRINT MID$(Back_Str$, Back_Str_Pos, idewx - 5) LOCATE idewy, 2 FOR x = Back_Str_Pos TO Back_Str_Pos + idewx - 6 i = CVL(MID$(Back_Str_I$, (x - 1) * 4 + 1, 4)) a = ASC(Back_Str$, x) IF a THEN COLOR 0, 7 IF i < Help_Back_Pos THEN COLOR 9, 7 IF i > Help_Back_Pos THEN COLOR 9, 7 PRINT CHR$(a); ELSE COLOR 7, 0 PRINT "Ä"; END IF NEXT 'Help_Search_Str a$ = "" IF LEN(Help_Search_Str) THEN a$ = Help_Search_Str IF LEN(a$) > 20 THEN a$ = "úúú" + RIGHT$(a$, 17) a$ = "[" + a$ + "](DELETE=next)" END IF IdeInfo$ = a$ END IF IF IdeSystem = 2 THEN 'override cursor position SCREEN , , 0, 0 LOCATE 2, idewx - 28 + 4 + LEN(findtext$) SCREEN , , 3, 0 END IF IF IdeSystem = 3 THEN 'override cursor position SCREEN , , 0, 0 _PALETTECOLOR 2, _RGB32(24, 24, 24) LOCATE Help_cy - Help_sy + Help_wy1, Help_cx - Help_sx + Help_wx1 SCREEN , , 3, 0 END IF IF IdeSystem <> 3 THEN IdeInfo$ = "" 'show info message (if any) a$ = IdeInfo$ IF LEN(a$) > 60 THEN a$ = LEFT$(a$, 57) + "úúú" IF LEN(a$) < 60 THEN a$ = a$ + SPACE$(60 - LEN(a$)) COLOR 0, 3: LOCATE idewy + idesubwindow, 2 PRINT a$; LOCATE , , 1 PCOPY 3, 0 END IF 'skipdisplay IF idechangemade THEN IF idelayoutallow THEN idelayoutallow = idelayoutallow - 1 idecurrentlinelayouti = 0 'invalidate idechangemade = 0 IF ideunsaved = -1 THEN ideunsaved = 0 ELSE ideunsaved = 1 IF idenoundo = 0 THEN 'undo/redo 'build data so it can be written in a single write (a backup requirement) a$ = "" a$ = a$ + MKL$(idesx) + MKL$(idesy) 'screen position a$ = a$ + MKL$(idecx) + MKL$(idecy) 'cursor position a$ = a$ + MKL$(ideselect) + MKL$(ideselectx1) + MKL$(ideselecty1) 'selection state & position a$ = a$ + MKL$(iden) 'number of lines a$ = a$ + MKL$(idel) 'selected line in buffer a$ = a$ + MKL$(ideli) 'selected line offset in buffer 'bookmark info [v2] a$ = a$ + MKL$(IdeBmkN) FOR bi = 1 TO IdeBmkN: a$ = a$ + MKL$(IdeBmk(bi).y) + MKL$(IdeBmk(bi).x): NEXT l& = LEN(idet$) a$ = a$ + MKL$(l&) 'data size a$ = MKL$(l& + LEN(a$)) + a$ + idet$ + MKL$(l& + LEN(a$)) 'header, data & encapsulation (reverse navigatable list) 'add undo event OPEN tmpdir$ + "undo2.bin" FOR BINARY AS #150 '[oldest state entry][newest state entry][top-most entry(ignore if no wrapping required)] h$ = SPACE$(12): GET #150, , h$: p1 = CVL(MID$(h$, 1, 4)): p2 = CVL(MID$(h$, 5, 4)): plast = CVL(MID$(h$, 9, 4)) IF idemergeundo THEN idemergeundo = 0 IF p2 <> p1 THEN 'can it be moved back? IF p2 = 13 THEN p2 = plast ELSE 'get offset of previous message GET #150, p2 - 4, pp2l p2 = p2 - 4 - pp2l - 4 END IF END IF END IF IF p1 = 0 THEN 'not init p1 = 13: p2 = 13 ELSE IF p2 >= p1 THEN 'no wrap 'should we extend? IF p2 >= idebackupsize * 1000000 THEN 'can't extend 'set p2 as top-most plast = p2 p2 = 13 'can new state (a$) fit before p1? DO WHILE (p2 + LEN(a$) - 1) >= p1 IF p1 = ideundobase THEN ideundobase = -1 'no, so move p1 to next entry 'note: it can be assumed that p1, being near/at beginning, won't have to wrap when being moved forward GET #150, p1, p1l p1 = p1 + 4 + p1l + 4 LOOP 'p1 & p2 ready ELSE 'extend 'find size of p2 event GET #150, p2, p2l p2 = p2 + 4 + p2l + 4 'p1 & p2 ready END IF ELSE 'wrap 'find size of p2 event GET #150, p2, p2l op2 = p2 p2 = p2 + 4 + p2l + 4 'can new state (a$) fit before p1? DO WHILE (p2 + LEN(a$) - 1) >= p1 IF p1 = ideundobase THEN ideundobase = -1 'no, so move p1 to next entry IF p1 = plast THEN p1 = 13 EXIT DO ELSE GET #150, p1, p1l p1 = p1 + 4 + p1l + 4 END IF LOOP 'should we extend? IF p2 >= idebackupsize * 1000000 THEN 'can't extend 'set op2 as top-most plast = op2 p2 = 13 'can new state (a$) fit before p1? DO WHILE (p2 + LEN(a$) - 1) >= p1 IF p1 = ideundobase THEN ideundobase = -1 'no, so move p1 to next entry 'note: it can be assumed that p1, being near/at beginning, won't have to wrap when being moved forward GET #150, p1, p1l p1 = p1 + 4 + p1l + 4 LOOP END IF 'p1 & p2 ready END IF END IF 'update p1,p2,plast h$ = MKL$(p1) + MKL$(p2) + MKL$(plast) PUT #150, 1, h$ 'add new state PUT #150, p2, a$ CLOSE #150 ideundopos = p2 IF ideundobase = 0 THEN ideundobase = ideundopos 'set undo flag once IF ideundoflag = 0 THEN ideundoflag = 1 OPEN tmpdir$ + "autosave.bin" FOR BINARY AS #150: a$ = CHR$(1): PUT #150, , a$: CLOSE #150 'set flag END IF ELSE idenoundo = 0 END IF 'begin new compilation IF IDEBuildModeChanged = 0 THEN ideautorun = 0 END IF IDEBuildModeChanged = 0 IF MakeAndroid THEN 'Cleanup excess files in temp folder SHELL _HIDE "cmd /c del /q " + tmpdir$ + "ret*.txt " + tmpdir$ + "data*.txt " + tmpdir$ + "free*.txt" END IF idecompiling = 1 ide2 = 2 idecompiledline$ = idegetline(1) idereturn$ = idecompiledline$ idecompiledline = 1 EXIT FUNCTION END IF 'idechangemade change = 0 waitforinput: IF idecurrentlinelayouti THEN IF idecy <> idecurrentlinelayouti THEN idesetline idecurrentlinelayouti, idecurrentlinelayout$ idecurrentlinelayouti = 0 change = 1 'simulate a change to force a screen update END IF END IF exitvalue = _EXIT IF (exitvalue AND 1) <> 0 OR ideexit <> 0 THEN ideexit = 0: GOTO quickexit IF UpdateHandle THEN ContinueDownloads IF DL(UpdateHandle).State = 2 THEN 'download complete update 0 UpdateHandle = 0 change = 1 'simulate a change to force a screen update ELSE IF ABS(TIMER - ideupdatetimerval) >= 5 THEN 'give up after 5 seconds CLOSE DL(UpdateHandle).Handle: DL(UpdateHandle).State = 0: UpdateHandle = 0 END IF END IF END IF GetInput IF iCHANGED THEN IF (mX <> mox OR mY <> moy) AND mB <> 0 THEN change = 1 'dragging mouse IF mB <> mOB THEN change = 1 'button changed IF mB2 <> mOB2 THEN change = 1 'button changed IF mCLICK <> 0 OR mCLICK2 <> 0 THEN change = 1 IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF KSTATECHANGED THEN change = 1 END IF IF mB <> 0 AND idembmonitor = 1 THEN change = 1 IF mB = 0 THEN idemouseselect = 0: idembmonitor = 0 IF KALT THEN 'alt held IF idealthighlight = 0 AND KALTPRESS = -1 THEN 'highlist first letter of each menu item idealthighlight = 1 LOCATE , , 0: COLOR 15, 7: x = 4 FOR i = 1 TO menus LOCATE 1, x: PRINT LEFT$(menu$(i, 0), 1); x = x + LEN(menu$(i, 0)) + 2 IF i = menus - 1 THEN x = idewx - LEN(menu$(menus, 0)) - 1 NEXT ideentermenu = 1 'alt has just been pressed, so any next keystroke could enter a menu) 'IF change = 0 THEN skipdisplay = 0: GOTO ideloop 'force update so cursor will be restored to correct position END IF ELSE 'alt not held IF idealthighlight = 1 THEN 'remove highlight idealthighlight = 0 LOCATE , , 0: COLOR 0, 7: LOCATE 1, 1: PRINT menubar$; IF ideentermenu = 1 AND KCONTROL = 0 THEN 'alt was pressed then released LOCATE , , , 8, 8: skipdisplay = 0: ideentermenu = 0: GOTO startmenu END IF END IF END IF 'alt not held IF change = 0 THEN 'continue compilation? IF idecompiling THEN IF sendnextline THEN IF idecompiledline < iden THEN idecompiledline = idecompiledline + 1 ide2 = 4 IF passback THEN idecompiledline$ = passback$ idereturn$ = idecompiledline$ ELSE idecompiledline$ = idegetline(idecompiledline) idereturn$ = idecompiledline$ END IF EXIT FUNCTION ELSE 'finished compilation ide2 = 5 'end of program reached, what next? 'could return: 'i) 6 code ready for export/run 'ii) 7 repass required (if so send data from the beginning again) EXIT FUNCTION END IF END IF END IF _LIMIT 16 GOTO waitforinput END IF 'change=0 ideentermenu = 0 ideundocombo = ideundocombo - 1 IF ideundocombo < 0 THEN ideundocombo = 0 skipdisplay = 0 'IdeSystem independent routines IF mCLICK THEN IF mX >= 2 AND mX <= idewx AND mY >= idewy - 3 AND mY <= idewy - 1 THEN IF SCREEN(mY, mX, 1) = 11 + 1 * 16 THEN IF idefocusline THEN idecx = 1: idecy = idefocusline: ideselect = 0: GOTO specialchar END IF END IF END IF IF KB = KEY_F5 AND KCTRL THEN 'run detached UseAndroid 0 idemdetached: iderunmode = 1 GOTO idemrunspecial END IF IF KB = KEY_F11 THEN 'make exe only UseAndroid 0 idemexe: iderunmode = 2 GOTO idemrunspecial END IF IF KB = KEY_F5 THEN 'Note: F5 or SHIFT+F5 accepted UseAndroid 0 idemrun: iderunmode = 0 'standard run idemrunspecial: 'run program IF ready <> 0 AND idechangemade = 0 THEN LOCATE , , 0 COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window IF idecompiled THEN IF iderunmode = 2 THEN LOCATE idewy - 3, 2 IF os$ = "LNX" THEN PRINT "Already created executable file!"; ELSE PRINT "Already created .EXE file!"; END IF GOTO specialchar END IF LOCATE idewy - 3, 2: PRINT "Starting program..."; ELSE IF os$ = "LNX" THEN LOCATE idewy - 3, 2: PRINT "Creating executable file..."; ELSE LOCATE idewy - 3, 2: PRINT "Creating .EXE file..."; END IF END IF PCOPY 3, 0 'send run request 'prepare name IF ideprogname$ = "" THEN f$ = "untitled" + tempfolderindexstr$ ELSE f$ = ideprogname$ f$ = RemoveFileExtension$(f$) END IF ide2 = 9: idereturn$ = f$ EXIT FUNCTION END IF 'not ready! IF failed = 1 THEN GOTO specialchar 'assume still compiling ... ideautorun = 1 'correct status message LOCATE , , 0 COLOR 7, 1: LOCATE idewy - 3, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 2, 2: PRINT SPACE$(idewx - 2);: LOCATE idewy - 1, 2: PRINT SPACE$(idewx - 2); 'clear status window LOCATE idewy - 3, 2: PRINT "Checking program... (editing program will cancel request)"; 'must move the cursor back to its correct location ideshowtext LOCATE , , 1 PCOPY 3, 0 GOTO specialchar END IF LOCATE , , 0 LOCATE , , , 8, 8 IF mCLICK AND idemouseselect = 0 THEN IF mY = 1 THEN x = 3 FOR i = 1 TO menus x2 = LEN(menu$(i, 0)) + 2 IF mX >= x AND mX < x + x2 THEN m = i GOTO showmenu END IF x = x + x2 IF i = menus - 1 THEN x = idewx - LEN(menu$(menus, 0)) - 2 NEXT END IF END IF FOR i = 1 TO menus a$ = UCASE$(LEFT$(menu$(i, 0), 1)) IF KALT AND UCASE$(K$) = a$ THEN m = i LOCATE 1, 1: COLOR 0, 7: PRINT menubar$; PCOPY 3, 0 GOTO showmenu END IF NEXT IF KB = KEY_F3 THEN IF IdeSystem = 3 THEN IdeSystem = 1 idemf3: IF idefindtext$ <> "" THEN IF KSHIFT THEN idefindinvert = 1 IdeAddSearched idefindtext idefindagain ELSE GOTO idefindjmp END IF GOTO specialchar END IF IF KSHIFT AND KB = KEY_F1 THEN IF idehelp = 0 THEN idesubwindow = idewy \ 2: idewy = idewy - idesubwindow Help_wx1 = 2: Help_wy1 = idewy + 1: Help_wx2 = idewx - 1: Help_wy2 = idewy + idesubwindow - 2: Help_ww = Help_wx2 - Help_wx1 + 1: Help_wh = Help_wy2 - Help_wy1 + 1 idehelp = 1 skipdisplay = 0 IdeSystem = 3 retval = 1: GOTO redraweverything2 END IF IdeSystem = 3 GOTO specialchar END IF 'Scroll bar code goes here STATIC Help_Scrollbar, Help_Scrollbar_Method '1=arrow less, 2=arrow more, 3=dragging 'bit', 4=clicking in space IF mB = 0 THEN Help_Scrollbar = 0 IF idehelp THEN IF IdeSystem = 3 THEN 'q = idehbar(2, idewy + idesubwindow - 1, idewx - 2, Help_cx, help_w + 1) 'q = idevbar(idewx, idewy + 1, idesubwindow - 2, Help_cy, help_h + 1) IF mCLICK THEN IF mX >= 2 AND mX <= idewx - 1 AND mY = idewy + idesubwindow - 1 THEN Help_Scrollbar = 1 v = idehbar(2, idewy + idesubwindow - 1, idewx - 2, Help_cx, help_w + 1) IF v <> mX THEN Help_Scrollbar_Method = 3 ELSE Help_Scrollbar_Method = 4 IF mX = 2 THEN Help_Scrollbar_Method = 1 IF mX = idewx - 1 THEN Help_Scrollbar_Method = 2 END IF IF mY >= idewy + 1 AND mY <= idewy + idesubwindow - 2 AND mX = idewx THEN Help_Scrollbar = 2 v = idevbar(idewx, idewy + 1, idesubwindow - 2, Help_cy, help_h + 1) IF v <> mY THEN Help_Scrollbar_Method = 3 ELSE Help_Scrollbar_Method = 4 IF mY = idewy + 1 THEN Help_Scrollbar_Method = 1 IF mY = idewy + idesubwindow - 2 THEN Help_Scrollbar_Method = 2 END IF END IF 'mclick IF Help_Scrollbar THEN idembmonitor = 1 IF Help_Scrollbar_Method = 1 THEN IF Help_Scrollbar = 1 THEN KB = KEY_LEFT: idewait 'fall through... IF Help_Scrollbar = 2 THEN KB = KEY_UP: idewait 'fall through... END IF IF Help_Scrollbar_Method = 2 THEN IF Help_Scrollbar = 1 THEN KB = KEY_RIGHT: idewait 'fall through... IF Help_Scrollbar = 2 THEN KB = KEY_DOWN: idewait 'fall through... END IF IF Help_Scrollbar_Method = 3 THEN IF Help_Scrollbar = 1 THEN v = idehbar(2, idewy + idesubwindow - 1, idewx - 2, Help_cx, help_w + 1) IF mX < v THEN Help_cx = Help_cx - 8 IF Help_cx < 1 THEN Help_cx = 1 IF Help_sx > Help_cx THEN Help_sx = Help_cx idewait END IF IF mX > v THEN Help_cx = Help_cx + 8 IF Help_cx > help_w + 1 THEN Help_cx = help_w + 1 idewait END IF END IF IF Help_Scrollbar = 2 THEN v = idevbar(idewx, idewy + 1, idesubwindow - 2, Help_cy, help_h + 1) IF mY < v THEN KB = KEY_PAGEUP: idewait 'fall through... IF mY > v THEN KB = KEY_PAGEDOWN: idewait 'fall through... END IF END IF IF Help_Scrollbar_Method = 4 THEN IF Help_Scrollbar = 1 THEN IF help_w > 1 THEN IF mX <= 3 THEN Help_sx = 1: Help_cx = 1 ELSEIF mX >= idewx - 2 THEN Help_sx = help_w + 1: Help_cx = help_w + 1 ELSE x = mX p! = x - 4 + .5 '4 (the min pos) becomes .5 p! = p! / (idewx - 3 - 3) i = p! * (help_w) + 1 Help_sx = i: Help_cx = i END IF END IF END IF IF Help_Scrollbar = 2 THEN IF help_h > 1 THEN IF mY <= idewy + 2 THEN Help_cy = 1 ELSEIF mY >= idewy + idesubwindow - 3 THEN Help_cy = help_h + 1 ELSE y = mY p! = y - idewy - 3 + .5 p! = p! / (idesubwindow - 3 - 3) i = p! * (help_h) + 1 Help_cy = i END IF 'fix cursor IF Help_cx < 1 THEN Help_cx = 1 IF Help_cx > help_w + 1 THEN Help_cx = help_w + 1 IF Help_cy < 1 THEN Help_cy = 1 IF Help_cy > help_h + 1 THEN Help_cy = help_h + 1 'screen follows cursor IF Help_cx < Help_sx THEN Help_sx = Help_cx IF Help_cx >= Help_sx + Help_ww THEN Help_sx = Help_cx - Help_ww + 1 IF Help_cy < Help_sy THEN Help_sy = Help_cy IF Help_cy >= Help_sy + Help_wh THEN Help_sy = Help_cy - Help_wh + 1 'fix screen IF Help_sx < 1 THEN Help_sx = 1 IF Help_sy < 1 THEN Help_sy = 1 END IF END IF END IF 'IF mB AND idemouseselect = 2 THEN ' 'move vbar scroller (idecy) to appropriate position ' IF iden > 1 THEN ' IF mY <= 4 THEN idecy = 1 ' IF mY >= idewy - 7 THEN idecy = iden ' IF mY > 4 AND mY < idewy - 7 THEN ' y = mY ' p! = y - 3 - 2 + .5 ' p! = p! / ((idewy - 8) - 4) ' i = p! * (iden - 1) + 1 ' idecy = i ' END IF ' END IF 'END IF IF mCLICK THEN mCLICK = 0 END IF END IF 'system=3 END IF 'idehelp 'IdeSystem specific code goes here IF mCLICK THEN IF mY = 2 AND mX > idewx - 30 AND mX < idewx - 1 THEN 'inside text box IF mX <= idewx - 28 + 2 THEN IF LEN(idefindtext) = 0 THEN IdeSystem = 2 'no search string, so begin editing ELSE IdeAddSearched idefindtext IdeSystem = 1: GOTO idemf3 'F3 functionality END IF ELSE IF mX = idewx - 3 THEN PCOPY 0, 3 f$ = idesearchedbox IF LEN(f$) THEN idefindtext = f$ PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF LEN(f$) THEN GOTO idemf3 'F3 functionality GOTO ideloop ELSE IF IdeSystem = 2 THEN idefindtext = "" 'clicking on the text field again clears text IdeSystem = 2 END IF END IF END IF END IF 'IdeSystem IF KB = KEY_F6 THEN 'switch windows IF idehelp = 1 THEN IF IdeSystem = 3 THEN IdeSystem = 1 ELSE IdeSystem = 3 END IF END IF END IF IF idehelp = 1 THEN 'switch windows? IF mCLICK THEN IF IdeSystem = 3 THEN IF mY >= 2 AND mY < idewy THEN IdeSystem = 1 END IF ELSE IF mY >= idewy AND mY < idewy + idesubwindow THEN IdeSystem = 3 END IF END IF END IF END IF IF IdeSystem = 2 THEN 'certain keys transfer control z = 0 IF KB = KEY_UP THEN z = 1 IF KB = KEY_DOWN THEN z = 1 IF KB = KEY_PAGEUP THEN z = 1 IF KB = KEY_PAGEDOWN THEN z = 1 IF mWHEEL THEN z = 1 IF z = 1 THEN IdeSystem = 1 END IF IF IdeSystem = 2 THEN IF (KSHIFT AND KB = KEY_INSERT) OR (KCONTROL AND UCASE$(K$) = "V") THEN 'paste from clipboard clip$ = _CLIPBOARD$ 'read clipboard x = INSTR(clip$, CHR$(13)) IF x THEN clip$ = LEFT$(clip$, x - 1) x = INSTR(clip$, CHR$(10)) IF x THEN clip$ = LEFT$(clip$, x - 1) IF LEN(clip$) THEN idefindtext = clip$ GOTO specialchar END IF END IF IF ((KCTRL AND KB = KEY_INSERT) OR (KCONTROL AND UCASE$(K$) = "C")) THEN 'copy to clipboard IF LEN(idefindtext) THEN _CLIPBOARD$ = idefindtext GOTO specialchar END IF IF LEN(K$) = 1 THEN IF K$ = CHR$(27) THEN IdeSystem = 1 GOTO specialchar END IF IF ASC(K$) = 13 THEN IF LEN(idefindtext) THEN IdeAddSearched idefindtext: GOTO idemf3 'F3 functionality GOTO specialchar END IF IF ASC(K$) = 8 THEN IF LEN(idefindtext) THEN idefindtext = LEFT$(idefindtext, LEN(idefindtext) - 1) GOTO specialchar END IF IF ASC(K$) < 32 THEN GOTO specialchar 'block control characters idefindtext = idefindtext + K$ GOTO specialchar END IF IF mCLICK THEN IF mX > 1 AND mX < idewx AND mY > 2 AND mY < (idewy - 5) THEN 'inside text box IdeSystem = 1 END IF END IF GOTO specialchar END IF IF IdeSystem = 3 THEN IF mCLICK OR K$ = CHR$(27) THEN IF (mY = idewy AND mX = idewx - 2) OR K$ = CHR$(27) THEN 'close help 'IF idesubwindow THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt: GOTO ideloop 'idesubwindow = idewy \ 2: idewy = idewy - idesubwindow idewy = idewy + idesubwindow idehelp = 0 idesubwindow = 0 skipdisplay = 0 IdeSystem = 1 retval = 1: GOTO redraweverything2 END IF END IF IF mCLICK THEN IF mY = idewy THEN sx = 2 FOR x = Back_Str_Pos TO Back_Str_Pos + idewx - 6 IF mX = sx THEN i = CVL(MID$(Back_Str_I$, (x - 1) * 4 + 1, 4)) a = ASC(Back_Str$, x) IF a <> 0 AND i <> Help_Back_Pos THEN Help_Back(Help_Back_Pos).sx = Help_sx 'update position Help_Back(Help_Back_Pos).sy = Help_sy Help_Back(Help_Back_Pos).cx = Help_cx Help_Back(Help_Back_Pos).cy = Help_cy Help_Back_Pos = i Help_Select = 0: Help_MSelect = 0 Help_sx = Help_Back(Help_Back_Pos).sx Help_sy = Help_Back(Help_Back_Pos).sy Help_cx = Help_Back(Help_Back_Pos).cx Help_cy = Help_Back(Help_Back_Pos).cy a$ = Wiki(Back$(Help_Back_Pos)) WikiParse a$ GOTO newpageparsed END IF END IF sx = sx + 1 NEXT 'LOCATE idewy, 2 'FOR x = Back_Str_Pos TO Back_Str_Pos + idewx - 5 ' i = CVL(MID$(Back_Str_I$, (x - 1) * 4 + 1, 4)) ' a = ASC(Back_Str$, x) ' IF a THEN ' COLOR 0, 7 ' IF i < Help_Back_Pos THEN COLOR 9, 7 ' IF i > Help_Back_Pos THEN COLOR 9, 7 ' PRINT CHR$(a); ' ELSE ' COLOR 7, 0 ' PRINT "Ä"; ' END IF 'NEXT END IF END IF IF KCONTROL AND UCASE$(K$) = "A" THEN 'select all IF help_h THEN Help_Select = 2 Help_SelX1 = 1 Help_SelY1 = 1 Help_SelX2 = 10000000 Help_SelY2 = help_h Help_cx = 1: Help_cy = help_h + 1 GOTO keep_select END IF END IF IF ((KCTRL AND KB = KEY_INSERT) OR (KCONTROL AND UCASE$(K$) = "C")) AND Help_Select = 2 THEN 'copy to clipboard clip$ = "" FOR y = Help_SelY1 TO Help_SelY2 IF y <> Help_SelY1 THEN clip$ = clip$ + CHR$(13) + CHR$(10) a$ = "" IF y <= help_h THEN l = CVL(MID$(Help_Line$, (y - 1) * 4 + 1, 4)) x = l x3 = 1 c = ASC(Help_Txt$, x) DO UNTIL c = 13 IF Help_Select = 2 THEN IF y >= Help_SelY1 AND y <= Help_SelY2 THEN IF x3 >= Help_SelX1 AND x3 <= Help_SelX2 THEN a$ = a$ + CHR$(c) END IF END IF END IF x3 = x3 + 1: x = x + 4: c = ASC(Help_Txt$, x) LOOP END IF clip$ = clip$ + a$ NEXT IF Help_SelY1 = Help_SelY2 AND Help_cy > Help_cy1 THEN clip$ = clip$ + CHR$(13) + CHR$(10) IF clip$ <> "" THEN _CLIPBOARD$ = clip$ GOTO keep_select END IF IF mX >= Help_wx1 AND mY >= Help_wy1 AND mX <= Help_wx2 AND mY <= Help_wy2 THEN IF mCLICK THEN Help_cx = Help_sx + (mX - Help_wx1) Help_cy = Help_sy + (mY - Help_wy1) Help_Select = 1 Help_MSelect = 1 Help_cx1 = Help_cx: Help_cy1 = Help_cy GOTO keep_select END IF IF (mB AND Help_Scrollbar = 0) THEN Help_cx = Help_sx + (mX - Help_wx1) Help_cy = Help_sy + (mY - Help_wy1) IF Help_Select THEN GOTO keep_select END IF ELSE 'outside field IF (mB AND Help_Scrollbar = 0) AND Help_MSelect = 1 AND Help_Select = 2 THEN IF mX < Help_wx1 THEN Help_cx = Help_cx - 1 IF mX > Help_wx2 THEN Help_cx = Help_cx + 1 IF mY < Help_wy1 THEN Help_cy = Help_cy - 1 IF mY > Help_wy2 THEN Help_cy = Help_cy + 1 GOTO keep_select END IF END IF IF KSHIFT THEN IF Help_Select = 0 THEN Help_Select = 1 Help_MSelect = 0 Help_cx1 = Help_cx: Help_cy1 = Help_cy END IF ELSE IF (KB > 0 OR mWHEEL <> 0) AND KSTATECHANGED = 0 THEN Help_Select = 0 END IF keep_select: IF KB = KEY_DELETE THEN IF LEN(Help_Search_Str) THEN norep = 1: GOTO delsrchagain END IF IF LEN(K$) = 1 AND KCONTROL = 0 THEN k = ASC(K$) IF alphanumeric(k) OR k = 36 OR k = 32 THEN norep = 0 t# = TIMER(0.001) oldk = 0: IF LEN(Help_Search_Str) THEN oldk = ASC(Help_Search_Str, LEN(Help_Search_Str)) IF t# > Help_Search_Time + 1 OR t# < Help_Search_Time OR (k = oldk AND LEN(Help_Search_Str) = 1) THEN IF k = oldk THEN norep = 1 Help_Search_Str = K$ ELSE Help_Search_Str = Help_Search_Str + K$ END IF Help_Search_Time = t# 'search for next appropriate link delsrchagain: ox = Help_cx oy = Help_cy IF oy > help_h THEN oy = 1 cy = oy cx = ox IF norep = 1 THEN cx = cx + 1 looped = 0 DO 'build the line l = CVL(MID$(Help_Line$, (cy - 1) * 4 + 1, 4)) x = l a$ = "" c = ASC(Help_Txt$, x) DO UNTIL c = 13 lnk = CVI(MID$(Help_Txt$, x + 2, 2)) IF lnk THEN a$ = a$ + CHR$(c) ELSE a$ = a$ + CHR$(0) 'only add text with links x = x + 4: c = ASC(Help_Txt$, x) LOOP helpscanrow: px = INSTR(cx, UCASE$(a$), UCASE$(Help_Search_Str)) px2 = INSTR(cx, UCASE$(a$), UCASE$("_" + Help_Search_Str)) IF px2 < px AND px2 <> 0 AND LEFT$(Help_Search_Str, 1) <> "_" THEN px = px2 IF looped = 1 AND cy = oy AND px = 0 THEN GOTO strnotfound IF px THEN 'isolate and REVERSE select link l = CVL(MID$(Help_Line$, (cy - 1) * 4 + 1, 4)) x = l x2 = 1 a$ = "" c = ASC(Help_Txt$, x) oldlnk = 0 lnkx1 = 0: lnkx2 = 0 DO UNTIL c = 13 lnk = CVI(MID$(Help_Txt$, x + 2, 2)) IF lnkx1 = 0 AND lnk <> 0 AND oldlnk = 0 AND px = x2 THEN lnkx1 = x2 IF lnkx1 <> 0 AND lnk = 0 AND lnkx2 = 0 THEN lnkx2 = x2 - 1 x = x + 4: c = ASC(Help_Txt$, x) x2 = x2 + 1 oldlnk = lnk LOOP IF Back_Name$(Help_Back_Pos) = "Alphabetical" OR Back_Name$(Help_Back_Pos) = "By Usage" THEN IF lnkx1 <> 3 THEN cx = px + 1 GOTO helpscanrow END IF END IF IF lnkx1 THEN IF lnkx2 = 0 THEN lnkx2 = x2 - 1 Help_Select = 2 Help_cx1 = lnkx2 + 1 Help_cx = lnkx1 Help_cy = cy Help_cy1 = cy GOTO foundsstr END IF cx = px + 1 GOTO helpscanrow END IF cx = 1 cy = cy + 1 IF cy > help_h THEN cy = 1: looped = 1 LOOP END IF END IF foundsstr: strnotfound: IF KB = KEY_HOME AND KCONTROL THEN Help_cx = 1: Help_cy = 1 END IF IF KB = KEY_END AND KCONTROL THEN Help_cx = 1: Help_cy = help_h + 1 END IF IF KB = KEY_HOME AND KCONTROL = 0 THEN Help_cx = 1 IF KB = KEY_END AND KCONTROL = 0 THEN Help_cx = Help_LineLen(Help_cy - Help_sy) + 1 END IF IF KB = KEY_PAGEUP THEN Help_cy = Help_cy - (Help_wh - 1) END IF IF KB = KEY_PAGEDOWN THEN Help_cy = Help_cy + (Help_wh - 1) END IF IF KB = KEY_DOWN THEN Help_cy = Help_cy + 1 IF KB = KEY_UP THEN Help_cy = Help_cy - 1 IF KB = KEY_LEFT THEN Help_cx = Help_cx - 1 IF KB = KEY_RIGHT THEN Help_cx = Help_cx + 1 'move relative to top/bottom IF mWHEEL < 0 THEN Help_cy = Help_sy IF mWHEEL > 0 THEN Help_cy = Help_sy + (Help_wh - 1) Help_cy = Help_cy + mWHEEL * 3 'fix cursor IF Help_cx < 1 THEN Help_cx = 1 IF Help_cx > help_w + 1 THEN Help_cx = help_w + 1 IF Help_cy < 1 THEN Help_cy = 1 IF Help_cy > help_h + 1 THEN Help_cy = help_h + 1 'screen follows cursor IF Help_cx < Help_sx THEN Help_sx = Help_cx IF Help_cx >= Help_sx + Help_ww THEN Help_sx = Help_cx - Help_ww + 1 IF Help_cy < Help_sy THEN Help_sy = Help_cy IF Help_cy >= Help_sy + Help_wh THEN Help_sy = Help_cy - Help_wh + 1 'fix screen IF Help_sx < 1 THEN Help_sx = 1 IF Help_sy < 1 THEN Help_sy = 1 IF K$ = CHR$(8) THEN IF Help_Back_Pos > 1 THEN Help_Back(Help_Back_Pos).sx = Help_sx 'update position Help_Back(Help_Back_Pos).sy = Help_sy Help_Back(Help_Back_Pos).cx = Help_cx Help_Back(Help_Back_Pos).cy = Help_cy Help_Back_Pos = Help_Back_Pos - 1 Help_Select = 0: Help_MSelect = 0 Help_sx = Help_Back(Help_Back_Pos).sx Help_sy = Help_Back(Help_Back_Pos).sy Help_cx = Help_Back(Help_Back_Pos).cx Help_cy = Help_Back(Help_Back_Pos).cy a$ = Wiki(Back$(Help_Back_Pos)) WikiParse a$ GOTO newpageparsed END IF END IF IF Help_cy >= 1 AND Help_cy <= help_h THEN l = CVL(MID$(Help_Line$, (Help_cy - 1) * 4 + 1, 4)) x = l x2 = 1 c = ASC(Help_Txt$, x) DO UNTIL c = 13 IF x2 = Help_cx THEN lnk = CVI(MID$(Help_Txt$, x + 2, 2)) IF lnk THEN 'retrieve lnk info l1 = 1 FOR lx = 1 TO lnk - 1 l1 = INSTR(l1, Help_Link$, Help_Link_Sep$) + 1 NEXT l2 = INSTR(l1, Help_Link$, Help_Link_Sep$) - 1 l$ = MID$(Help_Link$, l1, l2 - l1 + 1) 'assume PAGE l$ = RIGHT$(l$, LEN(l$) - 5) IF mCLICK OR K$ = CHR$(13) THEN mCLICK = 0 IF Back$(Help_Back_Pos) <> l$ THEN Help_Select = 0: Help_MSelect = 0 'COLOR 7, 0 Help_Back(Help_Back_Pos).sx = Help_sx 'update position Help_Back(Help_Back_Pos).sy = Help_sy Help_Back(Help_Back_Pos).cx = Help_cx Help_Back(Help_Back_Pos).cy = Help_cy top = UBOUND(back$) IF Help_Back_Pos < top THEN IF Back$(Help_Back_Pos + 1) = l$ THEN GOTO usenextentry END IF END IF top = top + 1 REDIM _PRESERVE Back(top) AS STRING REDIM _PRESERVE Help_Back(top) AS Help_Back_Type REDIM _PRESERVE Back_Name(top) AS STRING 'Shuffle array upwards after current pos FOR x = top - 1 TO Help_Back_Pos + 1 STEP -1 Back_Name$(x + 1) = Back_Name$(x) Back$(x + 1) = Back$(x) Help_Back(x + 1).sx = Help_Back(x).sx Help_Back(x + 1).sy = Help_Back(x).sy Help_Back(x + 1).cx = Help_Back(x).cx Help_Back(x + 1).cy = Help_Back(x).cy NEXT usenextentry: Help_Back_Pos = Help_Back_Pos + 1 Back$(Help_Back_Pos) = l$ Back_Name$(Help_Back_Pos) = Back2BackName$(l$) Help_Back(Help_Back_Pos).sx = 1 Help_Back(Help_Back_Pos).sy = 1 Help_Back(Help_Back_Pos).cx = 1 Help_Back(Help_Back_Pos).cy = 1 Help_sx = 1: Help_sy = 1: Help_cx = 1: Help_cy = 1 a$ = Wiki(l$) WikiParse a$ GOTO newpageparsed END IF END IF END IF END IF x = x + 4: c = ASC(Help_Txt$, x) x2 = x2 + 1 LOOP END IF IF Help_Select THEN Help_Select = 1 'revert to non-selected if cursor moved to neutral pos IF Help_cx <> Help_cx1 OR Help_cy <> Help_cy1 THEN Help_Select = 2 END IF 'Determine the exact region selected IF Help_Select = 2 THEN IF Help_cy = Help_cy1 THEN Help_SelY1 = Help_cy: Help_SelY2 = Help_cy IF Help_cx > Help_cx1 THEN Help_SelX1 = Help_cx1: Help_SelX2 = Help_cx - 1 ELSE Help_SelX1 = Help_cx: Help_SelX2 = Help_cx1 - 1 END IF ELSE Help_SelX1 = 1: Help_SelX2 = 10000000 IF Help_cy > Help_cy1 THEN Help_SelY1 = Help_cy1: Help_SelY2 = Help_cy IF Help_cx = 1 THEN Help_SelY2 = Help_cy - 1 ELSE Help_SelY1 = Help_cy: Help_SelY2 = Help_cy1 END IF END IF END IF newpageparsed: GOTO specialchar END IF IF KB = KEY_F1 THEN 'identify word or character at current cursor position a$ = idegetline(idecy) x = idecx IF x <= LEN(a$) THEN IF alphanumeric(ASC(a$, x)) THEN x1 = x DO WHILE x1 > 1 IF alphanumeric(ASC(a$, x1 - 1)) OR ASC(a$, x1 - 1) = 36 THEN x1 = x1 - 1 ELSE EXIT DO LOOP x2 = x DO WHILE x2 < LEN(a$) IF alphanumeric(ASC(a$, x2 + 1)) OR ASC(a$, x2 + 1) = 36 THEN x2 = x2 + 1 ELSE EXIT DO LOOP a2$ = MID$(a$, x1, x2 - x1 + 1) ELSE a2$ = CHR$(ASC(a$, x)) END IF a2$ = UCASE$(a2$) 'check if F1 is in help links fh = FREEFILE OPEN "internal\help\links.bin" FOR INPUT AS #fh lnks = 0: lnks$ = CHR$(0) DO UNTIL EOF(fh) LINE INPUT #fh, l$ c = INSTR(l$, ","): l1$ = LEFT$(l$, c - 1): l2$ = RIGHT$(l$, LEN(l$) - c) IF a2$ = UCASE$(l1$) THEN IF INSTR(lnks$, CHR$(0) + l2$ + CHR$(0)) = 0 THEN lnks = lnks + 1 IF l2$ = l1$ THEN lnks$ = CHR$(0) + l2$ + lnks$ ELSE lnks$ = lnks$ + l2$ + CHR$(0) END IF END IF END IF LOOP CLOSE #fh IF lnks THEN lnks$ = MID$(lnks$, 2, LEN(lnks$) - 2) lnk$ = lnks$ IF lnks > 1 THEN 'clarify context lnk$ = idef1box$(lnks$, lnks) END IF OpenHelpLnk: Help_Back(Help_Back_Pos).sx = Help_sx 'update position Help_Back(Help_Back_Pos).sy = Help_sy Help_Back(Help_Back_Pos).cx = Help_cx Help_Back(Help_Back_Pos).cy = Help_cy top = UBOUND(back$) IF Back$(Help_Back_Pos) = lnk$ THEN Help_Back_Pos = Help_Back_Pos - 1: GOTO usenextentry2 IF Help_Back_Pos < top THEN IF Back$(Help_Back_Pos + 1) = lnk$ THEN GOTO usenextentry2 END IF END IF top = top + 1 REDIM _PRESERVE Back(top) AS STRING REDIM _PRESERVE Help_Back(top) AS Help_Back_Type REDIM _PRESERVE Back_Name(top) AS STRING 'Shuffle array upwards after current pos FOR x = top - 1 TO Help_Back_Pos + 1 STEP -1 Back_Name$(x + 1) = Back_Name$(x) Back$(x + 1) = Back$(x) Help_Back(x + 1).sx = Help_Back(x).sx Help_Back(x + 1).sy = Help_Back(x).sy Help_Back(x + 1).cx = Help_Back(x).cx Help_Back(x + 1).cy = Help_Back(x).cy NEXT usenextentry2: Help_Back_Pos = Help_Back_Pos + 1 Back$(Help_Back_Pos) = lnk$ Back_Name$(Help_Back_Pos) = Back2BackName$(lnk$) Help_Back(Help_Back_Pos).sx = 1 Help_Back(Help_Back_Pos).sy = 1 Help_Back(Help_Back_Pos).cx = 1 Help_Back(Help_Back_Pos).cy = 1 Help_sx = 1: Help_sy = 1: Help_cx = 1: Help_cy = 1 a$ = Wiki(lnk$) IF idehelp = 0 THEN IF idesubwindow THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt: GOTO ideloop idesubwindow = idewy \ 2: idewy = idewy - idesubwindow Help_wx1 = 2: Help_wy1 = idewy + 1: Help_wx2 = idewx - 1: Help_wy2 = idewy + idesubwindow - 2: Help_ww = Help_wx2 - Help_wx1 + 1: Help_wh = Help_wy2 - Help_wy1 + 1 WikiParse a$ idehelp = 1 skipdisplay = 0 IdeSystem = 1 '*** retval = 1: GOTO redraweverything2 END IF WikiParse a$ IdeSystem = 1 '*** GOTO specialchar END IF 'lnks END IF GOTO specialchar END IF IF KALT AND KB = KEY_LEFT THEN bmkremoved = 0 bmkremove: FOR b = 1 TO IdeBmkN IF IdeBmk(b).y = idecy THEN FOR b2 = b TO IdeBmkN - 1 IdeBmk(b2) = IdeBmk(b2 + 1) NEXT IdeBmkN = IdeBmkN - 1 bmkremoved = 1 ideunsaved = 1 GOTO bmkremove END IF NEXT IF bmkremoved = 0 THEN IdeBmkN = IdeBmkN + 1 IF IdeBmkN > UBOUND(IdeBmk) THEN x = UBOUND(IdeBmk) * 2: REDIM _PRESERVE IdeBmk(x) AS IdeBmkType IdeBmk(IdeBmkN).y = idecy IdeBmk(IdeBmkN).x = idecx IdeBmk(IdeBmkN).reserved = 0: IdeBmk(IdeBmkN).reserved2 = 0 ideunsaved = 1 END IF GOTO specialchar END IF IF KALT AND (KB = KEY_DOWN OR KB = KEY_UP) THEN IF IdeBmkN = 0 THEN idemessagebox "Bookmarks", "No bookmarks exist (Use ALT+Left to create a bookmark)" SCREEN , , 3, 0: idewait4mous: idewait4alt idealthighlight = 0 LOCATE , , 0: COLOR 0, 7: LOCATE 1, 1: PRINT menubar$; GOTO specialchar END IF IF IdeBmkN = 1 THEN IF idecy = IdeBmk(1).y THEN idemessagebox "Bookmarks", "No other bookmarks exist" SCREEN , , 3, 0: idewait4mous: idewait4alt idealthighlight = 0 LOCATE , , 0: COLOR 0, 7: LOCATE 1, 1: PRINT menubar$; GOTO specialchar END IF END IF l = idecy DO IF KB = KEY_DOWN THEN l = l + 1 ELSE l = l - 1 IF l < 1 THEN l = iden IF l > iden THEN l = 1 FOR b = 1 TO IdeBmkN IF IdeBmk(b).y = l THEN EXIT DO NEXT LOOP idecy = l idecx = IdeBmk(b).x ideselect = 0 GOTO specialchar END IF IF KALT AND KB = KEY_RIGHT THEN '***RESERVED*** GOTO specialchar END IF IF mCLICK THEN IF mX > 1 AND mX < idewx AND mY > 2 AND mY < (idewy - 5) THEN 'inside text box ideselect = 1 idecx = mX - 1 + idesx - 1 idecy = mY - 2 + idesy - 1 IF idecy > iden THEN idecy = iden ideselect = 1: ideselectx1 = idecx: ideselecty1 = idecy idemouseselect = 1 END IF END IF IF mCLICK THEN IF mX = idewx THEN IF iden > 1 THEN 'take no action if not slider available y = idevbar(idewx, 3, idewy - 8, idecy, iden) IF y = mY THEN idemouseselect = 2 ideselect = 0 END IF END IF END IF END IF IF mCLICK THEN IF mY = idewy - 5 THEN x = idehbar(2, idewy - 5, idewx - 2, idesx, 608) IF x = mX THEN idemouseselect = 3 ideselect = 0 END IF END IF END IF IF mB AND idemouseselect = 0 THEN IF mX = idewx AND mY > 2 AND mY < idewy - 5 THEN 'inside vbar ideselect = 0 IF mY = 3 THEN KB = KEY_UP: idewait: idembmonitor = 1 IF mY = idewy - 6 THEN KB = KEY_DOWN: idewait: idembmonitor = 1 IF mY > 3 AND mY < (idewy - 6) THEN 'assume not on slider IF iden > 1 THEN 'take no action if not slider available y = idevbar(idewx, 3, idewy - 8, idecy, iden) IF y <> mY THEN IF mY < y THEN KB = KEY_PAGEUP: idewait: idembmonitor = 1 ELSE KB = KEY_PAGEDOWN: idewait: idembmonitor = 1 END IF END IF END IF END IF END IF END IF IF mB AND idemouseselect = 0 THEN IF mY = idewy - 5 AND mX > 1 AND mX < idewx THEN 'inside hbar ideselect = 0 IF mX = 2 THEN KB = KEY_LEFT: idewait: idembmonitor = 1 IF mX = idewx - 1 THEN KB = KEY_RIGHT: idewait: idembmonitor = 1 IF mX > 2 AND mX < idewx - 1 THEN 'assume not on slider x = idehbar(2, idewy - 5, idewx - 2, idesx, 608) IF x <> mX THEN IF mX < x THEN idecx = idecx - 8 IF idecx < 1 THEN idecx = 1 idewait: idembmonitor = 1 ELSE idecx = idecx + 8 idewait: idembmonitor = 1 END IF END IF END IF END IF END IF IF mB AND idemouseselect = 2 THEN 'move vbar scroller (idecy) to appropriate position IF iden > 1 THEN IF mY <= 4 THEN idecy = 1 IF mY >= idewy - 7 THEN idecy = iden IF mY > 4 AND mY < idewy - 7 THEN y = mY p! = y - 3 - 2 + .5 p! = p! / ((idewy - 8) - 4) i = p! * (iden - 1) + 1 idecy = i END IF END IF END IF IF mB AND idemouseselect = 3 THEN 'move hbar scroller (idecx) to appropriate position IF mX <= 3 THEN idesx = 1: idecx = idesx IF mX >= idewx - 2 THEN idesx = 608: idecx = idesx IF mX > 3 AND mX < idewx - 2 THEN x = mX p! = x - 2 - 2 + .5 p! = p! / ((idewx - 2) - 4) i = p! * (608 - 1) + 1 idesx = i idecx = idesx END IF END IF IF mB AND idemouseselect <= 1 THEN IF mX > 1 AND mX < idewx AND mY > 2 AND mY < idewy - 5 THEN 'inside text box IF idemouseselect = 1 THEN idecx = mX - 1 + idesx - 1 idecy = mY - 2 + idesy - 1 IF idecy > iden THEN idecy = iden END IF END IF END IF IF mB THEN IF mX = 1 OR mX = idewx OR mY <= 2 OR mY >= idewy - 5 THEN 'off text window area IF idemouseselect = 1 THEN 'scroll window IF mY >= idewy - 5 THEN idecy = idecy + 1: IF idecy > iden THEN idecy = iden IF mY <= 2 THEN idecy = idecy - 1: IF idecy < 1 THEN idecy = 1 IF mX = 1 THEN idecx = idecx - 1: IF idecx < 1 THEN idecx = 1 IF mX = idewx THEN idecx = idecx + 1 idewait END IF END IF END IF IF KCONTROL AND UCASE$(K$) = "A" THEN 'select all idemselectall: ideselect = 1: ideselectx1 = 1: ideselecty1 = 1 idecy = iden a$ = idegetline(idecy) idecx = LEN(a$) + 1 GOTO specialchar END IF IF K$ = CHR$(0) + CHR$(60) THEN 'F2 GOTO idesubsjmp END IF IF KCONTROL AND UCASE$(K$) = "Z" THEN 'undo (CTRL+Z) idemundo: IF ideundopos THEN OPEN tmpdir$ + "undo2.bin" FOR BINARY AS #150 h$ = SPACE$(12): GET #150, , h$: p1 = CVL(MID$(h$, 1, 4)): p2 = CVL(MID$(h$, 5, 4)): plast = CVL(MID$(h$, 9, 4)) 'does something exist to undo? u = 0 IF p2 >= p1 THEN 'linear IF ideundopos > p1 THEN GET #150, ideundopos - 4, upl u = ideundopos - 4 - upl - 4 END IF ELSE 'wrapped IF ideundopos > p1 THEN GET #150, ideundopos - 4, upl u = ideundopos - 4 - upl - 4 END IF IF ideundopos <= p2 THEN IF ideundopos = 13 THEN u = plast ELSE GET #150, ideundopos - 4, upl u = ideundopos - 4 - upl - 4 END IF END IF END IF IF u THEN IF ideundopos = ideundobase THEN 'if not untitled, then we MUST switch to a special state 'warn PCOPY 3, 0 what$ = ideyesnobox("Undo", "Undo through previous program content?") PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF what$ = "N" THEN CLOSE #150 GOTO skipundo END IF IF ideunsaved = 1 AND ideprogname <> "" THEN PCOPY 3, 0 r$ = idesavenow PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF r$ = "C" THEN CLOSE #150: GOTO skipundo IF r$ = "Y" THEN idesave idepath$ + idepathsep$ + ideprogname$ END IF END IF ideunsaved = 1 ideprogname$ = "" _TITLE "QB64" ideundobase = -1 'release base restriction END IF ideundopos = u 'set new current state 'get backup SEEK #150, u GET #150, , l2& 'should be the same as l& GET #150, , idesx: GET #150, , idesy GET #150, , idecx: GET #150, , idecy GET #150, , ideselect: GET #150, , ideselectx1: GET #150, , ideselecty1 GET #150, , iden GET #150, , idel GET #150, , ideli 'bookmark info [v2] GET #150, , IdeBmkN: REDIM IdeBmk(IdeBmkN + 1) AS IdeBmkType FOR bi = 1 TO IdeBmkN: GET #150, , IdeBmk(bi).y: GET #150, , IdeBmk(bi).x: NEXT GET #150, , x&: idet$ = SPACE$(x&): GET #150, , idet$ idechangemade = 1: idenoundo = 1 END IF 'u skipundo: CLOSE #150 END IF GOTO specialchar END IF IF KCONTROL AND UCASE$(K$) = "Y" THEN 'redo (CTRL+Y) idemredo: IF ideundopos THEN OPEN tmpdir$ + "undo2.bin" FOR BINARY AS #150 h$ = SPACE$(12): GET #150, , h$: p1 = CVL(MID$(h$, 1, 4)): p2 = CVL(MID$(h$, 5, 4)): plast = CVL(MID$(h$, 9, 4)) 'does something exist to redo? u = 0 IF p2 >= p1 THEN 'linear IF ideundopos < p2 THEN GET #150, ideundopos, upl u = ideundopos + 4 + upl + 4 END IF ELSE 'wrapped IF ideundopos >= p1 THEN IF ideundopos = plast THEN u = 13 ELSE GET #150, ideundopos, upl u = ideundopos + 4 + upl + 4 END IF ELSE IF ideundopos < p2 THEN GET #150, ideundopos, upl u = ideundopos + 4 + upl + 4 END IF END IF END IF IF u THEN ideundopos = u 'set new current state 'get backup SEEK #150, u GET #150, , l2& 'should be the same as l& GET #150, , idesx: GET #150, , idesy GET #150, , idecx: GET #150, , idecy GET #150, , ideselect: GET #150, , ideselectx1: GET #150, , ideselecty1 GET #150, , iden GET #150, , idel GET #150, , ideli 'bookmark info [v2] GET #150, , IdeBmkN: REDIM IdeBmk(IdeBmkN + 1) AS IdeBmkType FOR bi = 1 TO IdeBmkN: GET #150, , IdeBmk(bi).y: GET #150, , IdeBmk(bi).x: NEXT GET #150, , x&: idet$ = SPACE$(x&): GET #150, , idet$ idechangemade = 1: idenoundo = 1 END IF 'u CLOSE #150 END IF GOTO specialchar END IF IF ((KSHIFT AND KB = KEY_DELETE) OR (KCONTROL AND UCASE$(K$) = "X")) AND ideselect = 1 THEN 'cut to clipboard idemcut: idechangemade = 1 GOTO copy2clip END IF IF KB = KEY_DELETE AND ideselect = 1 THEN 'delete selection IF ideselecty1 <> idecy OR ideselectx1 <> idecx THEN idechangemade = 1 GOSUB delselect GOTO specialchar ELSE ideselect = 0 END IF END IF IF (KSHIFT AND KB = KEY_INSERT) OR (KCONTROL AND UCASE$(K$) = "V") THEN 'paste from clipboard idempaste: clip$ = _CLIPBOARD$ 'read clipboard IF LEN(clip$) THEN IF ideselect THEN GOSUB delselect IF INSTR(clip$, CHR$(13)) OR INSTR(clip$, CHR$(10)) THEN 'full lines paste idelayoutallow = 2 a$ = clip$ x3 = 1 'scan from position i = 0 'lines counter fullpastenextline: x = INSTR(x3, a$, CHR$(13)) x2 = INSTR(x3, a$, CHR$(10)) IF x = 0 THEN x = x2 IF x2 = 0 THEN x2 = x IF x2 < x THEN SWAP x, x2 IF x2 > x + 1 THEN x2 = x 'if seperated by more than one character, they are seperate line terminators 'x to x2 is the range of the next line terminator (1 or 2 characters) IF x THEN ideinsline idecy + i, converttabs$(MID$(a$, x3, x - x3)) i = i + 1 x3 = x2 + 1 ELSE ideinsline idecy + i, converttabs$(MID$(a$, x3, LEN(a$) - x3 + 1)) i = i + 1 x3 = LEN(a$) + 1 END IF IF x3 <= LEN(a$) GOTO fullpastenextline ELSE 'insert single line paste a$ = idegetline(idecy) IF LEN(a$) < idecx - 1 THEN a$ = a$ + SPACE$(idecx - 1 - LEN(a$)) a$ = LEFT$(a$, idecx - 1) + clip$ + RIGHT$(a$, LEN(a$) - idecx + 1) idesetline idecy, converttabs$(a$) END IF idechangemade = 1 END IF GOTO specialchar END IF IF ((KCTRL AND KB = KEY_INSERT) OR (KCONTROL AND UCASE$(K$) = "C")) AND ideselect = 1 THEN 'copy to clipboard copy2clip: clip$ = "" sy1 = ideselecty1 sy2 = idecy IF sy1 > sy2 THEN SWAP sy1, sy2 sx1 = ideselectx1 sx2 = idecx IF sx1 > sx2 THEN SWAP sx1, sx2 FOR y = sy1 TO sy2 IF y <= iden THEN a$ = idegetline(y) IF sy1 = sy2 THEN 'single line select FOR x = sx1 TO sx2 - 1 IF x <= LEN(a$) THEN clip$ = clip$ + MID$(a$, x, 1) ELSE clip$ = clip$ + " " NEXT ELSE 'multiline select IF idecx = 1 AND y = sy2 AND idecy > sy1 THEN clip$ = clip$ + CHR$(13) + CHR$(10): GOTO nofinalcopy IF clip$ = "" THEN clip$ = a$ ELSE clip$ = clip$ + CHR$(13) + CHR$(10) + a$ nofinalcopy: END IF END IF NEXT IF clip$ <> "" THEN _CLIPBOARD$ = clip$ IF (K$ = CHR$(0) + "S") OR (KSHIFT AND KB = KEY_DELETE) OR (KCONTROL AND UCASE$(K$) = "X") THEN GOSUB delselect GOTO specialchar END IF IF KB = KEY_INSERT THEN 'toggle INSERT mode ideinsert = ideinsert + 1 IF ideinsert = 2 THEN ideinsert = 0 END IF IF KB = KEY_UP THEN GOSUB selectcheck idecy = idecy - 1 IF idecy < 1 THEN idecy = 1 GOTO specialchar END IF IF KB = KEY_DOWN THEN GOSUB selectcheck idecy = idecy + 1 IF idecy > iden THEN idecy = iden GOTO specialchar END IF IF mWHEEL THEN GOSUB selectcheck 'move relative to top/bottom IF mWHEEL < 0 THEN idecy = idesy IF mWHEEL > 0 THEN idecy = idesy + (idewy - 9) idecy = idecy + mWHEEL * 3 IF idecy < 1 THEN idecy = 1 IF idecy > iden THEN idecy = iden GOTO specialchar END IF IF KB = KEY_LEFT THEN GOSUB selectcheck IF KCONTROL THEN 'move forward to next beginning alphanumeric a$ = idegetline(idecy) IF idecx > LEN(a$) THEN idecx = LEN(a$) + 1 skipping = 1 DO 'move idecx = idecx - 1 'latch onto prev character IF idecx < 1 THEN DO IF idecy = 1 THEN idecx = 1: GOTO specialchar idecy = idecy - 1 a$ = idegetline(idecy) idecx = LEN(a$) LOOP UNTIL LEN(a$) END IF 'check character IF alphanumeric(ASC(a$, idecx)) THEN IF idecx = 1 THEN GOTO specialchar x = idecx: y = idecy skipping = 0 ELSE IF skipping = 0 THEN idecx = x: idecy = y: GOTO specialchar END IF LOOP ELSE idecx = idecx - 1 IF idecx < 1 THEN idecx = 1 END IF GOTO specialchar END IF IF KB = KEY_RIGHT THEN GOSUB selectcheck IF KCONTROL THEN 'move forward to next beginning alphanumeric a$ = idegetline(idecy) skipping = 0 first = 1 DO 'move IF first = 0 THEN idecx = idecx + 1 'latch onto next character IF idecx > LEN(a$) THEN DO IF idecy = iden THEN GOTO specialchar idecy = idecy + 1: idecx = 1 a$ = idegetline(idecy) LOOP UNTIL LEN(a$) skipping = 0 first = 0 END IF 'check character IF alphanumeric(ASC(a$, idecx)) THEN IF first THEN skipping = 1 ELSE IF skipping = 0 THEN GOTO specialchar END IF ELSE skipping = 0 END IF first = 0 LOOP ELSE idecx = idecx + 1 END IF GOTO specialchar END IF IF KCONTROL AND KB = KEY_HOME THEN GOSUB selectcheck idecx = 1 idecy = 1 GOTO specialchar END IF IF KCONTROL AND KB = KEY_END THEN GOSUB selectcheck idecy = iden a$ = idegetline(idecy) idecx = LEN(a$) + 1 GOTO specialchar END IF IF KB = KEY_HOME THEN GOSUB selectcheck IF idecx <> 1 THEN idecx = 1 ELSE a$ = idegetline(idecy) idecx = 1 FOR x = 1 TO LEN(a$) IF ASC(a$, x) <> 32 THEN idecx = x: EXIT FOR NEXT END IF GOTO specialchar END IF IF KB = KEY_END THEN GOSUB selectcheck a$ = idegetline(idecy) idecx = LEN(a$) + 1 GOTO specialchar END IF IF KB = KEY_PAGEUP THEN GOSUB selectcheck idecy = idecy - (idewy - 9) IF idecy < 1 THEN idecy = 1 GOTO specialchar END IF IF KB = KEY_PAGEDOWN THEN GOSUB selectcheck idecy = idecy + (idewy - 9) IF idecy > iden THEN idecy = iden GOTO specialchar END IF GOTO skipgosubs selectcheck: IF KSHIFT AND ideselect = 0 THEN ideselect = 1: ideselectx1 = idecx: ideselecty1 = idecy IF KSHIFT = 0 THEN ideselect = 0 RETURN delselect: sy1 = ideselecty1 sy2 = idecy IF sy1 > sy2 THEN SWAP sy1, sy2 sx1 = ideselectx1 sx2 = idecx IF sx1 > sx2 THEN SWAP sx1, sx2 nolastlinedel = 0 IF sy1 <> sy2 AND idecx = 1 AND idecy > sy1 THEN sy2 = sy2 - 1: nolastlinedel = 1 'ignore last line of multi-line select? FOR y = sy2 TO sy1 STEP -1 IF sy1 = sy2 AND nolastlinedel = 0 THEN 'single line select a$ = idegetline(y) a2$ = "" IF sx1 <= LEN(a$) THEN a2$ = LEFT$(a$, sx1 - 1) ELSE a2$ = a$ IF sx2 <= LEN(a$) THEN a2$ = a2$ + RIGHT$(a$, LEN(a$) - sx2 + 1) idesetline y, a2$ ELSE 'multiline select IF iden = 1 AND y = 1 THEN idesetline y, "" ELSE idedelline y END IF NEXT idecx = sx1: IF sy1 <> sy2 OR nolastlinedel = 1 THEN idecx = 1 idecy = sy1 ideselect = 0 RETURN skipgosubs: IF K$ = CHR$(13) THEN ideselect = 0 idechangemade = 1 a$ = idegetline(idecy) IF idecx > LEN(a$) THEN ideinsline idecy + 1, "" ELSE idesetline idecy, LEFT$(a$, idecx - 1) ideinsline idecy + 1, RIGHT$(a$, LEN(a$) - idecx + 1) END IF IF idecx = 1 THEN FOR b = 1 TO IdeBmkN IF IdeBmk(b).y = idecy THEN IdeBmk(b).y = IdeBmk(b).y + 1 NEXT END IF idecy = idecy + 1 idecx = 1 GOTO specialchar END IF IF KB = KEY_DELETE THEN idechangemade = 1 a$ = idegetline(idecy) IF idecx <= LEN(a$) THEN a$ = LEFT$(a$, idecx - 1) + RIGHT$(a$, LEN(a$) - idecx) idesetline idecy, a$ ELSE a$ = a$ + SPACE$(idecx - LEN(a$) - 1) a$ = a$ + idegetline(idecy + 1) idesetline idecy, a$ idedelline idecy + 1 END IF GOTO specialchar END IF IF K$ = CHR$(8) THEN ideselect = 0 idechangemade = 1 'undocombos IF ideundocombochr <> 8 THEN ideundocombo = 2 ELSE ideundocombo = ideundocombo + 1 IF ideundocombo = 2 THEN idemergeundo = 1 END IF ideundocombochr = 8 a$ = idegetline(idecy) IF idecx = 1 THEN IF idecy > 1 THEN a2$ = idegetline(idecy - 1) idesetline idecy - 1, a2$ + a$ idedelline idecy idecx = LEN(a2$) + 1 idecy = idecy - 1 END IF GOTO specialchar END IF IF idecx > LEN(a$) + 1 THEN idecx = LEN(a$) + 1 ELSE a$ = LEFT$(a$, idecx - 2) + RIGHT$(a$, LEN(a$) - idecx + 1) idesetline idecy, a$ idecx = idecx - 1 END IF GOTO specialchar END IF 'patch#1 IF LEN(K$) <> 1 THEN GOTO specialchar IF K$ = CHR$(9) THEN GOTO ideforceinput IF block_chr(ASC(K$)) THEN GOTO specialchar ideforceinput: IF K$ = CHR$(9) THEN x = 4 IF ideautoindent <> 0 AND ideautoindentsize <> 0 THEN x = ideautoindentsize K$ = SPACE$(x - ((idecx - 1) MOD x)) END IF 'standard character IF ideselect THEN GOSUB delselect idechangemade = 1 'undocombos IF LEN(K$) = 1 THEN asck = ASC(K$) IF alphanumeric(asck) OR ideundocombochr = asck THEN IF ideundocombochr = 8 THEN ideundocombo = 0 IF ideundocombo = 0 THEN ideundocombo = 2 ELSE ideundocombo = ideundocombo + 1 IF ideundocombo = 2 THEN idemergeundo = 1 END IF END IF ideundocombochr = asck END IF a$ = idegetline(idecy) IF LEN(a$) < idecx - 1 THEN a$ = a$ + SPACE$(idecx - 1 - LEN(a$)) IF ideinsert THEN a2$ = RIGHT$(a$, LEN(a$) - idecx + 1) IF LEN(a2$) THEN a2$ = RIGHT$(a$, LEN(a$) - idecx) a$ = LEFT$(a$, idecx - 1) + K$ + a2$ ELSE a$ = LEFT$(a$, idecx - 1) + K$ + RIGHT$(a$, LEN(a$) - idecx + 1) END IF idesetline idecy, a$ idecx = idecx + LEN(K$) specialchar: LOOP '-------------------------------------------------------------------------------- startmenu: m = 1 startmenu2: altheld = 1 DO LOCATE 1, 3 FOR i = 1 TO menus IF m = i THEN COLOR 15, 0 ELSE COLOR 15, 7 PRINT " " + LEFT$(menu$(i, 0), 1); IF m = i THEN COLOR 7, 0 ELSE COLOR 0, 7 PRINT RIGHT$(menu$(i, 0), LEN(menu$(i, 0)) - 1) + " "; IF i = menus - 1 THEN LOCATE 1, idewx - LEN(menu$(menus, 0)) - 2 NEXT PCOPY 3, 0 DO lastaltheld = altheld GetInput IF iCHANGED = 0 THEN _LIMIT 100 IF KALT THEN altheld = 1 ELSE altheld = 0 IF altheld <> 0 AND lastaltheld = 0 THEN DO: _LIMIT 1000: GetInput: LOOP UNTIL KALT = 0 KB = KEY_ESC END IF IF mCLICK THEN IF mY = 1 THEN x = 3 FOR i = 1 TO menus x2 = LEN(menu$(i, 0)) + 2 IF mX >= x AND mX < x + x2 THEN m = i LOCATE 1, 1: COLOR 0, 7: PRINT menubar$; PCOPY 3, 0 GOTO showmenu END IF x = x + x2 NEXT END IF 'my=1 KB = KEY_ESC 'exit menu selection END IF LOOP UNTIL KB K$ = UCASE$(K$) FOR i = 1 TO menus a$ = UCASE$(LEFT$(menu$(i, 0), 1)) IF K$ = a$ THEN m = i LOCATE 1, 1: COLOR 0, 7: PRINT menubar$; PCOPY 3, 0 GOTO showmenu END IF NEXT IF KB = KEY_LEFT THEN m = m - 1 IF KB = KEY_RIGHT THEN m = m + 1 IF KB = KEY_ESC THEN LOCATE 1, 1: COLOR 0, 7: PRINT menubar$; GOTO ideloop END IF IF m < 1 THEN m = menus IF m > menus THEN m = 1 IF KB = KEY_UP OR KB = KEY_DOWN OR KB = KEY_ENTER THEN LOCATE 1, 1: COLOR 0, 7: PRINT menubar$; PCOPY 3, 0 GOTO showmenu END IF 'possible ALT+??? code? IF KB > 0 AND KB <= 255 THEN IF KALT = 0 THEN iCHECKLATER = 1 LOCATE 1, 1: COLOR 0, 7: PRINT menubar$; GOTO ideloop END IF END IF LOOP '-------------------------------------------------------------------------------- showmenu: altheld = 1 PCOPY 0, 2 SCREEN , , 1, 0 r = 1 DO PCOPY 2, 1 'find pos of menu m x = 4: FOR i = 1 TO m - 1: x = x + LEN(menu$(i, 0)) + 2 IF i = menus - 1 THEN x = idewx - LEN(menu$(menus, 0)) - 1 NEXT: xx = x LOCATE 1, xx - 1: COLOR 7, 0: PRINT " " + menu$(m, 0) + " " COLOR 0, 7 'calculate menu width w = 0 FOR i = 1 TO menusize(m) m$ = menu$(m, i) l = LEN(m$) IF INSTR(m$, "#") THEN l = l - 1 IF INSTR(m$, " ") THEN l = l + 2 'min 4 spacing IF l > w THEN w = l NEXT IF xx > idewx - w - 3 THEN xx = idewx - w - 3 ideboxshadow xx - 2, 2, w + 4, menusize(m) + 2 'draw menu items FOR i = 1 TO menusize(m) m$ = menu$(m, i) IF m$ = "-" THEN COLOR 0, 7: LOCATE i + 2, xx - 2: PRINT "Ã" + STRING$(w + 2, "Ä") + "´"; ELSE IF r = i THEN LOCATE i + 2, xx - 1: COLOR 7, 0: PRINT SPACE$(w + 2); LOCATE i + 2, xx h = -1: x = INSTR(m$, "#"): IF x THEN h = x: m$ = LEFT$(m$, x - 1) + RIGHT$(m$, LEN(m$) - x) x = INSTR(m$, " "): IF x THEN m1$ = LEFT$(m$, x - 1): m2$ = RIGHT$(m$, LEN(m$) - x - 1): m$ = m1$ + SPACE$(w - LEN(m1$) - LEN(m2$)) + m2$ FOR x = 1 TO LEN(m$) IF x = h THEN IF r = i THEN COLOR 15, 0 ELSE COLOR 15, 7 ELSE IF r = i THEN COLOR 7, 0 ELSE COLOR 0, 7 END IF PRINT MID$(m$, x, 1); NEXT END IF NEXT PCOPY 1, 0 change = 0 DO mousedown = 0: mouseup = 0 GetInput lastaltheld = altheld: IF KALT THEN altheld = 1 ELSE altheld = 0 IF iCHANGED THEN IF KB THEN change = 1 IF mCLICK THEN change = 1: mousedown = 1 IF mRELEASE THEN change = 1: mouseup = 1 END IF IF mB THEN change = 1 'revert to previous menuwhen alt pressed again IF altheld <> 0 AND lastaltheld = 0 THEN DO: _LIMIT 1000: GetInput: LOOP UNTIL KALT = 0 'wait till alt is released PCOPY 3, 0: SCREEN , , 3, 0 GOTO startmenu2 END IF _LIMIT 100 LOOP UNTIL change s = 0 'mouse selection IF mouseup THEN 'uses pre-calc xx & w IF mX >= xx - 2 AND mX < xx - 2 + w + 4 THEN IF mY > 2 AND mY <= menusize(m) + 2 THEN y = mY - 2 IF menu$(m, y) <> "-" THEN s = r END IF END IF END IF IF mX < xx - 2 OR mX >= xx - 2 + w + 4 OR mY > menusize(m) + 3 THEN PCOPY 3, 0: SCREEN , , 3, 0 GOTO ideloop END IF END IF IF mB THEN 'top row IF mY = 1 THEN lastm = m x = 3 FOR i = 1 TO menus x2 = LEN(menu$(i, 0)) + 2 IF mX >= x AND mX < x + x2 THEN m = i r = 1 IF lastm = m AND mousedown = 1 THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: GOTO ideloop EXIT FOR END IF x = x + x2 IF i = menus - 1 THEN x = idewx - LEN(menu$(menus, 0)) - 2 NEXT END IF 'uses pre-calc xx & w IF mX >= xx - 2 AND mX < xx - 2 + w + 4 THEN IF mY > 2 AND mY <= menusize(m) + 2 THEN y = mY - 2 IF menu$(m, y) <> "-" THEN r = y END IF END IF END IF 'mb IF KB = KEY_LEFT THEN m = m - 1: r = 1 IF KB = KEY_RIGHT THEN m = m + 1: r = 1 IF m < 1 THEN m = menus IF m > menus THEN m = 1 IF KB = KEY_ESC THEN PCOPY 3, 0: SCREEN , , 3, 0 GOTO ideloop END IF IF KB = KEY_DOWN THEN r = r + 1 IF menu$(m, r) = "-" THEN r = r + 1 IF r > menusize(m) THEN r = 1 END IF IF KB = KEY_UP THEN r = r - 1 IF menu$(m, r) = "-" THEN r = r - 1 IF r < 1 THEN r = menusize(m) END IF 'select? 'with enter IF KB = KEY_ENTER THEN s = r END IF 'with hotkey K$ = UCASE$(K$) FOR r2 = 1 TO menusize(m) x = INSTR(menu$(m, r2), "#") IF x THEN a$ = UCASE$(MID$(menu$(m, r2), x + 1, 1)) IF K$ = a$ THEN s = r2: EXIT FOR END IF NEXT IF s THEN IF KALT THEN idehl = 1 ELSE idehl = 0 'set idehl, a shared variable used by various dialogue boxes IF menu$(m, s) = "Comment (add ')" THEN y1 = idecy: y2 = y1 IF ideselect = 1 THEN y1 = ideselecty1 IF idecy > ideselecty1 AND idecx = 1 THEN y2 = y2 - 1 IF y1 > y2 THEN SWAP y1, y2 END IF 'calculate lhs lhs = 10000000 FOR y = y1 TO y2 a$ = idegetline(y) IF LEN(a$) THEN ta$ = LTRIM$(a$) t = LEN(a$) - LEN(ta$) IF t < lhs THEN lhs = t END IF NEXT 'edit lines FOR y = y1 TO y2 a$ = idegetline(y) IF LEN(a$) THEN a$ = LEFT$(a$, lhs) + "'" + RIGHT$(a$, LEN(a$) - lhs) idesetline y, a$ idechangemade = 1 END IF NEXT PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "Uncomment (remove ')" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt y1 = idecy: y2 = y1 IF ideselect = 1 THEN y1 = ideselecty1 IF idecy > ideselecty1 AND idecx = 1 THEN y2 = y2 - 1 IF y1 > y2 THEN SWAP y1, y2 END IF 'edit lines FOR y = y1 TO y2 a$ = idegetline(y) IF LEN(a$) THEN a2$ = LTRIM$(a$) IF LEN(a2$) THEN IF ASC(a2$, 1) = 39 THEN a$ = SPACE$(LEN(a$) - LEN(a2$)) + RIGHT$(a2$, LEN(a2$) - 1) idesetline y, a$ idechangemade = 1 END IF END IF END IF NEXT PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Language..." THEN PCOPY 2, 0 retval = idelanguagebox PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Google Android..." THEN PCOPY 2, 0 retval = ideandroidbox 'retval is ignored PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Display..." THEN PCOPY 2, 0 IF idehelp = 0 THEN retval = idedisplaybox IF retval = 1 THEN 'screen dimensions have changed and everything must be redrawn/reapplied WIDTH idewx, idewy + idesubwindow IF idecustomfont THEN _FONT idecustomfonthandle ELSE _FONT 16 END IF skipdisplay = 0 GOTO redraweverything END IF END IF PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Advanced..." THEN PCOPY 2, 0 retval = ideadvancedbox 'retval is ignored PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Code layout..." THEN PCOPY 2, 0 retval = idelayoutbox IF retval THEN idechangemade = 1: idelayoutallow = 2 'recompile if options changed PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "Add/Remove #Bookmark ALT+Left" THEN PCOPY 2, 0 bmkremoved = 0 bmkremoveb: FOR b = 1 TO IdeBmkN IF IdeBmk(b).y = idecy THEN FOR b2 = b TO IdeBmkN - 1 IdeBmk(b2) = IdeBmk(b2 + 1) NEXT IdeBmkN = IdeBmkN - 1 bmkremoved = 1 ideunsaved = 1 GOTO bmkremoveb END IF NEXT IF bmkremoved = 0 THEN IdeBmkN = IdeBmkN + 1 IF IdeBmkN > UBOUND(IdeBmk) THEN x = UBOUND(IdeBmk) * 2: REDIM _PRESERVE IdeBmk(x) AS IdeBmkType IdeBmk(IdeBmkN).y = idecy IdeBmk(IdeBmkN).x = idecx ideunsaved = 1 END IF SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Next Bookmark ALT+Down" OR menu$(m, s) = "#Previous Bookmark ALT+Up" THEN PCOPY 2, 0 IF IdeBmkN = 0 THEN idemessagebox "Bookmarks", "No bookmarks exist (Use ALT+Left to create a bookmark)" PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF IdeBmkN = 1 THEN IF idecy = IdeBmk(1).y THEN idemessagebox "Bookmarks", "No other bookmarks exist" PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF END IF l = idecy z = 0: IF menu$(m, s) = "#Next Bookmark ALT+Down" THEN z = 1 DO IF z = 1 THEN l = l + 1 ELSE l = l - 1 IF l < 1 THEN l = iden IF l > iden THEN l = 1 FOR b = 1 TO IdeBmkN IF IdeBmk(b).y = l THEN EXIT DO NEXT LOOP idecy = l idecx = IdeBmk(b).x ideselect = 0 SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Go to line..." THEN PCOPY 2, 0 retval = idegotobox 'retval is ignored PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Backup/Undo..." THEN PCOPY 2, 0 retval = idebackupbox 'retval is ignored PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Update..." THEN PCOPY 2, 0 retval = ideupdatebox 'retval is ignored PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#About..." THEN PCOPY 2, 0 idemessagebox "About", "QB64 Version " + Version$ PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "ASCII c#hart" THEN PCOPY 2, 0 ideASCIIbox PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt retval = 1 GOTO redraweverything2 GOTO ideloop END IF IF menu$(m, s) = "#Contents page" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt lnk$ = "QB64 Help Menu" GOTO OpenHelpLnk END IF IF menu$(m, s) = "Keyword #index" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt lnk$ = "Keyword Reference - Alphabetical" GOTO OpenHelpLnk END IF IF menu$(m, s) = "#Keywords by usage" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt lnk$ = "Keyword Reference - By usage" GOTO OpenHelpLnk END IF IF menu$(m, s) = "#View Shift+F1" THEN IF idehelp = 0 THEN IF idesubwindow THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt: GOTO ideloop idesubwindow = idewy \ 2: idewy = idewy - idesubwindow Help_wx1 = 2: Help_wy1 = idewy + 1: Help_wx2 = idewx - 1: Help_wy2 = idewy + idesubwindow - 2: Help_ww = Help_wx2 - Help_wx1 + 1: Help_wh = Help_wy2 - Help_wy1 + 1 idehelp = 1 skipdisplay = 0 IdeSystem = 3 retval = 1: GOTO redraweverything2 END IF GOTO ideloop END IF IF menu$(m, s) = "#Update current page" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF idehelp THEN Help_IgnoreCache = 1 a$ = Wiki$(Back$(Help_Back_Pos)) Help_IgnoreCache = 0 WikiParse a$ END IF GOTO ideloop END IF IF menu$(m, s) = "#Math" THEN Mathbox PCOPY 3, 0: SCREEN , , 3, 0 GOTO ideloop END IF IF menu$(m, s) = "Update all #pages" THEN PCOPY 2, 0 q$ = ideyesnobox("Update Help", "Redownload all cached help content? (~10 min)") PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF q$ = "Y" THEN IF idehelp = 0 THEN old_idesubwindow = idesubwindow: old_idewy = idewy idesubwindow = idewy \ 2: idewy = idewy - idesubwindow Help_wx1 = 2: Help_wy1 = idewy + 1: Help_wx2 = idewx - 1: Help_wy2 = idewy + idesubwindow - 2: Help_ww = Help_wx2 - Help_wx1 + 1: Help_wh = Help_wy2 - Help_wy1 + 1 idesubwindow = old_idesubwindow: idewy = old_idewy END IF SCREEN , , 4, 4 COLOR 7, 1 CLS PRINT "Generating list of cached content..." 'Create a list of all files to be recached f$ = CHR$(0) + idezfilelist$("internal/help", 1) + CHR$(0) IF LEN(f$) = 2 THEN f$ = CHR$(0) 'Prepend core pages to list f$ = CHR$(0) + "Keyword_Reference_-_By_usage.txt" + f$ f$ = CHR$(0) + "QB64_Help_Menu.txt" + f$ f$ = CHR$(0) + "QB64_FAQ.txt" + f$ PRINT "Adding core help pages added to list..." 'Download and PARSE alphabetical index to build required F1 help links PRINT "Regenerating keyword list..." Help_Recaching = 1: Help_IgnoreCache = 1 a$ = Wiki$("Keyword Reference - Alphabetical") Help_Recaching = 0: Help_IgnoreCache = 0 WikiParse a$ 'Add all linked pages to download list (if not already in list) fh = FREEFILE OPEN "internal\help\links.bin" FOR INPUT AS #fh DO UNTIL EOF(fh) LINE INPUT #fh, l$ IF LEN(l$) THEN c = INSTR(l$, ","): PageName2$ = RIGHT$(l$, LEN(l$) - c) DO WHILE INSTR(PageName2$, " ") ASC(PageName2$, INSTR(PageName2$, " ")) = 95 LOOP DO WHILE INSTR(PageName2$, "&") i = INSTR(PageName2$, "&") PageName2$ = LEFT$(PageName2$, i - 1) + "%26" + RIGHT$(PageName2$, LEN(PageName2$) - i) LOOP DO WHILE INSTR(PageName2$, "/") i = INSTR(PageName2$, "/") PageName2$ = LEFT$(PageName2$, i - 1) + "%2F" + RIGHT$(PageName2$, LEN(PageName2$) - i) LOOP PageName2$ = PageName2$ + ".txt" IF INSTR(f$, CHR$(0) + PageName2$ + CHR$(0)) = 0 THEN f$ = f$ + PageName2$ + CHR$(0) END IF END IF LOOP CLOSE #fh 'Redownload all listed files IF f$ <> CHR$(0) THEN c = 0 'count files to download FOR x = 2 TO LEN(f$) IF ASC(f$, x) = 0 THEN c = c + 1 NEXT c = c - 1 PRINT "Updating"; c; "help content files: (Press ESC to cancel)" f$ = RIGHT$(f$, LEN(f$) - 1) z$ = CHR$(0) n = 0 DO UNTIL LEN(f$) = 0 x2 = INSTR(f$, z$) f2$ = LEFT$(f$, x2 - 1): f$ = RIGHT$(f$, LEN(f$) - x2) IF RIGHT$(f2$, 4) = ".txt" THEN f2$ = LEFT$(f2$, LEN(f2$) - 4) n = n + 1 PRINT "(" + str2$(n) + "/" + str2$(c) + ") " + f2$ Help_IgnoreCache = 1: Help_Recaching = 1: ignore$ = Wiki(f2$): Help_Recaching = 0: Help_IgnoreCache = 0 END IF GetInput DO WHILE iCHANGED IF K$ = CHR$(27) THEN GOTO stoprecache GetInput LOOP LOOP END IF stoprecache: PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt END IF GOTO ideloop END IF IF menu$(m, s) = "#Update" THEN PCOPY 2, 0 UpdateHandle = BeginDownload("www.qb64.net/update2.txt") IF UpdateHandle THEN ideupdatetimerval = TIMER DO UNTIL ABS(TIMER - ideupdatetimerval) >= 5 ContinueDownloads IF DL(UpdateHandle).State = 2 THEN 'download complete update 1 UpdateHandle = 0 GOTO ideloop END IF _LIMIT 10 LOOP CLOSE DL(UpdateHandle).Handle: DL(UpdateHandle).State = 0: UpdateHandle = 0 idemessagebox "Update", "Could not connect to server." ELSE idemessagebox "Update", "Could not connect to server." PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt END IF 'updatehandle GOTO ideloop END IF IF menu$(m, s) = "New #SUB..." THEN PCOPY 2, 0 idenewsf "SUB" ideselect = 0 PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "New #FUNCTION..." THEN PCOPY 2, 0 idenewsf "FUNCTION" ideselect = 0 PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#SUBs... F2" THEN PCOPY 2, 0 idesubsjmp: r$ = idesubs IF r$ <> "C" THEN ideselect = 0 PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Find..." THEN PCOPY 2, 0 idefindjmp: r$ = idefind PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt '... GOTO ideloop END IF IF menu$(m, s) = "#Change..." THEN PCOPY 2, 0 r$ = idechange PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF r$ = "C" OR r$ = "" THEN GOTO ideloop 'assume "V", verify changes IdeAddSearched idefindtext oldcx = idecx: oldcy = idecy found = 0: looped = 0 s$ = idefindtext$ IF idefindcasesens = 0 THEN s$ = UCASE$(s$) start = idecy: y = start startx = idecx: x1 = startx first = 1 idefindnext2: l$ = idegetline(y) IF idefindcasesens = 0 THEN l$ = UCASE$(l$) IF first = 1 THEN first = 0 ELSE x1 = 1 IF idefindbackwards THEN x1 = LEN(l$) - LEN(s$) + 1 END IF END IF IF x1 < 0 THEN x1 = 0 idefindagain2: IF idefindbackwards THEN x = 0 FOR xx = x1 TO 1 STEP -1 IF ASC(l$, xx) = ASC(s$) THEN 'first char xxo = xx - 1 FOR xx2 = xx TO xx + LEN(s$) - 1 IF ASC(l$, xx2) <> ASC(s$, xx2 - xxo) THEN EXIT FOR NEXT IF xx2 = xx + LEN(s$) THEN 'matched! x = xx EXIT FOR END IF END IF 'first char NEXT IF y = start AND looped = 1 AND x <= startx THEN x = 0 ELSE x = INSTR(x1, l$, s$) IF y = start AND looped = 1 AND x >= startx THEN x = 0 END IF IF x THEN IF idefindwholeword THEN whole = 1 IF x > 1 THEN c = ASC(UCASE$(MID$(l$, x - 1, 1))) IF c >= 65 AND c <= 90 THEN whole = 0 IF c >= 48 AND c <= 57 THEN whole = 0 END IF IF x + LEN(s$) <= LEN(l$) THEN c = ASC(UCASE$(MID$(l$, x + LEN(s$), 1))) IF c >= 65 AND c <= 90 THEN whole = 0 IF c >= 48 AND c <= 57 THEN whole = 0 END IF IF whole = 0 THEN x1 = x + 1: IF idefindbackwards THEN x1 = x - 1 x = 0 IF x1 > 0 AND x1 <= LEN(l$) THEN GOTO idefindagain2 END IF END IF END IF IF x THEN ideselect = 1 idecx = x: idecy = y ideselectx1 = x + LEN(s$): ideselecty1 = y found = 1 ideshowtext SCREEN , , 0, 0: LOCATE , , 1: SCREEN , , 3, 0 PCOPY 3, 0 r$ = idechangeit idedeltxt PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt ideselect = 0 IF r$ = "C" THEN idecx = oldcx: idecy = oldcy: GOTO ideloop IF r$ = "Y" THEN l$ = idegetline(idecy) idechangemade = 1 IF LEN(l$) >= ideselectx1 THEN l$ = LEFT$(l$, idecx - 1) + idechangeto$ + RIGHT$(l$, LEN(l$) - ideselectx1 + 1) ELSE l$ = LEFT$(l$, idecx - 1) + idechangeto$ END IF idesetline idecy, l$ IF idefindcasesens = 0 THEN l$ = UCASE$(l$) IF idefindbackwards THEN IF x <= startx AND y = start THEN startx = startx - LEN(s$) + LEN(idechangeto$) 'move startx according to the difference ELSE IF x <= startx AND y = start AND looped = 1 THEN startx = startx - LEN(s$) + LEN(idechangeto$) 'move startx according to the difference x = x + LEN(idechangeto$) - 1 'skip changed portion END IF ELSE '"N" '(no action) END IF IF idefindbackwards THEN x1 = x - 1 ELSE x1 = x + 1 GOTO idefindagain2 END IF IF idefindbackwards THEN y = y - 1 IF y = start - 1 AND looped = 1 THEN GOTO finishedchange END IF IF y < 1 THEN y = iden: looped = 1 GOTO idefindnext2 ELSE y = y + 1 IF y = start + 1 AND looped = 1 THEN GOTO finishedchange END IF IF y > iden THEN y = 1: looped = 1 GOTO idefindnext2 END IF '------------------------------------------------- finishedchange: idecx = oldcx: idecy = oldcy IF found THEN ideshowtext SCREEN , , 0, 0: LOCATE , , 1: SCREEN , , 3, 0 PCOPY 3, 0 idechanged ELSE idenomatch END IF PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF '#Change... IF menu$(m, s) = "#Repeat Last Find (Shift+) F3" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO idemf3 END IF IF menu$(m, s) = "Cl#ear Del" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF ideselect = 1 THEN idechangemade = 1 GOSUB delselect END IF GOTO ideloop END IF IF menu$(m, s) = "#Paste Shift+Ins or CTRL+V" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO idempaste END IF IF menu$(m, s) = "#Copy Ctrl+Ins or CTRL+C" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF ideselect = 1 THEN GOTO copy2clip GOTO ideloop END IF IF menu$(m, s) = "Cu#t Shift+Del or CTRL+X" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF ideselect = 1 THEN K$ = CHR$(0) + "S" 'tricks handler into del after copy GOTO idemcut END IF GOTO ideloop END IF IF menu$(m, s) = "#Undo CTRL+Z" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO idemundo END IF IF menu$(m, s) = "#Redo CTRL+Y" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO idemredo END IF IF menu$(m, s) = "Select #All CTRL+A" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO idemselectall END IF menu$(m, i) = "Select #All CTRL+A": i = i + 1 IF menu$(m, s) = "#Start F5" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt UseAndroid 0 GOTO idemrun END IF IF menu$(m, s) = "Make #Android Project" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt UseAndroid 1 GOTO idemrun END IF IF menu$(m, s) = "Start (#Detached) Ctrl+F5" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt UseAndroid 0 GOTO idemdetached END IF IF menu$(m, s) = "Make E#XE Only F11" OR menu$(m, s) = "Make E#xecutable Only F11" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt UseAndroid 0 GOTO idemexe END IF IF menu$(m, s) = "E#xit" THEN PCOPY 2, 0 quickexit: IF ideunsaved = 1 THEN r$ = idesavenow PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF r$ = "C" THEN GOTO ideloop IF r$ = "Y" THEN IF ideprogname = "" THEN r$ = idesaveas$("untitled" + tempfolderindexstr$ + ".bas") IF r$ = "C" THEN PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt: GOTO ideloop END IF ELSE idesave idepath$ + idepathsep$ + ideprogname$ END IF END IF END IF fh = FREEFILE: OPEN tmpdir$ + "autosave.bin" FOR OUTPUT AS #fh: CLOSE #fh SYSTEM END IF IF menu$(m, s) = "#New" THEN PCOPY 2, 0 IF ideunsaved = 1 THEN r$ = idesavenow PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF r$ = "C" THEN GOTO ideloop IF r$ = "Y" THEN IF ideprogname = "" THEN r$ = idesaveas$("untitled" + tempfolderindexstr$ + ".bas") PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF r$ = "C" THEN GOTO ideloop ELSE idesave idepath$ + idepathsep$ + ideprogname$ END IF END IF END IF ideunsaved = -1 'new blank text field idet$ = MKL$(0) + MKL$(0): idel = 1: ideli = 1: iden = 1: IdeBmkN = 0 idesx = 1 idesy = 1 idecx = 1 idecy = 1 ideselect = 0 ideprogname$ = "" _TITLE "QB64" idechangemade = 1 ideundobase = 0 'reset GOTO ideloop END IF FOR ml = 1 TO 4 IF LEN(IdeRecentLink(ml, 1)) THEN IF menu$(m, s) = IdeRecentLink(ml, 1) THEN IdeOpenFile$ = IdeRecentLink(ml, 2) GOTO directopen END IF END IF NEXT IF menu$(m, s) = "#Recent..." THEN PCOPY 2, 0 f$ = iderecentbox IF LEN(f$) THEN IdeOpenFile$ = f$ GOTO directopen END IF PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt GOTO ideloop END IF IF menu$(m, s) = "#Open..." THEN IdeOpenFile$ = "" directopen: PCOPY 2, 0 IF ideunsaved THEN r$ = idesavenow PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF r$ = "C" THEN GOTO ideloop IF r$ = "Y" THEN IF ideprogname = "" THEN r$ = idesaveas$("untitled" + tempfolderindexstr$ + ".bas") IF r$ = "C" THEN GOTO ideloop ELSE idesave idepath$ + idepathsep$ + ideprogname$ END IF PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt END IF '"Y" END IF 'unsaved r$ = ideopen IF r$ <> "C" THEN ideunsaved = -1: idechangemade = 1: idelayoutallow = 2: ideundobase = 0 PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt: GOTO ideloop END IF IF menu$(m, s) = "#Save" THEN PCOPY 2, 0 IF ideprogname = "" THEN a$ = idesaveas$("untitled" + tempfolderindexstr$ + ".bas") ELSE idesave idepath$ + idepathsep$ + ideprogname$ END IF PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt: GOTO ideloop END IF IF menu$(m, s) = "Save #As..." THEN PCOPY 2, 0 IF ideprogname = "" THEN a$ = idesaveas$("untitled" + tempfolderindexstr$ + ".bas") ELSE a$ = idesaveas$(ideprogname$) END IF PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt: GOTO ideloop END IF SCREEN , , 0, 0 CLS: PRINT "MENU ITEM [" + menu$(m, s) + "] NOT IMPLEMENTED!": END END IF _LIMIT 100 LOOP '-------------------------------------------------------------------------------- END FUNCTION SUB idebox (x, y, w, h) LOCATE y, x: PRINT "Ú" + STRING$(w - 2, "Ä") + "¿"; FOR y2 = y + 1 TO y + h - 2 LOCATE y2, x: PRINT "³" + SPACE$(w - 2) + "³"; NEXT LOCATE y + h - 1, x: PRINT "À" + STRING$(w - 2, "Ä") + "Ù"; END SUB SUB ideboxshadow (x, y, w, h) LOCATE y, x: PRINT "Ú" + STRING$(w - 2, "Ä") + "¿"; FOR y2 = y + 1 TO y + h - 2 LOCATE y2, x: PRINT "³" + SPACE$(w - 2) + "³"; NEXT LOCATE y + h - 1, x: PRINT "À" + STRING$(w - 2, "Ä") + "Ù"; 'shadow COLOR 8, 0 FOR y2 = y + 1 TO y + h - 1 FOR x2 = x + w TO x + w + 1 IF x2 <= idewx AND y2 <= idewy THEN LOCATE y2, x2: PRINT CHR$(SCREEN(y2, x2)); END IF NEXT NEXT y2 = y + h IF y2 <= idewy THEN FOR x2 = x + 2 TO x + w + 1 IF x2 <= idewx THEN LOCATE y2, x2: PRINT CHR$(SCREEN(y2, x2)); END IF NEXT END IF END SUB FUNCTION idechange$ '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- 'built initial search strings IF ideselect THEN IF ideselecty1 = idecy THEN 'single line selected a$ = idegetline(idecy) a2$ = "" sx1 = ideselectx1: sx2 = idecx IF sx2 < sx1 THEN SWAP sx1, sx2 FOR x = sx1 TO sx2 - 1 IF x <= LEN(a$) THEN a2$ = a2$ + MID$(a$, x, 1) ELSE a2$ = a2$ + " " NEXT END IF END IF IF a2$ = "" THEN a2$ = idefindtext END IF i = 0 idepar p, 60, 12, "Change" i = i + 1 o(i).typ = 1 o(i).y = 2 o(i).nam = idenewtxt("#Find What") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 1 o(i).y = 5 o(i).nam = idenewtxt("Change #To") o(i).txt = idenewtxt(idechangeto) o(i).v1 = LEN(idechangeto) i = i + 1 o(i).typ = 4 'check box o(i).y = 8 o(i).nam = idenewtxt("#Match Upper/Lowercase") o(i).sel = idefindcasesens i = i + 1 o(i).typ = 4 'check box o(i).y = 9 o(i).nam = idenewtxt("#Whole Word") o(i).sel = idefindwholeword i = i + 1 o(i).typ = 4 'check box o(i).y = 10 o(i).nam = idenewtxt("#Search Backwards") o(i).sel = idefindbackwards i = i + 1 o(i).typ = 3 o(i).y = 11 o(i).txt = idenewtxt("Find and #Verify" + sep + "#Change All" + sep + "Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR (focus = 8 AND info <> 0) THEN idechange$ = "C" EXIT FUNCTION END IF IF focus = 7 AND info <> 0 THEN 'change all idefindcasesens = o(3).sel idefindwholeword = o(4).sel idefindbackwards = o(5).sel s$ = idetxt(o(1).txt) idefindtext$ = s$ idechangeto$ = idetxt(o(2).txt) IdeAddSearched idefindtext changed = 0 s$ = idefindtext$ IF idefindcasesens = 0 THEN s$ = UCASE$(s$) FOR y = 1 TO iden l$ = idegetline(y) l2$ = "" x1 = 1 idechangeall: IF idefindcasesens = 0 THEN l3$ = UCASE$(l$) ELSE l3$ = l$ x = INSTR(x1, l3$, s$) IF x THEN IF idefindwholeword THEN whole = 1 IF x > 1 THEN c = ASC(UCASE$(MID$(l$, x - 1, 1))) IF c >= 65 AND c <= 90 THEN whole = 0 IF c >= 48 AND c <= 57 THEN whole = 0 END IF IF x + LEN(s$) <= LEN(l$) THEN c = ASC(UCASE$(MID$(l$, x + LEN(s$), 1))) IF c >= 65 AND c <= 90 THEN whole = 0 IF c >= 48 AND c <= 57 THEN whole = 0 END IF IF whole = 0 THEN IF x1 <= LEN(l$) THEN l2$ = l2$ + MID$(l$, x1, x - x1 + 1) x1 = x + 1 GOTO idechangeall END IF x = 0 END IF END IF END IF IF x THEN l2$ = l2$ + MID$(l$, x1, x - x1) + idechangeto$ x1 = x + LEN(s$) IF x1 <= LEN(l$) THEN GOTO idechangeall END IF l2$ = l2$ + MID$(l$, x1, LEN(l$) - x1 + 1) IF l2$ <> l$ THEN idesetline y, l2$: changed = 1 NEXT IF changed = 0 THEN idenomatch ELSE idechanged: idechangemade = 1 EXIT FUNCTION END IF 'change all IF (focus = 6 AND info <> 0) OR K$ = CHR$(13) THEN idefindcasesens = o(3).sel idefindwholeword = o(4).sel idefindbackwards = o(5).sel idefindtext$ = idetxt(o(1).txt) idechangeto$ = idetxt(o(2).txt) idechange$ = "V" EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB idechanged '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 19, 4, "" i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("OK") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 3: PRINT "Change Complete"; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "Y" THEN altletter$ = "Y" IF UCASE$(K$) = "N" THEN altletter$ = "N" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) THEN EXIT SUB END IF IF info THEN EXIT SUB END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END SUB FUNCTION idechangeit$ '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 w = 45 p.x = 40 - w \ 2 p.y = 21 p.w = w p.h = 2 p.nam = idenewtxt("Change") i = i + 1 o(i).typ = 3 o(i).y = 2 o(i).txt = idenewtxt("#Change" + sep + "#Skip" + sep + "Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "C" THEN altletter$ = "C" IF UCASE$(K$) = "S" THEN altletter$ = "S" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) THEN idechangeit$ = "C" EXIT FUNCTION END IF IF info THEN IF info = 1 THEN idechangeit$ = "Y" IF info = 2 THEN idechangeit$ = "N" IF info = 3 THEN idechangeit$ = "C" EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB idedelline (i) FOR b = 1 TO IdeBmkN IF IdeBmk(b).y >= i THEN y = IdeBmk(b).y - 1: IF y = 0 THEN y = 1 IdeBmk(b).y = y END IF NEXT idegotoline i textlen = CVL(MID$(idet$, ideli, 4)) idet$ = LEFT$(idet$, ideli - 1) + RIGHT$(idet$, LEN(idet$) - ideli + 1 - 8 - textlen) iden = iden - 1 IF i > iden THEN idegotoline iden '[2013] if last line was removed, move to previous line END SUB SUB idedeltxt idetxtlast = 0 END SUB SUB idedrawobj (o AS idedbotype, f) DIM sep AS STRING * 1 sep = CHR$(0) '#1: SINGLE LINE TEXT INPUT BOX IF o.typ = 1 THEN IF o.x = 0 THEN o.x = 2 x = o.par.x + o.x: y = o.par.y + o.y COLOR 0, 7 IF o.nam THEN a$ = idetxt(o.nam) LOCATE y, x: idehPRINT a$ + ":" x = x + idehlen(a$) + 2 END IF IF o.w = 0 THEN x2 = o.par.x + o.par.w - 1: o.w = x2 - x - 3 idebox x, y - 1, o.w + 4, 3 IF o.txt = 0 THEN o.txt = idenewtxt("") a$ = idetxt(o.txt) IF o.v1 > LEN(a$) THEN o.v1 = LEN(a$) 'new cx = o.v1 IF LEN(a$) > o.w THEN IF o.foc = 0 THEN tx = o.v1 - o.w + 1 IF tx < 1 THEN tx = 1 a$ = MID$(a$, tx, o.w) cx = cx - tx + 1 ELSE a$ = LEFT$(a$, o.w) END IF END IF x = x + 2 LOCATE y, x: PRINT a$; IF o.foc = 0 THEN o.cx = x + cx: o.cy = y f = f + 1 END IF '#1 '#2: VERTICAL SCROLLING SELECTION BOX IF o.typ = 2 THEN IF o.x = 0 THEN o.x = 2 IF o.w = 0 THEN o.w = o.par.w - 2 - o.x IF o.h = 0 THEN o.h = o.par.h - 1 - o.y x = o.par.x + o.x: y = o.par.y + o.y COLOR 0, 7 idebox x, y, o.w + 2, o.h + 2 IF o.nam THEN a$ = idetxt(o.nam) w = o.w + 2 m = w \ 2: IF w AND 1 THEN m = m + 1 LOCATE y, x + m - 1 - ((idehlen(a$) + 2) - 1) \ 2: idehPRINT " " + a$ + " " END IF 'nam 'display list items IF o.sel = 0 THEN o.sel = -1 IF o.txt = 0 THEN o.txt = idenewtxt("") IF o.stx = 0 THEN o.stx = idenewtxt("") IF o.v1 = 0 THEN o.v1 = 1 s = ABS(o.sel) IF s >= o.v1 + o.h THEN o.v1 = s - o.h + 1 IF s < o.v1 THEN o.v1 = s IF o.foc <> 0 AND o.sel > 0 THEN o.sel = -o.sel a$ = idetxt(o.txt) n = 1 y = 1 v1 = o.v1 a3$ = "" FOR i2 = 1 TO LEN(a$) a2$ = MID$(a$, i2, 1) IF a2$ <> sep THEN a3$ = a3$ + a2$ IF a2$ = sep OR i2 = LEN(a$) THEN IF n < v1 THEN 'skip ELSE IF y <= o.h THEN IF o.sel = n THEN COLOR 7, 0 ELSE COLOR 0, 7 IF (o.sel = n OR -o.sel = n) AND o.foc = 0 THEN o.cx = o.par.x + o.x + 2: o.cy = o.par.y + o.y + y LOCATE o.par.y + o.y + y, o.par.x + o.x + 1 a3$ = " " + a3$ + SPACE$(o.w) a3$ = LEFT$(a3$, o.w) PRINT a3$; y = y + 1 END IF END IF n = n + 1 a3$ = "" END IF NEXT o.num = n - 1 tnum = o.num tsel = ABS(o.sel) q = idevbar(o.par.x + o.x + o.w + 1, o.par.y + o.y + 1, o.h, tsel, tnum) f = f + 1 END IF '#2 '#3: ACTION BUTTONS IF o.typ = 3 THEN IF o.x = 0 THEN o.x = 2 IF o.w = 0 THEN o.w = o.par.w - o.x 'spanable width IF o.txt = 0 THEN o.txt = idenewtxt("OK") a$ = idetxt(o.txt) n = 1 c = 0 FOR i2 = 1 TO LEN(a$) a2$ = MID$(a$, i2, 1) IF a2$ = CHR$(0) THEN n = n + 1 ELSE IF a$ <> "#" THEN c = c + 1 END IF NEXT w = o.w c = c + n * 4 'add characters for bracing < > buttons whitespace = w - c spacing = whitespace \ (n + 1) f2 = o.foc + 1 IF f2 < 1 OR f2 > n THEN IF o.dft THEN f2 = o.dft END IF n2 = 1 a3$ = "" LOCATE o.par.y + o.y, o.par.x + o.x x = o.par.x + o.x COLOR 0, 7 FOR i2 = 1 TO LEN(a$) a2$ = MID$(a$, i2, 1) IF a2$ <> CHR$(0) THEN a3$ = a3$ + a2$ IF a2$ = CHR$(0) OR i2 = LEN(a$) THEN PRINT SPACE$(spacing); x = x + spacing IF f2 = n2 THEN COLOR 15, 7 ELSE COLOR 0, 7 PRINT "< "; COLOR 0, 7: idehPRINT a3$ IF f2 = n2 THEN COLOR 15, 7 ELSE COLOR 0, 7 IF n2 = o.foc + 1 THEN o.cx = x + 2: o.cy = o.par.y + o.y END IF PRINT " >"; COLOR 0, 7 x = x + idehlen(a3$) + 4 a3$ = "" n2 = n2 + 1 END IF NEXT f = f + n END IF '#3 '#4: CHECK BOX IF o.typ = 4 THEN IF o.x = 0 THEN o.x = 2 x = o.par.x + o.x: y = o.par.y + o.y LOCATE y, x COLOR 0, 7 IF o.sel THEN PRINT "[X] "; ELSE PRINT "[ ] "; END IF IF o.nam THEN a$ = idetxt(o.nam) idehPRINT a$ END IF IF o.foc = 0 THEN o.cx = x + 1: o.cy = y f = f + 1 END IF '#4 END SUB SUB idedrawpar (p AS idedbptype) COLOR 0, 7: ideboxshadow p.x, p.y, p.w + 2, p.h + 2 IF p.nam THEN x = LEN(idetxt(p.nam)) + 2 COLOR 0, 7: LOCATE p.y, (idewx \ 2) - (x - 1) \ 2: PRINT " " + idetxt(p.nam) + " "; END IF END SUB SUB ideerrormessage (mess$) '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, LEN(mess$) + 4, 4, "" i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("OK") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 3: PRINT mess$; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "Y" THEN altletter$ = "Y" IF UCASE$(K$) = "N" THEN altletter$ = "N" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) THEN EXIT SUB END IF IF info THEN EXIT SUB END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END SUB FUNCTION idefileexists$ '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 'idepar p, 30, 6, "File already exists. Overwrite?" idepar p, 35, 4, "" i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("#Yes" + sep + "#No") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 3: PRINT "File already exists. Overwrite?"; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "Y" THEN altletter$ = "Y" IF UCASE$(K$) = "N" THEN altletter$ = "N" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) THEN idefileexists$ = "N" EXIT FUNCTION END IF IF info THEN IF info = 1 THEN idefileexists$ = "Y" ELSE idefileexists$ = "N" EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION idefind$ '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- 'built initial search string IF ideselect THEN IF ideselecty1 = idecy THEN 'single line selected a$ = idegetline(idecy) a2$ = "" sx1 = ideselectx1: sx2 = idecx IF sx2 < sx1 THEN SWAP sx1, sx2 FOR x = sx1 TO sx2 - 1 IF x <= LEN(a$) THEN a2$ = a2$ + MID$(a$, x, 1) ELSE a2$ = a2$ + " " NEXT END IF END IF IF a2$ = "" THEN a2$ = idefindtext END IF i = 0 idepar p, 60, 9, "Find" i = i + 1 o(i).typ = 1 o(i).y = 2 o(i).nam = idenewtxt("#Find What") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 4 'check box o(i).y = 5 o(i).nam = idenewtxt("#Match Upper/Lowercase") o(i).sel = idefindcasesens i = i + 1 o(i).typ = 4 'check box o(i).y = 6 o(i).nam = idenewtxt("#Whole Word") o(i).sel = idefindwholeword i = i + 1 o(i).typ = 4 'check box o(i).y = 7 o(i).nam = idenewtxt("#Search Backwards") o(i).sel = idefindbackwards i = i + 1 o(i).typ = 3 o(i).y = 9 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR (focus = 6 AND info <> 0) THEN idefind$ = "C" EXIT FUNCTION END IF IF K$ = CHR$(13) OR (focus = 5 AND info <> 0) THEN idefindcasesens = o(2).sel idefindwholeword = o(3).sel idefindbackwards = o(4).sel s$ = idetxt(o(1).txt) idefindtext$ = s$ IdeAddSearched idefindtext idefindagain EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB idefindagain IF idefindinvert THEN IF idefindbackwards = 0 THEN idefindbackwards = 1 ELSE idefindbackwards = 0 END IF s$ = idefindtext$ IF idefindcasesens = 0 THEN s$ = UCASE$(s$) start = idecy y = start idefindnext2: l$ = idegetline(y) IF idefindcasesens = 0 THEN l$ = UCASE$(l$) IF y = start THEN 'retrieve the unscanned portion of this line only IF looped = 1 THEN IF idefindbackwards THEN IF LEN(l$) > idecx THEN l$ = STRING$(idecx, 255) + RIGHT$(l$, LEN(l$) - idecx) ELSE l$ = "" ELSE IF LEN(l$) > idecx THEN l$ = LEFT$(l$, idecx) END IF ELSE IF idefindbackwards THEN IF LEN(l$) > idecx THEN l$ = LEFT$(l$, idecx - 1 + (LEN(s$) - 1)) ELSE IF LEN(l$) > idecx THEN l$ = STRING$(idecx, 255) + RIGHT$(l$, LEN(l$) - idecx) ELSE l$ = "" END IF END IF END IF x1 = 1 IF idefindbackwards THEN x1 = LEN(l$) - LEN(s$) + 1 IF x1 < 0 THEN x1 = 0 END IF idefindagain2: IF idefindbackwards THEN x = 0 FOR xx = x1 TO 1 STEP -1 IF ASC(l$, xx) = ASC(s$) THEN 'first char xxo = xx - 1 FOR xx2 = xx TO xx + LEN(s$) - 1 IF ASC(l$, xx2) <> ASC(s$, xx2 - xxo) THEN EXIT FOR NEXT IF xx2 = xx + LEN(s$) THEN 'matched! x = xx EXIT FOR END IF END IF 'first char NEXT ELSE x = INSTR(x1, l$, s$) END IF IF x THEN IF idefindwholeword THEN whole = 1 IF x > 1 THEN c = ASC(UCASE$(MID$(l$, x - 1, 1))) IF c >= 65 AND c <= 90 THEN whole = 0 IF c >= 48 AND c <= 57 THEN whole = 0 END IF IF x + LEN(s$) <= LEN(l$) THEN c = ASC(UCASE$(MID$(l$, x + LEN(s$), 1))) IF c >= 65 AND c <= 90 THEN whole = 0 IF c >= 48 AND c <= 57 THEN whole = 0 END IF IF whole = 0 THEN x1 = x + 1: IF idefindbackwards THEN x1 = x - 1 x = 0 IF x1 > 0 AND x1 <= LEN(l$) THEN GOTO idefindagain2 END IF END IF END IF IF x THEN ideselect = 1 idecx = x: idecy = y ideselectx1 = x + LEN(s$): ideselecty1 = y IF idefindinvert THEN IF idefindbackwards = 0 THEN idefindbackwards = 1 ELSE idefindbackwards = 0 idefindinvert = 0 END IF EXIT SUB END IF IF idefindbackwards THEN y = y - 1 IF y = start - 1 AND looped = 1 THEN idenomatch IF idefindinvert THEN IF idefindbackwards = 0 THEN idefindbackwards = 1 ELSE idefindbackwards = 0 idefindinvert = 0 END IF EXIT SUB END IF IF y < 1 THEN y = iden: looped = 1 GOTO idefindnext2 ELSE y = y + 1 IF y = start + 1 AND looped = 1 THEN idenomatch IF idefindinvert THEN IF idefindbackwards = 0 THEN idefindbackwards = 1 ELSE idefindbackwards = 0 idefindinvert = 0 END IF EXIT SUB END IF IF y > iden THEN y = 1: looped = 1 GOTO idefindnext2 END IF END SUB FUNCTION idegetline$ (i) IF i <> -1 THEN idegotoline i idegetline$ = MID$(idet$, ideli + 4, CVL(MID$(idet$, ideli, 4))) END FUNCTION SUB idegotoline (i) IF idel = i THEN EXIT SUB IF i < 1 THEN ERROR 5 'scan backwards IF i < idel THEN DO idel = idel - 1 ideli = ideli - CVL(MID$(idet$, ideli - 4, 4)) - 8 LOOP UNTIL idel = i EXIT SUB END IF 'assume scan forwards DO IF idel = iden THEN idet$ = idet$ + MKL$(0) + MKL$(0): iden = iden + 1 'insert blank line at end? idel = idel + 1 ideli = ideli + CVL(MID$(idet$, ideli, 4)) + 8 LOOP UNTIL idel = i END SUB FUNCTION idehbar (x, y, h, i2, n2) i = i2: n = n2 'COLOR 0, 7 'LOCATE y, x: PRINT CHR$(27); 'LOCATE y, x + w - 1: PRINT CHR$(26); 'FOR x2 = x + 1 TO x + w - 2 'LOCATE y, x2: PRINT "°"; 'NEXT 'IF w > 3 THEN 'p2! = w - 2 - .00001 'x2 = x + 1 + INT(p2! * p!) 'LOCATE y, x2: PRINT "Û"; 'END IF 'h is size in characters (inc. arrows) 'draw background & arrows COLOR 0, 7 LOCATE y, x: PRINT CHR$(27); LOCATE y, x + h - 1: PRINT CHR$(26); FOR x2 = x + 1 TO x + h - 2 LOCATE y, x2: PRINT "°"; NEXT 'draw slider IF n < 1 THEN n = 1 IF i < 1 THEN i = 1 IF i > n THEN i = n IF h = 2 THEN idehbar = x 'not position for slider exists EXIT FUNCTION END IF IF h = 3 THEN idehbar = x + 1 'dummy value 'no slider EXIT FUNCTION END IF IF h = 4 THEN IF n = 1 THEN idehbar = x + 1 'dummy value 'no slider required for 1 item EXIT FUNCTION ELSE 'show whichever is closer of the two positions p! = (i - 1) / (n - 1) IF p! < .5 THEN x2 = x + 1 ELSE x2 = x + 2 LOCATE y, x2: PRINT "Û"; idehbar = x2 EXIT FUNCTION END IF END IF IF h > 4 THEN IF n = 1 THEN idehbar = x + h \ 4 'dummy value 'no slider required for 1 item EXIT FUNCTION END IF IF i = 1 THEN x2 = x + 1 LOCATE y, x2: PRINT "Û"; idehbar = x2 EXIT FUNCTION END IF IF i = n THEN x2 = x + h - 2 LOCATE y, x2: PRINT "Û"; idehbar = x2 EXIT FUNCTION END IF 'between i=1 and i=n p! = (i - 1) / (n - 1) p! = p! * (h - 4) x2 = x + 2 + INT(p!) LOCATE y, x2: PRINT "Û"; idehbar = x2 EXIT FUNCTION END IF END FUNCTION FUNCTION idehlen (a$) IF INSTR(a$, "#") THEN idehlen = LEN(a$) - 1 ELSE idehlen = LEN(a$) END FUNCTION SUB idehPRINT (a$) COLOR 0, 7 FOR i = 1 TO LEN(a$) c$ = MID$(a$, i, 1) IF c$ = "#" THEN IF idehl THEN COLOR 15, 7 ELSE PRINT c$;: COLOR 0, 7 END IF NEXT END SUB SUB ideinsline (i, text$) 'note: cursor remains on line i FOR b = 1 TO IdeBmkN IF IdeBmk(b).y >= i THEN y = IdeBmk(b).y + 1 IdeBmk(b).y = y END IF NEXT text$ = RTRIM$(text$) IF i = -1 THEN i = idel 'if at end, use idesetline IF i > iden THEN idesetline i, text$ EXIT SUB END IF idegotoline i 'insert line textlen = LEN(text$) idet$ = LEFT$(idet$, ideli - 1) + MKL$(textlen) + text$ + MKL$(textlen) + RIGHT$(idet$, LEN(idet$) - ideli + 1) iden = iden + 1 END SUB SUB idenewsf (sf AS STRING) '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- 'built initial name if word selected IF ideselect THEN IF ideselecty1 = idecy THEN 'single line selected a$ = idegetline(idecy) a2$ = "" sx1 = ideselectx1: sx2 = idecx IF sx2 < sx1 THEN SWAP sx1, sx2 FOR x = sx1 TO sx2 - 1 IF x <= LEN(a$) THEN a2$ = a2$ + MID$(a$, x, 1) ELSE a2$ = a2$ + " " NEXT END IF END IF i = 0 idepar p, 60, 5, "New " + sf$ i = i + 1 o(i).typ = 1 o(i).y = 2 o(i).nam = idenewtxt("#Name") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 3 o(i).y = 5 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR (focus = 3 AND info <> 0) THEN EXIT SUB END IF IF K$ = CHR$(13) OR (focus = 2 AND info <> 0) THEN y = iden y = y + 1: idesetline y, "" y = y + 1: idesetline y, sf$ + " " + idetxt(o(1).txt) idesy = y y = y + 1: idesetline y, "" idecy = y y = y + 1: idesetline y, "END " + sf$ idecx = 1: idesx = 1 idechangemade = 1 EXIT SUB END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END SUB FUNCTION idenewtxt (a$) idetxtlast = idetxtlast + 1 idetxt$(idetxtlast) = a$ idenewtxt = idetxtlast END FUNCTION SUB idenomatch '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 19, 4, "" i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("OK") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 3: PRINT "Match not found"; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "Y" THEN altletter$ = "Y" IF UCASE$(K$) = "N" THEN altletter$ = "N" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) THEN EXIT SUB END IF IF info THEN EXIT SUB END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END SUB FUNCTION ideopen$ STATIC AllFiles '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- path$ = idepath$ filelist$ = idezfilelist$(path$, AllFiles) pathlist$ = idezpathlist$(path$) i = 0 idepar p, 70, idewy + idesubwindow - 7, "Open" i = i + 1 o(i).typ = 1 o(i).y = 2 o(i).nam = idenewtxt("File #Name") i = i + 1 o(i).typ = 2 o(i).y = 5 o(i).w = 32: o(i).h = idewy + idesubwindow - 14 o(i).nam = idenewtxt("#Files") o(i).txt = idenewtxt(filelist$): filelist$ = "" i = i + 1 o(i).typ = 2 o(i).x = 37: o(i).y = 5 o(i).w = 31: o(i).h = idewy + idesubwindow - 16 o(i).nam = idenewtxt("#Paths") o(i).txt = idenewtxt(pathlist$): pathlist$ = "" i = i + 1 o(i).typ = 4 'check box o(i).x = 37 o(i).y = idewy + idesubwindow - 9 o(i).nam = idenewtxt(".BAS Only") IF AllFiles THEN o(i).sel = 0 ELSE o(i).sel = 1 i = i + 1 o(i).typ = 3 o(i).y = idewy + idesubwindow - 7 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- IF LEN(IdeOpenFile) THEN f$ = IdeOpenFile: GOTO DirectLoad DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 4, p.x + 2: PRINT "Path: "; a$ = path$ w = p.w - 8 IF LEN(a$) > w - 3 THEN a$ = "úúú" + RIGHT$(a$, w - 3) PRINT a$; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF AllFiles = 1 AND o(4).sel <> 0 THEN AllFiles = 0 idetxt(o(2).txt) = idezfilelist$(path$, AllFiles) o(2).sel = -1 GOTO ideopenloop END IF IF AllFiles = 0 AND o(4).sel = 0 THEN AllFiles = 1 idetxt(o(2).txt) = idezfilelist$(path$, AllFiles) o(2).sel = -1 GOTO ideopenloop END IF IF K$ = CHR$(27) OR (focus = 6 AND info <> 0) THEN ideopen$ = "C" EXIT FUNCTION END IF IF idetxt(o(2).stx) <> "" THEN idetxt(o(1).txt) = idetxt(o(2).stx) o(1).v1 = LEN(idetxt(o(1).txt)) END IF IF focus = 3 THEN IF K$ = CHR$(13) OR info = 1 THEN path$ = idezchangepath(path$, idetxt(o(3).stx)) idetxt(o(2).txt) = idezfilelist$(path$, AllFiles) idetxt(o(3).txt) = idezpathlist$(path$) o(2).sel = -1 o(3).sel = 1 IF info = 1 THEN o(3).sel = -1 GOTO ideopenloop END IF END IF 'load file IF K$ = CHR$(13) OR (info = 1 AND focus = 2) OR (focus = 5 AND info <> 0) THEN f$ = idetxt(o(1).txt) 'change path? IF f$ = ".." OR f$ = "." THEN f$ = f$ + idepathsep$ IF RIGHT$(f$, 1) = idepathsep$ THEN path$ = idezgetfilepath$(path$, f$) 'note: path ending with pathsep needn't contain a file idetxt(o(1).txt) = "" idetxt(o(2).txt) = idezfilelist$(path$, AllFiles) o(2).sel = -1 idetxt(o(3).txt) = idezpathlist$(path$) o(3).sel = -1 GOTO ideopenloop END IF 'add .bas if not given IF (LCASE$(RIGHT$(f$, 4)) <> ".bas") AND AllFiles = 0 THEN f$ = f$ + ".bas" DirectLoad: 'check/acquire file path path$ = idezgetfilepath$(path$, f$) 'check file exists ideerror = 2 OPEN path$ + idepathsep$ + f$ FOR INPUT AS #150: CLOSE #150 'load file ideerror = 3 idet$ = MKL$(0) + MKL$(0): idel = 1: ideli = 1: iden = 1: IdeBmkN = 0 idesx = 1 idesy = 1 idecx = 1 idecy = 1 ideselect = 0 lineinput3load path$ + idepathsep$ + f$ idet$ = SPACE$(LEN(lineinput3buffer) * 8) i2 = 1 n = 0 chrtab$ = CHR$(9) space1$ = " ": space2$ = " ": space3$ = " ": space4$ = " " chr7$ = CHR$(7): chr11$ = CHR$(11): chr12$ = CHR$(12): chr28$ = CHR$(28): chr29$ = CHR$(29): chr30$ = CHR$(30): chr31$ = CHR$(31) DO a$ = lineinput3$ l = LEN(a$) IF l THEN asca = ASC(a$) ELSE asca = -1 IF asca <> 13 THEN IF asca <> -1 THEN 'fix tabs ideopenfixtabs: x = INSTR(a$, chrtab$) IF x THEN x2 = (x - 1) MOD 4 IF x2 = 0 THEN a$ = LEFT$(a$, x - 1) + space4$ + RIGHT$(a$, l - x): l = l + 3: GOTO ideopenfixtabs IF x2 = 1 THEN a$ = LEFT$(a$, x - 1) + space3$ + RIGHT$(a$, l - x): l = l + 2: GOTO ideopenfixtabs IF x2 = 2 THEN a$ = LEFT$(a$, x - 1) + space2$ + RIGHT$(a$, l - x): l = l + 1: GOTO ideopenfixtabs IF x2 = 3 THEN a$ = LEFT$(a$, x - 1) + space1$ + RIGHT$(a$, l - x): GOTO ideopenfixtabs END IF END IF 'asca<>-1 MID$(idet$, i2, l + 8) = MKL$(l) + a$ + MKL$(l): i2 = i2 + l + 8: n = n + 1 END IF LOOP UNTIL asca = 13 lineinput3buffer = "" iden = n: IF n = 0 THEN idet$ = MKL$(0) + MKL$(0): iden = 1 ELSE idet$ = LEFT$(idet$, i2 - 1) ideerror = 1 ideprogname = f$: _TITLE ideprogname + " - QB64" idepath$ = path$ IdeAddRecent idepath$ + idepathsep$ + ideprogname$ IdeImportBookmarks idepath$ + idepathsep$ + ideprogname$ EXIT FUNCTION END IF ideopenloop: 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB idepar (par AS idedbptype, w, h, title$) par.x = (idewx \ 2) - w \ 2 par.y = ((idewy + idesubwindow) \ 2) - h \ 2 par.w = w par.h = h IF LEN(title$) THEN par.nam = idenewtxt(title$) END SUB FUNCTION iderestore$ '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 'idepar p, 30, 6, "File already exists. Overwrite?" idepar p, 43, 4, "" i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("#Yes" + sep + "#No") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 3: PRINT "Recover program from auto-saved backup?"; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "Y" THEN altletter$ = "Y" IF UCASE$(K$) = "N" THEN altletter$ = "N" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF info THEN IF info = 1 THEN iderestore$ = "Y" ELSE iderestore$ = "N" EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB idesave (f$) OPEN f$ FOR OUTPUT AS #151 FOR i = 1 TO iden a$ = idegetline(i) PRINT #151, a$ NEXT CLOSE #151 IdeSaveBookmarks f$ ideunsaved = 0 END SUB FUNCTION idesaveas$ (programname$) '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- path$ = idepath$ pathlist$ = idezpathlist$(path$) i = 0 idepar p, 48, idewy + idesubwindow - 7, "Save As" i = i + 1 o(i).typ = 1 o(i).y = 2 o(i).nam = idenewtxt("File #Name") o(i).txt = idenewtxt(programname$) o(i).v1 = LEN(programname$) 'i = i + 1 'o(i).typ = 2 'o(i).y = 5 'o(i).w = 32: o(i).h = 11 'o(i).nam = idenewtxt("#Files") 'o(i).txt = idenewtxt(filelist$): filelist$ = "" i = i + 1 o(i).typ = 2 'o(i).x = 10: o(i).y = 5 o(i).w = 44: o(i).h = idewy + idesubwindow - 14 o(i).nam = idenewtxt("#Paths") o(i).txt = idenewtxt(pathlist$): pathlist$ = "" i = i + 1 o(i).typ = 3 o(i).y = idewy + idesubwindow - 7 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 4, p.x + 2: PRINT "Path: "; a$ = path$ w = p.w - 8 IF LEN(a$) > w - 3 THEN a$ = "úúú" + RIGHT$(a$, w - 3) PRINT a$; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) OR (focus = 4 AND info <> 0) THEN idesaveas$ = "C" EXIT FUNCTION END IF IF focus = 2 THEN IF K$ = CHR$(13) OR info = 1 THEN path$ = idezchangepath(path$, idetxt(o(2).stx)) idetxt(o(2).txt) = idezpathlist$(path$) o(2).sel = 1 IF info = 1 THEN o(2).sel = -1 END IF END IF IF (K$ = CHR$(13) AND focus <> 2) OR (focus = 3 AND info <> 0) THEN f$ = idetxt(o(1).txt) 'change path? IF f$ = ".." OR f$ = "." THEN f$ = f$ + idepathsep$ IF RIGHT$(f$, 1) = idepathsep$ THEN path$ = idezgetfilepath$(path$, f$) 'note: path ending with pathsep needn't contain a file idetxt(o(1).txt) = "" idetxt(o(2).txt) = idezpathlist$(path$) o(2).sel = -1 GOTO idesaveasloop END IF IF FileHasExtension(f$) = 0 THEN f$ = f$ + ".bas" path$ = idezgetfilepath$(path$, f$) ideerror = 3 OPEN path$ + idepathsep$ + f$ FOR BINARY AS #150 ideerror = 1 IF LOF(150) THEN CLOSE #150 a$ = idefileexists IF a$ = "N" THEN idesaveas$ = "C" EXIT FUNCTION 'user didn't agree to overwrite END IF ELSE CLOSE #150 END IF ideprogname$ = f$: _TITLE ideprogname + " - QB64" idesave path$ + idepathsep$ + f$ idepath$ = path$ IdeAddRecent idepath$ + idepathsep$ + ideprogname$ IdeSaveBookmarks idepath$ + idepathsep$ + ideprogname$ EXIT FUNCTION END IF idesaveasloop: 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION idesavenow$ '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 40, 4, "" i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("#Yes" + sep + "#No" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 4: PRINT "Program is not saved. Save it now?"; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "Y" THEN altletter$ = "Y" IF UCASE$(K$) = "N" THEN altletter$ = "N" IF UCASE$(K$) = "C" THEN altletter$ = "C" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) THEN idesavenow$ = "C" EXIT FUNCTION END IF IF info THEN IF info = 1 THEN idesavenow$ = "Y" IF info = 2 THEN idesavenow$ = "N" IF info = 3 THEN idesavenow$ = "C" EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB idesetline (i, text$) text$ = RTRIM$(text$) IF i <> -1 THEN idegotoline i textlen = LEN(text$) idet$ = LEFT$(idet$, ideli - 1) + MKL$(textlen) + text$ + MKL$(textlen) + RIGHT$(idet$, LEN(idet$) - ideli + 1 - CVL(MID$(idet$, ideli, 4)) - 8) END SUB SUB ideshowtext cc = -1 IF idecx < idesx THEN idesx = idecx IF idecy < idesy THEN idesy = idecy IF idecx - idesx >= (idewx - 2) THEN idesx = idecx - (idewx - 3) IF idecy - idesy >= (idewy - 8) THEN idesy = idecy - (idewy - 9) sy1 = ideselecty1 sy2 = idecy IF sy1 > sy2 THEN SWAP sy1, sy2 sx1 = ideselectx1 sx2 = idecx IF sx1 > sx2 THEN SWAP sx1, sx2 l = idesy FOR y = 0 TO (idewy - 9) LOCATE y + 3, 1 COLOR 7, 1 PRINT CHR$(179); 'clear prev bookmarks from lhs IF l = idefocusline AND idecy <> l THEN COLOR 7, 4 ELSE COLOR 7, 1 IF l <= iden THEN a$ = idegetline(l) IF l = idecy THEN IF idecx <= LEN(a$) THEN cc = ASC(a$, idecx) IF cc = 32 THEN IF LTRIM$(LEFT$(a$, idecx)) = "" THEN cc = -1 END IF END IF END IF a2$ = SPACE$(idesx + (idewx - 3)) MID$(a2$, 1) = a$ a2$ = RIGHT$(a2$, (idewx - 2)) ELSE a2$ = SPACE$((idewx - 2)) END IF ' ### STEVE EDIT TO MAKE QUOTES AND COMMENTS STAND OUT WITH MINOR COLOR ADJUSTMENTS ### 'FOR x = 1 TO LEN(a2$) ' PRINT CHR$(ASC(a2$, x)); 'NEXT inquote = 0 comment = 0 FOR k = 1 TO idesx 'First check the part of the line that's off screen to the left SELECT CASE MID$(a$, k, 1) CASE CHR$(34) inquote = NOT inquote CASE "'" IF inquote = 0 THEN comment = -1 END IF END SELECT NEXT k FOR m = 1 TO LEN(a2$) 'continue checking, while printing to the screen SELECT CASE MID$(a$, m + idesx - 1, 1) CASE CHR$(34) inquote = NOT inquote CASE "'" IF inquote = 0 THEN comment = -1 END IF END SELECT IF comment THEN COLOR 11 ELSEIF inquote OR MID$(a2$, m, 1) = CHR$(34) THEN COLOR 14 ELSE COLOR 15 END IF LOCATE y + 3, 2 + m - 1 PRINT MID$(a2$, m, 1); NEXT m '### END OF STEVE EDIT 'apply selection color change if necessary IF ideselect THEN IF l >= sy1 AND l <= sy2 THEN IF sy1 = sy2 THEN 'single line select COLOR 1, 7 x2 = idesx FOR x = 2 TO (idewx - 2) IF x2 >= sx1 AND x2 < sx2 THEN a = SCREEN(y + 3, x) IF a = 63 THEN '"?" c = SCREEN(y + 3, x, 1) ELSE c = 1 END IF IF (c AND 15) = 0 THEN 'black background COLOR 0, 7 LOCATE y + 3, x: PRINT "?"; COLOR 1, 7 ELSE LOCATE y + 3, x: PRINT CHR$(a); END IF END IF x2 = x2 + 1 NEXT COLOR 7, 1 ELSE 'multiline select IF idecx = 1 AND l = sy2 AND idecy > sy1 THEN GOTO nofinalselect LOCATE y + 3, 2 COLOR 1, 7 FOR x = 1 TO LEN(a2$) PRINT CHR$(ASC(a2$, x)); NEXT COLOR 7, 1 nofinalselect: END IF END IF END IF l = l + 1 NEXT COLOR 7, 1 FOR b = 1 TO IdeBmkN y = IdeBmk(b).y IF y >= idesy AND y <= idesy + (idewy - 9) THEN LOCATE 3 + y - idesy, 1: PRINT "Å"; END IF NEXT q = idevbar(idewx, 3, (idewy - 8), idecy, iden) q = idehbar(2, (idewy - 5), (idewx - 2), idesx, 608) 'update cursor pos in status bar COLOR 0, 3 LOCATE idewy + idesubwindow, idewx - 20: PRINT " : "; IF idecx < 100000 THEN LOCATE idewy + idesubwindow, idewx - 9 a$ = LTRIM$(STR$(idecx)) PRINT a$; IF cc <> -1 THEN PRINT "(" + str2$(cc) + ")"; END IF a$ = LTRIM$(STR$(idecy)) LOCATE idewy + idesubwindow, (idewx - 10) - LEN(a$) PRINT a$; SCREEN , , 0, 0: LOCATE idecy - idesy + 3, idecx - idesx + 2: SCREEN , , 3, 0 END SUB FUNCTION idesubs$ '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- ly$ = MKL$(1) l$ = ideprogname$ IF l$ = "" THEN l$ = "Untitled" + tempfolderindexstr$ FOR y = 1 TO iden a$ = idegetline(y) a$ = LTRIM$(RTRIM$(a$)) sf = 0 nca$ = UCASE$(a$) IF LEFT$(nca$, 4) = "SUB " THEN sf = 1: sf$ = "SUB " IF LEFT$(nca$, 9) = "FUNCTION " THEN sf = 2: sf$ = "FUNC " IF sf THEN IF RIGHT$(nca$, 7) = " STATIC" THEN a$ = RTRIM$(LEFT$(a$, LEN(a$) - 7)) END IF ly$ = ly$ + MKL$(y) IF sf = 1 THEN a$ = RIGHT$(a$, LEN(a$) - 4) ELSE a$ = RIGHT$(a$, LEN(a$) - 9) END IF a$ = LTRIM$(RTRIM$(a$)) x = INSTR(a$, "(") IF x THEN n$ = RTRIM$(LEFT$(a$, x - 1)) args$ = RIGHT$(a$, LEN(a$) - x + 1) ELSE n$ = a$ args$ = "" END IF IF LEN(n$) <= 20 THEN n$ = n$ + SPACE$(20 - LEN(n$)) ELSE n$ = LEFT$(n$, 17) + "úúú" END IF IF LEN(args$) <= (idewx - 41) THEN args$ = args$ + SPACE$((idewx - 41) - LEN(args$)) ELSE args$ = LEFT$(args$, (idewx - 44)) + "úúú" END IF l$ = l$ + sep + "ÃÄ" + n$ + " " + sf$ + args$ END IF NEXT FOR x = LEN(l$) TO 1 STEP -1 a$ = MID$(l$, x, 1) IF a$ = "Ã" THEN MID$(l$, x, 1) = "À": EXIT FOR NEXT '72,19 i = 0 idepar p, idewx - 8, idewy + idesubwindow - 6, "SUBs" i = i + 1 o(i).typ = 2 o(i).y = 1 '68 o(i).w = idewx - 12: o(i).h = idewy + idesubwindow - 9 o(i).txt = idenewtxt(l$) o(i).sel = 1 o(i).nam = idenewtxt("Program Items") i = i + 1 o(i).typ = 3 o(i).y = idewy + idesubwindow - 6 o(i).txt = idenewtxt("#Edit" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) OR (focus = 3 AND info <> 0) THEN idesubs$ = "C" EXIT FUNCTION END IF IF K$ = CHR$(13) OR (focus = 2 AND info <> 0) OR (info = 1 AND focus = 1) THEN y = o(1).sel IF y < 1 THEN y = -y idecy = CVL(MID$(ly$, y * 4 - 3, 4)) idesy = idecy idecx = 1 idesx = 1 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION idelanguagebox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- 'generate list of available code pages l$ = idecpname(1) FOR x = 2 TO idecpnum l$ = l$ + sep + idecpname(x) NEXT l$ = UCASE$(l$) i = 0 idepar p, idewx - 8, idewy + idesubwindow - 6, "Language" i = i + 1 o(i).typ = 2 o(i).y = 2 o(i).w = idewx - 12: o(i).h = idewy + idesubwindow - 10 o(i).txt = idenewtxt(l$) o(i).sel = 1: IF idecpindex THEN o(i).sel = idecpindex o(i).nam = idenewtxt("Code Pages") i = i + 1 o(i).typ = 3 o(i).y = idewy + idesubwindow - 6 o(i).txt = idenewtxt("#OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 1, p.x + 2: PRINT "Code-page for ASCII-UNICODE mapping: (Default: CP437)" '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) OR (focus = 3 AND info <> 0) THEN ' idesubs$ = "C" EXIT FUNCTION END IF IF K$ = CHR$(13) OR (focus = 2 AND info <> 0) OR (info = 1 AND focus = 1) THEN y = o(1).sel IF y < 1 THEN y = -y FOR x = 128 TO 255 u = VAL("&H" + MID$(idecp(y), x * 8 + 1, 8) + "&") IF u = 0 THEN u = 9744 _MAPUNICODE u TO x NEXT 'SEEK 1049 '[2] codepage(=0) 'total bytes: 1050 'save changes OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 SEEK #150, 1049 v% = y: PUT #150, , v%: idecpindex = v% CLOSE #150 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB ideupdateobj (o AS idedbotype, focus, f, focusoffset, kk$, altletter$, mb, mousedown, mouseup, mx, my, info, mw) DIM sep AS STRING * 1 sep = CHR$(0) t = o.typ IF t = 1 THEN 'text field IF mousedown THEN x1 = o.par.x + o.x: y = o.par.y + o.y x2 = x1 IF o.nam THEN x2 = x2 + idehlen(idetxt(o.nam)) + 2 END IF IF my >= y - 1 AND my <= y + 1 THEN IF mx >= x1 AND mx <= x2 + o.w + 3 THEN focus = f 'change cursor location? IF my = y THEN IF mx > x2 + 1 AND mx < x2 + o.w + 2 THEN a$ = idetxt(o.txt) x = mx - x2 - 2 '0-? IF x = o.v1 AND x <> LEN(a$) THEN 'dbl-click text=clear field text a$ = "" idetxt(o.txt) = a$ o.v1 = 0 ELSE IF x <= LEN(a$) THEN o.v1 = x ELSE o.v1 = LEN(a$) END IF END IF END IF END IF END IF END IF 'mousedown IF focusoffset = 0 THEN a$ = idetxt(o.txt) IF LEN(kk$) = 1 THEN k = ASC(kk$) IF k = 8 AND o.v1 > 0 THEN a1$ = LEFT$(a$, o.v1 - 1) IF o.v1 <= LEN(a$) THEN a2$ = RIGHT$(a$, LEN(a$) - o.v1) ELSE a2$ = "" a$ = a1$ + a2$: o.v1 = o.v1 - 1 END IF IF k <> 8 AND k <> 9 AND k <> 0 AND k <> 10 AND k <> 13 AND k <> 26 AND k <> 255 THEN IF o.v1 > 0 THEN a1$ = LEFT$(a$, o.v1) ELSE a1$ = "" IF o.v1 <= LEN(a$) THEN a2$ = RIGHT$(a$, LEN(a$) - o.v1) ELSE a2$ = "" a$ = a1$ + kk$ + a2$: o.v1 = o.v1 + 1 END IF idetxt(o.txt) = a$ END IF IF kk$ = CHR$(0) + "S" THEN 'DEL IF o.v1 > 0 THEN a1$ = LEFT$(a$, o.v1) ELSE a1$ = "" IF o.v1 < LEN(a$) THEN a2$ = RIGHT$(a$, LEN(a$) - o.v1 - 1) ELSE a2$ = "" a$ = a1$ + a2$ idetxt(o.txt) = a$ END IF IF (KSHIFT AND KB = KEY_INSERT) OR (KCONTROL AND UCASE$(K$) = "V") THEN 'paste from clipboard clip$ = _CLIPBOARD$ 'read clipboard x = INSTR(clip$, CHR$(13)) IF x THEN clip$ = LEFT$(clip$, x - 1) x = INSTR(clip$, CHR$(10)) IF x THEN clip$ = LEFT$(clip$, x - 1) IF LEN(clip$) THEN a$ = clip$ idetxt(o.txt) = a$ o.v1 = LEN(a$) END IF END IF IF ((KCTRL AND KB = KEY_INSERT) OR (KCONTROL AND UCASE$(K$) = "C")) THEN 'copy to clipboard _CLIPBOARD$ = idetxt(o.txt) END IF 'cursor control IF kk$ = CHR$(0) + "K" THEN o.v1 = o.v1 - 1 IF kk$ = CHR$(0) + "M" THEN o.v1 = o.v1 + 1 IF kk$ = CHR$(0) + "G" THEN o.v1 = 0 IF kk$ = CHR$(0) + "O" THEN o.v1 = LEN(a$) IF o.v1 < 0 THEN o.v1 = 0 IF o.v1 > LEN(a$) THEN o.v1 = LEN(a$) END IF 'hot-key focus IF LEN(altletter$) THEN IF o.nam THEN x = INSTR(idetxt(o.nam), "#") IF x THEN IF UCASE$(MID$(idetxt(o.nam), x + 1, 1)) = altletter$ THEN focus = f END IF END IF END IF f = f + 1 END IF '1 IF t = 2 THEN 'list box idetxt(o.stx) = "" IF mousedown THEN x1 = o.par.x + o.x: y1 = o.par.y + o.y x2 = x1 + o.w + 1: y2 = y1 + o.h + 1 IF mx >= x1 AND mx <= x2 AND my >= y1 AND my <= y2 THEN focus = f IF mx > x1 AND mx < x2 AND my > y1 AND my < y2 THEN y = my - y1 - 1 y = y + o.v1 IF o.sel = y THEN info = 1 o.sel = y IF o.sel > o.num THEN o.sel = o.num END IF END IF END IF 'mousedown IF mb THEN IF focusoffset = 0 THEN x1 = o.par.x + o.x: y1 = o.par.y + o.y x2 = x1 + o.w + 1: y2 = y1 + o.h + 1 IF mx >= x1 AND mx <= x2 AND my >= y1 AND my <= y2 THEN IF mx = x2 AND my > y1 + 1 AND my < y2 - 1 THEN tsel = ABS(o.sel) tnum = o.num q = idevbar(x2, y1 + 1, o.h, tsel, tnum) IF my < q THEN kk$ = CHR$(0) + CHR$(73) idewait END IF IF my > q THEN kk$ = CHR$(0) + CHR$(81) idewait END IF END IF IF mx = x2 AND my = y1 + 1 THEN kk$ = CHR$(0) + CHR$(72) idewait END IF IF mx = x2 AND my = y2 - 1 THEN kk$ = CHR$(0) + CHR$(80) idewait END IF END IF END IF END IF 'mb IF focusoffset = 0 THEN IF mw THEN 'move to top or bottom IF mw < 0 THEN IF o.sel > o.v1 THEN o.sel = o.v1 ELSE o.sel = o.v1 + o.h - 1 END IF o.sel = o.sel + mw * 3 IF o.sel < 1 THEN o.sel = 1 IF o.sel > o.num THEN o.sel = o.num END IF IF kk$ = CHR$(0) + CHR$(72) THEN IF o.sel < 0 THEN o.sel = -o.sel ELSE o.sel = o.sel - 1 IF o.sel < 1 THEN o.sel = 1 END IF END IF IF kk$ = CHR$(0) + CHR$(80) THEN IF o.sel < 0 THEN o.sel = -o.sel ELSE o.sel = o.sel + 1 IF o.sel > o.num THEN o.sel = o.num END IF END IF IF kk$ = CHR$(0) + CHR$(73) THEN IF o.sel < 0 THEN o.sel = -o.sel END IF o.sel = o.sel - o.h + 1 IF o.sel < 1 THEN o.sel = 1 END IF IF kk$ = CHR$(0) + CHR$(81) THEN IF o.sel < 0 THEN o.sel = -o.sel END IF o.sel = o.sel + o.h - 1 IF o.sel > o.num THEN o.sel = o.num END IF IF kk$ = CHR$(0) + "w" THEN o.sel = 1 END IF IF kk$ = CHR$(0) + "u" THEN o.sel = o.num END IF IF LEN(kk$) = 1 THEN k = ASC(UCASE$(kk$)): IF k < 32 OR k > 126 THEN k = 255 old_sel = o.sel a$ = idetxt(o.txt) retryfind: n = 1 x = 1 x2 = INSTR(x, a$, sep) IF LEN(a$) THEN again = 1 ELSE again = 0 DO WHILE x2 <> 0 OR again <> 0 IF x2 THEN ca2$ = MID$(a$, x, x2 - x) a2$ = UCASE$(ca2$) x = x2 + 1 again = 1 ELSE ca2$ = RIGHT$(a$, LEN(a$) - x + 1) a2$ = UCASE$(ca2$) again = 0 END IF IF n > old_sel THEN match = 0 FOR ai = 1 TO LEN(a2$) aa = ASC(a2$, ai) IF aa > 126 OR (k <> 95 AND aa = 95) THEN 'ignore ELSE IF aa = k THEN match = 1 EXIT FOR END IF NEXT IF match = 1 THEN o.sel = n GOTO selected END IF END IF IF n = o.sel THEN idetxt(o.stx) = ca2$ n = n + 1 x2 = INSTR(x, a$, sep) LOOP IF old_sel THEN old_sel = 0: GOTO retryfind selected: END IF END IF 'hot-key focus IF LEN(altletter$) THEN IF o.nam THEN x = INSTR(idetxt(o.nam), "#") IF x THEN IF UCASE$(MID$(idetxt(o.nam), x + 1, 1)) = altletter$ THEN focus = f END IF END IF END IF f = f + 1 END IF '2 IF t = 3 THEN 'buttons (eg. OK, Cancel) 'count buttons & check for hotkey(s) a$ = idetxt(o.txt) n = 1 x = 0 FOR i2 = 1 TO LEN(a$) a2$ = MID$(a$, i2, 1) IF a2$ = CHR$(0) THEN n = n + 1 IF x = 1 THEN IF UCASE$(a2$) = altletter$ THEN focus = f + n - 1 info = n END IF END IF IF a2$ = "#" THEN x = 1 ELSE x = 0 NEXT 'check for mouse click on button(s) IF mousedown THEN IF my = o.par.y + o.y THEN a$ = idetxt(o.txt) n = 1 c = 0 FOR i2 = 1 TO LEN(a$) a2$ = MID$(a$, i2, 1) IF a2$ = CHR$(0) THEN n = n + 1 ELSE IF a$ <> "#" THEN c = c + 1 END IF NEXT w = o.w c = c + n * 4 'add characters for bracing < > buttons whitespace = w - c spacing = whitespace \ (n + 1) 'f2 = o.foc + 1 'IF f2 < 1 OR f2 > n THEN 'IF o.dft THEN f2 = o.dft 'END IF n2 = 1 a3$ = "" 'LOCATE o.par.y + o.y, o.par.x + o.x x = o.par.x + o.x 'COLOR 0, 7 FOR i2 = 1 TO LEN(a$) a2$ = MID$(a$, i2, 1) IF a2$ <> CHR$(0) THEN a3$ = a3$ + a2$ IF a2$ = CHR$(0) OR i2 = LEN(a$) THEN 'PRINT SPACE$(spacing); x = x + spacing 'IF f2 = n2 THEN COLOR 15, 7 ELSE COLOR 0, 7 'PRINT "< "; 'COLOR 0, 7: idehPRINT a3$ 'IF f2 = n2 THEN COLOR 15, 7 ELSE COLOR 0, 7 'IF n2 = o.foc + 1 THEN 'o.cx = x + 2: o.cy = o.par.y + o.y 'END IF 'PRINT " >"; 'COLOR 0, 7 x2 = idehlen(a3$) + 4 IF mx >= x AND mx < x + x2 THEN info = n2: focus = f + n2 - 1 x = x + x2 a3$ = "" n2 = n2 + 1 END IF NEXT END IF 'my END IF 'mousedown IF focusoffset >= 0 AND focusoffset < n THEN f2 = f + focusoffset IF kk$ = CHR$(13) THEN info = focusoffset + 1 END IF END IF f = f + n END IF '3 IF t = 4 THEN 'checkbox IF mousedown THEN y = o.par.y + o.y x1 = o.par.x + o.x: x2 = x1 + 2 IF o.nam THEN x2 = x2 + 1 + idehlen(idetxt(o.nam)) END IF IF my = y THEN IF mx >= x1 AND mx <= x2 THEN focus = f o.sel = o.sel + 1: IF o.sel > 1 THEN o.sel = 0 'toggle END IF END IF END IF 'mousedown IF focusoffset = 0 THEN 'a$ = idetxt(o.txt) 'IF LEN(kk$) = 1 THEN 'k = ASC(kk$) 'IF k = 8 AND o.v1 > 0 THEN 'a1$ = LEFT$(a$, o.v1 - 1) 'IF o.v1 <= LEN(a$) THEN a2$ = RIGHT$(a$, LEN(a$) - o.v1) ELSE a2$ = "" 'a$ = a1$ + a2$: o.v1 = o.v1 - 1 'END IF 'IF k >= 32 AND k <= 126 THEN 'IF o.v1 > 0 THEN a1$ = LEFT$(a$, o.v1) ELSE a1$ = "" 'IF o.v1 <= LEN(a$) THEN a2$ = RIGHT$(a$, LEN(a$) - o.v1) ELSE a2$ = "" 'a$ = a1$ + kk$ + a2$: o.v1 = o.v1 + 1 'END IF 'idetxt(o.txt) = a$ 'END IF 'IF kk$ = CHR$(0) + "S" THEN 'DEL 'IF o.v1 > 0 THEN a1$ = LEFT$(a$, o.v1) ELSE a1$ = "" 'IF o.v1 < LEN(a$) THEN a2$ = RIGHT$(a$, LEN(a$) - o.v1 - 1) ELSE a2$ = "" 'a$ = a1$ + a2$ 'idetxt(o.txt) = a$ 'END IF ''cursor control 'IF kk$ = CHR$(0) + "K" THEN o.v1 = o.v1 - 1 'IF kk$ = CHR$(0) + "M" THEN o.v1 = o.v1 + 1 'IF kk$ = CHR$(0) + "G" THEN o.v1 = 0 'IF kk$ = CHR$(0) + "O" THEN o.v1 = LEN(a$) 'IF o.v1 < 0 THEN o.v1 = 0 'IF o.v1 > LEN(a$) THEN o.v1 = LEN(a$) IF kk$ = CHR$(0) + "H" THEN o.sel = 1 IF kk$ = CHR$(0) + "P" THEN o.sel = 0 IF kk$ = " " THEN o.sel = o.sel + 1: IF o.sel > 1 THEN o.sel = 0 'toggle END IF END IF 'in focus 'hot-key focus IF LEN(altletter$) THEN IF o.nam THEN x = INSTR(idetxt(o.nam), "#") IF x THEN IF UCASE$(MID$(idetxt(o.nam), x + 1, 1)) = altletter$ THEN focus = f END IF END IF END IF f = f + 1 END IF '4 END SUB FUNCTION idevbar (x, y, h, i2, n2) i = i2: n = n2 'h is height in charatcers (inc. arrows) 'draw background & arrows COLOR 0, 7 LOCATE y, x: PRINT CHR$(24); LOCATE y + h - 1, x: PRINT CHR$(25); FOR y2 = y + 1 TO y + h - 2 LOCATE y2, x: PRINT "°"; NEXT 'draw slider IF n < 1 THEN n = 1 IF i < 1 THEN i = 1 IF i > n THEN i = n IF h = 2 THEN idevbar = y 'not position for slider exists EXIT FUNCTION END IF IF h = 3 THEN idevbar = y + 1 'dummy value 'no slider EXIT FUNCTION END IF IF h = 4 THEN IF n = 1 THEN idevbar = y + 1 'dummy value 'no slider required for 1 item EXIT FUNCTION ELSE 'show whichever is closer of the two positions p! = (i - 1) / (n - 1) IF p! < .5 THEN y2 = y + 1 ELSE y2 = y + 2 LOCATE y2, x: PRINT "Û"; idevbar = y2 EXIT FUNCTION END IF END IF IF h > 4 THEN IF n = 1 THEN idevbar = y + h \ 4 'dummy value 'no slider required for 1 item EXIT FUNCTION END IF IF i = 1 THEN y2 = y + 1 LOCATE y2, x: PRINT "Û"; idevbar = y2 EXIT FUNCTION END IF IF i = n THEN y2 = y + h - 2 LOCATE y2, x: PRINT "Û"; idevbar = y2 EXIT FUNCTION END IF 'between i=1 and i=n p! = (i - 1) / (n - 1) p! = p! * (h - 4) y2 = y + 2 + INT(p!) LOCATE y2, x: PRINT "Û"; idevbar = y2 EXIT FUNCTION END IF END FUNCTION SUB idewait _DELAY 0.1 END SUB SUB idewait4alt 'stub END SUB SUB idewait4mous 'stub END SUB FUNCTION idezfilename$ (f$) IF os$ = "WIN" THEN idezfilename$ = CHR$(34) + f$ + CHR$(34) EXIT FUNCTION END IF IF os$ = "LNX" THEN idezfilename$ = "'" + f$ + "'" EXIT FUNCTION END IF END FUNCTION FUNCTION idezchangepath$ (path$, newpath$) idezchangepath$ = path$ 'default (for unsuccessful cases) IF os$ = "WIN" THEN 'go back a path IF newpath$ = ".." THEN FOR x = LEN(path$) TO 1 STEP -1 a$ = MID$(path$, x, 1) IF a$ = "\" THEN idezchangepath$ = LEFT$(path$, x - 1) EXIT FOR END IF NEXT EXIT FUNCTION END IF 'change drive IF LEN(newpath$) = 2 AND RIGHT$(newpath$, 1) = ":" THEN idezchangepath$ = newpath$ EXIT FUNCTION END IF idezchangepath$ = path$ + "\" + newpath$ EXIT FUNCTION END IF IF os$ = "LNX" THEN 'go back a path IF newpath$ = ".." THEN FOR x = LEN(path$) TO 1 STEP -1 a$ = MID$(path$, x, 1) IF a$ = "/" THEN idezchangepath$ = LEFT$(path$, x - 1) IF x = 1 THEN idezchangepath$ = "/" 'root path cannot be "" EXIT FOR END IF NEXT EXIT FUNCTION END IF IF path$ = "/" THEN idezchangepath$ = "/" + newpath$ ELSE idezchangepath$ = path$ + "/" + newpath$ EXIT FUNCTION END IF END FUNCTION FUNCTION idezfilelist$ (path$, method) 'method0=*.bas, method1=*.* DIM sep AS STRING * 1 sep = CHR$(0) IF os$ = "WIN" THEN OPEN ".\internal\temp\files.txt" FOR OUTPUT AS #150: CLOSE #150 IF method = 0 THEN SHELL _HIDE "dir /b /ON /A-D " + idezfilename$(path$) + "\*.bas >.\internal\temp\files.txt" IF method = 1 THEN SHELL _HIDE "dir /b /ON /A-D " + idezfilename$(path$) + "\*.* >.\internal\temp\files.txt" filelist$ = "" OPEN ".\internal\temp\files.txt" FOR INPUT AS #150 DO UNTIL EOF(150) LINE INPUT #150, a$ IF LEN(a$) THEN 'skip blank entries IF filelist$ = "" THEN filelist$ = a$ ELSE filelist$ = filelist$ + sep + a$ END IF LOOP CLOSE #150 idezfilelist$ = filelist$ EXIT FUNCTION END IF IF os$ = "LNX" THEN filelist$ = "" FOR i = 1 TO 2 - method OPEN "./internal/temp/files.txt" FOR OUTPUT AS #150: CLOSE #150 IF method = 0 THEN IF i = 1 THEN SHELL _HIDE "find " + idezfilename$(path$) + " -maxdepth 1 -type f -name " + CHR$(34) + "*.bas" + CHR$(34) + " >./internal/temp/files.txt" IF i = 2 THEN SHELL _HIDE "find " + idezfilename$(path$) + " -maxdepth 1 -type f -name " + CHR$(34) + "*.BAS" + CHR$(34) + " >./internal/temp/files.txt" END IF IF method = 1 THEN IF i = 1 THEN SHELL _HIDE "find " + idezfilename$(path$) + " -maxdepth 1 -type f -name " + CHR$(34) + "*" + CHR$(34) + " >./internal/temp/files.txt" END IF OPEN "./internal/temp/files.txt" FOR INPUT AS #150 DO UNTIL EOF(150) LINE INPUT #150, a$ IF LEN(a$) = 0 THEN EXIT DO FOR x = LEN(a$) TO 1 STEP -1 a2$ = MID$(a$, x, 1) IF a2$ = "/" THEN a$ = RIGHT$(a$, LEN(a$) - x) EXIT FOR END IF NEXT IF filelist$ = "" THEN filelist$ = a$ ELSE filelist$ = filelist$ + sep + a$ LOOP CLOSE #150 NEXT idezfilelist$ = filelist$ EXIT FUNCTION END IF END FUNCTION FUNCTION idezgetroot$ 'note: does NOT including a trailing / or \ on the right IF os$ = "WIN" THEN SHELL _HIDE "cd >.\internal\temp\root.txt" OPEN ".\internal\temp\root.txt" FOR INPUT AS #150 LINE INPUT #150, a$ idezgetroot$ = a$ CLOSE #150 EXIT FUNCTION END IF IF os$ = "LNX" THEN SHELL _HIDE "pwd >./internal/temp/root.txt" OPEN "./internal/temp/root.txt" FOR INPUT AS #150 LINE INPUT #150, a$ idezgetroot$ = a$ CLOSE #150 EXIT FUNCTION END IF END FUNCTION FUNCTION idezpathlist$ (path$) DIM sep AS STRING * 1 sep = CHR$(0) IF os$ = "WIN" THEN OPEN ".\internal\temp\paths.txt" FOR OUTPUT AS #150: CLOSE #150 a$ = "": IF RIGHT$(path$, 1) = ":" THEN a$ = "\" 'use a \ after a drive letter SHELL _HIDE "dir /b /ON /AD " + idezfilename$(path$ + a$) + " >.\internal\temp\paths.txt" pathlist$ = "" OPEN ".\internal\temp\paths.txt" FOR INPUT AS #150 DO UNTIL EOF(150) LINE INPUT #150, a$ IF pathlist$ = "" THEN pathlist$ = a$ ELSE pathlist$ = pathlist$ + sep + a$ LOOP CLOSE #150 'count instances of / or \ c = 0 FOR x = 1 TO LEN(path$) b$ = MID$(path$, x, 1) IF b$ = idepathsep$ THEN c = c + 1 NEXT IF c >= 1 THEN IF LEN(pathlist$) THEN pathlist$ = ".." + sep + pathlist$ ELSE pathlist$ = ".." END IF 'add drive paths FOR i = 0 TO 25 IF LEN(pathlist$) THEN pathlist$ = pathlist$ + sep pathlist$ = pathlist$ + CHR$(65 + i) + ":" NEXT idezpathlist$ = pathlist$ EXIT FUNCTION END IF IF os$ = "LNX" THEN pathlist$ = "" OPEN "./internal/temp/paths.txt" FOR OUTPUT AS #150: CLOSE #150 SHELL _HIDE "find " + idezfilename$(path$) + " -maxdepth 1 -mindepth 1 -type d >./internal/temp/paths.txt" OPEN "./internal/temp/paths.txt" FOR INPUT AS #150 DO UNTIL EOF(150) LINE INPUT #150, a$ IF LEN(a$) = 0 THEN EXIT DO FOR x = LEN(a$) TO 1 STEP -1 a2$ = MID$(a$, x, 1) IF a2$ = "/" THEN a$ = RIGHT$(a$, LEN(a$) - x) EXIT FOR END IF NEXT IF pathlist$ = "" THEN pathlist$ = a$ ELSE pathlist$ = pathlist$ + sep + a$ LOOP CLOSE #150 IF path$ <> "/" THEN a$ = ".." IF pathlist$ = "" THEN pathlist$ = a$ ELSE pathlist$ = a$ + sep + pathlist$ END IF idezpathlist$ = pathlist$ EXIT FUNCTION END IF END FUNCTION FUNCTION ideztakepath$ (f$) 'assume f$ contains a filename with an optional path p$ = "" IF os$ = "WIN" THEN FOR i = LEN(f$) TO 1 STEP -1 a$ = MID$(f$, i, 1) IF a$ = "\" THEN p$ = LEFT$(f$, i - 1) f$ = RIGHT$(f$, LEN(f$) - i) EXIT FOR END IF NEXT ideztakepath$ = p$ EXIT FUNCTION END IF IF os$ = "LNX" THEN FOR i = LEN(f$) TO 1 STEP -1 a$ = MID$(f$, i, 1) IF a$ = "/" THEN p$ = LEFT$(f$, i - 1) f$ = RIGHT$(f$, LEN(f$) - i) EXIT FOR END IF NEXT ideztakepath$ = p$ EXIT FUNCTION END IF END FUNCTION 'file f$ exists, and may contain a path 'return the FULL path (even if it was passed as a relative path) 'f$ is altered to only contain the name of the actual file 'root$ is the path to apply relative paths to FUNCTION idezgetfilepath$ (root$, f$) 'step #1: seperate file's name from its path (if any) p$ = ideztakepath$(f$) 'note: this is a simple seperation of the string 'step #2: if path was undefined, set it to root IF LEN(p$) = 0 THEN p$ = root$ 'step #3: if path is relative, make it relative to root$ IF LEFT$(p$, 1) = "." THEN p$ = root$ + idepathsep$ + p$ 'step #4: attempt a CHDIR to the path to (i) validate its existance ' & (ii) allow listing the paths full name ideerror = 4 'path not found p2$ = p$ IF os$ = "WIN" THEN IF RIGHT$(p2$, 1) = ":" THEN p2$ = p2$ + "\" 'force change to root of drive END IF CHDIR p2$ ideerror = 1 'step #5: get the path's full name (assume success) IF os$ = "WIN" THEN SHELL _HIDE "cd >" + idezfilename$(ideroot$) + "\internal\temp\root.txt" OPEN ideroot$ + "\internal\temp\root.txt" FOR INPUT AS #150 LINE INPUT #150, p$ IF RIGHT$(p$, 1) = "\" THEN p$ = LEFT$(p$, LEN(p$) - 1) 'strip trailing \ after root drive path CLOSE #150 END IF IF os$ = "LNX" THEN SHELL _HIDE "pwd >" + idezfilename$(ideroot$) + "/internal/temp/root.txt" OPEN ideroot$ + "/internal/temp/root.txt" FOR INPUT AS #150 LINE INPUT #150, p$ CLOSE #150 END IF 'step #6: restore root path (assume success) CHDIR ideroot$ 'important: no validation of f$ necessary idezgetfilepath$ = p$ END FUNCTION SUB initmouse _MOUSESHOW END SUB FUNCTION idelayoutbox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 60, 7, "Code Layout" i = i + 1 o(i).typ = 4 'check box o(i).y = 2 o(i).nam = idenewtxt("#Auto Spacing & Upper/Lowercase Formatting") o(i).sel = ideautolayout i = i + 1 o(i).typ = 4 'check box o(i).y = 4 o(i).nam = idenewtxt("Auto #Indent -") o(i).sel = ideautoindent a2$ = str2$(ideautoindentsize) i = i + 1 o(i).typ = 1 o(i).x = 20 o(i).y = 4 o(i).nam = idenewtxt("#Spacing") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 3 o(i).y = 7 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls a$ = idetxt(o(3).txt) IF LEN(a$) > 2 THEN a$ = LEFT$(a$, 2) '2 character limit FOR i = 1 TO LEN(a$) a = ASC(a$, i) IF i = 2 AND ASC(a$, 1) = 48 THEN a$ = "0": EXIT FOR IF a < 48 OR a > 57 THEN a$ = "": EXIT FOR NEXT IF LEN(a$) THEN a = VAL(a$) IF a > 64 THEN a$ = "64" END IF idetxt(o(3).txt) = a$ IF K$ = CHR$(27) OR (focus = 5 AND info <> 0) THEN EXIT FUNCTION IF K$ = CHR$(13) OR (focus = 4 AND info <> 0) THEN 'save changes OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 v% = o(1).sel: IF v% <> 0 THEN v% = 1 'ideautolayout PUT #150, , v% IF ideautolayout <> v% THEN ideautolayout = v%: idelayoutbox = 1 v% = o(2).sel: IF v% <> 0 THEN v% = 1 'ideautoindent PUT #150, , v% IF ideautoindent <> v% THEN ideautoindent = v%: idelayoutbox = 1 v$ = idetxt(o(3).txt) 'ideautoindentsize IF v$ = "" THEN v$ = "4" v% = VAL(v$) IF v% < 0 OR v% > 64 THEN v% = 4 PUT #150, , v% IF ideautoindentsize <> v% THEN ideautoindentsize = v% IF ideautoindent <> 0 THEN idelayoutbox = 1 END IF CLOSE #150 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION idebackupbox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 50, 5, "Backup/Undo" a2$ = str2$(idebackupsize) i = i + 1 o(i).typ = 1 o(i).y = 2 o(i).nam = idenewtxt("#Undo buffer limit (10-2000MB)") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 3 o(i).y = 5 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls a$ = idetxt(o(1).txt) IF LEN(a$) > 4 THEN a$ = LEFT$(a$, 4) '4 character limit FOR i = 1 TO LEN(a$) a = ASC(a$, i) IF i = 2 AND ASC(a$, 1) = 48 THEN a$ = "0": EXIT FOR IF a < 48 OR a > 57 THEN a$ = LEFT$(a$, i - 1): EXIT FOR NEXT IF focus <> 1 THEN a = VAL(a$) IF a < 10 THEN a$ = "10" IF a > 2000 THEN a$ = "2000" END IF idetxt(o(1).txt) = a$ IF K$ = CHR$(27) OR (focus = 3 AND info <> 0) THEN EXIT FUNCTION IF K$ = CHR$(13) OR (focus = 2 AND info <> 0) THEN 'save changes OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 SEEK #150, 1051 v$ = idetxt(o(1).txt) 'idebackupsize v& = VAL(v$) IF v& < 10 THEN v& = 10 IF v& > 2000 THEN v& = 2000 IF v& < idebackupsize THEN OPEN tmpdir$ + "undo2.bin" FOR OUTPUT AS #151: CLOSE #151 ideundobase = 0 ideundopos = 0 END IF idebackupsize = v& PUT #150, , v& CLOSE #150 idebackupbox = 1 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION idegotobox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 30, 5, "Go To Line" a2$ = "" i = i + 1 o(i).typ = 1 o(i).y = 2 o(i).nam = idenewtxt("#Line") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 3 o(i).y = 5 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls a$ = idetxt(o(1).txt) IF LEN(a$) > 8 THEN a$ = LEFT$(a$, 8) '8 character limit FOR i = 1 TO LEN(a$) a = ASC(a$, i) IF i = 2 AND ASC(a$, 1) = 48 THEN a$ = "0": EXIT FOR IF a < 48 OR a > 57 THEN a$ = LEFT$(a$, i - 1): EXIT FOR NEXT IF focus <> 1 THEN a = VAL(a$) IF a < 1 THEN a$ = "1" END IF idetxt(o(1).txt) = a$ IF K$ = CHR$(27) OR (focus = 3 AND info <> 0) THEN EXIT FUNCTION IF K$ = CHR$(13) OR (focus = 2 AND info <> 0) THEN v$ = idetxt(o(1).txt) v& = VAL(v$) IF v& < 1 THEN v& = 1 IF v& > iden THEN v& = iden idecy = v& ideselect = 0 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION ideadvancedbox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- DIM Direct_Text$(100) i = 0 i = i + 1 o(i).typ = 3 ' 'o(i).y = y o(i).txt = idenewtxt("#OK" + sep + "#Cancel") o(i).dft = 1 y = 2 '2nd blank line i = i + 1 o(i).typ = 4 'check box --- focus=3 o(i).y = y o(i).nam = idenewtxt("Embed C++ debug information into executable") o(i).sel = idedebuginfo y = y + 1: Direct_Text$(y) = " " + CHR$(254) + " Investigate crashes/freezes at C++ (not QB64) code level" y = y + 1: Direct_Text$(y) = " " + CHR$(254) + " Use internal/temp/debug batch file to debug your executable" y = y + 1: Direct_Text$(y) = " " + CHR$(254) + " Increases executable size" y = y + 1: Direct_Text$(y) = " " + CHR$(254) + " Makes public the names of variables in your program's code" y = y + 1: Direct_Text$(y) = " " + CHR$(254) + " QB64 libraries will be purged then rebuilt" y = y + 1: Direct_Text$(y) = " " + CHR$(254) + " This setting also affects command line compilation" y = y + 2 o(1).y = y 'close button '-------- end of init -------- idepar p, 75, y, "Advanced Options" '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- FOR y = 1 TO 100 IF LEN(Direct_Text$(y)) THEN COLOR 0, 7: LOCATE p.y + y, p.x + 1: PRINT Direct_Text$(y) END IF NEXT '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR (focus = 2 AND info <> 0) THEN EXIT FUNCTION IF K$ = CHR$(13) OR (focus = 1 AND info <> 0) THEN 'close 'save changes OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 'update idedebuginfo? v% = o(2).sel: IF v% <> 0 THEN v% = 1 IF v% <> idedebuginfo THEN SEEK #150, 1055: PUT #150, , v% idedebuginfo = v% Include_GDB_Debugging_Info = idedebuginfo IF os$ = "WIN" THEN CHDIR "internal\c" SHELL _HIDE "cmd /c purge_all_precompiled_content_win.bat" CHDIR "..\.." END IF IF os$ = "LNX" THEN CHDIR "./internal/c" IF INSTR(_OS$, "[MACOSX]") THEN SHELL _HIDE "./purge_all_precompiled_content_osx.command" ELSE SHELL _HIDE "./purge_all_precompiled_content_lnx.sh" END IF CHDIR "../.." END IF idechangemade = 1 'force recompilation END IF '... CLOSE #150 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION ideupdatebox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 40, 8, "Update" i = i + 1 o(i).typ = 4 'check box o(i).y = 2 o(i).nam = idenewtxt("#Check for updates:") o(i).sel = ideupdatecheck i = i + 1 o(i).typ = 4 'check box o(i).y = 4 o(i).x = 8 o(i).nam = idenewtxt("#Only check once per day") o(i).sel = ideupdatedaily i = i + 1 o(i).typ = 4 'check box o(i).y = 6 o(i).x = 8 o(i).nam = idenewtxt("#Automatically apply updates") o(i).sel = ideupdateauto i = i + 1 o(i).typ = 3 o(i).y = 8 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR (focus = 5 AND info <> 0) THEN EXIT FUNCTION IF K$ = CHR$(13) OR (focus = 4 AND info <> 0) THEN 'save changes OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 SEEK #150, 1039 v% = o(1).sel: IF v% <> 0 THEN v% = 1 PUT #150, , v% ideupdatecheck = v% v% = o(2).sel: IF v% <> 0 THEN v% = 1 PUT #150, , v% ideupdatedaily = v% v% = o(3).sel: IF v% <> 0 THEN v% = 1 PUT #150, , v% ideupdateauto = v% CLOSE #150 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION SUB idemessagebox (titlestr$, messagestr$) '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 w = LEN(messagestr$) + 2 w2 = LEN(titlestr$) + 4 IF w < w2 THEN w = w2 idepar p, w, 4, titlestr$ i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("OK") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 2: PRINT messagestr$; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR K$ = CHR$(13) OR (focus = 1 AND info <> 0) THEN EXIT SUB 'end of custom controls mousedown = 0 mouseup = 0 LOOP END SUB FUNCTION ideyesnobox$ (titlestr$, messagestr$) 'returns "Y" or "N" '-------- generic dialog box header -------- PCOPY 3, 0 PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 w = LEN(messagestr$) + 2 w2 = LEN(titlestr$) + 4 IF w < w2 THEN w = w2 idepar p, w, 4, titlestr$ i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("#Yes" + sep + "#No") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 2: PRINT messagestr$; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- IF UCASE$(K$) = "Y" THEN altletter$ = "Y" IF UCASE$(K$) = "N" THEN altletter$ = "N" '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- IF K$ = CHR$(27) THEN ideyesnobox$ = "N" EXIT FUNCTION END IF IF info THEN IF info = 1 THEN ideyesnobox$ = "Y" ELSE ideyesnobox$ = "N" EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION 'yes/no box FUNCTION ideandroidbox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 idepar p, 75, 15 - 4, "Google Android Options" i = i + 1 o(i).typ = 4 'check box o(i).y = 2 o(i).nam = idenewtxt("Enable #Run Menu Commands") o(i).sel = IdeAndroidMenu 'a2$ = IdeAndroidStartScript 'IF a2$ = "" THEN a2$ = "programs\android\start_android.bat" 'i = i + 1 'o(i).typ = 1 'o(i).y = 7 'o(i).nam = idenewtxt(CHR$(34) + "Start Android Project" + CHR$(34) + " Script") 'o(i).txt = idenewtxt(a2$) 'o(i).v1 = LEN(a2$) a2$ = IdeAndroidMakeScript IF a2$ = "" THEN a2$ = "programs\android\make_android.bat" i = i + 1 o(i).typ = 1 o(i).y = 11 - 4 o(i).nam = idenewtxt(CHR$(34) + "Make Android Project Only" + CHR$(34) + " Script") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 3 o(i).y = 15 - 4 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 8, 7: LOCATE p.y + 3, p.x + 4: PRINT "Projects are created at:"; COLOR 8, 7: LOCATE p.y + 4, p.x + 6: PRINT "qb64\programs\android\"; COLOR 3, 7 PRINT "bas_file_name_without_extension"; COLOR 8, 7: PRINT "\"; ' COLOR 8, 7: LOCATE p.y + 9, p.x + 4: PRINT "Script file is launched from within project's folder"; COLOR 8, 7: LOCATE p.y + 13 - 4, p.x + 4: PRINT "Script file is launched from within project's folder"; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls a$ = idetxt(o(2).txt) IF LEN(a$) > 256 THEN a$ = LEFT$(a$, 256) idetxt(o(2).txt) = a$ a$ = idetxt(o(3).txt) IF LEN(a$) > 256 THEN a$ = LEFT$(a$, 256) idetxt(o(3).txt) = a$ IF K$ = CHR$(27) OR (focus = 5 - 1 AND info <> 0) THEN EXIT FUNCTION IF K$ = CHR$(13) OR (focus = 4 - 1 AND info <> 0) THEN v% = o(1).sel IF v% < IdeAndroidMenu THEN menusize(5) = menusize(5) - 2 END IF IF v% > IdeAndroidMenu THEN menusize(5) = menusize(5) + 2 END IF 'v$ = idetxt(o(2).txt) v$ = "" IF LEN(v$) > 256 THEN v$ = LEFT$(v$, 256) IF LEN(v$) < 256 THEN v$ = v$ + SPACE$(256 - LEN(v$)) v3$ = idetxt(o(3 - 1).txt) IF LEN(v3$) > 256 THEN v3$ = LEFT$(v3$, 256) IF LEN(v3$) < 256 THEN v3$ = v3$ + SPACE$(256 - LEN(v3$)) OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 SEEK #150, 1057 PUT #150, , v% PUT #150, , v$ PUT #150, , v3$ CLOSE #150 IdeAndroidMenu = o(1).sel IdeAndroidStartScript = "" 'idetxt(o(2).txt) IdeAndroidMakeScript = idetxt(o(3 - 1).txt) EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION idedisplaybox '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- '-------- init -------- i = 0 'idepar p, 60, 16, "Display" 'note: manually set window position in case display to set too large by accident p.x = (80 \ 2) - 60 \ 2 p.y = (25 \ 2) - 16 \ 2 p.w = 60 p.h = 16 p.nam = idenewtxt("Display") a2$ = str2$(idewx) i = i + 1 o(i).typ = 1 o(i).x = 16 o(i).y = 2 o(i).nam = idenewtxt("#Width") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) a2$ = str2$(idewy + idesubwindow) i = i + 1 o(i).typ = 1 o(i).x = 15 o(i).y = 5 o(i).nam = idenewtxt("#Height") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 4 'check box o(i).y = 8 o(i).nam = idenewtxt("Custom #Font:") o(i).sel = idecustomfont a2$ = idecustomfontfile$ i = i + 1 o(i).typ = 1 o(i).x = 10 o(i).y = 10 o(i).nam = idenewtxt("File #Name") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) a2$ = str2$(idecustomfontheight) i = i + 1 o(i).typ = 1 o(i).x = 10 o(i).y = 13 o(i).nam = idenewtxt("#Row Height (Pixels)") o(i).txt = idenewtxt(a2$) o(i).v1 = LEN(a2$) i = i + 1 o(i).typ = 3 o(i).y = 16 o(i).txt = idenewtxt("OK" + sep + "#Cancel") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 2: PRINT "Window Size -"; COLOR 0, 7: LOCATE p.y + 9, p.x + 29: PRINT " Monospace TTF Font "; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls a$ = idetxt(o(1).txt) IF LEN(a$) > 3 THEN a$ = LEFT$(a$, 3) '3 character limit FOR i = 1 TO LEN(a$) a = ASC(a$, i) IF a < 48 OR a > 57 THEN a$ = "": EXIT FOR IF i = 2 AND ASC(a$, 1) = 48 THEN a$ = "0": EXIT FOR NEXT IF focus <> 1 THEN IF LEN(a$) THEN a = VAL(a$) ELSE a = 0 IF a < 80 THEN a$ = "80" END IF idetxt(o(1).txt) = a$ a$ = idetxt(o(2).txt) IF LEN(a$) > 3 THEN a$ = LEFT$(a$, 3) '3 character limit FOR i = 1 TO LEN(a$) a = ASC(a$, i) IF a < 48 OR a > 57 THEN a$ = "": EXIT FOR IF i = 2 AND ASC(a$, 1) = 48 THEN a$ = "0": EXIT FOR NEXT IF focus <> 2 THEN IF LEN(a$) THEN a = VAL(a$) ELSE a = 0 IF a < 25 THEN a$ = "25" END IF idetxt(o(2).txt) = a$ a$ = idetxt(o(4).txt) IF LEN(a$) > 1024 THEN a$ = LEFT$(a$, 1024) idetxt(o(4).txt) = a$ a$ = idetxt(o(5).txt) IF LEN(a$) > 2 THEN a$ = LEFT$(a$, 2) '2 character limit FOR i = 1 TO LEN(a$) a = ASC(a$, i) IF a < 48 OR a > 57 THEN a$ = "": EXIT FOR IF i = 2 AND ASC(a$, 1) = 48 THEN a$ = "0": EXIT FOR NEXT IF focus <> 5 THEN IF LEN(a$) THEN a = VAL(a$) ELSE a = 0 IF a < 8 THEN a$ = "8" END IF idetxt(o(5).txt) = a$ IF K$ = CHR$(27) OR (focus = 7 AND info <> 0) THEN EXIT FUNCTION IF K$ = CHR$(13) OR (focus = 6 AND info <> 0) THEN x = 0 'change to custom font 'get size in v% v$ = idetxt(o(5).txt): IF v$ = "" THEN v$ = "0" v% = VAL(v$) IF v% < 8 THEN v% = 8 IF v% > 99 THEN v% = 99 IF v% <> idecustomfontheight THEN x = 1 IF o(3).sel <> idecustomfont THEN IF o(3).sel = 0 THEN _FONT 16 _FREEFONT idecustomfonthandle ELSE x = 1 END IF END IF v$ = idetxt(o(4).txt): IF v$ <> idecustomfontfile$ THEN x = 1 IF o(3).sel = 1 AND x = 1 THEN oldhandle = idecustomfonthandle idecustomfonthandle = _LOADFONT(v$, v%, "MONOSPACE") IF idecustomfonthandle = -1 THEN 'failed! - revert to default settings o(3).sel = 0: idetxt(o(4).txt) = "c:\windows\fonts\lucon.ttf": idetxt(o(5).txt) = "21": _FONT 16 ELSE _FONT idecustomfonthandle END IF IF idecustomfont = 1 THEN _FREEFONT oldhandle END IF 'save changes OPEN ".\internal\temp\options.bin" FOR BINARY AS #150 SEEK #150, 7 v$ = idetxt(o(1).txt): IF v$ = "" THEN v$ = "0" v% = VAL(v$) IF v% < 80 THEN v% = 80 IF v% > 999 THEN v% = 999 PUT #150, , v% IF v% <> idewx THEN idedisplaybox = 1 idewx = v% v$ = idetxt(o(2).txt): IF v$ = "" THEN v$ = "0" v% = VAL(v$) IF v% < 25 THEN v% = 25 IF v% > 999 THEN v% = 999 PUT #150, , v% IF v% <> idewy THEN idedisplaybox = 1 idewy = v% - idesubwindow v% = o(3).sel IF v% <> 0 THEN v% = 1 PUT #150, , v% idecustomfont = v% v$ = idetxt(o(4).txt) IF LEN(v$) > 1024 THEN v$ = LEFT$(v$, 1024) idecustomfontfile$ = v$ v$ = v$ + SPACE$(1024 - LEN(v$)) PUT #150, , v$ v$ = idetxt(o(5).txt): IF v$ = "" THEN v$ = "0" v% = VAL(v$) IF v% < 8 THEN v% = 8 IF v% > 99 THEN v% = 99 PUT #150, , v% idecustomfontheight = v% CLOSE #150 EXIT FUNCTION END IF 'end of custom controls mousedown = 0 mouseup = 0 LOOP END FUNCTION FUNCTION HashValue& (a$) 'returns the hash table value of a string '[5(first)][5(second)][5(last)][5(2nd-last)][3(length AND 7)][1(first char is underscore)] l = LEN(a$) IF l = 0 THEN EXIT FUNCTION 'an (invalid) NULL string equates to 0 a = ASC(a$) IF a <> 95 THEN 'does not begin with underscore SELECT CASE l CASE 1 HashValue& = hash1char(a) + 1048576 EXIT FUNCTION CASE 2 HashValue& = hash2char(CVI(a$)) + 2097152 EXIT FUNCTION CASE 3 HashValue& = hash2char(CVI(a$)) + hash1char(ASC(a$, 3)) * 1024 + 3145728 EXIT FUNCTION CASE ELSE HashValue& = hash2char(CVI(a$)) + hash2char(ASC(a$, l) + ASC(a$, l - 1) * 256) * 1024 + (l AND 7) * 1048576 EXIT FUNCTION END SELECT ELSE 'does begin with underscore SELECT CASE l CASE 1 HashValue& = (1048576 + 8388608): EXIT FUNCTION 'note: underscore only is illegal in QB64 but supported by hash CASE 2 HashValue& = hash1char(ASC(a$, 2)) + (2097152 + 8388608) EXIT FUNCTION CASE 3 HashValue& = hash2char(ASC(a$, 2) + ASC(a$, 3) * 256) + (3145728 + 8388608) EXIT FUNCTION CASE 4 HashValue& = hash2char((CVL(a$) AND &HFFFF00) \ 256) + hash1char(ASC(a$, 4)) * 1024 + (4194304 + 8388608) EXIT FUNCTION CASE ELSE HashValue& = hash2char((CVL(a$) AND &HFFFF00) \ 256) + hash2char(ASC(a$, l) + ASC(a$, l - 1) * 256) * 1024 + (l AND 7) * 1048576 + 8388608 EXIT FUNCTION END SELECT END IF END FUNCTION SUB HashAdd (a$, flags, reference) 'find the index to use IF HashListFreeLast > 0 THEN 'take from free list i = HashListFree(HashListFreeLast) HashListFreeLast = HashListFreeLast - 1 ELSE IF HashListNext > HashListSize THEN 'double hash list size HashListSize = HashListSize * 2 REDIM _PRESERVE HashList(1 TO HashListSize) AS HashListItem REDIM _PRESERVE HashListName(1 TO HashListSize) AS STRING * 256 END IF i = HashListNext HashListNext = HashListNext + 1 END IF 'setup links to index x = HashValue(a$) i2 = HashTable(x) IF i2 THEN i3 = HashList(i2).LastItem HashList(i2).LastItem = i HashList(i3).NextItem = i HashList(i).PrevItem = i3 ELSE HashTable(x) = i HashList(i).PrevItem = 0 HashList(i).LastItem = i END IF HashList(i).NextItem = 0 'set common hashlist values HashList(i).Flags = flags HashList(i).Reference = reference HashListName(i) = UCASE$(a$) END SUB FUNCTION HashFind (a$, searchflags, resultflags, resultreference) '(0,1,2)z=hashfind[rev]("RUMI",Hashflag_label,resflag,resref) '0=doesn't exist '1=found, no more items to scan '2=found, more items still to scan i = HashTable(HashValue(a$)) IF i THEN ua$ = UCASE$(a$) + SPACE$(256 - LEN(a$)) hashfind_next: f = HashList(i).Flags IF searchflags AND f THEN 'flags in common IF HashListName(i) = ua$ THEN resultflags = f resultreference = HashList(i).Reference i2 = HashList(i).NextItem IF i2 THEN HashFind = 2 HashFind_NextListItem = i2 HashFind_Reverse = 0 HashFind_SearchFlags = searchflags HashFind_Name = ua$ HashRemove_LastFound = i EXIT FUNCTION ELSE HashFind = 1 HashRemove_LastFound = i EXIT FUNCTION END IF END IF END IF i = HashList(i).NextItem IF i THEN GOTO hashfind_next END IF END FUNCTION FUNCTION HashFindRev (a$, searchflags, resultflags, resultreference) '(0,1,2)z=hashfind[rev]("RUMI",Hashflag_label,resflag,resref) '0=doesn't exist '1=found, no more items to scan '2=found, more items still to scan i = HashTable(HashValue(a$)) IF i THEN i = HashList(i).LastItem ua$ = UCASE$(a$) + SPACE$(256 - LEN(a$)) hashfindrev_next: f = HashList(i).Flags IF searchflags AND f THEN 'flags in common IF HashListName(i) = ua$ THEN resultflags = f resultreference = HashList(i).Reference i2 = HashList(i).PrevItem IF i2 THEN HashFindRev = 2 HashFind_NextListItem = i2 HashFind_Reverse = 1 HashFind_SearchFlags = searchflags HashFind_Name = ua$ HashRemove_LastFound = i EXIT FUNCTION ELSE HashFindRev = 1 HashRemove_LastFound = i EXIT FUNCTION END IF END IF END IF i = HashList(i).PrevItem IF i THEN GOTO hashfindrev_next END IF END FUNCTION FUNCTION HashFindCont (resultflags, resultreference) '(0,1,2)z=hashfind[rev](resflag,resref) '0=no more items exist '1=found, no more items to scan '2=found, more items still to scan IF HashFind_Reverse THEN i = HashFind_NextListItem hashfindrevc_next: f = HashList(i).Flags IF HashFind_SearchFlags AND f THEN 'flags in common IF HashListName(i) = HashFind_Name THEN resultflags = f resultreference = HashList(i).Reference i2 = HashList(i).PrevItem IF i2 THEN HashFindCont = 2 HashFind_NextListItem = i2 HashRemove_LastFound = i EXIT FUNCTION ELSE HashFindCont = 1 HashRemove_LastFound = i EXIT FUNCTION END IF END IF END IF i = HashList(i).PrevItem IF i THEN GOTO hashfindrevc_next EXIT FUNCTION ELSE i = HashFind_NextListItem hashfindc_next: f = HashList(i).Flags IF HashFind_SearchFlags AND f THEN 'flags in common IF HashListName(i) = HashFind_Name THEN resultflags = f resultreference = HashList(i).Reference i2 = HashList(i).NextItem IF i2 THEN HashFindCont = 2 HashFind_NextListItem = i2 HashRemove_LastFound = i EXIT FUNCTION ELSE HashFindCont = 1 HashRemove_LastFound = i EXIT FUNCTION END IF END IF END IF i = HashList(i).NextItem IF i THEN GOTO hashfindc_next EXIT FUNCTION END IF END FUNCTION SUB HashRemove i = HashRemove_LastFound 'add to free list HashListFreeLast = HashListFreeLast + 1 IF HashListFreeLast > HashListFreeSize THEN HashListFreeSize = HashListFreeSize * 2 REDIM _PRESERVE HashListFree(1 TO HashListFreeSize) AS LONG END IF HashListFree(HashListFreeLast) = i 'unlink i1 = HashList(i).PrevItem IF i1 THEN 'not first item in list i2 = HashList(i).NextItem IF i2 THEN '(not first and) not last item HashList(i1).NextItem = i2 HashList(i2).LastItem = i1 ELSE 'last item x = HashTable(HashValue(HashListName$(i))) HashList(x).LastItem = i1 HashList(i1).NextItem = 0 END IF ELSE 'first item in list x = HashTable(HashValue(HashListName$(i))) i2 = HashList(i).NextItem IF i2 THEN '(first item but) not last item HashTable(x) = i2 HashList(i2).PrevItem = 0 HashList(i2).LastItem = HashList(i).LastItem ELSE '(first and) last item HashTable(x) = 0 END IF END IF END SUB SUB HashDump 'used for debugging purposes fh = FREEFILE OPEN "hashdump.txt" FOR OUTPUT AS #fh b$ = "12345678901234567890123456789012}" FOR x = 0 TO 16777215 IF HashTable(x) THEN PRINT #fh, "START HashTable("; x; "):" i = HashTable(x) 'validate lasti = HashList(i).LastItem IF HashList(i).LastItem = 0 OR HashList(i).PrevItem <> 0 OR HashValue(HashListName(i)) <> x THEN GOTO corrupt PRINT #fh, " HashList("; i; ").LastItem="; HashList(i).LastItem hashdumpnextitem: x$ = " [" + STR$(i) + "]" + HashListName(i) f = HashList(i).Flags x$ = x$ + ",.Flags=" + STR$(f) + "{" FOR z = 1 TO 32 ASC(b$, z) = (f AND 1) + 48 f = f \ 2 NEXT x$ = x$ + b$ x$ = x$ + ",.Reference=" + STR$(HashList(i).Reference) PRINT #fh, x$ 'validate i1 = HashList(i).PrevItem i2 = HashList(i).NextItem IF i1 THEN IF HashList(i1).NextItem <> i THEN GOTO corrupt END IF IF i2 THEN IF HashList(i2).PrevItem <> i THEN GOTO corrupt END IF IF i2 = 0 THEN IF lasti <> i THEN GOTO corrupt END IF i = HashList(i).NextItem IF i THEN GOTO hashdumpnextitem PRINT #fh, "END HashTable("; x; ")" END IF NEXT CLOSE #fh EXIT SUB corrupt: PRINT #fh, "HASH TABLE CORRUPT!" 'should never happen CLOSE #fh END SUB SUB HashClear 'clear entire hash table HashListSize = 65536 HashListNext = 1 HashListFreeSize = 1024 HashListFreeLast = 0 REDIM HashList(1 TO HashListSize) AS HashListItem REDIM HashListName(1 TO HashListSize) AS STRING * 256 REDIM HashListFree(1 TO HashListFreeSize) AS LONG REDIM HashTable(16777215) AS LONG '64MB lookup table with indexes to the hashlist HashFind_NextListItem = 0 HashFind_Reverse = 0 HashFind_SearchFlags = 0 HashFind_Name = "" HashRemove_LastFound = 0 END SUB SUB iderestrict417 (p417) x = 0 IF p417 AND 4 THEN x = x + 1 IF p417 AND 8 THEN x = x + 1 IF x > 1 THEN p417 = p417 AND 243 END SUB '######## UPDATE.BAS ######## FUNCTION decompress_2_huff$ (a$) IF ASC(a$) <> 2 THEN SCREEN 0, , 0, 0: PRINT "decompress_2_huff: invalid type": END 'get no. of branches and encoded bits totalbits = ASC(a$, 5) totalbits = totalbits * 256 + ASC(a$, 4) totalbits = totalbits * 256 + ASC(a$, 3) totalbits = totalbits * 256 + ASC(a$, 2) totalbytes = (totalbits + 7) \ 8 nb = (LEN(a$) - totalbytes - 5) \ 3 'number of branches 'read branches FOR i = 0 TO nb - 1 v = ASC(a$, 6 + i * 3) + ASC(a$, 6 + i * 3 + 1) * 256 + ASC(a$, 6 + i * 3 + 2) * 65536 huff_branch0(i) = v AND 4095 huff_branch1(i) = v \ 4096 NEXT 'buffer for decompression bufsiz = totalbits * 8 IF bufsiz > 1000000 THEN bufsiz = 1000000 b$ = SPACE$(bufsiz) 'decompress byteoff = LEN(a$) - totalbytes + 1 bitmask = 1 x = 0 b = 0 'branch byteval = ASC(a$, byteoff) huffreadbits: bit = byteval AND bitmask totalbits = totalbits - 1 IF bit THEN b = huff_branch1(b) ELSE b = huff_branch0(b) END IF IF huff_branch0(b) = 0 THEN x = x + 1: IF x > bufsiz THEN b$ = b$ + SPACE$(bufsiz): bufsiz = bufsiz * 2 ASC(b$, x) = huff_branch1(b) IF totalbits = 0 THEN GOTO hufffinished b = 0 END IF bitmask = bitmask * 2: IF bitmask = 256 THEN bitmask = 1: byteoff = byteoff + 1: byteval = ASC(a$, byteoff) GOTO huffreadbits hufffinished: decompress_2_huff$ = LEFT$(b$, x) END FUNCTION FUNCTION compress_2_huff$ (a$) 'count weights FOR i = 0 TO 255 huff_count(i) = 0 NEXT FOR i = 1 TO LEN(a$) v = ASC(a$, i) huff_count(v) = huff_count(v) + 1 NEXT 'setup initial branches b = 0 'note: pos 0 reserved for initial branch FOR i = 0 TO 255 IF huff_count(i) THEN b = b + 1 huff_branch(i) = b huff_weight(b) = huff_count(i) huff_bit0link(b) = 0 'it's a value huff_bit1link(b) = i 'the value huff_parent(b) = -1 END IF NEXT IF b = 1 THEN 'create a fake branch to allow for 1 bit encoding of uniform data b = b + 1 huff_weight(b) = 1 huff_bit0link(b) = 0 'it's a value huff_bit1link(b) = 0 'the value huff_parent(b) = -1 END IF 'find 2 lowest weights huff_buildbranches: w1 = 2147483647 w2 = 2147483647 FOR i = 1 TO b w = huff_weight(i) IF w <> 2147483647 THEN 'pump up (w1=lowest, w2=second lowest) IF w < w1 THEN w2 = w1: i2 = i1 w1 = w: i1 = i ELSE IF w < w2 THEN w2 = w: i2 = i END IF END IF NEXT 'form new branch IF w1 <> 2147483647 AND w2 <> 2147483647 THEN 'combine branches b = b + 1 huff_weight(b) = huff_weight(i1) + huff_weight(i2) huff_parent(b) = -1 huff_bit0link(b) = i1: huff_bit1link(b) = i2 huff_weight(i1) = 2147483647: huff_weight(i2) = 2147483647 huff_parent(i1) = b: huff_parent(i2) = b huff_bit(i1) = 0: huff_bit(i2) = 1 GOTO huff_buildbranches END IF 'note: i1 contains root branch 'copy final branch links to position 0 huff_bit0link(0) = huff_bit0link(i1): huff_bit1link(0) = huff_bit1link(i1) lastbranch = b - 1 '*for storage of key* 'build bit masks (clearing remainder of final byte of each to 0) totalbits = 0 FOR i = 0 TO 255 IF huff_count(i) THEN 'calc number of bits nbits = 0 b = huff_branch(i) huff_calcnbits: p = huff_parent(b) IF p <> -1 THEN nbits = nbits + 1: b = p: GOTO huff_calcnbits huff_mask_bits(i) = nbits totalbits = totalbits + nbits * huff_count(i) baseoffset = i * 256 'base offset 'clear bytes bytes = ((nbits + 7) + 7) \ 8 FOR x = 0 TO 7 byteo = baseoffset + (x * 32) FOR x2 = 0 TO bytes - 1 huff_mask(byteo + x2) = 0 NEXT NEXT 'create mask o1 = nbits b = huff_branch(i) huff_nextbranch: o1 = o1 - 1 IF huff_parent(b) <> -1 THEN IF huff_bit(b) THEN bitval = huff_bitval(o1 AND 7) FOR o2 = 0 TO 7 o = o1 + o2 byteo = baseoffset + (o2 * 32) + (o \ 8) huff_mask(byteo) = huff_mask(byteo) OR bitval bitval = bitval + bitval: IF bitval = 256 THEN bitval = 1 NEXT END IF 'bit set b = huff_parent(b) GOTO huff_nextbranch END IF END IF NEXT totalbytes = (totalbits + 7) \ 8 totalbytes = totalbytes + (lastbranch + 1) * 3 + 4 + 1 b$ = STRING$(totalbytes, 0) ASC(b$, 1) = 2 'type 'create key '[4]store number of bits ASC(b$, 2) = totalbits AND 255: totalbits = totalbits \ 256 ASC(b$, 3) = totalbits AND 255: totalbits = totalbits \ 256 ASC(b$, 4) = totalbits AND 255: totalbits = totalbits \ 256 ASC(b$, 5) = totalbits '[3*(lastbranch+1)]store branches x = 5 FOR i = 0 TO lastbranch v = huff_bit0link(i) + huff_bit1link(i) * 4096 x = x + 1: ASC(b$, x) = v AND 255 x = x + 1: ASC(b$, x) = (v \ 256) AND 255 x = x + 1: ASC(b$, x) = v \ 65536 NEXT 'store huffman encoded data (using masks to speed up process) x = x + 1 bitpos = 0 FOR z = 1 TO LEN(a$) v = ASC(a$, z) nbits = huff_mask_bits(v) nbytes = (bitpos + nbits + 7) \ 8 o = v * 256 + bitpos * 32 FOR i = 0 TO nbytes - 1 ASC(b$, x) = ASC(b$, x) OR huff_mask(o + i) x = x + 1 NEXT bitpos = (bitpos + nbits) AND 7 IF bitpos <> 0 THEN x = x - 1 NEXT compress_2_huff$ = b$ END FUNCTION FUNCTION decompress_1_rle$ (a$) IF ASC(a$) <> 1 THEN SCREEN 0, , 0, 0: PRINT "decompress_1_rle: invalid type": END 'calculate size of final string required i = 2 siz = 0 x = ASC(a$, i) DO WHILE x IF x AND 128 THEN i = i + 1: x = ASC(a$, i) IF x AND 128 THEN i = i + 1: x = ASC(a$, i) IF x2 AND 128 THEN i = i + 1: x = ASC(a$, i) END IF END IF END IF i = i + 2 'skip value s = ASC(a$, i) IF s = 255 THEN i = i + 1: s = ASC(a$, i) i = i + 1: s2 = ASC(a$, i) IF s = 255 AND s2 = 255 THEN i = i + 1 s = ASC(a$, i + 3) s = s * 256 + ASC(a$, i + 2) s = s * 256 + ASC(a$, i + 1) s = s * 256 + ASC(a$, i) i = i + 3 ELSE s = s + s2 * 256 END IF END IF siz = siz + s + 4 i = i + 1: x = ASC(a$, i) LOOP i = i + 1 'i=beginning of uncompressed data siz = siz + (LEN(a$) - i + 1) b$ = SPACE$(siz) 'begin decompression h = 1 p = 1 ins = i n = LEN(a$) unrle_getnext: h = h + 1: x = ASC(a$, h) IF x AND 128 THEN h = h + 1: x2 = ASC(a$, h): x = (x AND 127) + (x2 AND 127) * 128 IF x2 AND 128 THEN h = h + 1: x2 = ASC(a$, h): x = x + (x2 AND 127) * 16384 IF x2 AND 128 THEN h = h + 1: x2 = ASC(a$, h): x = x + (x2 AND 127) * 2097152 END IF END IF END IF IF x = 0 THEN ins = 2147483647 ELSE ins = ins + x - 1 h = h + 1: v = ASC(a$, h) h = h + 1 s = ASC(a$, h) IF s = 255 THEN h = h + 1: s = ASC(a$, h) h = h + 1: s2 = ASC(a$, h) IF s = 255 AND s2 = 255 THEN h = h + 1 s = ASC(a$, h + 3) s = s * 256 + ASC(a$, h + 2) s = s * 256 + ASC(a$, h + 1) s = s * 256 + ASC(a$, h) h = h + 3 ELSE s = s + s2 * 256 END IF END IF c = s + 4 END IF n2 = ins - 1 IF n2 > n THEN n2 = n FOR i = i TO n2 ASC(b$, p) = ASC(a$, i): p = p + 1 NEXT IF ins <> 2147483647 THEN FOR x = 1 TO c ASC(b$, p) = v: p = p + 1 NEXT GOTO unrle_getnext END IF decompress_1_rle$ = b$ END FUNCTION FUNCTION compress_1_rle$ (a$) 'IMPORTANT: the contents of a$ are corrupted in producing rle$ '[1-4:offset from previous position][1:val][[1]/{255}[2]/{65535}[4]]:repeats-4] ' ^top bit indicates also use bits of following byte (max offset=268435456) ' ^255 indicates larger format used n = LEN(a$) h$ = SPACE$(LEN(a$) + 2) ASC(h$, 1) = 1 'method 1 hp = 2 'header position i = 1 'source position p = 1 'dest position o = 1 'offset to reference position from DO v = ASC(a$, i) FOR i2 = i + 1 TO n IF v <> ASC(a$, i2) THEN EXIT FOR NEXT reps = i2 - i x = p - o + 1 'x=relative offset to insert data+1 IF x <= 127 THEN IF reps < 4 GOTO no_rle ASC(h$, hp) = x: hp = hp + 1 ELSEIF x <= 16383 THEN IF reps < 5 GOTO no_rle ASC(h$, hp) = (x AND 127) + 128: x = x \ 128: hp = hp + 1 ASC(h$, hp) = x: hp = hp + 1 ELSEIF x <= 2097151 THEN IF reps < 6 GOTO no_rle ASC(h$, hp) = (x AND 127) + 128: x = x \ 128: hp = hp + 1 ASC(h$, hp) = (x AND 127) + 128: x = x \ 128: hp = hp + 1 ASC(h$, hp) = x: hp = hp + 1 ELSE IF reps < 7 GOTO no_rle ASC(h$, hp) = (x AND 127) + 128: x = x \ 128: hp = hp + 1 ASC(h$, hp) = (x AND 127) + 128: x = x \ 128: hp = hp + 1 ASC(h$, hp) = (x AND 127) + 128: x = x \ 128: hp = hp + 1 ASC(h$, hp) = x: hp = hp + 1 END IF o = p 'encode value ASC(h$, hp) = v: hp = hp + 1 'encode reps-4 reps = reps - 4 IF reps >= 255 THEN ASC(h$, hp) = 255: hp = hp + 1 IF reps >= 65535 THEN ASC(h$, hp) = 255: hp = hp + 1 ASC(h$, hp) = 255: hp = hp + 1 ASC(h$, hp) = reps AND 255: reps = reps \ 256: hp = hp + 1 ASC(h$, hp) = reps AND 255: reps = reps \ 256: hp = hp + 1 ASC(h$, hp) = reps AND 255: reps = reps \ 256: hp = hp + 1 ASC(h$, hp) = reps: hp = hp + 1 ELSE ASC(h$, hp) = reps AND 255: reps = reps \ 256: hp = hp + 1 ASC(h$, hp) = reps: hp = hp + 1 END IF ELSE ASC(h$, hp) = reps: hp = hp + 1 END IF GOTO rle_applied no_rle: 'not enough repeats to encode IF i <> p THEN FOR i3 = i TO i2 - 1 ASC(a$, p) = ASC(a$, i3) p = p + 1 NEXT ELSE p = p + (i2 - i) END IF rle_applied: i = i2 LOOP UNTIL i > n 'finialize header ASC(h$, hp) = 0: hp = hp + 1 compress_1_rle$ = LEFT$(h$, hp - 1) + LEFT$(a$, p - 1) END FUNCTION FUNCTION compress$ (a$) a$ = CHR$(0) + a$ a$ = compress_1_rle$(a$) a$ = compress_2_huff$(a$) compress$ = a$ END FUNCTION FUNCTION decompress$ (a$) x = ASC(a$) DO WHILE x IF x = 1 THEN a$ = decompress_1_rle$(a$) IF x = 2 THEN a$ = decompress_2_huff$(a$) x = ASC(a$) LOOP a$ = RIGHT$(a$, LEN(a$) - 1) 'remove NULL byte indicating compression complete decompress$ = a$ END FUNCTION FUNCTION download (url$, file$) 'note: set file$ to "" to use string data only PRINT "Downloading " + CHR$(34) + url$ + CHR$(34) retry = 0 retry: PRINT "[ ]"; LOCATE CSRLIN, 2 _DELAY 0.25 'allow time for closure of any previous connections, to avoid possible denial of multiple connections from host url2$ = url$ x = INSTR(url2$, "/") IF x THEN url2$ = LEFT$(url$, x - 1) c = _OPENCLIENT("TCP/IP:80:" + url2$) IF c = 0 THEN EXIT FUNCTION END IF e$ = CHR$(13) + CHR$(10) url3$ = RIGHT$(url$, LEN(url$) - x + 1) x$ = "GET " + url3$ + " HTTP/1.1" + e$ x$ = x$ + "Host: " + url2$ + e$ + e$ PUT #c, , x$ lasttime# = TIMER(0.001) cancelmess = 0 dp = 0 dp2 = 0 a$ = "" l = 0 DO _DELAY 0.1 GET #c, , a2$ a$ = a$ + a2$ IF LEN(a2$) THEN lasttime# = TIMER(0.001) IF TIMER(0.001) > lasttime# + 5 THEN IF retry < 10 THEN 'automatically retry up to 10 times retry = retry + 1 CLOSE #c PRINT PRINT "Retry attempt" + STR$(retry) + "/10" GOTO retry END IF END IF IF TIMER(0.001) > lasttime# + 20 THEN IF cancelmess = 0 THEN cancelmess = 1 cl = CSRLIN cp = POS(0) LOCATE 25, 1 PRINT "Download may still be active! To abort this download press the ESC key."; LOCATE cl, cp DO UNTIL INKEY$ = "": LOOP 'flush kb buffer END IF END IF IF cancelmess = 1 THEN IF INKEY$ = CHR$(27) THEN PRINT CLOSE #c EXIT FUNCTION END IF END IF IF l THEN 'length is known IF i3 <> 0 THEN dp = (LEN(a$) - i3) / l * 50 IF dp > 50 THEN dp = 50 IF dp < 0 THEN dp = 0 DO WHILE dp2 < dp PRINT "þ"; dp2 = dp2 + 1 LOOP END IF END IF i = INSTR(a$, "Content-Length:") IF i THEN i2 = INSTR(i, a$, e$) IF i2 THEN l = VAL(MID$(a$, i + 15, i2 - i - 14)) i3 = INSTR(i2, a$, e$ + e$) IF i3 THEN i3 = i3 + 4 'move i3 to start of data IF (LEN(a$) - i3 + 1) = l THEN CLOSE c Download_String$ = MID$(a$, i3, l) IF file$ <> "" THEN fh = FREEFILE OPEN file$ FOR OUTPUT AS #fh: CLOSE #fh OPEN file$ FOR BINARY AS #fh PUT #fh, , Download_String$ CLOSE #fh END IF download = -1 DO WHILE dp2 < 50 PRINT "þ"; dp2 = dp2 + 1 LOOP PRINT EXIT FUNCTION END IF 'availabledata=l END IF 'i3 END IF 'i2 END IF 'i LOOP END FUNCTION FUNCTION chksum&& (f$) DIM c AS _INTEGER64, x AS _INTEGER64, b AS _INTEGER64 OPEN f$ FOR BINARY ACCESS READ SHARED AS #123 a$ = SPACE$(LOF(123)) GET #123, , a$ CLOSE #123 c = LEN(a$) b = 1 $CHECKING:OFF FOR i = 1 TO LEN(a$) c = c + (b * (ASC(a$, i) + 1)) b = b + b IF b = 281474976710656 THEN b = 1 NEXT $CHECKING:ON chksum&& = c END FUNCTION FUNCTION BeginDownload (url$) FOR i = 1 TO DLs IF DL(i).State = 0 THEN EXIT FOR NEXT IF i > DLs THEN DLs = DLs + 1 IF i > Maxdls THEN SCREEN 0, , 0, 0: PRINT "Too many active downloads!": END url2$ = url$ x = INSTR(url2$, "/") IF x THEN url2$ = LEFT$(url$, x - 1) h = _OPENCLIENT("TCP/IP:80:" + url2$) IF h = 0 THEN EXIT FUNCTION '0=failed e$ = CHR$(13) + CHR$(10) url3$ = RIGHT$(url$, LEN(url$) - x + 1) x$ = "GET " + url3$ + " HTTP/1.1" + e$ x$ = x$ + "Host: " + url2$ + e$ + e$ PUT #h, , x$ DL(i).State = 1 DL(i).Handle = h DL_Data(i) = "" BeginDownload = i END FUNCTION SUB ContinueDownloads e$ = CHR$(13) + CHR$(10) FOR d = 1 TO DLs s = DL(d).State IF s > 0 THEN SELECT CASE s CASE 1 GET #DL(d).Handle, , a2$ DL_Data(d) = DL_Data(d) + a2$ a$ = DL_Data(d) i = INSTR(a$, "Content-Length:") IF i THEN i2 = INSTR(i, a$, e$) IF i2 THEN l = VAL(MID$(a$, i + 15, i2 - i - 14)) i3 = INSTR(i2, a$, e$ + e$) IF i3 THEN i3 = i3 + 4 'move i3 to start of data IF (LEN(a$) - i3 + 1) >= l THEN DL_Data(d) = MID$(a$, i3, l) DL(d).State = 2 'finished! CLOSE #DL(d).Handle END IF 'availabledata=l END IF 'i3 END IF 'i2 END IF 'i CASE ELSE '... END SELECT END IF NEXT END SUB FUNCTION rippath$ (a$) 'doesn't include final \ FOR i = LEN(a$) TO 1 STEP -1 IF ASC(a$, i) = 92 THEN rippath$ = LEFT$(a$, i - 1): EXIT FUNCTION NEXT END FUNCTION SUB update (how) '0=called by IDE via automatic checking '1=called by IDE from File->Update menu option '2=called by -c command line compilation via automatic checking (from compilation finished/compilation error) '3=called by -c command line compilation via automatic checking (from syntax error) ON ERROR GOTO update_error_handler v$ = DL_Data(UpdateHandle): DL_Data(UpdateHandle) = "": DL(UpdateHandle).State = 0 'avoid update if multiple instances of QB64 are running IF tempfolderindex <> 1 THEN GOTO pretendnoupdates FOR i = 2 TO 4 MKDIR ".\internal\temp" + str2$(i) t$ = ".\internal\temp" + str2$(i) + "\" update_error = 0 OPEN t$ + "temp.bin" FOR OUTPUT LOCK READ WRITE AS #1 IF update_error THEN GOTO pretendnoupdates CLOSE #1 NEXT MKDIR ".\internal\update" MKDIR ".\internal\update\downloads" 'check current version against latest version uf$ = ".\internal\update\" OPEN uf$ + "update.txt" FOR BINARY AS #1 IF LOF(1) THEN CLOSE #1 OPEN uf$ + "update.txt" FOR INPUT AS #1: LINE INPUT #1, a$: CLOSE #1 ELSE CLOSE #1 a$ = "UNKNOWN" END IF IF a$ = v$ THEN 'latest version installed pretendnoupdates: IF how = 1 THEN idemessagebox "Update", "No new updates available." PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt END IF ON ERROR GOTO qberror EXIT SUB END IF '...ask user if they would like to apply new updates... IF (how = 0 AND ideupdateauto = 0) OR how = 1 THEN what$ = ideyesnobox$("Update Available", "Download and apply new update?") 'returns "Y" or "N" PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF what$ = "N" THEN ON ERROR GOTO qberror EXIT SUB END IF END IF IF how >= 2 AND ideupdateauto = 0 THEN IF compfailed THEN compfailed = 0 'cancel wait before exit PRINT "Update available!" PRINT "Download and apply new update? (Y/N)" DO: _LIMIT 100: K$ = UCASE$(INKEY$): LOOP UNTIL K$ = "N" OR K$ = "Y" IF K$ = "N" THEN IF how = 3 THEN SYSTEM ON ERROR GOTO qberror EXIT SUB END IF END IF IF how = 3 AND ideupdateauto = 1 THEN 'ensure user sees the error message printed above before continuing cl = CSRLIN LOCATE 25, 1: PRINT "Press any key to continue"; DO: _LIMIT 100: LOOP UNTIL INKEY$ <> "" LOCATE 25, 1: PRINT " "; LOCATE cl, 1 END IF IF how < 2 THEN SCREEN 0, , 0, 0 COLOR 7, 1 CLS END IF PRINT "Updating QB64" 'load current chksums into arrays for faster referencing OPEN uf$ + "chksums.txt" FOR BINARY AS #1 IF LOF(1) THEN CLOSE #1 'enumerate entries n = 0 OPEN uf$ + "chksums.txt" FOR INPUT AS #1 DO UNTIL EOF(1) LINE INPUT #1, a$: IF LEN(a$) THEN n = n + 1 LOOP CLOSE #1 IF n = 0 THEN n = 1 REDIM _PRESERVE chksums_name(1 TO n) AS STRING REDIM _PRESERVE chksums_valstr(1 TO n) AS STRING 'get entries n = 0 OPEN uf$ + "chksums.txt" FOR INPUT AS #1 DO UNTIL EOF(1) LINE INPUT #1, a$ IF LEN(a$) THEN n = n + 1 i = INSTR(a$, ",") a1$ = LEFT$(a$, i - 1): a2$ = RIGHT$(a$, LEN(a$) - i) chksums_name(n) = a1$: chksums_valstr(n) = a2$ END IF LOOP CLOSE #1 ELSE n = 0 CLOSE #1 END IF nchksums = n url$ = "www.qb64.net/" + v$ + "/" dlretry2: OK = download(url$ + "chksums.q", "") IF NOT OK THEN IF how <= 1 THEN PCOPY 3, 0: what$ = ideyesnobox("Download Failed", "Retry?"): PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF what$ = "Y" THEN SCREEN 0, , 0, 0: COLOR 7, 1: CLS: GOTO dlretry2 END IF ON ERROR GOTO qberror EXIT SUB END IF PRINT "Download Failed!": PRINT "Retry? (Y/N)" DO: _LIMIT 100: K$ = UCASE$(INKEY$): LOOP UNTIL K$ = "N" OR K$ = "Y" IF K$ = "N" THEN IF compfailed THEN PRINT "C++ COMPILATION FAILED!" 'redisplay failed message ON ERROR GOTO qberror IF how = 3 THEN SYSTEM EXIT SUB END IF GOTO dlretry2 END IF a$ = decompress(Download_String) OPEN uf$ + "chksums.tmp" FOR OUTPUT AS #1: PRINT #1, a$;: CLOSE #1 OPEN uf$ + "chksums.tmp" FOR INPUT AS #1 'seperate for testing, the same in practise qf$ = ".\" qf2$ = ".\" chksums_updated = 0 files_updated = 0 OPEN "setup.bat" FOR OUTPUT AS #10 PRINT #10, "@ping 127.0.0.1 -n 4 -w 1000 >NUL" 'wait 2 seconds to ensure this program as ended df$ = uf$ + "downloads\" n = 0 DO UNTIL EOF(1) LINE INPUT #1, a$ IF LEN(a$) THEN n = n + 1 i = INSTR(a$, ",") a1$ = LEFT$(a$, i - 1): a2$ = RIGHT$(a$, LEN(a$) - i) IF a2$ <> "0" THEN FOR i = 1 TO nchksums IF a1$ = chksums_name(i) THEN IF a2$ = chksums_valstr(i) THEN GOTO nochange 'same name, but differing checksum 'before overriding existing file, check if its content matches its existing chksum and warn if it doesn't update_error = 0 OPEN qf$ + a1$ FOR BINARY AS #2 IF update_error = 0 THEN IF LOF(2) THEN CLOSE #2 'it exists, so check its chksum c&& = chksum(qf$ + a1$): c$ = LTRIM$(RTRIM$(STR$(c&&))) IF c$ <> chksums_valstr(i) THEN 'possible custom mod warning chksums_updated = 1 'warning IF how <= 1 THEN PCOPY 3, 0 idemessagebox "This file has been modified by you but will be overwritten!", a1$ PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt SCREEN 0, , 0, 0 COLOR 7, 1 CLS END IF IF how >= 2 THEN PRINT "This file has been modified by you but will be overwritten: " + CHR$(34) + a1$ + CHR$(34) PRINT "Press any key to continue" DO: _LIMIT 100: LOOP UNTIL INKEY$ <> "" END IF chksums_valstr(i) = c$ END IF ELSE CLOSE #2 KILL qf$ + a1$ chksums_valstr(i) = "0" 'file no longer exists or is inaccessible chksums_updated = 1 END IF ELSE chksums_valstr(i) = "0" 'file no longer exists or is inaccessible chksums_updated = 1 END IF GOTO foundchksum END IF NEXT chksums_updated = 1 'chksum index not found, so check if file exists update_error = 0 OPEN qf$ + a1$ FOR BINARY AS #2 IF update_error = 0 THEN IF LOF(2) THEN CLOSE #2 'it exists, so add a chksum for it c&& = chksum(qf$ + a1$): c$ = LTRIM$(RTRIM$(STR$(c&&))) nchksums = nchksums + 1 REDIM _PRESERVE chksums_name(1 TO nchksums) AS STRING REDIM _PRESERVE chksums_valstr(1 TO nchksums) AS STRING chksums_name(nchksums) = a1$ chksums_valstr(nchksums) = c$ i = nchksums ELSE CLOSE #2 KILL qf$ + a1$ nchksums = nchksums + 1 REDIM _PRESERVE chksums_name(1 TO nchksums) AS STRING REDIM _PRESERVE chksums_valstr(1 TO nchksums) AS STRING i = nchksums GOTO nochksum END IF ELSE 'error nchksums = nchksums + 1 REDIM _PRESERVE chksums_name(1 TO nchksums) AS STRING REDIM _PRESERVE chksums_valstr(1 TO nchksums) AS STRING i = nchksums END IF foundchksum: IF chksums_valstr(i) = a2$ THEN GOTO nochange nochksum: 'set index i with new file's value and download chksums_name(i) = a1$ chksums_valstr(i) = a2$ dlretry: PRINT "Getting file:" + a1$ + "(" + LTRIM$(STR$(n)) + ".q)" OK = download(url$ + LTRIM$(STR$(n)) + ".q", "") IF NOT OK THEN IF how <= 1 THEN PCOPY 3, 0 what$ = ideyesnobox("Download Failed", "Retry?") PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt IF what$ = "Y" THEN SCREEN 0, , 0, 0 COLOR 7, 1 CLS GOTO dlretry END IF ON ERROR GOTO qberror IF how = 3 THEN SYSTEM EXIT SUB END IF PRINT "Download Failed!": PRINT "Retry? (Y/N)" DO: _LIMIT 100: K$ = UCASE$(INKEY$): LOOP UNTIL K$ = "N" OR K$ = "Y" IF K$ = "N" THEN IF compfailed THEN PRINT "C++ COMPILATION FAILED!" 'redisplay failed message ON ERROR GOTO qberror EXIT SUB END IF GOTO dlretry END IF files_updated = 1 'put the file in our updates folder OPEN df$ + LTRIM$(STR$(n)) + ".bin" FOR BINARY AS #2 x$ = decompress(Download_String) PUT #2, , x$ CLOSE #2 'add batch install lines 'ensure folder exists p$ = rippath$(a1$) IF p$ <> "" THEN PRINT #10, "md " + CHR$(34) + qf2$ + p$ + CHR$(34) 'move file (preserving case of filename) PRINT #10, "del " + CHR$(34) + qf2$ + a1$ + CHR$(34) PRINT #10, "copy " + CHR$(34) + df$ + LTRIM$(STR$(n)) + ".bin" + CHR$(34) + " " + CHR$(34) + qf2$ + a1$ + CHR$(34) PRINT #10, "del " + CHR$(34) + df$ + LTRIM$(STR$(n)) + ".bin" + CHR$(34) nochange: END IF '<>"0" END IF LOOP CLOSE #1 IF files_updated = 1 THEN 'create new chksum file OPEN uf$ + "chksums.tmp" FOR OUTPUT AS #1 FOR i = 1 TO nchksums PRINT #1, chksums_name(i) + "," + chksums_valstr(i) NEXT CLOSE #1 'create new update file OPEN uf$ + "update.tmp" FOR OUTPUT AS #1 PRINT #1, v$; CLOSE #1 PRINT #10, "copy " + uf$ + "chksums.tmp " + uf$ + "chksums.txt" PRINT #10, "del " + uf$ + "chksums.tmp" PRINT #10, "copy " + uf$ + "update.tmp " + uf$ + "update.txt" PRINT #10, "del " + uf$ + "update.tmp" IF how < 2 THEN PRINT #10, "start qb64.exe" 'attempt to relaunch qb64 PRINT #10, "del setup.bat" CLOSE #10 CLOSE IF how = 2 THEN IF compfailed THEN PRINT "C++ COMPILATION FAILED!" 'redisplay failed message LOCATE 25, 1: PRINT "Press any key to continue"; DO: _LIMIT 100: LOOP UNTIL LEN(INKEY$) END IF END IF fh = FREEFILE: OPEN tmpdir$ + "autosave.bin" FOR OUTPUT AS #fh: CLOSE #fh RUN "setup.bat" END IF CLOSE #10 KILL "setup.bat" IF chksums_updated = 1 THEN 'create new chksum file OPEN uf$ + "chksums.txt" FOR OUTPUT AS #1 FOR i = 1 TO nchksums PRINT #1, chksums_name(i) + "," + chksums_valstr(i) NEXT CLOSE #1 'PRINT "Checksums were updated." ELSE 'PRINT "No changes necessary" END IF 'replace update (version) file OPEN uf$ + "update.txt" FOR OUTPUT AS #1 PRINT #1, v$; CLOSE #1 KILL uf$ + "chksums.tmp" IF how <= 1 THEN PCOPY 3, 0 idemessagebox "Update", "No changes required." PCOPY 3, 0: SCREEN , , 3, 0: idewait4mous: idewait4alt END IF IF how = 2 THEN IF compfailed THEN PRINT "C++ COMPILATION FAILED!" 'redisplay failed message END IF ON ERROR GOTO qberror IF how = 3 THEN SYSTEM END SUB FUNCTION removecast$ (a$) removecast$ = a$ IF INSTR(a$, " )") THEN removecast$ = RIGHT$(a$, LEN(a$) - INSTR(a$, " )") - 2) END IF END FUNCTION FUNCTION converttabs$ (a2$) IF ideautoindent THEN s = ideautoindentsize ELSE s = 4 a$ = a2$ DO WHILE INSTR(a$, chr_tab) x = INSTR(a$, chr_tab) a$ = LEFT$(a$, x - 1) + SPACE$(s - ((x - 1) MOD s)) + RIGHT$(a$, LEN(a$) - x) LOOP converttabs$ = a$ END FUNCTION FUNCTION CTRL2 IF MacOSX THEN IF _KEYDOWN(100309) THEN CTRL2 = 1 IF _KEYDOWN(100310) THEN CTRL2 = 1 END IF END FUNCTION FUNCTION NewByteElement$ a$ = "byte_element_" + str2$(uniquenumber) NewByteElement$ = a$ IF use_global_byte_elements THEN PRINT #18, "byte_element_struct *" + a$ + "=(byte_element_struct*)malloc(12);" ELSE PRINT #13, "byte_element_struct *" + a$ + "=NULL;" PRINT #13, "if (!" + a$ + "){" PRINT #13, "if ((mem_static_pointer+=12) 40 THEN IF l = 0 THEN EXIT FUNCTION 'Note: variable names with periods need to be obfuscated, and this affects their length i = INSTR(a$, fix046$) DO WHILE i l = l - LEN(fix046$) + 1 i = INSTR(i + 1, a$, fix046$) LOOP IF l > 40 THEN EXIT FUNCTION l = LEN(a$) END IF 'check for single, leading underscore IF l >= 2 THEN IF ASC(a$, 1) = 95 AND ASC(a$, 2) <> 95 THEN EXIT FUNCTION END IF FOR i = 1 TO l a = ASC(a$, i) IF alphanumeric(a) = 0 THEN EXIT FUNCTION IF isnumeric(a) THEN trailingunderscore = 0 IF alphabetletter = 0 THEN EXIT FUNCTION ELSE IF a = 95 THEN trailingunderscore = 1 ELSE alphabetletter = 1 trailingunderscore = 0 END IF END IF NEXT IF trailingunderscore THEN EXIT FUNCTION validname = 1 END FUNCTION FUNCTION str_nth$ (x) IF x = 1 THEN str_nth$ = "1st": EXIT FUNCTION IF x = 2 THEN str_nth$ = "2nd": EXIT FUNCTION IF x = 3 THEN str_nth$ = "3rd": EXIT FUNCTION str_nth$ = str2(x) + "th" END FUNCTION SUB Give_Error (a$) Error_Happened = 1 Error_Message = a$ END SUB SUB GetInput IF iCHECKLATER THEN iCHECKLATER = 0: EXIT SUB 'Clear/Update immediate return values iCHANGED = 0 KSTATECHANGED = 0 mCLICK = 0: mCLICK2 = 0: mRELEASE = 0: mRELEASE2 = 0 mWHEEL = 0 K$ = "": KB = 0 mOB = mB: mOB2 = mB2 KOALT = KALT: KALTPRESS = 0: KALTRELEASE = 0 'Flush INKEY$ buffer (for good measure) DO: LOOP UNTIL INKEY$ = "" 'Keyboard event? k = _KEYHIT IF k THEN IF k < 0 THEN k = -k: release = 1 'modifiers IF k = KEY_LSHIFT OR k = KEY_RSHIFT THEN IF release = 1 THEN KSHIFT = 0 ELSE KSHIFT = -1 iCHANGED = -1: KSTATECHANGED = -1 END IF IF k = KEY_LALT OR k = KEY_RALT THEN IF release = 1 THEN KALT = 0: KALTRELEASE = -1 ELSE KALT = -1: KALTPRESS = -1 iCHANGED = -1: KSTATECHANGED = -1 END IF IF k = KEY_LCTRL OR k = KEY_RCTRL THEN IF release = 1 THEN KCTRL = 0: KCONTROL = 0 ELSE KCTRL = -1: KCONTROL = -1 iCHANGED = -1: KSTATECHANGED = -1 END IF IF k = KEY_LAPPLE OR k = KEY_RAPPLE THEN IF release = 1 THEN KCONTROL = 0 ELSE KCONTROL = -1 iCHANGED = -1: KSTATECHANGED = -1 END IF 'presses IF release = 0 THEN iCHANGED = -1 IF k <= 255 THEN K$ = CHR$(k) IF k >= 256 AND k <= 65535 AND ((k AND 255) = 0) THEN K$ = CHR$(0) + CHR$(k \ 256) KB = k END IF IF iCHANGED THEN EXIT SUB END IF DO WHILE _MOUSEINPUT iCHANGED = 1 mB = _MOUSEBUTTON(1): mB2 = _MOUSEBUTTON(2) mWHEEL = mWHEEL + _MOUSEWHEEL mX = _MOUSEX: mY = _MOUSEY IF mB <> 0 AND mOB = 0 THEN mCLICK = -1: EXIT SUB IF mB2 <> 0 AND mOB2 = 0 THEN mCLICK2 = -1: EXIT SUB IF mB = 0 AND mOB <> 0 THEN mRELEASE = -1: EXIT SUB IF mB2 = 0 AND mOB2 <> 0 THEN mRELEASE2 = -1: EXIT SUB LOOP END SUB SUB Help_ShowText STATIC setup IF setup = 0 AND UBOUND(back$) = 1 THEN setup = 1 a$ = Wiki(Back$(1)) WikiParse a$ END IF REDIM Help_LineLen(Help_wh) COLOR 7, 0 'CLS 'FOR y = Help_wy1 - 1 TO Help_wy2 + 1 ' FOR x = Help_wx1 - 1 TO Help_wx2 + 1 ' LOCATE y, x: PRINT "Û"; ' NEXT 'NEXT sy = Help_wy1 FOR y = Help_sy TO Help_sy + Help_wh - 1 IF y <= help_h THEN 'PRINT CVL(MID$(Help_Line$, (y - 1) * 4 + 1, 4)), LEN(Help_Txt$) l = CVL(MID$(Help_Line$, (y - 1) * 4 + 1, 4)) x = l x3 = 1 sx = Help_wx1 c = ASC(Help_Txt$, x): col = ASC(Help_Txt$, x + 1) LOCATE sy, sx DO UNTIL c = 13 COLOR col AND 15, col \ 16 IF Help_Select = 2 THEN IF y >= Help_SelY1 AND y <= Help_SelY2 THEN IF x3 >= Help_SelX1 AND x3 <= Help_SelX2 THEN COLOR 0, 7 END IF END IF END IF IF x3 >= Help_sx THEN IF sx <= Help_wx2 THEN PRINT CHR$(c); sx = sx + 1 END IF END IF x3 = x3 + 1: x = x + 4: c = ASC(Help_Txt$, x): col = ASC(Help_Txt$, x + 1) LOOP Help_LineLen(y - Help_sy) = x3 - 1 FOR x4 = 1 TO Help_wx2 - POS(0) + 1 IF col = 0 THEN col = 7 COLOR col AND 15, col \ 16 IF Help_Select = 2 THEN IF y >= Help_SelY1 AND y <= Help_SelY2 THEN IF x3 >= Help_SelX1 AND x3 <= Help_SelX2 THEN COLOR 0, 7 END IF END IF END IF PRINT " "; x3 = x3 + 1 NEXT ELSE sx = Help_wx1 LOCATE sy, sx x3 = Help_sx FOR x4 = 1 TO Help_ww COLOR 7, 0 IF Help_Select = 2 THEN IF y >= Help_SelY1 AND y <= Help_SelY2 THEN IF x3 >= Help_SelX1 AND x3 <= Help_SelX2 THEN COLOR 0, 7 END IF END IF END IF PRINT " "; x3 = x3 + 1 NEXT Help_LineLen(y - Help_sy) = 0 END IF sy = sy + 1 NEXT 'LOCATE Help_cy - Help_sy + Help_wy1, Help_cx - Help_sx + Help_wx1 'COLOR 15, 4 'PRINT CHR$(SCREEN(CSRLIN, POS(0))); 'c = 0 'DO ' old_kcontrol = KCONTROL ' GetInput ' IF KB > 0 THEN c = 1 ' IF mCLICK THEN c = 1 ' IF mWHEEL THEN c = 1 ' IF KCONTROL AND old_kcontrol = 0 THEN c = 0 ' IF mB THEN c = 1 'LOOP UNTIL c END SUB SUB SetDependency (requirement) IF requirement THEN DEPENDENCY(requirement) = 1 END IF END SUB SUB Build (path$) 'Count the separators in the path depth = 1 FOR x = 1 TO LEN(path$) IF ASC(path$, x) = 92 OR ASC(path$, x) = 47 THEN depth = depth + 1 NEXT CHDIR path$ bfh = FREEFILE OPEN "build" + BATCHFILE_EXTENSION FOR INPUT AS #bfh DO UNTIL EOF(bfh) LINE INPUT #bfh, c$ use = 0 IF LEN(c$) THEN use = 1 IF c$ = "pause" THEN use = 0 IF LEFT$(c$, 1) = "#" THEN use = 0 'eg. #!/bin/sh IF LEFT$(c$, 13) = "cd " + CHR$(34) + "$(dirname" THEN use = 0 'eg. cd "$(dirname "$0")" IF INSTR(LCASE$(c$), "press any key") THEN EXIT DO c$ = GDB_Fix$(c$) IF use THEN IF os$ = "WIN" THEN SHELL _HIDE "cmd /C " + c$ ELSE SHELL _HIDE c$ END IF END IF LOOP CLOSE #bfh return_path$ = ".." FOR x = 2 TO depth return_path$ = return_path$ + "\.." NEXT CHDIR return_path$ END SUB FUNCTION GDB_Fix$ (g_command$) 'edit a gcc/g++ command line to include debugging info c$ = g_command$ IF Include_GDB_Debugging_Info THEN IF LEFT$(c$, 4) = "gcc " OR LEFT$(c$, 4) = "g++ " THEN c$ = LEFT$(c$, 4) + " -g " + RIGHT$(c$, LEN(c$) - 4) GOTO added_gdb_flag END IF FOR o = 1 TO 6 IF o = 1 THEN o$ = "\g++ " IF o = 2 THEN o$ = "/g++ " IF o = 3 THEN o$ = "\gcc " IF o = 4 THEN o$ = "/gcc " IF o = 5 THEN o$ = " gcc " IF o = 6 THEN o$ = " g++ " x = INSTR(UCASE$(c$), UCASE$(o$)) 'note: -g adds debug symbols IF x THEN c$ = LEFT$(c$, x - 1) + o$ + " -g " + RIGHT$(c$, LEN(c$) - x - (LEN(o$) - 1)): EXIT FOR NEXT added_gdb_flag: 'note: -s strips all debug symbols which is good for size but not for debugging x = INSTR(c$, " -s "): IF x THEN c$ = LEFT$(c$, x - 1) + " " + RIGHT$(c$, LEN(c$) - x - 3) END IF GDB_Fix$ = c$ END FUNCTION SUB PATH_SLASH_CORRECT (a$) IF os$ = "WIN" THEN FOR x = 1 TO LEN(a$) IF ASC(a$, x) = 47 THEN ASC(a$, x) = 92 NEXT ELSE FOR x = 1 TO LEN(a$) IF ASC(a$, x) = 92 THEN ASC(a$, x) = 47 NEXT END IF END SUB SUB gl END SUB '----------------ripgl.bas-------------------------------------------------------------------------------- FUNCTION gl2qb_type_convert$ (a$, symbol$, typ, ctyp$) symbol$ = "" 'unsigned int IF a$ = "GLenum" THEN b$ = "_UNSIGNED LONG": symbol$ = "~&": typ = ULONGTYPE - ISPOINTER: ctyp$ = "uint32" IF a$ = "GLbitfield" THEN b$ = "_UNSIGNED LONG": symbol$ = "~&": typ = ULONGTYPE - ISPOINTER: ctyp$ = "uint32" IF a$ = "GLuint" THEN b$ = "_UNSIGNED LONG": symbol$ = "~&": typ = ULONGTYPE - ISPOINTER: ctyp$ = "uint32" 'int IF a$ = "GLint" THEN b$ = "LONG": symbol$ = "&": typ = LONGTYPE - ISPOINTER: ctyp$ = "int32" IF a$ = "GLsizei" THEN b$ = "LONG": symbol$ = "&": typ = LONGTYPE - ISPOINTER: ctyp$ = "int32" 'unsigned char IF a$ = "GLboolean" THEN b$ = "_UNSIGNED _BYTE": symbol$ = "~%%": typ = UBYTETYPE - ISPOINTER: ctyp$ = "uint8" IF a$ = "GLubyte" THEN b$ = "_UNSIGNED _BYTE": symbol$ = "~%%": typ = UBYTETYPE - ISPOINTER: ctyp$ = "uint8" 'char IF a$ = "GLbyte" THEN b$ = "_BYTE": symbol$ = "%%": typ = BYTETYPE - ISPOINTER: ctyp$ = "int8" 'unsigned short IF a$ = "GLushort" THEN b$ = "_UNSIGNED INTEGER": symbol$ = "~%": typ = UINTEGERTYPE - ISPOINTER: ctyp$ = "uint16" 'short IF a$ = "GLshort" THEN b$ = "INTEGER": symbol$ = "%": typ = INTEGERTYPE - ISPOINTER: ctyp$ = "int16" 'float IF a$ = "GLfloat" THEN b$ = "SINGLE": symbol$ = "!": typ = SINGLETYPE - ISPOINTER: ctyp$ = "float" IF a$ = "GLclampf" THEN b$ = "SINGLE": symbol$ = "!": typ = SINGLETYPE - ISPOINTER: ctyp$ = "float" 'double IF a$ = "GLdouble" THEN b$ = "DOUBLE": symbol$ = "#": typ = DOUBLETYPE - ISPOINTER: ctyp$ = "double" IF a$ = "GLclampd" THEN b$ = "DOUBLE": symbol$ = "#": typ = DOUBLETYPE - ISPOINTER: ctyp$ = "double" 'void IF a$ = "GLvoid" THEN b$ = "_OFFSET": symbol$ = "&&": typ = OFFSETTYPE - ISPOINTER: ctyp$ = "ptrszint" 'typedef unsigned int GLenum; 'typedef unsigned char GLboolean; 'typedef unsigned int GLbitfield; 'typedef signed char GLbyte; 'typedef short GLshort; 'typedef int GLint; 'typedef int GLsizei; 'typedef unsigned char GLubyte; 'typedef unsigned short GLushort; 'typedef unsigned int GLuint; 'typedef float GLfloat; 'typedef float GLclampf; 'typedef double GLdouble; 'typedef double GLclampd; 'typedef void GLvoid; IF b$ = "" THEN PRINT "Unknown type:" + a$: END gl2qb_type_convert$ = b$ END FUNCTION FUNCTION readchunk$ (a$, last_character$) a$ = LTRIM$(RTRIM$(a$)) FOR x = 1 TO LEN(a$) c = ASC(a$, x) IF c = 32 OR c = 44 OR c = 40 OR c = 41 THEN last_character$ = CHR$(c): readchunk$ = LEFT$(a$, x - 1): a$ = LTRIM$(RIGHT$(a$, LEN(a$) - x)): EXIT FUNCTION NEXT readchunk$ = a$: last_character$ = "": a$ = "" END FUNCTION SUB gl_scan_header IF GL_KIT THEN hk = FREEFILE: OPEN "internal\c\parts\core\gl_header_for_parsing\temp\gl_kit.bas" FOR OUTPUT AS #hk IF GL_KIT THEN PRINT #hk, "DECLARE LIBRARY" d = 0: a2$ = "" h = FREEFILE OPEN "internal\c\parts\core\gl_header_for_parsing\gl.h" FOR INPUT AS #h DO UNTIL EOF(h) LINE INPUT #h, a$ IF LEN(a$) THEN a$ = LTRIM$(RTRIM$(a$)) IF LEFT$(a$, 8) = "#define " THEN a2$ = "" a$ = a$ + " " FOR x = 1 TO LEN(a$) c = ASC(a$, x) IF c = 32 THEN FOR x2 = 1 TO LEN(a2$) c2 = ASC(a2$, x2) IF c2 >= 65 AND c2 <= 90 THEN GOTO define_ok IF c2 >= 48 AND c2 <= 57 AND x2 <> 1 THEN GOTO define_ok IF c2 = 95 THEN GOTO define_ok GOTO define_not_ok define_ok: NEXT value$ = LTRIM$(RTRIM$(RIGHT$(a$, LEN(a$) - x))) IF LEN(value$) = 0 THEN GOTO define_not_ok IF LEFT$(value$, 2) = "0x" THEN value&& = VAL("&H" + RIGHT$(value$, LEN(value$) - 2) + "&&") 'PRINT a2$, value&& d = d + 1: GL_DEFINES(d) = a2$: GL_DEFINES_VALUE(d) = value&& ELSEIF ASC(value$) >= 48 AND ASC(value$) <= 57 THEN value&& = VAL(value$) 'PRINT a2$, value&& d = d + 1: GL_DEFINES(d) = a2$: GL_DEFINES_VALUE(d) = value&& ELSE 'PRINT a2$, value$, "?" FOR i = 1 TO d IF GL_DEFINES(i) = value$ THEN d = d + 1: GL_DEFINES(d) = a2$: GL_DEFINES_VALUE(d) = GL_DEFINES_VALUE(i) 'PRINT a2$, GL_DEFINES_VALUE(i) EXIT FOR END IF NEXT END IF GOTO got_define define_not_ok: a2$ = "" ELSE a2$ = a2$ + CHR$(c) END IF NEXT got_define: END IF '#define IF RIGHT$(a$, 1) = ";" THEN a2$ = readchunk(a$, l$): IF a2$ <> "WINGDIAPI" GOTO discard ret_type$ = readchunk(a$, l$) IF ret_type$ = "const" THEN ret_type$ = readchunk(a$, l$) is_func = 0: IF ret_type$ <> "void" THEN is_func = 1 a2$ = readchunk(a$, l$) IF a2$ = "*APIENTRY" THEN ret_type$ = ret_type$ + "*": a2$ = "APIENTRY" IF a2$ <> "APIENTRY" THEN GOTO discard GL_COMMANDS_LAST = GL_COMMANDS_LAST + 1 c = GL_COMMANDS_LAST hc$ = "" hd$ = "" need_helper_function = 0 IF is_func THEN GL_COMMANDS(c).subfunc = 1 IF GL_KIT THEN PRINT #hk, "FUNCTION "; ELSE GL_COMMANDS(c).subfunc = 2 IF GL_KIT THEN PRINT #hk, "SUB "; END IF proc_name$ = readchunk(a$, l$) GL_COMMANDS(c).cn = "_" + proc_name$: IF GL_KIT THEN PRINT #hk, proc_name$; GL_COMMANDS(c).callname = proc_name$ GL_COMMANDS(c).ret = 0 IF is_func THEN pointer = 0: IF RIGHT$(ret_type$, 1) = "*" THEN pointer = 1 IF pointer THEN t$ = "_OFFSET": s$ = "&&" GL_COMMANDS(c).ret = OFFSETTYPE - ISPOINTER hd$ = hd$ + "ptrszint " need_helper_function = 1 ELSE t$ = gl2qb_type_convert(ret_type$, s$, typ, ctyp$) GL_COMMANDS(c).ret = typ hd$ = hd$ + ctyp$ + " " END IF IF GL_KIT THEN PRINT #hk, s$; hc$ = hc$ + "return (" + ctyp$ + ")(" + ret_type$ + ")" ELSE hd$ = hd$ + "void " END IF IF GL_KIT THEN PRINT #hk, "("; hc$ = hc$ + proc_name$ + "(" hd$ = hd$ + "call_" + proc_name$ + "(" GL_COMMANDS(c).args = 0 GL_COMMANDS(c).arg = "" DO var_type$ = readchunk(a$, l$) IF var_type$ = "" AND l$ = "(" THEN var_type$ = readchunk(a$, l$) 'space between fun name and "("? IF var_type$ = "const" THEN var_type$ = readchunk(a$, l$) IF var_type$ = "void" OR var_type$ = "" THEN GOTO no_arguments IF l$ <> "," AND l$ <> ")" THEN var_name$ = readchunk(a$, l$) IF LEFT$(var_name$, 1) = "*" THEN var_type$ = var_type$ + "*": var_name$ = RIGHT$(var_name$, LEN(var_name$) - 1) IF LEFT$(var_name$, 1) = "*" THEN var_type$ = var_type$ + "*": var_name$ = RIGHT$(var_name$, LEN(var_name$) - 1) 'Note: could be a poiner to a pointer ELSE var_name$ = "no_name" END IF var_type_backup$ = var_type$ pointer = 0 IF RIGHT$(var_type$, 1) = "*" THEN var_type$ = LEFT$(var_type$, LEN(var_type$) - 1) pointer = 1 END IF IF RIGHT$(var_type$, 1) = "*" THEN var_type$ = LEFT$(var_type$, LEN(var_type$) - 1) pointer = 2 END IF IF pointer = 2 THEN qb_type$ = "_OFFSET" 'it's the offset of an offset ELSE qb_type$ = gl2qb_type_convert$(var_type$, s$, typ, ctyp$) END IF 'IF pointer THEN need_helper_function = 1 need_helper_function = 1 IF GL_KIT THEN IF pointer = 0 THEN PRINT #hk, "BYVAL "; PRINT #hk, var_name$ + " AS " + qb_type$; IF l$ <> ")" THEN PRINT #hk, ","; END IF IF pointer = 0 THEN arg$ = MKL$(typ) END IF IF pointer = 1 THEN 'all pointers convert to BYVAL _OFFSET arg$ = MKL$(OFFSETTYPE - ISPOINTER) ctyp$ = "ptrszint" END IF IF pointer = 2 THEN 'all pointers-to-pointers convert to xxx"BYREF"xxx BYVAL _OFFSET arg$ = MKL$(OFFSETTYPE - ISPOINTER) ctyp$ = "ptrszint" '***this is important or you lose the ability to specify any offset, only the offset of a variable of type ' _OFFSET ' arg$ = MKL$(OFFSETTYPE) ' ctyp$ = "ptrszint*" END IF GL_COMMANDS(c).args = GL_COMMANDS(c).args + 1 MID$(GL_COMMANDS(c).arg, (GL_COMMANDS(c).args - 1) * 4 + 1, 4) = arg$ 'z$ = GL_COMMANDS(c).arg 'MID$(z$, (GL_COMMANDS(c).args - 1) * 4 + 1, 4) = arg$ 'GL_COMMANDS(c).arg = z$ letter$ = CHR$(96 + GL_COMMANDS(c).args) hc$ = hc$ + "(" + var_type_backup$ + ")" + letter$ hd$ = hd$ + ctyp$ + " " + letter$ IF l$ <> ")" THEN hc$ = hc$ + ",": hd$ = hd$ + "," LOOP UNTIL l$ = ")" no_arguments: hd$ = hd$ + "){" hc$ = hc$ + ");" IF GL_KIT THEN PRINT #hk, ")" h$ = hd$ + crlf + "if (!sub_gl_called) error(270);" + crlf + hc$ + crlf + "}" + crlf IF need_helper_function THEN 'do we need the helper function for this command? GL_HELPER_CODE = GL_HELPER_CODE + h$ GL_COMMANDS(c).callname = "call_" + proc_name$ END IF IF proc_name$ = "glGetString" THEN GL_COMMANDS(c).ret = STRINGTYPE GL_COMMANDS(c).callname = "( char* )" + RTRIM$(GL_COMMANDS(c).callname) END IF END IF END IF discard: LOOP CLOSE #h IF GL_KIT THEN PRINT #hk, "END DECLARE" GL_DEFINES_LAST = d REDIM _PRESERVE GL_DEFINES(d) AS STRING 'PRINT "Defines:"; GL_DEFINES_LAST REDIM _PRESERVE GL_COMMANDS(GL_COMMANDS_LAST) AS GL_idstruct 'PRINT "Commands:"; GL_COMMANDS_LAST IF GL_KIT THEN FOR i = 1 TO GL_DEFINES_LAST PRINT #hk, "CONST " + GL_DEFINES(i) + "="; GL_DEFINES_VALUE(i) NEXT END IF 'FOR i = 1 TO GL_COMMANDS_LAST ' PRINT ".cn="; GL_COMMANDS(i).cn ' PRINT ".callname="; GL_COMMANDS(i).callname ' PRINT ".subfunc="; GL_COMMANDS(i).subfunc ' PRINT ".args="; GL_COMMANDS(i).args ' _CONTROLCHR OFF ' PRINT ".arg=[" + RTRIM$(GL_COMMANDS(i).arg) + "]" ' _CONTROLCHR ON ' PRINT ".ret="; GL_COMMANDS(i).ret 'NEXT IF GL_KIT THEN CLOSE #hk fh = FREEFILE OPEN "internal\c\parts\core\gl_header_for_parsing\temp\gl_helper_code.h" FOR OUTPUT AS #fh PRINT #fh, GL_HELPER_CODE CLOSE #fh END SUB '----------------ripgl.bas-------------------------------------------------------------------------------- SUB gl_include_content 'add constants FOR d = 1 TO GL_DEFINES_LAST IF ASC(GL_DEFINES(d)) <> 95 THEN GL_DEFINES(d) = "_" + GL_DEFINES(d) END IF 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 i = constlast constname(i) = GL_DEFINES(d) constcname(i) = GL_DEFINES(d) constnamesymbol(i) = "&&" consttype(i) = INTEGER64TYPE - ISPOINTER constinteger(i) = GL_DEFINES_VALUE(d) constsubfunc(i) = 0 'global constdefined(i) = 1 'add to hash table HashAdd constcname(i), HASHFLAG_CONSTANT, i NEXT 'add subs/functions FOR c = 1 TO GL_COMMANDS_LAST DIM g AS GL_idstruct ' TYPE GL_idstruct ' cn AS STRING * 64 'case sensitive version of n ' subfunc AS INTEGER 'if function=1, sub=2 ' callname AS STRING * 64 ' args AS INTEGER ' arg AS STRING * 80 'similar to t ' ret AS LONG 'the value it returns if it is a function (again like t) ' END TYPE g = GL_COMMANDS(c) reginternalsubfunc = 1 clearid id.ccall = 1 '*** important for handling string returns correctly *** id.n = RTRIM$(g.cn) s = g.subfunc id.subfunc = s id.callname = RTRIM$(g.callname) id.args = g.args id.arg = g.arg id.ret = g.ret regid reginternalsubfunc = 0 NEXT 'add inline function definitions 'SUB gluPerspective (BYVAL fovy#, BYVAL aspect#, BYVAL zNear#, BYVAL zFar#) reginternalsubfunc = 1 clearid id.n = "_gluPerspective" id.subfunc = 2 'sub id.callname = "gluPerspective" id.args = 4 id.arg = MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) + MKL$(DOUBLETYPE - ISPOINTER) regid reginternalsubfunc = 0 END SUB SUB UseAndroid (Yes) STATIC inline_DATA_backup STATIC inline_DATA_backup_set IF inline_DATA_backup_set = 0 THEN inline_DATA_backup_set = 1 inline_DATA_backup = inline_DATA END IF IF Yes THEN IF MakeAndroid = 0 THEN MakeAndroid = 1 inline_DATA = 1 idechangemade = 1 IDEBuildModeChanged = 1 END IF ELSE IF MakeAndroid THEN MakeAndroid = 0 inline_DATA = inline_DATA_backup idechangemade = 1 IDEBuildModeChanged = 1 END IF END IF END SUB 'Steve Subs/Functins for _MATH support with CONST FUNCTION Evaluate_Expression$ (e$) t$ = e$ 'So we preserve our original data, we parse a temp copy of it b = INSTR(UCASE$(e$), "EQL") 'take out assignment before the preparser sees it IF b THEN t$ = MID$(e$, b + 3): var$ = UCASE$(LTRIM$(RTRIM$(MID$(e$, 1, b - 1)))) QuickReturn = 0 PreParse t$ IF QuickReturn THEN Evaluate_Expression$ = t$: EXIT FUNCTION IF LEFT$(t$, 5) = "ERROR" THEN Evaluate_Expression$ = t$: EXIT FUNCTION 'Deal with brackets first exp$ = "(" + t$ + ")" 'Starting and finishing brackets for our parse routine. DO Eval_E = INSTR(exp$, ")") IF Eval_E > 0 THEN c = 0 DO UNTIL Eval_E - c <= 0 c = c + 1 IF Eval_E THEN IF MID$(exp$, Eval_E - c, 1) = "(" THEN EXIT DO END IF LOOP s = Eval_E - c + 1 IF s < 1 THEN PRINT "ERROR -- BAD () Count": END eval$ = " " + MID$(exp$, s, Eval_E - s) + " " 'pad with a space before and after so the parser can pick up the values properly. ParseExpression eval$ eval$ = LTRIM$(RTRIM$(eval$)) IF LEFT$(eval$, 5) = "ERROR" THEN Evaluate_Expression$ = eval$: EXIT SUB exp$ = DWD(LEFT$(exp$, s - 2) + eval$ + MID$(exp$, Eval_E + 1)) temppp$ = DWD(LEFT$(exp$, s - 2) + " ## " + eval$ + " ## " + MID$(exp$, E + 1)) END IF LOOP UNTIL Eval_E = 0 c = 0 DO c = c + 1 SELECT CASE MID$(exp$, c, 1) CASE "0" TO "9", ".", "-" 'At this point, we should only have number values left. CASE ELSE: exp$ = "ERROR - Unknown Diagnosis: (" + exp$ + ") " END SELECT LOOP UNTIL c >= LEN(exp$) 'Post Parsing work, if we are required to set a variable IF var$ <> "" THEN 'we can't possibly have more than 2 characters (letter + optional "&") SELECT CASE LEN(var$) CASE 1: v$ = var$ CASE 2: IF RIGHT$(var$, 1) = "#" THEN v$ = LEFT$(var$, 1) ELSE Evaluate_Expression$ = "ERROR - Bad User Variable Value. (" + var$ + ")": EXIT SUB CASE ELSE: Evaluate_Expression$ = "ERROR - Bad User Variable Value. (" + var$ + ")": EXIT SUB END SELECT index = ASC(v$) - 64 IF index < 1 OR index > 26 THEN Evaluate_Expression$ = "ERROR - Letter required for variable name": EXIT SUB vars(index) = exp$ END IF f = FREEFILE OPEN FileName FOR BINARY AS #f counter = 0 FOR c = 0 TO 26 'variables length& = LEN(vars(c)) PUT #f, , length& PUT #f, , vars(c) NEXT c CLOSE #f vars(0) = exp$ 'the "previous result" (think the ANS button on your calculator) Evaluate_Expression$ = exp$ END FUNCTION SUB ParseExpression (exp$) DIM num(10) AS STRING 'We should now have an expression with no () to deal with FOR J = 1 TO 250 lowest = 0 DO UNTIL lowest = LEN(exp$) lowest = LEN(exp$): OpOn = 0 FOR P = 1 TO UBOUND(OName) 'Look for first valid operator IF J = PL(P) THEN 'Priority levels match IF LEFT$(exp$, 1) = "-" THEN op = INSTR(2, exp$, OName(P)) ELSE op = INSTR(exp$, OName(P)) IF op > 0 AND op < lowest THEN lowest = op: OpOn = P END IF NEXT IF OpOn = 0 THEN EXIT DO 'We haven't gotten to the proper PL for this OP to be processed yet. IF LEFT$(exp$, 1) = "-" THEN op = INSTR(2, exp$, OName(OpOn)) ELSE op = INSTR(exp$, OName(OpOn)) numset = 0 '*** SPECIAL OPERATION RULESETS IF OName(OpOn) = "-" THEN 'check for BOOLEAN operators before the - SELECT CASE MID$(exp$, op - 3, 3) CASE "NOT", "XOR", "AND", "EQV", "IMP" EXIT DO 'Not an operator, it's a negative END SELECT IF MID$(exp$, op - 3, 2) = "OR" THEN EXIT DO 'Not an operator, it's a negative END IF IF op THEN c = LEN(OName(OpOn)) - 1 DO SELECT CASE MID$(exp$, op + c + 1, 1) CASE "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ".": numset = -1 'Valid digit CASE "-" 'We need to check if it's a minus or a negative IF OName(OpOn) = "PI" OR numset THEN EXIT DO CASE ELSE 'Not a valid digit, we found our separator EXIT DO END SELECT c = c + 1 LOOP UNTIL op + c >= LEN(exp$) E = op + c c = 0 DO c = c + 1 SELECT CASE MID$(exp$, op - c, 1) CASE "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "." 'Valid digit CASE "-" 'We need to check if it's a minus or a negative c1 = c bad = 0 DO c1 = c1 + 1 SELECT CASE MID$(exp$, op - c1, 1) CASE "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "." bad = -1 EXIT DO 'It's a minus sign CASE ELSE 'It's a negative sign and needs to count as part of our numbers END SELECT LOOP UNTIL op - c1 <= 0 IF bad THEN EXIT DO 'We found our seperator CASE ELSE 'Not a valid digit, we found our separator EXIT DO END SELECT LOOP UNTIL op - c <= 0 s = op - c num(1) = MID$(exp$, s + 1, op - s - 1) 'Get our first number num(2) = MID$(exp$, op + LEN(OName(OpOn)), E - op - LEN(OName(OpOn)) + 1) 'Get our second number num(3) = EvaluateNumbers(OpOn, num()) 'PRINT "*************" 'PRINT num(1), OName(OpOn), num(2), num(3), exp$ IF LEFT$(num(3), 5) = "ERROR" THEN exp$ = num(3): EXIT SUB exp$ = LTRIM$(N2S(DWD(LEFT$(exp$, s) + RTRIM$(LTRIM$(num(3))) + MID$(exp$, E + 1)))) 'PRINT exp$ END IF op = 0 LOOP NEXT END SUB SUB Set_OrderOfOperations 'PL sets our priortity level. 1 is highest to 65535 for the lowest. 'I used a range here so I could add in new priority levels as needed. 'OName ended up becoming the name of our commands, as I modified things.... Go figure! LOL! IF _DIREXISTS("internal") THEN 'Good, we're being run from within the QB64 folder as intended ELSE MKDIR "internal" 'Make us an internal folder so we don't generate errors. END IF IF _DIREXISTS("internal/MathEval") THEN 'Good, we're have the proper subfolder as well ELSE MKDIR "internal/MathEval" 'Make us an internal folder so we don't generate errors. END IF 'Constants get evaluated first, with a Priority Level of 1 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ANS" 'the result of the previous calculation REDIM _PRESERVE PL(i): PL(i) = 1 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "PI" REDIM _PRESERVE PL(i): PL(i) = 1 'I'm not certain where exactly percentages should go. They kind of seem like a special case to me. COS10% should be COS.1 I'd think... 'I'm putting it here for now, and if anyone knows someplace better for it in our order of operations, let me know. i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "%" REDIM _PRESERVE PL(i): PL(i) = 5 'Then Functions with PL 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCCOS" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCSIN" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCSEC" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCCSC" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ARCCOT" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SECH" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "CSCH" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COTH" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COS" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SIN" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "TAN" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "LOG" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "EXP" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ATN" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "D2R" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "D2G" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "R2D" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "R2G" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "G2D" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "G2R" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ABS" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SGN" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "INT" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "_ROUND" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "FIX" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SEC" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "CSC" REDIM _PRESERVE PL(i): PL(i) = 10 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COT" REDIM _PRESERVE PL(i): PL(i) = 10 'Exponents with PL 20 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "^" REDIM _PRESERVE PL(i): PL(i) = 20 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "SQR" REDIM _PRESERVE PL(i): PL(i) = 20 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "ROOT" REDIM _PRESERVE PL(i): PL(i) = 20 'Multiplication and Division PL 30 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "*" REDIM _PRESERVE PL(i): PL(i) = 30 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "/" REDIM _PRESERVE PL(i): PL(i) = 30 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "BTM" REDIM _PRESERVE PL(i): PL(i) = 30 'Integer Division PL 40 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "\" REDIM _PRESERVE PL(i): PL(i) = 40 'MOD PL 50 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "MOD" REDIM _PRESERVE PL(i): PL(i) = 50 'Addition and Subtraction PL 60 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "+" REDIM _PRESERVE PL(i): PL(i) = 60 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "-" REDIM _PRESERVE PL(i): PL(i) = 60 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "BTA" REDIM _PRESERVE PL(i): PL(i) = 60 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "BTS" REDIM _PRESERVE PL(i): PL(i) = 60 'Relational Operators =, >, <, <>, <=, >= PL 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<>" REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "><" 'These next three are just reversed symbols as an attempt to help process a common typo REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<=" REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = ">=" REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "=<" 'I personally can never keep these things straight. Is it < = or = <... REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "=>" 'Who knows, check both! REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = ">" REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "<" REDIM _PRESERVE PL(i): PL(i) = 70 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "=" REDIM _PRESERVE PL(i): PL(i) = 70 'Logical Operations PL 80+ i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "NOT" REDIM _PRESERVE PL(i): PL(i) = 80 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "AND" REDIM _PRESERVE PL(i): PL(i) = 90 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "OR" REDIM _PRESERVE PL(i): PL(i) = 100 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "XOR" REDIM _PRESERVE PL(i): PL(i) = 110 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "EQV" REDIM _PRESERVE PL(i): PL(i) = 120 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "IMP" REDIM _PRESERVE PL(i): PL(i) = 130 f = FREEFILE FOR c = ASC("A") TO ASC("Z") 'variables i = i + 1: REDIM _PRESERVE OName(i): OName(i) = CHR$(c) + "#" REDIM _PRESERVE PL(i): PL(i) = 1 NEXT c FOR c = ASC("A") TO ASC("Z") 'strings i = i + 1: REDIM _PRESERVE OName(i): OName(i) = CHR$(c) + "!" REDIM _PRESERVE PL(i): PL(i) = 1000 NEXT c OPEN FileName FOR BINARY AS #f counter = 0 FOR c = 0 TO 26 'variables GET #f, , length& t$ = SPC(length&) GET #f, , t$ vars(c) = t$ NEXT c CLOSE #f 'SPECIAL STRING Operators have PL 1000. They shouldn't mix with lower value commands, as we handle them separate i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "DATE$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "TIME$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "COMMAND$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "WIKI" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "QB64" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "FORUMS" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "WEBCHAT" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "D2R$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "D2G$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "R2D$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "R2G$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "G2R$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "G2D$" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "RUN:" REDIM _PRESERVE PL(i): PL(i) = 1000 i = i + 1: REDIM _PRESERVE OName(i): OName(i) = "RETURN" REDIM _PRESERVE PL(i): PL(i) = 1000 END SUB FUNCTION EvaluateNumbers$ (p, num() AS STRING) DIM n1 AS _FLOAT, n2 AS _FLOAT, n3 AS _FLOAT SELECT CASE OName(p) 'Depending on our operator.. CASE "PI" n1 = 3.14159265358979323846264338327950288## 'Future compatable in case something ever stores extra digits for PI CASE "%" 'Note percent is a special case and works with the number BEFORE the % command and not after IF num(1) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get percent of NULL string": EXIT FUNCTION n1 = (VAL(num(1))) / 100 CASE "ARCCOS" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOS of NULL string": EXIT FUNCTION n1 = VAL(num(2)) IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOS from value >1, which is Invalid": EXIT FUNCTION IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOS from value <-1, which is Invalid": EXIT FUNCTION IF n1 = 1 THEN EvaluateNumbers$ = "0": EXIT FUNCTION n1 = (2 * ATN(1)) - ATN(n1 / SQR(1 - n1 * n1)) CASE "ARCSIN" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSIN of NULL string": EXIT FUNCTION n1 = VAL(num(2)) IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSIN from value >1, which is Invalid": EXIT FUNCTION IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSIN from value <-1, which is Invalid": EXIT FUNCTION n1 = ATN(n1 / SQR(1 - (n1 * n1))) CASE "ARCSEC" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSEC of NULL string": EXIT FUNCTION n1 = VAL(num(2)) IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSEC from value > 1, which is Invalid": EXIT FUNCTION IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCSEC from value < -1, which is Invalid": EXIT FUNCTION n1 = ATN(n1 / SQR(1 - n1 * n1)) + (SGN(n1) - 1) * (2 * ATN(1)) CASE "ARCCSC" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCSC of NULL string": EXIT FUNCTION n1 = VAL(num(2)) IF n1 > 1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCSC from value >=1, which is Invalid": EXIT FUNCTION IF n1 < -1 THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCSC from value <-1, which is Invalid": EXIT FUNCTION n1 = ATN(1 / SQR(1 - n1 * n1)) + (SGN(n1) - 1) * (2 * ATN(1)) CASE "ARCCOT" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ARCCOT of NULL string": EXIT FUNCTION n1 = VAL(num(2)) n1 = (2 * ATN(1)) - ATN(n1) CASE "SECH" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SECH of NULL string": EXIT FUNCTION n1 = VAL(num(2)) IF n1 > 88.02969 OR (EXP(n1) + EXP(-n1)) = 0 THEN EvaluateNumbers$ = "ERROR - Bad SECH command": EXIT FUNCTION n1 = 2 / (EXP(n1) + EXP(-n1)) CASE "CSCH" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get CSCH of NULL string": EXIT FUNCTION n1 = VAL(num(2)) IF n1 > 88.02969 OR (EXP(n1) - EXP(-n1)) = 0 THEN EvaluateNumbers$ = "ERROR - Bad CSCH command": EXIT FUNCTION n1 = 2 / (EXP(n1) - EXP(-n1)) CASE "COTH" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get COTH of NULL string": EXIT FUNCTION n1 = VAL(num(2)) IF 2 * n1 > 88.02969 OR EXP(2 * n1) - 1 = 0 THEN EvaluateNumbers$ = "ERROR - Bad COTH command": EXIT FUNCTION n1 = (EXP(2 * n1) + 1) / (EXP(2 * n1) - 1) CASE "COS" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get COS of NULL string": EXIT FUNCTION n1 = COS(VAL(num(2))) CASE "SIN" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SIN of NULL string": EXIT FUNCTION n1 = SIN(VAL(num(2))) CASE "TAN" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get TAN of NULL string": EXIT FUNCTION n1 = TAN(VAL(num(2))) CASE "LOG" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get LOG of NULL string": EXIT FUNCTION n1 = LOG(VAL(num(2))) CASE "EXP" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get EXP of NULL string": EXIT FUNCTION n1 = EXP(VAL(num(2))) CASE "ATN" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ATN of NULL string": EXIT FUNCTION n1 = ATN(VAL(num(2))) CASE "D2R" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Radian of NULL Degree value": EXIT FUNCTION n1 = 0.0174532925 * (VAL(num(2))) CASE "D2G" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Grad of NULL Degree string": EXIT FUNCTION n1 = 1.1111111111 * (VAL(num(2))) CASE "R2D" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Degree of NULL Radian string": EXIT FUNCTION n1 = 57.2957795 * (VAL(num(2))) CASE "R2G" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Grad of NULL Radian string": EXIT FUNCTION n1 = 0.015707963 * (VAL(num(2))) CASE "G2D" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Degree of NULL Gradian string": EXIT FUNCTION n1 = 0.9 * (VAL(num(2))) CASE "G2R" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get Radian of NULL Grad string": EXIT FUNCTION n1 = 63.661977237 * (VAL(num(2))) CASE "ABS" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ABS of NULL string": EXIT FUNCTION n1 = ABS(VAL(num(2))) CASE "SGN" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SGN of NULL string": EXIT FUNCTION n1 = SGN(VAL(num(2))) CASE "INT" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get INT of NULL string": EXIT FUNCTION n1 = INT(VAL(num(2))) CASE "_ROUND" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to _ROUND a NULL string": EXIT FUNCTION n1 = _ROUND(VAL(num(2))) CASE "FIX" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to FIX a NULL string": EXIT FUNCTION n1 = FIX(VAL(num(2))) CASE "SEC" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SEC of NULL string": EXIT FUNCTION n1 = COS(VAL(num(2))) IF n1 = 0 THEN EvaluateNumbers$ = "ERROR - COS value is 0, thus SEC is 1/0 which is Invalid": EXIT FUNCTION n1 = 1 / n1 CASE "CSC" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get CSC of NULL string": EXIT FUNCTION n1 = SIN(VAL(num(2))) IF n1 = 0 THEN EvaluateNumbers$ = "ERROR - SIN value is 0, thus CSC is 1/0 which is Invalid": EXIT FUNCTION n1 = 1 / n1 CASE "COT" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get COT of NULL string": EXIT FUNCTION n1 = COS(VAL(num(2))) IF n1 = 0 THEN EvaluateNumbers$ = "ERROR - TAN value is 0, thus COT is 1/0 which is Invalid": EXIT FUNCTION n1 = 1 / n1 CASE "BTA" IF num(2) = "" OR num(1) = "" THEN EvaluateNumbers$ = "ERROR - BTA": EXIT FUNCTION EvaluateNumbers$ = BTen$(num(1), "+", num(2)): EXIT FUNCTION CASE "BTS" IF num(2) = "" OR num(1) = "" THEN EvaluateNumbers$ = "ERROR - BTS": EXIT FUNCTION EvaluateNumbers$ = BTen$(num(1), "-", num(2)): EXIT FUNCTION CASE "BTM" IF num(2) = "" OR num(1) = "" THEN EvaluateNumbers$ = "ERROR - BTM": EXIT FUNCTION EvaluateNumbers$ = BTen$(num(1), "*", num(2)): EXIT FUNCTION CASE "^" IF num(1) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to raise NULL string to exponent": EXIT FUNCTION IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to raise number to NULL exponent": EXIT FUNCTION n1 = VAL(num(1)) ^ VAL(num(2)) CASE "SQR" IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get SQR of NULL string": EXIT FUNCTION IF VAL(num(2)) < 0 THEN EvaluateNumbers$ = "ERROR - Cannot take take SQR of numbers < 0. I'm a computer, I have a poor imagination.": EXIT FUNCTION n1 = SQR(VAL(num(2))) CASE "ROOT" IF num(1) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get ROOT of a NULL string": EXIT FUNCTION IF num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to get NULL ROOT of a string": EXIT FUNCTION n1 = VAL(num(1)): n2 = VAL(num(2)) IF n2 = 1 THEN EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))): EXIT FUNCTION IF n2 = 0 THEN EvaluateNumbers$ = "ERROR - There is no such thing as a 0 ROOT of a number": EXIT FUNCTION IF n1 < 0 AND n2 MOD 2 = 0 AND n2 > 1 THEN EvaluateNumbers$ = "ERROR - Cannot take take an EVEN ROOT of numbers < 0. I'm a computer, I have a poor imagination.": EXIT FUNCTION IF n1 < 0 AND n2 >= 1 THEN sign = -1: n1 = -n1 ELSE sign = 1 n3 = 1## / n2 IF n3 <> INT(n3) AND n2 < 1 THEN sign = SGN(n1): n1 = ABS(n1) n1 = sign * (n1 ^ n3) CASE "*" IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to multiply NULL string ": EXIT FUNCTION n1 = VAL(num(1)) * VAL(num(2)) CASE "/": IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to divide NULL string ": EXIT FUNCTION IF VAL(num(2)) = 0 THEN EvaluateNumbers$ = "ERROR - Division by 0": EXIT FUNCTION n1 = VAL(num(1)) / VAL(num(2)) CASE "\" IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to divide NULL string ": EXIT FUNCTION IF VAL(num(2)) = 0 THEN EvaluateNumbers$ = "ERROR - Division by 0": EXIT FUNCTION n1 = VAL(num(1)) \ VAL(num(2)) CASE "MOD" IF num(1) = "" OR num(2) = "" THEN EvaluateNumbers$ = "ERROR - Attemping to MOD with NULL string ": EXIT FUNCTION IF VAL(num(2)) = 0 THEN EvaluateNumbers$ = "ERROR - Division by 0": EXIT FUNCTION n1 = VAL(num(1)) MOD VAL(num(2)) CASE "+": n1 = VAL(num(1)) + VAL(num(2)) CASE "-": n1 = VAL(num(1)) - VAL(num(2)) CASE "=": n1 = VAL(num(1)) = VAL(num(2)) CASE ">": n1 = VAL(num(1)) > VAL(num(2)) CASE "<": n1 = VAL(num(1)) < VAL(num(2)) CASE "<>", "><": n1 = VAL(num(1)) <> VAL(num(2)) CASE "<=", "=<": n1 = VAL(num(1)) <= VAL(num(2)) CASE ">=", "=>": n1 = VAL(num(1)) >= VAL(num(2)) CASE "NOT": n1 = NOT VAL(num(2)) CASE "AND": n1 = VAL(num(1)) AND VAL(num(2)) CASE "OR": n1 = VAL(num(1)) OR VAL(num(2)) CASE "XOR": n1 = VAL(num(1)) XOR VAL(num(2)) CASE "EQV": n1 = VAL(num(1)) EQV VAL(num(2)) CASE "IMP": n1 = VAL(num(1)) IMP VAL(num(2)) CASE "ANS": n1 = VAL(vars(0)) CASE ELSE EvaluateNumbers$ = "ERROR - Bad operation (We shouldn't see this)" 'Let's say we're bad... FOR c = ASC("A") TO ASC("Z") 'Unless we evaluate to be a user set variable. IF OName(p) = CHR$(c) + "#" THEN EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(VAL(vars(c - 64))))): EXIT FUNCTION NEXT END SELECT EvaluateNumbers$ = RTRIM$(LTRIM$(STR$(n1))) END FUNCTION FUNCTION DWD$ (exp$) 'Deal With Duplicates 'To deal with duplicate operators in our code. 'Such as -- becomes a + '++ becomes a + '+- becomes a - '-+ becomes a - t$ = exp$ DO bad = 0 DO l = INSTR(t$, "++") IF l THEN t$ = LEFT$(t$, l - 1) + "+" + MID$(t$, l + 2): bad = -1 LOOP UNTIL l = 0 DO l = INSTR(t$, "+-") IF l THEN t$ = LEFT$(t$, l - 1) + "-" + MID$(t$, l + 2): bad = -1 LOOP UNTIL l = 0 DO l = INSTR(t$, "-+") IF l THEN t$ = LEFT$(t$, l - 1) + "-" + MID$(t$, l + 2): bad = -1 LOOP UNTIL l = 0 DO l = INSTR(t$, "--") IF l THEN t$ = LEFT$(t$, l - 1) + "+" + MID$(t$, l + 2): bad = -1 LOOP UNTIL l = 0 LOOP UNTIL NOT bad DWD$ = t$ VerifyString t$ END FUNCTION SUB PreParse (e$) DIM f AS _FLOAT t$ = e$ 'Check for High/Low Flag operations j = 1: highflag = 0: lowflag = 0 DO comp$ = UCASE$(MID$(t$, j, 1)) SELECT CASE comp$ CASE "0" TO "9", ".", "(", ")": j = j + 1 CASE ELSE good = 0 FOR i = 1 TO UBOUND(OName) IF UCASE$(MID$(t$, j, LEN(OName(i)))) = OName(i) AND PL(i) > 250 THEN highflag = -1 NEXT IF i <= UBOUND(Oname) THEN j = j + LEN(OName(i)) ELSE j = j + 1 END SELECT LOOP UNTIL j > LEN(t$) IF highflag THEN ParseString t$ IF QuickReturn THEN e$ = t$: EXIT SUB 'First strip all spaces t$ = "" FOR i = 1 TO LEN(e$) IF MID$(e$, i, 1) <> " " THEN t$ = t$ + MID$(e$, i, 1) NEXT t$ = UCASE$(t$) IF t$ = "" THEN e$ = "ERROR -- NULL string; nothing to evaluate" 'ERROR CHECK by counting our brackets l = 0 DO l = INSTR(l + 1, t$, "("): IF l THEN c = c + 1 LOOP UNTIL l = 0 l = 0 DO l = INSTR(l + 1, t$, ")"): IF l THEN c1 = c1 + 1 LOOP UNTIL l = 0 IF c <> c1 THEN e$ = "ERROR -- Bad Parenthesis:" + STR$(c) + "( vs" + STR$(c1) + ")": EXIT SUB 'Modify so that NOT will process properly l = 0 DO l = INSTR(l + 1, t$, "NOT") IF l THEN 'We need to work magic on the statement so it looks pretty. ' 1 + NOT 2 + 1 is actually processed as 1 + (NOT 2 + 1) 'Look for something not proper l1 = INSTR(l + 1, t$, "AND") IF l1 = 0 OR (INSTR(l + 1, t$, "OR") > 0 AND INSTR(l + 1, t$, "OR") < l1) THEN l1 = INSTR(l + 1, t$, "OR") IF l1 = 0 OR (INSTR(l + 1, t$, "XOR") > 0 AND INSTR(l + 1, t$, "XOR") < l1) THEN l1 = INSTR(l + 1, t$, "XOR") IF l1 = 0 OR (INSTR(l + 1, t$, "EQV") > 0 AND INSTR(l + 1, t$, "EQV") < l1) THEN l1 = INSTR(l + 1, t$, "EQV") IF l1 = 0 OR (INSTR(l + 1, t$, "IMP") > 0 AND INSTR(l + 1, t$, "IMP") < l1) THEN l1 = INSTR(l + 1, t$, "IMP") IF l1 = 0 THEN l1 = LEN(t$) + 1 t$ = LEFT$(t$, l - 1) + "(" + MID$(t$, l, l1 - l) + ")" + MID$(t$, l + l1 - l) l = l + 3 'PRINT t$ END IF LOOP UNTIL l = 0 'Check for bad operators before a ( bracket l = 0 DO l = INSTR(l + 1, t$, "(") IF l AND l > 2 THEN 'Don't check the starting bracket; there's nothing before it. good = 0 FOR i = 1 TO UBOUND(OName) IF MID$(t$, l - LEN(OName(i)), LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN e$ = "ERROR - Improper operations before (.": EXIT SUB l = l + 1 END IF LOOP UNTIL l = 0 'Check for bad operators after a ) bracket l = 0 DO l = INSTR(l + 1, t$, ")") IF l AND l < LEN(t$) THEN good = 0 FOR i = 1 TO UBOUND(OName) IF MID$(t$, l + 1, LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN e$ = "ERROR - Improper operations after ).": EXIT SUB l = l + 1 END IF LOOP UNTIL l = 0 OR l = LEN(t$) 'last symbol is a bracket 'Turn all &H (hex) numbers into decimal values for the program to process properly l = 0 DO l = INSTR(t$, "&H") IF l THEN E = l + 1: finished = 0 DO E = E + 1 comp$ = MID$(t$, E, 1) SELECT CASE comp$ CASE "0" TO "9", "A" TO "F" 'All is good, our next digit is a number, continue to add to the hex$ CASE ELSE good = 0 FOR i = 1 TO UBOUND(OName) IF MID$(t$, E, LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN e$ = "ERROR - Improper &H value. (" + comp$ + ")": EXIT SUB E = E - 1 finished = -1 END SELECT LOOP UNTIL finished OR E = LEN(t$) t$ = LEFT$(t$, l - 1) + LTRIM$(RTRIM$(STR$(VAL(MID$(t$, l, E - l + 1))))) + MID$(t$, E + 1) END IF LOOP UNTIL l = 0 'Turn all &B (binary) numbers into decimal values for the program to process properly l = 0 DO l = INSTR(t$, "&B") IF l THEN E = l + 1: finished = 0 DO E = E + 1 comp$ = MID$(t$, E, 1) SELECT CASE comp$ CASE "0", "1" 'All is good, our next digit is a number, continue to add to the hex$ CASE ELSE good = 0 FOR i = 1 TO UBOUND(OName) IF MID$(t$, E, LEN(OName(i))) = OName(i) AND PL(i) > 1 AND PL(i) <= 250 THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN e$ = "ERROR - Improper &B value. (" + comp$ + ")": EXIT SUB E = E - 1 finished = -1 END SELECT LOOP UNTIL finished OR E = LEN(t$) bin$ = MID$(t$, l + 2, E - l - 1) FOR i = 1 TO LEN(bin$) IF MID$(bin$, i, 1) = "1" THEN f = f + 2 ^ (LEN(bin$) - i) NEXT t$ = LEFT$(t$, l - 1) + LTRIM$(RTRIM$(STR$(f))) + MID$(t$, E + 1) END IF LOOP UNTIL l = 0 t$ = N2S(t$) VerifyString t$ e$ = t$ END SUB SUB ParseString (e$) t$ = e$ 'Since these are string swaps going on, we don't plug them into a nice little working formula as we did before. 'Instead, we write a separate routine for each method and evaluate on a command by command basis. 'RUN -- Special "Do Anything" type command IF UCASE$(LEFT$(t$, 4)) = "RUN:" THEN 'Look for RETURN: l = INSTR(UCASE$(t$), "RETURN") IF l = 0 THEN e$ = "ERROR -- No RETURN after RUN": QuickReturn = -1: EXIT SUB tempfile$ = "MathProcess" + DATE$ f = FREEFILE OPEN tempfile$ + ".txt" FOR OUTPUT AS #f PRINT #f, MID$(t$, 5, l - 5) PRINT #f, "OPEN " + CHR$(34) + tempfile$ + ".txt" + CHR$(34) + " FOR OUTPUT AS #1" PRINT #f, "PRINT #1, " + MID$(t$, l + 7) PRINT #f, "CLOSE" PRINT #f, "SYSTEM " CLOSE #f SHELL _HIDE "QB64.exe -c " + tempfile$ + ".txt" SHELL _HIDE tempfile$ + ".exe" OPEN tempfile$ + ".txt" FOR INPUT AS #f LINE INPUT #f, e$ CLOSE #f IF _FILEEXISTS(tempfile$ + ".txt") THEN KILL tempfile$ + ".txt" IF _FILEEXISTS(tempfile$ + ".exe") THEN KILL tempfile$ + ".exe" QuickReturn = -1: EXIT SUB END IF QUI = 0 'Quick User Insert FOR c = ASC("A") TO ASC("Z") 'Unless we evaluate to be a user set variable. IF INSTR(UCASE$(t$), CHR$(c) + "!") THEN f = FREEFILE IF _FILEEXISTS(DirName + CHR$(c) + "!.txt") THEN QUI = -1 OPEN DirName + CHR$(c) + "!.txt" FOR INPUT AS #f t$ = "" count = 0 DO UNTIL EOF(f) count = count + 1 LINE INPUT #f, t1$ t2$ = t2$ + t1$ + CHR$(13) LOOP CLOSE #f ELSE e$ = "ERROR --" + DirName + CHR$(c) + "!.txt is not a valid quickload file.": QuickReturn = -1: EXIT SUB END IF END IF NEXT IF QUI THEN SELECT CASE count CASE 0 e$ = "ERROR --" + DirName + CHR$(c) + "!.txt is a blank quickload file.": QuickReturn = -1: EXIT SUB CASE 1 'l = idecy 'a$ = idegetline(l) 'l$ = LEFT$(a$, idecx - 1): r$ = RIGHT$(a$, LEN(a$) - idecx + 1) 'text$ = l$ + t1$ + r$ 'textlen = LEN(text$) 'l$ = LEFT$(idet$, ideli - 1) 'm$ = MKL$(textlen) + text$ + MKL$(textlen) 'r$ = RIGHT$(idet$, LEN(idet$) - ideli - LEN(a$) - 7) 'idet$ = l$ + m$ + r$ 'idecx = idecx + LEN(t1$) e$ = t1$: QuickReturn = -1: EXIT SUB CASE ELSE a$ = t2$ x3 = 1 'scan from position i = 0 'lines counter DO x = INSTR(x3, a$, CHR$(13)) x2 = INSTR(x3, a$, CHR$(10)) IF x = 0 THEN x = x2 IF x2 = 0 THEN x2 = x IF x2 < x THEN SWAP x, x2 IF x2 > x + 1 THEN x2 = x 'if seperated by more than one character, they are seperate line terminators 'x to x2 is the range of the next line terminator (1 or 2 characters) IF x THEN ideinsline idecy + i, converttabs$(MID$(a$, x3, x - x3)) i = i + 1 x3 = x2 + 1 ELSE ideinsline idecy + i, converttabs$(MID$(a$, x3, LEN(a$) - x3 + 1)) i = i + 1 x3 = LEN(a$) + 1 END IF LOOP UNTIL x3 > LEN(a$) e$ = STR$(count) + " LINES INSERTED": QuickReturn = -1: EXIT SUB END SELECT END IF 'DATE$ l = 0 DO l = INSTR(UCASE$(t$), "DATE$") IF l THEN t$ = LEFT$(t$, l - 1) + DATE$ + MID$(t$, l + 5) END IF LOOP UNTIL l = 0 'TIME$ l = 0 DO l = INSTR(UCASE$(t$), "TIME$") IF l THEN t$ = LEFT$(t$, l - 1) + TIME$ + MID$(t$, l + 5) END IF LOOP UNTIL l = 0 'Commands that we should only process once and then be done with them. IF INSTR(UCASE$(t$), "WIKI") THEN SHELL _HIDE "http://qb64.net/wiki/index.php?title=Main_Page" IF INSTR(UCASE$(t$), "QB64") THEN SHELL _HIDE "http://www.qb64.net/" IF INSTR(UCASE$(t$), "FORUMS") THEN SHELL _HIDE "http://www.qb64.net/forum/index.php" IF INSTR(UCASE$(t$), "WEBCHAT") THEN SHELL _HIDE "http://webchat.freenode.net/" IF INSTR(UCASE$(t$), "COMMAND$") THEN t$ = LEFT$(t$, l - 1) + COMMAND$ + MID$(t$, l + 5) IF INSTR(UCASE$(t$), "D2R$") THEN t$ = LEFT$(t$, l - 1) + "FUNCTION D2R## (x AS _FLOAT): D2R = 0.0174532925 * x: END FUNCTION" + MID$(t$, l + 5) IF INSTR(UCASE$(t$), "D2G$") THEN t$ = LEFT$(t$, l - 1) + "FUNCTION D2G## (x AS _FLOAT): D2G = 1.1111111111 * x: END FUNCTION" + MID$(t$, l + 5) IF INSTR(UCASE$(t$), "R2G$") THEN t$ = LEFT$(t$, l - 1) + "FUNCTION R2D## (x AS _FLOAT): R2D = 57.2957795 * x: END FUNCTION" + MID$(t$, l + 5) IF INSTR(UCASE$(t$), "R2G$") THEN t$ = LEFT$(t$, l - 1) + "FUNCTION R2G## (x AS _FLOAT): R2G = 0.015707963 * x: END FUNCTION" + MID$(t$, l + 5) IF INSTR(UCASE$(t$), "G2D$") THEN t$ = LEFT$(t$, l - 1) + "FUNCTION G2D## (x AS _FLOAT): G2D = 0.9 * x: END FUNCTION" + MID$(t$, l + 5) IF INSTR(UCASE$(t$), "G2R$") THEN t$ = LEFT$(t$, l - 1) + "FUNCTION G2R## (x AS _FLOAT): G2R = 63.661977237 * x: END FUNCTION" + MID$(t$, l + 5) 'Strip out the commands we only process once l = 0 DO l = INSTR(UCASE$(t$), "D2R$") IF l = 0 THEN l = INSTR(UCASE$(t$), "D2G$") IF l = 0 THEN l = INSTR(UCASE$(t$), "D2G$") IF l = 0 THEN l = INSTR(UCASE$(t$), "R2G$") IF l = 0 THEN l = INSTR(UCASE$(t$), "R2D$") IF l = 0 THEN l = INSTR(UCASE$(t$), "G2D$") IF l = 0 THEN l = INSTR(UCASE$(t$), "G2R$") IF l = 0 THEN l = INSTR(UCASE$(t$), "WIKI") IF l = 0 THEN l = INSTR(UCASE$(t$), "QB64") IF l = 0 THEN l = INSTR(UCASE$(t$), "FORUMS") IF l = 0 THEN l = INSTR(UCASE$(t$), "WEBCHAT") IF l = 0 THEN l = INSTR(UCASE$(t$), "COMMAND$") IF l THEN t$ = LEFT$(t$, l - 1) + MID$(t$, l + 5) END IF LOOP UNTIL l = 0 e$ = t$: QuickReturn = -1 END SUB SUB VerifyString (t$) 'ERROR CHECK for unrecognized operations j = 1 DO comp$ = MID$(t$, j, 1) SELECT CASE comp$ CASE "0" TO "9", ".", "(", ")": j = j + 1 CASE ELSE good = 0 FOR i = 1 TO UBOUND(OName) IF MID$(t$, j, LEN(OName(i))) = OName(i) THEN good = -1: EXIT FOR 'We found an operator after our ), and it's not a CONST (like PI) NEXT IF NOT good THEN t$ = "ERROR - Bad Operational value. (" + comp$ + ")": EXIT SUB j = j + LEN(OName(i)) END SELECT LOOP UNTIL j > LEN(t$) END SUB FUNCTION BTen$ (InTop AS STRING, Op AS STRING, InBot AS STRING) REM $DYNAMIC InTop = LTRIM$(RTRIM$(InTop)) InBot = LTRIM$(RTRIM$(InBot)) l = INSTR(InTop, "-") IF l = 0 THEN l = INSTR(InTop, "+") IF l = 0 THEN InTop = "+" + InTop l = INSTR(InBot, "-") IF l = 0 THEN l = INSTR(InBot, "+") IF l = 0 THEN InBot = "+" + InBot l = INSTR(InTop, ".") IF l = 0 THEN InTop = InTop + "." l = INSTR(InBot, ".") IF l = 0 THEN InBot = InBot + "." IF Op$ = "-" THEN Op$ = "+" IF MID$(InBot, 1, 1) = "-" THEN MID$(InBot, 1, 1) = "+" ELSE MID$(InBot, 1, 1) = "-" END IF TDP& = Check&(10, InTop$) BDP& = Check&(10, InBot$) IF TDP& < 0 OR BDP& < 0 THEN EXIT FUNCTION TSign% = Check&(11, InTop$) BSign% = Check&(11, InBot$) ' Calculate Array Size IF Op$ = CHR$(43) OR Op$ = CHR$(45) THEN ' "+" (Add) OR "-" (Subtract) Temp& = 9 ELSEIF Op$ = CHR$(42) OR Op$ = CHR$(50) THEN ' "*" (Multiply) OR "2" (SQRT Multiply) Temp& = 7 ELSE EXIT FUNCTION END IF ' LSA (Left Side of Array) LSA& = TDP& - 2 TLS& = LSA& \ Temp& IF LSA& MOD Temp& > 0 THEN TLS& = TLS& + 1 DO WHILE (TLPad& + LSA&) MOD Temp& > 0 TLPad& = TLPad& + 1 LOOP END IF LSA& = BDP& - 2 BLS& = LSA& \ Temp& IF LSA& MOD Temp& > 0 THEN BLS& = BLS& + 1 DO WHILE (BLPad& + LSA&) MOD Temp& > 0 BLPad& = BLPad& + 1 LOOP END IF IF TLS& >= BLS& THEN LSA& = TLS& ELSE LSA& = BLS& ' RSA (Right Side of Array) RSA& = LEN(InTop$) - TDP& TRS& = RSA& \ Temp& IF RSA& MOD Temp& > 0 THEN TRS& = TRS& + 1 DO WHILE (TRPad& + RSA&) MOD Temp& > 0 TRPad& = TRPad& + 1 LOOP END IF RSA& = LEN(InBot$) - BDP& BRS& = RSA& \ Temp& IF RSA& MOD Temp& > 0 THEN BRS& = BRS& + 1 DO WHILE (BRPad& + RSA&) MOD Temp& > 0 BRPad& = BRPad& + 1 LOOP END IF IF TRS& >= BRS& THEN RSA& = TRS& ELSE RSA& = BRS& IF Op$ = CHR$(43) OR Op$ = CHR$(45) THEN ' "+" (Add) OR "-" (Subtract) DIM Result(1 TO (LSA& + RSA&)) AS LONG IF (Op$ = CHR$(43) AND TSign% = BSign%) OR (Op$ = CHR$(45) AND TSign% <> BSign%) THEN ' Add Absolute Values and Return Top Sign ' Left Side FOR I& = 1 TO LSA& ' Top IF I& <= (LSA& - TLS&) THEN ''' Result(I&) = Result(I&) + 0 ELSEIF I& = (1 + LSA& - TLS&) THEN Result(I&) = VAL(MID$(InTop$, 2, (9 - TLPad&))) TDP& = 11 - TLPad& ELSE Result(I&) = VAL(MID$(InTop$, TDP&, 9)) TDP& = TDP& + 9 END IF ' Bottom IF I& <= (LSA& - BLS&) THEN ''' Result(I&) = Result(I&) + 0 ELSEIF I& = (1 + LSA& - BLS&) THEN Result(I&) = Result(I&) + VAL(MID$(InBot$, 2, (9 - BLPad&))) BDP& = 11 - BLPad& ELSE Result(I&) = Result(I&) + VAL(MID$(InBot$, BDP&, 9)) BDP& = BDP& + 9 END IF NEXT I& ' Right Side TDP& = TDP& + 1: BDP& = BDP& + 1 FOR I& = (LSA& + 1) TO (LSA& + RSA&) ' Top IF I& > (LSA& + TRS&) THEN ''' Result(I&) = Result(I&) + 0 ELSEIF I& = (LSA& + TRS&) THEN Result(I&) = (10 ^ TRPad&) * VAL(RIGHT$(InTop$, (9 - TRPad&))) ELSE Result(I&) = VAL(MID$(InTop$, TDP&, 9)) TDP& = TDP& + 9 END IF ' Bottom IF I& > (LSA& + BRS&) THEN ''' Result(I&) = Result(I&) + 0 ELSEIF I& = (LSA& + BRS&) THEN Result(I&) = Result(I&) + (10 ^ BRPad&) * VAL(RIGHT$(InBot$, (9 - BRPad&))) ELSE Result(I&) = Result(I&) + VAL(MID$(InBot$, BDP&, 9)) BDP& = BDP& + 9 END IF NEXT I& ' Carry FOR I& = (LSA& + RSA&) TO 2 STEP -1 IF Result(I&) >= 1000000000 THEN Result(I& - 1) = Result(I& - 1) + 1 Result(I&) = Result(I&) - 1000000000 END IF NEXT I& ' Return Sign IF TSign% = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45) ELSE ' Compare Absolute Values IF TDP& > BDP& THEN Compare& = 1 ELSEIF TDP& < BDP& THEN Compare& = -1 ELSE IF LEN(InTop$) > LEN(InBot$) THEN Compare& = LEN(InBot$) ELSE Compare& = LEN(InTop$) FOR I& = 2 TO Compare& IF VAL(MID$(InTop$, I&, 1)) > VAL(MID$(InBot$, I&, 1)) THEN Compare& = 1 EXIT FOR ELSEIF VAL(MID$(InTop$, I&, 1)) < VAL(MID$(InBot$, I&, 1)) THEN Compare& = -1 EXIT FOR END IF NEXT I& IF Compare& > 1 THEN IF LEN(InTop$) > LEN(InBot$) THEN Compare& = 1 ELSEIF LEN(InTop$) < LEN(InBot$) THEN Compare& = -1 ELSE Compare& = 0 END IF END IF END IF ' Conditional Subtraction IF Compare& = 1 THEN ' Subtract Bottom from Top and Return Top Sign ' Top Result(1) = VAL(MID$(InTop$, 2, (9 - TLPad&))) TDP& = 11 - TLPad& FOR I& = 2 TO LSA& Result(I&) = VAL(MID$(InTop$, TDP&, 9)) TDP& = TDP& + 9 NEXT I& TDP& = TDP& + 1 FOR I& = (LSA& + 1) TO (LSA& + TRS& - 1) Result(I&) = VAL(MID$(InTop$, TDP&, 9)) TDP& = TDP& + 9 NEXT I& Result(LSA& + TRS&) = 10& ^ TRPad& * VAL(RIGHT$(InTop$, (9 - TRPad&))) ' Bottom BDP& = (LEN(InBot$) - 17) + BRPad& FOR I& = (LSA& + BRS&) TO (1 + LSA& - BLS&) STEP -1 IF I& = LSA& THEN BDP& = BDP& - 1 IF I& = (LSA& + BRS&) THEN Temp& = (10& ^ BRPad&) * VAL(RIGHT$(InBot$, (9 - BRPad&))) ELSEIF I& = (1 + LSA& - BLS&) THEN Temp& = VAL(MID$(InBot$, 2, (9 - BLPad&))) ELSE Temp& = VAL(MID$(InBot$, BDP&, 9)) BDP& = BDP& - 9 END IF IF Result(I&) < Temp& THEN ' Borrow FOR J& = (I& - 1) TO 1 STEP -1 IF Result(J&) = 0 THEN Result(J&) = 999999999 ELSE Result(J&) = Result(J&) - 1 EXIT FOR END IF NEXT J& Result(I&) = Result(I&) + 1000000000 END IF Result(I&) = Result(I&) - Temp& NEXT I& ' Return Sign IF TSign% = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45) ELSEIF Compare& = -1 THEN ' Subtract Top from Bottom and Return Bottom Sign ' Bottom Result(1) = VAL(MID$(InBot$, 2, (9 - BLPad&))) BDP& = 11 - BLPad& FOR I& = 2 TO LSA& Result(I&) = VAL(MID$(InBot$, BDP&, 9)) BDP& = BDP& + 9 NEXT I& BDP& = BDP& + 1 FOR I& = (LSA& + 1) TO (LSA& + BRS& - 1) Result(I&) = VAL(MID$(InBot$, BDP&, 9)) BDP& = BDP& + 9 NEXT I& Result(LSA& + BRS&) = 10& ^ BRPad& * VAL(RIGHT$(InBot$, (9 - BRPad&))) ' Top TDP& = (LEN(InTop$) - 17) + TRPad& FOR I& = (LSA& + TRS&) TO (1 + LSA& - TLS&) STEP -1 IF I& = LSA& THEN TDP& = TDP& - 1 IF I& = (LSA& + TRS&) THEN Temp& = (10& ^ TRPad&) * VAL(RIGHT$(InTop$, (9 - TRPad&))) ELSEIF I& = (1 + LSA& - TLS&) THEN Temp& = VAL(MID$(InTop$, 2, (9 - TLPad&))) ELSE Temp& = VAL(MID$(InTop$, TDP&, 9)) TDP& = TDP& - 9 END IF IF Result(I&) < Temp& THEN ' Borrow FOR J& = (I& - 1) TO 1 STEP -1 IF Result(J&) = 0 THEN Result(J&) = 999999999 ELSE Result(J&) = Result(J&) - 1 EXIT FOR END IF NEXT J& Result(I&) = Result(I&) + 1000000000 END IF Result(I&) = Result(I&) - Temp& NEXT I& ' Build Return Sign IF BSign% = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45) ELSE ' Result will always be 0 LSA& = 1: RSA& = 1 RetStr$ = CHR$(43) END IF END IF ' Generate Return String RetStr$ = RetStr$ + LTRIM$(STR$(Result(1))) FOR I& = 2 TO LSA& RetStr$ = RetStr$ + RIGHT$(STRING$(8, 48) + LTRIM$(STR$(Result(I&))), 9) NEXT I& RetStr$ = RetStr$ + CHR$(46) FOR I& = (LSA& + 1) TO (LSA& + RSA&) RetStr$ = RetStr$ + RIGHT$(STRING$(8, 48) + LTRIM$(STR$(Result(I&))), 9) NEXT I& ERASE Result ELSEIF Op$ = CHR$(42) THEN ' * (Multiply) DIM TArray(1 TO (LSA& + RSA&)) AS LONG DIM BArray(1 TO (LSA& + RSA&)) AS LONG DIM ResDBL(0 TO (LSA& + RSA&)) AS DOUBLE ' Push String Data Into Array FOR I& = 1 TO LSA& IF I& <= (LSA& - TLS&) THEN ''' TArray(I&) = TArray(I&) + 0 ELSEIF I& = (1 + LSA& - TLS&) THEN TArray(I&) = VAL(MID$(InTop$, 2, (7 - TLPad&))) TDP& = 9 - TLPad& ELSE TArray(I&) = VAL(MID$(InTop$, TDP&, 7)) TDP& = TDP& + 7 END IF IF I& <= (LSA& - BLS&) THEN ''' BArray(I&) = BArray(I&) + 0 ELSEIF I& = (1 + LSA& - BLS&) THEN BArray(I&) = VAL(MID$(InBot$, 2, (7 - BLPad&))) BDP& = 9 - BLPad& ELSE BArray(I&) = VAL(MID$(InBot$, BDP&, 7)) BDP& = BDP& + 7 END IF NEXT I& TDP& = TDP& + 1: BDP& = BDP& + 1 FOR I& = (LSA& + 1) TO (LSA& + RSA&) IF I& > (LSA& + TRS&) THEN ''' TArray(I&) = TArray(I&) + 0 ELSEIF I& = (LSA& + TRS&) THEN TArray(I&) = 10 ^ TRPad& * VAL(RIGHT$(InTop$, (7 - TRPad&))) ELSE TArray(I&) = VAL(MID$(InTop$, TDP&, 7)) TDP& = TDP& + 7 END IF IF I& > (LSA& + BRS&) THEN ''' BArray(I&) = BArray(I&) + 0 ELSEIF I& = (LSA& + BRS&) THEN BArray(I&) = 10 ^ BRPad& * VAL(RIGHT$(InBot$, (7 - BRPad&))) ELSE BArray(I&) = VAL(MID$(InBot$, BDP&, 7)) BDP& = BDP& + 7 END IF NEXT I& ' Multiply from Arrays to Array FOR I& = (LSA& + TRS&) TO (1 + LSA& - TLS&) STEP -1 FOR J& = (LSA& + BRS&) TO (1 + LSA& - BLS&) STEP -1 Temp# = 1# * TArray(I&) * BArray(J&) IF (I& + J&) MOD 2 = 0 THEN TL& = INT(Temp# / 10000000) TR& = Temp# - 10000000# * TL& ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL& ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + 10000000# * TR& ELSE ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + Temp# END IF IF ResDBL((I& + J&) \ 2) >= 100000000000000# THEN Temp# = ResDBL((I& + J&) \ 2) TL& = INT(Temp# / 100000000000000#) ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL& ResDBL((I& + J&) \ 2) = Temp# - 100000000000000# * TL& END IF NEXT J& NEXT I& ERASE TArray, BArray ' Generate Return String IF (TSign% * BSign%) = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45) RetStr$ = RetStr$ + LTRIM$(STR$(ResDBL(0))) FOR I& = 1 TO (LSA&) RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14) NEXT I& RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 7) + CHR$(46) + RIGHT$(RetStr$, 7) FOR I& = (LSA& + 1) TO (LSA& + RSA&) RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14) NEXT I& ERASE ResDBL ELSEIF Op$ = CHR$(50) THEN ' 2 (SQRT Multiply) DIM IArray(1 TO (LSA& + RSA&)) AS LONG DIM ResDBL(0 TO (LSA& + RSA&)) AS DOUBLE ' Push String Data Into Array FOR I& = 1 TO LSA& IF I& <= (LSA& - TLS&) THEN ''' IArray(I&) = IArray(I&) + 0 ELSEIF I& = (1 + LSA& - TLS&) THEN IArray(I&) = VAL(MID$(InTop$, 2, (7 - TLPad&))) TDP& = 9 - TLPad& ELSE IArray(I&) = VAL(MID$(InTop$, TDP&, 7)) TDP& = TDP& + 7 END IF NEXT I& TDP& = TDP& + 1 FOR I& = (LSA& + 1) TO (LSA& + RSA&) IF I& > (LSA& + TRS&) THEN ''' IArray(I&) = IArray(I&) + 0 ELSEIF I& = (LSA& + TRS&) THEN IArray(I&) = 10 ^ TRPad& * VAL(RIGHT$(InTop$, (7 - TRPad&))) ELSE IArray(I&) = VAL(MID$(InTop$, TDP&, 7)) TDP& = TDP& + 7 END IF NEXT I& ' SQRT Multiply from Array to Array FOR I& = (LSA& + TRS&) TO 1 STEP -1 FOR J& = I& TO 1 STEP -1 Temp# = 1# * IArray(I&) * IArray(J&) IF I& <> J& THEN Temp# = Temp# * 2 IF (I& + J&) MOD 2 = 0 THEN TL& = INT(Temp# / 10000000) TR& = Temp# - 10000000# * TL& ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL& ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + 10000000# * TR& ELSE ResDBL((I& + J&) \ 2) = ResDBL((I& + J&) \ 2) + Temp# END IF IF ResDBL((I& + J&) \ 2) >= 100000000000000# THEN Temp# = ResDBL((I& + J&) \ 2) TL& = INT(Temp# / 100000000000000#) ResDBL(((I& + J&) \ 2) - 1) = ResDBL(((I& + J&) \ 2) - 1) + TL& ResDBL((I& + J&) \ 2) = Temp# - 100000000000000# * TL& END IF NEXT J& NEXT I& ERASE IArray ' Generate Return String IF (TSign% * BSign%) = 1 THEN RetStr$ = CHR$(43) ELSE RetStr$ = CHR$(45) RetStr$ = RetStr$ + LTRIM$(STR$(ResDBL(0))) FOR I& = 1 TO (LSA&) RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14) NEXT I& RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 7) + CHR$(46) + RIGHT$(RetStr$, 7) ' Don't usually want the full right side for this, just enough to check the ' actual result against the expected result, which is probably an integer. ' Uncomment the three lines below when trying to find an oddball square root. 'FOR I& = (LSA& + 1) TO (LSA& + RSA&) ' RetStr$ = RetStr$ + RIGHT$(STRING$(13, 48) + LTRIM$(STR$(ResDBL(I&))), 14) 'NEXT I& ERASE ResDBL END IF ' Trim Leading and Trailing Zeroes DO WHILE MID$(RetStr$, 2, 1) = CHR$(48) AND MID$(RetStr$, 3, 1) <> CHR$(46) RetStr$ = LEFT$(RetStr$, 1) + RIGHT$(RetStr$, LEN(RetStr$) - 2) LOOP DO WHILE RIGHT$(RetStr$, 1) = CHR$(48) AND RIGHT$(RetStr$, 2) <> CHR$(46) + CHR$(48) RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 1) LOOP IF MID$(RetStr$, 1, 1) = "+" THEN MID$(RetStr$, 1, 1) = " " DO r$ = RIGHT$(RetStr$, 1) IF r$ = "0" THEN RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 1) LOOP UNTIL r$ <> "0" r$ = RIGHT$(RetStr$, 1) IF r$ = "." THEN RetStr$ = LEFT$(RetStr$, LEN(RetStr$) - 1) BTen$ = RetStr$ END FUNCTION REM $STATIC ' --------------------------------------------------------------------------- ' FUNCTION Check& (Op&, InString$) Multi-Purpose String Tester ' --------------------------------------------------------------------------- ' ' * Op& = Type of string to expect and/or operation to perform ' ' { 00A } = (10) Test Base-10-Format String ( *!* ALTERS InString$ *!* ) ' { 00B } = (11) Read Sign ("+", "-", or "ñ") ' ' Unlisted values are not used and will return [ Check& = 0 - Op& ]. ' Different Op& values produce various return values. ' Refer to the in-code comments for details. ' ' --------------------------------------------------------------------------- ' FUNCTION Check& (Op&, InString$) Multi-Purpose String Tester ' --------------------------------------------------------------------------- FUNCTION Check& (Op AS LONG, InString AS STRING) REM $DYNAMIC RetVal& = LEN(InString$) SELECT CASE Op& CASE 10 ' {00A} Test String for Base-10-Format ( *!* ALTERS InString$ *!* ) ' Returns: ' {& > 0} = DP offset; {& < 0} = FAILED at negative offset ' ' After testing passes, the string is trimmed ' of nonessential leading and trailing zeroes. IF RetVal& = 0 THEN RetVal& = -1 ELSE SELECT CASE ASC(LEFT$(InString$, 1)) CASE 43, 45 ' "+", "-" FOR I& = 2 TO RetVal& SELECT CASE ASC(MID$(InString$, I&, 1)) CASE 46 ' "." IF DPC% > 0 THEN RetVal& = 0 - I& EXIT FOR ELSE DPC% = DPC% + 1 RetVal& = I& END IF CASE 48 TO 57 ' keep going CASE ELSE RetVal& = 0 - I& EXIT FOR END SELECT NEXT I& CASE ELSE RetVal& = -1 END SELECT IF DPC% = 0 AND RetVal& > 0 THEN RetVal& = 0 - RetVal& ELSEIF RetVal& = 2 THEN InString$ = LEFT$(InString$, 1) + CHR$(48) + RIGHT$(InString$, LEN(InString$) - 1) RetVal& = RetVal& + 1 END IF IF RetVal& = LEN(InString$) THEN InString$ = InString$ + CHR$(48) DO WHILE ASC(RIGHT$(InString$, 1)) = 48 AND RetVal& < (LEN(InString$) - 1) InString$ = LEFT$(InString$, LEN(InString$) - 1) LOOP DO WHILE ASC(MID$(InString$, 2, 1)) = 48 AND RetVal& > 3 InString$ = LEFT$(InString$, 1) + RIGHT$(InString$, LEN(InString$) - 2) RetVal& = RetVal& - 1 LOOP END IF CASE 11 ' {00B} Read Sign ("+", "-", or "ñ") ' Returns: ' Explicit: +1 = Positive; -1 = Negative; 0 = Unsigned; ' Implied: +64 = Positive; -64 = NULL String IF RetVal& = 0 THEN RetVal& = -64 FOR I& = 1 TO RetVal& SELECT CASE ASC(MID$(InString$, I&, 1)) CASE 32 RetVal& = 64 ' keep going CASE 43 RetVal& = 1 EXIT FOR CASE 45 RetVal& = -1 EXIT FOR CASE 241 RetVal& = 0 EXIT FOR CASE ELSE RetVal& = 64 EXIT FOR END SELECT NEXT I& CASE ELSE RetVal& = 0 - Op& END SELECT Check& = RetVal& END FUNCTION FUNCTION N2S$ (exp$) 'scientific Notation to String t$ = LTRIM$(RTRIM$(exp$)) IF LEFT$(t$, 1) = "-" THEN sign$ = "-": t$ = MID$(t$, 2) dp = INSTR(t$, "D+"): dm = INSTR(t$, "D-") ep = INSTR(t$, "E+"): em = INSTR(t$, "E-") check1 = SGN(dp) + SGN(dm) + SGN(ep) + SGN(em) IF check1 < 1 OR check1 > 1 THEN N2S = exp$: EXIT SUB 'If no scientic notation is found, or if we find more than 1 type, it's not SN! SELECT CASE l 'l now tells us where the SN starts at. CASE IS < dp: l = dp CASE IS < dm: l = dm CASE IS < ep: l = ep CASE IS < em: l = em END SELECT l$ = LEFT$(t$, l - 1) 'The left of the SN r$ = MID$(t$, l + 1): r&& = VAL(r$) 'The right of the SN, turned into a workable long IF INSTR(l$, ".") THEN 'Location of the decimal, if any IF r&& > 0 THEN r&& = r&& - LEN(l$) + 2 ELSE r&& = r&& + 1 END IF l$ = LEFT$(l$, 1) + MID$(l$, 3) END IF SELECT CASE r&& CASE 0 'what the heck? We solved it already? 'l$ = l$ CASE IS < 0 FOR i = 1 TO -r&& l$ = "0" + l$ NEXT l$ = "0." + l$ CASE ELSE FOR i = 1 TO r&& l$ = l$ + "0" NEXT END SELECT N2S$ = sign$ + l$ END SUB SUB Mathbox 'Draw a box '-------- generic dialog box header -------- PCOPY 0, 2 PCOPY 0, 1 SCREEN , , 1, 0 focus = 1 DIM p AS idedbptype DIM o(1 TO 100) AS idedbotype DIM oo AS idedbotype DIM sep AS STRING * 1 sep = CHR$(0) '-------- end of generic dialog box header -------- DoAnother: titlestr$ = " Give me a Math Equation " messagestr$ = "" '-------- init -------- i = 0 w = LEN(messagestr$) + 2 w2 = LEN(titlestr$) + 4 IF w < w2 THEN w = w2 idepar p, w, 4, titlestr$ i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("OK") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 2: PRINT messagestr$; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) IF K$ = CHR$(27) THEN EXIT SUB END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 IF K$ > CHR$(31) AND K$ < CHR$(123) THEN messagestr$ = messagestr$ + K$ IF K$ = CHR$(8) THEN messagestr$ = LEFT$(messagestr$, LEN(messagestr$) - 1) f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR K$ = CHR$(13) OR (focus = 1 AND info <> 0) THEN EXIT DO 'end of custom controls mousedown = 0 mouseup = 0 LOOP temp$ = messagestr$ 'Make a back up of our user return titlestr$ = "(H)ex/(D)ec (U)n(C)omment (ESC)ape/(R)edo" ev$ = Evaluate_Expression$(messagestr$) messagestr$ = ev$ '-------- init -------- i = 0 w = LEN(messagestr$) + 2 w2 = LEN(titlestr$) + 4 IF w < w2 THEN w = w2 idepar p, w, 4, titlestr$ i = i + 1 o(i).typ = 3 o(i).y = 4 o(i).txt = idenewtxt("OK") o(i).dft = 1 '-------- end of init -------- '-------- generic init -------- FOR i = 1 TO 100: o(i).par = p: NEXT 'set parent info of objects '-------- end of generic init -------- DO 'main loop '-------- generic display dialog box & objects -------- idedrawpar p f = 1: cx = 0: cy = 0 FOR i = 1 TO 100 IF o(i).typ THEN 'prepare object o(i).foc = focus - f 'focus offset o(i).cx = 0: o(i).cy = 0 idedrawobj o(i), f 'display object IF o(i).cx THEN cx = o(i).cx: cy = o(i).cy END IF NEXT i lastfocus = f - 1 '-------- end of generic display dialog box & objects -------- '-------- custom display changes -------- COLOR 0, 7: LOCATE p.y + 2, p.x + 2: PRINT messagestr$; '-------- end of custom display changes -------- 'update visual page and cursor position PCOPY 1, 0 IF cx THEN SCREEN , , 0, 0: LOCATE cy, cx, 1: SCREEN , , 1, 0 '-------- read input -------- change = 0 DO GetInput IF mWHEEL THEN change = 1 IF KB THEN change = 1 IF mCLICK THEN mousedown = 1: change = 1 IF mRELEASE THEN mouseup = 1: change = 1 IF mB THEN change = 1 alt = KALT: IF alt <> oldalt THEN change = 1 oldalt = alt _LIMIT 100 LOOP UNTIL change IF alt THEN idehl = 1 ELSE idehl = 0 'convert "alt+letter" scancode to letter's ASCII character altletter$ = "" IF alt THEN IF LEN(K$) = 1 THEN k = ASC(UCASE$(K$)) IF k >= 65 AND k <= 90 THEN altletter$ = CHR$(k) END IF END IF SCREEN , , 0, 0: LOCATE , , 0: SCREEN , , 1, 0 '-------- end of read input -------- '-------- generic input response -------- info = 0 IF K$ = "" THEN K$ = CHR$(255) IF KSHIFT = 0 AND K$ = CHR$(9) THEN focus = focus + 1 IF KSHIFT AND K$ = CHR$(9) THEN focus = focus - 1 IF focus < 1 THEN focus = lastfocus IF focus > lastfocus THEN focus = 1 IF K$ = "H" OR K$ = "h" THEN ev$ = "&H" + HEX$(VAL(ev$)) IF K$ = "D" OR K$ = "d" THEN ev$ = STR$(VAL(ev$)) IF K$ = "U" OR K$ = "u" THEN comment = 0 IF K$ = "C" OR K$ = "c" THEN comment = -1 IF K$ = "R" OR K$ = "r" THEN GOTO DoAnother IF K$ = CHR$(27) THEN EXIT SUB IF comment THEN messagestr$ = ev$ + " ' " + temp$ ELSE messagestr$ = ev$ f = 1 FOR i = 1 TO 100 t = o(i).typ IF t THEN focusoffset = focus - f ideupdateobj o(i), focus, f, focusoffset, K$, altletter$, mB, mousedown, mouseup, mX, mY, info, mWHEEL END IF NEXT '-------- end of generic input response -------- 'specific post controls IF K$ = CHR$(27) OR K$ = CHR$(13) OR (focus = 1 AND info <> 0) THEN EXIT DO 'end of custom controls mousedown = 0 mouseup = 0 LOOP IF INSTR(messagestr$, " LINES INSERTED") THEN EXIT SUB l = idecy a$ = idegetline(l) l$ = LEFT$(a$, idecx - 1): r$ = RIGHT$(a$, LEN(a$) - idecx + 1) text$ = l$ + messagestr$ + r$ textlen = LEN(text$) l$ = LEFT$(idet$, ideli - 1) m$ = MKL$(textlen) + text$ + MKL$(textlen) r$ = RIGHT$(idet$, LEN(idet$) - ideli - LEN(a$) - 7) idet$ = l$ + m$ + r$ idecx = idecx + LEN(messagestr$) END SUB