refactor: move project to lib crate
This commit is contained in:
@@ -3,4 +3,12 @@ name = "glint"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
name = "glint"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "glint"
|
||||
path = "src/main.rs"
|
||||
|
||||
[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