Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread #48

Merged
merged 8 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading