schala/schala-lang/language/src/parsing/new.rs

551 lines
23 KiB
Rust
Raw Normal View History

use std::rc::Rc;
2021-11-04 21:11:19 -07:00
use crate::ast::*;
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-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! {
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-03 18:01:23 -07:00
pub rule program() -> AST =
2021-11-11 20:56:39 -08:00
__ statements:(statement() ** delimiter() ) __ { AST { id: Default::default(), 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-11 23:41:51 -08:00
pub rule block() -> Block = "{" __ items:block_item()* __ "}" { items.into() } /
"{" __ stmt:statement() __ "}" { vec![stmt].into() }
2021-11-06 20:33:33 -07:00
rule block_item() -> Statement =
stmt:statement() delimiter()+ { stmt }
2021-11-03 18:01:23 -07:00
2021-11-07 01:30:26 -08:00
rule statement() -> Statement =
2021-11-13 13:18:02 -08:00
_ pos:position!() kind:statement_kind() _ { Statement { id: Default::default(), location: pos.into(), kind } }
2021-11-07 03:13:35 -08:00
rule statement_kind() -> StatementKind =
2021-11-12 00:06:42 -08:00
__ import:import() { StatementKind::Import(import) } /
2021-11-11 19:36:48 -08:00
__ decl:declaration() { StatementKind::Declaration(decl) } /
2021-11-12 00:27:06 -08:00
__ flow:flow() { StatementKind::Flow(flow) } /
2021-11-11 19:36:48 -08:00
__ expr:expression() { StatementKind::Expression(expr) }
2021-11-07 01:30:26 -08:00
2021-11-12 00:27:06 -08:00
rule flow() -> FlowControl =
"continue" { FlowControl::Continue } /
"break" { FlowControl::Break } /
"return" _ expr:expression()? { FlowControl::Return(expr) }
2021-11-12 00:06:42 -08:00
rule import() -> ImportSpecifier =
"import" _ path_components:path_components() suffix:import_suffix()? {
ImportSpecifier {
id: Default::default(),
path_components,
imported_names: suffix.unwrap_or_else(|| ImportedNames::LastOfPath)
}
}
rule path_components() -> Vec<Rc<String>> =
"::"? name:identifier() rest:path_component()* {
let mut items = vec![rc_string(name)];
items.extend(rest.into_iter().map(|n| rc_string(n)));
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-07 01:30:26 -08:00
rule declaration() -> Declaration =
2021-11-11 23:44:26 -08:00
binding() / type_decl() / annotation() / func() / interface() / implementation() / module()
2021-11-11 22:00:04 -08:00
2021-11-11 23:44:26 -08:00
rule module() -> Declaration =
"module" _ name:identifier() _ items:block() { Declaration::Module { name: rc_string(name), items } }
2021-11-11 22:00:04 -08:00
rule implementation() -> Declaration =
"impl" _ interface:type_singleton_name() _ "for" _ type_name:type_identifier() _ block:decl_block() {
Declaration::Impl { type_name, interface_name: Some(interface), block }
} /
"impl" _ type_name:type_identifier() _ block:decl_block() {
Declaration::Impl { type_name, interface_name: None, block }
}
rule decl_block() -> Vec<Declaration> =
"{" __ decls:(func_declaration() ** (delimiter()+)) __ "}" { decls }
rule interface() -> Declaration =
"interface" _ name:identifier() _ signatures:signature_block() { Declaration::Interface { name: rc_string(name), signatures } }
rule signature_block() -> Vec<Signature> =
"{" __ signatures:(func_signature() ** (delimiter()+)) __ "}" { signatures }
2021-11-07 03:13:35 -08:00
rule func() -> Declaration =
2021-11-11 22:00:04 -08:00
decl:func_declaration() { decl } /
2021-11-07 03:13:35 -08:00
sig:func_signature() { Declaration::FuncSig(sig) }
2021-11-11 22:00:04 -08:00
rule func_declaration() -> Declaration =
2021-11-11 23:41:51 -08:00
_ sig:func_signature() __ body:block() { Declaration::FuncDecl(sig, body) }
2021-11-11 22:00:04 -08:00
2021-11-07 03:13:35 -08:00
//TODO handle operators
rule func_signature() -> Signature =
2021-11-11 22:00:04 -08:00
_ "fn" _ name:identifier() "(" _ params:formal_params() _ ")" _ type_anno:type_anno()? { Signature {
2021-11-07 03:13:35 -08:00
name: rc_string(name), operator: false, params, type_anno
} }
rule formal_params() -> Vec<FormalParam> = params:(formal_param() ** (_ "," _)) {? if params.len() < 256 { Ok(params) } else {
Err("function-too-long") }
}
rule formal_param() -> FormalParam =
name:identifier() _ anno:type_anno()? _ "=" expr:expression() { FormalParam { name: rc_string(name),
default: Some(expr), anno } } /
name:identifier() _ anno:type_anno()? { FormalParam { name: rc_string(name), default: None, anno } }
rule annotation() -> Declaration =
2021-11-11 23:41:51 -08:00
"@" name:identifier() args:annotation_args()? delimiter()+ _ inner:statement() { 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) }
}
rule annotation_args() -> Vec<Expression> =
"(" _ args:(expression() ** (_ "," _)) _ ")" { args }
2021-11-07 01:30:26 -08:00
rule binding() -> Declaration =
"let" _ mutable:"mut"? _ ident:identifier() _ type_anno:type_anno()? _ "=" _ expr:expression() {
Declaration::Binding { name: Rc::new(ident.to_string()), constant: mutable.is_none(),
type_anno, expr }
}
rule type_decl() -> Declaration =
"type" _ "alias" _ alias:type_alias() { alias } /
"type" _ mutable:"mut"? _ name:type_singleton_name() _ "=" _ body:type_body() {
Declaration::TypeDecl { name, body, mutable: mutable.is_some() }
}
rule type_singleton_name() -> TypeSingletonName =
name:identifier() params:type_params()? { TypeSingletonName { name: rc_string(name), params: if let Some(params) = params { params } else { vec![] } } }
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) }
rule type_body() -> TypeBody =
"{" _ items:(record_variant_item() ++ (_ "," _)) _ "}" { TypeBody::ImmediateRecord(Default::default(), items) } /
variants:(variant_spec() ** (_ "|" _)) { TypeBody::Variants(variants) }
rule variant_spec() -> Variant =
name:identifier() _ "{" _ typed_identifier_list:(record_variant_item() ++ (_ "," _)) _ "}" { Variant {
id: Default::default(), name: rc_string(name), kind: VariantKind::Record(typed_identifier_list)
} } /
name:identifier() "(" tuple_members:(type_identifier() ++ (_ "," _)) ")" { Variant {
id: Default::default(), name: rc_string(name), kind: VariantKind::TupleStruct(tuple_members) } } /
name:identifier() { Variant { id: Default::default(), name: rc_string(name), kind: VariantKind::UnitStruct } }
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-03 18:01:23 -07:00
pub rule expression() -> Expression =
2021-11-11 22:24:35 -08:00
__ kind:expression_kind() _ type_anno:type_anno()? { Expression { id: Default::default(), type_anno, kind } }
2021-11-03 18:01:23 -07:00
2021-11-07 01:30:26 -08:00
rule expression_no_struct() -> Expression =
2021-11-11 22:24:35 -08:00
__ kind:expression_kind_no_struct() { Expression { id: Default::default(), type_anno: None, kind: kind } }
2021-11-05 12:52:41 -07:00
2021-11-03 18:01:23 -07:00
rule expression_kind() -> ExpressionKind =
2021-11-05 03:16:44 -07:00
precedence_expr(true)
2021-11-03 23:57:22 -07:00
rule expression_kind_no_struct() -> ExpressionKind =
2021-11-05 03:16:44 -07:00
precedence_expr(false)
2021-11-05 03:16:44 -07:00
rule precedence_expr(struct_ok: bool) -> ExpressionKind =
first:prefix_expr(struct_ok) _ next:(precedence_continuation(struct_ok))* {
2021-11-04 21:11:19 -07:00
let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect();
BinopSequence { first, next }.do_precedence()
}
2021-11-03 23:57:22 -07:00
2021-11-05 03:16:44 -07:00
rule precedence_continuation(struct_ok: bool) -> (&'input str, ExpressionKind) =
op:operator() _ expr:prefix_expr(struct_ok) _ { (op, expr) }
2021-11-03 18:01:23 -07:00
2021-11-05 03:16:44 -07:00
rule prefix_expr(struct_ok: bool) -> ExpressionKind =
prefix:prefix()? expr:extended_expr(struct_ok) {
2021-11-04 21:11:19 -07:00
if let Some(p) = prefix {
let expr = Expression::new(Default::default(), expr);
let prefix = PrefixOp::from_sigil(p);
ExpressionKind::PrefixExp(prefix, Box::new(expr))
} else {
expr
}
}
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-05 03:16:44 -07:00
rule extended_expr(struct_ok: bool) -> ExpressionKind =
2021-11-12 21:41:15 -08:00
primary:primary(struct_ok) parts:(extended_expr_part()*) {
let mut expression = Expression::new(Default::default(), primary);
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 }
}
};
expression = Expression::new(Default::default(), kind);
2021-11-04 22:31:29 -07:00
}
2021-11-12 21:41:15 -08:00
expression.kind
}
2021-11-12 21:41:15 -08:00
rule extended_expr_part() -> ExtendedPart<'input> =
indexers:index_part() { ExtendedPart::Index(indexers) } /
arguments:call_part() { ExtendedPart::Call(arguments) } /
"." name:identifier() { ExtendedPart::Accessor(name) }
2021-11-04 22:31:29 -07:00
rule index_part() -> Vec<Expression> =
"[" indexers:(expression() ++ ",") "]" { indexers }
rule call_part() -> Vec<InvocationArgument> =
"(" arguments:(invocation_argument() ** ",") ")" { arguments }
//TODO this shouldn't be an expression b/c type annotations disallowed here
rule invocation_argument() -> InvocationArgument =
_ "_" _ { InvocationArgument::Ignored } /
_ ident:identifier() _ "=" _ expr:expression() { InvocationArgument::Keyword {
name: Rc::new(ident.to_string()),
expr
} } /
_ expr:expression() _ { InvocationArgument::Positional(expr) }
2021-11-05 03:16:44 -07:00
rule primary(struct_ok: bool) -> ExpressionKind =
2021-11-05 12:52:41 -07:00
while_expr() / for_expr() / float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() /
2021-11-11 02:42:14 -08:00
list_expr() / if_expr() / lambda_expr() /
2021-11-05 03:16:44 -07:00
item:named_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } /
identifier_expr()
2021-11-04 21:11:19 -07:00
2021-11-11 02:42:14 -08:00
rule lambda_expr() -> ExpressionKind =
r#"\"# __ "(" _ params:formal_params() _ ")" _ type_anno:(type_anno()?) _ body:block() {
ExpressionKind::Lambda { params, type_anno, body }
} /
r#"\"# param:formal_param() _ type_anno:(type_anno()?) _ body:block() {
ExpressionKind::Lambda { params: vec![param], type_anno, body }
}
2021-11-05 12:52:41 -07:00
rule for_expr() -> ExpressionKind =
"for" _ enumerators:for_enumerators() _ body:for_body() {
ExpressionKind::ForExpression { enumerators, body }
}
rule for_enumerators() -> Vec<Enumerator> =
"{" _ enumerators:(enumerator() ++ ",") _ "}" { enumerators } /
enumerator:enumerator() { vec![enumerator] }
//TODO add guards, etc.
rule enumerator() -> Enumerator =
ident:identifier() _ "<-" _ generator:expression_no_struct() {
Enumerator { id: Rc::new(ident.to_string()), generator }
} /
//TODO need to distinguish these two cases in AST
ident:identifier() _ "=" _ generator:expression_no_struct() {
Enumerator { id: Rc::new(ident.to_string()), generator }
}
rule for_body() -> Box<ForBody> =
"return" _ expr:expression() { Box::new(ForBody::MonadicReturn(expr)) } /
body:block() { Box::new(ForBody::StatementBlock(body)) }
rule while_expr() -> ExpressionKind =
"while" _ cond:expression_kind_no_struct()? _ body:block() {
ExpressionKind::WhileExpression {
condition: cond.map(|kind| Box::new(Expression::new(Default::default(), kind))),
body,
}
}
2021-11-04 21:11:19 -07:00
rule identifier_expr() -> ExpressionKind =
2021-11-04 22:31:29 -07:00
qn:qualified_identifier() { ExpressionKind::Value(qn) }
2021-11-04 21:11:19 -07:00
rule named_struct() -> ExpressionKind =
name:qualified_identifier() _ fields:record_block() {
ExpressionKind::NamedStruct {
name,
fields: fields.into_iter().map(|(n, exp)| (Rc::new(n.to_string()), exp)).collect(),
}
}
//TODO anonymous structs, update syntax for structs
rule record_block() -> Vec<(&'input str, Expression)> =
"{" _ entries:(record_entry() ** ",") _ "}" { entries }
rule record_entry() -> (&'input str, Expression) =
_ name:identifier() _ ":" _ expr:expression() _ { (name, expr) }
rule qualified_identifier() -> QualifiedName =
names:(identifier() ++ "::") { QualifiedName { id: Default::default(), components: names.into_iter().map(|name| Rc::new(name.to_string())).collect() } }
//TODO improve the definition of identifiers
rule identifier() -> &'input str =
2021-11-12 00:32:11 -08:00
!reserved() text:$(['a'..='z' | 'A'..='Z' | '_'] ['a'..='z' | 'A'..='Z' | '0'..='9' | '_']*) { text }
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
rule if_expr() -> ExpressionKind =
"if" _ discriminator:(expression()?) _ body:if_expr_body() {
ExpressionKind::IfExpression {
discriminator: discriminator.map(Box::new),
body: Box::new(body),
}
}
rule if_expr_body() -> IfExpressionBody =
cond_block() / simple_pattern_match() / simple_conditional()
rule simple_conditional() -> IfExpressionBody =
"then" _ then_case:expr_or_block() _ else_case:else_case() {
IfExpressionBody::SimpleConditional { then_case, else_case }
}
rule simple_pattern_match() -> IfExpressionBody =
"is" _ pattern:pattern() _ "then" _ then_case:expr_or_block() _ else_case:else_case() {
IfExpressionBody::SimplePatternMatch { pattern, then_case, else_case }
}
rule cond_block() -> IfExpressionBody =
2021-11-11 22:24:35 -08:00
"{" __ cond_arms:(cond_arm() ++ (delimiter()+)) __ "}" { IfExpressionBody::CondList(cond_arms) }
2021-11-04 21:11:19 -07:00
rule cond_arm() -> ConditionArm =
_ "else" _ body:expr_or_block() { ConditionArm { condition: Condition::Else, guard: None, body } } /
_ condition:condition() _ guard:condition_guard() _ "then" _ body:expr_or_block()
{ ConditionArm { condition, guard, body } }
rule condition() -> Condition =
"is" _ pat:pattern() { Condition::Pattern(pat) } /
op:operator() _ expr:expression() { Condition::TruncatedOp(BinOp::from_sigil(op), expr) }
rule condition_guard() -> Option<Expression> =
("if" _ expr:expression() { expr } )?
rule expr_or_block() -> Block = block() / pos:position!() ex:expression() {
2021-11-04 21:11:19 -07:00
Statement {
id: Default::default(), location: pos.into(),
2021-11-04 21:11:19 -07:00
kind: StatementKind::Expression(ex)
}.into()
}
rule else_case() -> Option<Block> =
("else" _ eorb:expr_or_block() { eorb })?
rule pattern() -> Pattern =
"(" _ variants:(pattern() ++ ",") _ ")" { Pattern::TuplePattern(variants) } /
_ pat:simple_pattern() { pat }
rule simple_pattern() -> Pattern =
pattern_literal() /
qn:qualified_identifier() "(" members:(pattern() ** ",") ")" {
Pattern::TupleStruct(qn, members)
} /
qn:qualified_identifier() _ "{" _ items:(record_pattern_entry() ** ",") "}" _ {
let items = items.into_iter().map(|(name, pat)| (Rc::new(name.to_string()), pat)).collect();
Pattern::Record(qn, items)
} /
qn:qualified_identifier() { Pattern::VarOrName(qn) }
rule record_pattern_entry() -> (&'input str, Pattern) =
_ name:identifier() _ ":" _ pat:pattern() _ { (name, pat) } /
_ name:identifier() _ {
let qn = QualifiedName {
id: Default::default(),
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
rule list_expr() -> ExpressionKind =
"[" exprs:(expression() ** ",") "]" {
let mut exprs = exprs;
ExpressionKind::ListLiteral(exprs)
}
rule paren_expr() -> ExpressionKind =
"(" exprs:(expression() ** ",") ")" {
let mut exprs = exprs;
match exprs.len() {
1 => exprs.pop().unwrap().kind,
_ => ExpressionKind::TupleLiteral(exprs),
}
2021-11-04 21:11:19 -07:00
}
rule string_literal() -> ExpressionKind =
2021-11-04 21:11:19 -07:00
s:bare_string_literal(){ ExpressionKind::StringLiteral(Rc::new(s.to_string())) }
//TODO string escapes, prefixes
rule bare_string_literal() -> &'input str =
"\"" items:$([^ '"' ]*) "\"" { items }
rule bool_literal() -> ExpressionKind =
"true" { ExpressionKind::BoolLiteral(true) } / "false" { ExpressionKind::BoolLiteral(false) }
2021-11-03 18:01:23 -07:00
rule nat_literal() -> ExpressionKind =
bin_literal() / hex_literal() / unmarked_literal()
rule unmarked_literal() -> ExpressionKind =
digits:digits() { ExpressionKind::NatLiteral(digits.parse().unwrap()) }
rule bin_literal() -> ExpressionKind =
"0b" digits:bin_digits() { ExpressionKind::NatLiteral(parse_binary(digits)) }
rule hex_literal() -> ExpressionKind =
"0x" digits:hex_digits() { ExpressionKind::NatLiteral(parse_hex(digits)) }
2021-11-03 18:01:23 -07:00
rule float_literal() -> ExpressionKind =
ds:$( digits() "." digits()? / "." digits() ) { ExpressionKind::FloatLiteral(ds.parse().unwrap()) }
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-04 21:11:19 -07:00
fn parse_binary(digits: &str /*, tok: Token*/) -> u64 {
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!(),
}
multiplier = match multiplier.checked_mul(2) {
Some(m) => m,
2021-11-04 21:11:19 -07:00
None =>
/*return ParseError::new_with_token("This binary expression will overflow", tok),*/
panic!(),
}
}
//Ok(result)
result
}
//TODO fix these two functions
fn parse_hex(digits: &str) -> u64 {
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,
None => panic!(),
}
multiplier = match multiplier.checked_mul(16) {
Some(m) => m,
2021-11-04 21:11:19 -07:00
None => panic!(),
}
}
result
}
2021-11-04 21:11:19 -07:00
#[derive(Debug)]
struct BinopSequence {
first: ExpressionKind,
next: Vec<(BinOp, ExpressionKind)>,
}
2021-11-04 21:11:19 -07:00
impl BinopSequence {
fn do_precedence(self) -> ExpressionKind {
fn helper(
precedence: i32,
lhs: ExpressionKind,
rest: &mut Vec<(BinOp, ExpressionKind)>,
) -> Expression {
let mut lhs = Expression::new(Default::default(), lhs);
loop {
let (next_op, next_rhs) = match rest.pop() {
Some((a, b)) => (a, b),
None => break,
};
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-04 21:11:19 -07:00
let rhs = helper(new_precedence, next_rhs, rest);
lhs = Expression::new(
Default::default(),
ExpressionKind::BinExp(next_op, Box::new(lhs), Box::new(rhs)),
);
}
lhs
}
2021-11-04 21:11:19 -07:00
let mut as_stack = self.next.into_iter().rev().collect();
helper(BinOp::min_precedence(), self.first, &mut as_stack).kind
2021-11-03 18:01:23 -07:00
}
}