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
],
"interface": {
"methods": [
{
"name": "fetchById",
"args": [
{
"name": "id",
"ty": {
"Primitive": "Uuid"
}
}
],
"ret": {
"Custom": "Asset"
}
},
{
"name": "fetchByName",
"args": [
{
"name": "name",
"ty": {
"Primitive": "String"
}
}
],
"ret": {
"Custom": "Asset"
}
},
{
"name": "fetchByIds",
"args": [
{
"name": "ids",
"ty": {
"Array": {
"interface": null,
"interfaces": [
{
"name": "asset_delivery",
"version": [
0,
0,
0
],
"methods": [
{
"name": "fetchById",
"args": [
{
"name": "id",
"ty": {
"Primitive": "Uuid"
}
}
}
],
"ret": {
"Array": {
],
"ret": {
"Custom": "Asset"
}
}
},
{
"name": "fetchByNames",
"args": [
{
"name": "names",
"ty": {
"Array": {
},
{
"name": "fetchByName",
"args": [
{
"name": "name",
"ty": {
"Primitive": "String"
}
}
}
],
"ret": {
"Array": {
],
"ret": {
"Custom": "Asset"
}
}
},
{
"name": "getId",
"args": [
{
"name": "name",
"ty": {
"Primitive": "String"
}
}
],
"ret": {
"Primitive": "Uuid"
}
}
],
"events": [
{
"name": "load_assets",
"args": [
{
"name": "assets",
"ty": {
"Array": {
"Custom": "Asset"
},
{
"name": "fetchByIds",
"args": [
{
"name": "ids",
"ty": {
"Array": {
"Primitive": "Uuid"
}
}
}
}
],
"ret": null
},
{
"name": "unload_assets",
"args": [
{
"name": "assets",
"ty": {
"Array": {
"Primitive": "Uuid"
}
],
"ret": {
"Array": {
"Custom": "Asset"
}
}
],
"ret": null
}
]
},
"interfaces": [],
},
{
"name": "fetchByNames",
"args": [
{
"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": [
{
"name": "Asset",
@ -241,57 +249,68 @@
0,
0
],
"interface": {
"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
}
]
},
"interface": null,
"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",
"version": null,
"version": [
0,
0,
0
],
"methods": [
{
"name": "interact",

View File

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

View File

@ -5,6 +5,7 @@ fn main() -> Result<()> {
let tree = fs::read_to_string("hypercosm.hidl")?;
let tree = hidl::grammar::NamespaceParser::new().parse(&tree).unwrap();
let tree = hidl::hir::lower_namespace(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" <name:Ident> "{"
<version:Version?>
<interface:ImplicitInterface>
<interface:ImplicitInterface?>
<interfaces:List<ExtensionInterface>>
<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 hir;
#[allow(clippy::all)]
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)
}
}