mirror of
https://github.com/Kindelia/Kind2.git
synced 2024-08-16 10:40:42 +03:00
feat(kind-fmt): improve specialize structure
This commit is contained in:
parent
d46739a9a5
commit
2cfea13c6e
15
crates/kind-fmt/src/expr.rs
Normal file
15
crates/kind-fmt/src/expr.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use kind_syntax::concrete::Expr;
|
||||||
|
use crate::{Result, FmtContext};
|
||||||
|
|
||||||
|
impl<'a> FmtContext<'a> {
|
||||||
|
pub fn expr(&mut self) -> Result<Expr> {
|
||||||
|
match self.kind() {
|
||||||
|
"call" => {
|
||||||
|
let callee = self.property("callee").unwrap();
|
||||||
|
|
||||||
|
self.cursor(callee).primary()
|
||||||
|
},
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,33 @@
|
|||||||
use std::path::PathBuf;
|
use thin_vec::ThinVec;
|
||||||
|
use tree_sitter::{Node, Parser, Tree, TreeCursor};
|
||||||
|
|
||||||
use thin_vec::{thin_vec, ThinVec};
|
use kind_syntax::concrete::Module;
|
||||||
use tree_sitter::{Parser, Tree, TreeCursor};
|
use kind_syntax::lexemes::Token;
|
||||||
|
|
||||||
use kind_syntax::concrete::{Block, ConstructorExpr, Expr, ExprKind, LocalExpr, Module, Pat, PatKind, Rule, Signature, Stmt, TopLevel, TopLevelKind};
|
mod expr;
|
||||||
use kind_syntax::lexemes::{Brace, Colon, Equal, Ident, Item, Name, Span, Token, Tokenized};
|
mod name;
|
||||||
|
mod parameter;
|
||||||
|
mod pattern;
|
||||||
|
mod primary;
|
||||||
|
mod statements;
|
||||||
|
mod top_level;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum FmtError {
|
pub enum FmtError {
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
|
Utf8Error(std::str::Utf8Error),
|
||||||
TreeSitterLanguageError(tree_sitter::LanguageError),
|
TreeSitterLanguageError(tree_sitter::LanguageError),
|
||||||
TreeSitterQueryError(tree_sitter::QueryError),
|
TreeSitterQueryError(tree_sitter::QueryError),
|
||||||
UnknownParseError,
|
UnknownParseError,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct FmtContext<'a> {
|
||||||
|
pub file: &'a str,
|
||||||
|
pub tree: &'a Tree,
|
||||||
|
pub cursor: *mut TreeCursor<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, FmtError>;
|
pub type Result<T> = std::result::Result<T, FmtError>;
|
||||||
|
|
||||||
pub fn run_fmt(string: String) -> Result<Module> {
|
pub fn run_fmt(string: String) -> Result<Module> {
|
||||||
@ -21,7 +35,7 @@ pub fn run_fmt(string: String) -> Result<Module> {
|
|||||||
parser
|
parser
|
||||||
.set_language(tree_sitter_kind::language())
|
.set_language(tree_sitter_kind::language())
|
||||||
.map_err(FmtError::TreeSitterLanguageError)?;
|
.map_err(FmtError::TreeSitterLanguageError)?;
|
||||||
let tree = parser
|
let mut tree = parser
|
||||||
.parse(string.as_bytes(), None)
|
.parse(string.as_bytes(), None)
|
||||||
.ok_or(FmtError::UnknownParseError)?;
|
.ok_or(FmtError::UnknownParseError)?;
|
||||||
|
|
||||||
@ -29,10 +43,16 @@ pub fn run_fmt(string: String) -> Result<Module> {
|
|||||||
|
|
||||||
let mut cursor = tree.root_node().walk();
|
let mut cursor = tree.root_node().walk();
|
||||||
|
|
||||||
let declarations = tree.root_node().children(&mut cursor)
|
let context = FmtContext {
|
||||||
.map(|node| {
|
file: &string,
|
||||||
specialize_top_level(&string, &tree, &mut node.walk())
|
tree: &tree,
|
||||||
})
|
cursor: &mut cursor,
|
||||||
|
};
|
||||||
|
|
||||||
|
let declarations = tree
|
||||||
|
.root_node()
|
||||||
|
.children(&mut cursor)
|
||||||
|
.map(|node| context.cursor(node).top_level())
|
||||||
.collect::<Result<ThinVec<_>>>()?;
|
.collect::<Result<ThinVec<_>>>()?;
|
||||||
|
|
||||||
Ok(Module {
|
Ok(Module {
|
||||||
@ -42,132 +62,91 @@ pub fn run_fmt(string: String) -> Result<Module> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn specialize_top_level(file: &String, tree: &Tree, cursor: &mut TreeCursor) -> Result<TopLevel> {
|
impl<'a> FmtContext<'a> {
|
||||||
let node = cursor.node();
|
pub fn node(&self) -> Node<'a> {
|
||||||
match node.kind() {
|
unsafe { (*self.cursor).node() }
|
||||||
"val_declaration" => {
|
}
|
||||||
let name = node.child_by_field_name("name").unwrap();
|
|
||||||
let return_type = node.child_by_field_name("return_type");
|
|
||||||
let value = node.child_by_field_name("value");
|
|
||||||
|
|
||||||
Ok(TopLevel {
|
pub fn get_current_cursor(&self) -> TreeCursor<'a> {
|
||||||
data: Item::new(
|
unsafe { (*self.cursor).clone() }
|
||||||
Span::default(),
|
}
|
||||||
TopLevelKind::Signature(Signature {
|
|
||||||
name: specialize_name(file, tree, &mut name.walk())?,
|
pub fn kind(&self) -> &'static str {
|
||||||
arguments: thin_vec![],
|
self.node().kind()
|
||||||
return_type: return_type.map_or(Ok(None), |node| {
|
}
|
||||||
let expr = specialize_expr(file, tree, &mut node.walk())?;
|
|
||||||
Ok(Some(Colon(Token::default(), expr)))
|
pub fn first(&self) -> Option<Node<'a>> {
|
||||||
})?,
|
self.node().child(0)
|
||||||
value: value.map_or(Ok(None), |node| {
|
}
|
||||||
let block = specialize_statements(file, tree, &mut node.walk())?;
|
|
||||||
Ok(Some(block))
|
pub fn at(&self, at: usize) -> Option<Node<'a>> {
|
||||||
})?,
|
self.node().child(at)
|
||||||
}),
|
}
|
||||||
),
|
|
||||||
attributes: thin_vec![],
|
pub fn named_at(&self, at: usize) -> Option<Node<'a>> {
|
||||||
|
self.node().named_child(at)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn property(&self, name: &str) -> Option<Node<'a>> {
|
||||||
|
self.node().child_by_field_name(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn properties(&self, name: &'static str) -> impl Iterator<Item = Node<'a>> {
|
||||||
|
unsafe {
|
||||||
|
self.node().children_by_field_name(name, self.cursor.as_mut().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find<F, T>(&self, name: &str, mut f: F) -> Result<Option<T>>
|
||||||
|
where
|
||||||
|
F: FnMut(Node) -> Result<T>,
|
||||||
|
{
|
||||||
|
self
|
||||||
|
.node()
|
||||||
|
.child_by_field_name(name)
|
||||||
|
.map_or(Ok(None), |node| {
|
||||||
|
let value = f(node)?;
|
||||||
|
Ok(Some(value))
|
||||||
})
|
})
|
||||||
}
|
|
||||||
_ => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn specialize_pattern(file: &String, tree: &Tree, cursor: &mut TreeCursor) -> Result<Pat> {
|
pub fn named_children(&self) -> impl Iterator<Item = Node<'a>> + '_ {
|
||||||
let node = cursor.node();
|
unsafe {
|
||||||
match node.kind() {
|
self.node().named_children(self.cursor.as_mut().unwrap())
|
||||||
"identifier" => {
|
|
||||||
specialize_name(file, tree, cursor)
|
|
||||||
.map(|name| Pat::new(
|
|
||||||
Span::default(),
|
|
||||||
PatKind::Name(name),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
"constructor_identifier" => {
|
|
||||||
specialize_name(file, tree, cursor)
|
|
||||||
.map(|name| Pat::new(
|
|
||||||
Span::default(),
|
|
||||||
PatKind::Name(name),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
kind => todo!("{}", kind),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn specialize_expr(file: &String, tree: &Tree, cursor: &mut TreeCursor) -> Result<Expr> {
|
pub fn children(&self) -> impl Iterator<Item = Node<'a>> + '_ {
|
||||||
let node = cursor.node();
|
let mut cursor = self.get_current_cursor();
|
||||||
match node.kind() {
|
|
||||||
"call" => {
|
|
||||||
let callee = node
|
|
||||||
.child_by_field_name("callee")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
specialize_primary(file, tree, &mut callee.walk())
|
cursor.reset(self.node());
|
||||||
},
|
cursor.goto_first_child();
|
||||||
kind => todo!("{}", kind),
|
(0..self.node().child_count()).map(move |_| {
|
||||||
|
let result = cursor.node();
|
||||||
|
cursor.goto_next_sibling();
|
||||||
|
result
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn specialize_name(file: &String, _tree: &Tree, cursor: &mut TreeCursor) -> Result<Name> {
|
pub fn text(&self) -> Result<&'a str> {
|
||||||
let node = cursor.node();
|
self.node()
|
||||||
match node.kind() {
|
.utf8_text(self.file.as_bytes())
|
||||||
"identifier" => {
|
.map_err(FmtError::Utf8Error)
|
||||||
let name = node.utf8_text(file.as_bytes()).unwrap().to_string();
|
|
||||||
|
|
||||||
Ok(Name::Ident(Ident(Item::new(
|
|
||||||
Span::default(),
|
|
||||||
Tokenized(Token::default(), name),
|
|
||||||
))))
|
|
||||||
}
|
|
||||||
kind => todo!("{}", kind),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn specialize_statements(file: &String, tree: &Tree, cursor: &mut TreeCursor) -> Result<Block> {
|
pub fn text_of(&self, node: Node<'_>) -> Result<&'a str> {
|
||||||
let node = cursor.node();
|
node.utf8_text(self.file.as_bytes())
|
||||||
match node.kind() {
|
.map_err(FmtError::Utf8Error)
|
||||||
"statements" => {
|
|
||||||
let statements = node.named_children(cursor)
|
|
||||||
.map(|node| {
|
|
||||||
specialize_expr(file, tree, &mut node.walk())
|
|
||||||
})
|
|
||||||
.collect::<Result<ThinVec<_>>>()?;
|
|
||||||
|
|
||||||
Ok(Brace(
|
|
||||||
Token::default(),
|
|
||||||
statements.iter().map(|expr| Stmt {
|
|
||||||
value: expr.clone(),
|
|
||||||
semi: None,
|
|
||||||
}).collect(),
|
|
||||||
Token::default(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
kind => todo!("{}", kind),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn specialize_primary(file: &String, tree: &Tree, cursor: &mut TreeCursor) -> Result<Expr> {
|
pub fn cursor<'b>(&'b self, node: Node<'b>) -> FmtContext<'b> {
|
||||||
let node = cursor.node();
|
// fix this leak
|
||||||
match node.kind() {
|
let cursor = Box::leak(Box::new(node.walk()));
|
||||||
"constructor_identifier" => {
|
FmtContext {
|
||||||
specialize_name(file, tree, cursor)
|
file: self.file,
|
||||||
.map(|name| Expr::new(
|
tree: self.tree,
|
||||||
Span::default(),
|
cursor,
|
||||||
ExprKind::Constructor(Box::new(ConstructorExpr {
|
|
||||||
name,
|
|
||||||
})),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
"identifier" => {
|
|
||||||
specialize_name(file, tree, cursor)
|
|
||||||
.map(|name| Expr::new(
|
|
||||||
Span::default(),
|
|
||||||
ExprKind::Local(Box::new(LocalExpr {
|
|
||||||
name,
|
|
||||||
})),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
_ => todo!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +156,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_works() {
|
fn it_works() {
|
||||||
let expr = run_fmt("bao:pao{a}".into()).unwrap();
|
let expr = run_fmt("Ata (name: U60) : Type { Something }".into()).unwrap();
|
||||||
println!("{:#?}", expr);
|
println!("{:#?}", expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
crates/kind-fmt/src/name.rs
Normal file
26
crates/kind-fmt/src/name.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use kind_syntax::lexemes::{Ident, Item, Name, QualifiedIdent, Span, Token, Tokenized};
|
||||||
|
use crate::{Result, FmtContext};
|
||||||
|
|
||||||
|
impl<'a> FmtContext<'a> {
|
||||||
|
pub fn name(&mut self) -> Result<Name> {
|
||||||
|
match self.kind() {
|
||||||
|
"identifier" => {
|
||||||
|
let name = self.text()?.to_string();
|
||||||
|
|
||||||
|
Ok(Name::Ident(Ident(Item::new(
|
||||||
|
Span::default(),
|
||||||
|
Tokenized(Token::default(), name),
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
"constructor_identifier" => {
|
||||||
|
let name = self.text()?.to_string();
|
||||||
|
|
||||||
|
Ok(Name::QualifiedIdent(QualifiedIdent(Item::new(
|
||||||
|
Span::default(),
|
||||||
|
Tokenized(Token::default(), name),
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
crates/kind-fmt/src/parameter.rs
Normal file
48
crates/kind-fmt/src/parameter.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use kind_syntax::concrete::{ParameterBinding, SignatureParameter, TypeBinding};
|
||||||
|
use kind_syntax::lexemes::{AngleBracket, Colon, Paren, Token};
|
||||||
|
|
||||||
|
use crate::{FmtContext, Result};
|
||||||
|
|
||||||
|
impl<'a> FmtContext<'a> {
|
||||||
|
pub fn parameter(&mut self) -> Result<SignatureParameter> {
|
||||||
|
match self.kind() {
|
||||||
|
"parameter" => {
|
||||||
|
let modifier = self.find("modifier", |node| self.text_of(node))?;
|
||||||
|
let signature = match modifier {
|
||||||
|
Some(x) if x == "+" => SignatureParameter::Include,
|
||||||
|
Some(x) if x == "-" => SignatureParameter::Exclude,
|
||||||
|
Some(x) if x == "-+" => SignatureParameter::Both,
|
||||||
|
Some(x) if x == "+-" => SignatureParameter::Both,
|
||||||
|
_ => SignatureParameter::Include,
|
||||||
|
};
|
||||||
|
|
||||||
|
let parameter = self.cursor(self.first().unwrap());
|
||||||
|
|
||||||
|
let name = parameter
|
||||||
|
.find("name", |node| parameter.cursor(node).name())?
|
||||||
|
.unwrap();
|
||||||
|
let binding_type = parameter.clone().find("type", |node| {
|
||||||
|
let expr = parameter.cursor(node).expr()?;
|
||||||
|
Ok(Colon(Token::default(), Box::new(expr)))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
match parameter.kind() {
|
||||||
|
"explicit_parameter" => Ok(signature(ParameterBinding::Explicit(Paren(
|
||||||
|
Token::default(),
|
||||||
|
TypeBinding { name, binding_type },
|
||||||
|
Token::default(),
|
||||||
|
)))),
|
||||||
|
"implicit_parameter" => {
|
||||||
|
Ok(signature(ParameterBinding::Implicit(AngleBracket(
|
||||||
|
Token::default(),
|
||||||
|
TypeBinding { name, binding_type },
|
||||||
|
Token::default(),
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
crates/kind-fmt/src/pattern.rs
Normal file
15
crates/kind-fmt/src/pattern.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use kind_syntax::concrete::{Pat, PatKind};
|
||||||
|
use kind_syntax::lexemes::Span;
|
||||||
|
use crate::{Result, FmtContext};
|
||||||
|
|
||||||
|
impl<'a> FmtContext<'a> {
|
||||||
|
pub fn pattern(&mut self) -> Result<Pat> {
|
||||||
|
match self.kind() {
|
||||||
|
"identifier" | "constructor_identifier" => {
|
||||||
|
let name = self.name()?;
|
||||||
|
Ok(Pat::new(Span::default(), PatKind::Name(name)))
|
||||||
|
}
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
crates/kind-fmt/src/primary.rs
Normal file
19
crates/kind-fmt/src/primary.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use kind_syntax::concrete::Expr;
|
||||||
|
use kind_syntax::lexemes::Span;
|
||||||
|
use crate::{FmtContext, Result};
|
||||||
|
|
||||||
|
impl<'a> FmtContext<'a> {
|
||||||
|
pub fn primary(&mut self) -> Result<Expr> {
|
||||||
|
match self.kind() {
|
||||||
|
"constructor_identifier" => {
|
||||||
|
let name = self.name()?;
|
||||||
|
Ok(Expr::constructor(Span::default(), name))
|
||||||
|
}
|
||||||
|
"identifier" => {
|
||||||
|
let name = self.name()?;
|
||||||
|
Ok(Expr::local(Span::default(), name))
|
||||||
|
}
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
crates/kind-fmt/src/statements.rs
Normal file
32
crates/kind-fmt/src/statements.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use thin_vec::ThinVec;
|
||||||
|
|
||||||
|
use kind_syntax::concrete::{Block, Stmt};
|
||||||
|
use kind_syntax::lexemes::{Brace, Token};
|
||||||
|
|
||||||
|
use crate::{FmtContext, Result};
|
||||||
|
|
||||||
|
impl<'a> FmtContext<'a> {
|
||||||
|
pub fn statements(&mut self) -> Result<Block> {
|
||||||
|
match self.kind() {
|
||||||
|
"statements" => {
|
||||||
|
let statements = self
|
||||||
|
.named_children()
|
||||||
|
.map(|node| self.cursor(node).expr())
|
||||||
|
.collect::<Result<ThinVec<_>>>()?;
|
||||||
|
|
||||||
|
Ok(Brace(
|
||||||
|
Token::default(),
|
||||||
|
statements
|
||||||
|
.iter()
|
||||||
|
.map(|expr| Stmt {
|
||||||
|
value: expr.clone(),
|
||||||
|
semi: None,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
Token::default(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
crates/kind-fmt/src/top_level.rs
Normal file
37
crates/kind-fmt/src/top_level.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use thin_vec::thin_vec;
|
||||||
|
use kind_syntax::concrete::{Signature, TopLevel, TopLevelKind};
|
||||||
|
use kind_syntax::lexemes::{Colon, Item, Span, Token};
|
||||||
|
use crate::{FmtContext, Result};
|
||||||
|
|
||||||
|
impl<'a> FmtContext<'a> {
|
||||||
|
pub fn top_level(&mut self) -> Result<TopLevel> {
|
||||||
|
match self.kind() {
|
||||||
|
"val_declaration" => {
|
||||||
|
let name = self.find("name", |node| self.cursor(node).name())?.unwrap();
|
||||||
|
let value = self.find("value", |node| self.cursor(node).statements())?;
|
||||||
|
let parameters = self
|
||||||
|
.properties("parameters")
|
||||||
|
.map(|node| self.cursor(node).parameter())
|
||||||
|
.collect::<Result<_>>()?;
|
||||||
|
let return_type = self.find("return_type", |node| {
|
||||||
|
let value = self.cursor(node).expr()?;
|
||||||
|
Ok(Colon(Token::default(), value))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(TopLevel {
|
||||||
|
data: Item::new(
|
||||||
|
Span::default(),
|
||||||
|
TopLevelKind::Signature(Signature {
|
||||||
|
name,
|
||||||
|
parameters,
|
||||||
|
return_type,
|
||||||
|
value,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
attributes: thin_vec![],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
kind => todo!("{}", kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
crates/kind-syntax/src/builders.rs
Normal file
32
crates/kind-syntax/src/builders.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use crate::concrete::{ConstructorExpr, Expr, ExprKind, LocalExpr};
|
||||||
|
use crate::lexemes::{Name, Span};
|
||||||
|
|
||||||
|
impl Expr {
|
||||||
|
pub fn constructor(span: Span, name: Name) -> Self {
|
||||||
|
Expr::new(
|
||||||
|
span,
|
||||||
|
ExprKind::Constructor(Box::new(ConstructorExpr { name })),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn local(span: Span, name: Name) -> Self {
|
||||||
|
Expr::new(span, ExprKind::Local(Box::new(LocalExpr { name })))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// macro_rules! impl_expr_kind {
|
||||||
|
// ( $( $name:ident( $( $arg:ident: $ty:ty ),* ) ),* ) => {
|
||||||
|
// impl Expr {
|
||||||
|
// $(pub fn $name($($arg: $ty),* span: Span) -> Self {
|
||||||
|
// Expr::new(
|
||||||
|
// span,
|
||||||
|
// ExprKind::$name(Box::new($name Expr { $($arg),* })))
|
||||||
|
// })*
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// impl_expr_kind!(
|
||||||
|
// Local( name: Name, ),
|
||||||
|
// Constructor( name: Name, ),
|
||||||
|
// );
|
@ -41,22 +41,22 @@ pub type Attribute = Item<AttributeKind>;
|
|||||||
/// A type binding is a type annotation for a variable.
|
/// A type binding is a type annotation for a variable.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct TypeBinding {
|
pub struct TypeBinding {
|
||||||
pub name: Ident,
|
pub name: Name,
|
||||||
pub typ: Colon<Box<Expr>>,
|
pub binding_type: Option<Colon<Box<Expr>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum ArgumentBinding {
|
pub enum ParameterBinding {
|
||||||
Implicit(AngleBracket<Param>),
|
Implicit(AngleBracket<TypeBinding>),
|
||||||
Explicit(Paren<Param>),
|
Explicit(Paren<TypeBinding>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An argument of a type signature.
|
/// An argument of a type signature.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Argument {
|
pub enum SignatureParameter {
|
||||||
pub minus: Option<lexemes::Minus>,
|
Exclude(ParameterBinding),
|
||||||
pub plus: Option<lexemes::Plus>,
|
Include(ParameterBinding),
|
||||||
pub binding: ArgumentBinding,
|
Both(ParameterBinding),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A local expression is a reference atom to a local declaration.
|
/// A local expression is a reference atom to a local declaration.
|
||||||
@ -79,9 +79,8 @@ pub struct ConstructorExpr {
|
|||||||
/// (x : Int)
|
/// (x : Int)
|
||||||
/// // or
|
/// // or
|
||||||
/// x
|
/// x
|
||||||
/// ```
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Param {
|
pub enum PiParameter {
|
||||||
Named(Paren<TypeBinding>),
|
Named(Paren<TypeBinding>),
|
||||||
Expr(Box<Expr>),
|
Expr(Box<Expr>),
|
||||||
}
|
}
|
||||||
@ -90,7 +89,7 @@ pub enum Param {
|
|||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct PiExpr {
|
pub struct PiExpr {
|
||||||
pub r#tilde: lexemes::Tilde,
|
pub r#tilde: lexemes::Tilde,
|
||||||
pub param: Param,
|
pub param: PiParameter,
|
||||||
pub r#arrow: lexemes::RightArrow,
|
pub r#arrow: lexemes::RightArrow,
|
||||||
pub body: Box<Expr>,
|
pub body: Box<Expr>,
|
||||||
}
|
}
|
||||||
@ -109,7 +108,7 @@ pub struct SigmaExpr {
|
|||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct LambdaExpr {
|
pub struct LambdaExpr {
|
||||||
pub r#tilde: Option<lexemes::Tilde>,
|
pub r#tilde: Option<lexemes::Tilde>,
|
||||||
pub param: Param,
|
pub param: PiParameter,
|
||||||
pub r#arrow: lexemes::FatArrow,
|
pub r#arrow: lexemes::FatArrow,
|
||||||
pub body: Box<Expr>,
|
pub body: Box<Expr>,
|
||||||
}
|
}
|
||||||
@ -309,7 +308,7 @@ pub struct CaseNode {
|
|||||||
pub struct MatchExpr {
|
pub struct MatchExpr {
|
||||||
pub r#match: lexemes::Match,
|
pub r#match: lexemes::Match,
|
||||||
pub typ: Option<Ident>,
|
pub typ: Option<Ident>,
|
||||||
pub with: Option<(lexemes::With, ThinVec<Param>)>,
|
pub with: Option<(lexemes::With, ThinVec<PiParameter>)>,
|
||||||
pub scrutinee: Box<Expr>,
|
pub scrutinee: Box<Expr>,
|
||||||
pub cases: Brace<ThinVec<CaseNode>>,
|
pub cases: Brace<ThinVec<CaseNode>>,
|
||||||
pub motive: Option<Colon<Box<Expr>>>,
|
pub motive: Option<Colon<Box<Expr>>>,
|
||||||
@ -387,7 +386,7 @@ pub type Expr = Item<ExprKind>;
|
|||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ConstructorPat {
|
pub struct ConstructorPat {
|
||||||
pub name: QualifiedIdent,
|
pub name: QualifiedIdent,
|
||||||
pub args: ThinVec<Argument>,
|
pub args: ThinVec<SignatureParameter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A pattern is part of a rule. It is a structure that matches an expression.
|
/// A pattern is part of a rule. It is a structure that matches an expression.
|
||||||
@ -411,7 +410,7 @@ pub type Pat = Item<PatKind>;
|
|||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Signature {
|
pub struct Signature {
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
pub arguments: ThinVec<Argument>,
|
pub parameters: ThinVec<SignatureParameter>,
|
||||||
pub return_type: Option<Colon<Expr>>,
|
pub return_type: Option<Colon<Expr>>,
|
||||||
pub value: Option<Block>,
|
pub value: Option<Block>,
|
||||||
}
|
}
|
||||||
@ -440,7 +439,7 @@ pub struct Rule {
|
|||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub arguments: ThinVec<Argument>,
|
pub arguments: ThinVec<SignatureParameter>,
|
||||||
pub return_typ: Option<Colon<Expr>>,
|
pub return_typ: Option<Colon<Expr>>,
|
||||||
pub value: Brace<Expr>,
|
pub value: Brace<Expr>,
|
||||||
}
|
}
|
||||||
@ -468,7 +467,7 @@ pub struct Command {
|
|||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Constructor {
|
pub struct Constructor {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub arguments: ThinVec<Argument>,
|
pub arguments: ThinVec<SignatureParameter>,
|
||||||
pub typ: Option<Colon<ThinVec<Expr>>>,
|
pub typ: Option<Colon<ThinVec<Expr>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,8 +477,8 @@ pub struct Constructor {
|
|||||||
pub struct TypeDef {
|
pub struct TypeDef {
|
||||||
pub name: QualifiedIdent,
|
pub name: QualifiedIdent,
|
||||||
pub constructors: ThinVec<Constructor>,
|
pub constructors: ThinVec<Constructor>,
|
||||||
pub params: ThinVec<Argument>,
|
pub params: ThinVec<SignatureParameter>,
|
||||||
pub indices: ThinVec<Argument>,
|
pub indices: ThinVec<SignatureParameter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A record definition is a top-level structure that defines a type with
|
/// A record definition is a top-level structure that defines a type with
|
||||||
@ -488,8 +487,8 @@ pub struct TypeDef {
|
|||||||
pub struct RecordDef {
|
pub struct RecordDef {
|
||||||
pub name: QualifiedIdent,
|
pub name: QualifiedIdent,
|
||||||
pub fields: ThinVec<TypeBinding>,
|
pub fields: ThinVec<TypeBinding>,
|
||||||
pub params: ThinVec<Argument>,
|
pub params: ThinVec<SignatureParameter>,
|
||||||
pub indices: ThinVec<Argument>,
|
pub indices: ThinVec<SignatureParameter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A top-level item is a item that is on the outermost level of a
|
/// A top-level item is a item that is on the outermost level of a
|
||||||
|
@ -4,3 +4,4 @@
|
|||||||
pub mod concrete;
|
pub mod concrete;
|
||||||
pub mod core;
|
pub mod core;
|
||||||
pub mod lexemes;
|
pub mod lexemes;
|
||||||
|
pub mod builders;
|
||||||
|
Loading…
Reference in New Issue
Block a user