mirror of
https://github.com/osmarks/osmarkscalculator.git
synced 2025-04-08 03:36:45 +00:00
Allow quoting
This commit is contained in:
parent
66a65c6715
commit
97e562e4b2
@ -17,7 +17,7 @@ pub struct Rule {
|
||||
pub result: RuleResult,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Operation {
|
||||
pub commutative: bool,
|
||||
pub associative: bool,
|
||||
|
@ -230,6 +230,11 @@ fn flatten_tree(v: &mut Value, env: &Env) -> Result<()> {
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
for child in args.iter_mut() {
|
||||
flatten_tree(child, env)?;
|
||||
}
|
||||
*/
|
||||
// Also do sorting after flattening, to avoid any weirdness with ordering.
|
||||
canonical_sort(v, env)?;
|
||||
return Ok(())
|
||||
@ -420,7 +425,6 @@ x^n/x = x^(n-1)
|
||||
PushRuleset[factor_postpostprocess]
|
||||
";
|
||||
|
||||
|
||||
pub struct ImperativeCtx {
|
||||
bindings: Bindings,
|
||||
current_ruleset_stage: InlinableString,
|
||||
|
45
src/parse.rs
45
src/parse.rs
@ -10,7 +10,15 @@ pub enum Token { Number(InlinableString), OpenBracket, CloseBracket, Op(char), E
|
||||
enum LexState {
|
||||
Number(InlinableString),
|
||||
Identifier(InlinableString),
|
||||
None
|
||||
None,
|
||||
Quote
|
||||
}
|
||||
|
||||
pub fn is_special_character(c: char) -> bool {
|
||||
match c {
|
||||
'#' | '+' | '(' | ')' | '-' | '/' | '*' | '^' | '=' | '[' | ']' | ',' => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
// lexer
|
||||
@ -30,20 +38,29 @@ pub fn lex(input: &str) -> Result<Vec<Token>> {
|
||||
n.push(char);
|
||||
LexState::Number(n)
|
||||
},
|
||||
// Allow quoting special characters
|
||||
('`', LexState::None) => {
|
||||
LexState::Quote
|
||||
},
|
||||
// if special character seen, commit existing state and push operator/bracket/comma token
|
||||
('#' | '+' | '(' | ')' | '-' | '/' | '*' | '^' | '=' | '[' | ']' | ',', state) => {
|
||||
match state {
|
||||
LexState::Number(s) => toks.push(Token::Number(s)),
|
||||
LexState::Identifier(s) => toks.push(Token::Identifier(s)),
|
||||
_ => ()
|
||||
};
|
||||
toks.push(match char {
|
||||
'(' => Token::OpenBracket, ')' => Token::CloseBracket,
|
||||
'[' => Token::OpenSqBracket, ']' => Token::CloseSqBracket,
|
||||
',' => Token::Comma,
|
||||
a => Token::Op(a)
|
||||
});
|
||||
LexState::None
|
||||
(c, state) if is_special_character(c) => {
|
||||
if let LexState::Quote = state {
|
||||
toks.push(Token::Identifier(char_to_string(char)));
|
||||
LexState::None
|
||||
} else {
|
||||
match state {
|
||||
LexState::Number(s) => toks.push(Token::Number(s)),
|
||||
LexState::Identifier(s) => toks.push(Token::Identifier(s)),
|
||||
_ => ()
|
||||
};
|
||||
toks.push(match char {
|
||||
'(' => Token::OpenBracket, ')' => Token::CloseBracket,
|
||||
'[' => Token::OpenSqBracket, ']' => Token::CloseSqBracket,
|
||||
',' => Token::Comma,
|
||||
a => Token::Op(a)
|
||||
});
|
||||
LexState::None
|
||||
}
|
||||
},
|
||||
// semicolon or newline is break
|
||||
(';' | '\n', state) => {
|
||||
|
13
src/value.rs
13
src/value.rs
@ -5,7 +5,7 @@ use std::fmt::{self, Write};
|
||||
use itertools::Itertools;
|
||||
use anyhow::{Result, anyhow};
|
||||
|
||||
use crate::parse::{Ast, precedence};
|
||||
use crate::parse::{Ast, precedence, is_special_character};
|
||||
use crate::env::{Env, Bindings};
|
||||
use crate::util::char_to_string;
|
||||
use crate::interval_arithmetic::Interval;
|
||||
@ -179,7 +179,16 @@ impl Value {
|
||||
Value::ExactNum(x) => if *x >= 0 {
|
||||
write!(f, "{}", x)
|
||||
} else { write!(f, "Negate[{}]", -x) },
|
||||
Value::Identifier(i) => write!(f, "{}", i),
|
||||
Value::Identifier(i) => {
|
||||
for c in i.chars() {
|
||||
if is_special_character(c) {
|
||||
write!(f, "`{}", c)?;
|
||||
} else {
|
||||
write!(f, "{}", c)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
Value::Call(head, args) => {
|
||||
match env.ops.get(head) {
|
||||
Some(_) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user