mirror of
https://github.com/HigherOrderCO/Kind1.git
synced 2024-09-11 08:45:32 +03:00
fix: fixed some problems with attribute parsing
This commit is contained in:
parent
b7bc9e9f1f
commit
bbe6c14cd6
@ -1,4 +1,4 @@
|
||||
use kind_span::Locatable;
|
||||
use kind_span::{Locatable, Range};
|
||||
use kind_tree::concrete::{Attribute, AttributeStyle};
|
||||
|
||||
use crate::errors::SyntaxError;
|
||||
@ -6,10 +6,10 @@ use crate::lexer::tokens::Token;
|
||||
use crate::state::Parser;
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
pub fn parse_attr_args(&mut self) -> Result<Vec<AttributeStyle>, SyntaxError> {
|
||||
pub fn parse_attr_args(&mut self) -> Result<(Vec<AttributeStyle>, Range), SyntaxError> {
|
||||
let mut attrs = Vec::new();
|
||||
|
||||
let range = self.range();
|
||||
let mut range = self.range();
|
||||
|
||||
if self.check_and_eat(Token::LBracket) {
|
||||
while let Some(res) = self.try_single(&|fun| fun.parse_attr_style())? {
|
||||
@ -18,11 +18,12 @@ impl<'a> Parser<'a> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self.eat_closing_keyword(Token::RBracket, range)?;
|
||||
let start = range;
|
||||
range = self.range();
|
||||
self.eat_closing_keyword(Token::RBracket, start)?;
|
||||
}
|
||||
|
||||
Ok(attrs)
|
||||
Ok((attrs, range))
|
||||
}
|
||||
|
||||
pub fn parse_attr_style(&mut self) -> Result<AttributeStyle, SyntaxError> {
|
||||
@ -68,15 +69,17 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let name = self.parse_id()?;
|
||||
|
||||
let args = self.parse_attr_args()?;
|
||||
let (args, mut last) = self.parse_attr_args()?;
|
||||
|
||||
let style = if self.check_and_eat(Token::Eq) {
|
||||
Some(self.parse_attr_style()?)
|
||||
let res = self.parse_attr_style()?;
|
||||
last = res.locate();
|
||||
Some(res)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(Attribute {
|
||||
range: start.mix(style.clone().map(|x| x.locate()).unwrap_or(name.range)),
|
||||
range: start.mix(last),
|
||||
value: style,
|
||||
args,
|
||||
name,
|
||||
|
@ -1,9 +1,84 @@
|
||||
use kind_tree::{concrete, desugared};
|
||||
use kind_tree::{concrete::{self, Attribute, AttributeStyle}, desugared};
|
||||
|
||||
use crate::errors::PassError;
|
||||
|
||||
use super::DesugarState;
|
||||
|
||||
impl<'a> DesugarState<'a> {
|
||||
pub fn desugar_attributes(&self, _attr: &[concrete::Attribute]) -> Vec<desugared::Attribute> {
|
||||
Vec::new()
|
||||
|
||||
fn args_should_be_empty(&mut self, attr: &Attribute) {
|
||||
if !attr.args.is_empty() {
|
||||
self.send_err(PassError::AttributeDoesNotExpectArgs(attr.range))
|
||||
};
|
||||
}
|
||||
|
||||
fn attr_without_value(&mut self, attr: &Attribute) {
|
||||
if attr.value.is_some() {
|
||||
self.send_err(PassError::AttributeDoesNotExpectEqual(attr.range))
|
||||
};
|
||||
}
|
||||
|
||||
fn attr_invalid_argument(&mut self, attr: &Attribute) {
|
||||
if !attr.value.is_some() {
|
||||
self.send_err(PassError::InvalidAttributeArgument(attr.range))
|
||||
};
|
||||
}
|
||||
|
||||
fn attr_expects_a_value(&mut self, attr: &Attribute) {
|
||||
if !attr.value.is_some() {
|
||||
self.send_err(PassError::InvalidAttributeArgument(attr.range))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn desugar_attributes(
|
||||
&mut self,
|
||||
attrs: &[concrete::Attribute],
|
||||
) -> Vec<desugared::Attribute> {
|
||||
let mut vec = Vec::new();
|
||||
|
||||
for attr in attrs {
|
||||
match attr.name.to_str() {
|
||||
// The derive attribute is treated by the expand
|
||||
// pass so here we just ignore it.
|
||||
"derive" => (),
|
||||
"inline" => {
|
||||
self.args_should_be_empty(attr);
|
||||
self.attr_without_value(attr);
|
||||
vec.push(desugared::Attribute::Inline);
|
||||
}
|
||||
"kdl_run" => {
|
||||
self.args_should_be_empty(attr);
|
||||
self.attr_without_value(attr);
|
||||
vec.push(desugared::Attribute::KdlRun);
|
||||
}
|
||||
"kdl_erase" => {
|
||||
self.args_should_be_empty(attr);
|
||||
self.attr_without_value(attr);
|
||||
vec.push(desugared::Attribute::KdlErase);
|
||||
}
|
||||
"kdl_name" => {
|
||||
self.args_should_be_empty(attr);
|
||||
match &attr.value {
|
||||
Some(AttributeStyle::Ident(_, ident)) => {
|
||||
vec.push(desugared::Attribute::KdlState(ident.clone()));
|
||||
},
|
||||
Some(_) => self.attr_invalid_argument(attr),
|
||||
None => self.attr_expects_a_value(attr)
|
||||
}
|
||||
},
|
||||
"kdl_state" => {
|
||||
self.args_should_be_empty(attr);
|
||||
match &attr.value {
|
||||
Some(AttributeStyle::Ident(_, ident)) => {
|
||||
vec.push(desugared::Attribute::KdlState(ident.clone()));
|
||||
},
|
||||
Some(_) => self.attr_invalid_argument(attr),
|
||||
None => self.attr_expects_a_value(attr)
|
||||
}
|
||||
},
|
||||
_ => self.send_err(PassError::AttributeDoesNotExists(attr.range))
|
||||
}
|
||||
}
|
||||
vec
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,13 @@ pub enum PassError {
|
||||
NoFieldCoverage(Range, Vec<String>),
|
||||
CannotPatternMatchOnErased(Range),
|
||||
|
||||
AttributeDoesNotAcceptEqual(Range),
|
||||
AttributeDoesNotExpectEqual(Range),
|
||||
AttributeDoesNotExpectArgs(Range),
|
||||
InvalidAttributeArgument(Range),
|
||||
AttributeExpectsAValue(Range),
|
||||
DuplicatedAttributeArgument(Range, Range),
|
||||
CannotDerive(String, Range),
|
||||
AttributeDoesNotExists(Range)
|
||||
}
|
||||
|
||||
// TODO: A way to build an error message with methods
|
||||
@ -431,7 +434,7 @@ impl Diagnostic for PassError {
|
||||
main: true,
|
||||
}],
|
||||
},
|
||||
PassError::AttributeDoesNotAcceptEqual(place) => DiagnosticFrame {
|
||||
PassError::AttributeDoesNotExpectEqual(place) => DiagnosticFrame {
|
||||
code: 209,
|
||||
severity: Severity::Error,
|
||||
title: "This attribute does not support values!".to_string(),
|
||||
@ -445,6 +448,20 @@ impl Diagnostic for PassError {
|
||||
main: true,
|
||||
}],
|
||||
},
|
||||
PassError::AttributeDoesNotExpectArgs(place) => DiagnosticFrame {
|
||||
code: 209,
|
||||
severity: Severity::Error,
|
||||
title: "This attribute does not expect arguments".to_string(),
|
||||
subtitles: vec![],
|
||||
hints: vec![],
|
||||
positions: vec![Marker {
|
||||
position: *place,
|
||||
color: Color::Fst,
|
||||
text: "Try to remove all of the arguments".to_string(),
|
||||
no_code: false,
|
||||
main: true,
|
||||
}],
|
||||
},
|
||||
PassError::InvalidAttributeArgument(place) => DiagnosticFrame {
|
||||
code: 209,
|
||||
severity: Severity::Error,
|
||||
@ -473,6 +490,35 @@ impl Diagnostic for PassError {
|
||||
main: true,
|
||||
}],
|
||||
},
|
||||
|
||||
PassError::AttributeExpectsAValue(place) => DiagnosticFrame {
|
||||
code: 209,
|
||||
severity: Severity::Error,
|
||||
title: format!("This attribute expects a value"),
|
||||
subtitles: vec![],
|
||||
hints: vec![],
|
||||
positions: vec![Marker {
|
||||
position: *place,
|
||||
color: Color::Fst,
|
||||
text: "Here!".to_string(),
|
||||
no_code: false,
|
||||
main: true,
|
||||
}],
|
||||
},
|
||||
PassError::AttributeDoesNotExists(place) => DiagnosticFrame {
|
||||
code: 209,
|
||||
severity: Severity::Error,
|
||||
title: format!("This attribute does not exists"),
|
||||
subtitles: vec![],
|
||||
hints: vec![],
|
||||
positions: vec![Marker {
|
||||
position: *place,
|
||||
color: Color::Fst,
|
||||
text: "Here!".to_string(),
|
||||
no_code: false,
|
||||
main: true,
|
||||
}],
|
||||
},
|
||||
PassError::DuplicatedAttributeArgument(first, sec) => DiagnosticFrame {
|
||||
code: 209,
|
||||
severity: Severity::Warning,
|
||||
|
@ -75,7 +75,7 @@ pub fn expand_derive(
|
||||
|
||||
if let Some(attr) = &attr.value {
|
||||
error_channel
|
||||
.send(Box::new(PassError::AttributeDoesNotAcceptEqual(
|
||||
.send(Box::new(PassError::AttributeDoesNotExpectEqual(
|
||||
attr.locate(),
|
||||
)))
|
||||
.unwrap();
|
||||
|
@ -257,7 +257,13 @@ pub struct Rule {
|
||||
/// Attributes describes some compiler specific aspects
|
||||
/// like inlining and derivations.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Attribute {}
|
||||
pub enum Attribute {
|
||||
Inline,
|
||||
KdlRun,
|
||||
KdlErase,
|
||||
KdlName(Ident),
|
||||
KdlState(Ident),
|
||||
}
|
||||
|
||||
/// An entry describes a function that is typed
|
||||
/// and has rules. The type of the function
|
||||
|
Loading…
Reference in New Issue
Block a user