Lowering I

trunk
Alona EM 2022-01-16 02:12:35 +00:00
parent e4e044e733
commit 09952b5193
8 changed files with 2341 additions and 2080 deletions

View File

@ -89,119 +89,127 @@
0, 0,
0 0
], ],
"interface": { "interface": null,
"methods": [ "interfaces": [
{ {
"name": "fetchById", "name": "asset_delivery",
"args": [ "version": [
{ 0,
"name": "id", 0,
"ty": { 0
"Primitive": "Uuid" ],
} "methods": [
} {
], "name": "fetchById",
"ret": { "args": [
"Custom": "Asset" {
} "name": "id",
}, "ty": {
{
"name": "fetchByName",
"args": [
{
"name": "name",
"ty": {
"Primitive": "String"
}
}
],
"ret": {
"Custom": "Asset"
}
},
{
"name": "fetchByIds",
"args": [
{
"name": "ids",
"ty": {
"Array": {
"Primitive": "Uuid" "Primitive": "Uuid"
} }
} }
} ],
], "ret": {
"ret": {
"Array": {
"Custom": "Asset" "Custom": "Asset"
} }
} },
}, {
{ "name": "fetchByName",
"name": "fetchByNames", "args": [
"args": [ {
{ "name": "name",
"name": "names", "ty": {
"ty": {
"Array": {
"Primitive": "String" "Primitive": "String"
} }
} }
} ],
], "ret": {
"ret": {
"Array": {
"Custom": "Asset" "Custom": "Asset"
} }
} },
}, {
{ "name": "fetchByIds",
"name": "getId", "args": [
"args": [ {
{ "name": "ids",
"name": "name", "ty": {
"ty": { "Array": {
"Primitive": "String" "Primitive": "Uuid"
} }
}
],
"ret": {
"Primitive": "Uuid"
}
}
],
"events": [
{
"name": "load_assets",
"args": [
{
"name": "assets",
"ty": {
"Array": {
"Custom": "Asset"
} }
} }
} ],
], "ret": {
"ret": null "Array": {
}, "Custom": "Asset"
{
"name": "unload_assets",
"args": [
{
"name": "assets",
"ty": {
"Array": {
"Primitive": "Uuid"
}
} }
} }
], },
"ret": null {
} "name": "fetchByNames",
] "args": [
}, {
"interfaces": [], "name": "names",
"ty": {
"Array": {
"Primitive": "String"
}
}
}
],
"ret": {
"Array": {
"Custom": "Asset"
}
}
},
{
"name": "getId",
"args": [
{
"name": "name",
"ty": {
"Primitive": "String"
}
}
],
"ret": {
"Primitive": "Uuid"
}
}
],
"events": [
{
"name": "load_assets",
"args": [
{
"name": "assets",
"ty": {
"Array": {
"Custom": "Asset"
}
}
}
],
"ret": null
},
{
"name": "unload_assets",
"args": [
{
"name": "assets",
"ty": {
"Array": {
"Primitive": "Uuid"
}
}
}
],
"ret": null
}
]
}
],
"types": [ "types": [
{ {
"name": "Asset", "name": "Asset",
@ -241,57 +249,68 @@
0, 0,
0 0
], ],
"interface": { "interface": null,
"methods": [],
"events": [
{
"name": "add_entitys",
"args": [
{
"name": "entities",
"ty": {
"Array": {
"Custom": "EntityInfo"
}
}
}
],
"ret": null
},
{
"name": "update_entitys",
"args": [
{
"name": "entities",
"ty": {
"Array": {
"Custom": "EntityInfo"
}
}
}
],
"ret": null
},
{
"name": "remove_entitys",
"args": [
{
"name": "entities",
"ty": {
"Array": {
"Primitive": "Uuid"
}
}
}
],
"ret": null
}
]
},
"interfaces": [ "interfaces": [
{
"name": "world",
"version": [
0,
0,
0
],
"methods": [],
"events": [
{
"name": "add_entitys",
"args": [
{
"name": "entities",
"ty": {
"Array": {
"Custom": "EntityInfo"
}
}
}
],
"ret": null
},
{
"name": "update_entitys",
"args": [
{
"name": "entities",
"ty": {
"Array": {
"Custom": "EntityInfo"
}
}
}
],
"ret": null
},
{
"name": "remove_entitys",
"args": [
{
"name": "entities",
"ty": {
"Array": {
"Primitive": "Uuid"
}
}
}
],
"ret": null
}
]
},
{ {
"name": "Entity", "name": "Entity",
"version": null, "version": [
0,
0,
0
],
"methods": [ "methods": [
{ {
"name": "interact", "name": "interact",

View File

@ -13,7 +13,7 @@ pub struct Namespace {
pub struct Extension { pub struct Extension {
pub name: String, pub name: String,
pub version: Version, pub version: Version,
pub interface: ImplicitInterface, pub interface: Option<ImplicitInterface>,
pub interfaces: Vec<ExtensionInterface>, pub interfaces: Vec<ExtensionInterface>,
pub types: Vec<TypeDef>, pub types: Vec<TypeDef>,
} }

View File

@ -5,6 +5,7 @@ fn main() -> Result<()> {
let tree = fs::read_to_string("hypercosm.hidl")?; let tree = fs::read_to_string("hypercosm.hidl")?;
let tree = hidl::grammar::NamespaceParser::new().parse(&tree).unwrap(); let tree = hidl::grammar::NamespaceParser::new().parse(&tree).unwrap();
let tree = hidl::hir::lower_namespace(tree);
debug2::dbg!(&tree); debug2::dbg!(&tree);

View File

@ -1,10 +0,0 @@
use std::fs;
use hidl::IDL;
fn main() {
let file = fs::read_to_string("spec.yaml").unwrap();
let spec: IDL = serde_yaml::from_str(&file).unwrap();
debug2::dbg!(spec);
}

View File

@ -21,7 +21,7 @@ pub Namespace: Namespace = {
Extension: Extension = { Extension: Extension = {
"extension" <name:Ident> "{" "extension" <name:Ident> "{"
<version:Version?> <version:Version?>
<interface:ImplicitInterface> <interface:ImplicitInterface?>
<interfaces:List<ExtensionInterface>> <interfaces:List<ExtensionInterface>>
<types:List<TypeDef>> <types:List<TypeDef>>
"}" "}"

File diff suppressed because it is too large Load Diff

115
hidl/src/hir.rs Normal file
View File

@ -0,0 +1,115 @@
//! Hir has the same types as ast, but with the following invarients:
//!
//! - All enum variants have a number
//! - The implicit interface is None
//! - All interfaces have a version
use std::collections::BTreeSet;
use crate::ast::{
Enum, EnumField, Extension, ExtensionInterface, ImplicitInterface, Namespace, TypeDef,
TypeKind, Version,
};
pub fn lower_namespace(
Namespace {
name,
interfaces,
types,
extensions,
}: Namespace,
) -> Namespace {
Namespace {
name,
interfaces,
types: types.into_iter().map(lower_type_def).collect(),
extensions: extensions.into_iter().map(lower_extension).collect(),
}
}
fn lower_extension(
Extension {
name,
version,
interface,
interfaces,
types,
}: Extension,
) -> Extension {
let mut new_interfaces = interface
.into_iter()
.map(|l| lower_implicit_interface(l, &name, version))
.collect::<Vec<_>>();
new_interfaces.extend(
interfaces
.into_iter()
.map(|l| lower_extension_interface(l, version)),
);
Extension {
name,
version,
interface: None,
interfaces: new_interfaces,
types,
}
}
fn lower_implicit_interface(
i: ImplicitInterface,
name: &str,
version: Version,
) -> ExtensionInterface {
ExtensionInterface {
name: name.to_owned(),
version: Some(version),
methods: i.methods,
events: i.events,
}
}
fn lower_extension_interface(i: ExtensionInterface, version: Version) -> ExtensionInterface {
ExtensionInterface {
name: i.name,
version: Some(i.version.unwrap_or(version)),
methods: i.methods,
events: i.events,
}
}
fn lower_type_def(TypeDef { name, kind }: TypeDef) -> TypeDef {
TypeDef {
name,
kind: match kind {
TypeKind::Struct(_) => kind,
TypeKind::Enum(e) => TypeKind::Enum(lower_enum(e)),
},
}
}
fn lower_enum(Enum { backing, fields }: Enum) -> Enum {
let mut pos = 0;
let mut seen = BTreeSet::new();
let mut new_fields = Vec::with_capacity(fields.len());
for EnumField { name, value } in fields {
let value = value.unwrap_or(pos);
if seen.contains(&value) {
panic!("Enum {} has duplicate value {}", name, value);
}
seen.insert(value);
pos += 1;
new_fields.push(EnumField {
name,
value: Some(value),
});
}
Enum {
fields: new_fields,
backing,
}
}

View File

@ -1,160 +1,5 @@
use debug2::Debug as Debug2;
use serde::{Deserialize, Serialize};
pub mod ast; pub mod ast;
pub mod hir;
#[allow(clippy::all)] #[allow(clippy::all)]
pub mod grammar; pub mod grammar;
#[derive(Debug, Debug2, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct Module {
interfaces: Vec<Interface>,
types: Vec<CustomType>,
}
#[derive(Debug, Debug2, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct IDL {
name: String,
root: Module,
extenstions: Vec<Extension>,
}
#[derive(Debug, Debug2, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct Extension {
name: String,
version: Version,
module: Module,
}
type Version = (u8, u8, u8);
#[derive(Debug, Debug2, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct Interface {
name: String,
version: Version,
methods: Vec<Method>,
events: Vec<Method>,
}
#[derive(Debug, Debug2, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct Method {
name: String,
ret: Type,
args: Vec<(String, Type)>,
}
#[derive(Debug, Debug2, Clone, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum Type {
NotIntType(NotIntType),
IntType(IntType),
}
#[derive(Debug, Debug2, Clone, Serialize, Deserialize, PartialEq)]
pub enum NotIntType {
/// TODO: Should we special case Array of u8?
Array(Box<Type>),
Custom(String),
String,
Object,
Uuid,
/// Unit type
Void,
}
impl Default for Type {
fn default() -> Self {
Self::NotIntType(NotIntType::Void)
}
}
#[derive(Debug, Debug2, Clone, Serialize, Deserialize, PartialEq)]
pub enum IntType {
U8,
U16,
U32,
U64,
I8,
I16,
I32,
I64,
VU16,
VU8,
VU32,
VU64,
VI8,
VI16,
VI32,
VI64,
}
#[derive(Debug, Debug2, Clone, Serialize, Deserialize, PartialEq)]
pub struct CustomType {
name: String,
kind: CustomTypeKind,
}
#[derive(Debug, Debug2, Clone, Serialize, Deserialize, PartialEq)]
enum CustomTypeKind {
Struct(CustomStruct),
Enum(Enum),
}
#[derive(Debug, Debug2, Clone, Serialize, Deserialize, PartialEq)]
pub struct Enum {
storage: IntType,
values: Vec<(String, i64)>,
}
#[derive(Debug, Debug2, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct CustomStruct {
fields: Vec<(String, Type)>,
}
#[derive(Debug, Debug2, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct Event {}
fn is_default<T: Default + PartialEq>(t: &T) -> bool {
t == &T::default()
}
mod ty {
use super::IntType::*;
use super::NotIntType::*;
use super::Type::{self, *};
pub fn void() -> Type {
NotIntType(Void)
}
pub fn array(t: Type) -> Type {
NotIntType(Array(Box::new(t)))
}
pub fn string() -> Type {
NotIntType(String)
}
pub fn object() -> Type {
NotIntType(Object)
}
pub fn uuid() -> Type {
NotIntType(Uuid)
}
pub fn u8() -> Type {
IntType(U8)
}
}