Powrót do strony głównej

HydraScript: język ze statycznym typowaniem i CGI dla Docker

HydraScript — język programowania z syntaksą JavaScript i statycznym typowaniem, opracowany jako projekt open-source. Artykuł opisuje cechy języka, system statycznej analizy i praktyczne zastosowanie do skryptów CGI z wdrażaniem w Docker.

Tworzymy usługi webowe na HydraScript: od parsowania JSON do Docker
Advertisement 728x90

HydraScript: od pracy dyplomowej do narzędzia CGI do parsowania JSON

Programista C# stworzył język programowania HydraScript, łączący składnię JavaScript ze statycznym typowaniem. Projekt ewoluował od pracy studenckiej do narzędzia open-source z obsługą CGI-skryptów, umożliwiającego wdrażanie usług webowych w Docker.

Ewolucja projektu edukacyjnego w narzędzie open-source

Początkowo HydraScript był koncepcją pracy dyplomowej "Rozszerzony Podzbiór JavaScript" na wydziale IU-9 Politechniki Baumanowskiej. Po czterech latach pracy wieczorowej projekt przekształcił się w pełnoprawny produkt open-source z CI/CD na GitHub Actions, semantycznym wersjonowaniem i automatycznymi wydaniami. Pliki binarne interpretera są kompilowane dla Windows (x64), macOS (arm64) i Linux (x64) w trybie Native AOT, co eliminuje zależności od środowiska uruchomieniowego.

Główne cele projektu:

Google AdInline article slot
  • Częściowa implementacja JavaScript z obiektami i strukturalnym statycznym typowaniem bez słów kluczowych constructor, class, interface.
  • Publiczny reverse-engineering współczesnych metod analizy statycznej.
  • Demistyfikacja technologii kompilatorowych poprzez otwarty kod źródłowy.
  • Gromadzenie zrozumiałych implementacji standardowych zadań kompilatorowych.

Analiza statyczna jako kluczowa zaleta

System typów HydraScript zapewnia kontrole, które w innych językach występują tylko podczas wykonania.

Wykrywanie dostępu do niezainicjalizowanych zmiennych

Interpreter analizuje kolejność inicjalizacji, zapobiegając błędom czasu wykonania. Przykład problematycznego kodu w TypeScript/JavaScript:

let x = f()
function f() {
    console.log(x) // Błąd: odwołanie do x przed przypisaniem
    return 5
}

HydraScript wykrywa ten problem na etapie kompilacji.

Google AdInline article slot

Automatyczne wartości domyślne

W przeciwieństwie do C#, gdzie niezainicjalizowane zmienne lokalne powodują błąd kompilacji, HydraScript przypisuje wartości domyślne na podstawie wywnioskowanego typu:

let x: number
>>> x // 0

let xArr: number[]
>>> xArr // []

let s: string
>>> ~s // 0 (długość ciągu znaków)

Rozdzielne przestrzenie nazw dla symboli

Język obsługuje trzy typy symboli: VariableSymbol, TypeSymbol i FunctionSymbol. Unikalność identyfikatorów jest wymagana tylko w ramach jednego typu, co pozwala używać tej samej nazwy dla różnych encji:

type x = number
let x:x
function x(x:x) {
    >>>x
    x = x + 1
}
x(x)

Integracja CGI dla web developmentu

Do praktycznego zastosowania HydraScript w backend developmentie dodano obsługę CGI-skryptów. Implementacja wymagała:

Google AdInline article slot
  • API do pracy z ciągami znaków
  • Wyjście na stdout
  • Odczyt zmiennych środowiskowych
  • Obsługę shebang-komentarzy

Wdrażanie w środowisku Docker

Konfiguracja obrazu Docker na bazie httpd (Apache 2) z zainstalowanym interpreterem HydraScript:

FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine as sdk-build
RUN dotnet tool update -g hydrascript
ENV PATH="/root/.dotnet/tools:${PATH}"

FROM httpd:2.4-alpine
COPY --from=sdk-build /root/.dotnet/tools/ /usr/bin
RUN apk add dotnet10-runtime

Przykładowy CGI-skrypt do parsowania QueryString

Skrypt przekształca parametry URL w ustrukturyzowany JSON, pokazując praktyczne zastosowanie języka:

#!/usr/bin/hydrascript

type QueryStringParseResultItem = {
    name: string;
    value: string;
}

type QueryStringParseResult = {
    result: QueryStringParseResultItem[];
}

type QueryStringParser = {
    input: string;
}

function parse(parser: QueryStringParser): QueryStringParseResult {
    const qsLen = ~parser.input
    let i = 0
    let items: QueryStringParseResultItem[]

    let currentName: string, currentValue: string
    let isName = true
    while (i < qsLen) {
        const currentChar = parser.input[i]
        if (currentChar == "&" || i == qsLen - 1) {
            let addittion = i == qsLen - 1 && currentChar != "&" ? currentChar : ""
            items = items ++ [{name: currentName; value: currentValue + addittion;}]
            currentName = ""
            currentValue = ""
            isName = true
        } else if (currentChar == "=") {
            isName = false
        } else {
            if (isName) {
                currentName = currentName + currentChar
            } else {
                currentValue = currentValue + currentChar
            }
        }
        i = i + 1
    }

    return {
        result: items;
    }
}

let parser: QueryStringParser = {
    input: $QUERY_STRING;
}

>>> "Content-Type: application/json\n\n"
>>>  parser.parse()

Dla ciągu a=1&b=bla&c=false skrypt zwraca:

{
  "result": [
    {"name": "a", "value": "1"},
    {"name": "b", "value": "bla"},
    {"name": "c", "value": "false"}
  ]
}

Co jest ważne

• HydraScript implementuje podejście hybrydowe: składnia JavaScript ze statycznym typowaniem bez klas i konstruktorów.

• System analizy statycznej zapobiega powszechnym błędom, takim jak dostęp do niezainicjalizowanych zmiennych.

• Obsługa CGI-skryptów pozwala używać języka do web developmentu z wdrażaniem w Docker.

• Projekt rozwija się jako open-source z pełnym cyklem rozwojowym: CI/CD, semantyczne wersjonowanie, kompilacje wieloplatformowe.

— Editorial Team

Advertisement 728x90

Czytaj dalej