More updates, bump derivative version
This commit is contained in:
parent
12a7fe3e3e
commit
33573bf268
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -198,13 +198,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derivative"
|
name = "derivative"
|
||||||
version = "1.0.3"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "942ca430eef7a3806595a6737bc388bf51adb888d3fc0dd1b50f1c170167ee3a"
|
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.30",
|
"proc-macro2 1.0.30",
|
||||||
"quote 0.6.13",
|
"quote 1.0.10",
|
||||||
"syn 0.15.44",
|
"syn 1.0.80",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -10,7 +10,7 @@ take_mut = "0.2.2"
|
|||||||
failure = "0.1.5"
|
failure = "0.1.5"
|
||||||
ena = "0.11.0"
|
ena = "0.11.0"
|
||||||
stopwatch = "0.0.7"
|
stopwatch = "0.0.7"
|
||||||
derivative = "1.0.3"
|
derivative = "2.2.0"
|
||||||
colored = "1.8"
|
colored = "1.8"
|
||||||
radix_trie = "0.1.5"
|
radix_trie = "0.1.5"
|
||||||
assert_matches = "1.5"
|
assert_matches = "1.5"
|
||||||
|
@ -143,10 +143,15 @@ pub struct Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO I can probably get rid of TypeBody
|
//TODO I can probably get rid of TypeBody
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, Derivative, Clone)]
|
||||||
|
#[derivative(PartialEq)]
|
||||||
pub enum TypeBody {
|
pub enum TypeBody {
|
||||||
Variants(Vec<Variant>),
|
Variants(Vec<Variant>),
|
||||||
ImmediateRecord(ItemId, Vec<(Rc<String>, TypeIdentifier)>),
|
ImmediateRecord {
|
||||||
|
#[derivative(PartialEq = "ignore")]
|
||||||
|
id: ItemId,
|
||||||
|
fields: Vec<(Rc<String>, TypeIdentifier)>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Derivative, Clone)]
|
#[derive(Debug, Derivative, Clone)]
|
||||||
|
@ -129,7 +129,34 @@ fn statement(input: Span) -> ParseResult<Statement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn declaration(input: Span) -> ParseResult<Declaration> {
|
fn declaration(input: Span) -> ParseResult<Declaration> {
|
||||||
alt((binding, type_decl, module))(input)
|
alt((binding, type_decl, func, module))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn func(input: Span) -> ParseResult<Declaration> {
|
||||||
|
alt((func_decl, map(func_signature, Declaration::FuncSig)))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn func_decl(input: Span) -> ParseResult<Declaration> {
|
||||||
|
map(pair(func_signature, block), |(sig, decl)| Declaration::FuncDecl(sig, decl))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO handle operators
|
||||||
|
fn func_signature(input: Span) -> ParseResult<Signature> {
|
||||||
|
map(tuple((kw("fn"), tok(identifier), formal_params, opt(type_anno))), |(_, name, params, type_anno)| {
|
||||||
|
Signature { name: rc_string(name.fragment()), operator: false, params, type_anno }
|
||||||
|
})(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn formal_params(input: Span) -> ParseResult<Vec<FormalParam>> {
|
||||||
|
delimited(tok(char('(')), separated_list0(tok(char(',')), formal_param), tok(char(')')))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO support 256-limit
|
||||||
|
fn formal_param(input: Span) -> ParseResult<FormalParam> {
|
||||||
|
map(
|
||||||
|
tuple((tok(identifier), opt(type_anno), opt(preceded(tok(char('=')), expression)))),
|
||||||
|
|(name, anno, default)| FormalParam { name: rc_string(name.fragment()), anno, default },
|
||||||
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_decl(input: Span) -> ParseResult<Declaration> {
|
fn type_decl(input: Span) -> ParseResult<Declaration> {
|
||||||
@ -153,7 +180,7 @@ fn type_body(input: Span) -> ParseResult<TypeBody> {
|
|||||||
alt((
|
alt((
|
||||||
map(
|
map(
|
||||||
delimited(tok(char('{')), separated_list1(tok(char(',')), record_variant_item), tok(char('}'))),
|
delimited(tok(char('{')), separated_list1(tok(char(',')), record_variant_item), tok(char('}'))),
|
||||||
move |items| TypeBody::ImmediateRecord(id, items),
|
move |items| TypeBody::ImmediateRecord { id, fields: items },
|
||||||
),
|
),
|
||||||
map(separated_list0(tok(char('|')), variant_spec), TypeBody::Variants),
|
map(separated_list0(tok(char('|')), variant_spec), TypeBody::Variants),
|
||||||
))(input)
|
))(input)
|
||||||
|
@ -56,7 +56,6 @@ impl Parser {
|
|||||||
fn block_comb(&mut self, input: &str) -> Result<Block, ParseError> {
|
fn block_comb(&mut self, input: &str) -> Result<Block, ParseError> {
|
||||||
let id_store: IdStore<ASTItem> = IdStore::new();
|
let id_store: IdStore<ASTItem> = IdStore::new();
|
||||||
let span = Span::new_extra(input, Rc::new(RefCell::new(id_store)));
|
let span = Span::new_extra(input, Rc::new(RefCell::new(id_store)));
|
||||||
|
|
||||||
combinator::block(span).map_err(|err| convert_err(input, err)).map(|(_, output)| output)
|
combinator::block(span).map_err(|err| convert_err(input, err)).map(|(_, output)| output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ peg::parser! {
|
|||||||
singleton:type_singleton_name() { TypeIdentifier::Singleton(singleton) }
|
singleton:type_singleton_name() { TypeIdentifier::Singleton(singleton) }
|
||||||
|
|
||||||
rule type_body(parser: &mut Parser) -> TypeBody =
|
rule type_body(parser: &mut Parser) -> TypeBody =
|
||||||
"{" _ items:(record_variant_item() ** (__ "," __)) __ "}" { TypeBody::ImmediateRecord(parser.fresh(), items) } /
|
"{" _ items:(record_variant_item() ** (__ "," __)) __ "}" { TypeBody::ImmediateRecord { id: parser.fresh(), fields: items } } /
|
||||||
variants:(variant_spec(parser) ** (__ "|" __)) { TypeBody::Variants(variants) }
|
variants:(variant_spec(parser) ** (__ "|" __)) { TypeBody::Variants(variants) }
|
||||||
|
|
||||||
rule variant_spec(parser: &mut Parser) -> Variant =
|
rule variant_spec(parser: &mut Parser) -> Variant =
|
||||||
|
@ -609,7 +609,7 @@ fn type_annotations() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn type_declarations() {
|
fn type_declarations() {
|
||||||
use Declaration::TypeDecl;
|
use Declaration::TypeDecl;
|
||||||
assert_ast! {
|
assert_ast_comb! {
|
||||||
"type Alpha = Alpha", vec![
|
"type Alpha = Alpha", vec![
|
||||||
decl(TypeDecl {
|
decl(TypeDecl {
|
||||||
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
||||||
@ -625,7 +625,7 @@ fn type_declarations() {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
"type mut Kuah = Kuah",
|
"type mut Kuah = Kuah",
|
||||||
decl(TypeDecl {
|
decl(TypeDecl {
|
||||||
name: TypeSingletonName { name: rc("Kuah"), params: vec![] },
|
name: TypeSingletonName { name: rc("Kuah"), params: vec![] },
|
||||||
@ -638,7 +638,7 @@ fn type_declarations() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ast! {
|
assert_ast_comb! {
|
||||||
"type Alpha = Alpha { a: Int, b: Int }",
|
"type Alpha = Alpha { a: Int, b: Int }",
|
||||||
vec![decl(TypeDecl {
|
vec![decl(TypeDecl {
|
||||||
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
||||||
@ -656,20 +656,20 @@ fn type_declarations() {
|
|||||||
})]
|
})]
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_ast! {
|
assert_ast_comb! {
|
||||||
"type Alpha = { a: Int, b: Int }",
|
"type Alpha = { a: Int, b: Int }",
|
||||||
vec![decl(TypeDecl {
|
vec![decl(TypeDecl {
|
||||||
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
name: TypeSingletonName { name: rc("Alpha"), params: vec![] },
|
||||||
mutable: false,
|
mutable: false,
|
||||||
body: TypeBody::ImmediateRecord(Default::default(), vec![
|
body: TypeBody::ImmediateRecord { id: Default::default(), fields: vec![
|
||||||
(rc("a"), ty_simple("Int")),
|
(rc("a"), ty_simple("Int")),
|
||||||
(rc("b"), ty_simple("Int"))
|
(rc("b"), ty_simple("Int"))
|
||||||
])
|
]}
|
||||||
|
|
||||||
})]
|
})]
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
"type Option<T> = None | Some(T)",
|
"type Option<T> = None | Some(T)",
|
||||||
vec![decl(TypeDecl {
|
vec![decl(TypeDecl {
|
||||||
name: TypeSingletonName {
|
name: TypeSingletonName {
|
||||||
@ -782,7 +782,7 @@ fn bindings() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn functions() {
|
fn functions() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
"fn oi()",
|
"fn oi()",
|
||||||
vec![stmt(StatementKind::Declaration(Declaration::FuncSig(Signature {
|
vec![stmt(StatementKind::Declaration(Declaration::FuncSig(Signature {
|
||||||
name: rc("oi"),
|
name: rc("oi"),
|
||||||
@ -792,12 +792,12 @@ fn functions() {
|
|||||||
})))]
|
})))]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
"oi()",
|
"oi()",
|
||||||
vec![stmt(StatementKind::Expression(expr(Call { f: bx(expr(Value(qn!(oi)))), arguments: vec![] })))]
|
vec![stmt(StatementKind::Expression(expr(Call { f: bx(expr(Value(qn!(oi)))), arguments: vec![] })))]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_expr!(
|
assert_expr_comb!(
|
||||||
"oi(a, 2+2)",
|
"oi(a, 2+2)",
|
||||||
expr(Call {
|
expr(Call {
|
||||||
f: bx(expr(Value(qn!(oi)))),
|
f: bx(expr(Value(qn!(oi)))),
|
||||||
@ -809,7 +809,7 @@ fn functions() {
|
|||||||
);
|
);
|
||||||
assert_fail!("a(b,,c)","error at 1:5: expected one of \"(\", \".\", \"0b\", \"0x\", \"[\", \"\\\"\", \"_\", \"false\", \"for\", \"if\", \"true\", \"while\", ['+' | '-' | '!'], ['0' ..= '9'], ['a' ..= 'z' | 'A' ..= 'Z' | '_'], r#\"\\\"#");
|
assert_fail!("a(b,,c)","error at 1:5: expected one of \"(\", \".\", \"0b\", \"0x\", \"[\", \"\\\"\", \"_\", \"false\", \"for\", \"if\", \"true\", \"while\", ['+' | '-' | '!'], ['0' ..= '9'], ['a' ..= 'z' | 'A' ..= 'Z' | '_'], r#\"\\\"#");
|
||||||
|
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
"fn a(b, c: Int): Int",
|
"fn a(b, c: Int): Int",
|
||||||
vec![stmt(StatementKind::Declaration(Declaration::FuncSig(Signature {
|
vec![stmt(StatementKind::Declaration(Declaration::FuncSig(Signature {
|
||||||
name: rc("a"),
|
name: rc("a"),
|
||||||
@ -834,7 +834,7 @@ fn functions() {
|
|||||||
|
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
source,
|
source,
|
||||||
vec![fn_decl(
|
vec![fn_decl(
|
||||||
Signature { name: rc("some_function"), operator: false, type_anno: None, params: vec![] },
|
Signature { name: rc("some_function"), operator: false, type_anno: None, params: vec![] },
|
||||||
@ -874,7 +874,7 @@ fn functions_with_different_whitespace() {
|
|||||||
"#;
|
"#;
|
||||||
|
|
||||||
for item in [a, b, c].iter() {
|
for item in [a, b, c].iter() {
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
item,
|
item,
|
||||||
vec![fn_decl(
|
vec![fn_decl(
|
||||||
Signature {
|
Signature {
|
||||||
@ -897,7 +897,7 @@ fn functions_with_different_whitespace() {
|
|||||||
fn functions_with_default_args() {
|
fn functions_with_default_args() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_ast!(
|
assert_ast_comb!(
|
||||||
"fn func(x: Int, y: Int = 4) { }",
|
"fn func(x: Int, y: Int = 4) { }",
|
||||||
vec![fn_decl(
|
vec![fn_decl(
|
||||||
Signature {
|
Signature {
|
||||||
|
@ -194,7 +194,7 @@ impl<'a> SymbolTablePopulator<'a> {
|
|||||||
) -> Vec<SymbolError> {
|
) -> Vec<SymbolError> {
|
||||||
let (variants, immediate_variant) = match type_body {
|
let (variants, immediate_variant) = match type_body {
|
||||||
TypeBody::Variants(variants) => (variants.clone(), false),
|
TypeBody::Variants(variants) => (variants.clone(), false),
|
||||||
TypeBody::ImmediateRecord(id, fields) => (
|
TypeBody::ImmediateRecord { id, fields } => (
|
||||||
vec![Variant {
|
vec![Variant {
|
||||||
id: *id,
|
id: *id,
|
||||||
name: type_name.name.clone(),
|
name: type_name.name.clone(),
|
||||||
|
Loading…
Reference in New Issue
Block a user