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:
- 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.
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:
- 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
Brak komentarzy.