TEIMSI
Developer's platform of programming text codes

TEIMSI compilation instructions

3)- @assumevar

11)- @eof_file

12)- @import:

13)- Data blocks

15)- _savelocal

Declaration of variables

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.


Go to top

Predefined variables

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 nameContent

_EThe "e" number of Euler: 2.71828182845...
_PIThe "PI" number: 3.1415926535898...
_NaNThe "NaN" number (Not real or "Not a Number").

_nlString chr(13)+chr(10)    //    Strings for general use.
_c0String chr(0)
_c1String chr(1)
_c2String chr(2)
_c9String chr(9)
_c10String chr(10)
_c13String chr(13)
_c34String chr(34)
_c39String chr(39)
_c44String chr(44)
_c47String chr(47)
_c92String chr(92)
_c64String chr(64)
_c124String chr(124)
_c126String chr(126)
_nulstrEmpty string: ""

_mb_okcancelInteger 1     //    Useful integers for the "alert_ex" function
_mb_abortretryignoreInteger 2
_mb_yesnocancelInteger 3
_mb_yesnoInteger 4
_mb_retrycancelInteger 5
_mb_iconerrorInteger 16
_mb_iconquestionInteger 32
_mb_iconexclamationInteger 48
_mb_iconinformationInteger 64
_mb_defbutton2Integer 256
_mb_defbutton3Integer 512
_mb_iconasteriskInteger 64
_mbret_yesInteger 6
_mbret_noInteger 7
_mbret_cancelInteger 2
_mbret_yesnoInteger 1
_mbret_abortInteger 3
_mbret_retryInteger 4
_mbret_ignoreInteger 5

_scolblackInteger 0     //    Useful integers for the "supercolorln" function of the file "tco_sources\bitmaps\supercolorln.thp"
_scolblueInteger 256
_scolgreenInteger 65280
_scolcyanInteger 65536
_scolredInteger 16711680
_scolmagentaInteger 16711936
_scolyellowInteger 16776960
_scolwhiteInteger 16777216

_sysboolInteger 0     //    Useful integers for the "itype" function
_syslongInteger 1
_sysdblInteger 2
_sysstrInteger 3
_sysarrInteger 4
_sysvarInteger 5
_sysvalidInteger 6
_sysfuncptrInteger 7
_sysundefInteger 8
_sysnullInteger 9
_sysInteger 10
_sysfuncInteger 11

_mod_statInteger 0     //    Useful integers for the "imode" function
_mod_dinaInteger 1
_mod_engiInteger 2

_move_absInteger 3     //    Useful integers for the "move" function of the file "tco_sources\click_move.thp"
_move_relInteger 2
_move_relptInteger 1
_move_relwinInteger 0

_numtype_dblInteger 2     //    Useful integers for the "number_type" function
_numtype_longInteger 1
_numtype_noneInteger 0

_tlyearInteger 0     //    Useful integers for the "timelong2arr" and "arr2timelong" functions
_tlmonthInteger 1
_tldayofweekInteger 2
_tldayInteger 3
_tlhourInteger 4
_tlminuteInteger 5
_tlsecondInteger 6

_waitkey_shiftInteger 4096     //    Useful integers for the "console_waitkeyex" function
_waitkey_ctrlInteger 2048
_waitkey_altInteger 512
_waitkey_bmayusInteger 32768
_waitkey_bnumInteger 8192
_waitkey_bdespInteger 16384
_waitkey_isdownInteger 0
_waitkey_scancodeInteger 1
_waitkey_asciicharInteger 2
_waitkey_ctrlkeystateInteger 3

Examples:





Go to top

@assumevar

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



Go to top

Path constants

Go to top

Flow instructions

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){

}else if(number==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++){

if(t==4){break}
}


Example 2:

			for(var k=-5,u=0; k<6 ; k++,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){
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:

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:
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()



Go to top

Declaration of procedures

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)

function ecuation1(parameter1){
return (24*91+parameter1*13)
}


Go to top

Pointer to function/public variable/label

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.


		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".
}


Go to top

File inclusions. The default paths constants

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).

ConstantContents

º_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_")


Go to top

## Declaration of constants

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(ºthething)


Go to top

Declaration of assembler extended constants.

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.

Go to top

@eof_file

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<


Go to top

@import:

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

_direct{
invoke Sleep, 1000

invoke GetTickCount
mov [tickc+reg.vo], eax
}

// 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.


Go to top

Data blocks

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{
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',\
'FileVersion','1.0',\
'ProductVersion','1.0',\
'OriginalFilename','example.exe',\
}


Go to top

Assembler code blocks

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:
}


Go to top

_savelocal

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()


Go to top

Conditional compilation instructions

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:

InstructionDescription

@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_endifThis 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)

includec(º_scriptdir_\english.thp)		//		Include a file according to the "LANGUAGE" conditional compilation variable.

@cc_endif

@cc_if(LANGUAGE!=english)

includec(º_scriptdir_\nonenglish.thp)

@cc_endif

@cc_if(CONTENT==undefined)

@cc_set(CONTENT, Text1)

@cc_endif

@cc_if(SUBJECT==work)

@cc_endif

@cc_if(SUBJECT!=work)

@cc_endif



Go to top

Creation and inclusion of TCO files

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:

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:

<...>

<...>

<...>

@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.