use std::{collections::HashMap, convert::TryInto, fmt, io};
use lexpr::datum::{self, ListIter};
use crate::{data, Ident, R};
pub type Expr = crate::Expr<R<Ident>>;
pub type TypeExpr = crate::TypeExpr<Ident, crate::Expr<R<Ident>>>;
pub type Field = crate::Field<TypeExpr>;
pub type NodeApp = crate::NodeApp<Ident, crate::Expr<R<Ident>>>;
#[derive(Debug, Clone)]
struct Env(Vec<(Ident, Expr)>);
impl Env {
fn new() -> Self {
let predefined = ["le", "be", "ne"]
.iter()
.map(|&name| {
(
name.parse().unwrap(),
Expr::Const(lexpr::Value::symbol(name)),
)
})
.collect();
Env(predefined)
}
fn from_params<P>(parameters: P) -> Self
where
P: IntoIterator<Item = Ident>,
{
let mut env = Env::new();
env.extend(
parameters
.into_iter()
.enumerate()
.map(|(i, ident)| (ident, Expr::Ref(R::Param(i)))),
);
env
}
fn lookup(&self, name: &str) -> Option<&Expr> {
self.0.iter().find_map(|(ident, arg)| {
if ident.as_str() == name {
Some(arg)
} else {
None
}
})
}
fn push(&mut self, name: Ident, expr: Expr) {
self.0.push((name, expr))
}
fn extend(&mut self, iter: impl IntoIterator<Item = (Ident, Expr)>) {
self.0.extend(iter)
}
}
#[derive(Debug)]
pub struct Error(InnerError);
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use InnerError::*;
match &self.0 {
Parse(e) => write!(f, "invalid s-expression: {}", e),
PrematureEol(expected) => write!(f, "premature end of list, expected {}", expected),
ImproperList(rest) => write!(
f,
"expected end of list at, found improper list terminated by '{}' at {}",
rest.value(),
display_span(rest.span())
),
Expected(expected, found) => write!(
f,
"expected {}, found '{}' at {}",
expected,
found.value(),
display_span(found.span())
),
InvalidFieldModifier(modifier) => write!(
f,
"invalid field modifier '{}' at {}",
modifier.value(),
display_span(modifier.span())
),
DuplicateFieldModifier(modifier) => write!(
f,
"duplicate field modifier '{}' at {}",
modifier.value(),
display_span(modifier.span())
),
DuplicateProperty(name) => write!(
f,
"duplicate property '{}' at {}",
name.value(),
display_span(name.span())
),
UnknownDef(name) => write!(
f,
"unknown definition '{}' at {}",
name.value(),
display_span(name.span())
),
}
}
}
impl std::error::Error for Error {}
#[derive(Debug)]
struct DisplaySpan(datum::Span);
fn display_span(span: datum::Span) -> DisplaySpan {
DisplaySpan(span)
}
impl fmt::Display for DisplaySpan {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let start = self.0.start();
let end = self.0.start();
write!(
f,
"{}:{}--{}:{}",
start.line(),
start.column(),
end.line(),
end.column()
)
}
}
#[derive(Debug)]
enum InnerError {
Parse(lexpr::parse::Error),
PrematureEol(&'static str),
Expected(&'static str, lexpr::Datum),
ImproperList(lexpr::Datum),
DuplicateFieldModifier(lexpr::Datum),
InvalidFieldModifier(lexpr::Datum),
DuplicateProperty(lexpr::Datum),
UnknownDef(lexpr::Datum),
}
#[derive(Debug, Clone)]
pub enum Def {
Root(data::Root),
Branch(data::Branch),
Enum(data::Enum),
}
pub struct Parser<T>
where
T: io::Read,
{
inner: lexpr::Parser<lexpr::parse::IoRead<T>>,
}
impl<T> Parser<T>
where
T: io::Read,
{
pub fn new(inner: T) -> Self {
Parser {
inner: lexpr::Parser::from_reader(inner),
}
}
pub fn parse_def(&mut self) -> Result<Option<Def>, Error> {
let datum = match self.inner.next_datum().map_err(parse_error)? {
Some(value) => value,
None => return Ok(None),
};
if let Some(mut items) = datum.list_iter() {
let keyword = take_datum(&mut items)?;
let def = match keyword
.value()
.as_symbol()
.ok_or_else(|| expected_error("definition keyword", keyword))?
{
"root" => parse_root_def(items).map(Def::Root)?,
"branch" => parse_branch_def(items).map(Def::Branch)?,
"enum" => parse_enum_def(items).map(Def::Enum)?,
_ => return Err(unknown_def(keyword)),
};
Ok(Some(def))
} else {
Err(expected_error("list", datum))
}
}
}
fn parse_root_def(mut items: ListIter<'_>) -> Result<data::Root, Error> {
let (name, parameters) = take_type_spec(&mut items)?;
let env = Env::from_params(parameters);
let mut fields = None;
for item in items.by_ref() {
if let Some(mut inner) = item.list_iter() {
let tag = take_datum(&mut inner)?;
match tag
.as_symbol()
.ok_or_else(|| expected_error("root clause", tag))?
{
"fields" => {
if fields.is_some() {
return Err(duplicate_property(tag));
}
fields = Some(expect_field_list(inner, &env)?);
}
_ => return Err(unknown_property(tag)),
}
} else {
return Err(expected_error("field entry", item));
}
}
expect_eol(&mut items)?;
Ok(data::Root {
name,
description: None,
fields: fields.unwrap_or_default(),
})
}
fn parse_enum_def(items: ListIter<'_>) -> Result<data::Enum, Error> {
let mut items = items;
let (name, parameters) = take_type_spec(&mut items)?;
let env = Env::from_params(parameters);
let mut variants = None;
let mut discriminants = None;
for item in items.by_ref() {
if let Some(mut inner) = item.list_iter() {
let tag = take_datum(&mut inner)?;
match tag
.as_symbol()
.ok_or_else(|| expected_error("enum clause keyword", tag))?
{
"variants" => {
if variants.is_some() {
return Err(duplicate_property(tag));
}
variants = Some(expect_variant_list(
inner,
discriminants
.as_ref()
.map(|v: &Vec<data::Field>| &v[..])
.unwrap_or_default(),
&env,
)?);
}
"discriminants" => {
if discriminants.is_some() {
return Err(duplicate_property(tag));
}
let mut fields = expect_field_list(inner, &env)?;
for field in &mut fields {
field.hidden = true;
}
discriminants = Some(fields);
}
_ => return Err(unknown_property(tag)),
}
} else {
return Err(expected_error("enum clause", item));
}
}
expect_eol(&mut items)?;
Ok(data::Enum {
name,
description: None,
discriminants: discriminants.unwrap_or_default(),
variants: variants.unwrap_or_default(),
})
}
fn expect_field(field: datum::Ref<'_>, env: &Env) -> Result<data::Field, Error> {
use lexpr::Value::*;
let (name, mut rest) = expect_tagged_list(field)?;
let ty = take_type_expr(&mut rest, env)?;
let mut hidden = None;
let mut constant = None;
for modifier in rest.by_ref() {
if let Some(mut items) = modifier.list_iter() {
let head = take_datum(&mut items)?;
match head
.as_symbol()
.ok_or_else(|| expected_error("field modifier keyword", head))?
{
"=" => {
if constant.is_some() {
return Err(duplicate_field_modifier(head));
}
let datum = take_datum(&mut items)?;
expect_eol(&mut items)?;
constant = Some(datum.into());
}
_ => return Err(invalid_field_modifier(modifier)),
}
} else {
match modifier.value() {
Symbol(name) => match name.as_ref() {
"hidden" => {
if hidden.is_some() {
return Err(duplicate_field_modifier(modifier));
}
hidden = Some(true);
}
_ => return Err(invalid_field_modifier(modifier)),
},
_ => return Err(invalid_field_modifier(modifier)),
}
}
}
expect_eol(&mut rest)?;
Ok(data::Field {
name: name.parse().expect("ident parsing cannot fail ATM"),
ty,
constant,
hidden: hidden.unwrap_or(false),
})
}
fn expect_variant_list(
mut items: ListIter<'_>,
discriminants: &[data::Field],
env: &Env,
) -> Result<Vec<data::Variant>, Error> {
let variants = items
.by_ref()
.map(|item| expect_variant(item, discriminants, env))
.collect::<Result<_, _>>()?;
expect_eol(&mut items)?;
Ok(variants)
}
fn expect_list_2(datum: datum::Ref<'_>) -> Result<(datum::Ref<'_>, datum::Ref<'_>), Error> {
if let Some(mut items) = datum.list_iter() {
let first = take_datum(&mut items)?;
let second = take_datum(&mut items)?;
expect_eol(&mut items)?;
Ok((first, second))
} else {
Err(expected_error("two-element list", datum))
}
}
fn take_let_bindings(form: &mut ListIter<'_>, env: &Env) -> Result<Env, Error> {
let bindings = take_datum(form)?;
let items = bindings
.list_iter()
.ok_or_else(|| expected_error("let bindings", bindings))?;
let mut let_env = env.clone();
for item in items {
let (name, expr) = expect_list_2(item)?;
let_env.push(expect_ident(name)?.clone(), expect_expr(expr, env)?);
}
Ok(let_env)
}
fn expect_field_expr(expr: datum::Ref<'_>, env: &Env) -> Result<Vec<data::Field>, Error> {
if let Some(mut items) = expr.list_iter() {
match items.peek() {
Some(head) if head.as_symbol() == Some("let") => {
items.next().unwrap();
let let_env = take_let_bindings(&mut items, env)?;
let mut fields = Vec::new();
for item in items.by_ref() {
fields.extend(expect_field_expr(item, &let_env)?);
}
expect_eol(&mut items)?;
Ok(fields)
}
_ => Ok(vec![expect_field(expr, env)?]),
}
} else {
Ok(vec![expect_field(expr, env)?])
}
}
fn expect_field_list(mut items: ListIter<'_>, env: &Env) -> Result<Vec<data::Field>, Error> {
let mut fields = Vec::new();
for item in items.by_ref() {
fields.extend(expect_field_expr(item, env)?);
}
expect_eol(&mut items)?;
Ok(fields)
}
fn parse_expr_op<F>(f: F, mut items: ListIter<'_>, env: &Env) -> Result<Expr, Error>
where
F: FnOnce(Vec<Expr>) -> Expr,
{
let args = items
.by_ref()
.map(|arg| expect_expr(arg, env))
.collect::<Result<_, _>>()?;
Ok(f(args))
}
fn parse_type_property(mut items: ListIter<'_>, env: &Env) -> Result<Expr, Error> {
let field_name = take_r(&mut items, env)?;
let value = take_datum(&mut items)?;
let (head, inner) = expect_list_2(value)?;
let propery_name = match (head.as_symbol(), inner.as_symbol()) {
(Some("quote"), Some(name)) => name,
_ => return Err(expected_error("quoted symbol", value)),
};
Ok(Expr::TypeProperty(field_name, propery_name.to_owned()))
}
fn expect_variant(
datum: datum::Ref<'_>,
discriminants: &[data::Field],
env: &Env,
) -> Result<data::Variant, Error> {
let (name, mut items) = expect_tagged_list(datum)?;
let condition = take_condition(&mut items, discriminants, env)?;
let mut fields = None;
let mut properties = None;
let env = Env::new();
for item in items.by_ref() {
if let Some(mut inner) = item.list_iter() {
let tag = take_datum(&mut inner)?;
match tag
.as_symbol()
.ok_or_else(|| expected_error("enum clause keyword", tag))?
{
"fields" => {
if fields.is_some() {
return Err(duplicate_property(tag));
}
fields = Some(expect_field_list(inner, &env)?);
}
"properties" => {
if properties.is_some() {
return Err(duplicate_property(tag));
}
properties = Some(parse_property_list(inner)?);
}
_ => return Err(unknown_property(tag)),
}
}
}
expect_eol(&mut items)?;
Ok(data::Variant {
name: name.parse().expect("identifiers cannot fail to parse ATM"),
condition,
fields: fields.unwrap_or_default(),
properties: properties.unwrap_or_default(),
})
}
fn parse_branch_def(items: ListIter<'_>) -> Result<data::Branch, Error> {
let mut items = items;
let path = take_datum(&mut items)?;
let (root, path, name) = expect_path(path)?
.split_branch()
.map_err(|_| expected_error("branch path", path))?;
let mut fields = None;
let mut condition = None;
let mut properties = None;
let mut implies = None;
let env = Env::new();
for item in items.by_ref() {
if let Some(mut inner) = item.list_iter() {
let tag = take_datum(&mut inner)?;
match tag
.as_symbol()
.ok_or_else(|| expected_error("enum clause keyword", tag))?
{
"fields" => {
if fields.is_some() {
return Err(duplicate_property(tag));
}
fields = Some(expect_field_list(inner, &env)?);
}
"condition" => {
if condition.is_some() {
return Err(duplicate_property(tag));
}
condition = Some(parse_expr_list(inner, &env)?);
}
"properties" => {
if properties.is_some() {
return Err(duplicate_property(tag));
}
properties = Some(parse_property_list(inner)?);
}
"implies" => {
if implies.is_some() {
return Err(duplicate_property(tag));
}
implies = Some(parse_implications(inner, &env)?);
}
_ => return Err(unknown_property(tag)),
}
} else {
return Err(expected_error("branch clause", item));
}
}
expect_eol(&mut items)?;
Ok(data::Branch {
root,
path,
name,
description: None,
implies: implies.unwrap_or_default(),
condition: condition.unwrap_or_else(|| data::Expr::constant(true)),
fields: fields.unwrap_or_default(),
properties: properties.unwrap_or_default(),
})
}
fn take_condition(
iter: &mut ListIter<'_>,
discriminants: &[data::Field],
env: &Env,
) -> Result<data::Expr, Error> {
let datum = iter.next().ok_or_else(|| premature_eol("value"))?;
use lexpr::Value::*;
match datum.value() {
c @ Number(_) => {
let field_name = match discriminants.len() {
0 => unimplemented!(),
1 => &discriminants[0].name,
_ => unimplemented!(),
};
Ok(Expr::equal(
R::Field(field_name.clone()),
Expr::constant(c.clone()),
))
}
_ => Ok(expect_expr(datum, env)?),
}
}
fn parse_expr_list(mut items: ListIter<'_>, env: &Env) -> Result<data::Expr, Error> {
let clauses = items
.by_ref()
.map(|item| expect_expr(item, env))
.collect::<Result<_, _>>()?;
expect_eol(&mut items)?;
Ok(data::Expr::And(clauses).simplified())
}
fn parse_property_list(items: ListIter<'_>) -> Result<HashMap<String, lexpr::Value>, Error> {
let properties = items.map(expect_property).collect::<Result<_, _>>()?;
Ok(properties)
}
fn parse_expr_unop<F>(f: F, mut items: ListIter<'_>, env: &Env) -> Result<data::Expr, Error>
where
F: FnOnce(Expr) -> Expr,
{
let e = take_expr(&mut items, env)?;
expect_eol(&mut items)?;
Ok(f(e))
}
fn parse_expr_binop<F>(f: F, mut items: ListIter<'_>, env: &Env) -> Result<data::Expr, Error>
where
F: FnOnce(Expr, Expr) -> Expr,
{
let e1 = take_expr(&mut items, env)?;
let e2 = take_expr(&mut items, env)?;
expect_eol(&mut items)?;
Ok(f(e1, e2))
}
fn parse_implications(mut items: ListIter<'_>, env: &Env) -> Result<Vec<NodeApp>, Error> {
let implications = items
.by_ref()
.map(|item| expect_node_app(item, env))
.collect::<Result<_, _>>()?;
expect_eol(&mut items)?;
Ok(implications)
}
fn parse_error(e: lexpr::parse::Error) -> Error {
Error(InnerError::Parse(e))
}
fn premature_eol(expected: &'static str) -> Error {
Error(InnerError::PrematureEol(expected))
}
fn unknown_def(name: datum::Ref<'_>) -> Error {
Error(InnerError::UnknownDef(name.into()))
}
fn unknown_property(property: datum::Ref<'_>) -> Error {
expected_error("property name", property)
}
fn improper_list(rest: datum::Ref<'_>) -> Error {
Error(InnerError::ImproperList(rest.into()))
}
fn duplicate_property(name: datum::Ref<'_>) -> Error {
Error(InnerError::DuplicateProperty(name.into()))
}
fn duplicate_field_modifier(name: datum::Ref<'_>) -> Error {
Error(InnerError::DuplicateFieldModifier(name.into()))
}
fn invalid_field_modifier(modifier: datum::Ref<'_>) -> Error {
Error(InnerError::InvalidFieldModifier(modifier.into()))
}
fn invalid_type_name(datum: datum::Ref<'_>) -> Error {
expected_error("type name", datum)
}
fn expected_error(expected: &'static str, found: impl Into<lexpr::Datum>) -> Error {
Error(InnerError::Expected(expected, found.into()))
}
fn expect_expr(datum: datum::Ref<'_>, env: &Env) -> Result<Expr, Error> {
if let Some(mut items) = datum.list_iter() {
let ident = take_datum(&mut items)?;
match ident
.as_symbol()
.ok_or_else(|| expected_error("expression operator", ident))?
{
"=" => parse_expr_binop(Expr::equal, items, env),
"and" => parse_expr_op(Expr::And, items, env),
"or" => parse_expr_op(Expr::Or, items, env),
"not" => Ok(Expr::Not(Box::new(take_expr(&mut items, env)?))),
"+" => parse_expr_binop(Expr::add, items, env),
"-" => parse_expr_binop(Expr::sub, items, env),
"*" => parse_expr_binop(Expr::mul, items, env),
"bitwise-not" => parse_expr_unop(Expr::bitwise_not, items, env),
"bitwise-and" => parse_expr_binop(Expr::bitwise_and, items, env),
"bitwise-or" => parse_expr_binop(Expr::bitwise_or, items, env),
"bitwise-shift-left" => parse_expr_binop(Expr::bitwise_shift_left, items, env),
"bitwise-shift-right" => parse_expr_binop(Expr::bitwise_shift_right, items, env),
"type-property" => parse_type_property(items, env),
_ => Err(expected_error("expression operator", ident)),
}
} else {
use lexpr::Value::*;
let expr = match datum.value() {
b @ Bool(_) => Expr::Const(b.clone()),
n @ Number(_) => Expr::Const(n.clone()),
Symbol(name) => match env.lookup(name) {
Some(e) => e.clone(),
None => Expr::Ref(R::Field(expect_ident(datum)?)),
},
_ => unimplemented!("expression syntax {:?}", datum),
};
Ok(expr)
}
}
fn expect_property(datum: datum::Ref<'_>) -> Result<(String, lexpr::Value), Error> {
let mut items = datum
.list_iter()
.ok_or_else(|| expected_error("property definition", datum))?;
let name = take_symbol(&mut items)?;
let datum = take_datum(&mut items)?;
expect_eol(&mut items)?;
Ok((name.to_owned(), datum.value().clone()))
}
fn expect_tagged_list(datum: datum::Ref<'_>) -> Result<(&str, ListIter<'_>), Error> {
let mut items = datum
.list_iter()
.ok_or_else(|| expected_error("tagged list", datum))?;
let tag = take_symbol(&mut items)?;
Ok((tag, items))
}
fn take_datum<'a>(iter: &mut ListIter<'a>) -> Result<datum::Ref<'a>, Error> {
iter.next().ok_or_else(|| premature_eol("datum"))
}
fn take_symbol<'a>(iter: &mut ListIter<'a>) -> Result<&'a str, Error> {
let datum = iter.next().ok_or_else(|| premature_eol("symbol"))?;
datum
.value()
.as_symbol()
.ok_or_else(|| expected_error("symbol", datum))
}
fn expect_ident(datum: datum::Ref<'_>) -> Result<Ident, Error> {
let name = datum
.value()
.as_symbol()
.ok_or_else(|| expected_error("identifier", datum))?;
Ok(name.parse().expect("identifiers cannot fail to parse ATM"))
}
fn take_ident(iter: &mut ListIter<'_>) -> Result<Ident, Error> {
let symbol = take_symbol(iter)?;
Ok(symbol
.parse()
.expect("identifiers cannot fail to parse ATM"))
}
fn take_r(iter: &mut ListIter<'_>, env: &Env) -> Result<R<Ident>, Error> {
let datum = take_datum(iter)?;
expect_r(datum, env)
}
fn expect_r(datum: datum::Ref<'_>, env: &Env) -> Result<R<Ident>, Error> {
let ident = expect_ident(datum)?;
match env.lookup(ident.as_str()) {
Some(Expr::Ref(r)) => Ok(r.clone()),
Some(_) => Err(expected_error("identifier", datum)),
None => Ok(R::Field(ident)),
}
}
fn take_type_spec(iter: &mut ListIter<'_>) -> Result<(Ident, Vec<Ident>), Error> {
use lexpr::Value::*;
let datum = take_datum(iter)?;
if let Some(mut items) = datum.list_iter() {
let name = take_ident(&mut items)?;
let params = items.by_ref().map(expect_ident).collect::<Result<_, _>>()?;
expect_eol(&mut items)?;
Ok((name, params))
} else {
match datum.value() {
Symbol(name) => Ok((
name.parse().expect("identifiers cannot fail to parse ATM"),
Vec::new(),
)),
_ => Err(expected_error("type name", datum)),
}
}
}
fn expect_path(datum: datum::Ref<'_>) -> Result<data::Path, Error> {
use lexpr::Value::*;
match datum.value() {
Symbol(name) => Ok(name.parse().expect("paths cannot fail to parse ATM")),
_ => Err(expected_error("path", datum)),
}
}
fn take_expr(iter: &mut ListIter<'_>, env: &Env) -> Result<Expr, Error> {
expect_expr(take_datum(iter)?, env)
}
fn parse_int_type_args(iter: &mut ListIter<'_>, env: &Env) -> Result<(Expr, Expr), Error> {
let width = take_expr(iter, env)?;
let endianness = if iter.peek().is_none() {
Expr::Const(lexpr::Value::symbol("be"))
} else {
take_expr(iter, env)?
};
expect_eol(iter)?;
Ok((width, endianness))
}
fn parse_exprs(iter: &mut ListIter<'_>, env: &Env) -> Result<Vec<Expr>, Error> {
let mut args = Vec::new();
while iter.peek().is_some() {
args.push(take_expr(iter, env)?);
}
expect_eol(iter)?;
Ok(args)
}
fn expect_eol(iter: &mut ListIter<'_>) -> Result<(), Error> {
match iter.next() {
None => {
if iter.is_empty() {
Ok(())
} else {
let rest = iter.next().unwrap();
Err(improper_list(rest))
}
}
Some(item) => Err(expected_error("end of list", item)),
}
}
fn parse_array_list(mut items: ListIter<'_>, env: &Env) -> Result<TypeExpr, Error> {
use lexpr::Value;
let arg = items
.next()
.ok_or_else(|| premature_eol("array type arguments"))?;
match arg.value() {
Value::Number(n) => {
let n = n
.as_u64()
.ok_or_else(|| expected_error("array size", arg))?
.try_into()
.map_err(|_| expected_error("array size", arg))?;
let et = take_type_expr(&mut items, env)?;
expect_eol(&mut items)?;
Ok(TypeExpr::ArrayN(Expr::Const(n), Box::new(et)))
}
_ => {
if items.is_empty() {
let et = expect_type_expr(arg, env)?;
return Ok(TypeExpr::ArrayV(Box::new(et)));
}
let n_expr = expect_expr(arg, env)?;
let et = take_type_expr(&mut items, env)?;
expect_eol(&mut items)?;
Ok(TypeExpr::ArrayN(n_expr, Box::new(et)))
}
}
}
fn take_type_expr(iter: &mut ListIter<'_>, env: &Env) -> Result<TypeExpr, Error> {
let datum = take_datum(iter)?;
expect_type_expr(datum, env)
}
fn expect_node_app(datum: datum::Ref<'_>, env: &Env) -> Result<NodeApp, Error> {
if let Some(mut items) = datum.list_iter() {
let ident = take_ident(&mut items)?;
let args = parse_exprs(&mut items, env)?;
Ok(NodeApp { id: ident, args })
} else {
let ident = expect_ident(datum)?;
Ok(NodeApp {
id: ident,
args: Vec::new(),
})
}
}
fn expect_type_expr(datum: datum::Ref<'_>, env: &Env) -> Result<TypeExpr, Error> {
use lexpr::Value::*;
if let Some(mut items) = datum.list_iter() {
let name_datum = take_datum(&mut items)?;
let name = name_datum
.as_symbol()
.ok_or_else(|| expected_error("type name", name_datum))?;
match name {
"i" => {
let (width, endianness) = parse_int_type_args(&mut items, env)?;
Ok(TypeExpr::I(width, endianness))
}
"u" => {
let (width, endianness) = parse_int_type_args(&mut items, env)?;
Ok(TypeExpr::U(width, endianness))
}
"array" => Ok(parse_array_list(items, env)?),
_ => {
let args = parse_exprs(&mut items, env)?;
Ok(TypeExpr::app(
name.parse().expect("identifiers are always parsable ATM"),
args,
))
}
}
} else {
match datum.value() {
Symbol(name) => {
if name.is_empty() {
return Err(invalid_type_name(datum));
}
match name.as_bytes()[0] {
b'i' => {
let n: u32 = name[1..].parse().map_err(|_| invalid_type_name(datum))?;
Ok(TypeExpr::I(
Expr::Const(n.into()),
Expr::Const(lexpr::Value::symbol("be")),
))
}
b'u' => {
let n: u32 = name[1..].parse().map_err(|_| invalid_type_name(datum))?;
Ok(TypeExpr::U(
Expr::Const(n.into()),
Expr::Const(lexpr::Value::symbol("be")),
))
}
_ => {
Ok(TypeExpr::ident(
name.parse().expect("identifiers are always parsable ATM"),
))
}
}
}
_ => Err(expected_error("type specification", datum)),
}
}
}