TEIMSI compilation instructions
3)- @assumevar
4)- Path constants
7)- Pointer to function/public variable/label
8)- File inclusions. The default paths constants
9)- Declaration of TEIMSI local constants
10)- Declaration of assembler extended constants.
11)- @eof_file
12)- @import:
13)- Data blocks
15)- _savelocal
16)- Conditional compilation instructions
17)- Creation and inclusion of TCO files
To declare variables, it's "var" like "var variable=value" where "variable" is the name of the variable. The name can begin with any letter or dot (".") or the underscore ("_") character, the following characters could be numbers. The value is optional, you can omit the "= value" and the variable takes the "undefined" value. Within some of the types of data that can be contained in variables: 32-bit integer, Double (double precision decimal number), string, boolean, array, "undefined" and others.
Examples:
var amout=1832 // Integer.
var number=32.44 // Double.
var string="Hello!" // String.
var matrix=array(1,3,5,7) // Array with four items.
var matrix2=array(234) // Array with 234 items, all of -1 value (default). If you only specify an integer, it will be taken as the size of the array.
var thetruth=true // Boolean
var result=(8*7+3) // Integer, is the result of evaluating an expression.
var str1=ucase("water"), str2=lcase("Sun") // Two string type variables declared in the same line that take the returned value by certain functions
// ("ucase" converts a string to uppercase and "lcase" to lowercase).
Next, will show some bad examples of use of "var":
var 8string="Hello!" // The name should not start with a number. var eax=3212 // "eax" is a reserved word for the assembly language code that "FASM" will read among others which are: push, pop, mov, mul, div, sub, add, stc, ret, // proc, endp, struct, ends, local, locals, endl and all the used by the assembler compiler.
The predefined variables were created since they are used in the everyday, for example "_nl" is the return line variable (the sum of characters ASCII code 13 and 10: chr(13) + chr(10)), "_c0" is chr(0). See the list below:
Variable name | Content | |
---|---|---|
_E | The "e" number of Euler: 2.71828182845... | |
_PI | The "PI" number: 3.1415926535898... | |
_NaN | The "NaN" number (Not real or "Not a Number"). | |
_nl | String chr(13)+chr(10) // Strings for general use. | |
_c0 | String chr(0) | |
_c1 | String chr(1) | |
_c2 | String chr(2) | |
_c9 | String chr(9) | |
_c10 | String chr(10) | |
_c13 | String chr(13) | |
_c34 | String chr(34) | |
_c39 | String chr(39) | |
_c44 | String chr(44) | |
_c47 | String chr(47) | |
_c92 | String chr(92) | |
_c64 | String chr(64) | |
_c124 | String chr(124) | |
_c126 | String chr(126) | |
_nulstr | Empty string: "" | |
_mb_okcancel | Integer 1 // Useful integers for the "alert_ex" function | |
_mb_abortretryignore | Integer 2 | |
_mb_yesnocancel | Integer 3 | |
_mb_yesno | Integer 4 | |
_mb_retrycancel | Integer 5 | |
_mb_iconerror | Integer 16 | |
_mb_iconquestion | Integer 32 | |
_mb_iconexclamation | Integer 48 | |
_mb_iconinformation | Integer 64 | |
_mb_defbutton2 | Integer 256 | |
_mb_defbutton3 | Integer 512 | |
_mb_iconasterisk | Integer 64 | |
_mbret_yes | Integer 6 | |
_mbret_no | Integer 7 | |
_mbret_cancel | Integer 2 | |
_mbret_yesno | Integer 1 | |
_mbret_abort | Integer 3 | |
_mbret_retry | Integer 4 | |
_mbret_ignore | Integer 5 | |
_scolblack | Integer 0 // Useful integers for the "supercolorln" function of the file "tco_sources\bitmaps\supercolorln.thp" | |
_scolblue | Integer 256 | |
_scolgreen | Integer 65280 | |
_scolcyan | Integer 65536 | |
_scolred | Integer 16711680 | |
_scolmagenta | Integer 16711936 | |
_scolyellow | Integer 16776960 | |
_scolwhite | Integer 16777216 | |
_sysbool | Integer 0 // Useful integers for the "itype" function | |
_syslong | Integer 1 | |
_sysdbl | Integer 2 | |
_sysstr | Integer 3 | |
_sysarr | Integer 4 | |
_sysvar | Integer 5 | |
_sysvalid | Integer 6 | |
_sysfuncptr | Integer 7 | |
_sysundef | Integer 8 | |
_sysnull | Integer 9 | |
_sys | Integer 10 | |
_sysfunc | Integer 11 | |
_mod_stat | Integer 0 // Useful integers for the "imode" function | |
_mod_dina | Integer 1 | |
_mod_engi | Integer 2 | |
_move_abs | Integer 3 // Useful integers for the "move" function of the file "tco_sources\click_move.thp" | |
_move_rel | Integer 2 | |
_move_relpt | Integer 1 | |
_move_relwin | Integer 0 | |
_numtype_dbl | Integer 2 // Useful integers for the "number_type" function | |
_numtype_long | Integer 1 | |
_numtype_none | Integer 0 | |
_tlyear | Integer 0 // Useful integers for the "timelong2arr" and "arr2timelong" functions | |
_tlmonth | Integer 1 | |
_tldayofweek | Integer 2 | |
_tlday | Integer 3 | |
_tlhour | Integer 4 | |
_tlminute | Integer 5 | |
_tlsecond | Integer 6 | |
_waitkey_shift | Integer 4096 // Useful integers for the "console_waitkeyex" function | |
_waitkey_ctrl | Integer 2048 | |
_waitkey_alt | Integer 512 | |
_waitkey_bmayus | Integer 32768 | |
_waitkey_bnum | Integer 8192 | |
_waitkey_bdesp | Integer 16384 | |
_waitkey_isdown | Integer 0 | |
_waitkey_scancode | Integer 1 | |
_waitkey_asciichar | Integer 2 | |
_waitkey_ctrlkeystate | Integer 3 | |
Examples:
alert("Row 1"+_nl+"Row 2") alert("You selected YES = " + (alert_ex("Hello! choose \"yes\" or \"no\":","Example",_mb_yesno+_mb_iconexclamation)==_mbret_yes));
The "@assumevar" statement lets you specify variables that have not been declared with "var" but whose content has been declared in the initialized data section. This allows you to add TEIMSI variables whose value is imported from elsewhere. The "place_idata" instruction is used to set variables into the assembler data section (see also Data blocks).
Example:
place_idata{ _string_1_cont db "Hell",111,0 string1 dd 0, 3, _string_1_cont, 5 ; A TEIMSI variable is expressed by 16 bytes in the data section, for more information see Introduction to the use of FASM with Teimsi ; The first integer dword "0" indicates the "_mod_stat" mode of the variable, the second dword indicates the data type "_sysstr", the third is the starting position of the static string, and the fourth the length. ; If the string has dynamic mode "_mod_dina" third dword would have the string's handler (dword integer). integer1 dd 0, 1, 111, 0 ; The first integer dword "0" indicates the "_mod_stat" mode of the variable, the second indicates the "_syslong" data type, the third is the integer, and the fourth should be zero. double1 dd 0, 2 ; The first integer dword "0" indicates the "_mod_stat" mode of the variable, the second indicates the "_sysdbl" data type, the third is a "QWORD" with the value. dq 3.51 } @assumevar:string1,integer1,double1 alert(string1) alert(integer1) alert(double1)
see File inclusions. The default paths constants
Now it will be described the usage of the following instructions for TEIMSI:
1)- "if"
2)- "for"
3)- "while"
4)- "<label>:"
5)- "jmp"
6)- "jmpcase"
7)- "sys.quit()"
1)- "if(condition){ TEIMSI_block }"
Evaluates if a condition is true, if that happens then the block comprised braces "{" and "}" is executed. You can specify a "}else{" instead of the closing brace "}" to execute code if the "condition" is not satisfied, it can also indicate a '}else if(condition2){" if you want to evaluate a second condition and execute the TEIMSI block that is contains in case that the first condition is not met.
Example:
var number=8 if(number==8){ alert("The number is 8") }else if(number==9){ alert("The number is 9") }else{ alert("The number is neither 8 nor 9") }
2)- "for(statements, condition_to_run_the_cycle, variation_instructions) {}"
The "for" instruction repeatedly executes the instructions included in the block in braces "{" and "}". The term "condition_to_run_the_cycle" is evaluated to see if it will remain in the "for" loop or leave it. The "statements" are of the form var <name> = separated by "," comma value; are used to initialize variables used in the "for" loop, more specifically the integer value that varies. The "variation_instructions" equation and expression is executed each time the code in the block "for" with TEIMSI code is executed.
The "break" instruction can be used to exit the "for" loop at any desired time.
Example 1:
for(var t=0;t<7;t++){ alert("t = "+t) if(t==4){break} }
Example 2:
for(var k=-5,u=0; k<6 ; k++,u++ ){ alert("k = "+k+_nl+"u = "+u) }
3)- "while(condition){ TEIMSI_block }"
The "while" instruction repeatedly executes the instructions included in the block in braces "{" and "}". The "condition" term is evaluated to see if staying in the "while" loop or leave it.
The "break" instruction can be used to exit the "while" cycle at any desired time.
Example: var t=0 while(t<7){ alert("t = "+t) if(t==4){break} t++ }
4)- "<label>:"
Declares a label that is a point in the code that will be used for jump instructions in both TEIMSI and assembler. For TEIMSI jump instructions are "jmp(label)" and "jmpcase(<condition>, label)". For assembler, there are several possible instructions like "jmp", "call", and also the references to that location in the code section and certain macros.
5)- "jmp"
The "jmp(label)" instruction changes the flow of execution of TEIMSI code to that position (to "label").
Example:
var k=0 loop_of_k: alert("k = "+k) if(k==5){ jmp(loop_of_kfin) } k++ jmp(loop_of_k) loop_of_kfin:
6)- "jmpcase"
The "jmpcase(condition, label)" instruction evaluates the expression "condition" if true, in which case changes the flow of execution of TEIMSI code to that position (to "label").
Example:
var k=0 loop_of_k: alert("k = "+k) k++ jmpcase(k<=5,loop_of_k)
7)- "sys.quit()"
The "sys.quit()" instruction, terminates the program execution for the currently running .exe program.
Example:
alert("hello!") sys.quit() alert("This is not shown!")
The declaration of TEIMSI procedures/functions is made with the "function" instruction. The optional "return" instruction exits the function, it receives the returned value by the function.
Syntax: "function name(parameters){block}"
Example program:
var num=ecuation1(44) alert("24*91+44*13 = " + num) function ecuation1(parameter1){ return (24*91+parameter1*13) }
You can load an integer, the internal pointer to the section of data or code that matches a given public variable or label or location of procedure.
This integer value has advanced uses and some uses on predefined and special TEIMSI functions like reghotkey and regtimer.
Example 1:
var number=932 number=@number function ecuation1(parameter1){ label1: return (24*91+parameter1*13) } alert(number) // Displays a number that has nothing to do with 932. (position in the data section of this variable). alert(@ecuation1) // Shows the position in the code section of that procedure. alert(@label1) // Shows the position in the code section of that label.
Example 2 (advanced):
var number=-932 var location_number=@number _direct{ mov esi, [location_number+reg.vo] ; It loads into "esi" the position of the "number" variable from the integer value of the "location_number" variable. neg dword [esi+reg.vo] ; Changes the integer value in the variable "number". } alert(number) // Shows 932 instead of -932.
In this section will be explained how TEIMSI files are included, you should know that the (main) header file of a certain project TEIMSI (preferably will have the TSI extension) is where the inclusion of other TEIMSI code files is allowed (and as a convention those file should have THP extension). To the TEIMSI Editor version 0.95, the inclusion of TEIMSI files from files already included is not enabled.
Example:
// The following instruction includes "text2clipboard.tco" file which is found in the "tco_inc" folder of the TEIMSI editor. include_tco(tco_inc\text2clipboard.tco)
The current folder during compilation is the folder of the TEIMSI editor program, so to refer to files in a project the following constants that are replaced at compile time by a real path should be used (which does not include the character "\" or "/" at the end of it).
Constant | Contents |
---|---|
º_editordir_ | Path to Directory/Folder of the TEIMSI Editor program file |
º_scriptdir_ | Path to the folder of the file currently being compiled |
º_scriptparentdir_ | Path to the parent folder of the folder containing the file being compiled |
º_fasmdir_ | Path to the folder containing the "fasm.exe" program needed to assemble |
º_documentsdir_ | Path to the user's documents folder that started session |
Then, some examples are shown:
// The following instruction includes the "funciones2.thp" file located in the same folder of the .tsi project file. includec(º_scriptdir_\funciones2.thp) // The following instruction includes the "report_timelong.tco" file located in the folder of the TEIMSI editor program file. include_tco(tco_inc\report_timelong.tco) // The following instruction performs the same as the previous one because the current path is the one containing the constant "º_editordir_". include_tco(º_editordir_\tco_inc\report_timelong.tco) // The following instruction (located in a "_direct" block) sets the inclusion path of the file to be used by FASM at assembly time. _direct{ include "º_scriptdir_\fnasm1.asm" }
This works because these constants (and those that are declared value ºconstant_name===value under TEIMSI") are replaced before compilation by their corresponding values. Indeed, it is possible to give other applications such as makes the following instruction:
alert("Path to the compiled original project = º_scriptdir_")
See also Declaration of TEIMSI local constants
Our compiler the Editor of TEIMSI, allows to define the desired constant strings. Such constant strings are replaced before compilation (also the constants to predefined paths, see File inclusions. The default paths constants) and may also express TEIMSI instructions. To declare them, the name of the variable must be preceded by a "º" character. As in the following examples:
ºthething==="Hello world!"+_nl+"Hola mundo!" ºfnc1===alert ºfnc1(ºthething)
This type of constants, are replaced before compilation but its content must respect the format accepted by the instruction "equ" used in assembler. This is because the compiler writes into the data section an assignment of a value to a constant.
When declaring the TEIMSI script:
ªstring==="Hello world!" ªnumber===8000
In the assembler data section appears:
ªstring equ "Hello world!"
ªnumber equ 8000
In this way it is possible to use visible constants to both compilers: TEIMSI and assembler.
The statement "eof_file" indicates the end of the root module and is used so like this (no spaces left with nothing on the right).
For the compiler, this line and the existing line that follows and its representation which is shown indicates the end of the whole project text. The compiler separates the text that it is not for him to do the work of creating the output executable, library or TEIMSI compiled object.
This instruction is useful for locating it then programmed texts, comments or text that the programmer wishes to incorporate into the project file.
TEIMSI program example:
alert("Hello") @eof_file >This text will not be interpreted by the compiler<
The "@import" statement allows you to add to the list of functions of the APIs Win.2000/XP/7/... imported a given function/s. The list of .inc files and libraries names (database) are defined in the "fasminclist" variable inside the "teimsicfg.ini" file located inside the TEIMSI's Editor folder, they describe the libraries to import. The "fasm_api_dir" variable indicates the path to the folder that has the .inc files, for example: "c:\fasm\include\api".
The following example program illustrates its usage:
@import:Sleep,GetTickCount var tickc=0 alert("Wait one second") _direct{ invoke Sleep, 1000 invoke GetTickCount mov [tickc+reg.vo], eax } alert("Done."+_nl+"TickCount = "+tickc) // Note: Sleep and GetTickCount functions are on the list of imported functions by default (from Kernel32.dll), such list // can be seen in the "import_dll.def" file of the "internal" folder inside the "engine" folder in the TEIMSI-editor's directory.
A program or library to be assembled comprises (by default) of various sections in its internal structure: the code section, the initialized data, the un-initialized data, the resource section (which may have data icons , binary strings from files, dialogs structures, specific information of the Exe or Dll object as "Copyright", Etc.) and the APIs imported functions.
To incorporate data variables into the assembler data sections, there are the instructions A) "place_idata", B) "place_udata" y C) "place_rdata".
A) place_idata, places variables or other assembler data in the initialized data section.
B) place_udata, places variables or other assembler data in the un-initialized data section.
C) place_rdata, places variables or other assembler data in the resources section.
Example Program:
place_idata{ str1asm db "Hello!",0 } place_udata{ str2asm db 10000 dup(?) ; Buffer about 10 "kilobytes" . } // The "icono.ico" file must be in the folder of the .tsi sample script being compiled. It will loaded as the program icon. place_rdata{ section '.rsrc' resource data readable directory RT_ICON,icons,\ RT_GROUP_ICON,group_icons,\ RT_VERSION,versions resource icons,\ 2,LANG_NEUTRAL,icon_data resource group_icons,\ 500,LANG_NEUTRAL,main_icon resource versions,\ 1,LANG_NEUTRAL,version icon main_icon,icon_data,'º_scriptdir_\icono.ico' versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_SPANISH+SUBLANG_DEFAULT,0,\ 'FileDescription','Example',\ 'LegalCopyright','Copyright (c) 3057 ? Rights reserved.',\ 'FileVersion','1.0',\ 'ProductVersion','1.0',\ 'OriginalFilename','example.exe',\ 'Comments','TEIMSI example.' }
The "_direct" instruction is used to place data, instructions and/or procedures into the program code section of the .exe or .dll file. When the flow finds the "_direct" block, the instructions there are executed, so if procedures are declared in the block; they must be preceded by a jump instruction (jmp) to a label declared after the text code of those procedures. The macro instruction "s_quit" stands for the instruction "sys.quit()" of TEIMSI (see Flow instructions) and it may be useful if you want express (in assembler code) that there ends the program flow. The macro "s_quit" only makes a jump to the termination of the program code and is the same instruction executed at the end of the whole TEIMSI code of a main project script.
Example of using "_direct"
place_idata{ str1asm db "This message is displayed from assembler, hello!",0 } place_udata{ str1pointer dd ? } _direct{ mov eax, (str1asm) mov [str1pointer], eax call2 funcasm_user, (str1pointer) ; The macro "call2" does what "invoke" but is used for functions that are not imported. jmp eofdirect1 proc funcasm_user, pointer2pointer ; Example of assembler procedure. locals asm_num dd ? endl mov [asm_num], 0 ; Example of local variable. mov esi, [pointer2pointer] mov esi, [esi] invoke MessageBox,0, esi, esi, [asm_num] ret endp ; funcasm_user eofdirect1: }
The TEIMSI procedures are also written as assembler procedures. That is, the statement "function" makes a statement "proc" and "endp" in the section of code with the same name of the function; it is possible to incorporate local variables to the assembler procedure from TEIMSI. The "_savelocal" statement is used for this, receives the list of local variables that are separated by "," (commas) Each variable includes on its right the data type ("dd" for 32-bit integers, "db" for "bytes", etc.).
The following program example shows the 503 integer and the path to the current directory from assembler:
@import:GetCurrentDirectory place_idata{ title db "Current directory:",0 } function tarea_n1(){ _savelocal: register dd ?, space db 256 dup(?) _direct{ mov [register], 504 dec [register] MOSTRAR2 [register] ; The "MOSTRAR2" predefined macro shows an integer/32bit register. lea eax, [space] invoke GetCurrentDirectory, 256, eax ; You can store a data string on the stack, because the "ss" register is same ; as the "ds" processor register by default (unless it's manually altered). lea esi, [space] invoke MessageBox,0, esi, (title), 0 } } tarea_n1()
The conditional compilation of TEIMSI code can be done with three instructions which must be declared with no spaces nor other instructions on its left:
Instruction | Description | |
---|---|---|
@cc_set(name_of_variable,value) | It sets the value of a conditional compilation variable, "name_of_variable" is the name of the variable and it must contain valid characters. The "value" parameter must also have valid variable name characters, but integer numbers are also allowed. | |
@cc_if(name_of_variable==value) | It tells the compiler to incorporate the text block of the Script placed between this instruction and the corresponding "@cc_endif" instruction only if the conditional compilation variable has the specified value. The conditional compilation variables do not interact with other types of variables. If the "name_of_variable" variable wasn't previously defined with "@cc_set" then it automatically takes the "undefined" value (without quotes), which can be evaluated with the "@cc_if(name_of_variable==undefined)" instruction. | |
@cc_if(name_of_variable!=value) | It does the same as the previous instruction but in case the variable does not have the specified value. | |
@cc_endif | This instruction is required only if it corresponds to some "@cc_if" instruction previously declared. | |
The following example program illustrates its usage:
@cc_set(LANGUAGE, english) @cc_set(SUBJECT, work) @cc_if(LANGUAGE==english) alert("The language is English.") includec(º_scriptdir_\english.thp) // Include a file according to the "LANGUAGE" conditional compilation variable. @cc_endif @cc_if(LANGUAGE!=english) alert("The language is not English.") includec(º_scriptdir_\nonenglish.thp) @cc_endif @cc_if(CONTENT==undefined) @cc_set(CONTENT, Text1) @cc_endif @cc_if(SUBJECT==work) alert("Subject: Work") @cc_endif @cc_if(SUBJECT!=work) alert("Subject: Is not Work") @cc_endif
Use the files with .tco type (TEIMSI Compiled Object), is a feature of this compiler that allows to store code instructions in the root module or procedures, data, references to imported functions and all element that can be expressed in a TEIMSI script. After including the Tco file with the instruction "include_tco" the code section that it contains will be included as if it were a file included with the "includec" instruction, the execution flow may be reach the included code (not TEIMSI functions) unless you skip it with a jump instruction like "jmp()" to a later label on the file or by placing the include instruction after the TEIMSI script has finished with the "sys.quit()" instruction.
The main advantages of using tco file are:
1- The compilation time of a project can be drastically reduced.
2- It allows you to organize and manage big projects of TEIMSI applications.
3- They have a text format that can be displayed (and changed if you are careful) containing also the included data sections and the TEIMSI code
assembler into assembler macro-instructions.
To create a TCO file, you must place the instruction "@tco_filename:<filename>". Being <filename> the name of the file with a .tco extension that will be created for the current script. To include a file Tco the "include_tco(<path_to_tco_file>)" instruction is used.
When creating a .tco, you can specify the public variables that will be required. To do this the instruction "@tco_reqrootvar:<variables>" where <variables> is a list of names of public variables (defined in the root module) separated by a comma (","). You can also specify which TEIMSI functions require to be defined before including the .tco file, for it use the instruction "@tco_reqfn:<functions>" where <functions> is a list of names of previously declared functions (or Tco imported from another file), each function name must be followed by the ":" character and an integer that indicates the amount of parameters received by such function; for example:
// The taskx and taskj functions used in Tco file, receive 3 and 2 parameters respectively:
@tco_reqfn:taskx:3,taskj:2
Also are the instructions "@tco_rem" and "@tco_eofrem" used to hold comments and the description of the file's content. For example:
@tco_rem:
<Comments block here>.
<...>
<...>
<...>
@tco_eofrem
The following example shows the usage of these instructions.
Example 1, compile the following script to create the .tco file:
; //##################################### @tco_filename:myobject.tco @tco_rem: > This tco file is an example that contains the "calculation(num)" function which calculates a square of a number by a coefficient. @tco_eofrem @tco_reqrootvar:coef_public @tco_reqfn:square:1 function calculo(num){ return (square(num)*coef_public) } alert("This message is being called from the file \"myobject.tco\"!") ; //#####################################
Example 2, compile the following script to display the inclusion and use of a .tco
; //##################################### var coef_public=0.01 function square(num){ return (num*num) } include_tco(º_scriptdir_\myobject.tco) // Includes the "myobject.tco" file previously compiled. alert("0.8*0.8="+calculo(8)) ; //#####################################