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