171 lines
3.8 KiB
Plaintext
171 lines
3.8 KiB
Plaintext
use crate::ast::*;
|
|
|
|
grammar();
|
|
|
|
|
|
// Skip over comments
|
|
match {
|
|
r"\s*" => { },
|
|
r"//[^\n\r]*[\n\r]*" => { },
|
|
_
|
|
}
|
|
|
|
pub Namespace: Namespace = {
|
|
"namespace" <name:Ident>
|
|
<interfaces:List<Interface>>
|
|
<types:List<TypeDef>>
|
|
<extensions:List<Extension>>
|
|
=> Namespace{<>}
|
|
}
|
|
|
|
Extension: Extension = {
|
|
"extension" <name:Ident> "{"
|
|
<version:Version?>
|
|
<interface:ImplicitInterface?>
|
|
<interfaces:List<ExtensionInterface>>
|
|
<types:List<TypeDef>>
|
|
"}"
|
|
=> Extension{name, version: version.unwrap_or_default(), interface, interfaces, types}
|
|
}
|
|
|
|
Interface: Interface = {
|
|
"interface" <name:Ident> "{"
|
|
<v:Version?>
|
|
<e:Events?>
|
|
<m:Methods?>
|
|
"}" => Interface { name, version: v.unwrap_or_default(), events: e.unwrap_or_default(), methods: m.unwrap_or_default() }
|
|
}
|
|
|
|
ExtensionInterface: ExtensionInterface = {
|
|
"interface" <name:Ident> "{"
|
|
<version:Version?>
|
|
<e:Events?>
|
|
<m:Methods?>
|
|
"}" => ExtensionInterface { name, version, events: e.unwrap_or_default(), methods: m.unwrap_or_default() }
|
|
}
|
|
|
|
ImplicitInterface: ImplicitInterface = {
|
|
"interface" "{"
|
|
<e:Events?>
|
|
<m:Methods?>
|
|
"}" => ImplicitInterface { events: e.unwrap_or_default(), methods: m.unwrap_or_default() }
|
|
}
|
|
|
|
Version: Version = {
|
|
"version" <Num> <Num> <Num> => (<>)
|
|
}
|
|
|
|
Events: Vec<Func> = { "events" "{" <List<Func>> "}" => <> }
|
|
Methods: Vec<Func> = { "methods" "{" <List<Func>> "}" => <> }
|
|
|
|
Func: Func = {
|
|
<name:Ident> "(" <args: Comma<Arg>> ")" <ret:("->" <Type>)?> => Func{<>}
|
|
}
|
|
|
|
|
|
Arg: Arg = {
|
|
<name:Ident> ":" <ty:Type> => Arg{<>}
|
|
}
|
|
|
|
|
|
// Argument types
|
|
|
|
Type: Type = {
|
|
PrimType => Type::Primitive(<>),
|
|
Ident => Type::Custom(<>),
|
|
IntType => Type::IntType(<>),
|
|
"[]" <Type> => Type::Array(Box::new(<>)),
|
|
}
|
|
|
|
PrimType: PrimType = {
|
|
"string" => PrimType::String,
|
|
"object" => PrimType::Object,
|
|
"uuid" => PrimType::Uuid,
|
|
"bytes" => PrimType::Bytes,
|
|
"bool" => PrimType::Bool,
|
|
|
|
"matrix4x4" => PrimType::Matrix4x4,
|
|
|
|
"f32" => PrimType::F32,
|
|
"f64" => PrimType::F64,
|
|
}
|
|
|
|
// These are seperate as only they can back an enum
|
|
IntType: IntType = {
|
|
"u8" => IntType::U8,
|
|
"u16" => IntType::U16,
|
|
"u32" => IntType::U32,
|
|
"u64" => IntType::U64,
|
|
"u128" => IntType::U128,
|
|
|
|
"vu8" => IntType::VU8,
|
|
"vu16" => IntType::VU16,
|
|
"vu32" => IntType::VU32,
|
|
"vu64" => IntType::VU64,
|
|
"vu128" => IntType::VU128,
|
|
|
|
"i8" => IntType::I8,
|
|
"i16" => IntType::I16,
|
|
"i32" => IntType::I32,
|
|
"i64" => IntType::I64,
|
|
"i128" => IntType::I128,
|
|
|
|
"vi8" => IntType::VI8,
|
|
"vi16" => IntType::VI16,
|
|
"vi32" => IntType::VI32,
|
|
"vi64" => IntType::VI64,
|
|
"vi128" => IntType::VI128,
|
|
}
|
|
|
|
// Typedefs
|
|
|
|
TypeDef: TypeDef = {
|
|
"struct" <name:Ident> <s:Struct> => TypeDef{name, kind: TypeKind::Struct(s)},
|
|
"enum" <name:Ident> "(" <backing:IntType> ")" <fields:Enum>
|
|
=> TypeDef{name, kind: TypeKind::Enum(Enum{fields, backing})},
|
|
// Enum => TypeDef::Enum(<>),
|
|
}
|
|
|
|
Struct: Struct = { "{" <fields:List<StructField>> "}" => Struct{<>} }
|
|
StructField: StructField = {
|
|
<name:Ident> ":" <ty:Type> => StructField{<>}
|
|
}
|
|
|
|
Enum: Vec<EnumField> = { "{" <List<EnumField>> "}" => <> }
|
|
EnumField: EnumField = {
|
|
<name:Ident> <value:("=" <Int>)?> => EnumField{<>}
|
|
}
|
|
|
|
|
|
|
|
// Terminals
|
|
|
|
// Num: u8 = {
|
|
// r"[0-9]+" => <>.parse().unwrap()
|
|
// }
|
|
Num: u8 = {
|
|
// TODO: This is a bit hacky, but it works for now
|
|
Int => <>.try_into().unwrap(),
|
|
}
|
|
Int: i64 = {
|
|
r"(-)?[0-9]+" => <>.parse().unwrap()
|
|
}
|
|
Ident: String = { r"[a-zA-Z][a-zA-Z0-9_]*" => <>.to_owned() }
|
|
|
|
|
|
// Combinators
|
|
|
|
List<T>: Vec<T> = {
|
|
<v:(<T>)*> => v
|
|
};
|
|
|
|
Comma<T>: Vec<T> = {
|
|
<v:(<T> ",")*> <e:T?> => match e {
|
|
None=> v,
|
|
Some(e) => {
|
|
let mut v = v;
|
|
v.push(e);
|
|
v
|
|
}
|
|
}
|
|
}; |