3 IRONSEED language reference
3.1 Abstract
Ironseed is a general-purpose crossplatform binary version-compatible programming language, also an answer to Microsoft's COM technology but without limitations of later. It uses late symbol linkage to avoid vtable id crashes instead of MS's method "Just do not edit code and it's vtable ids won't change". Among other highlights there are signals and (planned) templates and cross-platform bytecode compileable to native.
3.2 IRONSEED Syntax
Syntax of Ironseed language is near (but not equal) to C/C++/Java. An ironseed program consists of a number of class and function declarations, and member method and function implementations. Ironseed takes heavy usage of packages (or namespaces) and an indentifer usualy consists of a number of simple identifiers (alpha-numeric with leading alpha) separated by double colon '::'. For example, a main function (which will be run at program start) is named 'main'. For user convinices there are StartUsing and EndUsing commands which add and remove package to search list, and ability to explicate a package name by adding double colon at start, for example '::std::string'.
Implementation part mostly consists of statements, which can be groupped using curly brackets. In this small example, we declare main function printing 'Hello, world !' three times.
helloworld.is
#include <vector.ish>
#include <string.ish>
#include <kernel.ish>
int32 ::main(::std::vector args)
{
	std::print("Hello, world !\n");
	std::print("Hello, "+"world !\n");
	std::printf("Hello, %s !\n","world");
}
		
There are following data types in Ironseed allowed: simple types (integer, floating point, boolean), object references and enums. Objects automaticaly count number of references and are automaticaly destroyed on zero references so you have no need in garbage collecting. To solve cross-reference problem there are on_delref() and std::weakref available.
3.3 Running ironseed programs
At this moment, ironseed compiles programs to dynamic libraries and you need a (really small) ironrun program which loads given library into memory and starts ::main(::std::vector) function. This program is linked against libIRONSEED dynamic library which contains all C functions needed to resolve ironseed classes and functions and to load dependent libraries.
3.4 Language constructs (preprocessor)
Ironseed preprocessor is in developement stage and will possibly change alot, but at this moment it is very alike to C preprocessor. It understands #define, #include, #ifdef and #ifndef constructs.
3.4.1 #include construct
#include works exactly the same way as in C. It adds contents of destination file in place if itself. If file name is given in double quotes, it's full destination path is compiled from current directory, while if it is given in lighter-greater signs, then full destination path is compiled using search paths.
  Against some C compilers, if name is given in double quotes it is never searched in search paths and vice verca, for lighter-greater signs it is never searched in current directory (unless you add current directory to search path using compiler options).
3.4.2 #define construct
#define works nearly as in C, but (at this moment - dont know how it will do later) can come upon infinte recurse.
define_recurse.is
#define A B
#define B C
#define C A
A
			
In this example, it will run into infinite recurse at the last line.
3.4.3 #ifdef, #ifndef, #else, #endif constructs
As always the same as in C.
ifdef_example.is
#ifndef MYMODULE_ISH
#define MYMODULE_ISH
/* Here are some declarations */
#endif
			
3.5 Language constructs (compiler)
Ironseed is much like C, but (of course) not without important differences.
3.5.1 Comments
comments_example.is
/*
	This is multiline comment
*/

// This is single line comment
			
3.5.2 Declarations
3.5.2.1 Packages
Packages can be declared or pre-declared. They are proposed for user convinience and are somewhat alike C++'s namespaces and perl packages. All standart classes and functions are placed in std, std::io, std::gui, std::dbi and etc. packages. Speaking about compiler guts, a function printf located in std package is realy a ::std::printf function, same as a file class located in std::io package has real name ::std::io::file. For user convinience there are StartUsing and EndUsing keywords which add a namespace prefix to search list. A '::' namespace is always added to search list, so you have no need to add double colon at the start of class or function name.
package_example.is
package std;
package std {
	// Declaring something in package std
	class vector;
};
package std::io {
	// Declaring something in package std::io
	class file;
	class test;
};

class test;

// Adding std::io to search list
StartUsing std::io;

// We did not added std package to search list,
// so we have to use full name
int32 main(std::vector args)
{
	// We can use full name
	std::io::file f1;
	// Or short name (since we added std::io to search list)
	file f2;
	// ERROR! We can not use test since compiler will not understand
	// which class we mean.
	test t1;
	// OK, using full path
	std::io::test t2;
	// OK, using explicit naming
	::std::io::test t2;
	// OK, using explicit naming
	::test t3;
}
				
3.5.2.2 Enums
Enums be enums - not much to tell about them.
  At this moment enums are strictly represented as int32, but this can change at release point.
3.5.2.3 Functions
Same as in C, you can declare or implement function. The only difference is that declaring a function you must prefix it with 'extern' keyword.
functions_example.is
#include <string.ish>
// Declaring function
extern int32 print(::std::string);

// We can do it multiple times - nothing will happen
extern int32 print(::std::string);

// Function implementation
int32 main(std::vector args)
{
	print("Hello, world!\n");
}

// ERROR! We can not have multiple implementations
int32 main(std::vector args)
{

}
				
3.5.2.4 Classes
Among other data types, classes changed most in Ironseed. First, classes do not have multiple inheritance - see mclasses. All methods within class are always virtual so you will always be able to make an ancessor with some methods replaced or modified. Constructors and destructors are named plainly as 'constructor' and 'destructor'.
classes_example.is
class cl1: std::object {
public:
	void constructor(void);
	void destructor(void);
	void m1(void);
	void m2(void);
};

class cl2: cl1 {
public:
	void constructor(void);
	void destructor(void);
	void m1(void);
	void m3(void);
};
				
All data members are private, so if you want to allow access to them from external code, you must use 'access' directive to attach functions responsible for data reading and writting. External code stands for all functions (except this class's constructor and destructor) and methods of ancesstors - i.e. it is all except strictly this class's methods, constructor and destructor.
classes_access.is
class myclass: std::object {
public:
	void constructor(void);
	std::string get_str(void) const;
	void set_str(std::string v);
	void m1(void);

	std::string str;
	access str OnRead get_str, OnWrite set_str;
};
class myclass2: myclass {
public:
	void constructor(void);
	void destructor(void);
	void m1();
	void m2();
}

void myclass::constructor(void)
{
	str="MyString";// Accessed directly
}

std::string myclass::get_str(void) const
{
	return str->clone();// Accessed directly
}

void myclass::set_str(std::string v)
{
	str=v->clone();// Accessed directly
}

void myclass::m1(void)
{
	str="";// Accessed directly
}

void myclass2::constructor(void)
{
	str="MyString2";// set_str("MyString2") called instead
}

void myclass2::m1(void)
{
	str="aaa";// set_str("aaa") called instead
}

void myclass2::m2(void)
{
	str=str+"aaa";// set_str(get_str()+"aaa") called instead
}
				
3.5.2.5 MClasses
MClasses are classes with multiple inheritance allowed, but at this moment they are heavy TODO.
3.5.2.6 Constructors
3.5.2.7 Destructors
3.5.2.8 Methods
3.5.3 Statements
  This chapter describes statements as they should be rather then what they are at this precise moment - for a level of implementation see source files.
3.5.3.1 ExpressionStatement
Expression statement is just an expression followed by ';' (semicolon) sign.
expression_statement.is
a=b*sin(x);
printf("Hello, world\n");
				
3.5.3.2 IfStatement
This statement syntax is equal to C++ syntax. After keyword 'if' there is an expression in round brackets, a statement and optionaly an 'else' keyword with second statement. If expression in brackets is 'true', then first statement is executed, else executed second statement (if exist). To allow multiple statements to be executed group them using BlockStatement. Note on compiler: If stumbled upon shift/reduce conflict (as shown in example below) the option is 'shift'.
if_statement.is
// Simple IF
if (a!=0) print("a is not zero\n");
// IF with else option
if (b==0) print("b is zero\n"); else print("a is NOT zero\n");
// IF with BlockStatement as statement
if (b==0) {print("b");print(" is");print(" zero\n");}
// IF with shift/reduce conflict
if (b>0) if (b>10) print("b is big\n"); else print("b is small\n");
// The later is equal to
if (b>0) {if (b>10) print("b is big\n"); else print("b is small\n");}
				
3.5.3.3 WhileStatement
This statement's syntax is equal to C++ as well.
3.5.3.4 ForStatement
This statement's syntax is equal to C++ as well.
3.5.3.5 ReturnStatement
This statement's syntax is equal to C++ as well, but with one caveeat for those who are interested in how ironc works: before issuing real 'return', all object variables are del_ref'ed while since we dont want a varible to return to be deleted we call a set_nodestructorcall function before.
3.5.3.6 VarDeclarationStatement
This statement's syntax is similar to C++ but at this moment you can not initialize vars within it. The syntax is as follows: data type followed by one or more identifiers separated by commas and terminated with semicolon.
var_statement.is
uint32 a;
double b;
std::string c;
				
3.5.3.7 BlockStatement
This statement's syntax is equal to C++ as well.
3.5.3.8 AlertStatement
This statement should be used for debuging/error printing purposes. It works similar to print function, but displays file and function names and string number as well. Alert syntax is the same if you called a function with two optional parameters 'body' and 'header'. If program makes use of GUI it will be possible to create popup error messages instead of printing to stderr.
alert_statement.is
alert();// Will output filename, function name and string number.
alert("Does not work");// Will output 'Does not work' message either.
alert("Does not work","Error");// Will have a header also.
				
3.5.4 Expressions
3.6 Language constructs (ironC)
IronC is a low-level implementation of ironseed model. This pseudo-language (it is not even a language) is been converted to even more unreadable form (but usable by C compiler) by ironC compiler.
The language has nearly zero security checks and is used to create implementations of ironseed's methods and functions in C. Ironseed compiler works the same way - it just creates ironC code which is later processed by ironC compiler.
3.6.1 add_ref()
add_ref() and del_ref() functions are the most important ones in automatic garbage removal concept. This concept allows program to clear it's memory and delete objects whenever there is noone who tracks a reference to them (in this case you would not be able to gain a reference back to an object so why would you need it?). To make this work, programmer must increase reference count each time he creates a new reference to an object (unless this is a weak reference or he knows what he is doing) and similary decrease reference count each time he is about to remove a reference. After each decrease he must check reference count versus zero to check if anyone references this object, and if none, then call object's destructor and then free memory used (this is only a brief but close to reality view at this matter). See also del_ref_if(), add_ref_if() and set_nodestructorcall() functions.
To automate this process, there are ironseed's C core level add_ref() and del_ref() functions.
3.6.2 del_ref()
For matters of creation see add_ref() description. del_ref() function accepts a pointer to object pointer (it is done due to that del_ref() would be able to set object pointer to zero after object destruction). Function's algorithm is as follows:
1) Decrease reference count for object
2) Call on_delref() method of this class if it is implemented and it is not in progress
(Following points are done if reference count is zero)
3) Check if object's flag no_destructorcall is set to true, then set it to false and return (no more points is executed)
4) Call destructor
5) Call event remover [TODO]
6) Ennull weak pointers connected to object (See ::std::weakref class)
7) Free used memory
8) Set pointer to NULL
ironc_call1_example.ic
object *mystr;
#assign mystr ::std::string
mystr=object_create(RTTI(::std::string));
PCALL[void ::std::string::constructor(wchar_t*)](mystr,L"Hello, World");
add_ref(mystr);
....
del_ref(&mystr);
// At this point mystr==NULL (!)
			
3.6.3 CALL[...](...)
This construct is used to make a function call. This is done instead of standart call due to the following facts: a) So that programmers would be able to create a multiple functions with same name but different parameters, b) Because none of ironseed structures have any alternatives in C except then void*, and c) to check parameters' constantness and return value type. The latter comment is the most important one: imagine you created a function which returns a string, and some time after you changed it to return some other object. C++ dynamic loader will not feel the difference since it does not check types, but in ironseed you will get a core error which would tell that additional information of this function in program and library differs.
To make a function call you need to specify a function name and parameter types in square brackets and give optional parameters in round brackets.
ironc_call1_example.ic
object *myobj;
int32 size;
....
size=CALL[::std::printf(::std::string,::std::vector)](mystr,myvec);
if (myobj!=NULL) del_ref(&myobj);
myobj=CALL[::std::sprintf(::std::string,::std::vector)](mystr,myvec);
add_ref(myobj);
			
3.6.4 CALL<...>[...](...)
3.6.5 PCALL[...](...)
3.6.6 PCALL<...>[...](...)