2021-11-03 20:19:55 -07:00
|
|
|
use std::rc::Rc;
|
|
|
|
|
2021-11-13 14:22:34 -08:00
|
|
|
//TODO make use of the format_parse_error function
|
|
|
|
//use crate::error::{SchalaError, format_parse_error};
|
2021-11-13 22:38:57 -08:00
|
|
|
use crate::{
|
|
|
|
ast::*,
|
|
|
|
identifier::{Id, IdStore},
|
|
|
|
parsing::ParseError,
|
|
|
|
};
|
2021-11-03 23:57:22 -07:00
|
|
|
|
2021-11-07 01:30:26 -08:00
|
|
|
fn rc_string(s: &str) -> Rc<String> {
|
|
|
|
Rc::new(s.to_string())
|
|
|
|
}
|
|
|
|
|
2021-11-13 14:22:34 -08:00
|
|
|
pub struct Parser {
|
|
|
|
id_store: IdStore<ASTItem>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Parser {
|
|
|
|
pub(crate) fn new() -> Self {
|
|
|
|
Self { id_store: IdStore::new() }
|
|
|
|
}
|
|
|
|
|
2021-11-14 03:07:58 -08:00
|
|
|
pub(crate) fn parse(&mut self, input: &str) -> Result<AST, ParseError> {
|
2021-11-14 02:15:08 -08:00
|
|
|
use peg::str::LineCol;
|
|
|
|
|
|
|
|
schala_parser::program(input, self).map_err(|err: peg::error::ParseError<LineCol>| {
|
2021-11-13 14:22:34 -08:00
|
|
|
let msg = err.to_string();
|
2021-11-14 03:27:30 -08:00
|
|
|
ParseError { msg, location: err.location.offset.into() }
|
2021-11-13 14:22:34 -08:00
|
|
|
})
|
|
|
|
}
|
2021-11-13 22:38:57 -08:00
|
|
|
|
|
|
|
fn fresh(&mut self) -> Id<ASTItem> {
|
|
|
|
self.id_store.fresh()
|
|
|
|
}
|
2021-11-13 14:22:34 -08:00
|
|
|
}
|
|
|
|
|
2021-11-12 21:41:15 -08:00
|
|
|
enum ExtendedPart<'a> {
|
|
|
|
Index(Vec<Expression>),
|
|
|
|
Accessor(&'a str),
|
|
|
|
Call(Vec<InvocationArgument>),
|
|
|
|
}
|
|
|
|
|
2021-11-03 16:27:42 -07:00
|
|
|
peg::parser! {
|
2021-11-03 20:19:55 -07:00
|
|
|
pub grammar schala_parser() for str {
|
2021-11-03 18:01:23 -07:00
|
|
|
|
2021-11-13 01:41:17 -08:00
|
|
|
rule whitespace() = [' ' | '\t' ]
|
|
|
|
rule whitespace_or_newline() = [' ' | '\t' | '\n' ]
|
2021-11-03 23:57:22 -07:00
|
|
|
|
2021-11-13 13:18:02 -08:00
|
|
|
rule _ = quiet!{ (block_comment() / line_comment() / whitespace())* }
|
2021-11-03 23:57:22 -07:00
|
|
|
|
2021-11-13 13:18:02 -08:00
|
|
|
rule __ = quiet!{ (block_comment() / line_comment() / whitespace_or_newline())* }
|
2021-11-13 01:41:17 -08:00
|
|
|
|
|
|
|
rule block_comment() = "/*" (block_comment() / !"*/" [_])* "*/"
|
2021-11-13 13:18:02 -08:00
|
|
|
rule line_comment() = "//" (!['\n'] [_])* &"\n"
|
|
|
|
|
2021-11-07 03:13:35 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
pub rule program(parser: &mut Parser) -> AST =
|
2021-11-14 00:34:21 -08:00
|
|
|
__ statements:(statement(parser) ** (delimiter()+) ) __ { AST { id: parser.fresh(), statements: statements.into() } }
|
2021-11-03 18:01:23 -07:00
|
|
|
|
2021-11-05 12:52:41 -07:00
|
|
|
rule delimiter() = (";" / "\n")+
|
2021-11-03 18:01:23 -07:00
|
|
|
|
2021-11-06 20:33:33 -07:00
|
|
|
//Note - this is a hack, ideally the rule `rule block() -> Block = "{" _ items:(statement() **
|
|
|
|
//delimiter()) _ "}" { items.into() }` would've worked, but it doesn't.
|
2021-11-14 00:34:21 -08:00
|
|
|
pub rule block(parser: &mut Parser) -> Block =
|
|
|
|
"{" __ items:block_item(parser)* __ "}" { items.into() } /
|
|
|
|
"{" __ stmt:statement(parser) __ "}" { vec![stmt].into() }
|
2021-11-06 20:33:33 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule block_item(parser: &mut Parser) -> Statement =
|
2021-11-14 00:34:21 -08:00
|
|
|
_ stmt:statement(parser) _ delimiter()+ { stmt }
|
2021-11-03 18:01:23 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule statement(parser: &mut Parser) -> Statement =
|
|
|
|
_ pos:position!() kind:statement_kind(parser) _ { Statement { id: parser.fresh(), location: pos.into(), kind } }
|
2021-11-07 03:13:35 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule statement_kind(parser: &mut Parser) -> StatementKind =
|
|
|
|
__ import:import(parser) { StatementKind::Import(import) } /
|
|
|
|
__ decl:declaration(parser) { StatementKind::Declaration(decl) } /
|
|
|
|
__ flow:flow(parser) { StatementKind::Flow(flow) } /
|
|
|
|
__ expr:expression(parser) { StatementKind::Expression(expr) }
|
2021-11-07 01:30:26 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule flow(parser: &mut Parser) -> FlowControl =
|
2021-11-12 00:27:06 -08:00
|
|
|
"continue" { FlowControl::Continue } /
|
|
|
|
"break" { FlowControl::Break } /
|
2021-11-13 22:38:57 -08:00
|
|
|
"return" _ expr:expression(parser)? { FlowControl::Return(expr) }
|
2021-11-12 00:27:06 -08:00
|
|
|
|
2021-11-14 03:49:57 -08:00
|
|
|
//TODO add the ability to rename and exclude imports
|
2021-11-13 22:38:57 -08:00
|
|
|
rule import(parser: &mut Parser) -> ImportSpecifier =
|
2021-11-12 00:06:42 -08:00
|
|
|
"import" _ path_components:path_components() suffix:import_suffix()? {
|
|
|
|
ImportSpecifier {
|
2021-11-13 22:38:57 -08:00
|
|
|
id: parser.fresh(),
|
2021-11-12 00:06:42 -08:00
|
|
|
path_components,
|
2021-11-14 03:27:30 -08:00
|
|
|
imported_names: suffix.unwrap_or(ImportedNames::LastOfPath)
|
2021-11-12 00:06:42 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rule path_components() -> Vec<Rc<String>> =
|
|
|
|
"::"? name:identifier() rest:path_component()* {
|
|
|
|
let mut items = vec![rc_string(name)];
|
2021-11-14 03:27:30 -08:00
|
|
|
items.extend(rest.into_iter().map(rc_string));
|
2021-11-12 00:06:42 -08:00
|
|
|
items
|
|
|
|
}
|
|
|
|
|
|
|
|
rule path_component() -> &'input str = "::" ident:identifier() { ident }
|
|
|
|
|
|
|
|
rule import_suffix() -> ImportedNames =
|
|
|
|
"::*" { ImportedNames::All } /
|
|
|
|
"::{" __ names:(identifier() ** (_ "," _)) __ "}" { ImportedNames::List(names.into_iter().map(rc_string).collect()) }
|
|
|
|
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule declaration(parser: &mut Parser) -> Declaration =
|
2021-11-14 00:34:21 -08:00
|
|
|
binding(parser) / type_decl(parser) / annotation(parser) / func(parser) / interface(parser) /
|
2021-11-13 22:38:57 -08:00
|
|
|
implementation(parser) / module(parser)
|
2021-11-11 22:00:04 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule module(parser: &mut Parser) -> Declaration =
|
|
|
|
"module" _ name:identifier() _ items:block(parser) { Declaration::Module { name: rc_string(name), items } }
|
2021-11-11 22:00:04 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule implementation(parser: &mut Parser) -> Declaration =
|
|
|
|
"impl" _ interface:type_singleton_name() _ "for" _ type_name:type_identifier() _ block:decl_block(parser) {
|
2021-11-11 22:00:04 -08:00
|
|
|
Declaration::Impl { type_name, interface_name: Some(interface), block }
|
|
|
|
|
|
|
|
} /
|
2021-11-13 22:38:57 -08:00
|
|
|
"impl" _ type_name:type_identifier() _ block:decl_block(parser) {
|
2021-11-11 22:00:04 -08:00
|
|
|
Declaration::Impl { type_name, interface_name: None, block }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule decl_block(parser: &mut Parser) -> Vec<Declaration> =
|
|
|
|
"{" __ decls:(func_declaration(parser) ** (delimiter()+)) __ "}" { decls }
|
2021-11-11 22:00:04 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule interface(parser: &mut Parser) -> Declaration =
|
|
|
|
"interface" _ name:identifier() _ signatures:signature_block(parser) { Declaration::Interface { name: rc_string(name), signatures } }
|
2021-11-11 22:00:04 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule signature_block(parser: &mut Parser) -> Vec<Signature> =
|
|
|
|
"{" __ signatures:(func_signature(parser) ** (delimiter()+)) __ "}" { signatures }
|
2021-11-07 03:13:35 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule func(parser: &mut Parser) -> Declaration =
|
|
|
|
decl:func_declaration(parser) { decl } /
|
|
|
|
sig:func_signature(parser) { Declaration::FuncSig(sig) }
|
2021-11-07 03:13:35 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule func_declaration(parser: &mut Parser) -> Declaration =
|
|
|
|
_ sig:func_signature(parser) __ body:block(parser) { Declaration::FuncDecl(sig, body) }
|
2021-11-11 22:00:04 -08:00
|
|
|
|
2021-11-07 03:13:35 -08:00
|
|
|
//TODO handle operators
|
2021-11-13 22:38:57 -08:00
|
|
|
rule func_signature(parser: &mut Parser) -> Signature =
|
|
|
|
_ "fn" _ name:identifier() "(" _ params:formal_params(parser) _ ")" _ type_anno:type_anno()? { Signature {
|
2021-11-07 03:13:35 -08:00
|
|
|
name: rc_string(name), operator: false, params, type_anno
|
|
|
|
} }
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule formal_params(parser: &mut Parser) -> Vec<FormalParam> =
|
|
|
|
params:(formal_param(parser) ** (_ "," _)) {? if params.len() < 256 { Ok(params) } else {
|
2021-11-07 03:13:35 -08:00
|
|
|
Err("function-too-long") }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule formal_param(parser: &mut Parser) -> FormalParam =
|
|
|
|
name:identifier() _ anno:type_anno()? _ "=" expr:expression(parser) { FormalParam { name: rc_string(name),
|
2021-11-07 03:13:35 -08:00
|
|
|
default: Some(expr), anno } } /
|
|
|
|
name:identifier() _ anno:type_anno()? { FormalParam { name: rc_string(name), default: None, anno } }
|
|
|
|
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule annotation(parser: &mut Parser) -> Declaration =
|
|
|
|
"@" name:identifier() args:annotation_args(parser)? delimiter()+ _ inner:statement(parser) { Declaration::Annotation {
|
2021-11-07 03:13:35 -08:00
|
|
|
name: rc_string(name), arguments: if let Some(args) = args { args } else { vec![] }, inner: Box::new(inner) }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule annotation_args(parser: &mut Parser) -> Vec<Expression> =
|
|
|
|
"(" _ args:(expression(parser) ** (_ "," _)) _ ")" { args }
|
2021-11-07 03:13:35 -08:00
|
|
|
|
2021-11-07 01:30:26 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule binding(parser: &mut Parser) -> Declaration =
|
|
|
|
"let" _ mutable:"mut"? _ ident:identifier() _ type_anno:type_anno()? _ "=" _ expr:expression(parser) {
|
2021-11-07 01:30:26 -08:00
|
|
|
Declaration::Binding { name: Rc::new(ident.to_string()), constant: mutable.is_none(),
|
|
|
|
type_anno, expr }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-14 00:34:21 -08:00
|
|
|
rule type_decl(parser: &mut Parser) -> Declaration =
|
2021-11-07 01:30:26 -08:00
|
|
|
"type" _ "alias" _ alias:type_alias() { alias } /
|
2021-11-14 00:34:21 -08:00
|
|
|
"type" _ mutable:"mut"? _ name:type_singleton_name() _ "=" _ body:type_body(parser) {
|
2021-11-07 01:30:26 -08:00
|
|
|
Declaration::TypeDecl { name, body, mutable: mutable.is_some() }
|
|
|
|
}
|
|
|
|
|
|
|
|
rule type_singleton_name() -> TypeSingletonName =
|
2021-11-14 00:34:21 -08:00
|
|
|
name:identifier() params:type_params()? { TypeSingletonName {
|
2021-11-14 03:07:58 -08:00
|
|
|
name: rc_string(name), params: if let Some(params) = params { params } else { vec![] }
|
2021-11-14 00:34:21 -08:00
|
|
|
} }
|
2021-11-07 01:30:26 -08:00
|
|
|
|
|
|
|
rule type_params() -> Vec<TypeIdentifier> =
|
|
|
|
"<" _ idents:(type_identifier() ** (_ "," _)) _ ">" { idents }
|
|
|
|
|
|
|
|
rule type_identifier() -> TypeIdentifier =
|
|
|
|
"(" _ items:(type_identifier() ** (_ "," _)) _ ")" { TypeIdentifier::Tuple(items) } /
|
|
|
|
singleton:type_singleton_name() { TypeIdentifier::Singleton(singleton) }
|
|
|
|
|
2021-11-14 00:34:21 -08:00
|
|
|
rule type_body(parser: &mut Parser) -> TypeBody =
|
|
|
|
"{" _ items:(record_variant_item() ** (__ "," __)) __ "}" { TypeBody::ImmediateRecord(parser.fresh(), items) } /
|
|
|
|
variants:(variant_spec(parser) ** (__ "|" __)) { TypeBody::Variants(variants) }
|
2021-11-07 01:30:26 -08:00
|
|
|
|
2021-11-14 00:34:21 -08:00
|
|
|
rule variant_spec(parser: &mut Parser) -> Variant =
|
|
|
|
name:identifier() __ "{" __ typed_identifier_list:(record_variant_item() ** (__ "," __)) __ ","? __ "}" { Variant {
|
|
|
|
id: parser.fresh(), name: rc_string(name), kind: VariantKind::Record(typed_identifier_list)
|
2021-11-07 01:30:26 -08:00
|
|
|
} } /
|
2021-11-14 00:34:21 -08:00
|
|
|
name:identifier() "(" tuple_members:(type_identifier() ++ (__ "," __)) ")" { Variant {
|
|
|
|
id: parser.fresh(), name: rc_string(name), kind: VariantKind::TupleStruct(tuple_members) } } /
|
|
|
|
name:identifier() { Variant { id: parser.fresh(), name: rc_string(name), kind: VariantKind::UnitStruct } }
|
2021-11-07 01:30:26 -08:00
|
|
|
|
|
|
|
rule record_variant_item() -> (Rc<String>, TypeIdentifier) =
|
|
|
|
name:identifier() _ ":" _ ty:type_identifier() { (rc_string(name), ty) }
|
|
|
|
|
|
|
|
rule type_alias() -> Declaration =
|
|
|
|
alias:identifier() _ "=" _ name:identifier() { Declaration::TypeAlias { alias: rc_string(alias), original: rc_string(name), } }
|
|
|
|
|
|
|
|
rule type_anno() -> TypeIdentifier =
|
2021-11-11 19:01:16 -08:00
|
|
|
":" _ identifier:type_identifier() { identifier }
|
2021-11-07 01:30:26 -08:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
pub rule expression(parser: &mut Parser) -> Expression =
|
|
|
|
__ kind:expression_kind(true, parser) _ type_anno:type_anno()? { Expression { id: parser.fresh(), type_anno, kind } }
|
2021-11-05 12:52:41 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule expression_no_struct(parser: &mut Parser) -> Expression =
|
2021-11-14 03:27:30 -08:00
|
|
|
__ kind:expression_kind(false, parser) { Expression { id: parser.fresh(), type_anno: None, kind } }
|
2021-11-03 23:57:22 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule expression_kind(struct_ok: bool, parser: &mut Parser) -> ExpressionKind =
|
|
|
|
precedence_expr(struct_ok, parser)
|
2021-11-05 03:08:25 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule precedence_expr(struct_ok: bool, parser: &mut Parser) -> ExpressionKind =
|
|
|
|
first:prefix_expr(struct_ok, parser) _ next:(precedence_continuation(struct_ok, parser))* {
|
2021-11-04 21:11:19 -07:00
|
|
|
let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect();
|
2021-11-14 00:34:21 -08:00
|
|
|
BinopSequence { first, next }.do_precedence(parser)
|
2021-11-04 21:11:19 -07:00
|
|
|
}
|
2021-11-03 23:57:22 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule precedence_continuation(struct_ok: bool, parser: &mut Parser) -> (&'input str, ExpressionKind) =
|
|
|
|
op:operator() _ expr:prefix_expr(struct_ok, parser) _ { (op, expr) }
|
2021-11-03 18:01:23 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule prefix_expr(struct_ok: bool, parser: &mut Parser) -> ExpressionKind =
|
|
|
|
prefix:prefix()? expr:extended_expr(struct_ok, parser) {
|
2021-11-04 21:11:19 -07:00
|
|
|
if let Some(p) = prefix {
|
2021-11-13 22:38:57 -08:00
|
|
|
let expr = Expression::new(parser.fresh(), expr);
|
2021-11-04 21:11:19 -07:00
|
|
|
let prefix = PrefixOp::from_sigil(p);
|
|
|
|
ExpressionKind::PrefixExp(prefix, Box::new(expr))
|
|
|
|
} else {
|
|
|
|
expr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-05 03:08:25 -07:00
|
|
|
|
2021-11-04 21:11:19 -07:00
|
|
|
rule prefix() -> &'input str =
|
|
|
|
$(['+' | '-' | '!' ])
|
|
|
|
|
|
|
|
//TODO make the definition of operators more complex
|
2021-11-03 22:27:14 -07:00
|
|
|
rule operator() -> &'input str =
|
2021-11-13 01:41:17 -08:00
|
|
|
quiet!{!"*/" s:$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ ) { s } } /
|
2021-11-04 21:11:19 -07:00
|
|
|
expected!("operator")
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule extended_expr(struct_ok: bool, parser: &mut Parser) -> ExpressionKind =
|
|
|
|
primary:primary(struct_ok, parser) parts:(extended_expr_part(parser)*) {
|
2021-11-14 00:34:21 -08:00
|
|
|
let mut expression = Expression::new(parser.fresh(), primary);
|
2021-11-12 21:41:15 -08:00
|
|
|
for part in parts.into_iter() {
|
|
|
|
let kind = match part {
|
|
|
|
ExtendedPart::Index(indexers) => {
|
|
|
|
ExpressionKind::Index { indexee: Box::new(expression), indexers }
|
|
|
|
},
|
|
|
|
ExtendedPart::Accessor(name) => {
|
|
|
|
let name = rc_string(name);
|
|
|
|
ExpressionKind::Access { name, expr: Box::new(expression) }
|
|
|
|
},
|
|
|
|
ExtendedPart::Call(arguments) => {
|
|
|
|
ExpressionKind::Call { f: Box::new(expression), arguments }
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
expression = Expression::new(parser.fresh(), kind);
|
2021-11-04 22:31:29 -07:00
|
|
|
}
|
|
|
|
|
2021-11-12 21:41:15 -08:00
|
|
|
expression.kind
|
|
|
|
}
|
2021-11-05 03:08:25 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule extended_expr_part(parser: &mut Parser) -> ExtendedPart<'input> =
|
|
|
|
indexers:index_part(parser) { ExtendedPart::Index(indexers) } /
|
|
|
|
arguments:call_part(parser) { ExtendedPart::Call(arguments) } /
|
2021-11-12 21:41:15 -08:00
|
|
|
"." name:identifier() { ExtendedPart::Accessor(name) }
|
2021-11-05 03:08:25 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule index_part(parser: &mut Parser) -> Vec<Expression> =
|
|
|
|
"[" indexers:(expression(parser) ++ ",") "]" { indexers }
|
2021-11-04 22:31:29 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule call_part(parser: &mut Parser) -> Vec<InvocationArgument> =
|
|
|
|
"(" arguments:(invocation_argument(parser) ** ",") ")" { arguments }
|
2021-11-04 22:31:29 -07:00
|
|
|
|
|
|
|
//TODO this shouldn't be an expression b/c type annotations disallowed here
|
2021-11-13 22:38:57 -08:00
|
|
|
rule invocation_argument(parser: &mut Parser) -> InvocationArgument =
|
2021-11-04 22:31:29 -07:00
|
|
|
_ "_" _ { InvocationArgument::Ignored } /
|
2021-11-13 22:38:57 -08:00
|
|
|
_ ident:identifier() _ "=" _ expr:expression(parser) { InvocationArgument::Keyword {
|
2021-11-04 22:31:29 -07:00
|
|
|
name: Rc::new(ident.to_string()),
|
|
|
|
expr
|
|
|
|
} } /
|
2021-11-13 22:38:57 -08:00
|
|
|
_ expr:expression(parser) _ { InvocationArgument::Positional(expr) }
|
2021-11-04 22:31:29 -07:00
|
|
|
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule primary(struct_ok: bool, parser: &mut Parser) -> ExpressionKind =
|
|
|
|
while_expr(parser) / for_expr(parser) / float_literal() / nat_literal() / bool_literal() /
|
|
|
|
string_literal() / paren_expr(parser) /
|
|
|
|
list_expr(parser) / if_expr(parser) / lambda_expr(parser) /
|
|
|
|
item:named_struct(parser) {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } /
|
|
|
|
identifier_expr(parser)
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule lambda_expr(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
r#"\"# __ "(" _ params:formal_params(parser) _ ")" _ type_anno:(type_anno()?) _ body:block(parser) {
|
2021-11-11 02:42:14 -08:00
|
|
|
ExpressionKind::Lambda { params, type_anno, body }
|
|
|
|
} /
|
2021-11-13 22:38:57 -08:00
|
|
|
r#"\"# param:formal_param(parser) _ type_anno:(type_anno()?) _ body:block(parser) {
|
2021-11-11 02:42:14 -08:00
|
|
|
ExpressionKind::Lambda { params: vec![param], type_anno, body }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule for_expr(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
"for" _ enumerators:for_enumerators(parser) _ body:for_body(parser) {
|
2021-11-05 12:52:41 -07:00
|
|
|
ExpressionKind::ForExpression { enumerators, body }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule for_enumerators(parser: &mut Parser) -> Vec<Enumerator> =
|
|
|
|
"{" _ enumerators:(enumerator(parser) ++ ",") _ "}" { enumerators } /
|
|
|
|
enumerator:enumerator(parser) { vec![enumerator] }
|
2021-11-05 12:52:41 -07:00
|
|
|
|
|
|
|
//TODO add guards, etc.
|
2021-11-13 22:38:57 -08:00
|
|
|
rule enumerator(parser: &mut Parser) -> Enumerator =
|
|
|
|
ident:identifier() _ "<-" _ generator:expression_no_struct(parser) {
|
2021-11-05 12:52:41 -07:00
|
|
|
Enumerator { id: Rc::new(ident.to_string()), generator }
|
|
|
|
} /
|
|
|
|
//TODO need to distinguish these two cases in AST
|
2021-11-13 22:38:57 -08:00
|
|
|
ident:identifier() _ "=" _ generator:expression_no_struct(parser) {
|
2021-11-05 12:52:41 -07:00
|
|
|
Enumerator { id: Rc::new(ident.to_string()), generator }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule for_body(parser: &mut Parser) -> Box<ForBody> =
|
|
|
|
"return" _ expr:expression(parser) { Box::new(ForBody::MonadicReturn(expr)) } /
|
|
|
|
body:block(parser) { Box::new(ForBody::StatementBlock(body)) }
|
2021-11-05 12:52:41 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule while_expr(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
"while" _ cond:expression_kind(false, parser)? _ body:block(parser) {
|
2021-11-05 03:08:25 -07:00
|
|
|
ExpressionKind::WhileExpression {
|
2021-11-14 00:34:21 -08:00
|
|
|
condition: cond.map(|kind| Box::new(Expression::new(parser.fresh(), kind))),
|
2021-11-05 03:08:25 -07:00
|
|
|
body,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule identifier_expr(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
qn:qualified_identifier(parser) { ExpressionKind::Value(qn) }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule named_struct(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
name:qualified_identifier(parser) _ fields:record_block(parser) {
|
2021-11-04 21:11:19 -07:00
|
|
|
ExpressionKind::NamedStruct {
|
|
|
|
name,
|
|
|
|
fields: fields.into_iter().map(|(n, exp)| (Rc::new(n.to_string()), exp)).collect(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-14 03:49:57 -08:00
|
|
|
//TODO support anonymous structs and Elm-style update syntax for structs
|
2021-11-13 22:38:57 -08:00
|
|
|
rule record_block(parser: &mut Parser) -> Vec<(&'input str, Expression)> =
|
|
|
|
"{" _ entries:(record_entry(parser) ** ",") _ "}" { entries }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule record_entry(parser: &mut Parser) -> (&'input str, Expression) =
|
|
|
|
_ name:identifier() _ ":" _ expr:expression(parser) _ { (name, expr) }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule qualified_identifier(parser: &mut Parser) -> QualifiedName =
|
|
|
|
names:(identifier() ++ "::") { QualifiedName { id: parser.fresh(), components: names.into_iter().map(|name| Rc::new(name.to_string())).collect() } }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
|
|
|
//TODO improve the definition of identifiers
|
|
|
|
rule identifier() -> &'input str =
|
2021-11-14 00:34:21 -08:00
|
|
|
!(reserved() !(ident_continuation())) text:$(['a'..='z' | 'A'..='Z' | '_'] ident_continuation()*) { text }
|
|
|
|
|
|
|
|
rule ident_continuation() -> &'input str =
|
|
|
|
text:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_'])
|
2021-11-12 00:32:11 -08:00
|
|
|
|
2021-11-13 13:23:21 -08:00
|
|
|
rule reserved() = "if" / "then" / "else" / "is" / "fn" / "for" / "while" / "let" / "in" / "mut" / "return" /
|
|
|
|
"break" / "alias" / "type" / "self" / "Self" / "interface" / "impl" / "true" / "false" / "module" / "import"
|
2021-11-04 21:11:19 -07:00
|
|
|
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule if_expr(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
"if" _ discriminator:(expression(parser)?) _ body:if_expr_body(parser) {
|
2021-11-04 21:11:19 -07:00
|
|
|
ExpressionKind::IfExpression {
|
|
|
|
discriminator: discriminator.map(Box::new),
|
|
|
|
body: Box::new(body),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule if_expr_body(parser: &mut Parser) -> IfExpressionBody =
|
|
|
|
cond_block(parser) / simple_pattern_match(parser) / simple_conditional(parser)
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule simple_conditional(parser: &mut Parser) -> IfExpressionBody =
|
|
|
|
"then" _ then_case:expr_or_block(parser) _ else_case:else_case(parser) {
|
2021-11-04 21:11:19 -07:00
|
|
|
IfExpressionBody::SimpleConditional { then_case, else_case }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule simple_pattern_match(parser: &mut Parser) -> IfExpressionBody =
|
|
|
|
"is" _ pattern:pattern(parser) _ "then" _ then_case:expr_or_block(parser) _ else_case:else_case(parser) {
|
2021-11-04 21:11:19 -07:00
|
|
|
IfExpressionBody::SimplePatternMatch { pattern, then_case, else_case }
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule cond_block(parser: &mut Parser) -> IfExpressionBody =
|
|
|
|
"{" __ cond_arms:(cond_arm(parser) ++ (delimiter()+)) __ "}" { IfExpressionBody::CondList(cond_arms) }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule cond_arm(parser: &mut Parser) -> ConditionArm =
|
|
|
|
_ "else" _ body:expr_or_block(parser) { ConditionArm { condition: Condition::Else, guard: None, body } } /
|
|
|
|
_ condition:condition(parser) _ guard:condition_guard(parser) _ "then" _ body:expr_or_block(parser)
|
2021-11-04 21:11:19 -07:00
|
|
|
{ ConditionArm { condition, guard, body } }
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule condition(parser: &mut Parser) -> Condition =
|
|
|
|
"is" _ pat:pattern(parser) { Condition::Pattern(pat) } /
|
|
|
|
op:operator() _ expr:expression(parser) { Condition::TruncatedOp(BinOp::from_sigil(op), expr) }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule condition_guard(parser: &mut Parser) -> Option<Expression> =
|
|
|
|
("if" _ expr:expression(parser) { expr } )?
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule expr_or_block(parser: &mut Parser) -> Block = block(parser) / pos:position!() ex:expression(parser) {
|
2021-11-04 21:11:19 -07:00
|
|
|
Statement {
|
2021-11-13 22:38:57 -08:00
|
|
|
id: parser.fresh() , location: pos.into(),
|
2021-11-04 21:11:19 -07:00
|
|
|
kind: StatementKind::Expression(ex)
|
|
|
|
}.into()
|
|
|
|
}
|
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule else_case(parser: &mut Parser) -> Option<Block> =
|
|
|
|
("else" _ eorb:expr_or_block(parser) { eorb })?
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule pattern(parser: &mut Parser) -> Pattern =
|
|
|
|
"(" _ variants:(pattern(parser) ++ ",") _ ")" { Pattern::TuplePattern(variants) } /
|
|
|
|
_ pat:simple_pattern(parser) { pat }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule simple_pattern(parser: &mut Parser) -> Pattern =
|
2021-11-04 21:11:19 -07:00
|
|
|
pattern_literal() /
|
2021-11-13 22:38:57 -08:00
|
|
|
qn:qualified_identifier(parser) "(" members:(pattern(parser) ** ",") ")" {
|
2021-11-04 21:11:19 -07:00
|
|
|
Pattern::TupleStruct(qn, members)
|
|
|
|
} /
|
2021-11-13 22:38:57 -08:00
|
|
|
qn:qualified_identifier(parser) _ "{" _ items:(record_pattern_entry(parser) ** ",") "}" _ {
|
2021-11-04 21:11:19 -07:00
|
|
|
let items = items.into_iter().map(|(name, pat)| (Rc::new(name.to_string()), pat)).collect();
|
|
|
|
Pattern::Record(qn, items)
|
|
|
|
} /
|
2021-11-13 22:38:57 -08:00
|
|
|
qn:qualified_identifier(parser) { Pattern::VarOrName(qn) }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule record_pattern_entry(parser: &mut Parser) -> (&'input str, Pattern) =
|
|
|
|
_ name:identifier() _ ":" _ pat:pattern(parser) _ { (name, pat) } /
|
2021-11-04 21:11:19 -07:00
|
|
|
_ name:identifier() _ {
|
|
|
|
let qn = QualifiedName {
|
2021-11-14 00:34:21 -08:00
|
|
|
id: parser.fresh(),
|
2021-11-04 21:11:19 -07:00
|
|
|
components: vec![Rc::new(name.to_string())],
|
|
|
|
};
|
|
|
|
(name, Pattern::VarOrName(qn))
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rule pattern_literal() -> Pattern =
|
|
|
|
"true" { Pattern::Literal(PatternLiteral::BoolPattern(true)) } /
|
|
|
|
"false" { Pattern::Literal(PatternLiteral::BoolPattern(false)) } /
|
|
|
|
s:bare_string_literal() { Pattern::Literal(PatternLiteral::StringPattern(Rc::new(s.to_string()))) } /
|
2021-11-11 22:24:35 -08:00
|
|
|
sign:("-"?) num:(float_literal() / nat_literal()) {
|
2021-11-04 21:11:19 -07:00
|
|
|
let neg = sign.is_some();
|
|
|
|
Pattern::Literal(PatternLiteral::NumPattern { neg, num })
|
|
|
|
} /
|
|
|
|
"_" { Pattern::Ignored }
|
|
|
|
|
2021-11-03 20:31:46 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule list_expr(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
"[" exprs:(expression(parser) ** ",") "]" {
|
2021-11-03 20:31:46 -07:00
|
|
|
let mut exprs = exprs;
|
|
|
|
ExpressionKind::ListLiteral(exprs)
|
|
|
|
}
|
2021-11-03 20:19:55 -07:00
|
|
|
|
2021-11-13 22:38:57 -08:00
|
|
|
rule paren_expr(parser: &mut Parser) -> ExpressionKind =
|
|
|
|
"(" exprs:(expression(parser) ** ",") ")" {
|
2021-11-03 20:19:55 -07:00
|
|
|
let mut exprs = exprs;
|
|
|
|
match exprs.len() {
|
|
|
|
1 => exprs.pop().unwrap().kind,
|
|
|
|
_ => ExpressionKind::TupleLiteral(exprs),
|
|
|
|
}
|
2021-11-04 21:11:19 -07:00
|
|
|
}
|
2021-11-03 20:19:55 -07:00
|
|
|
|
2021-11-13 13:45:52 -08:00
|
|
|
//TODO need to do something with prefix in the AST
|
2021-11-03 20:19:55 -07:00
|
|
|
rule string_literal() -> ExpressionKind =
|
2021-11-13 13:45:52 -08:00
|
|
|
prefix:identifier()? s:bare_string_literal(){ ExpressionKind::StringLiteral(Rc::new(s.to_string())) }
|
2021-11-04 21:11:19 -07:00
|
|
|
|
|
|
|
rule bare_string_literal() -> &'input str =
|
2021-11-13 13:45:52 -08:00
|
|
|
"\"" s:$(string_component()*) "\"" { s }
|
|
|
|
|
|
|
|
rule string_component() -> &'input str =
|
|
|
|
r#"\\"# { "\\" } /
|
|
|
|
r#"\""# { "\"" } /
|
|
|
|
r#"\t"# { "\t" } /
|
|
|
|
r#"\n"# { "\n" } /
|
|
|
|
ch:$([^ '"' ]) { ch }
|
2021-11-03 20:19:55 -07:00
|
|
|
|
|
|
|
rule bool_literal() -> ExpressionKind =
|
|
|
|
"true" { ExpressionKind::BoolLiteral(true) } / "false" { ExpressionKind::BoolLiteral(false) }
|
2021-11-03 18:01:23 -07:00
|
|
|
|
|
|
|
rule nat_literal() -> ExpressionKind =
|
2021-11-03 20:19:55 -07:00
|
|
|
bin_literal() / hex_literal() / unmarked_literal()
|
|
|
|
|
|
|
|
rule unmarked_literal() -> ExpressionKind =
|
|
|
|
digits:digits() { ExpressionKind::NatLiteral(digits.parse().unwrap()) }
|
|
|
|
|
|
|
|
rule bin_literal() -> ExpressionKind =
|
2021-11-13 13:33:15 -08:00
|
|
|
"0b" digits:bin_digits() {? parse_binary(digits).map(ExpressionKind::NatLiteral) }
|
2021-11-03 20:19:55 -07:00
|
|
|
|
|
|
|
rule hex_literal() -> ExpressionKind =
|
2021-11-13 13:33:15 -08:00
|
|
|
"0x" digits:hex_digits() {? parse_hex(digits).map(ExpressionKind::NatLiteral) }
|
2021-11-03 18:01:23 -07:00
|
|
|
|
|
|
|
rule float_literal() -> ExpressionKind =
|
|
|
|
ds:$( digits() "." digits()? / "." digits() ) { ExpressionKind::FloatLiteral(ds.parse().unwrap()) }
|
|
|
|
|
2021-11-03 20:19:55 -07:00
|
|
|
rule digits() -> &'input str = $((digit_group() "_"*)+)
|
2021-11-04 21:11:19 -07:00
|
|
|
rule bin_digits() -> &'input str = $((bin_digit_group() "_"*)+)
|
|
|
|
rule hex_digits() -> &'input str = $((hex_digit_group() "_"*)+)
|
2021-11-03 18:01:23 -07:00
|
|
|
|
2021-11-04 21:11:19 -07:00
|
|
|
rule digit_group() -> &'input str = $(['0'..='9']+)
|
|
|
|
rule bin_digit_group() -> &'input str = $(['0' | '1']+)
|
|
|
|
rule hex_digit_group() -> &'input str = $(['0'..='9' | 'a'..='f' | 'A'..='F']+)
|
2021-11-03 16:27:42 -07:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2021-11-03 18:01:23 -07:00
|
|
|
|
2021-11-13 13:33:15 -08:00
|
|
|
fn parse_binary(digits: &str) -> Result<u64, &'static str> {
|
2021-11-03 20:19:55 -07:00
|
|
|
let mut result: u64 = 0;
|
|
|
|
let mut multiplier = 1;
|
|
|
|
for d in digits.chars().rev() {
|
|
|
|
match d {
|
|
|
|
'1' => result += multiplier,
|
|
|
|
'0' => (),
|
|
|
|
'_' => continue,
|
2021-11-04 21:11:19 -07:00
|
|
|
_ => unreachable!(),
|
2021-11-03 20:19:55 -07:00
|
|
|
}
|
|
|
|
multiplier = match multiplier.checked_mul(2) {
|
|
|
|
Some(m) => m,
|
2021-11-13 13:33:15 -08:00
|
|
|
None => return Err("Binary expression will overflow"),
|
2021-11-03 20:19:55 -07:00
|
|
|
}
|
|
|
|
}
|
2021-11-13 13:33:15 -08:00
|
|
|
Ok(result)
|
2021-11-03 20:19:55 -07:00
|
|
|
}
|
|
|
|
|
2021-11-13 13:33:15 -08:00
|
|
|
fn parse_hex(digits: &str) -> Result<u64, &'static str> {
|
2021-11-03 20:19:55 -07:00
|
|
|
let mut result: u64 = 0;
|
|
|
|
let mut multiplier: u64 = 1;
|
|
|
|
for d in digits.chars().rev() {
|
|
|
|
if d == '_' {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
match d.to_digit(16) {
|
|
|
|
Some(n) => result += n as u64 * multiplier,
|
2021-11-13 13:33:15 -08:00
|
|
|
None => return Err("Internal parser error: invalid hex digit"),
|
2021-11-03 20:19:55 -07:00
|
|
|
}
|
|
|
|
multiplier = match multiplier.checked_mul(16) {
|
|
|
|
Some(m) => m,
|
2021-11-13 13:33:15 -08:00
|
|
|
None => return Err("Hexadecimal expression will overflow"),
|
2021-11-03 20:19:55 -07:00
|
|
|
}
|
|
|
|
}
|
2021-11-13 13:33:15 -08:00
|
|
|
Ok(result)
|
2021-11-03 20:19:55 -07:00
|
|
|
}
|
|
|
|
|
2021-11-04 21:11:19 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
struct BinopSequence {
|
|
|
|
first: ExpressionKind,
|
|
|
|
next: Vec<(BinOp, ExpressionKind)>,
|
|
|
|
}
|
2021-11-03 20:19:55 -07:00
|
|
|
|
2021-11-04 21:11:19 -07:00
|
|
|
impl BinopSequence {
|
2021-11-14 00:34:21 -08:00
|
|
|
fn do_precedence(self, parser: &mut Parser) -> ExpressionKind {
|
2021-11-04 21:11:19 -07:00
|
|
|
fn helper(
|
|
|
|
precedence: i32,
|
|
|
|
lhs: ExpressionKind,
|
|
|
|
rest: &mut Vec<(BinOp, ExpressionKind)>,
|
2021-11-14 00:34:21 -08:00
|
|
|
parser: &mut Parser,
|
2021-11-04 21:11:19 -07:00
|
|
|
) -> Expression {
|
2021-11-14 00:34:21 -08:00
|
|
|
let mut lhs = Expression::new(parser.fresh(), lhs);
|
2021-11-14 03:27:30 -08:00
|
|
|
while let Some((next_op, next_rhs)) = rest.pop() {
|
2021-11-04 21:11:19 -07:00
|
|
|
let new_precedence = next_op.get_precedence();
|
|
|
|
if precedence >= new_precedence {
|
|
|
|
rest.push((next_op, next_rhs));
|
|
|
|
break;
|
2021-11-03 18:01:23 -07:00
|
|
|
}
|
2021-11-14 00:34:21 -08:00
|
|
|
let rhs = helper(new_precedence, next_rhs, rest, parser);
|
2021-11-04 21:11:19 -07:00
|
|
|
lhs = Expression::new(
|
2021-11-14 00:34:21 -08:00
|
|
|
parser.fresh(),
|
2021-11-04 21:11:19 -07:00
|
|
|
ExpressionKind::BinExp(next_op, Box::new(lhs), Box::new(rhs)),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
lhs
|
2021-11-03 20:19:55 -07:00
|
|
|
}
|
2021-11-04 21:11:19 -07:00
|
|
|
let mut as_stack = self.next.into_iter().rev().collect();
|
2021-11-14 00:34:21 -08:00
|
|
|
helper(BinOp::min_precedence(), self.first, &mut as_stack, parser).kind
|
2021-11-03 18:01:23 -07:00
|
|
|
}
|
|
|
|
}
|