redid the parser, patched up the project too.

This commit is contained in:
2022-07-03 18:01:40 +02:00
parent 6fb4b581b1
commit 2b55fae10d
30 changed files with 967 additions and 570 deletions

View File

@@ -1,61 +1,36 @@
use std::collections::HashMap;
use crate::parse;
use super::expr;
use crate::{Expr, Clause};
/// Replaces the first element of a name with the matching prefix from a prefix map
fn qualify(
name: &Vec<String>,
prefixes: &HashMap<String, Vec<String>>
) -> Option<Vec<String>> {
let value = prefixes.iter().find(|(k, _)| &&name[0] == k)?.1;
Some(value.iter().chain(name.iter().skip(1)).cloned().collect())
}
/// Produce a Token object for any value of parse::Expr other than Typed.
/// Produce a Token object for any value of Expr other than Typed.
/// Called by [#prefix] which handles Typed.
fn prefix_token(
expr: &parse::Expr,
fn prefix_clause(
expr: &Clause,
namespace: &Vec<String>
) -> expr::Token {
) -> Clause {
match expr {
parse::Expr::Typed(_, _) => panic!("This function should only be called by prefix!"),
parse::Expr::Char(c) => expr::Token::Literal(expr::Literal::Char(*c)),
parse::Expr::Int(i) => expr::Token::Literal(expr::Literal::Int(*i)),
parse::Expr::Num(n) => expr::Token::Literal(expr::Literal::Num(*n)),
parse::Expr::Str(s) => expr::Token::Literal(expr::Literal::Str(s.clone())),
parse::Expr::S(v) => expr::Token::S(v.iter().map(|e| prefix(e, namespace)).collect()),
parse::Expr::Auto(name, typ, body) => expr::Token::Auto(
Clause::S(c, v) => Clause::S(*c, v.iter().map(|e| prefix_expr(e, namespace)).collect()),
Clause::Auto(name, typ, body) => Clause::Auto(
name.clone(),
typ.clone().map(|expr| Box::new(prefix(&expr, namespace))),
body.iter().map(|e| prefix(e, namespace)).collect(),
typ.iter().map(|e| prefix_expr(e, namespace)).collect(),
body.iter().map(|e| prefix_expr(e, namespace)).collect(),
),
parse::Expr::Lambda(name, typ, body) => expr::Token::Lambda(
Clause::Lambda(name, typ, body) => Clause::Lambda(
name.clone(),
typ.clone().map(|expr| Box::new(prefix(&expr, namespace))),
body.iter().map(|e| prefix(e, namespace)).collect(),
typ.iter().map(|e| prefix_expr(e, namespace)).collect(),
body.iter().map(|e| prefix_expr(e, namespace)).collect(),
),
parse::Expr::Name(name) => expr::Token::Name {
qualified: namespace.iter().chain(name.iter()).cloned().collect(),
local: if name.len() == 1 {
Some(name[0].clone())
} else {
None
},
},
Clause::Name(name) => Clause::Name (
namespace.iter().chain(name.iter()).cloned().collect()
),
x => x.clone()
}
}
/// Produce an Expr object for any value of parse::Expr
pub fn prefix(expr: &parse::Expr, namespace: &Vec<String>) -> expr::Expr {
match expr {
parse::Expr::Typed(x, t) => expr::Expr {
typ: Some(Box::new(prefix(t, namespace))),
token: prefix_token(x, namespace),
},
_ => expr::Expr {
typ: None,
token: prefix_token(expr, namespace),
},
}
/// Produce an Expr object for any value of Expr
pub fn prefix_expr(Expr(clause, typ): &Expr, namespace: &Vec<String>) -> Expr {
Expr(
prefix_clause(clause, namespace),
typ.as_ref().map(|e| Box::new(prefix_expr(e, namespace)))
)
}