diff --git a/docs/developer/developer-eclipse-setup-with-oomph.mdx b/docs/developer/developer-eclipse-setup-with-oomph.mdx index d88abcb2c..a895934aa 100644 --- a/docs/developer/developer-eclipse-setup-with-oomph.mdx +++ b/docs/developer/developer-eclipse-setup-with-oomph.mdx @@ -109,7 +109,7 @@ Hello World. This should print "Hello World". -We strongly recommend browsing the system tests, which provide a concise overview of the capabilities of Lingua Franca. You can set up a project in the IDE for this using [these instructions](<../developer/regression-tests.mdx#browsing-and-editing-examples-in-the-lf-ide>). +We strongly recommend browsing the [integration tests](regression-tests.mdx), which provide a concise overview of the capabilities of Lingua Franca. ## Working on the Lingua-Franca Compiler diff --git a/docs/embedded/arduino.mdx b/docs/embedded/arduino.mdx index fd4c70a63..8cbc473d8 100644 --- a/docs/embedded/arduino.mdx +++ b/docs/embedded/arduino.mdx @@ -3,7 +3,7 @@ title: Arduino description: Developing LF Programs on Arduino. --- -# Overview +## Overview To run Lingua Franca on an Arduino-compatible microcontroller, you can use the `C` target with the `platform` target property set to `arduino`. The Lingua @@ -13,7 +13,7 @@ To flash the compiled sketch onto a board, you need specify a Fully Qualified Board Name (FQBN) as well as the port to which your board is connected. On this page, we explain exactly how to do this. -## Prerequisites +### Prerequisites - You need a development system that runs on macOS or Linux (there is currently no Windows support). - [Arduino CLI](https://arduino.github.io/arduino-cli/) must be installed on your development system. Confirm that your installation works by running: @@ -22,7 +22,7 @@ page, we explain exactly how to do this. arduino-cli version ``` -# Writing a simple Arduino Program +## Writing a simple Arduino Program The most basic Arduino program (Blink) can be defined in LF like so: @@ -56,7 +56,7 @@ can invoke Arduino library functions, just like one would do in the definition of an Arduino `loop()`. For any setup that might be needed at the beginning of execution, a reaction triggered by the built-in `startup` trigger can be used. -## Platform Options +### Platform Options The `platform` property can also be used so specify more details. Along with `name: "arduino"`, you can specify which `board`, `port`, and `baud-rate` you are using. If you want the program @@ -77,14 +77,14 @@ target C { The `board` is necessary for [building](#building) and the `port` is necessary for [flashing](#flashing). -### Baud rate of the serial port +#### Baud rate of the serial port All Arduino boards have at least one serial port (also known as a UART or USART), and some have several. By default, Lingua Franca will assume a default baud rate of 9600. This parameter is tunable by adjusting the `baud-rate` parameter in platform options. -# Building +## Building In order to have `arduino-cli` compile the generated sketch file, a `board` must be specified. If no `board` is set, `lfc` will run in `no-compile` mode, meaning @@ -112,7 +112,7 @@ If you specify your FQBN under `board` in the `platform` target property, `lfc` - for threaded programs (`arduino:mbed` boards), run: `arduino-cli compile -b [FQBN] --build-property compiler.c.extra_flags="-DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10" --build-property compiler.cpp.extra_flags="-DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10"` -# Flashing +## Flashing Arduino's can be flashed via USB. To find the port oto which your device is connected, run the following command: diff --git a/docs/reference/target-declaration.mdx b/docs/reference/target-declaration.mdx index cb4c13823..cd8916db2 100644 --- a/docs/reference/target-declaration.mdx +++ b/docs/reference/target-declaration.mdx @@ -28,9 +28,8 @@ A target specification may have optional parameters, the names and values of whi - [**build-type**](#build-type): One of Debug (the default), Release, RelWithDebInfo and MinSizeRel. - [**cargo-dependencies**](#cargo-dependencies): (Rust only) list of dependencies to include in the generated Cargo.toml file. - [**cargo-features**](#cargo-features): (Rust only) List of string names of features to include. -- [**cmake-include**](#cmake): List of paths to cmake files to guide compilation. +- [**cmake-include**](#cmake-include): List of paths to cmake files to guide compilation. - [**compiler**](#compiler): A string giving the name of the target language compiler to use. -- [**compiler-flags**](#compiler-flags): An arrays of strings giving options to be passed to the target compiler. - [**docker**](#docker): A boolean to generate a Dockerfile. - [**external-runtime-path**](#external-runtime-path): Specify a pre-compiled external runtime library located to link to instead of the default. - [**export-dependency-graph**](#export-dependency-graph): To export the reaction dependency graph as a dot graph (for debugging). @@ -646,7 +645,7 @@ Any errors in command-line arguments result in printing the above information. T ### Custom Command-Line Arguments -User-defined command-line arguments may be created by giving the main reactor [parameters](#using-parameters). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). +User-defined command-line arguments may be created by giving the main reactor [parameters](../writing-reactors/parameters-and-state-variables.mdx#parameter-declaration). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). Note: Custom arguments may not have the same names as standard arguments like `timeout` or `keepalive`. @@ -736,7 +735,7 @@ The generated C++ program understands the following command-line arguments, each - `-w, --workers `: Use n worker threads for executing reactions. - `--help`: Print the above information. -If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary (see [Using Parameters](#using-parameters)). +If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary. The Python target does not currently support any command-line arguments. You must specify properties as target parameters. diff --git a/docs/reference/target-language-details.mdx b/docs/reference/target-language-details.mdx index ab2948cf4..ac94f14a0 100644 --- a/docs/reference/target-language-details.mdx +++ b/docs/reference/target-language-details.mdx @@ -722,7 +722,7 @@ A state variable may be a time value, declared as follows: state time_value:time = 100 ms ``` -The `time_value` variable will be of type `TimeValue`, which is an object used to represent a time in the TypeScript Target. Refer to the section on [timed behavior](#timed-behavior) for more information. +The `time_value` variable will be of type `TimeValue`, which is an object used to represent a time in the TypeScript Target. Refer to the [section on time](#time) for more information. A state variable can have an array or object value. For example, the following reactor computes the **moving average** of the last four inputs each time it receives an input (from [MovingAverageImpl](https://github.com/lf-lang/lingua-franca/blob/master/test/TypeScript/src/MovingAverage.lf)): @@ -1486,7 +1486,7 @@ In the TypeScript target, all [TypeScript types](https://www.typescriptlang.org/ - `undefined` is not a valid type for an input, output, or action. This is because `undefined` is used to designate the absence of an input, output, or action during a reaction. -As with parameters and state variables, custom types (and classes) must be defined in the [preamble](#preamble) before they may be used. +As with parameters and state variables, custom types (and classes) must be defined in the [preamble](../writing-reactors/preambles.mdx) before they may be used. **To benefit from type checking, you should declare types for your reactor elements.** If a type isn't declared for an input, output, or action, it is assigned the [reactor-ts](https://github.com/lf-lang/reactor-ts) type `Present` which is defined as @@ -2134,11 +2134,11 @@ Second iteration - the microstep part of the tag is: 1. ... ``` -The first reaction prints the "First iteration" part of the output at microstep 0. The second reaction occurs one microstep later (explained in [Scheduling Delayed Reactions](#scheduling-delayed-reactions)) and illustrates how to split a `Tag` into its constituent `TimeValue` and microstep. +The first reaction prints the "First iteration" part of the output at microstep 0. The second reaction occurs one microstep later (explained in [Actions](../writing-reactors/actions.mdx)) and illustrates how to split a `Tag` into its constituent `TimeValue` and microstep. ### Summary of Time Functions -See [Time](#timed-behavior). These time functions are defined in the [time.ts](https://github.com/lf-lang/reactor-ts/blob/master/src/core/time.ts) library of [reactor-ts](https://github.com/lf-lang/reactor-ts). +See [Time](#time). These time functions are defined in the [time.ts](https://github.com/lf-lang/reactor-ts/blob/master/src/core/time.ts) library of [reactor-ts](https://github.com/lf-lang/reactor-ts). `UnitBasedTimeValue(value: number, unit:TimeUnit)` Constructor for `UnitBasedTimeValue`, a programmer-friendly subclass of TimeValue. Use a number and a `TimeUnit` enum. @@ -2609,7 +2609,7 @@ This version carries an `int` value. The data type of the action is required to > `lf_schedule_token(, , );` -This version carries a **token**, which has type `token_t` and points to the value, which can have any type. There is a `create_token()` function that can be used to create a token, but programmers will rarely need to use this. Instead, you can use `lf_schedule_value()` (see below), which will automatically create a token. Alternatively, for inputs with types ending in `*` or `[]`, the value is wrapped in a token, and the token can be obtained using the syntax `inputname->token` in a reaction and then forwarded using `lf_schedule_token()` (see [Dynamically Allocated Structs](#Dynamically-Allocated-Structs) above). If the input is mutable, the reaction can then even modify the value pointed to by the token and/or use `lf_schedule_token()` to send the token to a future logical time. For example, the [DelayPointer](https://github.com/lf-lang/lingua-franca/blob/master/test/C/src/DelayPointer.lf) reactor realizes a logical delay for any data type carried by a token: +This version carries a **token**, which has type `token_t` and points to the value, which can have any type. There is a `create_token()` function that can be used to create a token, but programmers will rarely need to use this. Instead, you can use `lf_schedule_value()` (see below), which will automatically create a token. Alternatively, for inputs with types ending in `*` or `[]`, the value is wrapped in a token, and the token can be obtained using the syntax `inputname->token` in a reaction and then forwarded using `lf_schedule_token()` (see [Dynamically Allocated Data](#dynamically-allocated-data) above). If the input is mutable, the reaction can then even modify the value pointed to by the token and/or use `lf_schedule_token()` to send the token to a future logical time. For example, the [DelayPointer](https://github.com/lf-lang/lingua-franca/blob/master/test/C/src/DelayPointer.lf) reactor realizes a logical delay for any data type carried by a token: ```lf-c reactor DelayPointer(delay:time(100 ms)) { @@ -2761,15 +2761,15 @@ FIXME: Details needed here. A suite of useful functions is provided in [util.h](https://www.lf-lang.org/reactor-c/d8/d3c/util_8h.html) for producing messages to be made visible when the generated program is run. Of course, you can always use `printf`, but this is not a good choice for logging or debug information, and it is not a good choice when output needs to be redirected to a window or some other user interface (see for example the [sensor simulator](https://github.com/lf-lang/reactor-c/blob/main/util/sensor_simulator.h)). Also, in federated execution, these functions identify which federate is producing the message. The functions are listed below. The arguments for all of these are identical to `printf` with the exception that a trailing newline is automatically added and therefore need not be included in the format string. -- `LF_PRINT_DEBUG(format, ...)`: Use this for verbose messages that are only needed during debugging. Nothing is printed unless the [target](<../introduction.md#logging>) parameter `logging` is set to `debug`. THe overhead is minimized when nothing is to be printed. +- `LF_PRINT_DEBUG(format, ...)`: Use this for verbose messages that are only needed during debugging. Nothing is printed unless the [target](target-declaration.mdx#logging) parameter `logging` is set to `debug`. THe overhead is minimized when nothing is to be printed. -- `LF_PRINT_LOG(format, ...)`: Use this for messages that are useful logs of the execution. Nothing is printed unless the [target parameter `logging`](<../introduction.md#logging>) is set to `log` or `debug`. This is a macro so that overhead is minimized when nothing is to be printed. +- `LF_PRINT_LOG(format, ...)`: Use this for messages that are useful logs of the execution. Nothing is printed unless the [target parameter `logging`](target-declaration.mdx#logging) is set to `log` or `debug`. This is a macro so that overhead is minimized when nothing is to be printed. -- `lf_print(format, ...)`: Use this for messages that should normally be printed but may need to be redirected to a user interface such as a window or terminal (see `register_print_function` below). These messages can be suppressed by setting the [logging target property](<../introduction.md#logging>) to `warn` or `error`. +- `lf_print(format, ...)`: Use this for messages that should normally be printed but may need to be redirected to a user interface such as a window or terminal (see `register_print_function` below). These messages can be suppressed by setting the [logging target property](target-declaration.mdx#logging) to `warn` or `error`. -- `lf_print_warning(format, ...)`: Use this for warning messages. These messages can be suppressed by setting the [logging target property](<../introduction.md#logging>) to `error`. +- `lf_print_warning(format, ...)`: Use this for warning messages. These messages can be suppressed by setting the [logging target property](target-declaration.mdx#logging) to `error`. -- `lf_print_error(format, ...)`: Use this for error messages. These messages are not suppressed by any [logging target property](<../introduction.md#logging>). +- `lf_print_error(format, ...)`: Use this for error messages. These messages are not suppressed by any [logging target property](target-declaration.mdx#logging). - `lf_print_error_and_exit(format, ...)`: Use this for catastrophic errors. @@ -2802,7 +2802,7 @@ Which type of messages are actually produced by the compiled program can be cont -The Python supports the [logging](<../introduction.md#logging>) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). +The Python supports the [logging](target-declaration.mdx#logging) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). @@ -2819,7 +2819,7 @@ The executable reacts to the environment variable `RUST_LOG`, which sets the log Error and warning logs are on by default. Enabling a level enables all greater levels (i.e., `RUST_LOG=info` also enables `warn` and `error`, but not `trace` or `debug`). -Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](<../introduction.md#command-line-arguments>). +Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](target-declaration.mdx#command-line-arguments). Note that the `logging` target property is ignored, as its levels do not match the Rust standard levels we use (those of the [`log` crate](https://docs.rs/log/)). @@ -3019,7 +3019,7 @@ primitives and sleep functions. ### Multithreaded Implementation -By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](<../introduction.md#threading>) statement or the `--workers` [command-line argument](<../introduction.md#command-line-arguments>) is given. +By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](target-declaration.mdx#workers) statement or the `--workers` [command-line argument](target-declaration.mdx#command-line-arguments) is given. Upon initialization, the main thread will create the specified number of worker threads. Execution proceeds in a manner similar to the [single threaded implementation](#single-threaded-implementation) @@ -3028,7 +3028,7 @@ The execution algorithm ensures that no reaction executes until all reactions th ### Single Threaded Implementation -By giving the `single-threaded` [target option](<../introduction.md#single-threaded>) or the `--single-threaded` [command-line argument](<../introduction.md#command-line-arguments>), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. +By giving the `single-threaded` [target option](target-declaration.mdx#single-threaded) or the `--single-threaded` [command-line argument](target-declaration.mdx#command-line-arguments), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. The execution strategy is to have two queues of pending accessor invocations, one that is sorted by tag (the **event queue**) and one that is sorted by priority (the **reaction queue**). @@ -3036,9 +3036,9 @@ Execution proceeds as follows: 1. At initialization, an event for each timer is put on the event queue and logical time is initialized to the current time, represented as the number of nanoseconds elapsed since January 1, 1970. -2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](<../introduction.md#command-line-arguments>) is given). +2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). -3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](<../introduction.md#command-line-arguments>) is given). Then advance logical time to match that earliest timestamp. +3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). Then advance logical time to match that earliest timestamp. 4. Execute reactions in order of priority from the reaction queue. These reactions may produce outputs, which results in more events getting put on the reaction queue. Those reactions are assured of having lower priority than the reaction that is executing. If a reaction calls `lf_schedule()`, an event will be put on the event queue, not the reaction queue. @@ -3052,7 +3052,7 @@ Unlike the C target, the Cpp target implements more of the analysis and setup of -The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [threading](<../introduction.md#threading>) target property can be used to override this behavior. +The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [single-threaded](target-declaration.mdx#single-threaded) target property can be used to override this behavior. Running [lfc](../tools/command-line-tools.mdx) on a `XXX.lf` program that uses the Python target specification on a Linux machine will create the following files (other operating systems will have @@ -3237,7 +3237,7 @@ The Lingua Franca compiler automatically invokes other programs as it compiles a ### package.json -Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. +Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](../writing-reactors/preambles.mdx#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. ### tsconfig.json @@ -3249,7 +3249,7 @@ If the `tsc` type check was successful, the Lingua Franca compiler uses `babel` ### Debugging Type Errors -Let's take the [minimal reactor example](#a-minimal-example), and intentionally break it by adding a type error into the reaction. +Let's take the minimal reactor example, and intentionally break it by adding a type error into the reaction. ```lf-ts target TypeScript; @@ -3343,13 +3343,13 @@ These utility functions may be called within a TypeScript reaction: `util.getCurrentTag(): Tag` Gets the current (logical) tag. See [Tags](#tags). -`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#timed-behavior). +`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#time). -`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#timed-behavior). +`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#time). -`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#time). -`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#time). `util.success(): void` Invokes the [reactor-ts](https://github.com/lf-lang/reactor-ts) App's default success callback. FIXME: Currently doesn't do anything in Lingua Franca. @@ -3408,7 +3408,7 @@ See [Target Declaration](../introduction.md) for the full list of supported targ ### The Executable -The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](<../introduction.md#command-line-arguments>) for details. +The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](target-declaration.mdx#command-line-arguments) for details. ### File layout diff --git a/docs/reference/tracing.mdx b/docs/reference/tracing.mdx index 9359ec581..1e1f8e0ec 100644 --- a/docs/reference/tracing.mdx +++ b/docs/reference/tracing.mdx @@ -13,7 +13,7 @@ import { Tracing is a powerful tool when it comes to analysis and debugging of applications. Unfortunately, most tracing tools that are readily available are designed specifically for analyzing processes, threads and system calls. Specialized tools are required to enable analysis that is tailored to an alternative model of computation such as Reactors. The tools should be capable of understanding the fundamental concepts of the model, such as the distinction between logical and physical time, as well as structural units such as reactors and reactions. This page gives an overview of the currently supported trace mechanism, as well as an outline of alternative tools that could be useful in the future. -Tracing is different from [logging](<../introduction.md#logging>). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. +Tracing is different from [logging](target-declaration.mdx#logging). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. Tracing is currently supported in the C, Python, and C++ targets. The mechanism used in C and Python is different from that used in C++. Tracing in C++ requires third-party tools that may only be available in Linux. Tracing in C and Python does not require any third-party tools. diff --git a/docs/videos.mdx b/docs/videos.mdx index b94ad0cc8..bbea2ccba 100644 --- a/docs/videos.mdx +++ b/docs/videos.mdx @@ -47,12 +47,12 @@ A [video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9Y **Useful links:** - [Complete video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9YEjulS4o) -- [Part I: Introduction](#introduction) -- [Part II: Hello World](#hello) -- [Part III: Target Languages](#target) -- [Part IV: Basic Concepts](#concepts) -- [Part V: Concurrency and Performance](#concurrency) -- [Part VI: Research Overview](#research) +- [Part I: Introduction](#part-i-introduction) +- [Part II: Hello World](#part-ii-hello-world) +- [Part III: Target Languages](#part-iii-target-languages) +- [Part IV: Basic Concepts](#part-iv-basic-concepts) +- [Part V: Concurrency and Performance](#part-v-concurrency) +- [Part VI: Research Overview](#part-vi-research-overview) - [Slides](https://docs.google.com/presentation/d/14cfIMmkBFwt6NOj2ujVs7YXPAXYsoHgLS2rUgBM-Deg/present?slide=id.g623f095f12_0_0) ### Part I: Introduction diff --git a/docs/writing-reactors/actions.mdx b/docs/writing-reactors/actions.mdx index 1a7053ef6..df43bf053 100644 --- a/docs/writing-reactors/actions.mdx +++ b/docs/writing-reactors/actions.mdx @@ -133,7 +133,7 @@ Action triggered at logical time 603669000 nsec after start. ... ``` -Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](<../introduction.md#fast>) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. +Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](../reference/target-declaration.mdx#fast) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. Whereas logical actions are required to be scheduled within a reaction of the reactor that declares the action, physical actions can be scheduled by code that is outside the Lingua Franca system. For example, some other thread or a callback function may call `schedule()`, passing it a physical action. For example: diff --git a/docs/writing-reactors/composing-reactors.mdx b/docs/writing-reactors/composing-reactors.mdx index daef9a51d..e8dde0c82 100644 --- a/docs/writing-reactors/composing-reactors.mdx +++ b/docs/writing-reactors/composing-reactors.mdx @@ -172,7 +172,7 @@ Connections may include a **logical delay** using the `after` keyword, as follow where `` can be any of the forms described in [Expressions](../reference/expressions.mdx). -The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/actions.mdx#superdense-time>) later than the event that triggered it. +The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/superdense-time.mdx>) later than the event that triggered it. ## Physical Connections diff --git a/docs/writing-reactors/multiports-and-banks.mdx b/docs/writing-reactors/multiports-and-banks.mdx index 263e072a3..1ca30cd35 100644 --- a/docs/writing-reactors/multiports-and-banks.mdx +++ b/docs/writing-reactors/multiports-and-banks.mdx @@ -374,7 +374,7 @@ The syntax `(a.out)+` means "repeat the output port `a.out` one or more times as -Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#Combining-Banks-and-Multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: +Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#combining-banks-and-multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: import C_Interleaved from '../assets/code/c/src/Interleaved.lf'; import Cpp_Interleaved from '../assets/code/cpp/src/Interleaved.lf'; diff --git a/docs/writing-reactors/preambles.mdx b/docs/writing-reactors/preambles.mdx index fb7cd6793..c2111eaf3 100644 --- a/docs/writing-reactors/preambles.mdx +++ b/docs/writing-reactors/preambles.mdx @@ -326,7 +326,7 @@ Your platform is Linux By putting import in the `preamble`, the module becomes available in all reactions of this reactor using the `self` modifier. -**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx#python-target-implementation-details>). +**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx>). Alternatively, you can define a `preamble` outside any reactor definition. Such a `preamble` can be used for functions such as import or to define a global function. The following example shows importing the [hello](https://github.com/lf-lang/lingua-franca/blob/master/test/Python/src/include/hello.py) module: @@ -432,7 +432,7 @@ Converted string 42 to number 42 ### Using Node Modules -Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](#preamble) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](#typescript-target-implementation-details) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. +Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're importing modules in the preamble and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](../reference/target-language-details.mdx) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. The important takeaway here is with the package.json file and the compiled JavaScript in the Foo/dist/ directory, you have a standard Node.js program that executes as such. You can modify and debug it just as you would a Node.js program. diff --git a/docs/writing-reactors/termination.mdx b/docs/writing-reactors/termination.mdx index fc9b8244f..58a43bf71 100644 --- a/docs/writing-reactors/termination.mdx +++ b/docs/writing-reactors/termination.mdx @@ -29,7 +29,7 @@ We address each of these in turn. ## Timeout -The [target property `timeout`](<../introduction.md#timeout>) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). +The [target property `timeout`](../reference/target-declaration.mdx#timeout) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). There is a significant subtlety when using [physical connections](<../writing-reactors/composing-reactors.mdx#physical-connections>), which are connections using the syntax `~>`. Such connections specify that the tag at the receiving end will be based on the physical time at which the message is received. If the tag assigned at the receiving end is greater than the final tag, then the message is lost. Hence, **messages sent near the `timeout` time are likely to be lost!** diff --git a/docs/writing-reactors/time-and-timers.mdx b/docs/writing-reactors/time-and-timers.mdx index 9f7ed7d03..41467929c 100644 --- a/docs/writing-reactors/time-and-timers.mdx +++ b/docs/writing-reactors/time-and-timers.mdx @@ -15,7 +15,7 @@ import { A key property of Lingua Franca is **logical time**. All events occur at an instant in logical time. By default, the runtime system does its best to align logical time with **physical time**, which is some measurement of time on the execution platform. The **lag** is defined to be physical time minus logical time, and the goal of the runtime system is maintain a small non-negative lag. -The **lag** is allowed to go negative only if the [`fast`](<../reference/target-declaration#fast>) target property or the [`--fast`](<../reference/target-declaration#command-line-arguments>) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. +The **lag** is allowed to go negative only if the [`fast`](../reference/target-declaration.mdx#fast) target property or the [`--fast`](../reference/target-declaration.mdx#command-line-arguments) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. @@ -60,7 +60,7 @@ import TS_SlowingClock from '../assets/code/ts/src/SlowingClock.lf'; -This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](<../writing-reactors/actions.mdx#logical-actions>), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: +This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](../writing-reactors/actions.mdx#logical-actions), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: ``` Logical time since start: 100000000 nsec. @@ -80,7 +80,7 @@ The simplest use of logical time in Lingua Franca is to invoke a reaction period The ``, which is optional, specifies the time interval between timer events. The ``, which is also optional, specifies the (logical) time interval between when the program starts executing and the first timer event. If no period is given, then the timer event occurs only once. If neither an offset nor a period is specified, then one timer event occurs at program start, simultaneous with the `startup` event. -The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](<../reference/expressions.mdx#basic-expressions>) for allowable units. Consider the following example: +The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](../reference/expressions.mdx#basic-expressions) for allowable units. Consider the following example: import C_Timer from '../assets/code/c/src/Timer.lf'; import Cpp_Timer from '../assets/code/cpp/src/Timer.lf'; @@ -165,7 +165,7 @@ A reaction is always invoked at a well-defined logical time, and logical time do ## Timeout -By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](<../introduction.md#timeout>) or a [`--timeout` command-line option](<../introduction.md#command-line-arguments>). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: +By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](../reference/target-declaration.mdx#timeout) or a [`--timeout` command-line option](../reference/target-declaration.mdx#command-line-arguments). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: ) 0, but may occur at a larger microstep. See [Superdense Time](<../writing-reactors/actions.mdx#superdense-time>) and [Termination](../writing-reactors/termination.mdx). +The **shutdown** trigger typically occurs at [microstep](../writing-reactors/superdense-time.mdx) 0, but may occur at a larger microstep. See [Superdense Time](../writing-reactors/superdense-time.mdx) and [Termination](../writing-reactors/termination.mdx). diff --git a/versioned_docs/version-0.5.0/developer/developer-eclipse-setup-with-oomph.mdx b/versioned_docs/version-0.5.0/developer/developer-eclipse-setup-with-oomph.mdx index d88abcb2c..cc05e402d 100644 --- a/versioned_docs/version-0.5.0/developer/developer-eclipse-setup-with-oomph.mdx +++ b/versioned_docs/version-0.5.0/developer/developer-eclipse-setup-with-oomph.mdx @@ -109,7 +109,7 @@ Hello World. This should print "Hello World". -We strongly recommend browsing the system tests, which provide a concise overview of the capabilities of Lingua Franca. You can set up a project in the IDE for this using [these instructions](<../developer/regression-tests.mdx#browsing-and-editing-examples-in-the-lf-ide>). +We strongly recommend browsing the [itegration tests](regression-tests.mdx), which provide a concise overview of the capabilities of Lingua Franca. ## Working on the Lingua-Franca Compiler diff --git a/versioned_docs/version-0.5.0/embedded/arduino.mdx b/versioned_docs/version-0.5.0/embedded/arduino.mdx index 202412423..173d3ab31 100644 --- a/versioned_docs/version-0.5.0/embedded/arduino.mdx +++ b/versioned_docs/version-0.5.0/embedded/arduino.mdx @@ -3,7 +3,7 @@ title: Arduino description: Developing LF Programs on Arduino. --- -# Overview +## Overview To run Lingua Franca on an Arduino-compatible microcontroller, you can use the `C` target with the `platform` target property set to `arduino`. The Lingua @@ -13,7 +13,7 @@ To flash the compiled sketch onto a board, you need specify a Fully Qualified Board Name (FQBN) as well as the port to which your board is connected. On this page, we explain exactly how to do this. -## Prerequisites +### Prerequisites - You need a development system that runs on macOS or Linux (there is currently no Windows support). - [Arduino CLI](https://arduino.github.io/arduino-cli/) must be installed on your development system. Confirm that your installation works by running: @@ -22,7 +22,7 @@ page, we explain exactly how to do this. arduino-cli version ``` -# Writing a simple Arduino Program +## Writing a simple Arduino Program The most basic Arduino program (Blink) can be defined in LF like so: @@ -56,7 +56,7 @@ can invoke Arduino library functions, just like one would do in the definition of an Arduino `loop()`. For any setup that might be needed at the beginning of execution, a reaction triggered by the built-in `startup` trigger can be used. -## Platform Options +### Platform Options The `platform` property can also be used so specify more details. Along with `name: "arduino"`, you can specify which `board`, `port`, and `baud-rate` you are using. If you want the program @@ -77,14 +77,14 @@ target C { The `board` is necessary for [building](#building) and the `port` is necessary for [flashing](#flashing). -### Baud rate of the serial port +#### Baud rate of the serial port All Arduino boards have at least one serial port (also known as a UART or USART), and some have several. By default, Lingua Franca will assume a default baud rate of 9600. This parameter is tunable by adjusting the `baud-rate` parameter in platform options. -# Building +## Building In order to have `arduino-cli` compile the generated sketch file, a `board` must be specified. If no `board` is set, `lfc` will run in `no-compile` mode, meaning @@ -112,7 +112,7 @@ If you specify your FQBN under `board` in the `platform` target property, `lfc` - for threaded programs (`arduino:mbed` boards), run: `arduino-cli compile -b [FQBN] --build-property compiler.c.extra_flags="-DLF_THREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10" --build-property compiler.cpp.extra_flags="-DLF_THREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10"` -# Flashing +## Flashing Arduino's can be flashed via USB. To find the port oto which your device is connected, run the following command: diff --git a/versioned_docs/version-0.5.0/reference/target-declaration.mdx b/versioned_docs/version-0.5.0/reference/target-declaration.mdx index f9a005f7e..57afe1003 100644 --- a/versioned_docs/version-0.5.0/reference/target-declaration.mdx +++ b/versioned_docs/version-0.5.0/reference/target-declaration.mdx @@ -29,7 +29,7 @@ A target specification may have optional parameters, the names and values of whi - [**cargo-dependencies**](#cargo-dependencies): (Rust only) list of dependencies to include in the generated Cargo.toml file. - [**cargo-features**](#cargo-features): (Rust only) List of string names of features to include. - [**cmake**](#cmake): Whether to use cmake for building. -- [**cmake-include**](#cmake): List of paths to cmake files to guide compilation. +- [**cmake-include**](#cmake-include): List of paths to cmake files to guide compilation. - [**compiler**](#compiler): A string giving the name of the target language compiler to use. - [**docker**](#docker): A boolean to generate a Dockerfile. - [**external-runtime-path**](#external-runtime-path): Specify a pre-compiled external runtime library located to link to instead of the default. @@ -45,7 +45,7 @@ A target specification may have optional parameters, the names and values of whi - [**rust-include**](#rust-include): (Rust only) A set of Rust modules in the generated project. - [**scheduler**](#scheduler): (C only) Specification of the scheduler to use. - [**single-file-project**](#single-file-project): (Rust only) If true, enables [single-file project layout](target-language-details/?target-languages=rs#file-layout). -- [**threading**](#threading): Whether to use multiple threads. +- [**single-threaded**](#single-threaded): Whether to use multiple threads. - [**timeout**](#timeout): A time value (with units) specifying the logical stop time of execution. See [Termination](../writing-reactors/termination.mdx). - [**workers**](#workers): If using multiple threads, how many worker threads to create. @@ -610,7 +610,7 @@ This argument takes a string (with quotation marks) containing any tag, branch n This target does not support the `rust-include` target option. -This specifies a set of Rust modules in the generated project. See [Linking support files](#linking-support-files). +This specifies a set of Rust modules in the generated project. @@ -632,18 +632,18 @@ This specifies the scheduler to use. See[Target Language Details](<../reference/ This target does not support the `single-file-project` target option. -If true, enables [single-file project layout](#single-file-layout). +If true, enables single-file project layout. -## threading +## single-threaded -This target does not support the `threading` target option. +This target does not support the `single-threaded` target option. -If threading is disabled (by setting `threading` to `false`), then no thread library is used, and the `lf_schedule()` function is not thread safe. This setting is incompatible with asynchronously scheduling any physical actions and hence this parameter will be ignored for programs that have physical actions. +If threading is disabled (by setting `single-threaded` to `true`), then no thread library is used, and the `lf_schedule()` function is not thread safe. This setting is incompatible with asynchronously scheduling any physical actions and hence this parameter will be ignored for programs that have physical actions. See [workers](#workers). @@ -667,7 +667,7 @@ A time value (with units) specifying the logical stop time of execution. See [Te This target does not support the `workers` target option. -This parameter takes a non-negative integer and specifies the number of worker threads to execute the generated program. If threading is turned on (the default, see [threading](#threading)), then the generated code will use a target platform thread library and generate multi-threaded code. This can transparently execute reactions that have no dependence on one another in parallel on multiple cores. By default, threading is turned on, and the `workers` property is set to `0`, which means that the number of workers is determined by the runtime system. Typically, it will be set to the number of cores on the machine running the code. To use a different number of worker threads, give a positive integer for this target parameter. +This parameter takes a non-negative integer and specifies the number of worker threads to execute the generated program. If threading is turned on (the default, see [single-threaded](#single-threaded)), then the generated code will use a target platform thread library and generate multi-threaded code. This can transparently execute reactions that have no dependence on one another in parallel on multiple cores. By default, threading is turned on, and the `workers` property is set to `0`, which means that the number of workers is determined by the runtime system. Typically, it will be set to the number of cores on the machine running the code. To use a different number of worker threads, give a positive integer for this target parameter. With value `0`, the runtime engine is free to choose the number of worker threads to use. Typically, this will equal the number of hardware threads on the machine on which the Lingua Franca code generator is run. @@ -710,7 +710,7 @@ Any errors in command-line arguments result in printing the above information. T ### Custom Command-Line Arguments -User-defined command-line arguments may be created by giving the main reactor [parameters](#using-parameters). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). +User-defined command-line arguments may be created by giving the main reactor [parameters](../writing-reactors/parameters-and-state-variables.mdx#parameter-declaration). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). Note: Custom arguments may not have the same names as standard arguments like `timeout` or `keepalive`. @@ -787,7 +787,7 @@ The generated C program understands the following command-line arguments, each o - `-f, --fast [true | false]`: Specifies whether to wait for physical time to match logical time. The default is `false`. If this is `true`, then the program will execute as fast as possible, letting logical time advance faster than physical time. - `-o, --timeout `: Stop execution when logical time has advanced by the specified _duration_. The units can be any of nsec, usec, msec, sec, minute, hour, day, week, or the plurals of those. -- `-w, --workers `: Executed using \ worker threads if possible. This option is ignored in the single-threaded version. That is, it is ignored if a `threading` option was given in the target properties with value `false`. +- `-w, --workers `: Executed using \ worker threads if possible. This option is ignored in the single-threaded version. That is, it is ignored if a `single-threaded` option was `true` in the target properties. - `-i, --id `: The ID of the federation that this reactor will join. Any other command-line arguments result in printing the above information. @@ -800,7 +800,7 @@ The generated C++ program understands the following command-line arguments, each - `-w, --workers `: Use n worker threads for executing reactions. - `--help`: Print the above information. -If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary (see [Using Parameters](#using-parameters)). +If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary. The Python target does not currently support any command-line arguments. You must specify properties as target parameters. @@ -812,7 +812,7 @@ The generated executable may feature a command-line interface (CLI), if it uses - `--timeout -The Python supports the [logging](<../introduction.md#logging>) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). +The Python supports the [logging](target-declaration.mdx#logging) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). @@ -2787,7 +2787,7 @@ The executable reacts to the environment variable `RUST_LOG`, which sets the log Error and warning logs are on by default. Enabling a level enables all greater levels (i.e., `RUST_LOG=info` also enables `warn` and `error`, but not `trace` or `debug`). -Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](<../introduction.md#command-line-arguments>). +Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](target-declaration.mdx#command-line-arguments). Note that the `logging` target property is ignored, as its levels do not match the Rust standard levels we use (those of the [`log` crate](https://docs.rs/log/)). @@ -2961,7 +2961,7 @@ primitives and sleep functions. ### Multithreaded Implementation -By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](<../introduction.md#threading>) statement or the `--workers` [command-line argument](<../introduction.md#command-line-arguments>) is given. +By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](target-declaration.mdx#workers) statement or the `--workers` [command-line argument](target-declaration.mdx#command-line-arguments) is given. Upon initialization, the main thread will create the specified number of worker threads. Execution proceeds in a manner similar to the [single threaded implementation](#single-threaded-implementation) @@ -2970,7 +2970,7 @@ The execution algorithm ensures that no reaction executes until all reactions th ### Single Threaded Implementation -By giving the `single-threaded` [target option](<../introduction.md#single-threaded>) or the `--single-threaded` [command-line argument](<../introduction.md#command-line-arguments>), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. +By giving the `single-threaded` [target option](target-declaration.mdx#single-threaded) or the `--single-threaded` [command-line argument](target-declaration.mdx#command-line-arguments), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. The execution strategy is to have two queues of pending accessor invocations, one that is sorted by tag (the **event queue**) and one that is sorted by priority (the **reaction queue**). @@ -2978,9 +2978,9 @@ Execution proceeds as follows: 1. At initialization, an event for each timer is put on the event queue and logical time is initialized to the current time, represented as the number of nanoseconds elapsed since January 1, 1970. -2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](<../introduction.md#command-line-arguments>) is given). +2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). -3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](<../introduction.md#command-line-arguments>) is given). Then advance logical time to match that earliest timestamp. +3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). Then advance logical time to match that earliest timestamp. 4. Execute reactions in order of priority from the reaction queue. These reactions may produce outputs, which results in more events getting put on the reaction queue. Those reactions are assured of having lower priority than the reaction that is executing. If a reaction calls `lf_schedule()`, an event will be put on the event queue, not the reaction queue. @@ -2994,7 +2994,7 @@ Unlike the C target, the Cpp target implements more of the analysis and setup of -The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [threading](<../introduction.md#threading>) target property can be used to override this behavior. +The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. Running [lfc](../tools/command-line-tools.mdx) on a `XXX.lf` program that uses the Python target specification on a Linux machine will create the following files (other operating systems will have @@ -3179,7 +3179,7 @@ The Lingua Franca compiler automatically invokes other programs as it compiles a ### package.json -Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. +Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](../writing-reactors/preambles.mdx#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. ### tsconfig.json @@ -3191,7 +3191,7 @@ If the `tsc` type check was successful, the Lingua Franca compiler uses `babel` ### Debugging Type Errors -Let's take the [minimal reactor example](#a-minimal-example), and intentionally break it by adding a type error into the reaction. +Let's take the minimal reactor example, and intentionally break it by adding a type error into the reaction. ```lf-ts target TypeScript; @@ -3285,13 +3285,13 @@ These utility functions may be called within a TypeScript reaction: `util.getCurrentTag(): Tag` Gets the current (logical) tag. See [Tags](#tags). -`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#timed-behavior). +`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#time). -`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#timed-behavior). +`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#time). -`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#time). -`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#time). `util.success(): void` Invokes the [reactor-ts](https://github.com/lf-lang/reactor-ts) App's default success callback. FIXME: Currently doesn't do anything in Lingua Franca. @@ -3350,7 +3350,7 @@ See [Target Declaration](../introduction.md) for the full list of supported targ ### The Executable -The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](<../introduction.md#command-line-arguments>) for details. +The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](target-declaration.mdx#command-line-arguments) for details. ### File layout diff --git a/versioned_docs/version-0.5.0/reference/tracing.mdx b/versioned_docs/version-0.5.0/reference/tracing.mdx index 9359ec581..1e1f8e0ec 100644 --- a/versioned_docs/version-0.5.0/reference/tracing.mdx +++ b/versioned_docs/version-0.5.0/reference/tracing.mdx @@ -13,7 +13,7 @@ import { Tracing is a powerful tool when it comes to analysis and debugging of applications. Unfortunately, most tracing tools that are readily available are designed specifically for analyzing processes, threads and system calls. Specialized tools are required to enable analysis that is tailored to an alternative model of computation such as Reactors. The tools should be capable of understanding the fundamental concepts of the model, such as the distinction between logical and physical time, as well as structural units such as reactors and reactions. This page gives an overview of the currently supported trace mechanism, as well as an outline of alternative tools that could be useful in the future. -Tracing is different from [logging](<../introduction.md#logging>). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. +Tracing is different from [logging](target-declaration.mdx#logging). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. Tracing is currently supported in the C, Python, and C++ targets. The mechanism used in C and Python is different from that used in C++. Tracing in C++ requires third-party tools that may only be available in Linux. Tracing in C and Python does not require any third-party tools. diff --git a/versioned_docs/version-0.5.0/tutorial-videos.mdx b/versioned_docs/version-0.5.0/tutorial-videos.mdx index 16afb93ff..456f85b79 100644 --- a/versioned_docs/version-0.5.0/tutorial-videos.mdx +++ b/versioned_docs/version-0.5.0/tutorial-videos.mdx @@ -9,12 +9,12 @@ A [video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9Y **Useful links:** - [Complete video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9YEjulS4o) -- [Part I: Introduction](#introduction) -- [Part II: Hello World](#hello) -- [Part III: Target Languages](#target) -- [Part IV: Basic Concepts](#concepts) -- [Part V: Concurrency and Performance](#concurrency) -- [Part VI: Research Overview](#research) +- [Part I: Introduction](#part-i-introduction) +- [Part II: Hello World](#part-ii-hello-world) +- [Part III: Target Languages](#part-iii-target-languages) +- [Part IV: Basic Concepts](#part-iv-basic-concepts) +- [Part V: Concurrency and Performance](#part-v-concurrency) +- [Part VI: Research Overview](#part-vi-research-overview) - [Slides](https://docs.google.com/presentation/d/14cfIMmkBFwt6NOj2ujVs7YXPAXYsoHgLS2rUgBM-Deg/present?slide=id.g623f095f12_0_0) ## Part I: Introduction diff --git a/versioned_docs/version-0.5.0/writing-reactors/actions.mdx b/versioned_docs/version-0.5.0/writing-reactors/actions.mdx index a999cda3a..16a15ae7e 100644 --- a/versioned_docs/version-0.5.0/writing-reactors/actions.mdx +++ b/versioned_docs/version-0.5.0/writing-reactors/actions.mdx @@ -133,7 +133,7 @@ Action triggered at logical time 603669000 nsec after start. ... ``` -Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](<../introduction.md#fast>) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. +Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](../reference/target-declaration.mdx#fast) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. Whereas logical actions are required to be scheduled within a reaction of the reactor that declares the action, physical actions can be scheduled by code that is outside the Lingua Franca system. For example, some other thread or a callback function may call `schedule()`, passing it a physical action. For example: diff --git a/versioned_docs/version-0.5.0/writing-reactors/composing-reactors.mdx b/versioned_docs/version-0.5.0/writing-reactors/composing-reactors.mdx index daef9a51d..e8dde0c82 100644 --- a/versioned_docs/version-0.5.0/writing-reactors/composing-reactors.mdx +++ b/versioned_docs/version-0.5.0/writing-reactors/composing-reactors.mdx @@ -172,7 +172,7 @@ Connections may include a **logical delay** using the `after` keyword, as follow where `` can be any of the forms described in [Expressions](../reference/expressions.mdx). -The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/actions.mdx#superdense-time>) later than the event that triggered it. +The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/superdense-time.mdx>) later than the event that triggered it. ## Physical Connections diff --git a/versioned_docs/version-0.5.0/writing-reactors/multiports-and-banks.mdx b/versioned_docs/version-0.5.0/writing-reactors/multiports-and-banks.mdx index d0beb8559..31fc6d8c7 100644 --- a/versioned_docs/version-0.5.0/writing-reactors/multiports-and-banks.mdx +++ b/versioned_docs/version-0.5.0/writing-reactors/multiports-and-banks.mdx @@ -379,7 +379,7 @@ The syntax `(a.out)+` means "repeat the output port `a.out` one or more times as -Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#Combining-Banks-and-Multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: +Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#combining-banks-and-multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: import C_Interleaved from '../assets/code/c/src/Interleaved.lf'; import Cpp_Interleaved from '../assets/code/cpp/src/Interleaved.lf'; diff --git a/versioned_docs/version-0.5.0/writing-reactors/preambles.mdx b/versioned_docs/version-0.5.0/writing-reactors/preambles.mdx index fb7cd6793..a78e3bb67 100644 --- a/versioned_docs/version-0.5.0/writing-reactors/preambles.mdx +++ b/versioned_docs/version-0.5.0/writing-reactors/preambles.mdx @@ -326,7 +326,7 @@ Your platform is Linux By putting import in the `preamble`, the module becomes available in all reactions of this reactor using the `self` modifier. -**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx#python-target-implementation-details>). +**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx>). Alternatively, you can define a `preamble` outside any reactor definition. Such a `preamble` can be used for functions such as import or to define a global function. The following example shows importing the [hello](https://github.com/lf-lang/lingua-franca/blob/master/test/Python/src/include/hello.py) module: @@ -432,7 +432,7 @@ Converted string 42 to number 42 ### Using Node Modules -Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](#preamble) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](#typescript-target-implementation-details) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. +Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](../writing-reactors/preambles.mdx) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](../reference/target-language-details.mdx) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. The important takeaway here is with the package.json file and the compiled JavaScript in the Foo/dist/ directory, you have a standard Node.js program that executes as such. You can modify and debug it just as you would a Node.js program. diff --git a/versioned_docs/version-0.5.0/writing-reactors/termination.mdx b/versioned_docs/version-0.5.0/writing-reactors/termination.mdx index fc9b8244f..58a43bf71 100644 --- a/versioned_docs/version-0.5.0/writing-reactors/termination.mdx +++ b/versioned_docs/version-0.5.0/writing-reactors/termination.mdx @@ -29,7 +29,7 @@ We address each of these in turn. ## Timeout -The [target property `timeout`](<../introduction.md#timeout>) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). +The [target property `timeout`](../reference/target-declaration.mdx#timeout) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). There is a significant subtlety when using [physical connections](<../writing-reactors/composing-reactors.mdx#physical-connections>), which are connections using the syntax `~>`. Such connections specify that the tag at the receiving end will be based on the physical time at which the message is received. If the tag assigned at the receiving end is greater than the final tag, then the message is lost. Hence, **messages sent near the `timeout` time are likely to be lost!** diff --git a/versioned_docs/version-0.5.0/writing-reactors/time-and-timers.mdx b/versioned_docs/version-0.5.0/writing-reactors/time-and-timers.mdx index 9f7ed7d03..41467929c 100644 --- a/versioned_docs/version-0.5.0/writing-reactors/time-and-timers.mdx +++ b/versioned_docs/version-0.5.0/writing-reactors/time-and-timers.mdx @@ -15,7 +15,7 @@ import { A key property of Lingua Franca is **logical time**. All events occur at an instant in logical time. By default, the runtime system does its best to align logical time with **physical time**, which is some measurement of time on the execution platform. The **lag** is defined to be physical time minus logical time, and the goal of the runtime system is maintain a small non-negative lag. -The **lag** is allowed to go negative only if the [`fast`](<../reference/target-declaration#fast>) target property or the [`--fast`](<../reference/target-declaration#command-line-arguments>) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. +The **lag** is allowed to go negative only if the [`fast`](../reference/target-declaration.mdx#fast) target property or the [`--fast`](../reference/target-declaration.mdx#command-line-arguments) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. @@ -60,7 +60,7 @@ import TS_SlowingClock from '../assets/code/ts/src/SlowingClock.lf'; -This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](<../writing-reactors/actions.mdx#logical-actions>), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: +This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](../writing-reactors/actions.mdx#logical-actions), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: ``` Logical time since start: 100000000 nsec. @@ -80,7 +80,7 @@ The simplest use of logical time in Lingua Franca is to invoke a reaction period The ``, which is optional, specifies the time interval between timer events. The ``, which is also optional, specifies the (logical) time interval between when the program starts executing and the first timer event. If no period is given, then the timer event occurs only once. If neither an offset nor a period is specified, then one timer event occurs at program start, simultaneous with the `startup` event. -The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](<../reference/expressions.mdx#basic-expressions>) for allowable units. Consider the following example: +The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](../reference/expressions.mdx#basic-expressions) for allowable units. Consider the following example: import C_Timer from '../assets/code/c/src/Timer.lf'; import Cpp_Timer from '../assets/code/cpp/src/Timer.lf'; @@ -165,7 +165,7 @@ A reaction is always invoked at a well-defined logical time, and logical time do ## Timeout -By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](<../introduction.md#timeout>) or a [`--timeout` command-line option](<../introduction.md#command-line-arguments>). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: +By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](../reference/target-declaration.mdx#timeout) or a [`--timeout` command-line option](../reference/target-declaration.mdx#command-line-arguments). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: ) 0, but may occur at a larger microstep. See [Superdense Time](<../writing-reactors/actions.mdx#superdense-time>) and [Termination](../writing-reactors/termination.mdx). +The **shutdown** trigger typically occurs at [microstep](../writing-reactors/superdense-time.mdx) 0, but may occur at a larger microstep. See [Superdense Time](../writing-reactors/superdense-time.mdx) and [Termination](../writing-reactors/termination.mdx). diff --git a/versioned_docs/version-0.6.0/developer/developer-eclipse-setup-with-oomph.mdx b/versioned_docs/version-0.6.0/developer/developer-eclipse-setup-with-oomph.mdx index d88abcb2c..cc05e402d 100644 --- a/versioned_docs/version-0.6.0/developer/developer-eclipse-setup-with-oomph.mdx +++ b/versioned_docs/version-0.6.0/developer/developer-eclipse-setup-with-oomph.mdx @@ -109,7 +109,7 @@ Hello World. This should print "Hello World". -We strongly recommend browsing the system tests, which provide a concise overview of the capabilities of Lingua Franca. You can set up a project in the IDE for this using [these instructions](<../developer/regression-tests.mdx#browsing-and-editing-examples-in-the-lf-ide>). +We strongly recommend browsing the [itegration tests](regression-tests.mdx), which provide a concise overview of the capabilities of Lingua Franca. ## Working on the Lingua-Franca Compiler diff --git a/versioned_docs/version-0.6.0/embedded/arduino.mdx b/versioned_docs/version-0.6.0/embedded/arduino.mdx index 202412423..173d3ab31 100644 --- a/versioned_docs/version-0.6.0/embedded/arduino.mdx +++ b/versioned_docs/version-0.6.0/embedded/arduino.mdx @@ -3,7 +3,7 @@ title: Arduino description: Developing LF Programs on Arduino. --- -# Overview +## Overview To run Lingua Franca on an Arduino-compatible microcontroller, you can use the `C` target with the `platform` target property set to `arduino`. The Lingua @@ -13,7 +13,7 @@ To flash the compiled sketch onto a board, you need specify a Fully Qualified Board Name (FQBN) as well as the port to which your board is connected. On this page, we explain exactly how to do this. -## Prerequisites +### Prerequisites - You need a development system that runs on macOS or Linux (there is currently no Windows support). - [Arduino CLI](https://arduino.github.io/arduino-cli/) must be installed on your development system. Confirm that your installation works by running: @@ -22,7 +22,7 @@ page, we explain exactly how to do this. arduino-cli version ``` -# Writing a simple Arduino Program +## Writing a simple Arduino Program The most basic Arduino program (Blink) can be defined in LF like so: @@ -56,7 +56,7 @@ can invoke Arduino library functions, just like one would do in the definition of an Arduino `loop()`. For any setup that might be needed at the beginning of execution, a reaction triggered by the built-in `startup` trigger can be used. -## Platform Options +### Platform Options The `platform` property can also be used so specify more details. Along with `name: "arduino"`, you can specify which `board`, `port`, and `baud-rate` you are using. If you want the program @@ -77,14 +77,14 @@ target C { The `board` is necessary for [building](#building) and the `port` is necessary for [flashing](#flashing). -### Baud rate of the serial port +#### Baud rate of the serial port All Arduino boards have at least one serial port (also known as a UART or USART), and some have several. By default, Lingua Franca will assume a default baud rate of 9600. This parameter is tunable by adjusting the `baud-rate` parameter in platform options. -# Building +## Building In order to have `arduino-cli` compile the generated sketch file, a `board` must be specified. If no `board` is set, `lfc` will run in `no-compile` mode, meaning @@ -112,7 +112,7 @@ If you specify your FQBN under `board` in the `platform` target property, `lfc` - for threaded programs (`arduino:mbed` boards), run: `arduino-cli compile -b [FQBN] --build-property compiler.c.extra_flags="-DLF_THREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10" --build-property compiler.cpp.extra_flags="-DLF_THREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10"` -# Flashing +## Flashing Arduino's can be flashed via USB. To find the port oto which your device is connected, run the following command: diff --git a/versioned_docs/version-0.6.0/reference/target-declaration.mdx b/versioned_docs/version-0.6.0/reference/target-declaration.mdx index bc70c242c..0aa0ec908 100644 --- a/versioned_docs/version-0.6.0/reference/target-declaration.mdx +++ b/versioned_docs/version-0.6.0/reference/target-declaration.mdx @@ -28,7 +28,7 @@ A target specification may have optional parameters, the names and values of whi - [**build-type**](#build-type): One of Debug (the default), Release, RelWithDebInfo and MinSizeRel. - [**cargo-dependencies**](#cargo-dependencies): (Rust only) list of dependencies to include in the generated Cargo.toml file. - [**cargo-features**](#cargo-features): (Rust only) List of string names of features to include. -- [**cmake-include**](#cmake): List of paths to cmake files to guide compilation. +- [**cmake-include**](#cmake-include): List of paths to cmake files to guide compilation. - [**compiler**](#compiler): A string giving the name of the target language compiler to use. - [**compiler-flags**](#compiler-flags): An arrays of strings giving options to be passed to the target compiler. - [**docker**](#docker): A boolean to generate a Dockerfile. @@ -556,7 +556,7 @@ This argument takes a string (with quotation marks) containing any tag, branch n This target does not support the `rust-include` target option. -This specifies a set of Rust modules in the generated project. See [Linking support files](#linking-support-files). +This specifies a set of Rust modules in the generated project. @@ -578,7 +578,7 @@ This specifies the scheduler to use. See[Target Language Details](<../reference/ This target does not support the `single-file-project` target option. -If true, enables [single-file project layout](#single-file-layout). +If true, enables single-file project layout. @@ -652,7 +652,7 @@ Any errors in command-line arguments result in printing the above information. T ### Custom Command-Line Arguments -User-defined command-line arguments may be created by giving the main reactor [parameters](#using-parameters). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). +User-defined command-line arguments may be created by giving the main reactor [parameters](../writing-reactors/parameters-and-state-variables.mdx#parameter-declaration). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). Note: Custom arguments may not have the same names as standard arguments like `timeout` or `keepalive`. @@ -742,7 +742,7 @@ The generated C++ program understands the following command-line arguments, each - `-w, --workers `: Use n worker threads for executing reactions. - `--help`: Print the above information. -If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary (see [Using Parameters](#using-parameters)). +If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary. The Python target does not currently support any command-line arguments. You must specify properties as target parameters. @@ -754,7 +754,7 @@ The generated executable may feature a command-line interface (CLI), if it uses - `--timeout -The Python supports the [logging](<../introduction.md#logging>) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). +The Python supports the [logging](target-declaration.mdx#logging) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). @@ -2787,7 +2787,7 @@ The executable reacts to the environment variable `RUST_LOG`, which sets the log Error and warning logs are on by default. Enabling a level enables all greater levels (i.e., `RUST_LOG=info` also enables `warn` and `error`, but not `trace` or `debug`). -Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](<../introduction.md#command-line-arguments>). +Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](target-declaration.mdx#command-line-arguments). Note that the `logging` target property is ignored, as its levels do not match the Rust standard levels we use (those of the [`log` crate](https://docs.rs/log/)). @@ -2961,7 +2961,7 @@ primitives and sleep functions. ### Multithreaded Implementation -By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](<../introduction.md#threading>) statement or the `--workers` [command-line argument](<../introduction.md#command-line-arguments>) is given. +By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](target-declaration.mdx#workers) statement or the `--workers` [command-line argument](target-declaration.mdx#command-line-arguments) is given. Upon initialization, the main thread will create the specified number of worker threads. Execution proceeds in a manner similar to the [single threaded implementation](#single-threaded-implementation) @@ -2970,7 +2970,7 @@ The execution algorithm ensures that no reaction executes until all reactions th ### Single Threaded Implementation -By giving the `single-threaded` [target option](<../introduction.md#single-threaded>) or the `--single-threaded` [command-line argument](<../introduction.md#command-line-arguments>), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. +By giving the `single-threaded` [target option](target-declaration.mdx#single-threaded) or the `--single-threaded` [command-line argument](target-declaration.mdx#command-line-arguments), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. The execution strategy is to have two queues of pending accessor invocations, one that is sorted by tag (the **event queue**) and one that is sorted by priority (the **reaction queue**). @@ -2978,9 +2978,9 @@ Execution proceeds as follows: 1. At initialization, an event for each timer is put on the event queue and logical time is initialized to the current time, represented as the number of nanoseconds elapsed since January 1, 1970. -2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](<../introduction.md#command-line-arguments>) is given). +2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). -3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](<../introduction.md#command-line-arguments>) is given). Then advance logical time to match that earliest timestamp. +3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). Then advance logical time to match that earliest timestamp. 4. Execute reactions in order of priority from the reaction queue. These reactions may produce outputs, which results in more events getting put on the reaction queue. Those reactions are assured of having lower priority than the reaction that is executing. If a reaction calls `lf_schedule()`, an event will be put on the event queue, not the reaction queue. @@ -2994,7 +2994,7 @@ Unlike the C target, the Cpp target implements more of the analysis and setup of -The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [threading](<../introduction.md#threading>) target property can be used to override this behavior. +The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [single-threaded](target-declaration.mdx#single-threaded) target property can be used to override this behavior. Running [lfc](../tools/command-line-tools.mdx) on a `XXX.lf` program that uses the Python target specification on a Linux machine will create the following files (other operating systems will have @@ -3179,7 +3179,7 @@ The Lingua Franca compiler automatically invokes other programs as it compiles a ### package.json -Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. +Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](../writing-reactors/preambles.mdx#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. ### tsconfig.json @@ -3191,7 +3191,7 @@ If the `tsc` type check was successful, the Lingua Franca compiler uses `babel` ### Debugging Type Errors -Let's take the [minimal reactor example](#a-minimal-example), and intentionally break it by adding a type error into the reaction. +Let's take the minimal reactor example, and intentionally break it by adding a type error into the reaction. ```lf-ts target TypeScript; @@ -3285,13 +3285,13 @@ These utility functions may be called within a TypeScript reaction: `util.getCurrentTag(): Tag` Gets the current (logical) tag. See [Tags](#tags). -`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#timed-behavior). +`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#time). -`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#timed-behavior). +`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#time). -`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#time). -`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#time). `util.success(): void` Invokes the [reactor-ts](https://github.com/lf-lang/reactor-ts) App's default success callback. FIXME: Currently doesn't do anything in Lingua Franca. @@ -3350,7 +3350,7 @@ See [Target Declaration](../introduction.md) for the full list of supported targ ### The Executable -The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](<../introduction.md#command-line-arguments>) for details. +The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](target-declaration.mdx#command-line-arguments) for details. ### File layout diff --git a/versioned_docs/version-0.6.0/reference/tracing.mdx b/versioned_docs/version-0.6.0/reference/tracing.mdx index 9359ec581..1e1f8e0ec 100644 --- a/versioned_docs/version-0.6.0/reference/tracing.mdx +++ b/versioned_docs/version-0.6.0/reference/tracing.mdx @@ -13,7 +13,7 @@ import { Tracing is a powerful tool when it comes to analysis and debugging of applications. Unfortunately, most tracing tools that are readily available are designed specifically for analyzing processes, threads and system calls. Specialized tools are required to enable analysis that is tailored to an alternative model of computation such as Reactors. The tools should be capable of understanding the fundamental concepts of the model, such as the distinction between logical and physical time, as well as structural units such as reactors and reactions. This page gives an overview of the currently supported trace mechanism, as well as an outline of alternative tools that could be useful in the future. -Tracing is different from [logging](<../introduction.md#logging>). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. +Tracing is different from [logging](target-declaration.mdx#logging). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. Tracing is currently supported in the C, Python, and C++ targets. The mechanism used in C and Python is different from that used in C++. Tracing in C++ requires third-party tools that may only be available in Linux. Tracing in C and Python does not require any third-party tools. diff --git a/versioned_docs/version-0.6.0/tutorial-videos.mdx b/versioned_docs/version-0.6.0/tutorial-videos.mdx index 16afb93ff..456f85b79 100644 --- a/versioned_docs/version-0.6.0/tutorial-videos.mdx +++ b/versioned_docs/version-0.6.0/tutorial-videos.mdx @@ -9,12 +9,12 @@ A [video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9Y **Useful links:** - [Complete video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9YEjulS4o) -- [Part I: Introduction](#introduction) -- [Part II: Hello World](#hello) -- [Part III: Target Languages](#target) -- [Part IV: Basic Concepts](#concepts) -- [Part V: Concurrency and Performance](#concurrency) -- [Part VI: Research Overview](#research) +- [Part I: Introduction](#part-i-introduction) +- [Part II: Hello World](#part-ii-hello-world) +- [Part III: Target Languages](#part-iii-target-languages) +- [Part IV: Basic Concepts](#part-iv-basic-concepts) +- [Part V: Concurrency and Performance](#part-v-concurrency) +- [Part VI: Research Overview](#part-vi-research-overview) - [Slides](https://docs.google.com/presentation/d/14cfIMmkBFwt6NOj2ujVs7YXPAXYsoHgLS2rUgBM-Deg/present?slide=id.g623f095f12_0_0) ## Part I: Introduction diff --git a/versioned_docs/version-0.6.0/writing-reactors/actions.mdx b/versioned_docs/version-0.6.0/writing-reactors/actions.mdx index a999cda3a..16a15ae7e 100644 --- a/versioned_docs/version-0.6.0/writing-reactors/actions.mdx +++ b/versioned_docs/version-0.6.0/writing-reactors/actions.mdx @@ -133,7 +133,7 @@ Action triggered at logical time 603669000 nsec after start. ... ``` -Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](<../introduction.md#fast>) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. +Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](../reference/target-declaration.mdx#fast) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. Whereas logical actions are required to be scheduled within a reaction of the reactor that declares the action, physical actions can be scheduled by code that is outside the Lingua Franca system. For example, some other thread or a callback function may call `schedule()`, passing it a physical action. For example: diff --git a/versioned_docs/version-0.6.0/writing-reactors/composing-reactors.mdx b/versioned_docs/version-0.6.0/writing-reactors/composing-reactors.mdx index daef9a51d..e8dde0c82 100644 --- a/versioned_docs/version-0.6.0/writing-reactors/composing-reactors.mdx +++ b/versioned_docs/version-0.6.0/writing-reactors/composing-reactors.mdx @@ -172,7 +172,7 @@ Connections may include a **logical delay** using the `after` keyword, as follow where `` can be any of the forms described in [Expressions](../reference/expressions.mdx). -The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/actions.mdx#superdense-time>) later than the event that triggered it. +The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/superdense-time.mdx>) later than the event that triggered it. ## Physical Connections diff --git a/versioned_docs/version-0.6.0/writing-reactors/multiports-and-banks.mdx b/versioned_docs/version-0.6.0/writing-reactors/multiports-and-banks.mdx index d0beb8559..31fc6d8c7 100644 --- a/versioned_docs/version-0.6.0/writing-reactors/multiports-and-banks.mdx +++ b/versioned_docs/version-0.6.0/writing-reactors/multiports-and-banks.mdx @@ -379,7 +379,7 @@ The syntax `(a.out)+` means "repeat the output port `a.out` one or more times as -Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#Combining-Banks-and-Multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: +Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#combining-banks-and-multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: import C_Interleaved from '../assets/code/c/src/Interleaved.lf'; import Cpp_Interleaved from '../assets/code/cpp/src/Interleaved.lf'; diff --git a/versioned_docs/version-0.6.0/writing-reactors/preambles.mdx b/versioned_docs/version-0.6.0/writing-reactors/preambles.mdx index fb7cd6793..a78e3bb67 100644 --- a/versioned_docs/version-0.6.0/writing-reactors/preambles.mdx +++ b/versioned_docs/version-0.6.0/writing-reactors/preambles.mdx @@ -326,7 +326,7 @@ Your platform is Linux By putting import in the `preamble`, the module becomes available in all reactions of this reactor using the `self` modifier. -**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx#python-target-implementation-details>). +**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx>). Alternatively, you can define a `preamble` outside any reactor definition. Such a `preamble` can be used for functions such as import or to define a global function. The following example shows importing the [hello](https://github.com/lf-lang/lingua-franca/blob/master/test/Python/src/include/hello.py) module: @@ -432,7 +432,7 @@ Converted string 42 to number 42 ### Using Node Modules -Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](#preamble) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](#typescript-target-implementation-details) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. +Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](../writing-reactors/preambles.mdx) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](../reference/target-language-details.mdx) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. The important takeaway here is with the package.json file and the compiled JavaScript in the Foo/dist/ directory, you have a standard Node.js program that executes as such. You can modify and debug it just as you would a Node.js program. diff --git a/versioned_docs/version-0.6.0/writing-reactors/termination.mdx b/versioned_docs/version-0.6.0/writing-reactors/termination.mdx index fc9b8244f..25b336857 100644 --- a/versioned_docs/version-0.6.0/writing-reactors/termination.mdx +++ b/versioned_docs/version-0.6.0/writing-reactors/termination.mdx @@ -29,9 +29,9 @@ We address each of these in turn. ## Timeout -The [target property `timeout`](<../introduction.md#timeout>) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). +The [target property `timeout`](../reference/target-declaration.mdx#timeout) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). -There is a significant subtlety when using [physical connections](<../writing-reactors/composing-reactors.mdx#physical-connections>), which are connections using the syntax `~>`. Such connections specify that the tag at the receiving end will be based on the physical time at which the message is received. If the tag assigned at the receiving end is greater than the final tag, then the message is lost. Hence, **messages sent near the `timeout` time are likely to be lost!** +There is a significant subtlety when using [physical connections](composing-reactors.mdx#physical-connections), which are connections using the syntax `~>`. Such connections specify that the tag at the receiving end will be based on the physical time at which the message is received. If the tag assigned at the receiving end is greater than the final tag, then the message is lost. Hence, **messages sent near the `timeout` time are likely to be lost!** ## Starvation diff --git a/versioned_docs/version-0.6.0/writing-reactors/time-and-timers.mdx b/versioned_docs/version-0.6.0/writing-reactors/time-and-timers.mdx index 9f7ed7d03..41467929c 100644 --- a/versioned_docs/version-0.6.0/writing-reactors/time-and-timers.mdx +++ b/versioned_docs/version-0.6.0/writing-reactors/time-and-timers.mdx @@ -15,7 +15,7 @@ import { A key property of Lingua Franca is **logical time**. All events occur at an instant in logical time. By default, the runtime system does its best to align logical time with **physical time**, which is some measurement of time on the execution platform. The **lag** is defined to be physical time minus logical time, and the goal of the runtime system is maintain a small non-negative lag. -The **lag** is allowed to go negative only if the [`fast`](<../reference/target-declaration#fast>) target property or the [`--fast`](<../reference/target-declaration#command-line-arguments>) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. +The **lag** is allowed to go negative only if the [`fast`](../reference/target-declaration.mdx#fast) target property or the [`--fast`](../reference/target-declaration.mdx#command-line-arguments) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. @@ -60,7 +60,7 @@ import TS_SlowingClock from '../assets/code/ts/src/SlowingClock.lf'; -This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](<../writing-reactors/actions.mdx#logical-actions>), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: +This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](../writing-reactors/actions.mdx#logical-actions), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: ``` Logical time since start: 100000000 nsec. @@ -80,7 +80,7 @@ The simplest use of logical time in Lingua Franca is to invoke a reaction period The ``, which is optional, specifies the time interval between timer events. The ``, which is also optional, specifies the (logical) time interval between when the program starts executing and the first timer event. If no period is given, then the timer event occurs only once. If neither an offset nor a period is specified, then one timer event occurs at program start, simultaneous with the `startup` event. -The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](<../reference/expressions.mdx#basic-expressions>) for allowable units. Consider the following example: +The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](../reference/expressions.mdx#basic-expressions) for allowable units. Consider the following example: import C_Timer from '../assets/code/c/src/Timer.lf'; import Cpp_Timer from '../assets/code/cpp/src/Timer.lf'; @@ -165,7 +165,7 @@ A reaction is always invoked at a well-defined logical time, and logical time do ## Timeout -By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](<../introduction.md#timeout>) or a [`--timeout` command-line option](<../introduction.md#command-line-arguments>). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: +By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](../reference/target-declaration.mdx#timeout) or a [`--timeout` command-line option](../reference/target-declaration.mdx#command-line-arguments). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: ) 0, but may occur at a larger microstep. See [Superdense Time](<../writing-reactors/actions.mdx#superdense-time>) and [Termination](../writing-reactors/termination.mdx). +The **shutdown** trigger typically occurs at [microstep](../writing-reactors/superdense-time.mdx) 0, but may occur at a larger microstep. See [Superdense Time](../writing-reactors/superdense-time.mdx) and [Termination](../writing-reactors/termination.mdx). diff --git a/versioned_docs/version-0.7.0/developer/developer-eclipse-setup-with-oomph.mdx b/versioned_docs/version-0.7.0/developer/developer-eclipse-setup-with-oomph.mdx index d88abcb2c..cc05e402d 100644 --- a/versioned_docs/version-0.7.0/developer/developer-eclipse-setup-with-oomph.mdx +++ b/versioned_docs/version-0.7.0/developer/developer-eclipse-setup-with-oomph.mdx @@ -109,7 +109,7 @@ Hello World. This should print "Hello World". -We strongly recommend browsing the system tests, which provide a concise overview of the capabilities of Lingua Franca. You can set up a project in the IDE for this using [these instructions](<../developer/regression-tests.mdx#browsing-and-editing-examples-in-the-lf-ide>). +We strongly recommend browsing the [itegration tests](regression-tests.mdx), which provide a concise overview of the capabilities of Lingua Franca. ## Working on the Lingua-Franca Compiler diff --git a/versioned_docs/version-0.7.0/embedded/arduino.mdx b/versioned_docs/version-0.7.0/embedded/arduino.mdx index 202412423..173d3ab31 100644 --- a/versioned_docs/version-0.7.0/embedded/arduino.mdx +++ b/versioned_docs/version-0.7.0/embedded/arduino.mdx @@ -3,7 +3,7 @@ title: Arduino description: Developing LF Programs on Arduino. --- -# Overview +## Overview To run Lingua Franca on an Arduino-compatible microcontroller, you can use the `C` target with the `platform` target property set to `arduino`. The Lingua @@ -13,7 +13,7 @@ To flash the compiled sketch onto a board, you need specify a Fully Qualified Board Name (FQBN) as well as the port to which your board is connected. On this page, we explain exactly how to do this. -## Prerequisites +### Prerequisites - You need a development system that runs on macOS or Linux (there is currently no Windows support). - [Arduino CLI](https://arduino.github.io/arduino-cli/) must be installed on your development system. Confirm that your installation works by running: @@ -22,7 +22,7 @@ page, we explain exactly how to do this. arduino-cli version ``` -# Writing a simple Arduino Program +## Writing a simple Arduino Program The most basic Arduino program (Blink) can be defined in LF like so: @@ -56,7 +56,7 @@ can invoke Arduino library functions, just like one would do in the definition of an Arduino `loop()`. For any setup that might be needed at the beginning of execution, a reaction triggered by the built-in `startup` trigger can be used. -## Platform Options +### Platform Options The `platform` property can also be used so specify more details. Along with `name: "arduino"`, you can specify which `board`, `port`, and `baud-rate` you are using. If you want the program @@ -77,14 +77,14 @@ target C { The `board` is necessary for [building](#building) and the `port` is necessary for [flashing](#flashing). -### Baud rate of the serial port +#### Baud rate of the serial port All Arduino boards have at least one serial port (also known as a UART or USART), and some have several. By default, Lingua Franca will assume a default baud rate of 9600. This parameter is tunable by adjusting the `baud-rate` parameter in platform options. -# Building +## Building In order to have `arduino-cli` compile the generated sketch file, a `board` must be specified. If no `board` is set, `lfc` will run in `no-compile` mode, meaning @@ -112,7 +112,7 @@ If you specify your FQBN under `board` in the `platform` target property, `lfc` - for threaded programs (`arduino:mbed` boards), run: `arduino-cli compile -b [FQBN] --build-property compiler.c.extra_flags="-DLF_THREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10" --build-property compiler.cpp.extra_flags="-DLF_THREADED -DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10"` -# Flashing +## Flashing Arduino's can be flashed via USB. To find the port oto which your device is connected, run the following command: diff --git a/versioned_docs/version-0.7.0/reference/target-declaration.mdx b/versioned_docs/version-0.7.0/reference/target-declaration.mdx index 08214c936..5c875b6f5 100644 --- a/versioned_docs/version-0.7.0/reference/target-declaration.mdx +++ b/versioned_docs/version-0.7.0/reference/target-declaration.mdx @@ -28,9 +28,8 @@ A target specification may have optional parameters, the names and values of whi - [**build-type**](#build-type): One of Debug (the default), Release, RelWithDebInfo and MinSizeRel. - [**cargo-dependencies**](#cargo-dependencies): (Rust only) list of dependencies to include in the generated Cargo.toml file. - [**cargo-features**](#cargo-features): (Rust only) List of string names of features to include. -- [**cmake-include**](#cmake): List of paths to cmake files to guide compilation. +- [**cmake-include**](#cmake-include): List of paths to cmake files to guide compilation. - [**compiler**](#compiler): A string giving the name of the target language compiler to use. -- [**compiler-flags**](#compiler-flags): An arrays of strings giving options to be passed to the target compiler. - [**docker**](#docker): A boolean to generate a Dockerfile. - [**external-runtime-path**](#external-runtime-path): Specify a pre-compiled external runtime library located to link to instead of the default. - [**export-dependency-graph**](#export-dependency-graph): To export the reaction dependency graph as a dot graph (for debugging). @@ -530,7 +529,7 @@ This argument takes a string (with quotation marks) containing any tag, branch n This target does not support the `rust-include` target option. -This specifies a set of Rust modules in the generated project. See [Linking support files](#linking-support-files). +This specifies a set of Rust modules in the generated project. @@ -552,7 +551,7 @@ This specifies the scheduler to use. See[Target Language Details](<../reference/ This target does not support the `single-file-project` target option. -If true, enables [single-file project layout](#single-file-layout). +If true, enables single-file project layout. @@ -626,7 +625,7 @@ Any errors in command-line arguments result in printing the above information. T ### Custom Command-Line Arguments -User-defined command-line arguments may be created by giving the main reactor [parameters](#using-parameters). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). +User-defined command-line arguments may be created by giving the main reactor [parameters](../writing-reactors/parameters-and-state-variables.mdx#parameter-declaration). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). Note: Custom arguments may not have the same names as standard arguments like `timeout` or `keepalive`. @@ -716,7 +715,7 @@ The generated C++ program understands the following command-line arguments, each - `-w, --workers `: Use n worker threads for executing reactions. - `--help`: Print the above information. -If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary (see [Using Parameters](#using-parameters)). +If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary. The Python target does not currently support any command-line arguments. You must specify properties as target parameters. @@ -728,7 +727,7 @@ The generated executable may feature a command-line interface (CLI), if it uses - `--timeout -The Python supports the [logging](<../introduction.md#logging>) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). +The Python supports the [logging](target-declaration.mdx#logging) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). @@ -2817,7 +2817,7 @@ The executable reacts to the environment variable `RUST_LOG`, which sets the log Error and warning logs are on by default. Enabling a level enables all greater levels (i.e., `RUST_LOG=info` also enables `warn` and `error`, but not `trace` or `debug`). -Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](<../introduction.md#command-line-arguments>). +Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](target-declaration.mdx#command-line-arguments). Note that the `logging` target property is ignored, as its levels do not match the Rust standard levels we use (those of the [`log` crate](https://docs.rs/log/)). @@ -2991,7 +2991,7 @@ primitives and sleep functions. ### Multithreaded Implementation -By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](<../introduction.md#threading>) statement or the `--workers` [command-line argument](<../introduction.md#command-line-arguments>) is given. +By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](target-declaration.mdx#workers) statement or the `--workers` [command-line argument](target-declaration.mdx#command-line-arguments) is given. Upon initialization, the main thread will create the specified number of worker threads. Execution proceeds in a manner similar to the [single threaded implementation](#single-threaded-implementation) @@ -3000,7 +3000,7 @@ The execution algorithm ensures that no reaction executes until all reactions th ### Single Threaded Implementation -By giving the `single-threaded` [target option](<../introduction.md#single-threaded>) or the `--single-threaded` [command-line argument](<../introduction.md#command-line-arguments>), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. +By giving the `single-threaded` [target option](target-declaration.mdx#single-threaded) or the `--single-threaded` [command-line argument](target-declaration.mdx#command-line-arguments), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. The execution strategy is to have two queues of pending accessor invocations, one that is sorted by tag (the **event queue**) and one that is sorted by priority (the **reaction queue**). @@ -3008,9 +3008,9 @@ Execution proceeds as follows: 1. At initialization, an event for each timer is put on the event queue and logical time is initialized to the current time, represented as the number of nanoseconds elapsed since January 1, 1970. -2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](<../introduction.md#command-line-arguments>) is given). +2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). -3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](<../introduction.md#command-line-arguments>) is given). Then advance logical time to match that earliest timestamp. +3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). Then advance logical time to match that earliest timestamp. 4. Execute reactions in order of priority from the reaction queue. These reactions may produce outputs, which results in more events getting put on the reaction queue. Those reactions are assured of having lower priority than the reaction that is executing. If a reaction calls `lf_schedule()`, an event will be put on the event queue, not the reaction queue. @@ -3024,7 +3024,7 @@ Unlike the C target, the Cpp target implements more of the analysis and setup of -The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [threading](<../introduction.md#threading>) target property can be used to override this behavior. +The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [single-threaded](target-declaration.mdx#single-threaded) target property can be used to override this behavior. Running [lfc](../tools/command-line-tools.mdx) on a `XXX.lf` program that uses the Python target specification on a Linux machine will create the following files (other operating systems will have @@ -3209,7 +3209,7 @@ The Lingua Franca compiler automatically invokes other programs as it compiles a ### package.json -Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. +Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](../writing-reactors/preambles.mdx#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. ### tsconfig.json @@ -3221,7 +3221,7 @@ If the `tsc` type check was successful, the Lingua Franca compiler uses `babel` ### Debugging Type Errors -Let's take the [minimal reactor example](#a-minimal-example), and intentionally break it by adding a type error into the reaction. +Let's take the minimal reactor example, and intentionally break it by adding a type error into the reaction. ```lf-ts target TypeScript; @@ -3315,13 +3315,13 @@ These utility functions may be called within a TypeScript reaction: `util.getCurrentTag(): Tag` Gets the current (logical) tag. See [Tags](#tags). -`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#timed-behavior). +`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#time). -`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#timed-behavior). +`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#time). -`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#time). -`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#time). `util.success(): void` Invokes the [reactor-ts](https://github.com/lf-lang/reactor-ts) App's default success callback. FIXME: Currently doesn't do anything in Lingua Franca. @@ -3380,7 +3380,7 @@ See [Target Declaration](../introduction.md) for the full list of supported targ ### The Executable -The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](<../introduction.md#command-line-arguments>) for details. +The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](target-declaration.mdx#command-line-arguments) for details. ### File layout diff --git a/versioned_docs/version-0.7.0/reference/tracing.mdx b/versioned_docs/version-0.7.0/reference/tracing.mdx index 9359ec581..1e1f8e0ec 100644 --- a/versioned_docs/version-0.7.0/reference/tracing.mdx +++ b/versioned_docs/version-0.7.0/reference/tracing.mdx @@ -13,7 +13,7 @@ import { Tracing is a powerful tool when it comes to analysis and debugging of applications. Unfortunately, most tracing tools that are readily available are designed specifically for analyzing processes, threads and system calls. Specialized tools are required to enable analysis that is tailored to an alternative model of computation such as Reactors. The tools should be capable of understanding the fundamental concepts of the model, such as the distinction between logical and physical time, as well as structural units such as reactors and reactions. This page gives an overview of the currently supported trace mechanism, as well as an outline of alternative tools that could be useful in the future. -Tracing is different from [logging](<../introduction.md#logging>). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. +Tracing is different from [logging](target-declaration.mdx#logging). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. Tracing is currently supported in the C, Python, and C++ targets. The mechanism used in C and Python is different from that used in C++. Tracing in C++ requires third-party tools that may only be available in Linux. Tracing in C and Python does not require any third-party tools. diff --git a/versioned_docs/version-0.7.0/tutorial-videos.mdx b/versioned_docs/version-0.7.0/tutorial-videos.mdx index 16afb93ff..456f85b79 100644 --- a/versioned_docs/version-0.7.0/tutorial-videos.mdx +++ b/versioned_docs/version-0.7.0/tutorial-videos.mdx @@ -9,12 +9,12 @@ A [video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9Y **Useful links:** - [Complete video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9YEjulS4o) -- [Part I: Introduction](#introduction) -- [Part II: Hello World](#hello) -- [Part III: Target Languages](#target) -- [Part IV: Basic Concepts](#concepts) -- [Part V: Concurrency and Performance](#concurrency) -- [Part VI: Research Overview](#research) +- [Part I: Introduction](#part-i-introduction) +- [Part II: Hello World](#part-ii-hello-world) +- [Part III: Target Languages](#part-iii-target-languages) +- [Part IV: Basic Concepts](#part-iv-basic-concepts) +- [Part V: Concurrency and Performance](#part-v-concurrency) +- [Part VI: Research Overview](#part-vi-research-overview) - [Slides](https://docs.google.com/presentation/d/14cfIMmkBFwt6NOj2ujVs7YXPAXYsoHgLS2rUgBM-Deg/present?slide=id.g623f095f12_0_0) ## Part I: Introduction diff --git a/versioned_docs/version-0.7.0/writing-reactors/actions.mdx b/versioned_docs/version-0.7.0/writing-reactors/actions.mdx index a999cda3a..16a15ae7e 100644 --- a/versioned_docs/version-0.7.0/writing-reactors/actions.mdx +++ b/versioned_docs/version-0.7.0/writing-reactors/actions.mdx @@ -133,7 +133,7 @@ Action triggered at logical time 603669000 nsec after start. ... ``` -Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](<../introduction.md#fast>) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. +Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](../reference/target-declaration.mdx#fast) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. Whereas logical actions are required to be scheduled within a reaction of the reactor that declares the action, physical actions can be scheduled by code that is outside the Lingua Franca system. For example, some other thread or a callback function may call `schedule()`, passing it a physical action. For example: diff --git a/versioned_docs/version-0.7.0/writing-reactors/composing-reactors.mdx b/versioned_docs/version-0.7.0/writing-reactors/composing-reactors.mdx index daef9a51d..e8dde0c82 100644 --- a/versioned_docs/version-0.7.0/writing-reactors/composing-reactors.mdx +++ b/versioned_docs/version-0.7.0/writing-reactors/composing-reactors.mdx @@ -172,7 +172,7 @@ Connections may include a **logical delay** using the `after` keyword, as follow where `` can be any of the forms described in [Expressions](../reference/expressions.mdx). -The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/actions.mdx#superdense-time>) later than the event that triggered it. +The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/superdense-time.mdx>) later than the event that triggered it. ## Physical Connections diff --git a/versioned_docs/version-0.7.0/writing-reactors/multiports-and-banks.mdx b/versioned_docs/version-0.7.0/writing-reactors/multiports-and-banks.mdx index d0beb8559..31fc6d8c7 100644 --- a/versioned_docs/version-0.7.0/writing-reactors/multiports-and-banks.mdx +++ b/versioned_docs/version-0.7.0/writing-reactors/multiports-and-banks.mdx @@ -379,7 +379,7 @@ The syntax `(a.out)+` means "repeat the output port `a.out` one or more times as -Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#Combining-Banks-and-Multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: +Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#combining-banks-and-multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: import C_Interleaved from '../assets/code/c/src/Interleaved.lf'; import Cpp_Interleaved from '../assets/code/cpp/src/Interleaved.lf'; diff --git a/versioned_docs/version-0.7.0/writing-reactors/preambles.mdx b/versioned_docs/version-0.7.0/writing-reactors/preambles.mdx index fb7cd6793..a78e3bb67 100644 --- a/versioned_docs/version-0.7.0/writing-reactors/preambles.mdx +++ b/versioned_docs/version-0.7.0/writing-reactors/preambles.mdx @@ -326,7 +326,7 @@ Your platform is Linux By putting import in the `preamble`, the module becomes available in all reactions of this reactor using the `self` modifier. -**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx#python-target-implementation-details>). +**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx>). Alternatively, you can define a `preamble` outside any reactor definition. Such a `preamble` can be used for functions such as import or to define a global function. The following example shows importing the [hello](https://github.com/lf-lang/lingua-franca/blob/master/test/Python/src/include/hello.py) module: @@ -432,7 +432,7 @@ Converted string 42 to number 42 ### Using Node Modules -Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](#preamble) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](#typescript-target-implementation-details) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. +Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](../writing-reactors/preambles.mdx) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](../reference/target-language-details.mdx) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. The important takeaway here is with the package.json file and the compiled JavaScript in the Foo/dist/ directory, you have a standard Node.js program that executes as such. You can modify and debug it just as you would a Node.js program. diff --git a/versioned_docs/version-0.7.0/writing-reactors/termination.mdx b/versioned_docs/version-0.7.0/writing-reactors/termination.mdx index db156dea7..3336e7c8f 100644 --- a/versioned_docs/version-0.7.0/writing-reactors/termination.mdx +++ b/versioned_docs/version-0.7.0/writing-reactors/termination.mdx @@ -29,7 +29,7 @@ We address each of these in turn. ## Timeout -The [target property `timeout`](<../introduction.md#timeout>) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). +The [target property `timeout`](../reference/target-declaration.mdx#timeout) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). There is a significant subtlety when using [physical connections](<../writing-reactors/composing-reactors.mdx#physical-connections>), which are connections using the syntax `~>`. Such connections specify that the tag at the receiving end will be based on the physical time at which the message is received. If the tag assigned at the receiving end is greater than the final tag, then the message is lost. Hence, **messages sent near the `timeout` time are likely to be lost!** diff --git a/versioned_docs/version-0.7.0/writing-reactors/time-and-timers.mdx b/versioned_docs/version-0.7.0/writing-reactors/time-and-timers.mdx index 8d68c15e1..24a39e076 100644 --- a/versioned_docs/version-0.7.0/writing-reactors/time-and-timers.mdx +++ b/versioned_docs/version-0.7.0/writing-reactors/time-and-timers.mdx @@ -15,7 +15,7 @@ import { A key property of Lingua Franca is **logical time**. All events occur at an instant in logical time. By default, the runtime system does its best to align logical time with **physical time**, which is some measurement of time on the execution platform. The **lag** is defined to be physical time minus logical time, and the goal of the runtime system is maintain a small non-negative lag. -The **lag** is alThe **lag** is allowed to go negative only if the [`fast`](<../reference/target-declaration#fast>) target property or the [`--fast`](<../reference/target-declaration#command-line-arguments>) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. +The **lag** is alThe **lag** is allowed to go negative only if the [`fast`](../reference/target-declaration.mdx#fast) target property or the [`--fast`](../reference/target-declaration.mdx#command-line-arguments) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. @@ -60,7 +60,7 @@ import TS_SlowingClock from '../assets/code/ts/src/SlowingClock.lf'; -This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](<../writing-reactors/actions.mdx#logical-actions>), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: +This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](../writing-reactors/actions.mdx#logical-actions), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: ``` Logical time since start: 100000000 nsec. @@ -80,7 +80,7 @@ The simplest use of logical time in Lingua Franca is to invoke a reaction period The ``, which is optional, specifies the time interval between timer events. The ``, which is also optional, specifies the (logical) time interval between when the program starts executing and the first timer event. If no period is given, then the timer event occurs only once. If neither an offset nor a period is specified, then one timer event occurs at program start, simultaneous with the `startup` event. -The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](<../reference/expressions.mdx#basic-expressions>) for allowable units. Consider the following example: +The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](../reference/expressions.mdx#basic-expressions) for allowable units. Consider the following example: import C_Timer from '../assets/code/c/src/Timer.lf'; import Cpp_Timer from '../assets/code/cpp/src/Timer.lf'; @@ -165,7 +165,7 @@ A reaction is always invoked at a well-defined logical time, and logical time do ## Timeout -By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](<../introduction.md#timeout>) or a [`--timeout` command-line option](<../introduction.md#command-line-arguments>). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: +By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](../reference/target-declaration.mdx#timeout) or a [`--timeout` command-line option](../reference/target-declaration.mdx#command-line-arguments). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: ) 0, but may occur at a larger microstep. See [Superdense Time](<../writing-reactors/actions.mdx#superdense-time>) and [Termination](../writing-reactors/termination.mdx). +The **shutdown** trigger typically occurs at [microstep](../writing-reactors/superdense-time.mdx) 0, but may occur at a larger microstep. See [Superdense Time](../writing-reactors/superdense-time.mdx) and [Termination](../writing-reactors/termination.mdx). diff --git a/versioned_docs/version-0.8.0/developer/developer-eclipse-setup-with-oomph.mdx b/versioned_docs/version-0.8.0/developer/developer-eclipse-setup-with-oomph.mdx index d88abcb2c..cc05e402d 100644 --- a/versioned_docs/version-0.8.0/developer/developer-eclipse-setup-with-oomph.mdx +++ b/versioned_docs/version-0.8.0/developer/developer-eclipse-setup-with-oomph.mdx @@ -109,7 +109,7 @@ Hello World. This should print "Hello World". -We strongly recommend browsing the system tests, which provide a concise overview of the capabilities of Lingua Franca. You can set up a project in the IDE for this using [these instructions](<../developer/regression-tests.mdx#browsing-and-editing-examples-in-the-lf-ide>). +We strongly recommend browsing the [itegration tests](regression-tests.mdx), which provide a concise overview of the capabilities of Lingua Franca. ## Working on the Lingua-Franca Compiler diff --git a/versioned_docs/version-0.8.0/embedded/arduino.mdx b/versioned_docs/version-0.8.0/embedded/arduino.mdx index fd4c70a63..8cbc473d8 100644 --- a/versioned_docs/version-0.8.0/embedded/arduino.mdx +++ b/versioned_docs/version-0.8.0/embedded/arduino.mdx @@ -3,7 +3,7 @@ title: Arduino description: Developing LF Programs on Arduino. --- -# Overview +## Overview To run Lingua Franca on an Arduino-compatible microcontroller, you can use the `C` target with the `platform` target property set to `arduino`. The Lingua @@ -13,7 +13,7 @@ To flash the compiled sketch onto a board, you need specify a Fully Qualified Board Name (FQBN) as well as the port to which your board is connected. On this page, we explain exactly how to do this. -## Prerequisites +### Prerequisites - You need a development system that runs on macOS or Linux (there is currently no Windows support). - [Arduino CLI](https://arduino.github.io/arduino-cli/) must be installed on your development system. Confirm that your installation works by running: @@ -22,7 +22,7 @@ page, we explain exactly how to do this. arduino-cli version ``` -# Writing a simple Arduino Program +## Writing a simple Arduino Program The most basic Arduino program (Blink) can be defined in LF like so: @@ -56,7 +56,7 @@ can invoke Arduino library functions, just like one would do in the definition of an Arduino `loop()`. For any setup that might be needed at the beginning of execution, a reaction triggered by the built-in `startup` trigger can be used. -## Platform Options +### Platform Options The `platform` property can also be used so specify more details. Along with `name: "arduino"`, you can specify which `board`, `port`, and `baud-rate` you are using. If you want the program @@ -77,14 +77,14 @@ target C { The `board` is necessary for [building](#building) and the `port` is necessary for [flashing](#flashing). -### Baud rate of the serial port +#### Baud rate of the serial port All Arduino boards have at least one serial port (also known as a UART or USART), and some have several. By default, Lingua Franca will assume a default baud rate of 9600. This parameter is tunable by adjusting the `baud-rate` parameter in platform options. -# Building +## Building In order to have `arduino-cli` compile the generated sketch file, a `board` must be specified. If no `board` is set, `lfc` will run in `no-compile` mode, meaning @@ -112,7 +112,7 @@ If you specify your FQBN under `board` in the `platform` target property, `lfc` - for threaded programs (`arduino:mbed` boards), run: `arduino-cli compile -b [FQBN] --build-property compiler.c.extra_flags="-DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10" --build-property compiler.cpp.extra_flags="-DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10"` -# Flashing +## Flashing Arduino's can be flashed via USB. To find the port oto which your device is connected, run the following command: diff --git a/versioned_docs/version-0.8.0/reference/target-declaration.mdx b/versioned_docs/version-0.8.0/reference/target-declaration.mdx index 08214c936..5c875b6f5 100644 --- a/versioned_docs/version-0.8.0/reference/target-declaration.mdx +++ b/versioned_docs/version-0.8.0/reference/target-declaration.mdx @@ -28,9 +28,8 @@ A target specification may have optional parameters, the names and values of whi - [**build-type**](#build-type): One of Debug (the default), Release, RelWithDebInfo and MinSizeRel. - [**cargo-dependencies**](#cargo-dependencies): (Rust only) list of dependencies to include in the generated Cargo.toml file. - [**cargo-features**](#cargo-features): (Rust only) List of string names of features to include. -- [**cmake-include**](#cmake): List of paths to cmake files to guide compilation. +- [**cmake-include**](#cmake-include): List of paths to cmake files to guide compilation. - [**compiler**](#compiler): A string giving the name of the target language compiler to use. -- [**compiler-flags**](#compiler-flags): An arrays of strings giving options to be passed to the target compiler. - [**docker**](#docker): A boolean to generate a Dockerfile. - [**external-runtime-path**](#external-runtime-path): Specify a pre-compiled external runtime library located to link to instead of the default. - [**export-dependency-graph**](#export-dependency-graph): To export the reaction dependency graph as a dot graph (for debugging). @@ -530,7 +529,7 @@ This argument takes a string (with quotation marks) containing any tag, branch n This target does not support the `rust-include` target option. -This specifies a set of Rust modules in the generated project. See [Linking support files](#linking-support-files). +This specifies a set of Rust modules in the generated project. @@ -552,7 +551,7 @@ This specifies the scheduler to use. See[Target Language Details](<../reference/ This target does not support the `single-file-project` target option. -If true, enables [single-file project layout](#single-file-layout). +If true, enables single-file project layout. @@ -626,7 +625,7 @@ Any errors in command-line arguments result in printing the above information. T ### Custom Command-Line Arguments -User-defined command-line arguments may be created by giving the main reactor [parameters](#using-parameters). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). +User-defined command-line arguments may be created by giving the main reactor [parameters](../writing-reactors/parameters-and-state-variables.mdx#parameter-declaration). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). Note: Custom arguments may not have the same names as standard arguments like `timeout` or `keepalive`. @@ -716,7 +715,7 @@ The generated C++ program understands the following command-line arguments, each - `-w, --workers `: Use n worker threads for executing reactions. - `--help`: Print the above information. -If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary (see [Using Parameters](#using-parameters)). +If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary. The Python target does not currently support any command-line arguments. You must specify properties as target parameters. @@ -728,7 +727,7 @@ The generated executable may feature a command-line interface (CLI), if it uses - `--timeout -The Python supports the [logging](<../introduction.md#logging>) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). +The Python supports the [logging](target-declaration.mdx#logging) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). @@ -2817,7 +2817,7 @@ The executable reacts to the environment variable `RUST_LOG`, which sets the log Error and warning logs are on by default. Enabling a level enables all greater levels (i.e., `RUST_LOG=info` also enables `warn` and `error`, but not `trace` or `debug`). -Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](<../introduction.md#command-line-arguments>). +Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](target-declaration.mdx#command-line-arguments). Note that the `logging` target property is ignored, as its levels do not match the Rust standard levels we use (those of the [`log` crate](https://docs.rs/log/)). @@ -2991,7 +2991,7 @@ primitives and sleep functions. ### Multithreaded Implementation -By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](<../introduction.md#threading>) statement or the `--workers` [command-line argument](<../introduction.md#command-line-arguments>) is given. +By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](target-declaration.mdx#workers) statement or the `--workers` [command-line argument](target-declaration.mdx#command-line-arguments) is given. Upon initialization, the main thread will create the specified number of worker threads. Execution proceeds in a manner similar to the [single threaded implementation](#single-threaded-implementation) @@ -3000,7 +3000,7 @@ The execution algorithm ensures that no reaction executes until all reactions th ### Single Threaded Implementation -By giving the `single-threaded` [target option](<../introduction.md#single-threaded>) or the `--single-threaded` [command-line argument](<../introduction.md#command-line-arguments>), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. +By giving the `single-threaded` [target option](target-declaration.mdx#single-threaded) or the `--single-threaded` [command-line argument](target-declaration.mdx#command-line-arguments), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. The execution strategy is to have two queues of pending accessor invocations, one that is sorted by tag (the **event queue**) and one that is sorted by priority (the **reaction queue**). @@ -3008,9 +3008,9 @@ Execution proceeds as follows: 1. At initialization, an event for each timer is put on the event queue and logical time is initialized to the current time, represented as the number of nanoseconds elapsed since January 1, 1970. -2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](<../introduction.md#command-line-arguments>) is given). +2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). -3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](<../introduction.md#command-line-arguments>) is given). Then advance logical time to match that earliest timestamp. +3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). Then advance logical time to match that earliest timestamp. 4. Execute reactions in order of priority from the reaction queue. These reactions may produce outputs, which results in more events getting put on the reaction queue. Those reactions are assured of having lower priority than the reaction that is executing. If a reaction calls `lf_schedule()`, an event will be put on the event queue, not the reaction queue. @@ -3024,7 +3024,7 @@ Unlike the C target, the Cpp target implements more of the analysis and setup of -The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [threading](<../introduction.md#threading>) target property can be used to override this behavior. +The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [single-threaded](target-declaration.mdx#single-threaded) target property can be used to override this behavior. Running [lfc](../tools/command-line-tools.mdx) on a `XXX.lf` program that uses the Python target specification on a Linux machine will create the following files (other operating systems will have @@ -3209,7 +3209,7 @@ The Lingua Franca compiler automatically invokes other programs as it compiles a ### package.json -Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. +Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](../writing-reactors/preambles.mdx#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. ### tsconfig.json @@ -3221,7 +3221,7 @@ If the `tsc` type check was successful, the Lingua Franca compiler uses `babel` ### Debugging Type Errors -Let's take the [minimal reactor example](#a-minimal-example), and intentionally break it by adding a type error into the reaction. +Let's take the minimal reactor example, and intentionally break it by adding a type error into the reaction. ```lf-ts target TypeScript; @@ -3315,13 +3315,13 @@ These utility functions may be called within a TypeScript reaction: `util.getCurrentTag(): Tag` Gets the current (logical) tag. See [Tags](#tags). -`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#timed-behavior). +`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#time). -`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#timed-behavior). +`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#time). -`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#time). -`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#time). `util.success(): void` Invokes the [reactor-ts](https://github.com/lf-lang/reactor-ts) App's default success callback. FIXME: Currently doesn't do anything in Lingua Franca. @@ -3380,7 +3380,7 @@ See [Target Declaration](../introduction.md) for the full list of supported targ ### The Executable -The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](<../introduction.md#command-line-arguments>) for details. +The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](target-declaration.mdx#command-line-arguments) for details. ### File layout diff --git a/versioned_docs/version-0.8.0/reference/tracing.mdx b/versioned_docs/version-0.8.0/reference/tracing.mdx index 9359ec581..1e1f8e0ec 100644 --- a/versioned_docs/version-0.8.0/reference/tracing.mdx +++ b/versioned_docs/version-0.8.0/reference/tracing.mdx @@ -13,7 +13,7 @@ import { Tracing is a powerful tool when it comes to analysis and debugging of applications. Unfortunately, most tracing tools that are readily available are designed specifically for analyzing processes, threads and system calls. Specialized tools are required to enable analysis that is tailored to an alternative model of computation such as Reactors. The tools should be capable of understanding the fundamental concepts of the model, such as the distinction between logical and physical time, as well as structural units such as reactors and reactions. This page gives an overview of the currently supported trace mechanism, as well as an outline of alternative tools that could be useful in the future. -Tracing is different from [logging](<../introduction.md#logging>). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. +Tracing is different from [logging](target-declaration.mdx#logging). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. Tracing is currently supported in the C, Python, and C++ targets. The mechanism used in C and Python is different from that used in C++. Tracing in C++ requires third-party tools that may only be available in Linux. Tracing in C and Python does not require any third-party tools. diff --git a/versioned_docs/version-0.8.0/tutorial-videos.mdx b/versioned_docs/version-0.8.0/tutorial-videos.mdx index 16afb93ff..456f85b79 100644 --- a/versioned_docs/version-0.8.0/tutorial-videos.mdx +++ b/versioned_docs/version-0.8.0/tutorial-videos.mdx @@ -9,12 +9,12 @@ A [video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9Y **Useful links:** - [Complete video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9YEjulS4o) -- [Part I: Introduction](#introduction) -- [Part II: Hello World](#hello) -- [Part III: Target Languages](#target) -- [Part IV: Basic Concepts](#concepts) -- [Part V: Concurrency and Performance](#concurrency) -- [Part VI: Research Overview](#research) +- [Part I: Introduction](#part-i-introduction) +- [Part II: Hello World](#part-ii-hello-world) +- [Part III: Target Languages](#part-iii-target-languages) +- [Part IV: Basic Concepts](#part-iv-basic-concepts) +- [Part V: Concurrency and Performance](#part-v-concurrency) +- [Part VI: Research Overview](#part-vi-research-overview) - [Slides](https://docs.google.com/presentation/d/14cfIMmkBFwt6NOj2ujVs7YXPAXYsoHgLS2rUgBM-Deg/present?slide=id.g623f095f12_0_0) ## Part I: Introduction diff --git a/versioned_docs/version-0.8.0/writing-reactors/actions.mdx b/versioned_docs/version-0.8.0/writing-reactors/actions.mdx index a999cda3a..16a15ae7e 100644 --- a/versioned_docs/version-0.8.0/writing-reactors/actions.mdx +++ b/versioned_docs/version-0.8.0/writing-reactors/actions.mdx @@ -133,7 +133,7 @@ Action triggered at logical time 603669000 nsec after start. ... ``` -Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](<../introduction.md#fast>) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. +Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](../reference/target-declaration.mdx#fast) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. Whereas logical actions are required to be scheduled within a reaction of the reactor that declares the action, physical actions can be scheduled by code that is outside the Lingua Franca system. For example, some other thread or a callback function may call `schedule()`, passing it a physical action. For example: diff --git a/versioned_docs/version-0.8.0/writing-reactors/composing-reactors.mdx b/versioned_docs/version-0.8.0/writing-reactors/composing-reactors.mdx index daef9a51d..e8dde0c82 100644 --- a/versioned_docs/version-0.8.0/writing-reactors/composing-reactors.mdx +++ b/versioned_docs/version-0.8.0/writing-reactors/composing-reactors.mdx @@ -172,7 +172,7 @@ Connections may include a **logical delay** using the `after` keyword, as follow where `` can be any of the forms described in [Expressions](../reference/expressions.mdx). -The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/actions.mdx#superdense-time>) later than the event that triggered it. +The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/superdense-time.mdx>) later than the event that triggered it. ## Physical Connections diff --git a/versioned_docs/version-0.8.0/writing-reactors/multiports-and-banks.mdx b/versioned_docs/version-0.8.0/writing-reactors/multiports-and-banks.mdx index f95a28143..d06cbccbf 100644 --- a/versioned_docs/version-0.8.0/writing-reactors/multiports-and-banks.mdx +++ b/versioned_docs/version-0.8.0/writing-reactors/multiports-and-banks.mdx @@ -379,7 +379,7 @@ The syntax `(a.out)+` means "repeat the output port `a.out` one or more times as -Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#Combining-Banks-and-Multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: +Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#combining-banks-and-multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: import C_Interleaved from '../assets/code/c/src/Interleaved.lf'; import Cpp_Interleaved from '../assets/code/cpp/src/Interleaved.lf'; diff --git a/versioned_docs/version-0.8.0/writing-reactors/preambles.mdx b/versioned_docs/version-0.8.0/writing-reactors/preambles.mdx index fb7cd6793..a78e3bb67 100644 --- a/versioned_docs/version-0.8.0/writing-reactors/preambles.mdx +++ b/versioned_docs/version-0.8.0/writing-reactors/preambles.mdx @@ -326,7 +326,7 @@ Your platform is Linux By putting import in the `preamble`, the module becomes available in all reactions of this reactor using the `self` modifier. -**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx#python-target-implementation-details>). +**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx>). Alternatively, you can define a `preamble` outside any reactor definition. Such a `preamble` can be used for functions such as import or to define a global function. The following example shows importing the [hello](https://github.com/lf-lang/lingua-franca/blob/master/test/Python/src/include/hello.py) module: @@ -432,7 +432,7 @@ Converted string 42 to number 42 ### Using Node Modules -Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](#preamble) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](#typescript-target-implementation-details) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. +Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](../writing-reactors/preambles.mdx) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](../reference/target-language-details.mdx) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. The important takeaway here is with the package.json file and the compiled JavaScript in the Foo/dist/ directory, you have a standard Node.js program that executes as such. You can modify and debug it just as you would a Node.js program. diff --git a/versioned_docs/version-0.8.0/writing-reactors/termination.mdx b/versioned_docs/version-0.8.0/writing-reactors/termination.mdx index fc9b8244f..58a43bf71 100644 --- a/versioned_docs/version-0.8.0/writing-reactors/termination.mdx +++ b/versioned_docs/version-0.8.0/writing-reactors/termination.mdx @@ -29,7 +29,7 @@ We address each of these in turn. ## Timeout -The [target property `timeout`](<../introduction.md#timeout>) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). +The [target property `timeout`](../reference/target-declaration.mdx#timeout) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). There is a significant subtlety when using [physical connections](<../writing-reactors/composing-reactors.mdx#physical-connections>), which are connections using the syntax `~>`. Such connections specify that the tag at the receiving end will be based on the physical time at which the message is received. If the tag assigned at the receiving end is greater than the final tag, then the message is lost. Hence, **messages sent near the `timeout` time are likely to be lost!** diff --git a/versioned_docs/version-0.8.0/writing-reactors/time-and-timers.mdx b/versioned_docs/version-0.8.0/writing-reactors/time-and-timers.mdx index 31c2b6cdd..77ccce901 100644 --- a/versioned_docs/version-0.8.0/writing-reactors/time-and-timers.mdx +++ b/versioned_docs/version-0.8.0/writing-reactors/time-and-timers.mdx @@ -15,7 +15,7 @@ import { A key property of Lingua Franca is **logical time**. All events occur at an instant in logical time. By default, the runtime system does its best to align logical time with **physical time**, which is some measurement of time on the execution platform. The **lag** is defined to be physical time minus logical time, and the goal of the runtime system is maintain a small non-negative lag. -The **lag** is allowed to go negative only if the [`fast`](<../reference/target-declaration#fast>) target property or the [`--fast`](<../reference/target-declaration#command-line-arguments>) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. +The **lag** is allowed to go negative only if the [`fast`](../reference/target-declaration.mdx#fast) target property or the [`--fast`](../reference/target-declaration.mdx#command-line-arguments) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. @@ -60,7 +60,7 @@ import TS_SlowingClock from '../assets/code/ts/src/SlowingClock.lf'; -This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](<../writing-reactors/actions.mdx#logical-actions>), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: +This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](../writing-reactors/actions.mdx#logical-actions), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: ``` Logical time since start: 100000000 nsec. @@ -80,7 +80,7 @@ The simplest use of logical time in Lingua Franca is to invoke a reaction period The ``, which is optional, specifies the time interval between timer events. The ``, which is also optional, specifies the (logical) time interval between when the program starts executing and the first timer event. If no period is given, then the timer event occurs only once. If neither an offset nor a period is specified, then one timer event occurs at program start, simultaneous with the `startup` event. -The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](<../reference/expressions.mdx#basic-expressions>) for allowable units. Consider the following example: +The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](../reference/expressions.mdx#basic-expressions) for allowable units. Consider the following example: import C_Timer from '../assets/code/c/src/Timer.lf'; import Cpp_Timer from '../assets/code/cpp/src/Timer.lf'; @@ -165,7 +165,7 @@ A reaction is always invoked at a well-defined logical time, and logical time do ## Timeout -By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](<../introduction.md#timeout>) or a [`--timeout` command-line option](<../introduction.md#command-line-arguments>). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: +By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](../reference/target-declaration.mdx#timeout) or a [`--timeout` command-line option](../reference/target-declaration.mdx#command-line-arguments). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: ) 0, but may occur at a larger microstep. See [Superdense Time](<../writing-reactors/actions.mdx#superdense-time>) and [Termination](../writing-reactors/termination.mdx). +The **shutdown** trigger typically occurs at [microstep](../writing-reactors/superdense-time.mdx) 0, but may occur at a larger microstep. See [Superdense Time](../writing-reactors/superdense-time.mdx) and [Termination](../writing-reactors/termination.mdx). diff --git a/versioned_docs/version-0.9.0/developer/developer-eclipse-setup-with-oomph.mdx b/versioned_docs/version-0.9.0/developer/developer-eclipse-setup-with-oomph.mdx index d88abcb2c..cc05e402d 100644 --- a/versioned_docs/version-0.9.0/developer/developer-eclipse-setup-with-oomph.mdx +++ b/versioned_docs/version-0.9.0/developer/developer-eclipse-setup-with-oomph.mdx @@ -109,7 +109,7 @@ Hello World. This should print "Hello World". -We strongly recommend browsing the system tests, which provide a concise overview of the capabilities of Lingua Franca. You can set up a project in the IDE for this using [these instructions](<../developer/regression-tests.mdx#browsing-and-editing-examples-in-the-lf-ide>). +We strongly recommend browsing the [itegration tests](regression-tests.mdx), which provide a concise overview of the capabilities of Lingua Franca. ## Working on the Lingua-Franca Compiler diff --git a/versioned_docs/version-0.9.0/embedded/arduino.mdx b/versioned_docs/version-0.9.0/embedded/arduino.mdx index fd4c70a63..8cbc473d8 100644 --- a/versioned_docs/version-0.9.0/embedded/arduino.mdx +++ b/versioned_docs/version-0.9.0/embedded/arduino.mdx @@ -3,7 +3,7 @@ title: Arduino description: Developing LF Programs on Arduino. --- -# Overview +## Overview To run Lingua Franca on an Arduino-compatible microcontroller, you can use the `C` target with the `platform` target property set to `arduino`. The Lingua @@ -13,7 +13,7 @@ To flash the compiled sketch onto a board, you need specify a Fully Qualified Board Name (FQBN) as well as the port to which your board is connected. On this page, we explain exactly how to do this. -## Prerequisites +### Prerequisites - You need a development system that runs on macOS or Linux (there is currently no Windows support). - [Arduino CLI](https://arduino.github.io/arduino-cli/) must be installed on your development system. Confirm that your installation works by running: @@ -22,7 +22,7 @@ page, we explain exactly how to do this. arduino-cli version ``` -# Writing a simple Arduino Program +## Writing a simple Arduino Program The most basic Arduino program (Blink) can be defined in LF like so: @@ -56,7 +56,7 @@ can invoke Arduino library functions, just like one would do in the definition of an Arduino `loop()`. For any setup that might be needed at the beginning of execution, a reaction triggered by the built-in `startup` trigger can be used. -## Platform Options +### Platform Options The `platform` property can also be used so specify more details. Along with `name: "arduino"`, you can specify which `board`, `port`, and `baud-rate` you are using. If you want the program @@ -77,14 +77,14 @@ target C { The `board` is necessary for [building](#building) and the `port` is necessary for [flashing](#flashing). -### Baud rate of the serial port +#### Baud rate of the serial port All Arduino boards have at least one serial port (also known as a UART or USART), and some have several. By default, Lingua Franca will assume a default baud rate of 9600. This parameter is tunable by adjusting the `baud-rate` parameter in platform options. -# Building +## Building In order to have `arduino-cli` compile the generated sketch file, a `board` must be specified. If no `board` is set, `lfc` will run in `no-compile` mode, meaning @@ -112,7 +112,7 @@ If you specify your FQBN under `board` in the `platform` target property, `lfc` - for threaded programs (`arduino:mbed` boards), run: `arduino-cli compile -b [FQBN] --build-property compiler.c.extra_flags="-DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10" --build-property compiler.cpp.extra_flags="-DPLATFORM_ARDUINO -DINITIAL_EVENT_QUEUE_SIZE=10 -DINITIAL_REACT_QUEUE_SIZE=10"` -# Flashing +## Flashing Arduino's can be flashed via USB. To find the port oto which your device is connected, run the following command: diff --git a/versioned_docs/version-0.9.0/reference/target-declaration.mdx b/versioned_docs/version-0.9.0/reference/target-declaration.mdx index 2e96ac7d2..91d92f782 100644 --- a/versioned_docs/version-0.9.0/reference/target-declaration.mdx +++ b/versioned_docs/version-0.9.0/reference/target-declaration.mdx @@ -28,9 +28,8 @@ A target specification may have optional parameters, the names and values of whi - [**build-type**](#build-type): One of Debug (the default), Release, RelWithDebInfo and MinSizeRel. - [**cargo-dependencies**](#cargo-dependencies): (Rust only) list of dependencies to include in the generated Cargo.toml file. - [**cargo-features**](#cargo-features): (Rust only) List of string names of features to include. -- [**cmake-include**](#cmake): List of paths to cmake files to guide compilation. +- [**cmake-include**](#cmake-include): List of paths to cmake files to guide compilation. - [**compiler**](#compiler): A string giving the name of the target language compiler to use. -- [**compiler-flags**](#compiler-flags): An arrays of strings giving options to be passed to the target compiler. - [**docker**](#docker): A boolean to generate a Dockerfile. - [**external-runtime-path**](#external-runtime-path): Specify a pre-compiled external runtime library located to link to instead of the default. - [**export-dependency-graph**](#export-dependency-graph): To export the reaction dependency graph as a dot graph (for debugging). @@ -627,7 +626,7 @@ Any errors in command-line arguments result in printing the above information. T ### Custom Command-Line Arguments -User-defined command-line arguments may be created by giving the main reactor [parameters](#using-parameters). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). +User-defined command-line arguments may be created by giving the main reactor [parameters](../writing-reactors/parameters-and-state-variables.mdx#parameter-declaration). Assigning the main reactor a parameter of type `string`, `number`, `boolean`, or `time` will add an argument with corresponding name and type to the generated program's command-line-interface. Custom arguments will also appear in the generated program's usage guide (from the `--help` option). If the generated program is executed with a value specified for a custom command-line argument, that value will override the default value for the corresponding parameter. Arguments typed `string`, `number`, and `boolean` are parsed in the expected way, but `time` arguments must be specified on the command line like the `--timeout` property as `' '` (in quotes). Note: Custom arguments may not have the same names as standard arguments like `timeout` or `keepalive`. @@ -717,7 +716,7 @@ The generated C++ program understands the following command-line arguments, each - `-w, --workers `: Use n worker threads for executing reactions. - `--help`: Print the above information. -If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary (see [Using Parameters](#using-parameters)). +If the main reactor declares parameters, these parameters will appear as additional CLI options that can be specified when invoking the binary. The Python target does not currently support any command-line arguments. You must specify properties as target parameters. diff --git a/versioned_docs/version-0.9.0/reference/target-language-details.mdx b/versioned_docs/version-0.9.0/reference/target-language-details.mdx index c2af6f95f..e7a31c263 100644 --- a/versioned_docs/version-0.9.0/reference/target-language-details.mdx +++ b/versioned_docs/version-0.9.0/reference/target-language-details.mdx @@ -720,7 +720,7 @@ A state variable may be a time value, declared as follows: state time_value:time = 100 ms ``` -The `time_value` variable will be of type `TimeValue`, which is an object used to represent a time in the TypeScript Target. Refer to the section on [timed behavior](#timed-behavior) for more information. +The `time_value` variable will be of type `TimeValue`, which is an object used to represent a time in the TypeScript Target. Refer to the section on [timed behavior](#time) for more information. A state variable can have an array or object value. For example, the following reactor computes the **moving average** of the last four inputs each time it receives an input (from [MovingAverageImpl](https://github.com/lf-lang/lingua-franca/blob/master/test/TypeScript/src/MovingAverage.lf)): @@ -1484,7 +1484,7 @@ In the TypeScript target, all [TypeScript types](https://www.typescriptlang.org/ - `undefined` is not a valid type for an input, output, or action. This is because `undefined` is used to designate the absence of an input, output, or action during a reaction. -As with parameters and state variables, custom types (and classes) must be defined in the [preamble](#preamble) before they may be used. +As with parameters and state variables, custom types (and classes) must be defined in the [preamble](../writing-reactors/preambles.mdx) before they may be used. **To benefit from type checking, you should declare types for your reactor elements.** If a type isn't declared for an input, output, or action, it is assigned the [reactor-ts](https://github.com/lf-lang/reactor-ts) type `Present` which is defined as @@ -2132,11 +2132,11 @@ Second iteration - the microstep part of the tag is: 1. ... ``` -The first reaction prints the "First iteration" part of the output at microstep 0. The second reaction occurs one microstep later (explained in [Scheduling Delayed Reactions](#scheduling-delayed-reactions)) and illustrates how to split a `Tag` into its constituent `TimeValue` and microstep. +The first reaction prints the "First iteration" part of the output at microstep 0. The second reaction occurs one microstep later (explained in [Actions](../writing-reactors/actions.mdx)) and illustrates how to split a `Tag` into its constituent `TimeValue` and microstep. ### Summary of Time Functions -See [Time](#timed-behavior). These time functions are defined in the [time.ts](https://github.com/lf-lang/reactor-ts/blob/master/src/core/time.ts) library of [reactor-ts](https://github.com/lf-lang/reactor-ts). +See [Time](#time). These time functions are defined in the [time.ts](https://github.com/lf-lang/reactor-ts/blob/master/src/core/time.ts) library of [reactor-ts](https://github.com/lf-lang/reactor-ts). `UnitBasedTimeValue(value: number, unit:TimeUnit)` Constructor for `UnitBasedTimeValue`, a programmer-friendly subclass of TimeValue. Use a number and a `TimeUnit` enum. @@ -2607,7 +2607,7 @@ This version carries an `int` value. The data type of the action is required to > `lf_schedule_token(, , );` -This version carries a **token**, which has type `token_t` and points to the value, which can have any type. There is a `create_token()` function that can be used to create a token, but programmers will rarely need to use this. Instead, you can use `lf_schedule_value()` (see below), which will automatically create a token. Alternatively, for inputs with types ending in `*` or `[]`, the value is wrapped in a token, and the token can be obtained using the syntax `inputname->token` in a reaction and then forwarded using `lf_schedule_token()` (see [Dynamically Allocated Structs](#Dynamically-Allocated-Structs) above). If the input is mutable, the reaction can then even modify the value pointed to by the token and/or use `lf_schedule_token()` to send the token to a future logical time. For example, the [DelayPointer](https://github.com/lf-lang/lingua-franca/blob/master/test/C/src/DelayPointer.lf) reactor realizes a logical delay for any data type carried by a token: +This version carries a **token**, which has type `token_t` and points to the value, which can have any type. There is a `create_token()` function that can be used to create a token, but programmers will rarely need to use this. Instead, you can use `lf_schedule_value()` (see below), which will automatically create a token. Alternatively, for inputs with types ending in `*` or `[]`, the value is wrapped in a token, and the token can be obtained using the syntax `inputname->token` in a reaction and then forwarded using `lf_schedule_token()` (see [Dynamically Allocated Data](#dynamically-allocated-data) above). If the input is mutable, the reaction can then even modify the value pointed to by the token and/or use `lf_schedule_token()` to send the token to a future logical time. For example, the [DelayPointer](https://github.com/lf-lang/lingua-franca/blob/master/test/C/src/DelayPointer.lf) reactor realizes a logical delay for any data type carried by a token: ```lf-c reactor DelayPointer(delay:time(100 ms)) { @@ -2759,15 +2759,15 @@ FIXME: Details needed here. A suite of useful functions is provided in [util.h](https://www.lf-lang.org/reactor-c/d8/d3c/util_8h.html) for producing messages to be made visible when the generated program is run. Of course, you can always use `printf`, but this is not a good choice for logging or debug information, and it is not a good choice when output needs to be redirected to a window or some other user interface (see for example the [sensor simulator](https://github.com/lf-lang/reactor-c/blob/main/util/sensor_simulator.h)). Also, in federated execution, these functions identify which federate is producing the message. The functions are listed below. The arguments for all of these are identical to `printf` with the exception that a trailing newline is automatically added and therefore need not be included in the format string. -- `LF_PRINT_DEBUG(format, ...)`: Use this for verbose messages that are only needed during debugging. Nothing is printed unless the [target](<../introduction.md#logging>) parameter `logging` is set to `debug`. THe overhead is minimized when nothing is to be printed. +- `LF_PRINT_DEBUG(format, ...)`: Use this for verbose messages that are only needed during debugging. Nothing is printed unless the [target](target-declaration.mdx#logging) parameter `logging` is set to `debug`. THe overhead is minimized when nothing is to be printed. -- `LF_PRINT_LOG(format, ...)`: Use this for messages that are useful logs of the execution. Nothing is printed unless the [target parameter `logging`](<../introduction.md#logging>) is set to `log` or `debug`. This is a macro so that overhead is minimized when nothing is to be printed. +- `LF_PRINT_LOG(format, ...)`: Use this for messages that are useful logs of the execution. Nothing is printed unless the [target parameter `logging`](target-declaration.mdx#logging) is set to `log` or `debug`. This is a macro so that overhead is minimized when nothing is to be printed. -- `lf_print(format, ...)`: Use this for messages that should normally be printed but may need to be redirected to a user interface such as a window or terminal (see `register_print_function` below). These messages can be suppressed by setting the [logging target property](<../introduction.md#logging>) to `warn` or `error`. +- `lf_print(format, ...)`: Use this for messages that should normally be printed but may need to be redirected to a user interface such as a window or terminal (see `register_print_function` below). These messages can be suppressed by setting the [logging target property](target-declaration.mdx#logging) to `warn` or `error`. -- `lf_print_warning(format, ...)`: Use this for warning messages. These messages can be suppressed by setting the [logging target property](<../introduction.md#logging>) to `error`. +- `lf_print_warning(format, ...)`: Use this for warning messages. These messages can be suppressed by setting the [logging target property](target-declaration.mdx#logging) to `error`. -- `lf_print_error(format, ...)`: Use this for error messages. These messages are not suppressed by any [logging target property](<../introduction.md#logging>). +- `lf_print_error(format, ...)`: Use this for error messages. These messages are not suppressed by any [logging target property](target-declaration.mdx#logging). - `lf_print_error_and_exit(format, ...)`: Use this for catastrophic errors. @@ -2800,7 +2800,7 @@ Which type of messages are actually produced by the compiled program can be cont -The Python supports the [logging](<../introduction.md#logging>) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). +The Python supports the [logging](target-declaration.mdx#logging) target specification. This will cause the runtime to produce more or less information about the execution. However, user-facing functions for different logging levels are not yet implemented (see issue [#619](https://github.com/lf-lang/lingua-franca/issues/619)). @@ -2817,7 +2817,7 @@ The executable reacts to the environment variable `RUST_LOG`, which sets the log Error and warning logs are on by default. Enabling a level enables all greater levels (i.e., `RUST_LOG=info` also enables `warn` and `error`, but not `trace` or `debug`). -Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](<../introduction.md#command-line-arguments>). +Logging can also be turned on with the `--log-level` CLI option, if the application features a [CLI](target-declaration.mdx#command-line-arguments). Note that the `logging` target property is ignored, as its levels do not match the Rust standard levels we use (those of the [`log` crate](https://docs.rs/log/)). @@ -3012,7 +3012,7 @@ primitives and sleep functions. ### Multithreaded Implementation -By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](<../introduction.md#threading>) statement or the `--workers` [command-line argument](<../introduction.md#command-line-arguments>) is given. +By default, the C runtime system uses multiple worker threads in order to take advantage of multicore execution. The number of worker threads will match the number of cores on the machine unless the `workers` argument is given in the [target](target-declaration.mdx#workers) statement or the `--workers` [command-line argument](target-declaration.mdx#command-line-arguments) is given. Upon initialization, the main thread will create the specified number of worker threads. Execution proceeds in a manner similar to the [single threaded implementation](#single-threaded-implementation) @@ -3021,7 +3021,7 @@ The execution algorithm ensures that no reaction executes until all reactions th ### Single Threaded Implementation -By giving the `single-threaded` [target option](<../introduction.md#single-threaded>) or the `--single-threaded` [command-line argument](<../introduction.md#command-line-arguments>), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. +By giving the `single-threaded` [target option](target-declaration.mdx#single-threaded) or the `--single-threaded` [command-line argument](target-declaration.mdx#command-line-arguments), the generated program will execute the program using only a single thread. This option is most useful for creating programs to run on bare-metal microprocessors that have no threading support. On such platforms, mutual exclusion is typically realized by disabling interrupts. The execution strategy is to have two queues of pending accessor invocations, one that is sorted by tag (the **event queue**) and one that is sorted by priority (the **reaction queue**). @@ -3029,9 +3029,9 @@ Execution proceeds as follows: 1. At initialization, an event for each timer is put on the event queue and logical time is initialized to the current time, represented as the number of nanoseconds elapsed since January 1, 1970. -2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](<../introduction.md#command-line-arguments>) is given). +2. At each logical time, pull all events from event queue that have the same earliest tag, find the reactions that these events trigger, and put them on the reaction queue. If there are no events on the event queue, then exit the program (unless the `--keepalive true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). -3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](<../introduction.md#command-line-arguments>) is given). Then advance logical time to match that earliest timestamp. +3. Wait until physical time matches or exceeds that earliest timestamp (unless the `--fast true` [command-line argument](target-declaration.mdx#command-line-arguments) is given). Then advance logical time to match that earliest timestamp. 4. Execute reactions in order of priority from the reaction queue. These reactions may produce outputs, which results in more events getting put on the reaction queue. Those reactions are assured of having lower priority than the reaction that is executing. If a reaction calls `lf_schedule()`, an event will be put on the event queue, not the reaction queue. @@ -3045,7 +3045,7 @@ Unlike the C target, the Cpp target implements more of the analysis and setup of -The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [threading](<../introduction.md#threading>) target property can be used to override this behavior. +The Python target is built on top of the C runtime to enable maximum efficiency where possible. It uses the single-threaded C runtime by default but will switch to the multi-threaded C runtime if a physical action is detected. The [single-threaded](target-declaration.mdx#single-threaded) target property can be used to override this behavior. Running [lfc](../tools/command-line-tools.mdx) on a `XXX.lf` program that uses the Python target specification on a Linux machine will create the following files (other operating systems will have @@ -3230,7 +3230,7 @@ The Lingua Franca compiler automatically invokes other programs as it compiles a ### package.json -Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. +Node.js uses a [package.json](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/) file to describe metadata relevant to a Node project. This includes a list of project dependencies (i.e. modules) used by the project. When the Lingua Franca compiler copies a default package.json file into a Lingua Franca project that doesn't already have a package.json, the compiler runs the command `npm install` to create a node_modules directory. The default package.json only lists dependencies for the [reactor-ts](https://github.com/lf-lang/reactor-ts) submodule. [Follow these instructions](../writing-reactors/preambles.mdx#using-node-modules) to modify package.json if you want to use other Node modules in your reactors. ### tsconfig.json @@ -3242,7 +3242,7 @@ If the `tsc` type check was successful, the Lingua Franca compiler uses `babel` ### Debugging Type Errors -Let's take the [minimal reactor example](#a-minimal-example), and intentionally break it by adding a type error into the reaction. +Let's take the minimal reactor example, and intentionally break it by adding a type error into the reaction. ```lf-ts target TypeScript; @@ -3336,13 +3336,13 @@ These utility functions may be called within a TypeScript reaction: `util.getCurrentTag(): Tag` Gets the current (logical) tag. See [Tags](#tags). -`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#timed-behavior). +`util.getCurrentLogicalTime(): TimeValue` Gets the current logical TimeValue. See [Time](#time). -`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#timed-behavior). +`util.getCurrentPhysicalTime(): TimeValue` Gets the current physical TimeValue. See [Time](#time). -`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedLogicalTime(): TimeValue` Gets the elapsed logical TimeValue from execution start. See [Time](#time). -`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#timed-behavior). +`util.getElapsedPhysicalTime(): TimeValue` Gets the elapsed physical TimeValue from execution start. See [Time](#time). `util.success(): void` Invokes the [reactor-ts](https://github.com/lf-lang/reactor-ts) App's default success callback. FIXME: Currently doesn't do anything in Lingua Franca. @@ -3401,7 +3401,7 @@ See [Target Declaration](../introduction.md) for the full list of supported targ ### The Executable -The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](<../introduction.md#command-line-arguments>) for details. +The executable name is the name of the main reactor _transformed to snake_case_: `main reactor RustProgram` will generate `rust_program`. See [Command-Line Arguments](target-declaration.mdx#command-line-arguments) for details. ### File layout diff --git a/versioned_docs/version-0.9.0/reference/tracing.mdx b/versioned_docs/version-0.9.0/reference/tracing.mdx index 9359ec581..1e1f8e0ec 100644 --- a/versioned_docs/version-0.9.0/reference/tracing.mdx +++ b/versioned_docs/version-0.9.0/reference/tracing.mdx @@ -13,7 +13,7 @@ import { Tracing is a powerful tool when it comes to analysis and debugging of applications. Unfortunately, most tracing tools that are readily available are designed specifically for analyzing processes, threads and system calls. Specialized tools are required to enable analysis that is tailored to an alternative model of computation such as Reactors. The tools should be capable of understanding the fundamental concepts of the model, such as the distinction between logical and physical time, as well as structural units such as reactors and reactions. This page gives an overview of the currently supported trace mechanism, as well as an outline of alternative tools that could be useful in the future. -Tracing is different from [logging](<../introduction.md#logging>). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. +Tracing is different from [logging](target-declaration.mdx#logging). Logging produces human-readable output in textual form and incurs significant overhead. Tracing produces binary data that must be further processed to be useful and is designed to have minimal impact on the execution time of a program. Tracing is currently supported in the C, Python, and C++ targets. The mechanism used in C and Python is different from that used in C++. Tracing in C++ requires third-party tools that may only be available in Linux. Tracing in C and Python does not require any third-party tools. diff --git a/versioned_docs/version-0.9.0/videos.mdx b/versioned_docs/version-0.9.0/videos.mdx index 497e6832b..d17b4efec 100644 --- a/versioned_docs/version-0.9.0/videos.mdx +++ b/versioned_docs/version-0.9.0/videos.mdx @@ -9,12 +9,12 @@ A [video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9Y **Useful links:** - [Complete video playlist](https://youtube.com/playlist?list=PL4zzL7roKtfXyKE3k8lOwPub9YEjulS4o) -- [Part I: Introduction](#introduction) -- [Part II: Hello World](#hello) -- [Part III: Target Languages](#target) -- [Part IV: Basic Concepts](#concepts) -- [Part V: Concurrency and Performance](#concurrency) -- [Part VI: Research Overview](#research) +- [Part I: Introduction](#part-i-introduction) +- [Part II: Hello World](#part-ii-hello-world) +- [Part III: Target Languages](#part-iii-target-languages) +- [Part IV: Basic Concepts](#part-iv-basic-concepts) +- [Part V: Concurrency and Performance](#part-v-concurrency) +- [Part VI: Research Overview](#part-vi-research-overview) - [Slides](https://docs.google.com/presentation/d/14cfIMmkBFwt6NOj2ujVs7YXPAXYsoHgLS2rUgBM-Deg/present?slide=id.g623f095f12_0_0) ## Part I: Introduction diff --git a/versioned_docs/version-0.9.0/writing-reactors/actions.mdx b/versioned_docs/version-0.9.0/writing-reactors/actions.mdx index 2b76a0683..67d7d2c38 100644 --- a/versioned_docs/version-0.9.0/writing-reactors/actions.mdx +++ b/versioned_docs/version-0.9.0/writing-reactors/actions.mdx @@ -133,7 +133,7 @@ Action triggered at logical time 603669000 nsec after start. ... ``` -Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](<../introduction.md#fast>) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. +Here, logical time is lagging physical time by a few milliseconds. Note that, unless the [fast option](../reference/target-declaration.mdx#fast) is given, logical time _t_ chases physical time _T_, so _t_ < _T_. Hence, the event being scheduled in the reaction to input `x` is assured of being in the future in logical time. Whereas logical actions are required to be scheduled within a reaction of the reactor that declares the action, physical actions can be scheduled by code that is outside the Lingua Franca system. For example, some other thread or a callback function may call `schedule()`, passing it a physical action. For example: diff --git a/versioned_docs/version-0.9.0/writing-reactors/composing-reactors.mdx b/versioned_docs/version-0.9.0/writing-reactors/composing-reactors.mdx index daef9a51d..e8dde0c82 100644 --- a/versioned_docs/version-0.9.0/writing-reactors/composing-reactors.mdx +++ b/versioned_docs/version-0.9.0/writing-reactors/composing-reactors.mdx @@ -172,7 +172,7 @@ Connections may include a **logical delay** using the `after` keyword, as follow where `` can be any of the forms described in [Expressions](../reference/expressions.mdx). -The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/actions.mdx#superdense-time>) later than the event that triggered it. +The `after` keyword specifies that the logical time of the event delivered to the destination port will be larger than the logical time of the reaction that wrote to source port. The time value is required to be non-negative, but it can be zero, in which case the input event at the receiving end will be one [microstep](<../writing-reactors/superdense-time.mdx>) later than the event that triggered it. ## Physical Connections diff --git a/versioned_docs/version-0.9.0/writing-reactors/multiports-and-banks.mdx b/versioned_docs/version-0.9.0/writing-reactors/multiports-and-banks.mdx index 263e072a3..1ca30cd35 100644 --- a/versioned_docs/version-0.9.0/writing-reactors/multiports-and-banks.mdx +++ b/versioned_docs/version-0.9.0/writing-reactors/multiports-and-banks.mdx @@ -374,7 +374,7 @@ The syntax `(a.out)+` means "repeat the output port `a.out` one or more times as -Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#Combining-Banks-and-Multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: +Sometimes, we don't want to broadcast messages to all reactors, but need more fine-grained control as to which reactor within a bank receives a message. If we have separate source and destination reactors, this can be done by combining multiports and banks as was shown in [Combining Banks and Multiports](#combining-banks-and-multiports). Setting a value on the index _n_ of the output multiport, will result in a message to the _n_-th reactor instance within the destination bank. However, this pattern gets slightly more complicated, if we want to exchange addressable messages between instances of the same bank. This pattern is shown in the following example: import C_Interleaved from '../assets/code/c/src/Interleaved.lf'; import Cpp_Interleaved from '../assets/code/cpp/src/Interleaved.lf'; diff --git a/versioned_docs/version-0.9.0/writing-reactors/preambles.mdx b/versioned_docs/version-0.9.0/writing-reactors/preambles.mdx index fb7cd6793..a78e3bb67 100644 --- a/versioned_docs/version-0.9.0/writing-reactors/preambles.mdx +++ b/versioned_docs/version-0.9.0/writing-reactors/preambles.mdx @@ -326,7 +326,7 @@ Your platform is Linux By putting import in the `preamble`, the module becomes available in all reactions of this reactor using the `self` modifier. -**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx#python-target-implementation-details>). +**Note:** Preambles will be put in the generated Python class for the given reactor, and thus is part of the instance of the reactor. This means that anything you put in the preamble will be specific to a particular reactor instance and cannot be used to share information between different instantiations of the reactor (this is a feature, not a bug, because it helps ensure determinacy). For more information about implementation details of the Python target, see [Implementation Details](<../reference/target-language-details.mdx>). Alternatively, you can define a `preamble` outside any reactor definition. Such a `preamble` can be used for functions such as import or to define a global function. The following example shows importing the [hello](https://github.com/lf-lang/lingua-franca/blob/master/test/Python/src/include/hello.py) module: @@ -432,7 +432,7 @@ Converted string 42 to number 42 ### Using Node Modules -Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](#preamble) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](#typescript-target-implementation-details) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. +Installing Node.js modules for TypeScript reactors with `npm` is essentially the same as installing modules for an ordinary Node.js program. First, write a Lingua Franca program (`Foo.lf`) and compile it. It may not type check if if you're [importing modules in the preamble](../writing-reactors/preambles.mdx) and you haven't installed the modules yet, but compiling your program will cause the TypeScript code generator to [produce a project](../reference/target-language-details.mdx) for your program. There should now be a package.json file in the same directory as your .lf file. Open a terminal and navigate to that directory. You can use the standard [`npm install`](https://docs.npmjs.com/cli/install) command to install modules for your TypeScript reactors. The important takeaway here is with the package.json file and the compiled JavaScript in the Foo/dist/ directory, you have a standard Node.js program that executes as such. You can modify and debug it just as you would a Node.js program. diff --git a/versioned_docs/version-0.9.0/writing-reactors/termination.mdx b/versioned_docs/version-0.9.0/writing-reactors/termination.mdx index fc9b8244f..58a43bf71 100644 --- a/versioned_docs/version-0.9.0/writing-reactors/termination.mdx +++ b/versioned_docs/version-0.9.0/writing-reactors/termination.mdx @@ -29,7 +29,7 @@ We address each of these in turn. ## Timeout -The [target property `timeout`](<../introduction.md#timeout>) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). +The [target property `timeout`](../reference/target-declaration.mdx#timeout) specifies the last logical time at which reactions should be triggered. The last invocation of reactions will be at tag (`timeout`, 0). There is a significant subtlety when using [physical connections](<../writing-reactors/composing-reactors.mdx#physical-connections>), which are connections using the syntax `~>`. Such connections specify that the tag at the receiving end will be based on the physical time at which the message is received. If the tag assigned at the receiving end is greater than the final tag, then the message is lost. Hence, **messages sent near the `timeout` time are likely to be lost!** diff --git a/versioned_docs/version-0.9.0/writing-reactors/time-and-timers.mdx b/versioned_docs/version-0.9.0/writing-reactors/time-and-timers.mdx index 9f7ed7d03..41467929c 100644 --- a/versioned_docs/version-0.9.0/writing-reactors/time-and-timers.mdx +++ b/versioned_docs/version-0.9.0/writing-reactors/time-and-timers.mdx @@ -15,7 +15,7 @@ import { A key property of Lingua Franca is **logical time**. All events occur at an instant in logical time. By default, the runtime system does its best to align logical time with **physical time**, which is some measurement of time on the execution platform. The **lag** is defined to be physical time minus logical time, and the goal of the runtime system is maintain a small non-negative lag. -The **lag** is allowed to go negative only if the [`fast`](<../reference/target-declaration#fast>) target property or the [`--fast`](<../reference/target-declaration#command-line-arguments>) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. +The **lag** is allowed to go negative only if the [`fast`](../reference/target-declaration.mdx#fast) target property or the [`--fast`](../reference/target-declaration.mdx#command-line-arguments) command-line argument is set to `true`. In that case, the program will execute as fast as possible with no regard to physical time. @@ -60,7 +60,7 @@ import TS_SlowingClock from '../assets/code/ts/src/SlowingClock.lf'; -This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](<../writing-reactors/actions.mdx#logical-actions>), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: +This has two time parameters, `start` and `incr`, each with default value `100 ms` and type `time`. This parameter is used to initialize the `interval` state variable, which also stores a time. The `logical` `action` `a`, explained in [Actions](../writing-reactors/actions.mdx#logical-actions), is used to schedule events to occur at time `start` after program startup and then at intervals that are increased each time by `incr`. The result of executing this program will look like this: ``` Logical time since start: 100000000 nsec. @@ -80,7 +80,7 @@ The simplest use of logical time in Lingua Franca is to invoke a reaction period The ``, which is optional, specifies the time interval between timer events. The ``, which is also optional, specifies the (logical) time interval between when the program starts executing and the first timer event. If no period is given, then the timer event occurs only once. If neither an offset nor a period is specified, then one timer event occurs at program start, simultaneous with the `startup` event. -The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](<../reference/expressions.mdx#basic-expressions>) for allowable units. Consider the following example: +The period and offset are given by a number and a units, for example, `10 ms`. See the [expressions documentation](../reference/expressions.mdx#basic-expressions) for allowable units. Consider the following example: import C_Timer from '../assets/code/c/src/Timer.lf'; import Cpp_Timer from '../assets/code/cpp/src/Timer.lf'; @@ -165,7 +165,7 @@ A reaction is always invoked at a well-defined logical time, and logical time do ## Timeout -By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](<../introduction.md#timeout>) or a [`--timeout` command-line option](<../introduction.md#command-line-arguments>). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: +By default, a Lingua Franca program will terminate when there are no more events to process. If there is a timer with a non-zero period, then there will always be more events to process, so the default execution will be unbounded. To specify a finite execution horizon, you can either specify a [`timeout` target property](../reference/target-declaration.mdx#timeout) or a [`--timeout` command-line option](../reference/target-declaration.mdx#command-line-arguments). For example, the following `timeout` property will cause the above timer with a period of one second to terminate after 11 events: ) 0, but may occur at a larger microstep. See [Superdense Time](<../writing-reactors/actions.mdx#superdense-time>) and [Termination](../writing-reactors/termination.mdx). +The **shutdown** trigger typically occurs at [microstep](../writing-reactors/superdense-time.mdx) 0, but may occur at a larger microstep. See [Superdense Time](../writing-reactors/superdense-time.mdx) and [Termination](../writing-reactors/termination.mdx).