refactor: move project to lib crate
This commit is contained in:
@@ -3,4 +3,12 @@ name = "glint"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "glint"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "glint"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
8
src/lib.rs
Normal file
8
src/lib.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
pub mod ast;
|
||||||
|
pub mod compiler;
|
||||||
|
pub mod opcodes;
|
||||||
|
pub mod parser;
|
||||||
|
|
||||||
|
pub use ast::{Directive, ModuleSoA, NodeId, Value};
|
||||||
|
pub use compiler::Compiler;
|
||||||
|
pub use parser::Parser;
|
||||||
302
src/main.rs
302
src/main.rs
@@ -1,302 +0,0 @@
|
|||||||
mod ast;
|
|
||||||
mod compiler;
|
|
||||||
mod opcodes;
|
|
||||||
mod parser;
|
|
||||||
|
|
||||||
use compiler::Compiler;
|
|
||||||
use parser::Parser;
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
const INPUT: &str = r#"
|
|
||||||
@version 1
|
|
||||||
@style "desktop.glts"
|
|
||||||
|
|
||||||
@global $username = !rhei: os.env("USER")
|
|
||||||
@global $hostname = !rhei: os.hostname()
|
|
||||||
@global $locale = "ru_RU"
|
|
||||||
@global $scaleFactor = 1.0
|
|
||||||
|
|
||||||
@singleton Config {
|
|
||||||
wallpaper = fs:/home/$username/.config/de/wallpaper.jpg
|
|
||||||
wallpaperFit = "cover"
|
|
||||||
iconTheme = "papirus-dark"
|
|
||||||
fontMain = "Inter"
|
|
||||||
fontMono = "JetBrains Mono"
|
|
||||||
fontSize = 13
|
|
||||||
workspaces = 4
|
|
||||||
animEnabled = true
|
|
||||||
accentColor = #cba6f7
|
|
||||||
taskbarPos = "bottom"
|
|
||||||
}
|
|
||||||
|
|
||||||
@singleton SystemState {
|
|
||||||
battery = !rhei: sys.battery()
|
|
||||||
volume = !rhei: sys.volume.get()
|
|
||||||
brightness = !rhei: sys.brightness.get()
|
|
||||||
network = !rhei: sys.network.status()
|
|
||||||
timezone = !rhei: os.timezone()
|
|
||||||
}
|
|
||||||
|
|
||||||
@component DesktopIcon(label: str, icon: fspath, exec: str) {
|
|
||||||
Button(class="desktop-icon") {
|
|
||||||
@on click {
|
|
||||||
!rhei: process.spawn($exec)
|
|
||||||
}
|
|
||||||
@on dblclick {
|
|
||||||
!rhei {
|
|
||||||
process.spawn($exec)
|
|
||||||
wm.raise(process.lastPid())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Image(src=$icon, class="icon-img") {}
|
|
||||||
Label(class="icon-label") $label
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@component BatteryWidget {
|
|
||||||
@if $SystemState.battery.present {
|
|
||||||
@let $lvl = $SystemState.battery.level
|
|
||||||
@let $ico = !rhei: icons.battery($lvl)
|
|
||||||
|
|
||||||
Panel(class="tray-item") {
|
|
||||||
Icon(src=$ico, class="tray-icon") {}
|
|
||||||
@if $SystemState.battery.charging {
|
|
||||||
Icon(src=fs:/usr/share/glint-de/icons/charging.svg,
|
|
||||||
class="tray-icon tray-icon--accent") {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@component ClockWidget {
|
|
||||||
@let $time = !rhei: sys.time.format("%H:%M", $SystemState.timezone)
|
|
||||||
@let $date = !rhei: sys.time.format("%d %b", $SystemState.timezone)
|
|
||||||
|
|
||||||
Panel(class="clock-widget") {
|
|
||||||
@on click {
|
|
||||||
!rhei: ui.toggle("calendar-popup")
|
|
||||||
}
|
|
||||||
Label(class="clock-time") $time
|
|
||||||
Label(class="clock-date") $date
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@component SystemTray {
|
|
||||||
Panel(id="system-tray", class="tray") {
|
|
||||||
BatteryWidget {}
|
|
||||||
|
|
||||||
@if $SystemState.network.connected {
|
|
||||||
Icon(class="tray-icon",
|
|
||||||
src=!rhei: icons.network($SystemState.network.type)) {}
|
|
||||||
} @else {
|
|
||||||
Icon(class="tray-icon tray-icon--warn",
|
|
||||||
src=fs:/usr/share/glint-de/icons/net-offline.svg) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Slider(id="vol-slider", class="tray-slider",
|
|
||||||
value=$SystemState.volume, min=0, max=100) {
|
|
||||||
@on change {
|
|
||||||
!rhei: sys.volume.set($self.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClockWidget {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Screen(id="root", width=1920, height=1080, scale=$scaleFactor) {
|
|
||||||
Wallpaper(id="bg",
|
|
||||||
src=$Config.wallpaper,
|
|
||||||
fallback=fs:/usr/share/glint-de/wallpapers/default.jpg,
|
|
||||||
fit=$Config.wallpaperFit,
|
|
||||||
watch=true) {}
|
|
||||||
|
|
||||||
Panel(id="desktop", class="desktop") {
|
|
||||||
@let $desktopFiles = !rhei: fs.glob("/home/$username/Desktop/*.desktop")
|
|
||||||
|
|
||||||
@each $f in $desktopFiles {
|
|
||||||
@let $entry = !rhei: xdg.parseDesktop($f)
|
|
||||||
DesktopIcon(
|
|
||||||
label=$entry.name,
|
|
||||||
icon=!rhei: icons.resolve($entry.icon, $Config.iconTheme),
|
|
||||||
exec=$entry.exec
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@on contextmenu {
|
|
||||||
!rhei: ui.show("desktop-ctx")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextMenu(id="desktop-ctx", class="ctx-menu", visible=false) {
|
|
||||||
MenuItem(class="ctx-item") {
|
|
||||||
@on click { !rhei: ui.show("settings") }
|
|
||||||
"Настройки рабочего стола"
|
|
||||||
}
|
|
||||||
MenuItem(class="ctx-item") {
|
|
||||||
@on click { !rhei: wallpaper.showPicker() }
|
|
||||||
"Сменить обои"
|
|
||||||
}
|
|
||||||
MenuDivider {}
|
|
||||||
MenuItem(class="ctx-item ctx-item--danger") {
|
|
||||||
@on click { !rhei: session.logout() }
|
|
||||||
"Выйти из сеанса"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Panel(id="taskbar", class="taskbar") {
|
|
||||||
Button(id="launcher-btn", class="launcher-button") {
|
|
||||||
@on click { !rhei: ui.toggle("app-launcher") }
|
|
||||||
Image(src=fs:/usr/share/glint-de/logo.svg) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Panel(id="window-list", class="window-list") {
|
|
||||||
@let $wins = !rhei: wm.getWindows()
|
|
||||||
|
|
||||||
@each $w in $wins {
|
|
||||||
Button(class="taskbar-win", data-wid=$w.id,
|
|
||||||
active=$w.focused) {
|
|
||||||
@on click { !rhei: wm.focus($w.id) }
|
|
||||||
@on middleclick { !rhei: wm.close($w.id) }
|
|
||||||
Icon(src=$w.icon, class="win-icon") {}
|
|
||||||
Label(class="win-title") $w.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SystemTray {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Overlay(id="app-launcher", class="launcher", visible=false) {
|
|
||||||
@on keydown(key="Escape") {
|
|
||||||
!rhei: ui.hide("app-launcher")
|
|
||||||
}
|
|
||||||
|
|
||||||
Input(id="launcher-search", class="launcher-search",
|
|
||||||
placeholder="Поиск приложений...",
|
|
||||||
autofocus=true) {
|
|
||||||
@on input {
|
|
||||||
!rhei: launcher.filter($self.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Grid(id="app-grid", class="launcher-grid", columns=6) {
|
|
||||||
@let $apps = !rhei: apps.listAll()
|
|
||||||
|
|
||||||
@each $app in $apps {
|
|
||||||
Button(class="launcher-app") {
|
|
||||||
@on click {
|
|
||||||
!rhei {
|
|
||||||
process.spawn($app.exec)
|
|
||||||
ui.hide("app-launcher")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Image(src=$app.icon, class="app-icon") {}
|
|
||||||
Label(class="app-name") $app.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Overlay(id="notif-layer", class="notif-layer") {
|
|
||||||
@let $notifs = !rhei: notifications.active()
|
|
||||||
|
|
||||||
@each $n in $notifs {
|
|
||||||
Panel(class="notif-card", data-id=$n.id) {
|
|
||||||
Panel(class="notif-header") {
|
|
||||||
Icon(src=$n.appIcon, class="notif-icon") {}
|
|
||||||
Label(class="notif-app") $n.appName
|
|
||||||
Button(class="notif-close") {
|
|
||||||
@on click { !rhei: notifications.dismiss($n.id) }
|
|
||||||
"×"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Label(class="notif-title") $n.summary
|
|
||||||
@if $n.body {
|
|
||||||
Label(class="notif-body") $n.body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@if !rhei: os.env("GLINT_DEV") {
|
|
||||||
!rhei {
|
|
||||||
debug.overlay.show()
|
|
||||||
debug.log("DE инициализирован. Пользователь: " + $username)
|
|
||||||
debug.log("Синглтоны: Config, SystemState")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut parser = Parser::new(INPUT);
|
|
||||||
match parser.parse_all() {
|
|
||||||
Ok(_) => {
|
|
||||||
println!("Parse is successful");
|
|
||||||
|
|
||||||
let m = &parser.module;
|
|
||||||
|
|
||||||
let mut child_indices = HashSet::new();
|
|
||||||
for (start, len) in &m.elem_child_spans {
|
|
||||||
for i in *start..(*start + *len) {
|
|
||||||
child_indices.insert(i as usize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for dir in &m.directives {
|
|
||||||
let span = match dir {
|
|
||||||
ast::Directive::Component { child_span, .. } => Some(child_span),
|
|
||||||
ast::Directive::If {
|
|
||||||
child_span,
|
|
||||||
else_span,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
if let Some(es) = else_span {
|
|
||||||
for i in es.0..(es.0 + es.1) {
|
|
||||||
child_indices.insert(i as usize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(child_span)
|
|
||||||
}
|
|
||||||
ast::Directive::Each { child_span, .. } => Some(child_span),
|
|
||||||
ast::Directive::On { child_span, .. } => Some(child_span),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
if let Some((start, len)) = span {
|
|
||||||
for i in *start..(*start + *len) {
|
|
||||||
child_indices.insert(i as usize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut root_nodes = Vec::new();
|
|
||||||
for (i, node) in m.hierarchy.iter().enumerate() {
|
|
||||||
if !child_indices.contains(&i) {
|
|
||||||
root_nodes.push(node.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Compile...");
|
|
||||||
let compiler = Compiler::new(m);
|
|
||||||
let bytecode = compiler.compile(&root_nodes);
|
|
||||||
|
|
||||||
let output_path = "desktop.glbc";
|
|
||||||
let mut file = File::create(output_path).expect("Не удалось создать файл");
|
|
||||||
file.write_all(&bytecode)
|
|
||||||
.expect("Не удалось записать байткод");
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Compile is successful. Compiled in {} ({} bytes)",
|
|
||||||
output_path,
|
|
||||||
bytecode.len()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("❌ Error of parse: {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
Reference in New Issue
Block a user