mirror of
https://github.com/PaddiM8/kalker.git
synced 2024-11-08 00:44:40 +01:00
Interpretation timeout
This commit is contained in:
parent
58bb2fd60f
commit
b7153d68b7
@ -12,15 +12,24 @@ pub struct Context<'a> {
|
|||||||
angle_unit: String,
|
angle_unit: String,
|
||||||
precision: u32,
|
precision: u32,
|
||||||
sum_n_value: Option<i128>,
|
sum_n_value: Option<i128>,
|
||||||
|
timeout: Option<u32>,
|
||||||
|
start_time: std::time::SystemTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context<'a> {
|
impl<'a> Context<'a> {
|
||||||
pub fn new(symbol_table: &'a mut SymbolTable, angle_unit: &str, precision: u32) -> Self {
|
pub fn new(
|
||||||
|
symbol_table: &'a mut SymbolTable,
|
||||||
|
angle_unit: &str,
|
||||||
|
precision: u32,
|
||||||
|
timeout: Option<u32>,
|
||||||
|
) -> Self {
|
||||||
Context {
|
Context {
|
||||||
angle_unit: angle_unit.into(),
|
angle_unit: angle_unit.into(),
|
||||||
symbol_table,
|
symbol_table,
|
||||||
precision,
|
precision,
|
||||||
sum_n_value: None,
|
sum_n_value: None,
|
||||||
|
timeout: timeout,
|
||||||
|
start_time: std::time::SystemTime::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +91,12 @@ fn eval_expr_stmt(context: &mut Context, expr: &Expr) -> Result<KalkNum, CalcErr
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn eval_expr(context: &mut Context, expr: &Expr, unit: &str) -> Result<KalkNum, CalcError> {
|
fn eval_expr(context: &mut Context, expr: &Expr, unit: &str) -> Result<KalkNum, CalcError> {
|
||||||
|
if let (Ok(elapsed), Some(timeout)) = (context.start_time.elapsed(), context.timeout) {
|
||||||
|
if elapsed.as_secs() >= timeout as u64 {
|
||||||
|
return Err(CalcError::TimedOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Binary(left, op, right) => eval_binary_expr(context, &left, op, &right, unit),
|
Expr::Binary(left, op, right) => eval_binary_expr(context, &left, op, &right, unit),
|
||||||
Expr::Unary(op, expr) => eval_unary_expr(context, op, expr, unit),
|
Expr::Unary(op, expr) => eval_unary_expr(context, op, expr, unit),
|
||||||
@ -352,7 +367,7 @@ mod tests {
|
|||||||
.insert(DEG_RAD_UNIT.clone())
|
.insert(DEG_RAD_UNIT.clone())
|
||||||
.insert(RAD_DEG_UNIT.clone());
|
.insert(RAD_DEG_UNIT.clone());
|
||||||
|
|
||||||
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION, None);
|
||||||
context.interpret(vec![stmt])
|
context.interpret(vec![stmt])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,8 +443,8 @@ mod tests {
|
|||||||
deg_symbol_table
|
deg_symbol_table
|
||||||
.insert(DEG_RAD_UNIT.clone())
|
.insert(DEG_RAD_UNIT.clone())
|
||||||
.insert(RAD_DEG_UNIT.clone());
|
.insert(RAD_DEG_UNIT.clone());
|
||||||
let mut rad_context = Context::new(&mut rad_symbol_table, "rad", PRECISION);
|
let mut rad_context = Context::new(&mut rad_symbol_table, "rad", PRECISION, None);
|
||||||
let mut deg_context = Context::new(&mut deg_symbol_table, "deg", PRECISION);
|
let mut deg_context = Context::new(&mut deg_symbol_table, "deg", PRECISION, None);
|
||||||
|
|
||||||
assert!(cmp(
|
assert!(cmp(
|
||||||
rad_context
|
rad_context
|
||||||
@ -452,7 +467,7 @@ mod tests {
|
|||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
symbol_table.insert(var_decl("x", literal(1f64)));
|
symbol_table.insert(var_decl("x", literal(1f64)));
|
||||||
|
|
||||||
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
context.interpret(vec![stmt]).unwrap().unwrap().to_f64(),
|
context.interpret(vec![stmt]).unwrap().unwrap().to_f64(),
|
||||||
1f64
|
1f64
|
||||||
@ -473,7 +488,7 @@ mod tests {
|
|||||||
fn test_var_decl() {
|
fn test_var_decl() {
|
||||||
let stmt = var_decl("x", literal(1f64));
|
let stmt = var_decl("x", literal(1f64));
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
Context::new(&mut symbol_table, "rad", PRECISION)
|
Context::new(&mut symbol_table, "rad", PRECISION, None)
|
||||||
.interpret(vec![stmt])
|
.interpret(vec![stmt])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -492,7 +507,7 @@ mod tests {
|
|||||||
binary(var("x"), TokenKind::Plus, literal(2f64)),
|
binary(var("x"), TokenKind::Plus, literal(2f64)),
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut context = Context::new(&mut symbol_table, "rad", PRECISION);
|
let mut context = Context::new(&mut symbol_table, "rad", PRECISION, None);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
context.interpret(vec![stmt]).unwrap().unwrap().to_f64(),
|
context.interpret(vec![stmt]).unwrap().unwrap().to_f64(),
|
||||||
3f64
|
3f64
|
||||||
|
@ -24,6 +24,7 @@ pub struct Context {
|
|||||||
pos: usize,
|
pos: usize,
|
||||||
symbol_table: SymbolTable,
|
symbol_table: SymbolTable,
|
||||||
angle_unit: String,
|
angle_unit: String,
|
||||||
|
timeout: Option<u32>,
|
||||||
/// This is true whenever the parser is currently parsing a unit declaration.
|
/// This is true whenever the parser is currently parsing a unit declaration.
|
||||||
/// It is necessary to keep track of this in order to know when to find (figure out) units that haven't been defined yet.
|
/// It is necessary to keep track of this in order to know when to find (figure out) units that haven't been defined yet.
|
||||||
/// Unit names are instead treated as variables.
|
/// Unit names are instead treated as variables.
|
||||||
@ -43,6 +44,7 @@ impl Context {
|
|||||||
pos: 0,
|
pos: 0,
|
||||||
symbol_table: SymbolTable::new(),
|
symbol_table: SymbolTable::new(),
|
||||||
angle_unit: DEFAULT_ANGLE_UNIT.into(),
|
angle_unit: DEFAULT_ANGLE_UNIT.into(),
|
||||||
|
timeout: None,
|
||||||
parsing_unit_decl: false,
|
parsing_unit_decl: false,
|
||||||
unit_decl_base_unit: None,
|
unit_decl_base_unit: None,
|
||||||
parsing_identifier_stmt: false,
|
parsing_identifier_stmt: false,
|
||||||
@ -60,6 +62,12 @@ impl Context {
|
|||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_timeout(mut self, timeout: Option<u32>) -> Self {
|
||||||
|
self.timeout = timeout;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Context {
|
impl Default for Context {
|
||||||
@ -75,6 +83,7 @@ pub enum CalcError {
|
|||||||
InvalidNumberLiteral(String),
|
InvalidNumberLiteral(String),
|
||||||
InvalidOperator,
|
InvalidOperator,
|
||||||
InvalidUnit,
|
InvalidUnit,
|
||||||
|
TimedOut,
|
||||||
UnexpectedToken(TokenKind, TokenKind),
|
UnexpectedToken(TokenKind, TokenKind),
|
||||||
UndefinedFn(String),
|
UndefinedFn(String),
|
||||||
UndefinedVar(String),
|
UndefinedVar(String),
|
||||||
@ -95,8 +104,12 @@ pub fn eval(
|
|||||||
context.contains_equal_sign = input.contains("=");
|
context.contains_equal_sign = input.contains("=");
|
||||||
let statements = parse(context, input)?;
|
let statements = parse(context, input)?;
|
||||||
|
|
||||||
let mut interpreter =
|
let mut interpreter = interpreter::Context::new(
|
||||||
interpreter::Context::new(&mut context.symbol_table, &context.angle_unit, precision);
|
&mut context.symbol_table,
|
||||||
|
&context.angle_unit,
|
||||||
|
precision,
|
||||||
|
context.timeout,
|
||||||
|
);
|
||||||
interpreter.interpret(statements)
|
interpreter.interpret(statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +50,9 @@ fn default_action(context: &Context) {
|
|||||||
} else {
|
} else {
|
||||||
get_env_angle_unit()
|
get_env_angle_unit()
|
||||||
};
|
};
|
||||||
let mut parser_context = parser::Context::new().set_angle_unit(&angle_unit);
|
let mut parser_context = parser::Context::new()
|
||||||
|
.set_angle_unit(&angle_unit)
|
||||||
|
.set_timeout(Some(5));
|
||||||
let precision = context.int_flag("precision").unwrap_or(53isize) as u32;
|
let precision = context.int_flag("precision").unwrap_or(53isize) as u32;
|
||||||
|
|
||||||
if let Ok(input_file_path) = context.string_flag("input-file") {
|
if let Ok(input_file_path) = context.string_flag("input-file") {
|
||||||
|
@ -35,6 +35,7 @@ fn print_calc_err(err: CalcError) {
|
|||||||
InvalidNumberLiteral(x) => format!("Invalid number literal: '{}'.", x),
|
InvalidNumberLiteral(x) => format!("Invalid number literal: '{}'.", x),
|
||||||
InvalidOperator => format!("Invalid operator."),
|
InvalidOperator => format!("Invalid operator."),
|
||||||
InvalidUnit => format!("Invalid unit."),
|
InvalidUnit => format!("Invalid unit."),
|
||||||
|
TimedOut => format!("Operation took too long."),
|
||||||
UnexpectedToken(got, expected) => {
|
UnexpectedToken(got, expected) => {
|
||||||
format!("Unexpected token: '{:?}', expected '{:?}'.", got, expected)
|
format!("Unexpected token: '{:?}', expected '{:?}'.", got, expected)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user