mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-03-13 04:48:17 +01:00
Support loading files in config dir
This commit is contained in:
parent
474b4d9016
commit
dbf3866137
@ -9,10 +9,10 @@ use std::io::Read;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let app = App::new("kalk")
|
||||
let app = App::new("kalker")
|
||||
.author(env!("CARGO_PKG_AUTHORS"))
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.usage("kalk [options] [input]")
|
||||
.usage("kalker [options] [input]")
|
||||
.action(default_action)
|
||||
.flag(
|
||||
Flag::new("input-file", FlagType::String)
|
||||
@ -55,6 +55,10 @@ fn default_action(context: &Context) {
|
||||
.int_flag("precision")
|
||||
.unwrap_or(output::DEFAULT_PRECISION as isize) as u32;
|
||||
|
||||
if let Some(input_file_path) = get_input_file_by_name("default") {
|
||||
load_input_file(&input_file_path, precision, &mut parser_context);
|
||||
}
|
||||
|
||||
if let Ok(input_file_path) = context.string_flag("input-file") {
|
||||
load_input_file(&input_file_path, precision, &mut parser_context);
|
||||
}
|
||||
@ -68,7 +72,20 @@ fn default_action(context: &Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_input_file(file_name: &str, precision: u32, parser_context: &mut parser::Context) {
|
||||
pub(crate) fn get_input_file_by_name(name: &str) -> Option<String> {
|
||||
let mut path = dirs::config_dir()?;
|
||||
path.push("kalker");
|
||||
path.push(name);
|
||||
path.set_extension("kalker");
|
||||
|
||||
if path.exists() {
|
||||
Some(path.to_str()?.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_input_file(file_name: &str, precision: u32, parser_context: &mut parser::Context) {
|
||||
let mut file_content = String::new();
|
||||
File::open(&file_name)
|
||||
.expect("Couldn't find file.")
|
||||
@ -77,7 +94,9 @@ fn load_input_file(file_name: &str, precision: u32, parser_context: &mut parser:
|
||||
|
||||
// Parse the input file content, resulting in the symbol table being filled out.
|
||||
// Output is not needed here.
|
||||
parser::eval(parser_context, &file_content, precision).expect("Failed to parse input file.");
|
||||
if let Err(error) = parser::eval(parser_context, &file_content, precision) {
|
||||
eprintln!("{}", error.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
fn get_env_angle_unit() -> String {
|
||||
|
@ -74,6 +74,16 @@ pub fn start(mut parser: &mut parser::Context, precision: u32) {
|
||||
}
|
||||
|
||||
fn eval_repl(parser: &mut parser::Context, input: &str, precision: u32) {
|
||||
if input.starts_with("load ") {
|
||||
let file_name = &input[5..];
|
||||
if let Some(file_path) = crate::get_input_file_by_name(file_name) {
|
||||
crate::load_input_file(&file_path, precision, parser);
|
||||
} else {
|
||||
println!("Unable to find '{}'", file_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
match input {
|
||||
"" => eprint!(""),
|
||||
"clear" => print!("\x1B[2J"),
|
||||
@ -96,7 +106,7 @@ impl Highlighter for LineHighlighter {
|
||||
|
||||
let reg = Regex::new(
|
||||
r"(?x)
|
||||
(?P<op>([+\-/*%^!×÷]|if|otherwise)) |
|
||||
(?P<op>([+\-/*%^!×÷]|if|otherwise|load|exit|clear|help)) |
|
||||
(?P<radix>0[box][a-zA-Z0-9]+) |
|
||||
(?P<identifier>[^!-@\s_|^⌊⌋⌈⌉\[\]\{\}≠≥≤⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎]+(_\d+)?)",
|
||||
)
|
||||
|
@ -42,6 +42,7 @@ pub enum TokenKind {
|
||||
ClosedBrace,
|
||||
Comma,
|
||||
Semicolon,
|
||||
Newline,
|
||||
|
||||
EOF,
|
||||
}
|
||||
@ -97,7 +98,7 @@ impl<'a> Lexer<'a> {
|
||||
return eof;
|
||||
};
|
||||
|
||||
while c == ' ' || c == '\t' || c == '\r' || c == '\n' {
|
||||
while c == ' ' || c == '\t' || c == '\r' {
|
||||
if let None = self.advance() {
|
||||
return eof;
|
||||
}
|
||||
@ -141,6 +142,7 @@ impl<'a> Lexer<'a> {
|
||||
'<' => build(TokenKind::LessThan, "", span),
|
||||
',' => build(TokenKind::Comma, "", span),
|
||||
';' => build(TokenKind::Semicolon, "", span),
|
||||
'\n' => build(TokenKind::Newline, "", span),
|
||||
'%' => build(TokenKind::Percent, "", span),
|
||||
'\'' => build(TokenKind::Tick, "", span),
|
||||
'≠' => build(TokenKind::NotEquals, "", span),
|
||||
@ -350,7 +352,7 @@ fn is_valid_identifier(c: Option<&char>) -> bool {
|
||||
match c {
|
||||
'+' | '-' | '/' | '*' | '%' | '^' | '!' | '(' | ')' | '=' | '.' | ',' | ';' | '|'
|
||||
| '⌊' | '⌋' | '⌈' | '⌉' | '[' | ']' | '{' | '}' | 'π' | '√' | 'τ' | 'ϕ' | 'Γ' | '<'
|
||||
| '>' | '≠' | '≥' | '≤' | '×' | '÷' => false,
|
||||
| '>' | '≠' | '≥' | '≤' | '×' | '÷' | '\n' => false,
|
||||
_ => !c.is_digit(10) || is_superscript(c) || is_subscript(c),
|
||||
}
|
||||
} else {
|
||||
|
@ -205,6 +205,8 @@ pub fn parse(context: &mut Context, input: &str) -> Result<Vec<Stmt>, CalcError>
|
||||
if match_token(context, TokenKind::Semicolon) {
|
||||
advance(context);
|
||||
}
|
||||
|
||||
skip_newlines(context);
|
||||
}
|
||||
|
||||
Ok(statements)
|
||||
@ -283,6 +285,7 @@ fn parse_identifier_stmt(context: &mut Context) -> Result<Stmt, CalcError> {
|
||||
|
||||
fn parse_piecewise(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
advance(context);
|
||||
skip_newlines(context);
|
||||
|
||||
let mut pieces = Vec::new();
|
||||
let mut reached_otherwise = false;
|
||||
@ -314,10 +317,18 @@ fn parse_piecewise(context: &mut Context) -> Result<Expr, CalcError> {
|
||||
return Err(CalcError::ExpectedIf);
|
||||
}
|
||||
|
||||
advance(context);
|
||||
previous(context).kind == TokenKind::Semicolon && !reached_otherwise
|
||||
if match_token(context, TokenKind::Semicolon) {
|
||||
advance(context);
|
||||
}
|
||||
skip_newlines(context);
|
||||
|
||||
(previous(context).kind == TokenKind::Semicolon
|
||||
|| previous(context).kind == TokenKind::Newline)
|
||||
&& !reached_otherwise
|
||||
} {}
|
||||
|
||||
advance(context);
|
||||
|
||||
Ok(Expr::Piecewise(pieces))
|
||||
}
|
||||
|
||||
@ -864,6 +875,12 @@ fn is_at_end(context: &Context) -> bool {
|
||||
context.pos >= context.tokens.len() || peek(context).kind == TokenKind::EOF
|
||||
}
|
||||
|
||||
fn skip_newlines(context: &mut Context) {
|
||||
while match_token(context, TokenKind::Newline) {
|
||||
advance(context);
|
||||
}
|
||||
}
|
||||
|
||||
fn string_to_num(value: &str) -> Result<f64, CalcError> {
|
||||
let base = get_base(value)?;
|
||||
if let Some(result) = crate::radix::parse_float_radix(&value.replace(" ", ""), base) {
|
||||
|
Loading…
Reference in New Issue
Block a user