SIMPOL stands for Superbase International Multi-Platform Object Language. It is pronounced the same as the word "simple". SIMPOL was designed to be a modern replacement for the Superbase Basic Language (SBL). While SBL has over 270 keywords that can then be combined in different ways and with various parameters, SIMPOL has only about 20 keywords of which only about 10 are regularly used. Everything else in SIMPOL is an object. http://www.simpol.com/faq.html Simpol is produced by Simpol Limited is a company registered in England and Wales with company number 04759852. Example programing A program in SIMPOL is made up of functions. The normal entry point to a program is the function called main(). The most basic possible SIMPOL program is: function main() end function Consider the following program: function main() string s s = "Hello world" end function s The first statement, string s, defines a local variable called s. The second statement, s = "Hello world", assigns the value "Hello world" to the local variable s. However there is more to the assignment than it might at first appear. Local variables do not hold values, they refer to objects, and it is objects that contain values. In the above program the assignment to s of the string literal "Hello world" causes a new string object to be created, the string literal value is put in the new object and the local variable s is set to refer to that object. Constants There are three kinds of constant values in a SIMPOL program, string literals, numeric literals and intrinsic constants. String literals can be delimited by either single or double quotes, but the ending delimiter must match the starting delimiter. This allows single and double quotes to be used in strings without any special escape sequences, e.g.: "Can't" or 'Fred said "no"'. Numeric literals can be specified in one of several bases by starting them with a leading zero and then a base indicator letter, e.g.: 0d100 (decimal), 0xff (hexadecimal), 0o377 (octal) or 0b11001101 (binary). If no leading zero and base indicator are found then the number is assumed to be decimal. Intrinsic constants are identifiers that have a single fixed value. The permitted constants are .nul (the null value), .inf (infinity), .true (the boolean true value) and .false (the boolean false value). A function can return a value by specifying that value after the end function that terminates the function, for example: function main() end function "The end of the program" or function main() string s s = "Hello world" end function s If no return value is specified then the return value is the null constant, .nul. A function can be called from within an expression, and may take parameters in the normal way, for example the following program will have a final return value of 15: function main() integer i i = 5 i = i + double(i) end function i function double(integer i) end function i+i Function Parameters Function parameters can be named and take a default value. Actual parameters supplied when the function is called can be specified by name, and if not specified at all will take the default value. When passing parameters to a function named parameters are resolved and passed first, and then unnamed actual parameters are passed to the unused function parameters from left to right. Finally any unpassed parameters are set to their default values, or if none is specified unused parameters are set to .nul. For example, the following program produces a result value of: x abc, y function main() end function x_and_y(x = 'abc') function x_and_y(string x '', string y \ '') end function "x = " + x + ", y=" + y Also, the next program produces a result value of: x xyz, y , z = uvw function main() end function x_and_y_and_z(z = 'uvw','xyz') function x_and_y_and_z(string x '', string y \ '', string z = '') end function "x = " + x + ", y=" + y + ", z= " + z Functions, types and local variables all have names, and parameters can be named. In order to be valid a name must start with a letter and all other characters in it must be a letter, a digit or an underscore Statements Within a function SIMPOL is made up of statements. Typically a statement will occupy a single line within the source code, but more than one statement can be placed on one line by separating them with semi-colons (;) or colons (:). Also it is possible to break a statement into more than one line; the backslash (\) character is used to indicate that the following line is a continuation of the current one, but is only valid if it is the last non-white-space character on the line. Intrinsic Functions In order to manipulate values SIMPOL provides intrinsic functions. These are functions whose parameters are unnamed and must all be supplied. The return from an intrinsic function is some other value, which depends on, and only on, the parameter values. For example the .len() function takes a single string parameter and returns the number of characters it contains. As another example, the .tostr() function takes two numeric values, the first being a value to be represented as a string and the second being the base to use, e.g.: .tostr(13,2) returns '1101', or .tostr(123456,10) returns the string '123456'. Operators In addition to intrinsic functions there are operators which work on one or more parameters. Common examples of these are the addition operator +, the unary negation operator - which converts a value to its opposite, in some sense depending on the value type, and the comparison operators, ==, < etc., which return a boolean value that depends on a comparison between the left and right operands. It should be noted that operators operate on values, not objects. For example the code: integer i integer j i = 3 j = - i does not change the value in the object referred to by i from 3, it takes the value from that object, negates the value only, and assigns the result to j. Complex Object Types The object types that are also value types, such as string or boolean, exist primarily to hold values of that type. More complicated types exist either to provide information to the program, or to allow the program to do something. For example the fsfileinputstream type is used to read data from a file in a file system (such as on disk or over a network). With the simple value types an object is created for a local variable to refer to when an assignment is made to that local variable, as in the string s;s = 'Hello world' example earlier. With non-value types this is not the case — it is necessary to explicitly create these objects, normally using a new() function. The following example creates an input stream to read from the file c:\autoexec.bat: function main() fsfileinputstream f f =@ fsfileinputstream.new("c:\autoexec.bat") end function The =@ operator in this example is an important one which caused the local variable f to be set to refer to the object on the right hand side of the operator. This should be contrasted with the = operator which instructs the value on the right hand side to be assigned to the object referred to by the local variable on the left. As a rather pedantic yet instructive example, the following program has a resulting value of 1: function main() integer i integer j i = 1 j = i i = 3 end function j whereas the following program produces a result of 3: function main() integer i integer j i = 1 j =@ i i = 3 end function j The difference is that j i assigns to the integer object referred to by j the value of the integer object referred to by i, whereas j @ i causes both i and j to refer to the same integer object, so when a value is assigned to i it is setting the value of the object to which j refers. The input stream is destroyed (closing the file) when the local variable f is destroyed, at the end of the function. In the case of an input stream, the parameters that have to be passed to a new function depend on the type of object being created, in this case only the filename is required. Object types also have properties, which are either embedded objects of other types or references to other objects. For example the fsfileinputstream type has a property called filename of type string, which contains the name of the file being read. Extending the previous example slightly gives a program the result of which is the value 'c:\autoexec.bat': function main() fsfileinputstream f f =@ fsfileinputstream.new("c:\autoexec.bat") end function f.filename Object types can also have member functions, or methods, which are functions that do something with or to the object. For example the fsfileinputstream type has a member function called getstring, which can be used to read a string from the input file. The following program has a return value that is the first line of the c:\autoexec.bat file. The exact syntax for member functions such as getstring is type and function dependent, and can be found in the language reference. function main() fsfileinputstream f f =@ fsfileinputstream.new("c:\autoexec.bat") end function f.getstring(.inf,1,.true,.char(13)+.char(10)) Flow Control There are flow control constructs in SIMPOL that are similar to many other languages. The if … else if … else … end if construct is straightforward: if (i == 3) j = 5 else if (i == 4) j = 6 else j = 7 end if In some cases the .if() intrinsic function provides a better alternative to the if construct. The while … end while can have conditional expressions at the beginning or the end, or both. The contained block will be entered if the initial expression is absent or is considered to have passed. At the end of the block control will return to the first test if the final condition is absent or is considered to have failed. The end while condition should therefore be thought of as an end while if type of expression. For example the following kind of loop could be used to process the lines in an autoexec.bat file: fsfileinputstream f string line boolean error f =@ fsfileinputstream.new("c:\autoexec.bat") error = .false while (f.endofdata == .false) line = f.getstring(.inf,1,.true,.char(13)+.char(10)) … <process the line maybe setting error to true if an error is encountered> … end while (error == .true) Variable Typing SIMPOL is what is known as a strongly typed language. By this is generally meant that it is considered an error to assign an object or value of one type to a variable of another type. As an example, if I have one variable that is declared to be of type integer it is an error to assign a variable of type number to that variable. It will result in a type mismatch error. This is one way that the programming language protects the programmer from making an error that might otherwise be very hard to find. If instead of generating an error, the programming language automatically converted the variable of type number to an integer value, truncating or rounding the non-integer portion of the value, it would be very difficult to track down, especially in a large program since the problem may only appear to be intermittent (it would only occur when the value in the variable of type number was not an integer value). Additional References http://www.simpol.com/docs/langref/index.html
|
|
|