Skip to content

Commit

Permalink
Thread (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
meloalright authored Oct 12, 2024
1 parent d3c014b commit 88e7b75
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 7 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/Threading.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: threading

on:
push:
branches:
- '*'
pull_request:
branches:
- main

jobs:
reasoning:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: clippy
override: true

- name: Repl
run: |
cargo build --features="repl" --release
- name: Threading
run: |
./target/release/3body -V
./target/release/3body -c '给 cx 以 程心(); 给 星环公司 以 法则(name, y, limit) { 给 掩体纪年 以 y; 面壁 (掩体纪年 <= limit) { 冬眠(1000); 广播([name, 掩体纪年]); 掩体纪年 = 掩体纪年 + 1; } } cx.thread(星环公司, ["掩体工程", 0, 11]) 冬眠(5000) cx.thread(星环公司, ["研制曲率飞船", 5, 11]) 冬眠(6000)'
./target/release/3body -c '给 cx 以 程心(); 给 星环公司 以 法则(name, y, limit) { 给 掩体纪年 以 y; 面壁 (掩体纪年 <= limit) { 冬眠(1000); 广播([name, 掩体纪年]); 掩体纪年 = 掩体纪年 + 1; } } 给 秘密研究 以 cx.thread(星环公司, ["重启光速飞船的研究", 11, 66]) cx.join(秘密研究)'
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ members = ["interpreter"]
[dependencies]
rustyline = { version = "12.0.0", optional = true }
rustyline-derive = { version = "0.4.0", optional = true }
three_body_interpreter = { version = "0.6.1", path = "./interpreter", features = ["sophon"] }
three_body_interpreter = { version = "0.6.1", path = "./interpreter", features = ["sophon", "threading"] }

[[bin]]
name = "3body"
Expand Down
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ $ 3body
// > true
```
## Summary
|Token|3body-lang|Explanation|
Expand All @@ -215,6 +216,60 @@ $ 3body
|exit|毁灭|"destroy"|
|deep-equal|没关系的都一样|"It's okay. It's all the same."|
## 🧶 Threading
三体编程语言可以通过 "程心" 创建并管理线程。
Able to use threading to create and handle threads.
#### Threads Create
```rust
给 cx 以 程心();

给 星环公司 以 法则(name, y, limit) {
给 掩体纪年 以 y;
面壁 (掩体纪年 <= limit) {
冬眠(1000);
广播([name, 掩体纪年]);
掩体纪年 = 掩体纪年 + 1;
}
}

cx.thread(星环公司, ["掩体工程", 0, 11])
冬眠(5000)
cx.thread(星环公司, ["研制曲率飞船", 5, 11])
冬眠(6000)

// > ["掩体工程", 0]
// ...
// > ["研制曲率飞船", 5]
// > ["掩体工程", 5]
// > ["研制曲率飞船", 6]
// > ["掩体工程", 6]
```
#### Threads Await
```rust
给 cx 以 程心();

给 星环公司 以 法则(name, y, limit) {
给 掩体纪年 以 y;
面壁 (掩体纪年 <= limit) {
冬眠(1000);
广播([name, 掩体纪年]);
掩体纪年 = 掩体纪年 + 1;
}
}

给 秘密研究 以 cx.thread(星环公司, ["重启光速飞船的研究", 11, 66])
cx.join(秘密研究)

// > ["重启光速飞船的研究", 11]
// > ["重启光速飞船的研究", 12]
```
## 🤗 LLM
三体编程语言可以通过 "智子工程" 加载本地大语言模型进行推理。
Expand Down
4 changes: 3 additions & 1 deletion interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ rand = { version = "0.8.5" }
llm = { version = "0.1.1", optional = true }
llm-base = { version = "0.1.1", optional = true }
spinoff = { version = "0.7.0", default-features = false, features = ["dots", "arc", "line"], optional = true }
tokio = { version = "1.40.0", features = ["sync", "time", "macros", "rt-multi-thread"], optional = true }

[features]
default = []
sophon = ["llm", "llm-base", "spinoff"]
sophon = ["llm", "llm-base", "spinoff"]
threading = ["tokio"]
116 changes: 111 additions & 5 deletions interpreter/src/evaluator/builtins.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use std::collections::HashMap;

use std::cell::RefCell;
use std::rc::Rc;

extern crate rand;

use crate::evaluator::object::Object;
use crate::evaluator::object::NativeObject;
use crate::evaluator::env::Env;
use crate::evaluator::Evaluator;
use crate::ast;

use rand::distributions::Uniform;
use rand::{thread_rng, Rng};
Expand Down Expand Up @@ -44,6 +50,11 @@ pub fn new_builtins() -> HashMap<String, Object> {
String::from("智子工程"),
Object::Builtin(1, three_body_sophon_engineering),
);
#[cfg(feature="threading")] // threading
builtins.insert(
String::from("程心"),
Object::Builtin(0, three_body_threading),
);
builtins
}

Expand Down Expand Up @@ -174,7 +185,7 @@ fn three_body_sophon_engineering(args: Vec<Object>) -> Object {
};

let model_type = model_type.as_str();


let model_path = {
match model_path {
Expand Down Expand Up @@ -208,7 +219,7 @@ fn three_body_sophon_engineering(args: Vec<Object>) -> Object {
.unwrap_or_else(|err| {
panic!("Failed to load {model_type} model from {model_path:?}: {err}")
});

let model = Box::leak(model);

println!(
Expand Down Expand Up @@ -289,11 +300,11 @@ fn three_body_sophon_engineering(args: Vec<Object>) -> Object {
|t| {
print!("{t}");
std::io::stdout().flush().unwrap();

Ok(())
},
);

match res {
Err(err) => println!("\n{err}"),
_ => ()
Expand All @@ -315,7 +326,7 @@ fn three_body_sophon_engineering(args: Vec<Object>) -> Object {
NativeObject::LLMModel(model_ptr) => {
model_ptr.clone()
},
_ => panic!()
_ => panic!(),
}
},
_ => panic!()
Expand All @@ -337,6 +348,99 @@ fn three_body_sophon_engineering(args: Vec<Object>) -> Object {
}
}



#[cfg(feature="threading")]
fn three_body_threading(args: Vec<Object>) -> Object {
let mut session_hash = HashMap::new();
{
fn three_body_thread_new(args: Vec<Object>) -> Object {
match &args[0] {
Object::Function(params, ast, env ) => {

let stmts = ast.clone();
let params = params.clone();

let literals: Vec<crate::ast::Literal> = match &args[1] {
Object::Array(arr) => {
arr.iter().map(|o| match o {
Object::Int(i) => ast::Literal::Int(i.clone()),
Object::String(str) => ast::Literal::String(str.clone()),
Object::Bool(bool) => ast::Literal::Bool(bool.clone()),
_ => todo!(),
}).collect()
},
_ => panic!()
};

let mut handle = std::thread::spawn(move || {
let local_set = tokio::task::LocalSet::new();
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();

local_set.spawn_local(async move {
let mut ev = Evaluator {
env: {
let scoped_env = Rc::new(RefCell::new(Env::from(new_builtins())));

for (i, ident) in params.iter().enumerate() {
let crate::ast::Ident(name) = ident.clone();
let o = match &literals[i] {
ast::Literal::Int(i) => Object::Int(i.clone()),
ast::Literal::String(str) => Object::String(str.clone()),
ast::Literal::Bool(bo) => Object::Bool(bo.clone()),
_ => todo!(),
};
scoped_env.borrow_mut().set(name, o.clone());
}

scoped_env
},
};
ev.eval(&stmts);
});

rt.block_on(local_set);
});

let handle = Box::leak(Box::new(handle));
let handle_ptr = &mut *handle as *mut std::thread::JoinHandle<()>;
Object::Native(Box::new(NativeObject::Thread(handle_ptr)))
}
_ => panic!()
}
}
session_hash.insert(Object::String("thread".to_owned()), Object::Builtin(2, three_body_thread_new));
}



{
fn three_body_thread_join(args: Vec<Object>) -> Object {
match &args[0] {
Object::Native(ptr) => {
let handle_ptr = match **ptr {
NativeObject::Thread(handle_ptr) => {
handle_ptr.clone()
}
_ => panic!()
};
unsafe { Box::from_raw(handle_ptr) }.join();
Object::Null
},
_ => panic!()
}
}
session_hash.insert(Object::String("join".to_owned()), Object::Builtin(1, three_body_thread_join));
}


Object::Hash(session_hash)

}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -578,4 +682,6 @@ mod tests {
assert_eq!(got, expected);
}
}


}
2 changes: 2 additions & 0 deletions interpreter/src/evaluator/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub type BuiltinFunc = fn(Vec<Object>) -> Object;
pub enum NativeObject {
#[cfg(feature="sophon")]
LLMModel(*mut dyn llm::Model),
#[cfg(feature="threading")]
Thread(*mut std::thread::JoinHandle<()>),
}

#[derive(PartialEq, Clone, Debug)]
Expand Down

0 comments on commit 88e7b75

Please sign in to comment.