use std::collections::HashMap;
use sindra::scope::SymbolStore;
use value::Value;
use Symbol;
use psk_std::Environment;
use psk_std::stdlib::*;
use psk_std::complex::Complex;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ExtFuncIdent {
SetImageDims,
GetImageHeight,
GetImageWidth,
Write,
SetPixelData,
Project,
Re,
Im
}
type FuncResult = Result<Value, String>;
type RustFuncInterface = fn(&mut Environment, Vec<Value>) -> FuncResult;
pub struct StdFuncTable {
func_table: HashMap<ExtFuncIdent, Box<RustFuncInterface>>,
}
impl Default for StdFuncTable {
fn default() -> StdFuncTable {
StdFuncTable {
func_table: HashMap::new(),
}
}
}
impl StdFuncTable {
pub fn call(&self, env: &mut Environment, func: ExtFuncIdent, args: Vec<Value>) -> FuncResult {
self.func_table[&func](env, args)
}
pub fn new<Sc: SymbolStore<Symbol>>(scope: &mut Sc) -> StdFuncTable {
let mut tbl = StdFuncTable::default();
add_func!(scope, tbl.func_table, "set_image_dims", ExtFuncIdent::SetImageDims,
psk_set_image_dims, [("height", "int"), ("width", "int")], PType::Void);
add_func!(scope, tbl.func_table, "get_image_height", ExtFuncIdent::GetImageHeight,
psk_get_image_height, [], PType::Int);
add_func!(scope, tbl.func_table, "get_image_width", ExtFuncIdent::GetImageWidth,
psk_get_image_width, [], PType::Int);
add_func!(scope, tbl.func_table, "write", ExtFuncIdent::Write, psk_write,
[("file", "string")], PType::Void);
add_func!(scope, tbl.func_table, "set_pixel_data", ExtFuncIdent::SetPixelData,
psk_set_pixel_data, [("row", "int"), ("col", "int"), ("value", "float")], PType::Void);
add_func!(scope, tbl.func_table, "project", ExtFuncIdent::Project, psk_project,
[("row", "int"), ("col", "int"), ("center", "complex"), ("size", "complex")],
PType::Complex);
add_func!(scope, tbl.func_table, "re", ExtFuncIdent::Re, psk_re, [("c", "complex")],
PType::Float);
add_func!(scope, tbl.func_table, "im", ExtFuncIdent::Im, psk_im, [("c", "complex")],
PType::Float);
tbl
}
}
add_interpreter_func!(psk_set_image_dims, set_image_dims, [i64, i64], |_| Value::Empty);
add_interpreter_func!(psk_get_image_height, get_image_height, [], |i| Value::Int(i as i64));
add_interpreter_func!(psk_get_image_width, get_image_width, [], |i| Value::Int(i as i64));
add_interpreter_func!(psk_set_pixel_data, set_pixel_data, [i64, i64, f64], |_| Value::Empty);
add_interpreter_func!(psk_write, write, [String], |_| Value::Empty);
add_interpreter_func!(psk_project, project, [i64, i64, Complex, Complex],
|c| Value::Complex(c.re, c.im));
add_interpreter_func!(psk_re, re, [Complex], |f| Value::Float(f));
add_interpreter_func!(psk_im, im, [Complex], |f| Value::Float(f));