![]() |
Language reference |
version 7.1 feedback: 2step@zentense.com |
![]() |
1. Glossary of terms |
This is a list of terms widely used in this documentation with its definition.
|
![]() |
2. Lexical structure |
|
This chapter specifies the lexical structure of the 2step programming
language. 2step is lexically identical to Java, except some minor details.
2.1. Comments There are two kinds of comments:
2.2. Identifiers An identifier is an unlimited-length sequence of Java letters (a to z, lower and uppercase) and Java digits (0 to 9), the first of which must be a Java letter. An identifier cannot have the same spelling (Unicode character sequence) as a 2step keyword, boolean literal, the null literal or any Java keyword. 2.3. Keywords The following character sequences, formed with ASCII letters, are reserved for use as keywords and cannot be used as identifiers
2.4. Literals A literal is the source code representation of a value. These values always represent Java objects. 2.4.1. Integer literals Are expressed in decimal (base 10) and are equivalent to Java Integers. Their range goes from -2147483648 to 2147483647, including both. These are integer literals:
2.4.2. Floating point literals The String representation consists of an optional sign, '+' or '-', followed by a sequence of zero or more decimal digits ("the integer"), optionally followed by a fraction, optionally followed by an exponent. The fraction consists of a decimal point followed by zero or more decimal digits. The string must contain at least one digit in either the integer or the fraction. The number formed by the sign, the integer and the fraction is referred to as the significand. The exponent consists of the character 'e' or 'E'
followed by one or more decimal digits. The value of the exponent must
lie into Java Integer range.
2.4.3. Boolean literals There are two: true and false 2.4.4. String literals A string literal, as in Java, consists of zero or more characters enclosed in double quotes. Each character may be represented by an escape sequence. A scape sequence is a backslash '\' followed by one characer. These are the valid ones:
2.4.5. Null literal As in Java, represents the null value. Internally, sometimes null value is represented in 2step by com.zentense.step2.expression.Null.NULL instead of Java null value. So in 2step then expression null.toString() works and returns "Null" string. 2.5. Separators The following nine ASCII characters are the separators (punctuators):
2.6. Operators These are all the operators supported in 2step.
Under these lines there is a list with all the valid 2step operators. Basically, are the same and work the same as in Java. The parenthesis at the right says the resulting type of the operator. 2step will try to convert the types of the expression which are applied to the operator to the resulting type of the operator, but if it is not possible, it will be noticed by an error at compile time. The order which operators are presented is the same as the precedence order of evaluation of these operators. The precedence rules are the same as in Java language program. The precedence order can be changed using parentesis, like in Java. 2.6.1. Unary operators There operators have one unique operand and work on numbers, except the last one that negates booleans.
2.6.2. Multiplicative operators Mathematic multiplication, division and modulus.
2.6.3. Additive operators Mathematic addition and substraction. Notice that Strings can also be added (String concatenation) as in Java.
2.6.4. Relational operators Operators for comparing objects. Objects must implement java.lang.Comparable interface (Strings, Booleans and Numbers for instance) and the result of these operators is always a Boolean.
2.6.5. Equality operators Operators for see if two objects are equal. Objects must implement java.lang.Comparable interface (Strings, Booleans and Numbers for instance) and the result of these operators is always a Boolean.
2.6.6. Bitwise operators Operators for doing binary operations on Integers.
2.6.7. Logical operators Operators for doing logical operators on Booleans.
2.6.8. Assignment operators Operators for assigning values to variables. The first one is the assignment operator. The other ones are the result of combine the assignment operator with another one.
|
![]() |
3. Objects |
|
2step objects are Java objects. No differences between them. You can write a Java class, instantiate
it (using new), call its methods and get the returning values. In a 2step application values are
passed from / to Java code to 2step code all the time, efficiently, because 2step code will become
Java code when compiled. 2step is a wrapper around Java.
3.1. Types Java is a strongly typed language, while 2step is a loosely typed language. This means that in Java any variable is declared with a type, and only will be able to store values of that type. For instance a integer variable cannot store strings, while and String object cannot store Hashtables. At the other side, in 2step variables are declared without any type, they can store any value. Literals are typed. A string literal, obviously, has a type String. A number, if has no decimal part, is an integer literal, otherwise is a double literal. True and false are boolean literals. And null has no type. The type of an expression is determined by the operators and literals (if any). For instance, if you add a variable plus an integer literal (var + 3), the resulting type of this expression will be an integer, because literal has integer type, var has type object, and plus operator accepts the sum of integers. When compiling a 2step application, the compiler keeps track of every expression that is assigned to each variable, and deduces the type of the variable from it. For instance, if you assign an Integer to a local variable, then this variable is typed as Integer. Then, if you assign a String to the same variable, compiler will retype variable as an Object. Sometimes is hard to deduce the right type, specially if you use complex expressions involving different types. 2step was not designed as a general purpose language, but as a web-application oriented language. When you need a general purpose language, just do whatever you need in the powerful Java language, but for doing all the typical tasks associated to web applications, 2step will be the answer. So it will be hard (but possible) to program, for instance, a complex encryption algorithm, which is a task that can be done much more easily in Java, but you will save time accessing sessions, request parameters or cookies using 2step, because was designed to work with this concepts. 3.2. Variables A variable is a memory storage location that can store an Object. A variable's value is changed by assignment operator (=). Variables an be of several types. In the next table a brief description of possible types of 2step variables is shown with some properties. Visibility is from where a variable can be accessed, can be block if the variable can be only viewed from the block where it was declared, of application if the variable can be accessed from any part of the applicatin. Lifespan describes the life cycle of the variable. Is the lifespan is request, the variable is created and initialized on each request, and leaves to exist qhen the request finished. A lifespan of session means that the variable is created and initialized when a session starts, and leaves to exist when the session finishes, so the variable maintain its value between requests. A lifespan of application means that the variable is created when the application is loaded, and exists while the application is running, so they maintain its value not only between requests, but also between sessions. Accessibility says if that kind of variable is writeble or only readable. It is supposed that a variable, as its name says, is always writable, but here, for the sake of simplicity some entities that could be considered as constant have been included here. Class says which class the variable can contain, and declared where the variables are declared.
3.2.1. Implicit variables There are some variables implicity declared in any 2step application and automatically initialized by runtime. These variables are always available to any 2step application. They are:
|
![]() |
4. Language syntax |
|
In this section we will see the syntax of 2step, which is very similar to
Java's one.
The syntax notation used to describe 2step structures is the next: Words enclosed between < and > are another syntactic structures that are described in this document. Parts enclosed between brackets, [ and ], are optional parts. The rest of words and symbols are part of the syntax. Some common definitions:
4.1. Expression A expression is a combination of primary expressions and operators that results in a single object. 4.1.1. Primary expressions A expression consists of one or more primary expressions (if there are more than one, they will be combined with operators), so the primary expressions are the bricks of all expressions. 4.1.1.1. Literal Any literal (Integer, Double, String...) is a primary expression. Literals are read-only expressions (you cannot assign a value to a literal, because a literal is just a value itself). 4.1.1.2. Allocation new <className> [(<expressionList>)]Works the same way as Java allocation. In fact, a 2step allocation is a Java allocation. 4.1.1.3. vm This primary expression (vm) returns a com.zentense.step2.JungleVM instance. This object stores all important runtime objects of current request, and other objects will need this one to obtain all the information they need to perform their tasks. 4.1.1.4. session The session object is an instance of javax.servlet.http.HttpServletSession. All the information associated to a session is stored in this object. For instance, all the global variables are attributes of this session object. 4.1.1.5. request The request object is a instance of javax.servlet.http.HttpServletRequest. All the information associated to a request is stored in this object. All the request parameters come from this object. 4.1.1.6. response The response object is an instance of javax.servlet.http.HttpServletResponse. All the information associated to a response is stored in this object. 4.1.1.7. access This is the user access control object (an instance of com.zentense.step2.access.AccessMaster. This object is responsible for deciding the accessibility of resources as defined in access.properties file of the application. 4.1.1.8. 2step Returns the servlet URI String. The servlet URI is the base URL that points to the web application itself. Appending some parameters to the servlet URI you can build links to any part of the web application. Links made this way will work with or without cookies (if cookies are not accepted, URL rewriting will be used). 4.1.1.9. Request parameter request.<name>Gets or sets the string value for the request parameter with the given name. Equivalent to request.setAttribute(<name>) or request.getAttribute(<name>). Request parameters are read-write (you can modify their values from the script). 4.1.1.10. constant constant.<name>Returns the value of the constant with the given name. Constants are defined in application properties file. Constants are read-only (although you can change constants in administration area). 4.1.1.11. i18n i18n.<name>Returns the internationalized text with the given name, in the language that best fits with client browser language configuration. Internationalized texts are read only in 2step because texts are not supposed to change. 4.1.1.12. view view(<expression> [, <expression>])This instruction is deprecated. Use com.zentense.step2.model.ResultSetModel) instead of DBModel. View initialises a view with a model (a subclass of com.zentense.step2.model.DataModel), a nd returns the initialized view (a subclass of com.zentense.step2.view.RowView). The first expression is a call to a model's method that returns the Vector of rows to be viewed. The second expression is optional. Without it, a RowView is automatically created. If it's specified, then it should be a VectorRowView or a subclass of it. 4.1.1.13. Variables <name>Variables are referenced as identifiers (as in Java). Variables can be local or global depending on where they were declared and are equivalent to Java Object type. Variables are read-write. 4.1.1.14. Field in a view <name>.<name>Accessing the value of a field (second identifier) in a view (first identifier) previously obtained from a view expression or directly, is equivalent to invoke the get method of the view with the name of the field as a parameter (<name>.get("<name>")). Fields in a view are read-write, but after changing the values you must invoke insertRow or updateRow method in the view for commiting the changes. Notice that if the view is a com.zentense.step2.view.ResultSetView assigning a value to a field will throw an Exception unless a call to updateMode on the model is done before the query is executed. 4.1.1.15. Models model.<name>Models represent a database table, composed of rows and columns that can be queried with SQL. The resultsets returned by a model are called views in 2step. Models are read-only and are instantiated automatically by 2step. Models are a instance of type com.zentense.step2.model.AutoModel 4.1.1.16. Method invocation <expression>.<name>([<expressionList>])As in Java, we can invoke methods (or pass messages to objects) giving the instance name (any expression or even literal), the method name, and the list of expressions to be passed as arguments of the method (if any). The result is the same as calling the method directly from Java. In fact, when compiled, it will be translated as a Java method invocation if types of arguments can be deduced and match formal parameters of one of the methods with the same name. If arguments cannot be deduced (far less than 1% of cases), then the method to be called is resolved in runtime (which obviously is far slower than direct invocation). 4.1.1.17. Model finder execution model.<name>::<name>([<expressionList>])A finder is a SQL statement associated to a model. Finders are declared in the model file and when executed return a View containing the results of the corresponding query. The arguments passed to the finder are the parameters defined in the SQL query with question tags. 4.1.1.18. Java expression {{ <Java expression> }}
You can embed Java expression into 2step programs enclosing them between double
brackets. 2step compiler will insert the expression as is into the translated
Java, so if the Java expressions contain errors they will be noticed by the
Java compiler.
4.1.2. Assignable expressions The assignable expressions (those that can be at the left hand side of an assignment operator "=") are variables, fields of views and request parameters. All the other expressions cannot be assigned a value, but they can be used to be assigned to one of the assignable expressions. 4.1.3. Conversions Unlike Java, there are no casts in 2step. In fact, 2step is a loosely typed programming language, but the underlying language under 2step is Java, which is strongly typed. Types are deduced at compile time, but in some cases that type deduction does not work, you may have problems with types in 2step (for instance, when invoking a Java method because all the types of the arguments must match with method formal parameters). Of course, if you need to do something very tricky, you can program it directly in Java, and cast it at your will. For some conversions, operators can be used for converting between different types:
For example: "32"*1 returns the Integer 32 32*1.0 returns the Double 32.0 32+"" returns the String "32" 4.2. Statements Statements are the execution units of the language. An statement may be empty, may be single and finished by a semicolon (';'), or must enclose several other statements using brackets ('{' and '}') as in Java. An statement can be also any expression, as a variable assignation or a method call, and even expression that by itself doesn't do nothing (like a+1). The single statements are:
4.2.1. if, for and while if, for and while work the same way as Java analogues, so no more comments about them. 4.2.2. switch switch(<expression>) {
case <expression1>: <statement>
...
case <expressionN>: <statement>
[default: <statement>]
}
2step switch works almost the same as Java one. The difference is that no break is needed
at the end of any case, because the next case implicitly ends previous one.
4.2.3. put put(<expression>)Writes the result of the expression to the output. By default, the output of a web application is sent to the client browser, but is possible to redirect output to anywhere you want. 4.2.4. render render <name> render <name>.<name>(<expressionList>) render *<expression>This statement renders a template or a block. It has 3 different forms. The first one is for rendering a whole template with the given name. Notice you can render as many templates as you want from a single template or action. The second one is for rendering a block of a template (the first name is template's one, and the second is block's). The blocks may have parameters so, if any, expressions for them will be provided between parenthesis. The third render form allows to render a template which name is contained in the provided expression. It is used when the name of the template to be rendered is unknown at compilation time. 4.2.5. include include(<expression>)Include allows to include a whole file into the current template being rendered. The file will be included as is, without any further processing, so included files can not have any tag. The given expresion contains the full path of the file to be included. Notice that if you set the content type of an action to "image/jpeg" and include a JPEG image, then that 2step action will 'generate' a JPEG image. 4.2.6. break Ends the current (and only the current) action, template or block execution. 4.2.7. inspector Launches an object inspector window. The object inspector shows values of variables and runtime objects and is very useful for debugging applications. 4.2.8. return return [<expression>]Ends the execution of the current action, template or block. Optionally may return a value, but this is only allowed in actions, not in templates neither blocks. 4.2.9. object return [<nameAndInitList>]Since version 6.0 objects can also be declared and initialized into the code, as in Java. 4.3. Application 2step applications have the next structure:
application <name>;
[import <nameList>;]
[static <nameAndInitList>;]
[object <nameAndInitList>;]
[onbegin <statement>]
[onbegin request <statement>]
<ApplicationUnitList>
[onend request <statement>]
[onend <statement>]
In the import section there is (if any) a comma-separated list of packages to import
to this application.
onbegin and onend statements are executed when a new session is created, and when a session expires respectively. onbegin request and ondend request statements are executed at the beginning and at the end of each request respectively. Static Variables are declared in the static section. Static variables are initialized when the application is loaded and are kept in memory while appliation is running. This kind of variables are shared between all requests and sessions. Variables declared in the object section are global and accessible from any action or template, and with a session scope (this variables are created when session is started, and they are kept in memory till session has finished). The list of application units is composed of template and actions. 4.4. Packages 2step packages are basically applications without import and object section (global variables came from main application). An application can be composed of as many modules as needed, that can be imported in the import section of application.
package <name>;
[onbegin <statement>]
<ApplicationUnitList>
[onend <statement>]
The onbegin and onend statements are appended to onbegin and onend of main application (*).
The application unit list is composed of templates and actions, as in application. 4.5. Actions An action is a sequence of statements that can be invoked from 2step code or through a URL by its name.
[<modifiers>] action <name> (<nameList>) [:<mimeType>] {
[object <nameAndInitList>]
<statement>
}
In the object section the local variables for this action are declared, and
optionally, initialized with a value.
4.5.1. Action modifiers There are several optional modifiers. All of them can be combined independently except private, which can only be used alone.
4.5.2. Scheduled actions
action <name> {
[object <nameAndInitList>]
<statement>
} <schedulingPattern>
An scheduled action is an action, that, unlike the normal ones that are executed on
demand each time that the action is requested. The scheduled ones are executed at
certain times defined by the schedulingPattern. These are the possible scheduling
patterns available:
<minute> is a number from 0 to 59, <hour> a number from 0 to 23, <dayOfWeek> is one of mon, tue, wed, thu, fri, sat or sun but long format is also supported (for instance, wednesday), <dayOfMonth> is a number from 1 to 31, and <minutes> is the number of minutes between action executions. An scheduled action has no contenttype, modifiers or parameters, because there is not any client browser waiting for the output or giving request parameters. Scheduled actions are invoked internally by 2step when the scheduling pattern matches with current time. If they need to access the database,then must assign one explicitly from the pool. Scheduled actions are executed without session so trying to access session varibles will not work. 4.6. Templates Templates, like actions, are sequences of statement that can be invoked from 2step code or through a URL by its name. But while an action is a single sequence of statements, a template has several sequences of statements that are associated to a tag name, and a template has a file associated to it. This template file contains the text that will form the output of this template (i.e. HTML code), and embedded in this text there are tags that trigger sequences of statements defined in the template.
[<modifiers>] template <name>(["<fileName>"])[:<mimeType>] [extends <name>] {
[object <nameAndInitList>]
[onbegin <statement>]
<templateUnitList>
[onend <statement>]
}
In the object section the local variables for this template are declared, and
optionally, initialized with a value.
The onbegin statement is the first code of the template that is executed when it is rendered (except expressions in the object section, that are executed before onbegin. The onend statement is, analogously, executed after the template file is rendered and is the last code of the template executed. 4.6.1. Template modifiers and inheritance Basically, are the same as for actions but templates can also be extended, similar to a Java class that can be extended using the extends keyword. A template that extends another template, inherits from its parent the onbegin and onend statements (parent's onbegin is executed before son's one, and son's onend is executed before parent's one), blocks, and all tags (see template units for more information on blocks and tags), and local variables. The tags in the extended template will override the tags in the parent template (like methods in the extended template override the ones in the parent), and the same happens with block declarations. Now take a look at template declaration. Between parenthesis, there is the name of the template file (which is used for rendering the template), and it is optional. Depending if a template is extending another one or not, and if a template has a template file or not, there are four types of templates:
4.6.2. Template units Template units can be tags or blocks. The first ones are code that is executed in the point of the template file where the tag is invoked. Blocks are parts of the template file that are enclosed between one tag at the begin, and other one at the end of the block. The content of the block will be rendered 0, 1 or many times depending on how is declared. 4.6.2.1. Tags Tags are the main union nexus liying between template files and 2step code. In the template file, tags are names enclosed between ASCII characters <$ and $>. When the template is executed, tags will be subtituted by the output generated by the tag (if any). Tags are declared this way inside a template: tag <name> <statement>; There are four kind of tags:
4.6.2.2. Blocks Blocks are areas of the template enclosed between a begin and an end tag. They can be invoked from 2step code, or from an execution tag into a template. This is useful for repeating or hiding certain parts of the template. There are four types of blocks. But all of them share some things in common
block <name>[{
[object <nameAndInitList>]
[onbegin <statement> ]
[templateUnitList]
[onend <statement>]
}]: <name>
The two mandatory names are, the begin and the end tag respectivaly
that must be found into template file.The structure is very similar to template's one, but they don't have modifiers. A block can be defined inside another one, so that they can be nested. Variables declared in a block, are only accessible from that block (or any subblock). 4.6.2.2.1. Parametrized block This block can be invoked through a render statement (from any template or action), with a list of parameters (if any) that act as local variables of the block. The block will not appear when rendering the template file where the block is declared if it's not rendered explicitaly.
block <name> [(<nameList>)] [{ ... }]: <name>
4.6.2.2.2. Conditional block This block will be rendered only when the given codition is evaluated as true:
if(<booleanExpression>)
block <name> [{ ... }]:<name>
[else block <name;>[{ ... }]:<name>]
4.6.2.2.3. View blocks block <name> view(<name>) [{ ... }]:<name>
This block is rendered as many times as rows are contained in the given view, previously obtained from a view expression. The onbegin and onend blocks of this block will only executed once, before the execution of the loop, so onbegin can be used for initializing the view. 4.6.2.2.4. While blocks while(<booleanExpression>)
block <name> [{ ... }]:<name>
This block is rendered while condition is evaluated as true. The onbegin and onend blocks will be executed each time the block is rendered.
| ||||||||||||||||||||||||||||||||