This commit is contained in:
Able 2022-04-09 17:26:20 -05:00
parent d2e32d1570
commit 9b99dff857
10 changed files with 332 additions and 0 deletions

16
axel/Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "axel"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
versioning = {git = "https://git.ablecorp.us/able/versioning"}
hashbrown = "0.12.0"
log = "0.4.14"
[dependencies.logos]
version = "0.12.0"
default-features = false
features = ["export_derive"]

80
axel/src/lib.rs Normal file
View file

@ -0,0 +1,80 @@
#![no_std]
#![deny(unsafe_code, missing_docs)]
//! A simple format for apis
use {
hashbrown::HashMap,
logos::Logos,
node::{lexer::Token, tree::AxelNode},
};
pub(crate) use alloc::{
string::{String, ToString},
vec::Vec,
};
pub use node::signature::FunctionSignature;
pub extern crate alloc;
pub mod node;
/// Parse a string into a vector of nodes
pub fn parse(string: String) -> Vec<AxelNode> {
let lex = Token::lexer(&string);
let mut node_list: Vec<AxelNode> = Vec::new();
let mut node = AxelNode {
name: String::new(),
vals: HashMap::new(),
functs: Vec::new(),
};
let mut last_type_key = false;
let mut key = String::new();
for token in lex {
use Token::*;
match token {
Key(data) => {
key = data;
last_type_key = true;
}
NodeName(name) => {
node.name = name;
}
Version(version) if last_type_key => {
use node::tree::Values::*;
node.vals.insert(key.clone(), Version(version));
}
True => {
use node::tree::Values::*;
node.vals.insert(key.clone(), Boolean(true));
}
False => {
use node::tree::Values::*;
node.vals.insert(key.clone(), Boolean(false));
}
NodeClose => {
node_list.push(node);
node = AxelNode {
name: String::new(),
vals: HashMap::new(),
functs: Vec::new(),
};
}
Number(number) => {
if last_type_key {
use node::tree::Values::*;
node.vals.insert(key.clone(), Number(number));
}
}
FunctionSignature(signature) => {
node.functs.push((key.clone(), signature));
}
_ => {}
}
}
node_list
}

9
axel/src/main.rs Normal file
View file

@ -0,0 +1,9 @@
use axel::parse;
pub fn main() {
let p = parse(include_str!("mouse.axel").to_string());
for node in p {
println!("{:?}", node);
}
}

11
axel/src/mouse.axel Normal file
View file

@ -0,0 +1,11 @@
mouse{
val=
x: 1000
y: 200
buttons: true
fn|
sub: (Num,Num)->(Num);
floatify: (Num,Num)->(Float);
able: (None)->(None);
foo: (None)->(Num);
}

92
axel/src/node/lexer.rs Normal file
View file

@ -0,0 +1,92 @@
//!
use crate::*;
use super::signature::{signature_handle, FunctionSignature};
use alloc::string::ToString;
use logos::{Lexer, Logos};
use versioning::Version;
#[derive(Logos, Debug, PartialEq)]
///
pub enum Token {
#[regex("[(][a-zA-Z,]+[)]->[(][a-zA-Z,]+[)]", signature_handle)]
///
FunctionSignature(FunctionSignature),
#[token("true")]
/// True
True,
#[token("false")]
/// False
False,
#[regex("[a-zA-Z]+=")]
///
Values,
#[regex("[a-zA-Z]+|")]
///
Functions,
#[regex("[a-zA-Z]+[:]", node_handler)]
///
Key(String),
#[regex("[a-zA-Z]+[{]", node_handler)]
///
NodeName(String),
#[regex("[a-zA-Z]+[(]", node_handler)]
///
FunctionName(String),
#[regex("[0-9].[0-9].[0-9]", version_parse)]
///
Version(Version),
#[regex("-?[0-9]+", num_handler)]
///
Number(i32),
#[token("}")]
///
NodeClose,
#[error]
#[regex(r"[ \t\n\f]+", logos::skip)]
///
Error,
}
fn node_handler(lex: &mut Lexer<Token>) -> Option<String> {
let slice = lex.slice();
let mut node = slice.to_string();
node.pop();
Some(node)
}
fn version_parse(lex: &mut Lexer<Token>) -> Option<Version> {
let slice = lex.slice();
let mut version = Version {
major: 0,
minor: 0,
patch: 0,
};
let mut parts = slice.split('.');
version.major = parts.next().unwrap().parse().unwrap();
version.minor = parts.next().unwrap().parse().unwrap();
version.patch = parts.next().unwrap().parse().unwrap();
Some(version)
}
fn num_handler(lex: &mut Lexer<Token>) -> Option<i32> {
let slice = lex.slice();
let mut num = slice.to_string();
num.pop();
Some(num.parse().unwrap())
}

5
axel/src/node/mod.rs Normal file
View file

@ -0,0 +1,5 @@
//!
pub mod lexer;
pub mod signature;
pub mod tree;

View file

@ -0,0 +1,52 @@
//!
use crate::*;
use logos::Lexer;
/// A function signature of an axel node
pub type FunctionSignature = (Vec<Values>, Vec<Values>);
use super::{lexer::Token, tree::Values};
/// Construct a signature handler
pub fn signature_handle(lex: &mut Lexer<Token>) -> Option<FunctionSignature> {
let slice = lex.slice();
let string_sig = slice.to_string();
let mut str_pli = string_sig.split("->");
let intype = str_pli.next().unwrap().to_string();
let outtype = str_pli.next().unwrap().to_string();
let ins = typeify(intype);
let outs = typeify(outtype);
Some((ins, outs))
}
/// Turn a string into a vector of values
pub fn typeify(mut types: String) -> Vec<Values> {
let mut ret = Vec::new();
types.remove(0);
types.pop();
for t in types.split(',') {
match t {
"Num" => {
ret.push(Values::Number(0));
}
"Float" => {
ret.push(Values::Float(0.0));
}
"String" => {
ret.push(Values::String("".to_string()));
}
"None" => {
ret.push(Values::Empty);
}
"Bool" => {
ret.push(Values::Boolean(false));
}
_ => {}
}
}
ret
}

43
axel/src/node/tree.rs Normal file
View file

@ -0,0 +1,43 @@
//!
use crate::*;
#[derive(Debug, PartialEq)]
///
pub enum Values {
/// No value
Empty,
///
Version(versioning::Version),
///
Number(i32),
///
Float(f32),
///
String(String),
///
Boolean(bool),
}
#[derive(Debug)]
///
pub struct AxelNode {
///
pub name: String,
///
pub vals: HashMap<String, Values>,
///
pub functs: Vec<(String, FunctionSignature)>,
}
impl AxelNode {
/// Generate an empty axel node
pub fn new(name: String) -> Self {
AxelNode {
name,
vals: HashMap::new(),
functs: Vec::new(),
}
}
}

11
versioning/Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "versioning"
version = "0.1.2"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dependencies.serde]
version = "1.0"
features = ["derive"]

13
versioning/src/lib.rs Normal file
View file

@ -0,0 +1,13 @@
// ! A unified versioning system for Rust.
#![no_std]
use core::prelude::rust_2021::derive;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Version {
pub major: u8,
pub minor: u8,
pub patch: u8,
}