Compare commits

..

4 Commits

Author SHA1 Message Date
Mark 3a08cfb2d3
Updated TODO 2023-08-21 13:26:53 -07:00
Mark b136353d36
Comments 2023-08-21 13:24:49 -07:00
Mark a125e867c4
Help text typo 2023-08-21 13:24:28 -07:00
Mark c477302c88
Fixed `ans` evaluation 2023-08-21 13:17:58 -07:00
6 changed files with 45 additions and 25 deletions

23
TODO.md
View File

@ -1,4 +1,5 @@
## Version Bump checklist ## Version Bump checklist
- TODO: build and publish script
- update Cargo.toml - update Cargo.toml
- run cargo test - run cargo test
- commit - commit
@ -10,28 +11,22 @@
## Pre-release ## Pre-release
- Fix linelocation (consistent, what does an operator's linelocation mean?)
- Tuple operations - Tuple operations
- we don't need vectors as arguments to operators - we don't need vectors as arguments to operators
- Assignment tests - Fix linelocation when evaluating functions
- Color check is too slow
## Parser ## Parser
- Better error when `sin = 2`
- Should functions be operators? - Should functions be operators?
- Binary, hex, octal numbers - Binary, hex, octal numbers
## General ## General
- Better tests (assignment, many expressions in one context)
- Optional config file - Optional config file
- Optional history file - Optional history file
- daisyrc file
- Compile to WASM, publish a webapp - Compile to WASM, publish a webapp
- evaluate straight from command line - evaluate straight from command line
- Auto-push to crates.io
- Package for debian - Package for debian
- Faster startup
## Internals ## Internals
@ -41,7 +36,6 @@
- Remove rug dependency (too big, incompatible) - Remove rug dependency (too big, incompatible)
## Math Features ## Math Features
- Dice
- Mean, Median, Min - Mean, Median, Min
- Arbitrary base logarithm - Arbitrary base logarithm
- Derivatives - Derivatives
@ -49,21 +43,16 @@
- Complex numbers - Complex numbers
- acot/acoth functions - acot/acoth functions
- Sums and products with functional arguments - Sums and products with functional arguments
- Add functions: gcd, inverse mod - Add functions: gcd, inverse mod, dice
## Prompt ## Prompt
- Fix terminal color detection
- Live syntax/output (like firefox js terminal) - Live syntax/output (like firefox js terminal)
- Syntax highlight input and output - Syntax highlighting
- fish-style tab completion - fish-style tab completion
- Numbered expressions, history recall - Numbered expressions, history recall
- Color configuration
- Enable/disable unit sets (defaults?) - Enable/disable unit sets (defaults?)
- Consistent unit ordering - Consistent unit ordering
- Better linelocation
- we shouldn't need to re-print user input on evaluation errors, red arrows should adjust themselves to the prettyprinted string
- Backend-independent colorful printing
- Better colors in error texts
- Better substitution. Consistent: when ascii, when unicode?
- Command to list substitutions - Command to list substitutions
## Units ## Units

View File

@ -224,7 +224,7 @@ pub fn do_command(
if args.len() != 2 { if args.len() != 2 {
return FormattedText::new( return FormattedText::new(
format!( format!(
"[c]{first}[n] [t]takes exactly two arguments.[n]\n\n", "[c]{first}[n] [t]takes exactly one argument.[n]\n\n",
) )
); );
} }

View File

@ -126,6 +126,7 @@ impl Context {
} else { panic!() } } else { panic!() }
} }
// Can we define a new variable with this name?
pub fn valid_varible(&self, s: &str) -> bool { pub fn valid_varible(&self, s: &str) -> bool {
if { if {
Function::from_string(s).is_some() || Function::from_string(s).is_some() ||
@ -145,10 +146,17 @@ impl Context {
} }
} }
// Can we get a value fro mthis variable name?
pub fn is_varible(&self, s: &str) -> bool { pub fn is_varible(&self, s: &str) -> bool {
return { return {
(
s == "ans" &&
self.history.len() != 0
) ||
(
self.valid_varible(s) && self.valid_varible(s) &&
(self.variables.contains_key(s) || self.shadow.contains_key(s)) (self.variables.contains_key(s) || self.shadow.contains_key(s))
)
}; };
} }

View File

@ -11,6 +11,23 @@ use super::super::LineLocation;
#[derive(Debug)] #[derive(Debug)]
#[derive(Clone)] #[derive(Clone)]
pub enum Expression { pub enum Expression {
// Meaning of `LineLocation`:
//
// For Variables, Constants, Quantities, Tuples:
// If this expression was parsed, LineLocation is what part of the prompt was parsed to get this expression
// If this expression is the result of a calculation, LineLocaion is the sum of the LineLocations of
// all expressions used to make it. In other words, it points to the part of the prompt that was evaluated
// to get this new expression.
//
// For Operators:
// Linelocation points to the operator's position in the prompt.
// If this is a function, it points to the function name.
// If this is `+`, `!`, or etc, it points to that character.
// Operator arguments are NOT included in this linelocation.
//
//
// All the above rules are implemented when parsing and evaluating expressions.
Variable(LineLocation, String), Variable(LineLocation, String),
Quantity(LineLocation, Quantity), Quantity(LineLocation, Quantity),
Constant(LineLocation, Constant), Constant(LineLocation, Constant),

View File

@ -35,6 +35,12 @@ pub fn parse_no_context(s: &String) -> Result<Expression, (LineLocation, DaisyEr
parse(&Context::new(), s) parse(&Context::new(), s)
} }
// Substitiution replaces certain string with pretty unicode characters.
// When it is enabled, ALL input strings are substituted. Variable and
// operator tokens use the replaced string value. Make sure both the
// original and the replaced strings are handled correctly by the parser.
pub fn substitute(context: &Context, s: &String) -> String { pub fn substitute(context: &Context, s: &String) -> String {
if !context.config.enable_substituion { return s.clone(); } if !context.config.enable_substituion { return s.clone(); }
let (_, s) = substitute_cursor(context, s, s.chars().count()); let (_, s) = substitute_cursor(context, s, s.chars().count());

View File

@ -62,13 +62,13 @@ fn sub_string(s: &str) -> Option<&'static str> {
} }
// Finds substitutions in an array of tokens.
// Returns new token array and substitution list.
pub fn find_subs( pub fn find_subs(
mut g: VecDeque<Token>, mut g: VecDeque<Token>,
) -> ( ) -> (
VecDeque<(LineLocation, String)>, VecDeque<(LineLocation, String)>, // List of substrings to replace (in order)
VecDeque<Token> VecDeque<Token> // New token array, with updated strings and linelocations
) { ) {
// Array of replacements // Array of replacements
@ -103,7 +103,7 @@ pub fn find_subs(
}; };
if target.is_none() { if target.is_none() {
// Even if nothing changed, we need to update token location // Even if nothing changed, we need to update the new token's linelocation
let l = t.get_mut_linelocation(); let l = t.get_mut_linelocation();
*l = LineLocation{pos: l.pos - offset, len: l.len}; *l = LineLocation{pos: l.pos - offset, len: l.len};
} else { } else {