Skip to content
Stable.msx@modelscript/modelscript 10 diagnostic rules
Parser WASM GLR
Diagnostics 10 rules
DAE Arena Lowering
Simulation Co-sim / Export
Projections DAE
Live ExampleServoDriveThread.msx

Closed-Loop Electromechanical Servo Drive

Couples a permanent-magnet DC motor, harmonic gear reducer, and proportional-derivative position controller with safety invariants.

Playground
Source (18 lines)
1model ServoDriveThread
2  parameter Real J_load = 0.045 "Load moment of inertia [kg.m2]";
3  parameter Real K_t = 0.82 "Motor torque constant [N.m/A]";
4  parameter Real R_a = 1.25 "Armature resistance [Ohm]";
5  parameter Real K_p = 48.0 "Proportional gain [V/rad]";
6  parameter Real K_d = 6.5 "Derivative damping gain [V.s/rad]";
7  parameter Real theta_ref = 1.5708 "Target step angle [rad]";
8 
9  Real theta(start = 0.0) "Output shaft angle [rad]";
10  Real omega(start = 0.0) "Angular velocity [rad/s]";
11  Real i_a(start = 0.0) "Armature current [A]";
12  Real v_cmd "Controller voltage command [V]";
13equation
14  v_cmd = K_p * (theta_ref - theta) - K_d * omega;
15  R_a * i_a + K_t * omega = v_cmd;
16  J_load * der(omega) = K_t * i_a - 0.12 * omega;
17  der(theta) = omega;
18end ServoDriveThread;
Multi-Domain Block & Physical Schematic
theta_ref v_cmd [V] K_t·i_a [N·m] theta, omega «source» Step Reference «parameters» theta_ref = 1.5708 rad «control» PD Controller «gains» K_p = 48.0 V/rad K_d = 6.5 V·s/rad «electrical» PM DC Armature «parameters» R_a = 1.25 Ω K_t = 0.82 N·m/A «mechanics» Inertial Shaft Load «states» J_load = 0.045 kg·m² theta, omega
Drag to pan · Click % to reset

ModelScript (.msx, .modelscript) ​

@modelscript/modelscript (languages/modelscript) is the native ModelScript systems modeling and query language. It combines zero-cost linear-memory data layout control (@unmanaged struct), WebAssembly/C++ native compilation, and declarative XQuery-inspired FLWOR (for–let–where–order by–return) queries over polyglot engineering graphs.


Supported Extensions & Dialects ​

ExtensionDescription
.msxCanonical ModelScript source module
.modelscriptLong-form ModelScript source module

Language Features & Grammar ​

The native WebAssembly GLR parser (languages/modelscript/src/language.ts) parses .msx modules into a compact Concrete Syntax Tree (CST) with five primary syntactic constructs:

1. Module Imports ​

Import declarations bind symbols from external ModelScript modules or polyglot engineering artifacts:

ts
import { ThermalNode, Conductance as G } from "./thermal_kernel.msx";

2. Unmanaged Linear-Memory Structs (@unmanaged struct) ​

Structs annotated with @unmanaged are packed directly into 32-bit WebAssembly linear memory without garbage-collected wrapper allocation:

ts
@unmanaged struct StateVector {
  id: u32;
  temperature: f64;
  pressure: f64;
  active: bool;
}

3. Type System ​

  • Primitive Types: i32, u32, i64, u64, f32, f64, bool, string, usize, void
  • Generic & Pointer Types: Array<T>, Slice<T>, ptr<T>
  • User-Defined Structs: Any declared struct identifier

4. Functions, Statements & Control Flow ​

Functions declare strongly typed parameters and return types, supporting let and const variable bindings, if/else branches, while loops, C-style for loops, and member/index expressions:

ts
const BOLTZMANN: f64 = 1.380649e-23;

function computeHeatFlux(k: f64, area: f64, dT: f64, dx: f64): f64 {
  if (dx <= 0.0) {
    return 0.0;
  }
  let flux: f64 = -k * area * (dT / dx);
  return flux;
}

5. Declarative FLWOR Queries ​

ModelScript embeds first-class FLWOR (for–let–where–order by–return) expressions directly in the expression grammar for querying collections, CST nodes, and simulation trajectories:

ts
let criticalNodes =
  for node in nodes
  let margin := node.limit - node.temperature
  where margin < 15.0 && node.active == true
  order by margin asc
  return { id: node.id, margin: margin };

Multi-Target Compiler (ModelScriptCompiler) ​

ModelScriptCompiler (languages/modelscript/src/index.ts) lowers the linear-memory CST across three code generation backends:

BackendEmitter ClassAPI MethodsTarget Output
JavaScriptJsEmittercompileToJs(source) / executeJs(source, context)Executable ES module with lowered FLWOR pipelines (.filter().sort().map())
WebAssemblyWasmEmittercompileToWat(source) / compileToWasm(source) / executeWasm(source, fn, args)Textual WAT S-expressions and binary .wasm modules with @unmanaged linear-memory offsets
Native BinaryNativeEmittercompileToNative(source, { outPath, entryFn?, cc?, cflags? })WASM lowered to C via wasm2c, then compiled with the host C compiler ($CC, default clang)
ts
import fs from "node:fs";
import { ModelScriptCompiler } from "@modelscript/modelscript";

const compiler = new ModelScriptCompiler();
await compiler.init();

const source = fs.readFileSync("kernel.msx", "utf8");
const { js } = compiler.compileToJs(source); // ES module source
const wasm = await compiler.compileToWasm(source); // Uint8Array
const result = await compiler.executeWasm(source, "main", []);
const binary = await compiler.compileToNative(source, { outPath: "build/kernel" }); // requires wasm2c + clang

Command Line Interface (msx compile & msx lint) ​

Compile, lint, and run ModelScript source modules directly from the terminal:

bash
# Lint ModelScript modules for syntax, type errors, and unmanaged struct layout
msx lint kernel.msx

# Compile a ModelScript module into flattened DAE or WebAssembly bytecode
msx compile MainModule kernel.msx --flattener=wasm --timing

Salsa Query Engine & Linear-Memory Struct Layout ​

ModelScriptQueryEngine (languages/modelscript/src/queries.ts) provides memoized semantic queries over the CST:

  • structLayout(rawStructNode): Computes deterministic 32-bit WebAssembly linear-memory byte layouts (StructLayout) for every struct_declaration:
    • bool: 1 byte (alignment 1)
    • i32, u32, f32, usize, string, ptr<T>, Array<T>, Slice<T>: 4 bytes (alignment 4)
    • i64, u64, f64: 8 bytes (alignment 8)
    • Automatically inserts natural alignment padding (alignOffset) between fields and aligns the total struct byte size to the maximum field alignment (maxAlign).
  • inferExpressionType(rawNode, scope): Infers static types across literals, binary/unary expressions, struct field access, function calls, and FLWOR return clauses (Array<ReturnType>).

Semantic Linter & Error Codes ​

ModelScriptLinter (languages/modelscript/src/linter.ts and languages/modelscript/src/errors.ts) enforces 10 static analysis rules across syntax, name resolution, type checking, FLWOR clauses, and struct/function calls:

10 rules10 error

CodeRuleSeverityMessage
M1001parse-errorerrorParse error.
M2001undefined-variableerrorVariable '<name>' is not declared in current scope.
M2002duplicate-declarationerrorIdentifier '<name>' is already declared in this scope.
M2003unknown-typeerrorType '<typeName>' is not recognized.
M3001type-mismatcherrorType mismatch: cannot assign '<sourceType>' to '<targetType>'.
M3002invalid-binary-operanderrorOperator '<op>' cannot be applied to operands of type '<type>'.
M4001non-iterable-collectionerrorExpression '<expr>' in 'for' clause is not iterable.
M4002flwor-unbound-variableerrorVariable '<varName>' in FLWOR clause is not bound in preceding 'for' or 'let' clauses.
M5001argument-count-mismatcherrorFunction '<fnName>' expects <expected> arguments, but got <actual>.
M5002unknown-struct-fielderrorStruct '<structName>' has no field named '<fieldName>'.

Generated from languages/modelscript/src/errors.ts. All languages →


Polyglot TGG Rules ​

@modelscript/modelscript registers two Triple Graph Grammar (TGG) synchronization rules in languages/modelscript/src/language.ts for bidirectional projection with Modelica:

Rule NameSource PatternTarget Pattern (modelica)Semantics
ModelScriptStructToModelicaRecordStructDeclarationClassDefinition (record)Synchronizes a @unmanaged struct declaration with a Modelica record definition
ModelScriptParamToModelicaModVariableDeclarationComponentClause (parameter)Synchronizes a top-level constant or variable binding with a Modelica component parameter modification

Open-Core under the GNU AGPL v3 License; Enterprise Edition (ee/) under the ModelScript Enterprise License. • Trademark Policy