rust-nix/src/parser/expression.rs

111 lines
2.3 KiB
Rust

use super::Identifier;
use std::sync::Arc;
#[derive(Clone, Debug)]
pub enum Number {
Integer(i64),
Float(f64),
}
#[derive(Clone, Debug)]
pub enum Literal {
Number(Number),
String(String),
}
#[derive(Clone, Debug)]
pub enum AttributeName {
// plain identifier
Literal(Identifier),
// quoted strings or ${...} expressions
Interpolated(Arc<Expression>),
}
#[derive(Clone, Debug)]
pub enum PathElement {
Fixed(String),
// ${...}
Expression(Arc<Expression>),
}
#[derive(Clone, Debug)]
// `inherit NAME1 NAME2;`
// `inherit (SET) NAME1 NAME2;`
pub struct Inherit {
pub from: Option<Arc<Expression>>,
// quoted identifiers are ok, but not dynamic ones
pub names: Vec<Identifier>,
}
#[derive(Clone, Debug)]
pub enum LetAssignment {
Assign {
// quoted identifier is ok, but not dynamic one
name: Identifier,
value: Arc<Expression>,
},
Inherit(Inherit),
}
#[derive(Clone, Debug)]
pub struct LambdaSetParam {
pub names: Vec<(Identifier, Option<Arc<Expression>>)>,
pub open: bool, // `...`
}
#[derive(Clone, Debug)]
pub enum Expression {
Identifier(Identifier),
Literal(Arc<Literal>),
InterpolateString(Vec<Arc<Expression>>),
Path {
// base must include `/`, otherwise wouldn't be recognized as path
base: String,
interpolate: Vec<PathElement>,
},
// `let (NAME = VALUE;)* in EVALUATE`
Let {
assignments: Vec<(Identifier, Arc<Expression>)>,
evaluate: Arc<Expression>,
},
// `with SET; EVALUATE`
// attributes from with don't "shadow" attributes in scope from let/lambda/rec.
// but they do shadow attributes from "more distant" with statements.
With {
set: Arc<Expression>,
evaluate: Arc<Expression>,
},
// `[ ... ]`
List {
elements: Vec<Arc<Expression>>,
},
// `{ ... }`
AttributeSet {
elements: Vec<(AttributeName, Arc<Expression>)>,
inherits: Vec<Inherit>,
},
// `rec ...`
RecursiveSet(Arc<Expression>),
// `NAME: BODY
// `NAME@{...}: BODY
// `{...}: BODY
Lambda {
// quoting not allowed
name: Option<Identifier>,
set_params: LambdaSetParam,
body: Arc<Expression>,
},
// `if COND then TRUE_BRANCH else FALSE_BRANCH`
Conditional {
cond: Arc<Expression>,
true_branch: Arc<Expression>,
false_branch: Arc<Expression>,
},
// `assert ASSERTION; BODY`
Assert {
assertion: Arc<Expression>,
body: Arc<Expression>,
}
}