Usage.md 7.24 KB
Newer Older
1
2
#  Tessla compiler Usage

3
4
5
## Scala

The TeSSLa Scala compiler can be run in the following way:
6
7

```
8
java -jar tessla.jar compile-scala [options] <tessla-file>
9
10
11
12
13
```

Following options are available:

```
14
15
16
17
-a, --add-source <value  Additional source file included on top of the generated source
-o, --out-file <value>   Place the generated Scala source code at this location.
-j, --jar-file <value>   Compile TeSSLa specification to an executable jar file which is created at the given location.
-n, --no-io              Replaces I/O Handling in generated source with simple API interface
18
19
```

Benedikt Stepanek's avatar
Benedikt Stepanek committed
20
### Stdio monitor generation
21
22
23

Without further options the TeSSLa compiler generates a file `out.scala` which can be compiled with `scalac` and executed as monitor.
This monitor accepts events via stdio. More detailed information about the input/output format see [here](../../IO.md).
24
Note: If the monitor receives more than one input for the same stream at the same timestamp, the later ones are ignored.
25

Benedikt Stepanek's avatar
Benedikt Stepanek committed
26
Instead of compiling to Scala source one can directly compile to an executable jar file by using the `-b` parameter followed by the
27
28
29
path of the jar archive that shall be created. The generated jar file can directly be launched via `java -jar ...` and behaves exactly
like the monitor generated from source.

Benedikt Stepanek's avatar
Benedikt Stepanek committed
30
### API monitor generation
31
32
33

It is also possible to generate a monitor with an API interface and without I/O handling. This may especially be useful if one wants
to access the monitor from another Java or Scala application. The compilation to API code can be achieved with the `-n` flag.
34
The Api monitor can be generated as Scala code and as (non-executable) jar archive as well. Details about how the API can be accessed
35
36
can be found [here](API.md).

Benedikt Stepanek's avatar
Benedikt Stepanek committed
37
### Connecting TeSSLa to external functions
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

Further it is possible to include Scala (and hence also Java) functions in the monitor. Therfore write your functions in a file
`addSource.scala` and include them by passing `-a addSource.scala`. The code from `addSource.scala` is then included at the very top
of the generated monitor. The corresponding functions and types can then be accessed from a TeSSLa specification via the `extern`
keyword and `native:` put in front of the extern name.

If you for example define a Scala function

```
object foo {
    def bar(x: Long) : Long = x + 5
}
```

in Scala you can import this function as

```
def bar(x:Int) : Int = extern("native:foo.bar")
```

in your TeSSLa specification and use it (Note: Int in TeSSLa is translated to Long in Scala). 
Also a reference to the Java standard library is possible this way:

```
def bas(x:Int) : Int = extern("native:java.lang.Math.abs")
```

A list how TeSSLa types correspond to Scala types can be found [here](Types.md).

For detailed examples of using external Scala functions see this testcases

* externalFunctionUse
    * [externalFunctionUse.tessla](../src/test/resources/de/uni_luebeck/isp/tessla/tesslac/nativeExterns/externalFunctionUse.tessla)
71
    * [externalFunctionUse.scala](../src/test/resources/de/uni_luebeck/isp/tessla/tesslac/nativeExterns/externalFunctionUse.scala)
72
73
74
    
* externalTypes
    * [externalTypes.tessla](../src/test/resources/de/uni_luebeck/isp/tessla/tesslac/nativeExterns/externalTypes.tessla)
75
    * [externalTypes.scala](../src/test/resources/de/uni_luebeck/isp/tessla/tesslac/nativeExterns/externalTypes.scala)
76
77
78
79
80
81
82
83
84
    
Note: 

* Use of Scala externs is currently only supported by the compiler backend not by the interpreter
* Expressions using Scala externs cannot be evaluated during compilation time. This may in some cases avoid macro expansion.
  If a macro (function) which is receiving or returning a stream variable cannot be evaluated at compilation time due to 
  a non evaluateable Scala extern compilation will refuse according to the TeSSLa language specification.
* As consequence of the previous point: Extern Scala functions cannot directly receive streams but can be made liftable and 
  applied on streams.
Benedikt Stepanek's avatar
Benedikt Stepanek committed
85
86
87

## Rust

Benedikt Stepanek's avatar
Benedikt Stepanek committed
88
The TeSSLa Rust compiler can be run in the following way:
89
90
91
92
93
94
95
96
97
98
99
100
101
102

```
java -jar tessla.jar compile-rust [options] <tessla-file>
```

Following options are available:

```
-b, --bin-file <value>     Compile a full monitor binary and place it in the given location
-a, --add-source <value>   Additional rust file inserted at the top of the monitor library
-p, --project-dir <value>  Export a Cargo workspace with everything necessary to modify and build the tessla monitor yourself
-m, --io-interface         Generate the code for an executable I/O interface (src/main.rs) in the exported workspace
```

Benedikt Stepanek's avatar
Benedikt Stepanek committed
103
104
### Stdio monitor generation

Benedikt Stepanek's avatar
Benedikt Stepanek committed
105
106
107
108
109
110
111
112
You must specify at least one of the two options `-p` and `-b`.

If you provide `-p` you must specify a folder name.
Then a complete Cargo project including the TeSSLa standard library is created into that folder.
Depending on whether you specify `-m` the generated monitor will contain code to receive events via stdio.
More detailed information about the input/output format see [here](../../IO.md).
Note: If the monitor receives more than one input for the same stream at the same timestamp, the last one will be used.
If you
113
*don't* specify `-m` you need to provide your custom `main` function (API monitor generation).
Benedikt Stepanek's avatar
Benedikt Stepanek committed
114
115

If you specify `-b` the compiler will compile a complete runnable binary by invoking cargo. This binary always receives
116
input via stdio. You can combine `-p` and `-b` as both flags are treated separately.
Benedikt Stepanek's avatar
Benedikt Stepanek committed
117
118
119
120
121

### API monitor generation

It is also possible to generate a monitor with an API interface and without I/O handling. This may especially be useful if one wants
to access the monitor from another application written in any language that can interface to Rust.
122
The API is always generated when a cargo project is created with `-p`. Details about how the API can be accessed
Benedikt Stepanek's avatar
Benedikt Stepanek committed
123
124
125
126
can be found [here](API.md).

### Connecting TeSSLa to external functions

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
It is possible to insert your own rust code into the monitor with the `-a include.rs` argument.
The contents of this file will be placed at the top of the generated `monitor.rs`.
The corresponding Rust functions and types can be accessed from a TeSSLa specification via the `extern` keyword
with the `native:` prefix in front of the desired name.

For example, this Rust function:
```rust
fn bar(x: TesslaInt) -> TesslaFloat {
  match TesslaFloat::from(x) {
    Error(error) => Error(error),
    Value(value) => Value(value.to_degrees())
  }
}
```
can be imported to TeSSLa as:
```
def bar(x: Float): Float = extern("native:bar")
```

You can find more information on how to deal with the `TesslaValue` container, and how the TeSSLa types correspond to Rust types [here](./Types.md#Rust).

#### Notes:
- All values going in, and coming out of imported native externs, must be of Type `TesslaValue<T>`, where `T` may be a
custom type you defined yourself, if it implements the necessary Traits as specified [here](./Types.md#Types).
- Expressions using externs cannot be evaluated at compile time. This may in some cases avoid macro expansion.
If a macro (function) which is receiving or returning a stream variable cannot be evaluated at compilation time due to
a non evaluateable extern, compilation will refuse according to TeSSLa language specification.
- As a consequence of the previous point: Extern Rust functions cannot directly receive streams, but can be made liftable, and applied to streams.