From f3de183607c6113a4c1ea2dba96ec49b001c078a Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Sat, 30 Apr 2022 04:14:44 +0900 Subject: [PATCH 1/4] Add example kybra_like --- examples/kybra_like.py | 90 ++++++++++++++++++++++++++++++++++++++++++ examples/kybra_like.rs | 27 +++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 examples/kybra_like.py create mode 100644 examples/kybra_like.rs diff --git a/examples/kybra_like.py b/examples/kybra_like.py new file mode 100644 index 000000000..c94ad3f59 --- /dev/null +++ b/examples/kybra_like.py @@ -0,0 +1,90 @@ +from dataclasses import dataclass +from typing import Dict, Any + +Query = Any +Update = Any +nat64 = Any + +__all__ = [ + "initialize_supply", + "transfer", + "balance", + "ticker", + "name", + "total_supply", +] + + +@dataclass +class Account: + address: str + balance: nat64 + + +@dataclass +class State: + accounts: Dict[str, Account] + total_supply: nat64 + ticker: str + name: str + + +state = State( + accounts={}, + total_supply=0, + ticker="", + name="KYBRA", +) + + +def initialize_supply( + ticker: str, name: str, total_supply: nat64, original_address: str +) -> Update: + global state + state = State( + accounts={ + original_address: Account( + address=original_address, + balance=total_supply, + ) + }, + ticker=ticker, + name=name, + total_supply=total_supply, + ) + + return True + + +def transfer(from_: str, to: str, amount: nat64) -> Update: + global state + if state.accounts[to] is None: + state.accounts[to] = Account(address=to, balance=0) + + state.accounts[from_].balance -= amount + state.accounts[to].balance += amount + + return True + + +def balance(address: str) -> Query: + account = state.accounts[address] + if account is None: + return 0 + return account.balance + + +def ticker() -> Query: + return state.ticker + + +def name() -> Query: + return state.name + + +def total_supply() -> Query: + return state.total_supply + + +if __name__ == "__main__": + print(name()) diff --git a/examples/kybra_like.rs b/examples/kybra_like.rs new file mode 100644 index 000000000..ae7ef9aaf --- /dev/null +++ b/examples/kybra_like.rs @@ -0,0 +1,27 @@ +use rustpython_vm as vm; +use vm::builtins::PyStrRef; + +fn main() -> vm::PyResult<()> { + let interp = vm::Interpreter::with_init(Default::default(), |vm| { + vm.add_native_modules(rustpython_stdlib::get_module_inits()); + }); + let result = interp + .run_or_else( + |vm, exc| { + vm.print_exception(exc.clone()); + Err(exc) + }, + |vm| { + vm.insert_sys_path(vm.new_pyobj("examples")) + .expect("add path"); + let module = vm.import("kybra_like", None, 0)?; + let name_func = module.get_attr("name", vm)?; + let result = vm.invoke(&name_func, ())?; + let result: PyStrRef = result.try_into_value(vm)?; + Ok(result) + }, + ) + .unwrap(); + println!("name: {}", &result); + Ok(()) +} From fcd564ad9701dabfd1a5e460e8a85f78fb8508c4 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Sat, 30 Apr 2022 20:26:51 +0900 Subject: [PATCH 2/4] Replace kybra_like to project-neutral example --- examples/kybra_like.py | 90 --------------------------------------- examples/kybra_like.rs | 27 ------------ examples/package_embed.py | 24 +++++++++++ examples/package_embed.rs | 27 ++++++++++++ 4 files changed, 51 insertions(+), 117 deletions(-) delete mode 100644 examples/kybra_like.py delete mode 100644 examples/kybra_like.rs create mode 100644 examples/package_embed.py create mode 100644 examples/package_embed.rs diff --git a/examples/kybra_like.py b/examples/kybra_like.py deleted file mode 100644 index c94ad3f59..000000000 --- a/examples/kybra_like.py +++ /dev/null @@ -1,90 +0,0 @@ -from dataclasses import dataclass -from typing import Dict, Any - -Query = Any -Update = Any -nat64 = Any - -__all__ = [ - "initialize_supply", - "transfer", - "balance", - "ticker", - "name", - "total_supply", -] - - -@dataclass -class Account: - address: str - balance: nat64 - - -@dataclass -class State: - accounts: Dict[str, Account] - total_supply: nat64 - ticker: str - name: str - - -state = State( - accounts={}, - total_supply=0, - ticker="", - name="KYBRA", -) - - -def initialize_supply( - ticker: str, name: str, total_supply: nat64, original_address: str -) -> Update: - global state - state = State( - accounts={ - original_address: Account( - address=original_address, - balance=total_supply, - ) - }, - ticker=ticker, - name=name, - total_supply=total_supply, - ) - - return True - - -def transfer(from_: str, to: str, amount: nat64) -> Update: - global state - if state.accounts[to] is None: - state.accounts[to] = Account(address=to, balance=0) - - state.accounts[from_].balance -= amount - state.accounts[to].balance += amount - - return True - - -def balance(address: str) -> Query: - account = state.accounts[address] - if account is None: - return 0 - return account.balance - - -def ticker() -> Query: - return state.ticker - - -def name() -> Query: - return state.name - - -def total_supply() -> Query: - return state.total_supply - - -if __name__ == "__main__": - print(name()) diff --git a/examples/kybra_like.rs b/examples/kybra_like.rs deleted file mode 100644 index ae7ef9aaf..000000000 --- a/examples/kybra_like.rs +++ /dev/null @@ -1,27 +0,0 @@ -use rustpython_vm as vm; -use vm::builtins::PyStrRef; - -fn main() -> vm::PyResult<()> { - let interp = vm::Interpreter::with_init(Default::default(), |vm| { - vm.add_native_modules(rustpython_stdlib::get_module_inits()); - }); - let result = interp - .run_or_else( - |vm, exc| { - vm.print_exception(exc.clone()); - Err(exc) - }, - |vm| { - vm.insert_sys_path(vm.new_pyobj("examples")) - .expect("add path"); - let module = vm.import("kybra_like", None, 0)?; - let name_func = module.get_attr("name", vm)?; - let result = vm.invoke(&name_func, ())?; - let result: PyStrRef = result.try_into_value(vm)?; - Ok(result) - }, - ) - .unwrap(); - println!("name: {}", &result); - Ok(()) -} diff --git a/examples/package_embed.py b/examples/package_embed.py new file mode 100644 index 000000000..6aeb723ac --- /dev/null +++ b/examples/package_embed.py @@ -0,0 +1,24 @@ +from dataclasses import dataclass +from typing import Any + +__all__ = ["context"] + + +@dataclass +class Context: + name: str + something: Any + + +_context = Context( + name="test name", + something=None, +) + + +def context() -> Context: + return _context + + +if __name__ == "__main__": + print(context().name) diff --git a/examples/package_embed.rs b/examples/package_embed.rs new file mode 100644 index 000000000..664ea6d3c --- /dev/null +++ b/examples/package_embed.rs @@ -0,0 +1,27 @@ +use rustpython_vm as vm; +use vm::{builtins::PyStrRef, Interpreter}; + +fn py_main(interp: &Interpreter) -> vm::PyResult { + interp.enter(|vm| { + vm.insert_sys_path(vm.new_pyobj("examples")) + .expect("add path"); + let module = vm.import("package_embed", None, 0)?; + let name_func = module.get_attr("context", vm)?; + let result = vm.invoke(&name_func, ())?; + let result: PyStrRef = result.get_attr("name", vm)?.try_into_value(vm)?; + vm::PyResult::Ok(result) + }) +} + +fn main() -> vm::PyResult<()> { + let interp = vm::Interpreter::with_init(Default::default(), |vm| { + vm.add_native_modules(rustpython_stdlib::get_module_inits()); + }); + let result = py_main(&interp); + let result = result.and_then(|result| { + println!("name: {}", result); + Ok(()) + }); + let exit_code = interp.run(|_vm| result); + std::process::exit(exit_code); +} From eb8c640518217166713d2231330de7120d9bae41 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Sat, 30 Apr 2022 05:01:56 +0900 Subject: [PATCH 3/4] generator sample --- examples/generator.rs | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 examples/generator.rs diff --git a/examples/generator.rs b/examples/generator.rs new file mode 100644 index 000000000..228f043ac --- /dev/null +++ b/examples/generator.rs @@ -0,0 +1,51 @@ +use rustpython_vm as vm; +use vm::{ + builtins::PyIntRef, + protocol::{PyIter, PyIterReturn}, + Interpreter, PyResult, +}; + +fn py_main(interp: &Interpreter) -> vm::PyResult<()> { + let generator = interp.enter(|vm| { + let scope = vm.new_scope_with_builtins(); + let _ = vm.run_code_string( + scope.clone(), + r#" +def gen(): + for i in range(10): + yield i + +generator = gen() +"#, + "".to_owned(), + )?; + let generator = scope.globals.get_item("generator", vm)?; + Ok(generator) + })?; + + loop { + let r = interp.enter(|vm| { + let v = match PyIter::new(generator.clone()).next(vm)? { + PyIterReturn::Return(obj) => { + PyIterReturn::Return(obj.try_into_value::(vm)?) + } + PyIterReturn::StopIteration(x) => PyIterReturn::StopIteration(x), + }; + PyResult::Ok(v) + })?; + match r { + PyIterReturn::Return(value) => println!("{}", value), + PyIterReturn::StopIteration(_) => break, + } + } + + Ok(()) +} + +fn main() { + let interp = vm::Interpreter::with_init(Default::default(), |vm| { + vm.add_native_modules(rustpython_stdlib::get_module_inits()); + }); + let result = py_main(&interp); + std::process::exit(interp.run(|_vm| result)); +} From bae68873dd8112d3898160d26b7252578279d392 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Mon, 2 May 2022 04:12:17 +0900 Subject: [PATCH 4/4] Adapt BlockExpr to example/generator.rs --- examples/generator.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/generator.rs b/examples/generator.rs index 228f043ac..49c37f52e 100644 --- a/examples/generator.rs +++ b/examples/generator.rs @@ -8,18 +8,16 @@ use vm::{ fn py_main(interp: &Interpreter) -> vm::PyResult<()> { let generator = interp.enter(|vm| { let scope = vm.new_scope_with_builtins(); - let _ = vm.run_code_string( + let generator = vm.run_block_expr( scope.clone(), r#" def gen(): for i in range(10): yield i -generator = gen() +gen() "#, - "".to_owned(), )?; - let generator = scope.globals.get_item("generator", vm)?; Ok(generator) })?;