Przejdź do treści

Kompletne przykłady języka

Zakres weryfikacji

Treść zachowana z obecnego źródła. Publikacja dokumentacji nie oznacza ponownego potwierdzenia wszystkich komend, przykładów i deklaracji możliwości.

Poziom: wszystkie poziomy. Przykłady rosną razem z zakresem kontroli.

Każdy przykład jest pełnym plikiem .jnx i przechodzi junexis check w automatycznej kontroli dokumentacji.

Początkujący: wartościowy system z bezpiecznym prowadzeniem

Trzy zadania tworzą pomiary, podejmują decyzję i obsługują alarm. Kompilator otrzymuje jedno bezpieczne środowisko, ale użytkownik poznaje typowane komunikaty, asynchroniczność oraz topologię.

// Kurs początkujący: wartościowy system z typowanym przepływem danych.
struct PomiarTemperatury {
    strefa: Text
    wartosc: Float
}

struct AlarmTemperatury {
    strefa: Text
    komunikat: Text
}

task OdbierzPomiar() @server -> chan<PomiarTemperatury> {
    config {
        strefa: Text : "magazyn-A"
        wartosc_testowa: Float : 31.5
    }

    every 2s {
        send PomiarTemperatury {
            strefa: config.strefa,
            wartosc: config.wartosc_testowa
        }
    }
}

task OcenPomiar(wejscie: chan<PomiarTemperatury>) @server -> chan<AlarmTemperatury> {
    config {
        prog_alarmu: Float : 28.0
    }

    loop {
        let pomiar = recv wejscie
        if pomiar.wartosc > config.prog_alarmu {
            send AlarmTemperatury {
                strefa: pomiar.strefa,
                komunikat: "Temperatura przekroczyla bezpieczny prog"
            }
        }
    }
}

task ZapiszAlarm(wejscie: chan<AlarmTemperatury>) @server {
    for alarm in wejscie {
        log(alarm.komunikat)
    }
}

pipeline StraznikMagazynu {
    use OdbierzPomiar -> OcenPomiar
    use OcenPomiar -> ZapiszAlarm
}

Pobierz pełny system początkujący i otwórz kurs krok po kroku.

Mała próbka składni

Plik beginner.jnx pozostaje szybką kontrolą parsera i generatora. Nie reprezentuje całego poziomu początkującego.

Średniozaawansowany: typowany potok

Program wprowadza własne typy, config, pętlę, czas i trzy połączone zadania, ale pozostaje w jednym środowisku wykonania.

// Poziom średniozaawansowany: typowany przepływ w jednym środowisku.
struct Pomiar {
    czujnik: Text
    wartosc: Float
}

struct Alarm {
    czujnik: Text
    komunikat: Text
}

task OdbierzPomiary() @server -> chan<Pomiar> {
    every 5s {
        send Pomiar {
            czujnik: "symulator",
            wartosc: 21.5
        }
    }
}

task SprawdzProg(wejscie: chan<Pomiar>) @server -> chan<Alarm> {
    config {
        prog: Float : 30.0
    }

    loop {
        let pomiar = recv wejscie
        if pomiar.wartosc > config.prog {
            send Alarm {
                czujnik: pomiar.czujnik,
                komunikat: "Przekroczony próg"
            }
        }
    }
}

task ZapiszAlarmy(wejscie: chan<Alarm>) @server {
    for alarm in wejscie {
        log(alarm.komunikat)
    }
}

pipeline Monitoring {
    use OdbierzPomiary -> SprawdzProg
    use SprawdzProg -> ZapiszAlarmy
}

Pobierz plik średniozaawansowany.

Ekspert: system wielośrodowiskowy

Ten wariant rozdziela urządzenie, analizę serwerową i panel. Jawnie deklaruje profil urządzenia i funkcje extern, których implementacja należy do autora.

flowchart LR
    SENSOR["Czujnik<br/>@embedded"] -->|"chan&lt;PomiarTemperatury&gt;"| ANALYSIS["Analiza<br/>@server"]
    ANALYSIS -->|"stream&lt;StanTemperatury&gt;"| PANEL["Panel<br/>@report"]
    USER["Kod autora w user/"] -.-> SENSOR
    USER -.-> PANEL
// Poziom ekspercki: trzy środowiska i jawna granica kodu autora.
struct PomiarTemperatury {
    celsius: Float
    czas: Time
}

struct StanTemperatury {
    celsius: Float
    przekroczony_prog: Bool
}

extern sensor OdczytTemperatury {
    target embedded
    language cpp
    file "user/embedded/odczyt_temperatury.cpp"

    fn odczytaj(pin: u8) -> Float
}

extern task OdczytTemperatury_odczytaj(pin: u8) @embedded -> Float
extern task pokaz_temperature(stan: StanTemperatury) @report

device CzujnikKuchenny @embedded(esp32c3) {
    hardware {
        pin_danych: u8 : 4
    }
    timing {
        okres: Duration : 5s
    }
}

task Czujnik() @embedded(CzujnikKuchenny) -> chan<PomiarTemperatury> {
    config {
        pin_danych: u8 : 4
        okres: Duration : 5s
    }

    every config.okres {
        send PomiarTemperatury {
            celsius: OdczytTemperatury_odczytaj(config.pin_danych),
            czas: now()
        }
    }
}

task Analiza(wejscie: chan<PomiarTemperatury>) @server -> stream<StanTemperatury> {
    config {
        prog: Float : 30.0
    }

    loop {
        let pomiar = recv wejscie
        send StanTemperatury {
            celsius: pomiar.celsius,
            przekroczony_prog: pomiar.celsius > config.prog
        }
    }
}

task Panel(stany: stream<StanTemperatury>) @report {
    for stan in stany {
        pokaz_temperature(stan)
    }
}

pipeline SystemTemperatury {
    use Czujnik -> Analiza
    use Analiza -> Panel
}

Pobierz plik ekspercki.

Uruchomienie kontroli

Po zapisaniu wybranego pliku:

junexis check .\przyklad.jnx

Dla pełnego przykładu początkującego możesz od razu zbudować serwer:

junexis build .\beginner-system.jnx --target server

Przykład ekspercki wymaga implementacji funkcji extern, zanim wszystkie artefakty będą kompletne. Samo check potwierdza kontrakty języka, ale nie zastępuje natywnej kontroli artefaktów.

Zobacz ścieżki nauki i referencję języka.