conlang: Add Quote
expression as a hack for testing
Possibly removed later, or replaced with something that turns Conlang AST nodes into Conlang data structures.
This commit is contained in:
parent
518fbe74a1
commit
d21683ad61
@ -347,6 +347,8 @@ pub enum ExprKind {
|
|||||||
/// An empty expression: `(` `)`
|
/// An empty expression: `(` `)`
|
||||||
#[default]
|
#[default]
|
||||||
Empty,
|
Empty,
|
||||||
|
/// A backtick-quoted expression
|
||||||
|
Quote(Quote),
|
||||||
/// A local bind instruction, `let` [`Sym`] `=` [`Expr`]
|
/// A local bind instruction, `let` [`Sym`] `=` [`Expr`]
|
||||||
Let(Let),
|
Let(Let),
|
||||||
/// An [Assign]ment expression: [`Expr`] (`=` [`Expr`])\+
|
/// An [Assign]ment expression: [`Expr`] (`=` [`Expr`])\+
|
||||||
@ -396,6 +398,12 @@ pub enum ExprKind {
|
|||||||
Continue,
|
Continue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A backtick-quoted subexpression-literal
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Quote {
|
||||||
|
pub quote: Box<ExprKind>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A local variable declaration [Stmt]
|
/// A local variable declaration [Stmt]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Let {
|
pub struct Let {
|
||||||
|
@ -415,6 +415,7 @@ mod display {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ExprKind::Empty => "()".fmt(f),
|
ExprKind::Empty => "()".fmt(f),
|
||||||
|
ExprKind::Quote(v) => v.fmt(f),
|
||||||
ExprKind::Let(v) => v.fmt(f),
|
ExprKind::Let(v) => v.fmt(f),
|
||||||
ExprKind::Assign(v) => v.fmt(f),
|
ExprKind::Assign(v) => v.fmt(f),
|
||||||
ExprKind::Modify(v) => v.fmt(f),
|
ExprKind::Modify(v) => v.fmt(f),
|
||||||
@ -442,6 +443,13 @@ mod display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Quote {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let Self { quote } = self;
|
||||||
|
write!(f, "`{quote}`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Let {
|
impl Display for Let {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let Self { mutable, name, ty, init } = self;
|
let Self { mutable, name, ty, init } = self;
|
||||||
@ -764,6 +772,7 @@ mod convert {
|
|||||||
}
|
}
|
||||||
impl From for ExprKind {
|
impl From for ExprKind {
|
||||||
Let => ExprKind::Let,
|
Let => ExprKind::Let,
|
||||||
|
Quote => ExprKind::Quote,
|
||||||
Assign => ExprKind::Assign,
|
Assign => ExprKind::Assign,
|
||||||
Modify => ExprKind::Modify,
|
Modify => ExprKind::Modify,
|
||||||
Binary => ExprKind::Binary,
|
Binary => ExprKind::Binary,
|
||||||
|
@ -529,6 +529,7 @@ pub fn or_fold_stmt_kind<F: Fold + ?Sized>(folder: &mut F, kind: StmtKind) -> St
|
|||||||
pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> ExprKind {
|
pub fn or_fold_expr_kind<F: Fold + ?Sized>(folder: &mut F, kind: ExprKind) -> ExprKind {
|
||||||
match kind {
|
match kind {
|
||||||
ExprKind::Empty => ExprKind::Empty,
|
ExprKind::Empty => ExprKind::Empty,
|
||||||
|
ExprKind::Quote(q) => ExprKind::Quote(q), // quoted expressions are left unmodified
|
||||||
ExprKind::Let(l) => ExprKind::Let(folder.fold_let(l)),
|
ExprKind::Let(l) => ExprKind::Let(folder.fold_let(l)),
|
||||||
ExprKind::Assign(a) => ExprKind::Assign(folder.fold_assign(a)),
|
ExprKind::Assign(a) => ExprKind::Assign(folder.fold_assign(a)),
|
||||||
ExprKind::Modify(m) => ExprKind::Modify(folder.fold_modify(m)),
|
ExprKind::Modify(m) => ExprKind::Modify(folder.fold_modify(m)),
|
||||||
|
@ -452,6 +452,7 @@ pub fn or_visit_stmt_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a StmtKind)
|
|||||||
pub fn or_visit_expr_kind<'a, V: Visit<'a>>(visitor: &mut V, e: &'a ExprKind) {
|
pub fn or_visit_expr_kind<'a, V: Visit<'a>>(visitor: &mut V, e: &'a ExprKind) {
|
||||||
match e {
|
match e {
|
||||||
ExprKind::Empty => {}
|
ExprKind::Empty => {}
|
||||||
|
ExprKind::Quote(_q) => {} // Quoted expressions are left unvisited
|
||||||
ExprKind::Let(l) => visitor.visit_let(l),
|
ExprKind::Let(l) => visitor.visit_let(l),
|
||||||
ExprKind::Assign(a) => visitor.visit_assign(a),
|
ExprKind::Assign(a) => visitor.visit_assign(a),
|
||||||
ExprKind::Modify(m) => visitor.visit_modify(m),
|
ExprKind::Modify(m) => visitor.visit_modify(m),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Values in the dynamically typed AST interpreter.
|
//! Values in the dynamically typed AST interpreter.
|
||||||
//!
|
//!
|
||||||
//! The most permanent fix is a temporary one.
|
//! The most permanent fix is a temporary one.
|
||||||
use cl_ast::{format::FmtAdapter, Sym};
|
use cl_ast::{format::FmtAdapter, ExprKind, Sym};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
error::{Error, IResult},
|
error::{Error, IResult},
|
||||||
@ -42,6 +42,8 @@ pub enum ConValue {
|
|||||||
Struct(Box<(Sym, HashMap<Sym, ConValue>)>),
|
Struct(Box<(Sym, HashMap<Sym, ConValue>)>),
|
||||||
/// An entire namespace
|
/// An entire namespace
|
||||||
Module(Box<HashMap<Sym, Option<ConValue>>>),
|
Module(Box<HashMap<Sym, Option<ConValue>>>),
|
||||||
|
/// A quoted expression
|
||||||
|
Quote(Box<ExprKind>),
|
||||||
/// A callable thing
|
/// A callable thing
|
||||||
Function(Rc<Function>),
|
Function(Rc<Function>),
|
||||||
/// A built-in function
|
/// A built-in function
|
||||||
@ -165,6 +167,7 @@ from! {
|
|||||||
&str => ConValue::String,
|
&str => ConValue::String,
|
||||||
String => ConValue::String,
|
String => ConValue::String,
|
||||||
Rc<str> => ConValue::String,
|
Rc<str> => ConValue::String,
|
||||||
|
ExprKind => ConValue::Quote,
|
||||||
Function => ConValue::Function,
|
Function => ConValue::Function,
|
||||||
Vec<ConValue> => ConValue::Tuple,
|
Vec<ConValue> => ConValue::Tuple,
|
||||||
&'static dyn BuiltIn => ConValue::BuiltIn,
|
&'static dyn BuiltIn => ConValue::BuiltIn,
|
||||||
@ -319,6 +322,9 @@ impl std::fmt::Display for ConValue {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
ConValue::Quote(q) => {
|
||||||
|
write!(f, "`{q}`")
|
||||||
|
}
|
||||||
ConValue::Function(func) => {
|
ConValue::Function(func) => {
|
||||||
write!(f, "{}", func.decl())
|
write!(f, "{}", func.decl())
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,7 @@ impl Interpret for ExprKind {
|
|||||||
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
|
||||||
match self {
|
match self {
|
||||||
ExprKind::Empty => Ok(ConValue::Empty),
|
ExprKind::Empty => Ok(ConValue::Empty),
|
||||||
|
ExprKind::Quote(q) => q.interpret(env),
|
||||||
ExprKind::Let(v) => v.interpret(env),
|
ExprKind::Let(v) => v.interpret(env),
|
||||||
ExprKind::Assign(v) => v.interpret(env),
|
ExprKind::Assign(v) => v.interpret(env),
|
||||||
ExprKind::Modify(v) => v.interpret(env),
|
ExprKind::Modify(v) => v.interpret(env),
|
||||||
@ -174,6 +175,13 @@ impl Interpret for ExprKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Interpret for Quote {
|
||||||
|
fn interpret(&self, _env: &mut Environment) -> IResult<ConValue> {
|
||||||
|
// TODO: squoosh down into a ConValue?
|
||||||
|
Ok(ConValue::Quote(self.quote.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod assignment {
|
mod assignment {
|
||||||
/// Pattern matching engine for assignment
|
/// Pattern matching engine for assignment
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -900,6 +900,18 @@ impl Parse<'_> for ExprKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Parse<'_> for Quote {
|
||||||
|
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
|
||||||
|
let quote = delim(
|
||||||
|
ExprKind::parse,
|
||||||
|
(TokenKind::Grave, TokenKind::Grave),
|
||||||
|
Parsing::ExprKind,
|
||||||
|
)(p)?
|
||||||
|
.into();
|
||||||
|
Ok(Quote { quote })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Parse<'_> for Let {
|
impl Parse<'_> for Let {
|
||||||
fn parse(p: &mut Parser) -> PResult<Let> {
|
fn parse(p: &mut Parser) -> PResult<Let> {
|
||||||
p.consume_peeked();
|
p.consume_peeked();
|
||||||
|
@ -16,6 +16,7 @@ pub fn exprkind(p: &mut Parser, power: u8) -> PResult<ExprKind> {
|
|||||||
literal_like!() => Literal::parse(p)?.into(),
|
literal_like!() => Literal::parse(p)?.into(),
|
||||||
path_like!() => exprkind_pathlike(p)?,
|
path_like!() => exprkind_pathlike(p)?,
|
||||||
TokenKind::Amp | TokenKind::AmpAmp => AddrOf::parse(p)?.into(),
|
TokenKind::Amp | TokenKind::AmpAmp => AddrOf::parse(p)?.into(),
|
||||||
|
TokenKind::Grave => Quote::parse(p)?.into(),
|
||||||
TokenKind::LCurly => Block::parse(p)?.into(),
|
TokenKind::LCurly => Block::parse(p)?.into(),
|
||||||
TokenKind::LBrack => exprkind_arraylike(p)?,
|
TokenKind::LBrack => exprkind_arraylike(p)?,
|
||||||
TokenKind::LParen => exprkind_tuplelike(p)?,
|
TokenKind::LParen => exprkind_tuplelike(p)?,
|
||||||
|
@ -388,6 +388,7 @@ pub mod yamlify {
|
|||||||
impl Yamlify for ExprKind {
|
impl Yamlify for ExprKind {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
match self {
|
match self {
|
||||||
|
ExprKind::Quote(k) => k.yaml(y),
|
||||||
ExprKind::Let(k) => k.yaml(y),
|
ExprKind::Let(k) => k.yaml(y),
|
||||||
ExprKind::Assign(k) => k.yaml(y),
|
ExprKind::Assign(k) => k.yaml(y),
|
||||||
ExprKind::Modify(k) => k.yaml(y),
|
ExprKind::Modify(k) => k.yaml(y),
|
||||||
@ -417,6 +418,11 @@ pub mod yamlify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl Yamlify for Quote {
|
||||||
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
|
y.key("Quote").value(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Yamlify for Assign {
|
impl Yamlify for Assign {
|
||||||
fn yaml(&self, y: &mut Yamler) {
|
fn yaml(&self, y: &mut Yamler) {
|
||||||
let Self { parts } = self;
|
let Self { parts } = self;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user