ebook img

Seed7 Programming Language Manual PDF

190 Pages·2019·0.795 MB·
Save to my drive
Quick download
Download
Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.

Preview Seed7 Programming Language Manual

Seed7 Manual 1. Introduction 2. Tutorial 3. Declarations 4. Predefined Statements 5. Predefined Types 6. Parameters 7. Object Orientation 8. File System 9. Structured Syntax Definition 10. Tokens 11. Expressions 12. Operating System Access 13. Primitive Actions 14. Foreign Function Interface 15. Errors 1 Introduction 1.1 What is Seed7? Seed7 is a general-purpose programming language. It is a higher level language compared to Ada, C++ and Java. In Seed7 new statements and operators can be defined easily. Functions with type results and type parameters are more elegant than the usual template or generics concept. Object orientation is used when it brings advantages and not in places when other solutions are more obvious. Although Seed7 contains several concepts of other programming languages it is generally not considered as a direct descendant of any other programming language. The programmer should concentrate on problem solving instead of administration or the fulfillment of some paradigm. Therefore Seed7 allows programming in the "problem space" instead of bending everything into a small syntactic or semantic concept. The predefined constructs of Seed7 are defined in a way to be easy readable and understandable. This practical approach can be summarized as: Programming should be fun Seed7 programs can be interpreted or compiled. Therefore Seed7 can be used for scripting and for "real" programs. 1.2 Why a new programming language? Conventional programming languages have a firmly given syntactic structure. The form of the statements, operators, declarations, procedures and functions is fixed in the language definition and cannot be changed by the user. It is only possible to declare new procedures, functions and in some languages also new operators. However the syntax of procedure-, function and operator calls cannot be changed. Although this rigid pattern is favorable for the portability of programs, the improvement of a programming language is almost impossible. Extensions are however desirable, in order to repair existing weaknesses, to introduce new more obvious constructs and to adapt the programming language to different application areas. E.g.: In the area of mathematics the readability of a program can be substantially increased by the introduction of matrix and vector operators. After declaring an inner product and an outer (or cross) product for vectors it is possible to write e.g. v1: = v2 cross v3; write(v1 * v2); Programs which search for some data in a database can become more understandable by using a for statement to loop over the tables. A usage of such a for statement could be: for person1, person2 where person1.age = person2.age and person1.mother = person2.mother and person1 <> person2 do writeln("Twins: " <& person1.name <& " and " <& person2.name); end for; Such extensions make understanding, changing and debugging of a program easier. 1.3 Features of Seed7 Seed7 has the following features User defined statements and operators. l Types are first class objects and therefore templates and generics can be defined easily without special l syntax. Predefined constructs like arrays or for-loops are defined in the language itself. l Object orientation is based on interfaces, supports multiple dispatch and allows to connect methods to l objects. Static type checking and no automatic casts. l exception handling l overloading of procedures/functions/operators/statements l Various predefined types like resizable arrays, hashes, bitsets, structs, etc. l But a new programming language differs not only from existing ones by new features. The real advantage comes from omitting features which are outdated. Several concepts in use by other languages are not present There is no goto statement. Hidden gotos like break- and continue-statements are also omitted. l There is no return statement. Instead a result variable can be defined to which the result of a function can l be assigned. There are no automatic type conversions. When a subprogram should be used for different types it must be l overloaded. There are no variable length parameter lists. Instead it is possible to use arrays as parameters. l There are no default parameters. But it is easy to define two subprograms: One with and one without an l additional parameter. There is no special "parameter" called "self" or "this". In a procedure the receiving object is defined as l formal parameter with a user-defined name. There is no macro feature since this mechanism is too similar to the subprogram feature. Instead l subprograms can be used in a more flexible way than in other languages. There are no reserved words. l There is no conceptual distinction between functions, operators, procedures and statements. l The procedure calling mechanism is not based on a concept with an object-message pair (An object l receives a message). Instead a match is done over a list of objects. This more general (and powerful) mechanism is called multiple dispatch and it includes the simple object-message mechanism as special case. There are several concepts which are also used by other languages: Block comments start with (* and end with *) and may be nested. l Line comments start with # and are terminated with the end of the line. l There are several concepts which are new Variables and constants must be initialized when they are defined. l Every expression has exactly one type. That means that overloaded functions are resolved with their actual l parameters and not with the context of their call. (This is different to the overloading mechanism used by ADA) With a syntax declaration new operators and statements can be defined. l Not only predefined operator symbols can be overloaded. Additionally it is possible to invent completely l new operator symbols. Several restrictions of other languages are released There is no limitation in the length of an identifier and all characters of an identifier are significant. l Statements and parentheses can be nested without limitation in depth. l The number of parameters and local variables is not limited. l Strings can contain any characters (also the NUL character) This allows holding binary information in l strings. Although strings are not NUL terminated they have no size limitation. (Except there is no more memory) l String literals can have any length. l There is no limitation in the length of a source line. l There is no level limitation for nesting includes. l 1.4 How to read the manual You can have several views of the Seed7 programming language. Dependent on the view you can concentrate on specific chapters. For example Seed7 can be used as conventional programming language. In this case you are interested in how the statements look like, which types are available, which operators are predefined, how to declare variables and procedures and other things like these. The statements and the predefined types are described in chapter 4 (Predefined statements) and chapter 5 (Predefined types) and the declaration mechanism is described in chapter 3 (Declarations). But Seed7 is also an object oriented programming language. In this case you are interested in how to define new classes, how instances are generated, the method calling mechanism, the predefined class hierarchy and other things like these. The object orientation of Seed7 is described in chapter 7 (Object orientation). A good example for classes and instances is the file system which is described in chapter 8 (The file system). And Seed7 is also an extensible programming language. In this case you are interested in how to declare new statements, how to define new operators, assigning a priority and an associativity to operators and other things like these. An overview about syntax declarations can be found in Chapter 3.2 (Syntax declarations). A detailed description of the Seed7 syntax definitions can be found in chapter 9 (Structured syntax definition). Chapter 4 (Predefined statements) contains various examples of syntax and semantic declarations. The basic parts of the syntax are described in chapter 10 (Tokens) and chapter 11 (Expressions). 2 Tutorial We begin with a tutorial introduction to Seed7. In this chapter we want to show the principal ideas that make Seed7 work. At this point, we are not trying to be complete or precise. We just want to give a clear view to the primary philosophic ideas of Seed7. When the primary ideas are understood a complete and precise reference can be learned easier. 2.1 Hello world A Seed7 program consists of a sequence of declarations. With each declaration a type and a name is attached to the new object. In addition every new declared object gets an initial value. Here is an example of an object declaration: const proc: main is func begin writeln("hello world"); end func; The object 'main' is declared as constant and proc is the type of 'main'. Declaring 'main' with the type proc makes a procedure out of it. The object 'main' gets a func ... end func construct as value. The 'func' construct is similar to begin ... end in PASCAL and { ... } in C. Inside the 'func' is a writeln statement with the "hello world" string. The writeln statement is used to write a string followed by a newline character. To use this declaration as the standard hello world example program, we have to add a few things: $ include "seed7_05.s7i"; const proc: main is func begin writeln("hello world"); end func; The first line includes all definitions of the standard library. In contrast to other standard libraries the seed7_05.s7i library contains not only function declarations but also declarations of statements and operators. Additionally the seed7_05.s7i library defines the 'main' function as entry point for a Seed7 program. If you write this program in a file called hello.sd7 and execute the command s7 hello The Seed7 interpreter writes something like SEED7 INTERPRETER Version 5.0.4 Copyright (c) 1990-2013 Thomas Mertes hello world You get information about the Seed7 interpreter and the output of the world.sd7 program: hello world The the option -q can be used to suppress the line with information about the Seed7 interpreter: s7 -q hello 2.2 Local declarations and expressions To write a Fahrenheit to Celsius conversion table we use the following program: (* Print a Fahrenheit-Celsius table for Fahrenheit values between 0 and 300 *) $ include "seed7_05.s7i"; const proc: main is func local const integer: lower is 0; const integer: upper is 300; const integer: increment is 20; var integer: fahr is 0; var integer: celsius is 0; begin fahr := lower; while fahr <= upper do celsius := 5 * (fahr - 32) div 9; write(fahr); write(" "); writeln(celsius); fahr := fahr + increment; end while; end func; Everything between (* and *) is a comment, which is ignored. This program contains local constants and variables of the type integer. The constants and variables must be initialized when they are declared. This program contains also an assignment, a while-statement and the expression to compute the 'celsius' value. Note that the statements inside the while-loop are between 'do' and 'end while'. The expression to compute the 'celsius' value uses an integer division (div). The 'write' statement can be used to write strings and integers without a newline character. The output produced by this program is 0 -17 20 -6 40 4 60 15 80 26 100 37 120 48 140 60 160 71 180 82 200 93 220 104 240 115 260 126 280 137 300 148 2.3 For loop and float expressions An improved version of the program to write the Fahrenheit to Celsius conversion table is: $ include "seed7_05.s7i"; include "float.s7i"; const proc: main is func local const integer: lower is 0; const integer: upper is 300; const integer: increment is 20; var integer: fahr is 0; var float: celsius is 0.0; begin for fahr range lower to upper step increment do celsius := flt(5 * (fahr - 32)) / 9.0; writeln(fahr lpad 3 <& " " <& celsius digits 2 lpad 6); end for; end func; To use the type float it is necessary to include float.s7i. The float variable 'celsius' must be initialized with 0.0 (instead of 0). The for-loop is written as: for ... range ... to ... step ... do ... end for To specify a lower and an upper limit together with a step value. For a step value of 1 the for-loop it is written as: for ... range ... to ... do ... end for And for a step value of -1 it can be written as: for ... range ... downto ... do ... end for Since Seed7 is strong typed integer and float values cannot be mixed in expressions. Therefore the integer expression '5 * (fahr - 32)' is converted to float with the function flt. For the same reason a '/' division and the value '9.0' must be used. The <& operator is used to concatenate elements before writing. If the right operand of the <& operator has not the type string it is converted to a string using the 'str' function. The lpad operator converts the value of 'fahr' to a string and pads spaces to the left until the string has length 3. The digits operator converts the value of 'celsius' to a string with 2 decimal digits. The resulting string is padded left up to a length of 6. 2.4 Parameters Most parameters are not changed inside a function. Seed7 uses 'in' parameters to describe this situation: const func integer: negate (in integer: num1) is return -num1; const func integer: fib (in integer: num1) is func result var integer: fib is 1; begin if num1 <> 1 and num1 <> 2 then fib := fib(pred(num1)) + fib(num1 - 2); end if; end func; The functions above use 'in' parameters named 'num1'. An assignment to 'num1' is not allowed. A formal 'in' parameter like 'num1' behaves like a constant. Trying to change a formal 'in' parameter: const proc: wrong (in integer: num2) is func begin num2 := 0; end func; results in a compile time error: *** tst77.sd7(5):52: Variable expected in {num2 := 0 } found parameter (in integer: num2) num2 := 0; When a function wants to change the value of the actual parameter it can use an 'inout' parameter: const proc: reset (inout integer: num2) is func begin num2 := 0; end func; If you call this function with reset(number); the variable 'number' has the value 0 afterwards. Calling 'reset' with a constant instead of a variable: reset(8); results in a compile time error *** tst77.sd7(12):52: Variable expected in {8 reset } found constant integer: 8 reset(8); Sometimes an 'in' parameter is needed, but you need to change the formal parameter in the function without affecting the actual parameter. In this case we use the 'in var' parameter: const func string: oct_str (in var integer: number) is func result var string: stri is ""; begin if number >= 0 then repeat; stri := str(number mod 8) & stri; number := number mdiv 8; until number = 0; end if; end func; As you can see this works like a combination of an 'in' parameter with a local 'var'. Conventionally there are two kinds of parameters: 'call by value' and 'call by reference'. When taking the access right (constant or variable) into account we get the following table: parameter call by access right val value const ref reference const in val / ref const in var value var inout reference var Additionally to the parameters we already know this table describes also 'val' and 'ref' parameters which use 'call by value' and 'call by reference' and have a constant formal parameter. The 'in' parameter is called by 'val / ref' in this table which is easily explained: An 'in' parameter is either a 'val' or a 'ref' parameter depending on the type of the parameter. The parameter in integer: number is a 'val' parameter which could also be declared as val integer: number while the parameter in string: stri is a 'ref' parameter which could also be declared as ref string: stri The meaning of the 'in' parameter is predefined for most types. Usually types with small amounts of data use 'val' as 'in' parameter while types with bigger data amounts use 'ref'. Most of the time it is not necessary to care if an 'in' parameter is really a 'val' or 'ref' parameter. In rare cases a 'ref' parameter would have undesired side effects with global variables or other 'ref' parameters. In these cases an explicit 'val' parameter instead of an 'in' parameter makes sense. In all normal cases an 'in' parameter should be preferred over an explicit 'val' and 'ref' parameter. 2.5 Declare a statement This example program writes its arguments $ include "seed7_05.s7i"; # Standard Seed7 library const proc: main is func local var string: stri is ""; begin for stri range argv(PROGRAM) do write(stri <& " "); end for; writeln; end func; The for-statement iterates over argv(PROGRAM). The function argv(PROGRAM) returns an array string (=array of string elements). The for-statement is overloaded for various collection types. In the standard Seed7 library seed7_05.s7i the for-statement for arrays is declared as follows: const proc: for (inout baseType: variable) range (in arrayType: arr_obj) do (in proc: statements) end for is func local var integer: number is 0; begin for number range 1 to length(arr_obj) do variable := arr_obj[number]; statements; end for; end func; The syntax of this for-statement is declared as: $ syntax expr: .for.().range.().to.().do.().end.for is -> 25; Additionally everybody can overload the for-statement also. Because of these powerful features Seed7 does not need iterators. 2.6 Template declaring a statement Templates are just normal functions with types as parameters. The following template function declares for- statements: const proc: FOR_DECLS (in type: aType) is func begin const proc: for (inout aType: variable) range (in aType: low) to (in aType: high) do (in proc: statements) end for is func begin variable := low; if variable <= high then statements; while variable < high do incr(variable); statements; end while; end if; end func; end func; FOR_DECLS(char);

See more

The list of books you might like

Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.