feat: add module constants
This commit is contained in:
parent
34c8a58391
commit
fedafed845
|
@ -185,6 +185,11 @@ pub enum Constant<T, RecordTag> {
|
||||||
value: String,
|
value: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Tuple {
|
||||||
|
location: Span,
|
||||||
|
elements: Vec<Self>,
|
||||||
|
},
|
||||||
|
|
||||||
List {
|
List {
|
||||||
location: Span,
|
location: Span,
|
||||||
elements: Vec<Self>,
|
elements: Vec<Self>,
|
||||||
|
@ -221,6 +226,9 @@ impl TypedConstant {
|
||||||
Constant::Int { .. } => builtins::int(),
|
Constant::Int { .. } => builtins::int(),
|
||||||
Constant::String { .. } => builtins::string(),
|
Constant::String { .. } => builtins::string(),
|
||||||
Constant::ByteArray { .. } => builtins::byte_array(),
|
Constant::ByteArray { .. } => builtins::byte_array(),
|
||||||
|
Constant::Tuple { elements, .. } => {
|
||||||
|
builtins::tuple(elements.iter().map(|e| e.tipo()).collect())
|
||||||
|
}
|
||||||
Constant::List { tipo, .. }
|
Constant::List { tipo, .. }
|
||||||
| Constant::Record { tipo, .. }
|
| Constant::Record { tipo, .. }
|
||||||
| Constant::Var { tipo, .. } => tipo.clone(),
|
| Constant::Var { tipo, .. } => tipo.clone(),
|
||||||
|
@ -232,6 +240,7 @@ impl<A, B> Constant<A, B> {
|
||||||
pub fn location(&self) -> Span {
|
pub fn location(&self) -> Span {
|
||||||
match self {
|
match self {
|
||||||
Constant::Int { location, .. }
|
Constant::Int { location, .. }
|
||||||
|
| Constant::Tuple { location, .. }
|
||||||
| Constant::List { location, .. }
|
| Constant::List { location, .. }
|
||||||
| Constant::String { location, .. }
|
| Constant::String { location, .. }
|
||||||
| Constant::Record { location, .. }
|
| Constant::Record { location, .. }
|
||||||
|
|
|
@ -351,6 +351,13 @@ impl<'comments> Formatter<'comments> {
|
||||||
module: Some(module),
|
module: Some(module),
|
||||||
..
|
..
|
||||||
} => docvec![module, ".", name],
|
} => docvec![module, ".", name],
|
||||||
|
|
||||||
|
Constant::Tuple { elements, .. } => "#"
|
||||||
|
.to_doc()
|
||||||
|
.append(wrap_args(
|
||||||
|
elements.iter().map(|e| (self.const_expr(e), false)),
|
||||||
|
))
|
||||||
|
.group(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ fn module_parser() -> impl Parser<Token, Vec<UntypedDefinition>, Error = ParseEr
|
||||||
data_parser(),
|
data_parser(),
|
||||||
type_alias_parser(),
|
type_alias_parser(),
|
||||||
fn_parser(),
|
fn_parser(),
|
||||||
|
constant_parser(),
|
||||||
))
|
))
|
||||||
.repeated()
|
.repeated()
|
||||||
.then_ignore(end())
|
.then_ignore(end())
|
||||||
|
@ -265,6 +266,202 @@ pub fn fn_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseEr
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn constant_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
|
||||||
|
pub_parser()
|
||||||
|
.or_not()
|
||||||
|
.then_ignore(just(Token::Const))
|
||||||
|
.then(select! {Token::Name{name} => name})
|
||||||
|
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
|
||||||
|
.then_ignore(just(Token::Equal))
|
||||||
|
.then(constant_value_parser())
|
||||||
|
.map_with_span(|(((public, name), annotation), value), span| {
|
||||||
|
ast::UntypedDefinition::ModuleConstant(ast::ModuleConstant {
|
||||||
|
doc: None,
|
||||||
|
location: span,
|
||||||
|
public: public.is_some(),
|
||||||
|
name,
|
||||||
|
annotation,
|
||||||
|
value: Box::new(value),
|
||||||
|
tipo: (),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn constant_value_parser() -> impl Parser<Token, ast::UntypedConstant, Error = ParseError> {
|
||||||
|
recursive(|r| {
|
||||||
|
let constant_string_parser =
|
||||||
|
select! {Token::String {value} => value}.map_with_span(|value, span| {
|
||||||
|
ast::UntypedConstant::String {
|
||||||
|
location: span,
|
||||||
|
value,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let constant_int_parser =
|
||||||
|
select! {Token::Int {value} => value}.map_with_span(|value, span| {
|
||||||
|
ast::UntypedConstant::Int {
|
||||||
|
location: span,
|
||||||
|
value,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let constant_tuple_parser = just(Token::Hash)
|
||||||
|
.ignore_then(r.clone())
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.allow_trailing()
|
||||||
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
||||||
|
.map_with_span(|elements, span| ast::UntypedConstant::Tuple {
|
||||||
|
location: span,
|
||||||
|
elements,
|
||||||
|
});
|
||||||
|
|
||||||
|
let constant_bytearray_parser = just(Token::Hash)
|
||||||
|
.ignore_then(
|
||||||
|
select! {Token::Int {value} => value}.validate(|value, span, emit| {
|
||||||
|
let byte: u8 = match value.parse() {
|
||||||
|
Ok(b) => b,
|
||||||
|
Err(_) => {
|
||||||
|
emit(ParseError::expected_input_found(
|
||||||
|
span,
|
||||||
|
None,
|
||||||
|
Some(error::Pattern::Byte),
|
||||||
|
));
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
byte
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.allow_trailing()
|
||||||
|
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare))
|
||||||
|
.map_with_span(|bytes, span| ast::UntypedConstant::ByteArray {
|
||||||
|
location: span,
|
||||||
|
bytes,
|
||||||
|
});
|
||||||
|
|
||||||
|
let constant_list_parser = r
|
||||||
|
.clone()
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.allow_trailing()
|
||||||
|
.delimited_by(just(Token::LeftSquare), just(Token::RightSquare))
|
||||||
|
.map_with_span(|elements, span| ast::UntypedConstant::List {
|
||||||
|
location: span,
|
||||||
|
elements,
|
||||||
|
tipo: (),
|
||||||
|
});
|
||||||
|
|
||||||
|
let constant_record_parser = choice((
|
||||||
|
choice((
|
||||||
|
select! {Token::Name { name } => name}
|
||||||
|
.then_ignore(just(Token::Dot))
|
||||||
|
.or_not()
|
||||||
|
.then(select! {Token::UpName { name } => name})
|
||||||
|
.then(
|
||||||
|
select! {Token::Name {name} => name}
|
||||||
|
.then_ignore(just(Token::Colon))
|
||||||
|
.or_not()
|
||||||
|
.then(r.clone())
|
||||||
|
.validate(|(label_opt, value), span, emit| {
|
||||||
|
let label = if label_opt.is_some() {
|
||||||
|
label_opt
|
||||||
|
} else if let ast::UntypedConstant::Var { name, .. } = &value {
|
||||||
|
Some(name.clone())
|
||||||
|
} else {
|
||||||
|
emit(ParseError::expected_input_found(
|
||||||
|
value.location(),
|
||||||
|
None,
|
||||||
|
Some(error::Pattern::RecordPunning),
|
||||||
|
));
|
||||||
|
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
ast::CallArg {
|
||||||
|
location: span,
|
||||||
|
value,
|
||||||
|
label,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.allow_trailing()
|
||||||
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||||
|
)
|
||||||
|
.map_with_span(
|
||||||
|
|((module, name), args), span| ast::UntypedConstant::Record {
|
||||||
|
location: span,
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
tag: (),
|
||||||
|
tipo: (),
|
||||||
|
field_map: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
select! {Token::Name { name } => name}
|
||||||
|
.then_ignore(just(Token::Dot))
|
||||||
|
.or_not()
|
||||||
|
.then(select! {Token::UpName { name } => name})
|
||||||
|
.then(
|
||||||
|
r.clone()
|
||||||
|
.map_with_span(|value, span| ast::CallArg {
|
||||||
|
location: span,
|
||||||
|
value,
|
||||||
|
label: None,
|
||||||
|
})
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.allow_trailing()
|
||||||
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||||
|
)
|
||||||
|
.map_with_span(
|
||||||
|
|((module, name), args), span| ast::UntypedConstant::Record {
|
||||||
|
location: span,
|
||||||
|
module,
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
tag: (),
|
||||||
|
tipo: (),
|
||||||
|
field_map: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
select! {Token::Name { name } => name}
|
||||||
|
.then_ignore(just(Token::Dot))
|
||||||
|
.then(select! {Token::Name{name} => name})
|
||||||
|
.map_with_span(|(module, name), span: Span| ast::UntypedConstant::Var {
|
||||||
|
location: span.union(span),
|
||||||
|
module: Some(module),
|
||||||
|
name,
|
||||||
|
constructor: None,
|
||||||
|
tipo: (),
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
|
||||||
|
let constant_var_parser =
|
||||||
|
select! {Token::Name {name} => name}.map_with_span(|name, span| {
|
||||||
|
ast::UntypedConstant::Var {
|
||||||
|
location: span,
|
||||||
|
module: None,
|
||||||
|
name,
|
||||||
|
constructor: None,
|
||||||
|
tipo: (),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
choice((
|
||||||
|
constant_string_parser,
|
||||||
|
constant_int_parser,
|
||||||
|
constant_tuple_parser,
|
||||||
|
constant_bytearray_parser,
|
||||||
|
constant_list_parser,
|
||||||
|
constant_record_parser,
|
||||||
|
constant_var_parser,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fn_param_parser() -> impl Parser<Token, ast::UntypedArg, Error = ParseError> {
|
pub fn fn_param_parser() -> impl Parser<Token, ast::UntypedArg, Error = ParseError> {
|
||||||
choice((
|
choice((
|
||||||
select! {Token::Name {name} => name}
|
select! {Token::Name {name} => name}
|
||||||
|
@ -445,6 +642,10 @@ pub fn expr_parser(
|
||||||
tail,
|
tail,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let block_parser = seq_r
|
||||||
|
.clone()
|
||||||
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
||||||
|
|
||||||
let anon_fn_parser = just(Token::Fn)
|
let anon_fn_parser = just(Token::Fn)
|
||||||
.ignore_then(
|
.ignore_then(
|
||||||
anon_fn_param_parser()
|
anon_fn_param_parser()
|
||||||
|
@ -453,11 +654,7 @@ pub fn expr_parser(
|
||||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen)),
|
||||||
)
|
)
|
||||||
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
||||||
.then(
|
.then(seq_r.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)))
|
||||||
seq_r
|
|
||||||
.clone()
|
|
||||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
|
||||||
)
|
|
||||||
.map_with_span(
|
.map_with_span(
|
||||||
|((arguments, return_annotation), body), span| expr::UntypedExpr::Fn {
|
|((arguments, return_annotation), body), span| expr::UntypedExpr::Fn {
|
||||||
arguments,
|
arguments,
|
||||||
|
@ -468,8 +665,6 @@ pub fn expr_parser(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let block_parser = seq_r.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
|
||||||
|
|
||||||
// TODO: do guards later
|
// TODO: do guards later
|
||||||
// let when_clause_guard_parser = just(Token::If);
|
// let when_clause_guard_parser = just(Token::If);
|
||||||
|
|
||||||
|
@ -999,10 +1194,16 @@ pub fn pattern_parser() -> impl Parser<Token, ast::UntypedPattern, Error = Parse
|
||||||
label: Some(name),
|
label: Some(name),
|
||||||
value: pattern,
|
value: pattern,
|
||||||
}),
|
}),
|
||||||
r.clone().map_with_span(|pattern, span| {
|
r.clone().validate(|pattern, span, emit| {
|
||||||
let label = if let ast::UntypedPattern::Var { name, .. } = &pattern {
|
let label = if let ast::UntypedPattern::Var { name, .. } = &pattern {
|
||||||
Some(name.clone())
|
Some(name.clone())
|
||||||
} else {
|
} else {
|
||||||
|
emit(ParseError::expected_input_found(
|
||||||
|
pattern.location(),
|
||||||
|
None,
|
||||||
|
Some(error::Pattern::RecordPunning),
|
||||||
|
));
|
||||||
|
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use miette::Diagnostic;
|
||||||
use crate::{ast::Span, parser::token::Token};
|
use crate::{ast::Span, parser::token::Token};
|
||||||
|
|
||||||
#[derive(Debug, Diagnostic, thiserror::Error)]
|
#[derive(Debug, Diagnostic, thiserror::Error)]
|
||||||
#[error("{kind}")]
|
#[error("{kind}\n")]
|
||||||
pub struct ParseError {
|
pub struct ParseError {
|
||||||
pub kind: ErrorKind,
|
pub kind: ErrorKind,
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -104,12 +104,17 @@ pub enum Pattern {
|
||||||
TermIdent,
|
TermIdent,
|
||||||
#[error("Unexpected end of input")]
|
#[error("Unexpected end of input")]
|
||||||
End,
|
End,
|
||||||
#[error("Bad list spread pattern")]
|
#[error("Malformed list spread pattern")]
|
||||||
#[diagnostic(help("List spread in matches can\nuse have a discard or var"))]
|
#[diagnostic(help("List spread in matches can\nuse have a discard or var"))]
|
||||||
Match,
|
Match,
|
||||||
#[error("Bad byte literal")]
|
#[error("Malformed byte literal")]
|
||||||
#[diagnostic(help("Bytes must be between 0-255"))]
|
#[diagnostic(help("Bytes must be between 0-255"))]
|
||||||
Byte,
|
Byte,
|
||||||
|
#[error("Unexpected pattern")]
|
||||||
|
#[diagnostic(help(
|
||||||
|
"If no label is provided then only variables\nmatching a field name are allowed"
|
||||||
|
))]
|
||||||
|
RecordPunning,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<char> for Pattern {
|
impl From<char> for Pattern {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use super::Type;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error, Diagnostic)]
|
#[derive(Debug, thiserror::Error, Diagnostic)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("Duplicate argument\n\n{label}")]
|
#[error("Duplicate argument\n\n{label}\n")]
|
||||||
#[diagnostic(help("Try renaming it"))]
|
#[diagnostic(help("Try renaming it"))]
|
||||||
DuplicateArgument {
|
DuplicateArgument {
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -16,7 +16,7 @@ pub enum Error {
|
||||||
label: String,
|
label: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Duplicate const\n\n{name}")]
|
#[error("Duplicate const\n\n{name}\n")]
|
||||||
#[diagnostic(help("Try renaming it"))]
|
#[diagnostic(help("Try renaming it"))]
|
||||||
DuplicateConstName {
|
DuplicateConstName {
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -26,7 +26,7 @@ pub enum Error {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Duplicate import\n\n{name}")]
|
#[error("Duplicate import\n\n{name}\n")]
|
||||||
#[diagnostic(help("Try renaming it"))]
|
#[diagnostic(help("Try renaming it"))]
|
||||||
DuplicateImport {
|
DuplicateImport {
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -36,7 +36,7 @@ pub enum Error {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Duplicate field\n\n{label}")]
|
#[error("Duplicate field\n\n{label}\n")]
|
||||||
#[diagnostic(help("Try renaming it"))]
|
#[diagnostic(help("Try renaming it"))]
|
||||||
DuplicateField {
|
DuplicateField {
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -44,7 +44,7 @@ pub enum Error {
|
||||||
label: String,
|
label: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Duplicate name\n\n{name}")]
|
#[error("Duplicate name\n\n{name}\n")]
|
||||||
#[diagnostic(help("Try renaming it"))]
|
#[diagnostic(help("Try renaming it"))]
|
||||||
DuplicateName {
|
DuplicateName {
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -54,7 +54,7 @@ pub enum Error {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Duplicate type name\n\n{name}")]
|
#[error("Duplicate type name\n\n{name}\n")]
|
||||||
#[diagnostic(help("Try renaming it"))]
|
#[diagnostic(help("Try renaming it"))]
|
||||||
DuplicateTypeName {
|
DuplicateTypeName {
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -64,7 +64,7 @@ pub enum Error {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Incorrect arity\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
|
#[error("Incorrect arity\n\nExpected\n\n{expected}\n\nGiven\n\n{given}\n")]
|
||||||
IncorrectArity {
|
IncorrectArity {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -73,7 +73,7 @@ pub enum Error {
|
||||||
labels: Vec<String>,
|
labels: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Incorrect number of clause patterns\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
|
#[error("Incorrect number of clause patterns\n\nExpected\n\n{expected}\n\nGiven\n\n{given}\n")]
|
||||||
IncorrectNumClausePatterns {
|
IncorrectNumClausePatterns {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -81,7 +81,7 @@ pub enum Error {
|
||||||
given: usize,
|
given: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Incorrect type arity for `{name}`\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
|
#[error("Incorrect type arity for `{name}`\n\nExpected\n\n{expected}\n\nGiven\n\n{given}\n")]
|
||||||
IncorrectTypeArity {
|
IncorrectTypeArity {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -90,7 +90,7 @@ pub enum Error {
|
||||||
given: usize,
|
given: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Non-exhaustive pattern match")]
|
#[error("Non-exhaustive pattern match\n")]
|
||||||
NotExhaustivePatternMatch {
|
NotExhaustivePatternMatch {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -104,65 +104,65 @@ pub enum Error {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Module\n\n{name}\n\ncontains keyword\n\n{keyword}")]
|
#[error("Module\n\n{name}\n\ncontains keyword\n\n{keyword}\n")]
|
||||||
KeywordInModuleName { name: String, keyword: String },
|
KeywordInModuleName { name: String, keyword: String },
|
||||||
|
|
||||||
#[error("Clause guard {name} is not local")]
|
#[error("Clause guard {name} is not local\n")]
|
||||||
NonLocalClauseGuardVariable {
|
NonLocalClauseGuardVariable {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Positional argument after labeled")]
|
#[error("Positional argument after labeled\n")]
|
||||||
PositionalArgumentAfterLabeled {
|
PositionalArgumentAfterLabeled {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Private type leaked")]
|
#[error("Private type leaked\n")]
|
||||||
PrivateTypeLeak {
|
PrivateTypeLeak {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
leaked: Type,
|
leaked: Type,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Record access unknown type")]
|
#[error("Record access unknown type\n")]
|
||||||
RecordAccessUnknownType {
|
RecordAccessUnknownType {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Record update invalid constructor")]
|
#[error("Record update invalid constructor\n")]
|
||||||
RecordUpdateInvalidConstructor {
|
RecordUpdateInvalidConstructor {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("{name} is a reserved module name")]
|
#[error("{name} is a reserved module name\n")]
|
||||||
ReservedModuleName { name: String },
|
ReservedModuleName { name: String },
|
||||||
|
|
||||||
#[error("Unexpected labeled argument\n\n{label}")]
|
#[error("Unexpected labeled argument\n\n{label}\n")]
|
||||||
UnexpectedLabeledArg {
|
UnexpectedLabeledArg {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
label: String,
|
label: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unexpected type hole")]
|
#[error("Unexpected type hole\n")]
|
||||||
UnexpectedTypeHole {
|
UnexpectedTypeHole {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown labels")]
|
#[error("Unknown labels\n")]
|
||||||
UnknownLabels {
|
UnknownLabels {
|
||||||
unknown: Vec<(String, Span)>,
|
unknown: Vec<(String, Span)>,
|
||||||
valid: Vec<String>,
|
valid: Vec<String>,
|
||||||
supplied: Vec<String>,
|
supplied: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown module\n\n{name}")]
|
#[error("Unknown module\n\n{name}\n")]
|
||||||
UnknownModule {
|
UnknownModule {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -170,7 +170,7 @@ pub enum Error {
|
||||||
imported_modules: Vec<String>,
|
imported_modules: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown module field\n\n{name}\n\nin module\n\n{module_name}")]
|
#[error("Unknown module field\n\n{name}\n\nin module\n\n{module_name}\n")]
|
||||||
UnknownModuleField {
|
UnknownModuleField {
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -179,7 +179,7 @@ pub enum Error {
|
||||||
type_constructors: Vec<String>,
|
type_constructors: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown module value\n\n{name}")]
|
#[error("Unknown module value\n\n{name}\n")]
|
||||||
UnknownModuleValue {
|
UnknownModuleValue {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -188,7 +188,7 @@ pub enum Error {
|
||||||
value_constructors: Vec<String>,
|
value_constructors: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown type\n\n{name}\n\nin module\n\n{module_name}")]
|
#[error("Unknown type\n\n{name}\n\nin module\n\n{module_name}\n")]
|
||||||
UnknownModuleType {
|
UnknownModuleType {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -197,7 +197,7 @@ pub enum Error {
|
||||||
type_constructors: Vec<String>,
|
type_constructors: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown record field\n\n{label}")]
|
#[error("Unknown record field\n\n{label}\n")]
|
||||||
UnknownRecordField {
|
UnknownRecordField {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -207,7 +207,7 @@ pub enum Error {
|
||||||
situation: Option<UnknownRecordFieldSituation>,
|
situation: Option<UnknownRecordFieldSituation>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown type\n\n{name}")]
|
#[error("Unknown type\n\n{name}\n")]
|
||||||
UnknownType {
|
UnknownType {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -215,7 +215,7 @@ pub enum Error {
|
||||||
types: Vec<String>,
|
types: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unknown variable\n\n{name}")]
|
#[error("Unknown variable\n\n{name}\n")]
|
||||||
UnknownVariable {
|
UnknownVariable {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -223,14 +223,14 @@ pub enum Error {
|
||||||
variables: Vec<String>,
|
variables: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Unnecessary spread operator")]
|
#[error("Unnecessary spread operator\n")]
|
||||||
UnnecessarySpreadOperator {
|
UnnecessarySpreadOperator {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Cannot update a type with multiple constructors")]
|
#[error("Cannot update a type with multiple constructors\n")]
|
||||||
UpdateMultiConstructorType {
|
UpdateMultiConstructorType {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -271,7 +271,7 @@ pub enum Error {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("")]
|
#[error("Recursive type detected\n")]
|
||||||
RecursiveType {
|
RecursiveType {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -363,7 +363,7 @@ impl Error {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, thiserror::Error, Diagnostic)]
|
#[derive(Debug, PartialEq, Clone, thiserror::Error, Diagnostic)]
|
||||||
pub enum Warning {
|
pub enum Warning {
|
||||||
#[error("todo")]
|
#[error("Todo\n")]
|
||||||
Todo {
|
Todo {
|
||||||
kind: TodoKind,
|
kind: TodoKind,
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -371,31 +371,31 @@ pub enum Warning {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("implicitly discarded result")]
|
#[error("Implicitly discarded result\n")]
|
||||||
ImplicitlyDiscardedResult {
|
ImplicitlyDiscardedResult {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused literal")]
|
#[error("Unused literal\n")]
|
||||||
UnusedLiteral {
|
UnusedLiteral {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("record update with no fields")]
|
#[error("Record update with no fields\n")]
|
||||||
NoFieldsRecordUpdate {
|
NoFieldsRecordUpdate {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("record update using all fields")]
|
#[error("Record update using all fields\n")]
|
||||||
AllFieldsRecordUpdate {
|
AllFieldsRecordUpdate {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused type {name}")]
|
#[error("Unused type {name}\n")]
|
||||||
UnusedType {
|
UnusedType {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -403,7 +403,7 @@ pub enum Warning {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused constructor {name}")]
|
#[error("Unused constructor {name}\n")]
|
||||||
UnusedConstructor {
|
UnusedConstructor {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -411,35 +411,35 @@ pub enum Warning {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused imported value {name}")]
|
#[error("Unused imported value {name}\n")]
|
||||||
UnusedImportedValue {
|
UnusedImportedValue {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused imported module {name}")]
|
#[error("Unused imported module {name}\n")]
|
||||||
UnusedImportedModule {
|
UnusedImportedModule {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused private module constant {name}")]
|
#[error("Unused private module constant {name}\n")]
|
||||||
UnusedPrivateModuleConstant {
|
UnusedPrivateModuleConstant {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused private function {name}")]
|
#[error("Unused private function {name}\n")]
|
||||||
UnusedPrivateFunction {
|
UnusedPrivateFunction {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("unused variable {name}")]
|
#[error("Unused variable {name}\n")]
|
||||||
UnusedVariable {
|
UnusedVariable {
|
||||||
#[label]
|
#[label]
|
||||||
location: Span,
|
location: Span,
|
||||||
|
|
|
@ -1177,6 +1177,22 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
Ok((typed_pattern, typed_alternatives))
|
Ok((typed_pattern, typed_alternatives))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn infer_const_tuple(
|
||||||
|
&mut self,
|
||||||
|
untyped_elements: Vec<UntypedConstant>,
|
||||||
|
location: Span,
|
||||||
|
) -> Result<TypedConstant, Error> {
|
||||||
|
let mut elements = Vec::with_capacity(untyped_elements.len());
|
||||||
|
|
||||||
|
for element in untyped_elements {
|
||||||
|
let element = self.infer_const(&None, element)?;
|
||||||
|
|
||||||
|
elements.push(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Constant::Tuple { elements, location })
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: extract the type annotation checking into a infer_module_const
|
// TODO: extract the type annotation checking into a infer_module_const
|
||||||
// function that uses this function internally
|
// function that uses this function internally
|
||||||
pub fn infer_const(
|
pub fn infer_const(
|
||||||
|
@ -1193,6 +1209,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
location, value, ..
|
location, value, ..
|
||||||
} => Ok(Constant::String { location, value }),
|
} => Ok(Constant::String { location, value }),
|
||||||
|
|
||||||
|
Constant::Tuple {
|
||||||
|
elements, location, ..
|
||||||
|
} => self.infer_const_tuple(elements, location),
|
||||||
|
|
||||||
Constant::List {
|
Constant::List {
|
||||||
elements, location, ..
|
elements, location, ..
|
||||||
} => self.infer_const_list(elements, location),
|
} => self.infer_const_list(elements, location),
|
||||||
|
|
|
@ -265,7 +265,7 @@ impl Diagnostic for Error {
|
||||||
|
|
||||||
#[derive(thiserror::Error)]
|
#[derive(thiserror::Error)]
|
||||||
pub enum Warning {
|
pub enum Warning {
|
||||||
#[error("type checking")]
|
#[error("Checking")]
|
||||||
Type {
|
Type {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
src: String,
|
src: String,
|
||||||
|
|
|
@ -3,6 +3,8 @@ use sample/mint
|
||||||
use sample/spend
|
use sample/spend
|
||||||
use aiken/builtin
|
use aiken/builtin
|
||||||
|
|
||||||
|
const something = 5
|
||||||
|
|
||||||
pub type Redeemer {
|
pub type Redeemer {
|
||||||
signer: ByteArray,
|
signer: ByteArray,
|
||||||
amount: Int,
|
amount: Int,
|
||||||
|
|
Loading…
Reference in New Issue