mirror of
https://github.com/ParkerTenBroeck/automata.git
synced 2026-06-06 21:24:06 -04:00
reorganized project
This commit is contained in:
parent
34b20ec1fe
commit
c57a95b7b5
29 changed files with 34 additions and 43 deletions
16
web_lib/Cargo.toml
Normal file
16
web_lib/Cargo.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "automata-web"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
automata = {path="../automata", features = ["serde"]}
|
||||
console_error_panic_hook = "0.1.7"
|
||||
wasm-bindgen = "*"
|
||||
web-sys = { version = "0.3.83", features = ["Window", "Document", "HtmlElement", "Text"] }
|
||||
212
web_lib/src/lib.rs
Normal file
212
web_lib/src/lib.rs
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use automata::loader::{self, Context, Span, Spanned, lexer::Lexer};
|
||||
|
||||
use serde::Serialize;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
panic!()
|
||||
}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main() {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn init() {
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Kind {
|
||||
Ident = "ident",
|
||||
Keyword = "keyword",
|
||||
Error = "error",
|
||||
Comment = "comment",
|
||||
Punc = "punc",
|
||||
|
||||
LPar = "lpar",
|
||||
LBrace = "lbrace",
|
||||
LBracket = "lbracket",
|
||||
|
||||
RPar = "rpar",
|
||||
RBrace = "rbrace",
|
||||
RBracket = "rbracket",
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Tok {
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
pub scope_level: usize,
|
||||
pub kind: Kind,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn lex(input: &str) -> Vec<Tok> {
|
||||
let mut scope_level = 0;
|
||||
let mut index_utf16 = 0;
|
||||
let mut index_utf8 = 0;
|
||||
Lexer::new(input)
|
||||
.map(|Spanned(tok, Span(start_utf8, end_utf8))| {
|
||||
let since_last = &input[index_utf8..start_utf8];
|
||||
let since_start = &input[start_utf8..end_utf8];
|
||||
|
||||
index_utf8 = end_utf8;
|
||||
let start = index_utf16 + since_last.chars().map(char::len_utf16).sum::<usize>();
|
||||
let end = start + since_start.chars().map(char::len_utf16).sum::<usize>();
|
||||
index_utf16 = end;
|
||||
|
||||
let Ok(tok) = tok else {
|
||||
return Tok {
|
||||
start,
|
||||
end,
|
||||
kind: Kind::Error,
|
||||
scope_level,
|
||||
};
|
||||
};
|
||||
use automata::loader::lexer::Token;
|
||||
let kind = match tok {
|
||||
Token::LPar => Kind::LPar,
|
||||
Token::RPar => Kind::RPar,
|
||||
Token::LBrace => Kind::LBrace,
|
||||
Token::RBrace => Kind::RBrace,
|
||||
Token::LBracket => Kind::LBracket,
|
||||
Token::RBracket => Kind::RBracket,
|
||||
Token::Tilde => Kind::Keyword,
|
||||
Token::Eq => Kind::Punc,
|
||||
Token::Comma => Kind::Punc,
|
||||
Token::Or => Kind::Punc,
|
||||
Token::Plus => Kind::Punc,
|
||||
Token::Star => Kind::Punc,
|
||||
Token::And => Kind::Punc,
|
||||
Token::LSmallArrow => Kind::Punc,
|
||||
Token::LBigArrow => Kind::Punc,
|
||||
Token::Comment(_) => Kind::Comment,
|
||||
Token::Ident(_)
|
||||
if input[..start_utf8]
|
||||
.split("\n")
|
||||
.last()
|
||||
.unwrap_or_default()
|
||||
.trim()
|
||||
.is_empty() =>
|
||||
{
|
||||
Kind::Keyword
|
||||
}
|
||||
Token::Ident(
|
||||
loader::EPSILON_LOWER
|
||||
| "epsilon"
|
||||
| loader::DELTA_LOWER
|
||||
| "delta"
|
||||
| loader::GAMMA_UPPER
|
||||
| "gamma"
|
||||
| loader::GAMMA_LOWER
|
||||
| loader::SIGMA_UPPER
|
||||
| "sigma",
|
||||
) => Kind::Keyword,
|
||||
Token::Ident(_) => Kind::Ident,
|
||||
Token::LineEnd => Kind::Punc,
|
||||
};
|
||||
|
||||
let scope_level = match kind {
|
||||
Kind::LPar | Kind::LBrace | Kind::LBracket => {
|
||||
scope_level = scope_level.saturating_add(1);
|
||||
scope_level.saturating_sub(1)
|
||||
}
|
||||
Kind::RPar | Kind::RBrace | Kind::RBracket => {
|
||||
scope_level = scope_level.saturating_sub(1);
|
||||
scope_level
|
||||
}
|
||||
_ => scope_level,
|
||||
};
|
||||
Tok {
|
||||
start,
|
||||
end,
|
||||
kind,
|
||||
scope_level,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum LogLevel {
|
||||
Info = "info",
|
||||
Warning = "warning",
|
||||
Error = "error",
|
||||
}
|
||||
|
||||
#[wasm_bindgen(getter_with_clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct CompileLog {
|
||||
pub level: LogLevel,
|
||||
pub message: String,
|
||||
pub start: Option<usize>,
|
||||
pub end: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct Graph<'a> {
|
||||
initial: &'a str,
|
||||
final_states: Vec<&'a str>,
|
||||
states: Vec<&'a str>,
|
||||
transitions: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen(getter_with_clone)]
|
||||
pub struct CompileResult {
|
||||
pub log: Vec<CompileLog>,
|
||||
pub log_formatted: String,
|
||||
pub graph: Option<String>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn compile(input: &str) -> CompileResult {
|
||||
let mut ctx = Context::new(input);
|
||||
let result = automata::loader::parse_universal(&mut ctx);
|
||||
|
||||
let graph = if let Some(result) = result {
|
||||
Some(match result {
|
||||
loader::Machine::Fa(fa) => serde_json::to_string(&fa).unwrap(),
|
||||
loader::Machine::Pda(pda) => serde_json::to_string(&pda).unwrap(),
|
||||
loader::Machine::Tm(tm) => serde_json::to_string(&tm).unwrap(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
use std::fmt::Write;
|
||||
let log_formatted = ctx.logs_display().fold(String::new(), |mut s, e| {
|
||||
write!(&mut s, "{e}").unwrap();
|
||||
s
|
||||
});
|
||||
|
||||
let log = ctx
|
||||
.into_logs()
|
||||
.into_entries()
|
||||
.map(|e| CompileLog {
|
||||
level: match e.level {
|
||||
loader::log::LogLevel::Info => LogLevel::Info,
|
||||
loader::log::LogLevel::Warning => LogLevel::Warning,
|
||||
loader::log::LogLevel::Error => LogLevel::Error,
|
||||
},
|
||||
message: e.message,
|
||||
start: e
|
||||
.span
|
||||
.map(|span| input[..span.0].chars().map(char::len_utf16).count()),
|
||||
end: e
|
||||
.span
|
||||
.map(|span| input[..span.1].chars().map(char::len_utf16).count()),
|
||||
})
|
||||
.collect();
|
||||
|
||||
CompileResult {
|
||||
log,
|
||||
log_formatted,
|
||||
graph,
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue