asdf
This commit is contained in:
parent
2515141eeb
commit
b388d04bfa
5 changed files with 106 additions and 85 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -9,6 +9,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
|
@ -266,6 +272,7 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||||
name = "nomwut"
|
name = "nomwut"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lalrpop",
|
"lalrpop",
|
||||||
"lalrpop-util",
|
"lalrpop-util",
|
||||||
|
|
|
@ -12,6 +12,7 @@ build = "build.rs"
|
||||||
lalrpop-util = "0.19.5"
|
lalrpop-util = "0.19.5"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
|
anyhow = "1.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
lalrpop = "0.19.5"
|
lalrpop = "0.19.5"
|
||||||
|
|
80
src/config.rs
Normal file
80
src/config.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use anyhow::*;
|
||||||
|
|
||||||
|
type VarName = String;
|
||||||
|
type AttrValue = String;
|
||||||
|
type AttrName = String;
|
||||||
|
|
||||||
|
pub enum AstError {
|
||||||
|
UnexpectedNode,
|
||||||
|
InvalidDefinition,
|
||||||
|
WrongExprType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<WrongExprType> for AstError {
|
||||||
|
fn from(_: WrongExprType) -> Self {
|
||||||
|
AstError::WrongExprType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FromExpr: Sized {
|
||||||
|
fn from_expr(e: Expr) -> Result<Self, AstError>;
|
||||||
|
fn from_sp(e: Sp<Expr>) -> Result<Self, AstError> {
|
||||||
|
Self::from_expr(e.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum DefType {
|
||||||
|
Widget,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromExpr for DefType {
|
||||||
|
fn from_expr(e: Expr) -> Result<Self, AstError> {
|
||||||
|
if let Expr::Symbol(sym) = e {
|
||||||
|
match sym.as_str() {
|
||||||
|
"defwidget" => Ok(DefType::Widget),
|
||||||
|
_ => Err(AstError::InvalidDefinition),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(AstError::UnexpectedNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Definitional<T> {
|
||||||
|
def_type: DefType,
|
||||||
|
name: String,
|
||||||
|
attrs: HashMap<AttrName, Sp<Expr>>,
|
||||||
|
children: Vec<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: FromExpr> FromExpr for Definitional<T> {
|
||||||
|
fn from_expr(e: Expr) -> Result<Self, AstError> {
|
||||||
|
if let Expr::List(list) = e {
|
||||||
|
let mut iter = list.into_iter();
|
||||||
|
let def_type = DefType::from_sp(iter.next().unwrap())?;
|
||||||
|
let name = iter.next().unwrap().1.str()?;
|
||||||
|
let mut attrs = HashMap::new();
|
||||||
|
while let Some(Sp(_, Expr::Keyword(x), _)) = iter.next() {
|
||||||
|
attrs.insert(x, iter.next().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let children = iter.map(T::from_sp).collect::<Result<Vec<_>, AstError>>()?;
|
||||||
|
Ok(Definitional {
|
||||||
|
def_type,
|
||||||
|
name,
|
||||||
|
attrs,
|
||||||
|
children,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(AstError::UnexpectedNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WidgetDefinition {
|
||||||
|
name: String,
|
||||||
|
argnames: Vec<VarName>,
|
||||||
|
}
|
85
src/lexer.rs
85
src/lexer.rs
|
@ -1,85 +0,0 @@
|
||||||
use std::str::CharIndices;
|
|
||||||
|
|
||||||
pub type Spanned<Tok, Loc, Error> = Result<(Loc, Tok, Loc), Error>;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub enum Tok {
|
|
||||||
LPren,
|
|
||||||
RPren,
|
|
||||||
Space,
|
|
||||||
Int(i32),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub enum LexicalError {
|
|
||||||
InvalidDigit,
|
|
||||||
UnknownToken,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for LexicalError {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{:?}", self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Lexer<'input> {
|
|
||||||
chars: CharIndices<'input>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'input> Lexer<'input> {
|
|
||||||
pub fn new(input: &'input str) -> Self {
|
|
||||||
Lexer {
|
|
||||||
chars: input.char_indices(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'input> Iterator for Lexer<'input> {
|
|
||||||
type Item = Spanned<Tok, usize, LexicalError>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let c = self.chars.next();
|
|
||||||
match c {
|
|
||||||
Some((i, '(')) => Some(Ok((i, Tok::LPren, i + 1))),
|
|
||||||
Some((i, ')')) => Some(Ok((i, Tok::RPren, i + 1))),
|
|
||||||
Some((i, s)) if s.is_whitespace() => {
|
|
||||||
let mut last_space = i;
|
|
||||||
loop {
|
|
||||||
match self.chars.next() {
|
|
||||||
Some((i, next)) if next.is_whitespace() => {
|
|
||||||
last_space = i;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(Ok((i, Tok::Space, last_space + 1)))
|
|
||||||
}
|
|
||||||
Some((i, s)) if s.is_digit(10) || s == '-' => {
|
|
||||||
let mut end = i;
|
|
||||||
let mut digits = String::new();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
match self.chars.next() {
|
|
||||||
Some((i, next)) if next.is_digit(10) => {
|
|
||||||
end = i;
|
|
||||||
digits.push(next);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let num = match digits.parse::<i32>() {
|
|
||||||
Ok(num) => num,
|
|
||||||
Err(_err) => return Some(Err(LexicalError::InvalidDigit)),
|
|
||||||
};
|
|
||||||
Some(Ok((i, Tok::Int(num), end + 1)))
|
|
||||||
}
|
|
||||||
Some((_, _)) => Some(Err(LexicalError::UnknownToken)),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
18
src/main.rs
18
src/main.rs
|
@ -1,4 +1,9 @@
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
mod config;
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
@ -17,6 +22,9 @@ impl<T: std::fmt::Display> std::fmt::Display for Sp<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct WrongExprType;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
List(Vec<Sp<Expr>>),
|
List(Vec<Sp<Expr>>),
|
||||||
|
@ -28,6 +36,16 @@ pub enum Expr {
|
||||||
Comment,
|
Comment,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Expr {
|
||||||
|
fn str(self) -> Result<String, WrongExprType> {
|
||||||
|
use Expr::*;
|
||||||
|
match self {
|
||||||
|
Str(x) => Ok(x),
|
||||||
|
_ => Err(WrongExprType),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Expr {
|
impl std::fmt::Display for Expr {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
use Expr::*;
|
use Expr::*;
|
||||||
|
|
Loading…
Add table
Reference in a new issue