feat: complete language tour

This commit is contained in:
rvcas
2022-11-30 15:24:37 -05:00
committed by Lucas
parent 0823b78bf8
commit 34c8a58391
27 changed files with 1130 additions and 252 deletions

View File

@@ -398,6 +398,34 @@ pub fn expr_parser(
elems,
});
let bytearray = 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| expr::UntypedExpr::ByteArray {
location: span,
bytes,
});
let list_parser = just(Token::LeftSquare)
.ignore_then(r.clone().separated_by(just(Token::Comma)))
.then(choice((
@@ -505,7 +533,7 @@ pub fn expr_parser(
let assert_parser = just(Token::Assert)
.ignore_then(pattern_parser())
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
.then_ignore(just(Token::Is))
.then_ignore(just(Token::Equal))
.then(r.clone())
.map_with_span(
|((pattern, annotation), value), span| expr::UntypedExpr::Assignment {
@@ -520,7 +548,7 @@ pub fn expr_parser(
let check_parser = just(Token::Check)
.ignore_then(pattern_parser())
.then(just(Token::Colon).ignore_then(type_parser()).or_not())
.then_ignore(just(Token::Is))
.then_ignore(just(Token::Equal))
.then(r.clone())
.map_with_span(
|((pattern, annotation), value), span| expr::UntypedExpr::Assignment {
@@ -572,6 +600,7 @@ pub fn expr_parser(
var_parser,
todo_parser,
tuple,
bytearray,
list_parser,
anon_fn_parser,
block_parser,

View File

@@ -5,7 +5,7 @@ use miette::Diagnostic;
use crate::{ast::Span, parser::token::Token};
#[derive(Debug, Diagnostic, thiserror::Error)]
#[error("{}", .kind)]
#[error("{kind}")]
pub struct ParseError {
pub kind: ErrorKind,
#[label]
@@ -71,7 +71,7 @@ impl<T: Into<Pattern>> chumsky::Error<T> for ParseError {
pub enum ErrorKind {
#[error("unexpected end")]
UnexpectedEnd,
#[error("unexpected {0}")]
#[error("{0}")]
#[diagnostic(help("{}", .0.help().unwrap_or_else(|| Box::new(""))))]
Unexpected(Pattern),
#[error("unclosed {start}")]
@@ -87,22 +87,29 @@ pub enum ErrorKind {
#[derive(Debug, PartialEq, Eq, Hash, Diagnostic, thiserror::Error)]
pub enum Pattern {
#[error("{0:?}")]
#[error("Unexpected {0:?}")]
#[diagnostic(help("Try removing it"))]
Char(char),
#[error("{0}")]
#[diagnostic(help("try removing it"))]
#[error("Unexpected {0}")]
#[diagnostic(help("Try removing it"))]
Token(Token),
#[error("literal")]
#[error("Unexpected literal")]
#[diagnostic(help("Try removing it"))]
Literal,
#[error("type name")]
#[error("Unexpected type name")]
#[diagnostic(help("Try removing it"))]
TypeIdent,
#[error("indentifier")]
#[error("Unexpected indentifier")]
#[diagnostic(help("Try removing it"))]
TermIdent,
#[error("end of input")]
#[error("Unexpected end of input")]
End,
#[error("pattern")]
#[diagnostic(help("list spread in match can only have a discard or var"))]
#[error("Bad list spread pattern")]
#[diagnostic(help("List spread in matches can\nuse have a discard or var"))]
Match,
#[error("Bad byte literal")]
#[diagnostic(help("Bytes must be between 0-255"))]
Byte,
}
impl From<char> for Pattern {

View File

@@ -6,20 +6,18 @@ use crate::ast::{BinOp, Span, TodoKind};
use super::Type;
// use aiken/pub
// pub fn do_thing() { pub.other() }
#[derive(Debug, thiserror::Error, Diagnostic)]
pub enum Error {
#[error("duplicate argument {label}")]
#[error("Duplicate argument\n\n{label}")]
#[diagnostic(help("Try renaming it"))]
DuplicateArgument {
#[label]
location: Span,
label: String,
},
#[error("duplicate const {name}")]
#[error("Duplicate const\n\n{name}")]
#[diagnostic(help("Try renaming it"))]
DuplicateConstName {
#[label]
location: Span,
@@ -28,7 +26,8 @@ pub enum Error {
name: String,
},
#[error("duplicate import {name}")]
#[error("Duplicate import\n\n{name}")]
#[diagnostic(help("Try renaming it"))]
DuplicateImport {
#[label]
location: Span,
@@ -37,14 +36,16 @@ pub enum Error {
name: String,
},
#[error("duplicate name {label}")]
#[error("Duplicate field\n\n{label}")]
#[diagnostic(help("Try renaming it"))]
DuplicateField {
#[label]
location: Span,
label: String,
},
#[error("duplicate name {name}")]
#[error("Duplicate name\n\n{name}")]
#[diagnostic(help("Try renaming it"))]
DuplicateName {
#[label]
location: Span,
@@ -53,7 +54,8 @@ pub enum Error {
name: String,
},
#[error("duplicate type name {name}")]
#[error("Duplicate type name\n\n{name}")]
#[diagnostic(help("Try renaming it"))]
DuplicateTypeName {
#[label]
location: Span,
@@ -62,7 +64,7 @@ pub enum Error {
name: String,
},
#[error("incorrect arity expected {expected} but given {given}")]
#[error("Incorrect arity\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
IncorrectArity {
#[label]
location: Span,
@@ -71,7 +73,7 @@ pub enum Error {
labels: Vec<String>,
},
#[error("incorrect number of clause patterns expected {expected} but given {given}")]
#[error("Incorrect number of clause patterns\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
IncorrectNumClausePatterns {
#[label]
location: Span,
@@ -79,7 +81,7 @@ pub enum Error {
given: usize,
},
#[error("{name} has incorrect type arity expected {expected} but given {given}")]
#[error("Incorrect type arity for `{name}`\n\nExpected\n\n{expected}\n\nGiven\n\n{given}")]
IncorrectTypeArity {
#[label]
location: Span,
@@ -88,50 +90,50 @@ pub enum Error {
given: usize,
},
#[error("non-exhaustive pattern match")]
#[error("Non-exhaustive pattern match")]
NotExhaustivePatternMatch {
#[label]
location: Span,
unmatched: Vec<String>,
},
#[error("not a function")]
#[error("Not a function")]
NotFn {
#[label]
location: Span,
tipo: Arc<Type>,
},
#[error("{name} contains keyword {keyword}")]
#[error("Module\n\n{name}\n\ncontains keyword\n\n{keyword}")]
KeywordInModuleName { name: String, keyword: String },
#[error("clause guard {name} is not local")]
#[error("Clause guard {name} is not local")]
NonLocalClauseGuardVariable {
#[label]
location: Span,
name: String,
},
#[error("positional argument after labeled")]
#[error("Positional argument after labeled")]
PositionalArgumentAfterLabeled {
#[label]
location: Span,
},
#[error("private type leaked")]
#[error("Private type leaked")]
PrivateTypeLeak {
#[label]
location: Span,
leaked: Type,
},
#[error("record access unknown type")]
#[error("Record access unknown type")]
RecordAccessUnknownType {
#[label]
location: Span,
},
#[error("record update invalid constructor")]
#[error("Record update invalid constructor")]
RecordUpdateInvalidConstructor {
#[label]
location: Span,
@@ -140,27 +142,27 @@ pub enum Error {
#[error("{name} is a reserved module name")]
ReservedModuleName { name: String },
#[error("unexpected labeled argument {label}")]
#[error("Unexpected labeled argument\n\n{label}")]
UnexpectedLabeledArg {
#[label]
location: Span,
label: String,
},
#[error("unexpected type hole")]
#[error("Unexpected type hole")]
UnexpectedTypeHole {
#[label]
location: Span,
},
#[error("unknown labels")]
#[error("Unknown labels")]
UnknownLabels {
unknown: Vec<(String, Span)>,
valid: Vec<String>,
supplied: Vec<String>,
},
#[error("unknown module {name}")]
#[error("Unknown module\n\n{name}")]
UnknownModule {
#[label]
location: Span,
@@ -168,7 +170,7 @@ pub enum Error {
imported_modules: Vec<String>,
},
#[error("unknown module field {name} in module {module_name}")]
#[error("Unknown module field\n\n{name}\n\nin module\n\n{module_name}")]
UnknownModuleField {
location: Span,
name: String,
@@ -177,7 +179,7 @@ pub enum Error {
type_constructors: Vec<String>,
},
#[error("unknown module value {name}")]
#[error("Unknown module value\n\n{name}")]
UnknownModuleValue {
#[label]
location: Span,
@@ -186,7 +188,7 @@ pub enum Error {
value_constructors: Vec<String>,
},
#[error("unknown type {name} in module {module_name}")]
#[error("Unknown type\n\n{name}\n\nin module\n\n{module_name}")]
UnknownModuleType {
#[label]
location: Span,
@@ -195,7 +197,7 @@ pub enum Error {
type_constructors: Vec<String>,
},
#[error("unknown record field {label}")]
#[error("Unknown record field\n\n{label}")]
UnknownRecordField {
#[label]
location: Span,
@@ -205,7 +207,7 @@ pub enum Error {
situation: Option<UnknownRecordFieldSituation>,
},
#[error("unknown type {name}")]
#[error("Unknown type\n\n{name}")]
UnknownType {
#[label]
location: Span,
@@ -213,7 +215,7 @@ pub enum Error {
types: Vec<String>,
},
#[error("unknown variable {name}")]
#[error("Unknown variable\n\n{name}")]
UnknownVariable {
#[label]
location: Span,
@@ -221,14 +223,14 @@ pub enum Error {
variables: Vec<String>,
},
#[error("unnecessary spread operator")]
#[error("Unnecessary spread operator")]
UnnecessarySpreadOperator {
#[label]
location: Span,
arity: usize,
},
#[error("cannot update a type with multiple constructors")]
#[error("Cannot update a type with multiple constructors")]
UpdateMultiConstructorType {
#[label]
location: Span,

View File

@@ -12,30 +12,30 @@ use miette::{
#[allow(dead_code)]
#[derive(thiserror::Error)]
pub enum Error {
#[error("duplicate module {module}")]
#[error("Duplicate module\n\n{module}")]
DuplicateModule {
module: String,
first: PathBuf,
second: PathBuf,
},
#[error("file operation failed")]
#[error("File operation failed")]
FileIo { error: io::Error, path: PathBuf },
#[error("source code incorrectly formatted")]
#[error("Source code incorrectly formatted")]
Format { problem_files: Vec<Unformatted> },
#[error(transparent)]
StandardIo(#[from] io::Error),
#[error("cyclical module imports")]
#[error("Syclical module imports")]
ImportCycle { modules: Vec<String> },
/// Useful for returning many [`Error::Parse`] at once
#[error("a list of errors")]
#[error("A list of errors")]
List(Vec<Self>),
#[error("parsing")]
#[error("Parsing")]
Parse {
path: PathBuf,
@@ -47,7 +47,7 @@ pub enum Error {
error: Box<ParseError>,
},
#[error("type checking")]
#[error("Checking")]
Type {
path: PathBuf,
src: String,
@@ -56,7 +56,7 @@ pub enum Error {
error: tipo::error::Error,
},
#[error("validator functions must return Bool")]
#[error("Validator functions must return Bool")]
ValidatorMustReturnBool {
path: PathBuf,
src: String,
@@ -64,7 +64,7 @@ pub enum Error {
location: Span,
},
#[error("{name} requires at least {at_least} arguments")]
#[error("Validator\n\n{name}\n\nrequires at least {at_least} arguments")]
WrongValidatorArity {
name: String,
at_least: u8,
@@ -198,7 +198,7 @@ impl Diagnostic for Error {
Error::ImportCycle { .. } => Some(Box::new("aiken::module::cyclical")),
Error::List(_) => None,
Error::Parse { .. } => Some(Box::new("aiken::parser")),
Error::Type { .. } => Some(Box::new("aiken::typecheck")),
Error::Type { .. } => Some(Box::new("aiken::check")),
Error::StandardIo(_) => None,
Error::Format { .. } => None,
Error::ValidatorMustReturnBool { .. } => Some(Box::new("aiken::scripts")),