Was this page helpful?

Target Declaration

This page is showing examples in the target language CC++PythonTypeScriptRust. You can change the target language in the left sidebar.

Every Lingua Franca program begins with a statement of this form:

    target <name> <parameters>

The <name> gives the name of some Lingua Franca target language, which is the language in which reactions are written. This is also the language of the program(s) generated by the Lingua Franca compiler. The target languages currently supported are C, C++, Python, TypeScript, and Rust.

Summary of Parameters

A target specification may have optional parameters, the names and values of which depend on which specific target you are using. Each parameter is a key-value pair, where the supported keys are a subset of the following:

  • auth: A boolean specifying to apply authorization between RTI and federates when federated execution.
  • build: A command to execute after code generation instead of the default compile command.
  • build-type: One of Release (the default), Debug, RelWithDebInfo and MinSizeRel.
  • cargo-dependencies: (Rust only) list of dependencies to include in the generated Cargo.toml file.
  • cargo-features: (Rust only) List of string names of features to include.
  • cmake: Whether to use cmake for building.
  • cmake-include: List of paths to cmake files to guide compilation.
  • compiler: A string giving the name of the target language compiler to use.
  • docker: A boolean to generate a Dockerfile.
  • external-runtime-path: Specify a pre-compiled external runtime library located to link to instead of the default.
  • export-dependency-graph: To export the reaction dependency graph as a dot graph (for debugging).
  • fast: A boolean specifying to execute as fast as possible without waiting for physical time to match logical time.
  • files: An array of paths to files or directories to be copied to the directory that contains the generated sources.
  • flags: An arrays of strings giving options to be passed to the target compiler.
  • logging: An indicator of how much information to print when executing the program.
  • no-compile: If true, then do not invoke a target language compiler. Just generate code.
  • no-runtime-validation: If true, disable runtime validation.
  • protobufs: An array of .proto files that are to be compiled and included in the generated code.
  • runtime-version: Specify which version of the runtime system to use.
  • rust-include: (Rust only) A set of Rust modules in the generated project.
  • single-file-project: (Rust only) If true, enables single-file project layout.
  • threading: Whether to use multiple threads.
  • timeout: A time value (with units) specifying the logical stop time of execution. See Termination.
  • workers: If using multiple threads, how many worker threads to create.

Not all targets support all target parameters. The full set of target parameters supported by the CCppPythonTypeScriptRust target is:

target C {
    auth: <true or false>
    build: <string>,
    build-type: <Release, Debug, RelWithDebInfo, or MinSizeRel>,
    cmake: <true or false>,
    cmake-include: <string or list of strings>,
    compiler: <string>,
    docker: <true or false>,
    fast: <true or false>,
    files: <string or list of strings>,
    flags: <string or list of strings>,
    logging: <error, warning, info, log, debug>,
    no-compile: <true or false>,
    protobufs: <string or list of strings>,
    threading: <true or false>,
    timeout: <time>,
    workers: <non-negative integer>,
};
target Cpp {
    build-type: <Release, Debug, RelWithDebInfo, or MinSizeRel>,
    cmake-include: <string or list of strings>,
    external-runtime-path: <string>,
    export-dependency-graph <true or false>,
    fast: <true or false>,
    logging: <error, warning, info, log, debug>,
    no-compile: <true or false>,
    no-runtime-validation: <true or false>,
    runtime-version: <string>,
    timeout: <time>,
    workers: <non-negative integer>,
};
target Python {
    docker: <true or false>,
    fast: <true or false>,
    files: <string or list of strings>,
    logging: <error, warning, info, log, debug>,
    no-compile: <true or false>,
    protobufs: <string or list of strings>,
    threading: <true or false>,
    timeout: <time>,
    workers: <non-negative integer>,
};
target TypeScript {
    docker: <true or false>,
    fast: <true or false>,
    logging: <ERROR, WARN, INFO, LOG, or DEBUG>,
    timeout: <time>,
};
target Rust {
    build-type: <Debug, Release, RelWithDebInfo, or MinSizeRel>,
    cargo-features: <array of strings>,
    cargo-dependencies: <list of key-value pairs>,
    export-dependency-graph: <true or false>,
    rust-include: <array of strings>,
    single-file-project: <true or false>,
    timeout: <time value>,
}

For example:

target C {
    cmake: false,
    compiler: "cc",
    flags: "-O3",
    fast: true,
    logging: log,
    timeout: 1 secs,
};

This specifies to use compiler cc instead of the default gcc, to use optimization level 3, to execute as fast as possible, and to exit execution when logical time has advanced to 10 seconds. Note that all events at logical time 10 seconds greater than the starting logical time will be executed.

The comma on the last parameter is optional, as is the semicolon on the last line. A target may support overriding the target parameters on the command line when invoking the compiled program.

auth

The CCppPythonTypeScriptRust target does not currently support the auth target option.

The detailed documentation is here.

build

The CCppPythonTypeScriptRust target does not currently support the build target option.

A command to execute after code generation instead of the default compile command. This is either a single string or an array of strings. The specified command(s) will be executed an environment that has the following environment variables defined:

  • LF_CURRENT_WORKING_DIRECTORY: The directory in which the command is invoked.
  • LF_SOURCE_DIRECTORY: The directory containing the .lf file being compiled.
  • LF_SOURCE_GEN_DIRECTORY: The directory in which generated files are placed.
  • LF_BIN_DIRECTORY: The directory into which to put binaries.

The command will be executed in the same directory as the .lf file being compiled. For example, if you specify

target C {
    build: "./compile.sh Foo"
}

then instead of invoking the C compiler after generating code, the code generator will invoke your compile.sh script, which could look something like this:

#!/bin/bash
# Build the generated code.
cd ${LF_SOURCE_GEN_DIRECTORY}
cmake .
make

# Move the executable to the bin directory.
mv $1 ${LF_BIN_DIRECTORY}

# Invoke the executable.
${LF_BIN_DIRECTORY}/$1

# Plot the results, which have appeared in the src-gen directory.
gnuplot ${LF_SOURCE_DIRECTORY}/$1.gnuplot
open $1.pdf

The first few lines of this script do the same thing that is normally done when there is no build option in the target. Specifically, they use cmake to create a makefile, invoke make, and then move the executable to the bin directory. The next line, however, gives new functionality. It executes the compiled code! The final two lines assume that the program has produced a file with data to be plotted and use gnuplot to plot the data. This requires, of course, that you have gnuplot installed, and that there is a file called Foo.gnuplot in the same directory as Foo.lf. The file Foo.gnuplot contains the commands to plot the data, and might look something like the following:

set title 'My Title'
set xrange [0:3]
set yrange [-2:2]
set xlabel "Time (seconds)"
set terminal pdf size 5, 3.5
set output 'Foo.pdf'
plot 'mydata1.data' using 1:2 with lines, \
     'mydata2.data' using 1:2 with lines

This assumes that your program has written two files, mydata1.data and mydata2.data containing two columns, time and value.

build-type

The CCppPythonTypeScriptRust target does not currently support the build-type target option.

This parameter works with cargo to specify how to compile the code. The following options are supported:

  • Release: Optimization is turned on and debug information is missing.
  • Debug: Debug information is included in the executable.
  • RelWithDebInfo: Optimization with debug information.
  • MinSizeRel: Optimize for smallest size.

This defaults to Release.

This parameter works with cmake to specify how to compile the code. The following options are supported:

  • Release: Optimization is turned on and debug information is missing.
  • Debug: Debug information is included in the executable.
  • RelWithDebInfo: Optimization with debug information.
  • MinSizeRel: Optimize for smallest size.

This defaults to Release.

cargo-dependencies

This is a list of dependencies to include in the generated Cargo.toml file. The value of this parameter is a map of package name to dependency-spec.

Here is an example for defining dependencies:

target Rust {
    cargo-dependencies: {
        fxhash: {
            version: "0.2.1",
        },
        rand: {
            version: "0.8",
            features: ["small_rng"],
        },
    }
};

cargo-features

This is a list of features of the generated crate. Supported are:

cmake

The CCppPythonTypeScriptRust target does not support the cmake target option.

The CCppPythonTypeScriptRust target does not support the cmake target option because it always uses cmake.

target C {
    cmake: <true or false>
};

This will enable or disable the CMake-based build system (the default is true). Enabling the CMake build system will result in a CMakeLists.txt being generated in the src-gen directory. This CMakeLists.txt is then used when cmake is invoked by the LF runtime (either the lfc or the IDE). Alternatively, the generated program can be built manually. To do so, in the src-gen/ProgramName directory, run:

mkdir build && cd build
cmake ../
make

If cmake is disabled, gcc is directly invoked after code generation by default. In this case, additional target properties, such as compiler and flags can be used to gain finer control over the compilation process.

cmake-include

The CCppPythonTypeScriptRust target does not support the cmake-include target option.

target C {
    cmake-include: ["relative/path/to/foo.txt", "relative/path/to/bar.txt", ...]
};
target Cpp {
    cmake-include: ["relative/path/to/foo.txt", "relative/path/to/bar.txt", ...]
};

This will optionally append additional custom CMake instructions to the generated CMakeLists.txt, drawing these instructions from the specified text files (e.g, foo.txt). The specified files are resolved using the same file search algorithm as used for the files target parameter. Those files will be copied into the src-gen directory that contains the generated sources. This is done to make the generated code more portable (a feature that is useful in federated execution).

The cmake-include target property can be used, for example, to add dependencies on various packages (e.g., by using the find_package and target_link_libraries commands).

A CMake variable called ${LF_MAIN_TARGET} can be used in the included text file(s) for convenience. This variable will contain the name of the CMake target (i.e., the name of the main reactor). For example, a foo.txt file can contain:

find_package(m REQUIRED) # Finds the m library

target_link_libraries( ${LF_MAIN_TARGET} m ) # Links the m library

foo.txt can then be included by specifying it as an argument to cmake-include.

Note: For a general tutorial on finding packages in CMake, see this external documentation entry. For a list of CMake find modules, see this.

The cmake-include parameter works in conjunction with the import statement. If any imported .lf file has cmake-include among its target properties, the specified text files will be appended to the current list of cmake-includes. These files will be resolved relative to the imported .lf file using the same search procedure as for the files parameter. This helps resolve dependencies in imported reactors automatically and makes the code more modular.

CMakeInclude.lf is an example that uses this feature. A more sophisticated example of the usage of this target parameter can be found in Rhythm.lf. A distributed version can be found in DistributedCMakeInclude.lf is a test that uses this feature.

Note: For federated execution, both cmake-include and files are kept separate for each federate as much as possible. This means that if one federate is imported, or uses an imported reactor that other federates don’t use, it will only have access to cmake-includes and files defined in the main .lf file, plus the selectively imported .lf files. DistributedCMakeIncludeSeparateCompile.lf is a test that demonstrates this feature.

See AsyncCallback.lf for an example.

compiler

The CCppPythonTypeScriptRust target does not support the compiler target option.

This parameter is a string giving the name of the C compiler to use. It is used only when cmake is set to false. For example:

target C {
    cmake: false,
    compiler: "cc",
};

The compiler option here specifies to use cc rather than gcc.

This parameter is a string giving the name of the C++ compiler to use. Normally CMake selects the best compiler for your system, but you can use this parameter to point it to your preferred C++ compiler.

docker

This option takes a boolean argument (default is false).

If true, a docker file will be generated in the unfederated case.

In the federated case, a docker file for each federate will be generated. A docker-compose file will also be generated for the top-level federated reactor.

The CCppPythonTypeScriptRust target does not support the docker target option.

external-runtime-path

The CCppPythonTypeScriptRust target does not support the external-runtime-path target option.

This option takes a string argument given a path to a pre-compiled external runtime library to use instead of the default one.

This option takes a path as string argument to a folder containing an alternative runtime crate to use instead of the default one.

export-dependency-graph

The CCppPythonTypeScriptRust target does not support the export-dependency-graph target option.

This parameter takes arguments true or false to specify whether the compiled binary will export its internal dependency graph as a dot graph when executed. This is a debugging utility.

If a CLI is generated, the target property is ignored, and the user should instead use the --export-graph flag of the generated program.

fast

By default, the execution of a Lingua Franca program is slowed down, if necessary, so that logical time does not elapse faster than physical time. If you wish to execute the program as fast as possible without this constraint, then specify the fast target parameter with value true.

files

The CCppPythonTypeScriptRust target does not support the files option.

The files target parameter specifies array of files or directories to be copied to the directory that contains the generated sources.

target C {
    files: ["file1", "file2", ...]
}
target Python {
    files: ["file1", "file2", ...]
}

The lookup procedure for these files and directories is as follows:

1- Search in the directory containing the .lf file that has the target directive.

2- If not found, search in LF_CLASSPATH.

3- If still not found, search in CLASSPATH.

4- If still not found, search for the file as a resource. Specifically, if a file begins with a forward slash /, then the path is assumed to be relative to the root directory of the Lingua Franca source tree.

For example, if you wish to use audio on a Mac, you can specify:

target C {
    files: ["/lib/C/util/audio_loop_mac.c", "/lib/C/util/audio_loop.h"]
}

Your preamble code can then include these files, for example:

preamble {=
    #include "audio_loop_mac.c"
=}

Your reactions can then invoke functions defined in that .c file.

Sometimes, you will need access to these files from target code in a reaction. For the C target (at least), the generated program will contain a line like this:

    #define TARGET_FILES_DIRECTORY "path"

where path is the full path to the directory containing these files. This can be used in reactions, for example, to read those files.

Moreover, the files target specification works in conjunction with the import statement. If a .lf file is imported and has designated supporting files using the files target parameter, those files will be resolved relative to that .lf file and copied to the directory that contains the generated sources. This is done to make code that imports other .lf files more modular. Rhythm.lf is an example that demonstrates most of these features.

flags

The CCppPythonTypeScriptRust target does not support the flags parameter.

This parameter is a list of strings giving additional arguments to pass to the target language compiler. It is used only when cmake is set to false. For example:

target C {
    cmake: false,
    flags: ["-g", "-I/usr/local/include", "-L/usr/local/lib", "-lpaho-mqtt3c"],
};

The flags option specifies to include debug information in the compiled code (-g); a directory to search for include files (-I/usr/local/include); a directory to search for library files (-L/usr/local/lib); a library to link with (-lpaho-mqtt3c, which will link with file libpaho-mqtt3c.so).

Note: Using the flags standard parameter when cmake is enabled is strongly discouraged, although supported. Flags are compiler-specific, and thus interfere with CMake’s ability to find the most suitable compiler for each platform. In a similar fashion, we recommend against the use of the compiler standard parameter for the same reason. A better solution is to provide a cmake-include file, as described next.

logging

The CCppPythonTypeScriptRust target does not support the logging parameter.

By default, when executing a generated Lingua Franca program, error messages, warnings, and informational messages are printed to standard out. You can get additional information printed by setting the logging parameter to LOG or DEBUG (or log or debug). The latter is more verbose. If you set the logging parameter to warn, then warnings and errors will be printed, but informational messages will not (e.g. message produced using the info_print utility function). If you set logging to error, then warning messages will also not be printed.

The C and Python targets also support tracing, which outputs binary traces of an execution rather than human-readable text and is designed to have minimal impact on performance.

The logging option is one of error, warn, info, log or debug. It specifies the level of diagnostic messages about execution to print to the console. A message will print if this parameter is greater than or equal to the level of the message, where error < warn < info < log < debug. The default value is info, which means that messages log or debug messages will not print.

The logging option is one of ERROR, WARN, INFO, LOG or DEBUG. It specifies the level of diagnostic messages about execution to print to the console. A message will print if this parameter is greater than or equal to the level of the message, where ERROR < WARN < INFO < LOG < DEBUG. The default value is INFO, which means that messages tagged LOG and DEBUG will not print. Internally this is handled by the ulog module.

no-compile

The CCppPythonTypeScriptRust target does not support the no-compile target option.

If true, then do not invoke a target language compiler nor cmake. Just generate code.

no-runtime-validation

The CCppPythonTypeScriptRust target does not support the no-runtime-validation target option.

This parameter takes value true or false (the default). If this is set to true, then all runtime checks in reactor-cpp will be disabled. This brings a slight performance boost but should be used with care and only on tested programs.

protobufs

The CCppPythonTypeScriptRust target does not support the protobufs target option.

Protobufs is a serialization protocol by which data in a target language can be copied over the network to a remote location. The protobufs target parameter gives an array of .proto files that are to be compiled and included in the generated code. For an example, see PersonProtocolBuffers.lf PersonProtocolBuffers.lf.

runtime-version

The CCppPythonTypeScriptRust target does not support the runtime-version target option.

This argument takes a string (with quotation marks) containing any tag, branch name, or git hash in the reactor-cpp repository. This will specify the version of the runtime library that the compiled binary will link against.

rust-include

set of Rust modules in the generated project. See Linking support files.

single-file-project

If true, enables single-file project layout.

threading

The CCppPythonTypeScriptRust target does not support the threading 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. See workers.

The Python target uses the single threaded C runtime by default but will switch to the multithreaded C runtime if a physical action is detected. This target property can be used to override this behavior.

Boolean flag (either true (default) or false) that controls if the project is to be compiled with support for multi-threading.

See workers.

timeout

A time value (with units) specifying the logical stop time of execution. See Termination.

workers

The CCppPythonTypeScriptRust 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), 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.

This parameter takes a non-negative integer and specifies the number of worker threads to execute the generated program. With value 0 (the default), the runtime engine is free to choose the number of worker threads to use. In the CCppPythonTypeScriptRust target, the runtime system will determine the number of hardware threads on the machine on which the program is run and set the number of worker threads equal to that number.

If the workers property is set to 1, the scheduler will not create any worker threads and instead inline the execution of reactions. This is an optimization and avoids any unnecessary synchronization. Note that, in contrast to the C target, the single threaded implementation is still thread safe and asynchronous reaction scheduling is supported.

This parameter takes a non-negative integer and specifies the number of worker threads to execute the generated program. Note, however, that the Python core is unable to execute safely in parallel on multiple cores. As a consequence, at execution time, each reaction invocation will acquire a mutual exclusion lock before executing. Hence, there is little point in setting this to any number greater than 1.

This parameter takes a non-negative integer and specifies the number of worker threads to execute the generated program. With value 0 (the default), the runtime engine is free to choose the number of worker threads to use and the number of worker threads may vary over time.

Command-Line Arguments

The generated executable may feature a command-line interface (CLI), if it uses the cargo-features: ["cli"] target property. When that feature is enabled:

  • some target properties become settable at runtime:
    • --timeout <time value>: override the default timeout mentioned as a target property. The syntax for times is just like the LF one (e.g. 1msec, "2 seconds").
    • --workers <number>: override the default worker count mentioned as a target property. This option is ignored unless the runtime crate has been built with the feature parallel-runtime.
    • --export-graph: export the dependency graph (corresponds to export-dependency-graph target property). This is a flag, i.e., absent means false, present means true. This means the value of the target property is ignored and not used as default.
    • --log-level: corresponds to the logging target property, but note that the levels have different meanings, and the target property is ignored. See Logging levels.
  • parameters of the main reactor are translated to CLI parameters.
    • Each LF parameter named param corresponds to a CLI parameter named --main-param. Underscores in the LF parameter name are replaced by hyphens.
    • The type of each parameters must implement the trait FromStr.

When the cli feature is disabled, the parameters of the main reactor will each assume their default value.

The generated C program understands the following command-line arguments, each of which has a short form (one character) and a long form:

  • -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 <duration> <units>: 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 <n>: 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.
  • -i, --id <n>: The ID of the federation that this reactor will join.

Any other command-line arguments result in printing the above information.

The generated C++ program understands the following command-line arguments, each of which has a short form (one character) and a long form:

  • -f, --fast: If set, then the program will execute as fast as possible, letting logical time advance faster than physical time.
  • -o, --timeout '<duration> <units>': 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 <n>: 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).

The Python target does not currently support any command-line arguments. You must specify properties as target parameters.

In the TypeScript target, the generated JavaScript program understands the following command-line arguments, each of which has a short form (one character) and a long form:

  • -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 '<duration> <units>': 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. For the duration and units of a timeout argument to be parsed correctly as a single value, these should be specified in quotes with no leading or trailing space (e.g. ‘5 sec’).
  • -k, --keepalive [true | false]: Specifies whether to stop execution if there are no events to process. This defaults to false, meaning that the program will stop executing when there are no more events on the event queue. If you set this to true, then the program will keep executing until either the timeout logical time is reached or the program is externally killed. If you have physical actions, it usually makes sense to set this to true.
  • -l, --logging [ERROR | WARN | INFO | LOG | DEBUG]: The level of logging messages from the reactor-ts runtime to to print to the console. Messages tagged with a given type (error, warn, etc.) will print if this argument is greater than or equal to the level of the message (ERROR < WARN < INFO < LOG < DEBUG).
  • -h, --help: Print this usage guide. The program will not execute if this flag is present.

If provided, a command line argument will override whatever value the corresponding target property had specified in the source .lf file.

Command line options are parsed by the command-line-arguments module with these rules. For example

node <LF_file_name>/dist/<LF_file_name>.js -f false --keepalive=true -o '4 sec' -l INFO

is a valid setting.

Any errors in command-line arguments result in printing the above information. The program will not execute if there is a parsing error for command-line arguments.

Custom Command-Line Arguments

User-defined command-line arguments may be created by giving the main reactor 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 '<duration> <units>' (in quotes).

Note: Custom arguments may not have the same names as standard arguments like timeout or keepalive.

For example this reactor has a custom command line argument named customArg of type number and default value 2:

target TypeScript;
main reactor clArg(customArg:number(2)) {
    reaction (startup) {=
        console.log(customArg);
    =}
}

If this reactor is compiled from the file simpleCLArgs.lf, executing

node simpleCLArgs/dist/simpleCLArgs.js

outputs the default value 2. But running

node simpleCLArgs/dist/simpleCLArgs.js --customArg=42

outputs 42. Additionally, we can view documentation for the custom command line argument with the --help command.

node simpleCLArgs/dist/simpleCLArgs.js -h

The program will generate the standard usage guide, but also

--customArg '<duration> <units>'                    Custom argument. Refer to
                                                      <path>/simpleCLArgs.lf
                                                      for documentation.

Additional types for Custom Command-Line Arguments

Main reactor parameters that are not typed string, number, boolean, or time will not create custom command-line arguments. However, that doesn’t mean it is impossible to obtain other types from the command line, just use a string and specify how the parsing is done yourself. See below for an example of a reactor that parses a custom command-line argument of type string into a state variable of type Array<number> using JSON.parse and a user-defined type guard.

target TypeScript;
main reactor customType(arrayArg:string("")) {
    preamble {=
        function isArrayOfNumbers(x: any): x is Array<number> {
            for (let item of x) {
                if (typeof item !== "number") {
                    return false;
                }
            }
            return true;
        }
    =}
    state foo:{=Array<number>=}({=[]=});
    reaction (startup) {=
        let parsedArgument = JSON.parse(customType);
        if (isArrayOfNumbers(parsedArgument)) {
            foo = parsedArgument;
            }
        else {
            throw new Error("Custom command line argument is not an array of numbers.");
        }
        console.log(foo);
    =}
}

Lingua Franca is an open source project. Help us improve these pages by sending a Pull Request

Contributors to this page:
Eeal  (7)
JJakio815  (4)
CMChristian Menard  (4)
HKHokeun Kim  (3)
PDPeter Donovan  (2)
JHJohannes Hayeß  (2)
SSteven  (2)
1+

Last updated: Mar 30, 2023