Skip to content

Commit bceb2e3

Browse files
committed
feat(library): 补充 sleep 实现.
修复标准库中错误的异常抛出方式.
1 parent b026fa8 commit bceb2e3

5 files changed

Lines changed: 64 additions & 20 deletions

File tree

lib/system.exf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ function native read();
55

66
function native thread(func);
77
function native thread_exit();
8+
function native nano_sleep(time);
9+
10+
function sleep(time) {
11+
nano_sleep(time * 1000000);
12+
}
813

914
function println(output) {
1015
print(output + "\n");

src/compiler/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl Compiler {
130130
Self::dump_lexer_error(&lex_error, file);
131131
return;
132132
}
133-
ParserError::Eof | ParserError::Empty => {
133+
ParserError::Eof | ParserError::Empty | ParserError::RuntimeError(..) => {
134134
return;
135135
}
136136
ParserError::IdentifierExpected(token) => {

src/compiler/parser/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::compiler::parser::import::import_eval;
2323
use crate::compiler::parser::judgment::if_eval;
2424
use crate::compiler::parser::var::var_eval;
2525
use crate::compiler::parser::r#while::while_eval;
26+
use crate::runtime::RuntimeError;
2627

2728
#[derive(Debug)]
2829
pub enum ParserError {
@@ -44,6 +45,7 @@ pub enum ParserError {
4445
NoNativeImplement(Token), // 无本地实现
4546
NotFoundLibrary(Token), // 找不到库
4647
Empty, // 占位符
48+
RuntimeError(RuntimeError), // 运行时占位符
4749
Eof,
4850
}
4951

src/library/system.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use smol_str::{SmolStr, ToSmolStr};
2-
use std::io;
3-
use std::io::Read;
4-
use std::process::exit;
5-
61
use crate::compiler::ast::vm_ir::Value;
72
use crate::library::{LibModule, ModuleFunc, output_capture::print, register_library};
83
use crate::runtime::RuntimeError;
94
use crate::runtime::context;
5+
use smol_str::{SmolStr, ToSmolStr};
6+
use std::io::Read;
7+
use std::process::exit;
8+
use std::time::Duration;
9+
use std::{io, thread};
1010

1111
fn print_impl(value: Value) {
1212
match value {
@@ -159,6 +159,33 @@ fn reg_thread_exit() -> ModuleFunc {
159159
}
160160
}
161161

162+
#[allow(clippy::unnecessary_wraps)]
163+
fn system_nano_sleep(args: &[Value]) -> Result<Value, RuntimeError> {
164+
let arg_time = args.first().unwrap().clone();
165+
let Value::Int(raw_time) = arg_time else {
166+
return Err(RuntimeError::TypeException(
167+
"nano_sleep: time not a number.".to_smolstr(),
168+
));
169+
};
170+
let time = if raw_time >= 0 {
171+
raw_time as u64
172+
} else {
173+
return Err(RuntimeError::TypeException(
174+
"nano_sleep: time must > 0.".to_smolstr(),
175+
));
176+
};
177+
thread::sleep(Duration::from_nanos(time));
178+
Ok(Value::Null)
179+
}
180+
181+
fn reg_nano_sleep() -> ModuleFunc {
182+
ModuleFunc {
183+
name: SmolStr::new("nano_sleep"),
184+
arity: 1,
185+
func: system_nano_sleep,
186+
}
187+
}
188+
162189
pub fn register_system_lib() {
163190
let mut system_lib = LibModule {
164191
name: SmolStr::new("system"),
@@ -169,5 +196,6 @@ pub fn register_system_lib() {
169196
system_lib.functions.push(reg_read());
170197
system_lib.functions.push(reg_thread());
171198
system_lib.functions.push(reg_thread_exit());
199+
system_lib.functions.push(reg_nano_sleep());
172200
register_library(system_lib);
173201
}

src/runtime/executor.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::runtime::context::SyncTable;
99
use crate::runtime::vm_operation::*;
1010
use crate::runtime::vm_table_opt::*;
1111
use crate::runtime::{MetadataUnit, RuntimeError, SharedGlobals, SharedSync};
12+
use crate::runtime::RuntimeError::NoSuchFunctionException;
1213

1314
pub struct StackFrame<'a> {
1415
pc: usize,
@@ -388,10 +389,9 @@ fn print_and_return(executor: &Executor, failed_status: Option<RuntimeError>) ->
388389
Value::Null
389390
}
390391

391-
fn print_error(executor: &Executor, path: SmolStr) {
392+
fn print_error(executor: &Executor, error: RuntimeError) {
392393
eprintln!(
393-
"RuntimeError: {:?}",
394-
RuntimeError::NoSuchFunctionException(path)
394+
"RuntimeError: {error:?}",
395395
);
396396
for frame in &executor.call_stack {
397397
let name = frame.get_frame_name();
@@ -456,24 +456,33 @@ pub fn call_function(
456456
argument.push(stack_frame.pop_op_stack());
457457
}
458458

459-
if let Ok(lib) = find_library(file, |f| {
459+
match find_library(file, |f| {
460460
if let Some(lib) = f
461461
&& let Some(func) = lib.find_func(&SmolStr::new(func))
462462
{
463-
(func.func)(&argument).map_or(Err(ParserError::Empty), Ok)
463+
match (func.func)(&argument) {
464+
Err(error) => Err(ParserError::RuntimeError(error)),
465+
Ok(ok ) => Ok(ok),
466+
}
464467
} else {
465-
Err(ParserError::Empty)
468+
Err(ParserError::RuntimeError(NoSuchFunctionException(path.clone())))
466469
}
467470
}) {
468-
let mut frame = executor.call_stack.pop().unwrap();
469-
if let Some((unit_index, func_index)) = frame.take_sync_lock() {
470-
sync_table.unlock(unit_index, func_index);
471+
Ok(lib) => {
472+
let mut frame = executor.call_stack.pop().unwrap();
473+
if let Some((unit_index, func_index)) = frame.take_sync_lock() {
474+
sync_table.unlock(unit_index, func_index);
475+
}
476+
executor.call_stack.last_mut().unwrap().push_op_stack(lib);
477+
executor.frame_index -= 1;
478+
},
479+
Err(error) => {
480+
let ParserError::RuntimeError(error) = error else {
481+
unreachable!()
482+
};
483+
print_error(&executor, error);
484+
break;
471485
}
472-
executor.call_stack.last_mut().unwrap().push_op_stack(lib);
473-
executor.frame_index -= 1;
474-
} else {
475-
print_error(&executor, path);
476-
break;
477486
}
478487
} else {
479488
match run_code(units, stack_frame, &globals, &call_cache, &sync_table) {

0 commit comments

Comments
 (0)