Types & Converters
| < Variables | Maps > |
What is "type support"?
In addition to all built-in Java types, terp supports a host of terp-specific support types, as well as any Java types that are on the terp engine's classpath. "Type support" is of course a very flexible term. At a minimum, the term "type support" implies that an instance of the type can be instantiated and its instance fields and methods can be used from within terp.
There might be additional type support within the terp framework though. Consider the string type for example. You can definitely use string literals and invoke string methods on them. But can you use strings with mathematical operators? For example, can you say something like "terp"+" example"? Can you say "test"-3?
The answer is that terp supports many different types with many different operators. You can certainly concatenate strings by using the plus operator. You cannot subtract an integer from a string using the minus operator because we could not come up with a meaningful interpretation of that expression. We did come up with a meaningful interpretation for the minus operator used on a collection and a string though. In that case, we attempt to remove the string from the collection. We're mentioning this here because you can interpret this feature either as type-related or as operator-related. In reality, it is of course related to the <operator,type>-tuple.
Instantiation
How do you instantiate instances of an arbitrary type? You can either use literals in the case of strings, characters, and numbers, or you can use type conversion operators. The general conversion/instantiation syntax is:
[ @ | ^ ] typename ( argument-list? )
Either the @ or the ^ character may be used to start a conversion/instantiation expression. Conversions and instantiations have a lot in common: in either case you end up with an instance of a particular type. You don't really have to know or care whether a constructor or a conversion function was called. The following examples illustrate the use of constructors for the creation of new objects via constructors:
@java.util.Vector( 3 ) ^java.util.Hashtable()
In the above cases, terp locates Java constructors and invokes them. You can also create object instances by invoking type converters. A type converter takes an instance of one type and converts it to an instance of the target type. Think of it as a factory method. All built-in terp types support conversion from string and conversion from their own type, for example:
@version("1.4")
^version(1.4)
@procarch("x86")
^java.lang.Integer("3")
^int("3")
^int(3)
What you're seeing above is the use of type aliases in combination with conversion operators. Many of the commonly used Java types have been registered with an alias that makes them easier to use and the template easier to read. The table below contains the registered conversion aliases. Converters really are a generalization of the factory method pattern. Think of a converter as a factory method that takes suitable inputs and returns an instance of the target type.
Some converters support the instantiation of the desired object without any input, i.e. with a null input or with an empty map as input. These converters are usually converters for types representing system objects that have a default value. For example: asking for a Java Runtime Environment via the unparametrized ^jre() converter will give you a JRE, any JRE terp could find. The choice of JRE is of course not quite random. There is a rule deciding which JRE among the many JREs that might be found on your system is being chosen. The important point is that terp interprets the absence of an input object as an indication that we're willing to accept whatever terp's choice might be rather than as a reason to return nothing (null).
This is different from simple converters like ^int(). Clearly, we could come up with a default value for an integer to return for null input, but it makes more sense to return null output for null input.
Built-in Type Converters
| Alias | Target Type | Supported Source Types* |
|---|---|---|
| acc | com.codemesh.terp.data.Cpp.AccExecutor | null, Number, Version, File, Map |
| ant | com.codemesh.terp.data.Ant.AntExecutor | null, File, Map |
| bool | java.lang.Boolean | |
| byte | java.lang.Byte | Number |
| cpp | com.codemesh.terp.data.Cpp.CppExecutor | null, Number, Version, File, Map |
| char | java.lang.Character | Number |
| date | java.sql.Date | Number |
| double | java.lang.Double | Number |
| exec | com.codemesh.terp.eval.executors.ProcessExecutor | null, File, Map |
| f, file | java.io.File | |
| fp, filepattern | com.codemesh.terp.data.FilePattern | Pattern |
| float | java.lang.Float | Number |
| gcc | com.codemesh.terp.data.Cpp.GccExecutor | null, Number, Version, File, Map |
| host | com.codemesh.terp.data.Host | |
| int | java.lang.Integer | Number |
| ip | java.net.InetAddress | |
| java | com.codemesh.terp.eval.executors.JavaExecutor | null, Number, Version, File, Map |
| javac | com.codemesh.terp.eval.executors.JavacExecutor | null, Number, Version, File, Map |
| javadoc | com.codemesh.terp.eval.executors.JavadocExecutor | null, Number, Version, File, Map |
| jdk | com.codemesh.terp.data.Jdk$Impl | null, Number, Version, File, Map |
| jre | com.codemesh.terp.data.Jre$Impl | null, Number, Version, File, Map |
| lib | com.codemesh.terp.data.Lib.LibExecutor | null, String, File, Cpp.MsvcExecutor, Map |
| list | java.util.ArrayList | null, Collection, Iterator, Enumeration |
| long | java.lang.Long | Number |
| msvc | com.codemesh.terp.data.Cpp.MsvcExecutor | null, Number, Version, File, Map |
| os | com.codemesh.terp.data.OS | Map |
| path | com.codemesh.terp.data.Path$Impl | File, array, Collection |
| pattern | java.util.regex.Pattern | |
| procarch | com.codemesh.terp.data.ProcArch | Map |
| regex | java.util.regex.Pattern | |
| set | java.util.HashSet | null, Collection, Iterator, Enumeration |
| shell | com.codemesh.terp.eval.executors.ShellExecutor | null, File, Map |
| short | java.lang.Short | Number |
| str, string | java.lang.String | anything but null |
| suncc | com.codemesh.terp.data.Cpp.SunccExecutor | null, Number, Version, File, Map |
| uri | java.net.URI | |
| v, version | com.codemesh.terp.data.VersionImpl | |
| xlc | com.codemesh.terp.data.Cpp.XlcExecutor | null, Number, Version, File, Map |
* all types support conversion from String and from their own type.
Type Converter Details
^v(), ^version()
The version converter supports conversions from any instance implementing the Versioned interface, from Numbers, Strings, and Maps. If a map is used as the source instance, the following properties are supported:
| Property | Type | Description |
|---|---|---|
| build | Number | The fourth numeric component in the build number. |
| major | Number | The first numeric component in the build number. |
| minor | Number | The second numeric component in the build number. |
| patch | Number | The third numeric component in the build number. |
| prefix | String | The string prefix. |
| suffix | String | The string suffix. |
