ALA7 language syntax

Copyright 2008 Maciej Bienias

When programming in ALA7 language, a programmer can use both static and dynamic types. Static types ensure better code quality (through type safety) and faster executable code. On the other hand dynamic typing gives more freedom to a programmer and is a chance to have shorter, more expressive code. This may result in more reliable, faster programs and in shorter development time.


Types:

type

For object type we have 32 bit pointer to object managed by base library. Objects are created, references are counted and finaly when reference count drops to 0 objects are automaticly deleted.

simple_type:

object_type:

Class types are defined by class definition.

class_definition:

class class_name

list of class_instructions


	class Cl1
		a1=0
		a2=””
		a3=[]

arrayC: arrayC_base_type [ array_size ]

arrayC_base_type: byte or char or int or float or int64 or float80

array_size :integer constant

struct_definition:

struct or union struct_name

list of instructions


  • type_name atribute_name
  • attribute_name = constant_value

As struct attribute only following types are allowed:

  • immediate_type
  • int64
  • float80
  • struct_type
  • arrayC
	struct St1
		a1=0
		a2=00h
		byte[8] arr1

Constant definition:

const const_name const_value

const_value:

  • byte constant: 00h, FFH
  • int constant :integer number 12, -2,000h,FFFFFFFFh
  • char constant 'a, 'A
  • str constant "xxxxxx"
  • list constatnt [] empty list, [ int or str constants separated by comma] :[1,2,"Ala"]
  • int64 constatnt hexadecimal number with more than 8 digits 200000000h
  • float constant integer number fullstop gigits: 1.0 , -2.0
  • const_expression for instance CONST1 + 1

	const CONST1 12
	const CONST2 CONST1+1

Variable declarations

All variables must be declared before they are used (however impilcit declaration by assignment is possible).

variable_declaration: type_name variable_names_separated_by_comma
or outer struct_type variable_name

	i=0
	s=""
	int i1,i2,i3

Assignment

left_value = expression

left_value:

  • variable
  • parameter_attribute

parameter_attribute:object_paramter_name one or more ( . class_attr_name )


variable:

  • simple_variable_name
  • object_variable_name
  • variable_attribute:object_variable_name one or more ( . class_attr_name )

Not all variables or parameters are allowed at left side of assignment.
At left side we can have variable or parameter of the left_value_type or outer struct_type variable.

left_value_type:

  • immediate_type (int, byte)
  • str
  • int64
  • float80
  • object_type

The same type at both sides or all type must be used.

	i1=3		#simple variable

	c1=c2		#object variable
	c1.a=1		#object variable c1 class attribute a
	c2.c1.s="Ala"	#object variable c2 class attribute c1 class attribute s

For types: byte, char, int, str operation simply makes copy, for list, mem, classes objects references are assigned

	l1=l2
  • dereference previous l1 objects
  • write l2 object reference to l1
  • increment l2 object reference count

expression:

  • constant
  • left_value
  • parameter
  • function_call
  • [] empty list
  • reminder reminder from divide operation
  • unary_operation expression
  • expression binary_operation expresion
  • expression one or more (add_sub_operation expression)
  • expression one or more (multiply_divide_operation expression)
  • parenthesized_expression
  • new_expression
  • type_id_expression
	i1=3		#constant
	i2=i1		#variable or parameter
	i2=cl1.i	
	i3=f3()
	lines=[]	#empty list
	i4=i3/i2;i5=reminder
	i=-i1
	i=i1+i2+i3+i4
	i=(i1+i2)*(i3+i4)

Base operations for int type:

  • - (one argument)
  • *, /
  • +, -
  • >>, >> shift left, right ,i >> 2 shift 2 bits left
  • neg (negate all bits)
  • & bit and
  • xand
  • | bit or
  • xor
	i1 = - i2
	i1 = i1 + i2
	i1 = (i1 + i2 ) *( i3 + i4)
	i1 = i1 >> 2 #shift two bits right

String and list operations

	s[i] 		get i element , indexes start at 0, c1=s[0] 
	s[i:j] 	sub, take elements start from i to j , excluding j: s="1234"; s1=s[0:]->s1 is "12"
	s[i:] 	from i to the end
	s[:j] 	from beginning to j, excluding j
	+ 		s1=s1+s2, s="12"+"34" ->"1234"

new operator

new_expression: new object_type_name
The new operator creates new object

	class A

	a= new list 
	a1= new A1

Class typeId

type_id_expression: fundamental_type_name .typeId or class_name .typeId

To get object type id we can use typeId function.

	class A
		a=0
	i=int.typeId
	i =A.typeId	 
	i=typeId(a)	 

Int64 assignments

  • int64_lv = int_expression
  • int64_lv = int_expression * int_expression
  • int64_lv = int64_lv + - * / int_expression
  • int64_lv = int64_lv + - int64_lv

Program layout

Instructions divided by end of line, in one line separated by ;

	x=1	#comment to the end of line 
	y=2
	z1=3; z2=4

When we want to continue line in next _ is used.

Instructions divided to blocks according to line indent.

	if x=1	block 1
		y=2 		block 2
		z=3		block 2
	x=2		block 1

Logical expressions

As logical_expression we have:

  • int value true if not 0, false if 0
  • str value true if not equal to empty string, false if empty string
  • variable in (constant list)
    if x in (1,2,3,4) 
  • comparison operations : =,!=, <>,<,>,<=,>=
     if x=2 
  • logical_operations

Logical_operations

  • not
  • and
  • or

int64 comparisons:

  • int64_lv comparison int_expression
    i64 <= i 
  • int64_lv comparison int64_lv
    i64_a = i64_b 

Program control

To control program flow if elif else, while, for are used.

if logical_expression : instruction_block
elif logical_expression :instruction_block
else:instr_block

if expression

instr_block

elif expression

instr_block

else

instr_block

if x=1 and y=2 : w=2;z=3
elif x=2 :w=3
else:z=4

if x=1 and y=2
	w=2
	z=3
elif x=2
	w=3
else
	z=4

while logical_expression

instr_block

for var = expr to expr optional step expr

	for i=1 to 12 -> 1,2,.. 11,12

for var_name in list_name
var_name must be unique in program unit.

	for e in l
		print(e)

Program structure

Program consists of modules. In modules we have constants, classes, functions, procedures and instructions

For instructions with no indent implicitly module main is assumed.

	const Co1 1 #first instruction from main module
	class Cl1
	p1()
	p2()
	f1()=
	f2()=

When we want define modules in main file:

	module m1
		const Co1 1
		class Cl1
		p1()
		p2()
		f1()=
		f2()=

	x=0 #first instruction from main module

Each program uses elements from base module for instance:

	print(var_name)

Functions and procedures

function_definition: optional return_type_name fun_name ( parameter_list ) =

Pay attention to equal sign = in function definition.

parameter_list: parameter_declaration divided by comma

parameter_declaration:

  • type_name parameter_name
  • [ list_subtype_name ] parameter_name
  • arrayC_base_type [ array_size ]

Last instruction must be return.

return_type:

  • immediate_type
  • direct_type
  • object_type
	int f( int x, int y)=
		z=x+y; return z

	int f1([int] p1) #declares parameter p1 as list of ints

	int f2(int[10] p2) #declares parameter p2 as arrayC od ints

As far as arrayC type is concerned then it is possible to use 0 as array size.
In such a case arrayC of any size will be passed as parameter, and it is programmer resposiblity co control index values,
for instnce using another parameter.

procedure_definition: proc proc_name ( parameter_list )

	proc p(int x, int y)
		print(x); print(y)

auxiliary_assembler_procedure : aux aux_name ()

function_call : left_value = function_name ( actual parameter list ) optionaly con

	x=2;y=3
	x=f(x,y)

procedure_call : procedure_name ( actual parameter list ) optionaly con

	p(x,y)

auxiliary_procedure_call : call aux_name

	call printRegs

When con is used function/procedure is passed to second processor core (option mt must be set in ide environment).

External dll procedure call

external_dll_procedure_call: call dll_name.function_name or call dll_name.function_name( actual_parameter_list)

when parameters are used pascal not c parameter passing sequence is used.

	hWnd=12
	call USER32.UpdateWindow(hWnd)

Late binding

	proc p1(int x)=..
	proc p1(str s)=.. function name p1 is overloaded
	l=[1,”Ala] first int than str value
	for e in l
		p1(e) 	e type unknown during compile, so parameter is bound during  code execution

Internal (built in) procedures


int addr(var_name): return address of variables
int ref(var_name): returns address of object referenced by variable 
int typeId(var_name): returns type id of variable
mem getMem(int size) : returns block of memory
Type copy(var_name): new object is created, all attributes are copied
	Class C1
	C1 c1; c2=copy(c1)

For lists
proc append(list_name,var_name): appends var to list
	l=[]; s=”Ala”
	append(l,s)

all pop(list_name)
	s=pop(l)

proc replace(list_name,index_var,new_item)
	replace(l,0,”Ala”) : list element 0 i replaced by “Ala”

proc replace(list_name,for_loop_variable_name,new_item)
	for e in l
		replace(l,e,”123”)

Classes


	class C1 		# class with 3 attributes: int_attr, str_attr, list_attr
		int_attr=0 	# initial value 
		str_attr=”Ala”
		list_attr=[]

	class C2
		id=0
		C1 attr_c1	#type_name:C1, attribute_name:attr_c1

	C1 c 			#variable c is declared as object of the class C1

Attributes are referenced by full stop(.)

	c.int_attr=12
	c.str_attr=”1234”
	append(c.list_attr,”12”)

	text=c.str_attr

	C2 c2
	c2.c1.int_attr=13

Gui

gui_class_names:

  • Window
  • Button
  • TextBox
  • ListBox
  • Static
  • ComboBox
  • TreeList
  • Control
  • CheckBox
  • RadioButton

gui_var_definition: gui_var_name = gui_class_name(parameter_list)

	window1=Window(....)

binding:

  • bind gui_var_name , event_id , handler_call
  • bind1 gui_var_name , event_id , subevent_id , handler_call

handler_call:

  • proc_name ( var_name )
  • proc_name ( var_name , systemEvent )

If we have more than one bind instruction for a gui_var then in handlers the same variable must be used.


	p1(Class1 c1)=..
	p2(Class2 c2, Event event)=..

	Class1 c1;Class2 c2
	
	bind window1,WM_SIZE, p1(c1)
	bind window1,WM_MOVE, p2(c1) #second bind instruction for window1 so as argument in p2, c1 must be used !!!!!!!

	bind window2, WM_SIZE, p2(c2,systemEvent)

	Where class Event
		msg=0
		wParam=0
		lParam=0

Mov instruction

mov destination , source

mov_instruction:

  • mov register_name or byte_register_name , immediate_type_left_value
  • mov register_name or byte_register_name , object_type_type_left_value
  • mov register_name addr left_value
  • mov register_name addr function_name
  • mov immediate_type_left_value , register_name or byte_register_name

register_name: eax or ebx or ecx or edx or edi or esi
byte_register_name:ah or al or bh or bl or ch or cl or dh or dl


	i=0
	mov eax, i

	mov ebx, addr f1

Inline assembling

asm assembler_instruction or $asm directive to switch on/off assembler codind
$asm is valid to the end of program unit (function or procedure).


	x=1
	asm mov eax,1

	$asm start of assembler lines
	mov eax, 2
	mov ebx, 3
	$asm end of assembler lines

	x=2

Global variables

global global_variable_name


	proc1:
		global main_window_hwnd;  main_window_hwnd=12
	proc2:
		global main_window_hwnd; int main_window_hwnd
		hwnd=main_window_hwnd

Modules

module module_name

module m1
	const C 1
	class Ala
		a=1
	proc p()
		x=1
	f()=
		return 1

$import module_name from file_name

file1.fsp:
	module m1
		const C1 1
		int f()=
			return 1
	int f1()=
		return 2
	x=1 	# here is first instruction of main module and program startup in file1.exe
	x=f() 	# compile first tries to match function name and parameters in current module
		# then in current file modules so f from m1 is found
file2.fsp:
	$import m1 from file1.fsp
	x=2	#program start in file2.exe
	x=f() 	#first current module searched, then current file, then imported modules
	print(x)	#print found in base.fsp that is searched at the end

Virtual functions

type_name virtual_fun_name ( type_name object_var , parameters_list ) = virtual

virtual virtual_fun_name ( object_var_name, type_names_list) = actual_fun_name ( type_names_list, additional_variables_list )
Additional_variables_list max length=3


	str getField(DataDrid dataGrid, int row, int col)= virtual 

dataGrid is an object_var, parameter_list:int row, int col (1)

	str newGrodField(int row,int col, Form form)
	DataGrid dataGrid; Form form1 

	virtual getField(dataGrid, int,int)=newGridField(int,int,form1) 

getField : virtual_fun_name
newGridField actual_fun_name
int, int : type names list fiting to (1): int row, int col
form1 : one element additional_variables_list, here one variable that we can pass to newGridField