HydraScript 2.6.0
dotnet tool install --global HydraScript --version 2.6.0
dotnet new tool-manifest
dotnet tool install --local HydraScript --version 2.6.0
#tool dotnet:?package=HydraScript&version=2.6.0
nuke :add-package HydraScript --version 2.6.0
HydraScript
Installation
Interpreter executable is built during release for 3 following platforms:
- Windows (x64)
- MacOS (arm64 Apple Silicon)
- Linux (x64)
Download hydrascript executable on the corresponding release page.
The latest relase is available here.
Alternatively you can consume HydraScript as dotnet tool:
dotnet tool update --global hydrascript
Project History
It started as a bachelor thesis "Extended JavaScript Subset". Now it's named "HydraScript", because as I fix one bug another occurs.
I took ECMA-262 standard as a basis and made:
Working samples can be found here. I use them for integration tests.
Project Goals
- Partially implement JavaScript with objects and strong static structural typing, getting rid of such things as:
constructor,class,interface - Publicly reverse engineer modern static analysis (type inference, forward refs, compile-time detection of the runtime errors, etc.)
- Simplifying compilers construction domain with HydraScript source code
- Gather clear and concise standard problem solutions and algorithm implementations (Lexer, Parser, CFG, SSA, DCE, etc.)
Language docs
Comments
All comments are single-line:
// double slash comment
# shebang comment
Typing
The HydraScript has strong static structural typing.
There are 5 primitive types:
- number
- boolean
- string
- null
- void
The other types can be grouped as such:
- NullableType (type that allows
null) - ObjectType (the type of object, obviously, and also is NullableType)
- ArrayType (the type of array)
The types have the following default values:
| Type | Value |
|---|---|
| number | 0 |
| boolean | false |
| string | "" |
| NullableType | null |
| ArrayType | [] |
You can also create your own type alias as in C++ or TypeScript:
type int = number
type maybeInt = int?
type ints = int[]
type point = {
x: int;
y: int;
}
type composite = {
p: point;
arr: ints;
}
Strings
Strings support following operations:
- index access, returns
string:
let str = "str"
>>> str[1] // t
- length getter:
let str = "str"
>>> ~str // 3
Variables
For declaring mutable variables use let:
let i = 1 // HydraScript infers type from expression
let j: number // Here it writes to j the default value
let k: number = 1 // Fully explicit declaration
For declaring readonly variables use const:
const flag = true
To work with Environment Variables place $ before identifier:
$MY_ENV_VAR = "my_env_var_value"
const flagValue = $FLAG_VALUE
Input and Output
The HydraScript is able to print any values in console and read strings from it:
# output
>>> [1, 2, 3]
>>> { x: true; }
>>> "Hello, world!"
// input
let name: string
<<< name
Objects
Object literal declaration is similar to JSON:
let v2d = {
x: 3;
y: 4;
}
You can clone objects using with expressions like in C#:
let v = {
x: 2;
y: 1;
}
let vToX = v with { y: 0; }
Arrays
HydraScript arrays are basically lists. Legacy naming, unfortunately.
Array literal declaration is similar to JSON:
let array = [1, 2, 3]
You have special operators to work with arrays:
let size = ~array // length
array::1 // remove at index
array = array ++ [5, 7] // concatenation
Operators
| Operator | Binary or Unary | Operand Types | Result Type |
|---|---|---|---|
| + | binary | both number or both string | number or string |
| *, -, /, % | binary | number | number |
| ||, && | binary | boolean | boolean |
| !=, == | binary | same on both sides | boolean |
| ⇐, >=, >, < | binary | number | boolean |
| ! | unary | boolean | boolean |
| - | unary | number | number |
| ++ | binary | [] | [] |
| :: | binary | [] and number | void |
| ~ | unary | [] or string | number |
Conditionals
The language supports classic if-else:
if (1 == 1) {
// ...
} else if (2 == 2) {
// ...
}
else {
// ...
}
// basically C-like syntax and semantic
// test expression must have boolean type
There is also ternary operator:
let x = 1 > 0 ? 0 <= 1 ? 1 : 0 : -2 < 0 ? -1 : 0
Loops
Now it has only while:
while (cond) {
// ...
continue
// ...
break
}
Functions
Functions are similar to TypeScript:
// declaration
function add(a: number, b: number): number {
return a + b
}
// call
let c = add(1, 2)
The return type can be specified explicitly or inferred:
// this is also valid
function add(a: number, b: number) {
return a + b
}
let c = add(1, 2) // c is number
Methods
A function can be method if it's bound to an object using the "Golang-like approach":
# The binding is done with object type alias
// step 1. Declare type alias
type Point2 = {
x: number;
y: number;
}
// step 2. Declare variable of type defined earlier
// It's obligatory to explicitly define type after colon to make it work
let v2d: Point2 = {
x: 3;
y: 4;
}
// step 3. While declaring function place first the paremeter with aliased object type
// it's basically explicit "this"
function lengthSquared(obj: Point2) {
let x = obj.x
let y = obj.y
return x * x + y * y
}
// step 4. make a call
let s = v2d.lengthSquared()
Overloads and default parameters
Both, methods and functions, do support overloading and default parameters:
function func(x = 0){
>>> x
}
function func(x:number, y:number) {
return x + y
}
func()
func(1)
func(func(2, 3))
Access operators
Access means being able to get element of an array or property of an object:
// objects
let x = v2d.x
// arrays
let l = array[2]
Type casting
HydraScript supports explicit casting through as keyword:
let s = v2d as string
let one = "1" as number
let falseValue = 0 as boolean
let nullableNumber = null as number?
One can cast using following rules:
any→stringstring→numberstring→booleanboolean→numbernumber→booleantype?→typetype→type?null→type?
Requirements
Before 2.3.0 version executable launch needed .NET Runtime installed.
There is match table of hydrascript and dotnet:
| hydrascript | dotnet |
|---|---|
| <ul><li>1.0.0</li><li>1.0.2</li></ul> | .NET 5 |
| <ul><li>1.1.2</li><li>1.1.3</li><li>1.1.4</li><li>1.1.5</li></ul> | .NET 6 |
| <ul><li>1.2.5</li><li>1.2.6</li><ul> | .NET 7 |
| 2.0.0 | .NET 8 |
| <ul><li>2.1.0</li><li>2.1.1</li><li>2.2.0</li></ul> | .NET 9 |
If you use dotnet tool then requirements is specified on NuGet page.
Build from source
Install latest .NET SDK. The project uses SLNX as solution format.
Do this inside HydraScript root after cloning repository:
dotnet publish ./src/HydraScript/HydraScript.csproj -r <RUNTIME_IDENTIFIER> -o <OUTPUT_DIRECTORY>
Runtime identifier list can be found here
How to run
Default:
HydraScript file.js
Dumping debug info as files (tokens, ast, ir code):
HydraScript file.js --dump
Sources:
- "Compilers Construction" and "Optimized Code Generation" courses of @bmstu-iu9
- ECMA-262
- DragonBook
- Stanford CS143 Lectures
- Simple Virtual Machine
- Ахо А., Ульман Дж. Теория синтаксического анализа, перевода и компиляции
- Свердлов С.З. Языки программирования и методы трансляции
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.6.0 | 71 | 12/26/2025 |
| 2.5.1 | 118 | 12/23/2025 |
| 2.5.0 | 113 | 12/23/2025 |
| 2.4.0 | 120 | 12/23/2025 |
| 2.3.0 | 120 | 12/23/2025 |
| 2.2.0 | 116 | 12/23/2025 |
| 2.1.1 | 114 | 12/23/2025 |
| 2.1.0 | 118 | 12/23/2025 |
| 2.0.0 | 113 | 12/23/2025 |
| 1.2.6 | 113 | 12/23/2025 |
| 1.2.5 | 115 | 12/23/2025 |
| 1.1.5 | 112 | 12/23/2025 |
| 1.1.4 | 109 | 12/23/2025 |
| 1.1.3 | 118 | 12/23/2025 |
| 1.1.2 | 114 | 12/23/2025 |
| 1.0.2 | 123 | 12/23/2025 |
| 1.0.0 | 118 | 12/23/2025 |