wip
This commit is contained in:
parent
6e02a1a644
commit
463e4abd30
13 changed files with 172 additions and 26 deletions
|
@ -3,7 +3,7 @@ use ordered_float::OrderedFloat;
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
io::{BufReader, ErrorKind, Read},
|
||||
io::{stdin, stdout, BufReader, ErrorKind, Read, Seek, SeekFrom, Write},
|
||||
rc::Rc,
|
||||
sync::RwLock,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
|
@ -53,7 +53,7 @@ impl Callable for ReadFile {
|
|||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
1
|
||||
2
|
||||
}
|
||||
|
||||
fn call(
|
||||
|
@ -61,18 +61,24 @@ impl Callable for ReadFile {
|
|||
_interpreter: &mut Interpreter,
|
||||
args: Vec<Value>,
|
||||
) -> Result<Value, CallingError> {
|
||||
if args.len() != self.arity() {
|
||||
return Err(CallingError::ArgumentMismatch(self.arity(), args.len()));
|
||||
}
|
||||
|
||||
let file_path = args
|
||||
.first()
|
||||
.ok_or(CallingError::CallFailed("arg not readable".into()))?;
|
||||
let file_path = args.first().ok_or(CallingError::CallFailed(
|
||||
"first arg must be file path".into(),
|
||||
))?;
|
||||
if let Value::String(file_path) = file_path {
|
||||
self.ensure_file_handle(file_path)?;
|
||||
let mut file_handles = FILE_HANDLES.write().unwrap();
|
||||
let reader = file_handles.get_mut(file_path).unwrap();
|
||||
let mut buffer = [0; 1];
|
||||
|
||||
let backwards = args.get(1).unwrap_or(&Value::Boolean(false));
|
||||
if let Value::Boolean(backwards) = backwards {
|
||||
if *backwards {
|
||||
reader
|
||||
.seek(SeekFrom::Current(-2))
|
||||
.map_err(|e| CallingError::CallFailed(e.to_string()))?;
|
||||
}
|
||||
}
|
||||
|
||||
let character = match reader.read_exact(&mut buffer) {
|
||||
Ok(_) => {
|
||||
let character = buffer[0] as char;
|
||||
|
@ -143,9 +149,81 @@ impl Callable for Out {
|
|||
}
|
||||
}
|
||||
|
||||
struct AsciiOut;
|
||||
impl Callable for AsciiOut {
|
||||
fn name(&self) -> String {
|
||||
"asciiOut".into()
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn call(&self, interpreter: &mut Interpreter, args: Vec<Value>) -> Result<Value, CallingError> {
|
||||
if args.len() != self.arity() {
|
||||
return Err(CallingError::ArgumentMismatch(self.arity(), args.len()));
|
||||
}
|
||||
|
||||
let value = args
|
||||
.first()
|
||||
.ok_or(CallingError::CallFailed("arg not readable".into()))?;
|
||||
if let Value::Number(value) = value {
|
||||
let ascii = value.0 as u8 as char;
|
||||
print!("{ascii}");
|
||||
|
||||
Ok(Value::Nil)
|
||||
} else {
|
||||
Err(CallingError::CallFailed(
|
||||
"file_path arg must be a number".into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PromptAscii;
|
||||
impl Callable for PromptAscii {
|
||||
fn name(&self) -> String {
|
||||
"prompt_ascii".into()
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn call(
|
||||
&self,
|
||||
_interpreter: &mut Interpreter,
|
||||
args: Vec<Value>,
|
||||
) -> Result<Value, CallingError> {
|
||||
if args.len() != self.arity() {
|
||||
return Err(CallingError::ArgumentMismatch(self.arity(), args.len()));
|
||||
}
|
||||
|
||||
let prompt = args
|
||||
.first()
|
||||
.ok_or(CallingError::CallFailed("arg not readable".into()))?;
|
||||
if let Value::String(prompt) = prompt {
|
||||
print!("{prompt} ");
|
||||
stdout().flush();
|
||||
|
||||
let mut buffer = [0; 1];
|
||||
stdin().read_exact(&mut buffer);
|
||||
|
||||
todo!()
|
||||
// Ok(Value::Number(buffer[0] as char))
|
||||
} else {
|
||||
Err(CallingError::CallFailed("prompt must be a string".into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return all native functions available to the Lox interpreter
|
||||
pub fn all() -> Vec<(String, Value)> {
|
||||
vec![
|
||||
(
|
||||
"asciiOut".into(),
|
||||
Value::Callable((Rc::new(AsciiOut {}), CallableType::Function)),
|
||||
),
|
||||
(
|
||||
"clock".into(),
|
||||
Value::Callable((Rc::new(Clock {}), CallableType::Function)),
|
||||
|
@ -158,5 +236,9 @@ pub fn all() -> Vec<(String, Value)> {
|
|||
"read".into(),
|
||||
Value::Callable((Rc::new(ReadFile {}), CallableType::Function)),
|
||||
),
|
||||
(
|
||||
"prompt".into(),
|
||||
Value::Callable((Rc::new(PromptAscii {}), CallableType::Function)),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue