forked from Rust-related/RustPython
Make the parser and vm two separate crates
This commit is contained in:
927
Cargo.lock
generated
927
Cargo.lock
generated
@@ -1,4 +1,927 @@
|
||||
[[package]]
|
||||
name = "RustPython"
|
||||
version = "0.1.0"
|
||||
name = "aho-corasick"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ascii-canvas"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "docopt"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ena"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lalrpop-snap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop-snap"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop-util"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ordermap"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.7.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.7.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rustpython_parser 0.0.1",
|
||||
"rustpython_vm 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython_parser"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lalrpop 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython_vm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_codegen"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_codegen_internals"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_codegen 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache_codegen"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string_cache_shared"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-util"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "wincolor"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
|
||||
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd1479b7c29641adbd35ff3b5c293922d696a92f25c8c975da3e0acbc87258f"
|
||||
"checksum ascii-canvas 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b385d69402821a1c254533a011a312531cbcc0e3e24f19bbb4747a5a2daf37e2"
|
||||
"checksum atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0fd4c0631f06448cc45a6bbb3b710ebb7ff8ccb96a0800c994afe23a70d5df2"
|
||||
"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
|
||||
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
|
||||
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
|
||||
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
|
||||
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
|
||||
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||
"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
|
||||
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
|
||||
"checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
|
||||
"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
|
||||
"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
|
||||
"checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d"
|
||||
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
|
||||
"checksum ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe5a5078ac8c506d3e4430763b1ba9b609b1286913e7d08e581d1c2de9b7e5"
|
||||
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
|
||||
"checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a"
|
||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||
"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
|
||||
"checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
|
||||
"checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lalrpop 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ba451f7bd819b7afc99d4cf4bdcd5a4861e64955ba9680ac70df3a50625ad6cf"
|
||||
"checksum lalrpop-snap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "60013fd6be14317d43f47658b1440956a9ca48a9ed0257e0e0a59aac13e43a1f"
|
||||
"checksum lalrpop-util 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "60c6c48ba857cd700673ce88907cadcdd7e2cd7783ed02378537c5ffd4f6460c"
|
||||
"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
|
||||
"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
|
||||
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
"checksum log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6fddaa003a65722a7fb9e26b0ce95921fe4ba590542ced664d8ce2fa26f9f3ac"
|
||||
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
|
||||
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
||||
"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
|
||||
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
"checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28"
|
||||
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
|
||||
"checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4"
|
||||
"checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998"
|
||||
"checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930"
|
||||
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
|
||||
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
|
||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
|
||||
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
|
||||
"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
|
||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
|
||||
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
|
||||
"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
|
||||
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
|
||||
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
|
||||
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
|
||||
"checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
|
||||
"checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
||||
"checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
|
||||
"checksum serde_codegen 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c5d8a33087d8984f9535daa62a6498a08f6476050b00ab9339dd847e4c25cc"
|
||||
"checksum serde_codegen_internals 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "afad7924a009f859f380e4a2e3a509a845c2ac66435fcead74a4d983b21ae806"
|
||||
"checksum serde_derive 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "ce44e5f4264b39e9d29c875357b7cc3ebdfb967bb9e22bfb5e44ffa400af5306"
|
||||
"checksum serde_derive 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "0a90213fa7e0f5eac3f7afe2d5ff6b088af515052cc7303bd68c7e3b91a3fb79"
|
||||
"checksum serde_json 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "67f7d2e9edc3523a9c8ec8cd6ec481b3a27810aafee3e625d311febd3e656b4c"
|
||||
"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
|
||||
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
|
||||
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
||||
"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191"
|
||||
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum syn 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)" = "58fd09df59565db3399efbba34ba8a2fec1307511ebd245d0061ff9d42691673"
|
||||
"checksum syn 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c67da57e61ebc7b7b6fff56bb34440ca3a83db037320b0507af4c10368deda7d"
|
||||
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
|
||||
"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
||||
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
|
||||
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
|
||||
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
|
||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
|
||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
|
||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
[package]
|
||||
name = "RustPython"
|
||||
name = "rustpython"
|
||||
version = "0.1.0"
|
||||
authors = ["Windel Bouwman", "Shing Lyu <shing.lyu@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
rustpython_parser = {path = "parser"}
|
||||
rustpython_vm = {path = "vm/RustPython"}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
[package]
|
||||
name = "RustPython"
|
||||
name = "rustpython_parser"
|
||||
version = "0.0.1"
|
||||
authors = [ "Shing Lyu", "Windel Bouwman" ]
|
||||
build = "build.rs"
|
||||
|
||||
@@ -19,4 +19,4 @@ pub use self::vm::evaluate;
|
||||
// Mimic eval code objects:
|
||||
//pub fn eval_code() -> pyobject::PyObjectRef {
|
||||
|
||||
//}
|
||||
//}
|
||||
|
||||
4
parser/src/lib.rs
Normal file
4
parser/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
mod compiler;
|
||||
@@ -1,3 +1,6 @@
|
||||
//extern crate rustpython_parser;
|
||||
extern crate rustpython_vm;
|
||||
|
||||
fn main() {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "rustpython"
|
||||
name = "rustpython_vm"
|
||||
version = "0.1.0"
|
||||
authors = ["Shing Lyu <shing.lyu@gmail.com>"]
|
||||
|
||||
|
||||
970
vm/RustPython/src/lib.rs
Normal file
970
vm/RustPython/src/lib.rs
Normal file
@@ -0,0 +1,970 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate env_logger;
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
|
||||
//extern crate eval; use eval::eval::*;
|
||||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::rc::Rc;
|
||||
use std::ops::Deref;
|
||||
|
||||
mod builtins;
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum NativeType{
|
||||
NoneType,
|
||||
Boolean(bool),
|
||||
Int(i32),
|
||||
Float(f64),
|
||||
Str(String),
|
||||
Unicode(String),
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
List(RefCell<Vec<NativeType>>),
|
||||
Tuple(Vec<NativeType>),
|
||||
Iter(Vec<NativeType>), // TODO: use Iterator instead
|
||||
Code(PyCodeObject),
|
||||
Function(Function),
|
||||
Slice(Option<i32>, Option<i32>, Option<i32>), // start, stop, step
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
NativeFunction(fn(Vec<Rc<NativeType>>) -> NativeType ),
|
||||
}
|
||||
|
||||
const CMP_OP: &'static [&'static str] = &[">",
|
||||
"<=",
|
||||
"==",
|
||||
"!=",
|
||||
">",
|
||||
">=",
|
||||
"in",
|
||||
"not in",
|
||||
"is",
|
||||
"is not",
|
||||
"exception match",
|
||||
"BAD"
|
||||
];
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Block {
|
||||
block_type: String, //Enum?
|
||||
handler: usize // The destination we should jump to if the block finishes
|
||||
// level?
|
||||
}
|
||||
|
||||
struct Frame {
|
||||
// TODO: We are using Option<i32> in stack for handline None return value
|
||||
code: PyCodeObject,
|
||||
// We need 1 stack per frame
|
||||
stack: Vec<Rc<NativeType>>, // The main data frame of the stack machine
|
||||
blocks: Vec<Block>, // Block frames, for controling loops and exceptions
|
||||
globals: HashMap<String, Rc<NativeType>>, // Variables
|
||||
locals: HashMap<String, Rc<NativeType>>, // Variables
|
||||
labels: HashMap<usize, usize>, // Maps label id to line number, just for speedup
|
||||
lasti: usize, // index of last instruction ran
|
||||
return_value: NativeType,
|
||||
why: String, //Not sure why we need this //Maybe use a enum if we have fininte options
|
||||
// cmp_op: Vec<&'a Fn(NativeType, NativeType) -> bool>, // TODO: change compare to a function list
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
/// Get the current bytecode offset calculated from curr_frame.lasti
|
||||
fn get_bytecode_offset(&self) -> Option<usize> {
|
||||
// Linear search the labels HashMap, inefficient. Consider build a reverse HashMap
|
||||
let mut last_offset = None;
|
||||
for (offset, instr_idx) in self.labels.iter() {
|
||||
if *instr_idx == self.lasti {
|
||||
last_offset = Some(*offset)
|
||||
}
|
||||
}
|
||||
last_offset
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Function {
|
||||
code: PyCodeObject
|
||||
}
|
||||
|
||||
impl Function {
|
||||
fn new(code: PyCodeObject) -> Function {
|
||||
Function {
|
||||
code: code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct VirtualMachine{
|
||||
frames: Vec<Frame>,
|
||||
}
|
||||
|
||||
impl VirtualMachine {
|
||||
pub fn new() -> VirtualMachine {
|
||||
VirtualMachine {
|
||||
frames: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn curr_frame(&mut self) -> &mut Frame {
|
||||
self.frames.last_mut().unwrap()
|
||||
}
|
||||
|
||||
fn pop_frame(&mut self) {
|
||||
self.frames.pop().unwrap();
|
||||
}
|
||||
|
||||
fn unwind(&mut self, reason: String) {
|
||||
let curr_frame = self.curr_frame();
|
||||
let curr_block = curr_frame.blocks[curr_frame.blocks.len()-1].clone(); // use last?
|
||||
curr_frame.why = reason; // Why do we need this?
|
||||
debug!("block status: {:?}, {:?}", curr_block.block_type, curr_frame.why);
|
||||
match (curr_block.block_type.as_ref(), curr_frame.why.as_ref()) {
|
||||
("loop", "break") => {
|
||||
curr_frame.lasti = curr_block.handler; //curr_frame.labels[curr_block.handler]; // Jump to the end
|
||||
// Return the why as None
|
||||
curr_frame.blocks.pop();
|
||||
},
|
||||
("loop", "none") => (), //skipped
|
||||
_ => panic!("block stack operation not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
// Can we get rid of the code paramter?
|
||||
|
||||
fn make_frame(&self, code: PyCodeObject, callargs: HashMap<String, Rc<NativeType>>, globals: Option<HashMap<String, Rc<NativeType>>>) -> Frame {
|
||||
//populate the globals and locals
|
||||
let mut labels = HashMap::new();
|
||||
let mut curr_offset = 0;
|
||||
for (idx, op) in code.co_code.iter().enumerate() {
|
||||
labels.insert(curr_offset, idx);
|
||||
curr_offset += op.0;
|
||||
}
|
||||
//TODO: This is wrong, check https://github.com/nedbat/byterun/blob/31e6c4a8212c35b5157919abff43a7daa0f377c6/byterun/pyvm2.py#L95
|
||||
let globals = match globals {
|
||||
Some(g) => g,
|
||||
None => HashMap::new(),
|
||||
};
|
||||
let mut locals = globals;
|
||||
locals.extend(callargs);
|
||||
|
||||
//TODO: move this into the __builtin__ module when we have a module type
|
||||
locals.insert("print".to_string(), Rc::new(NativeType::NativeFunction(builtins::print)));
|
||||
locals.insert("len".to_string(), Rc::new(NativeType::NativeFunction(builtins::len)));
|
||||
Frame {
|
||||
code: code,
|
||||
stack: vec![],
|
||||
blocks: vec![],
|
||||
// save the callargs as locals
|
||||
globals: locals.clone(),
|
||||
locals: locals,
|
||||
labels: labels,
|
||||
lasti: 0,
|
||||
return_value: NativeType::NoneType,
|
||||
why: "none".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
// The Option<i32> is the return value of the frame, remove when we have implemented frame
|
||||
// TODO: read the op codes directly from the internal code object
|
||||
fn run_frame(&mut self, frame: Frame) -> NativeType {
|
||||
self.frames.push(frame);
|
||||
|
||||
//let mut why = None;
|
||||
// Change this to a loop for jump
|
||||
loop {
|
||||
//while curr_frame.lasti < curr_frame.code.co_code.len() {
|
||||
let op_code = {
|
||||
let curr_frame = self.curr_frame();
|
||||
let op_code = curr_frame.code.co_code[curr_frame.lasti].clone();
|
||||
curr_frame.lasti += 1;
|
||||
op_code
|
||||
};
|
||||
let why = self.dispatch(op_code);
|
||||
/*if curr_frame.blocks.len() > 0 {
|
||||
self.manage_block_stack(&why);
|
||||
}
|
||||
*/
|
||||
if let Some(_) = why {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let return_value = {
|
||||
//let curr_frame = self.frames.last_mut().unwrap();
|
||||
self.curr_frame().return_value.clone()
|
||||
};
|
||||
self.pop_frame();
|
||||
return_value
|
||||
}
|
||||
|
||||
pub fn run_code(&mut self, code: PyCodeObject) {
|
||||
let frame = self.make_frame(code, HashMap::new(), None);
|
||||
self.run_frame(frame);
|
||||
// check if there are any leftover frame, fail if any
|
||||
}
|
||||
|
||||
fn dispatch(&mut self, op_code: (usize, String, Option<usize>)) -> Option<String> {
|
||||
{
|
||||
debug!("stack:{:?}", self.curr_frame().stack);
|
||||
debug!("env :{:?}", self.curr_frame().locals);
|
||||
debug!("Executing op code: {:?}", op_code);
|
||||
}
|
||||
match (op_code.1.as_ref(), op_code.2) {
|
||||
("LOAD_CONST", Some(consti)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
curr_frame.stack.push(Rc::new(curr_frame.code.co_consts[consti].clone()));
|
||||
None
|
||||
},
|
||||
|
||||
// TODO: universal stack element type
|
||||
("LOAD_CONST", None) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
self.curr_frame().stack.push(Rc::new(NativeType::NoneType));
|
||||
None
|
||||
},
|
||||
("POP_TOP", None) => {
|
||||
self.curr_frame().stack.pop();
|
||||
None
|
||||
},
|
||||
("LOAD_FAST", Some(var_num)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
let ref name = curr_frame.code.co_varnames[var_num];
|
||||
curr_frame.stack.push(curr_frame.locals.get::<str>(name).unwrap().clone());
|
||||
None
|
||||
},
|
||||
("STORE_NAME", Some(namei)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
curr_frame.locals.insert(curr_frame.code.co_names[namei].clone(), curr_frame.stack.pop().unwrap().clone());
|
||||
None
|
||||
},
|
||||
("LOAD_NAME", Some(namei)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
if let Some(code) = curr_frame.locals.get::<str>(&curr_frame.code.co_names[namei]) {
|
||||
curr_frame.stack.push(code.clone());
|
||||
}
|
||||
else {
|
||||
panic!("Can't find symbol {:?} in the current frame", &curr_frame.code.co_names[namei]);
|
||||
}
|
||||
None
|
||||
},
|
||||
("LOAD_GLOBAL", Some(namei)) => {
|
||||
// We need to load the underlying value the name points to, but stuff like
|
||||
// AssertionError is in the names right after compile, so we load the string
|
||||
// instead for now
|
||||
let curr_frame = self.curr_frame();
|
||||
let name = &curr_frame.code.co_names[namei];
|
||||
curr_frame.stack.push(curr_frame.globals.get::<str>(name).unwrap().clone());
|
||||
None
|
||||
},
|
||||
|
||||
("BUILD_LIST", Some(count)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let mut vec = vec!();
|
||||
for _ in 0..count {
|
||||
vec.push((*curr_frame.stack.pop().unwrap()).clone());
|
||||
}
|
||||
vec.reverse();
|
||||
curr_frame.stack.push(Rc::new(NativeType::List(RefCell::new(vec))));
|
||||
None
|
||||
},
|
||||
|
||||
("BUILD_SLICE", Some(count)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
assert!(count == 2 || count == 3);
|
||||
let mut vec = vec!();
|
||||
for _ in 0..count {
|
||||
vec.push(curr_frame.stack.pop().unwrap());
|
||||
}
|
||||
vec.reverse();
|
||||
let mut out:Vec<Option<i32>> = vec.into_iter().map(|x| match *x {
|
||||
NativeType::Int(n) => Some(n),
|
||||
NativeType::NoneType => None,
|
||||
_ => panic!("Expect Int or None as BUILD_SLICE arguments, got {:?}", x),
|
||||
}).collect();
|
||||
|
||||
if out.len() == 2 {
|
||||
out.push(None);
|
||||
}
|
||||
assert!(out.len() == 3);
|
||||
// TODO: assert the stop start and step are NativeType::Int
|
||||
// See https://users.rust-lang.org/t/how-do-you-assert-enums/1187/8
|
||||
curr_frame.stack.push(Rc::new(NativeType::Slice(out[0], out[1], out[2])));
|
||||
None
|
||||
},
|
||||
|
||||
("GET_ITER", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let iter = match *tos {
|
||||
//TODO: is this clone right?
|
||||
// Return a Iterator instead vvv
|
||||
NativeType::Tuple(ref vec) => NativeType::Iter(vec.clone()),
|
||||
NativeType::List(ref vec) => NativeType::Iter(vec.borrow().clone()),
|
||||
_ => panic!("TypeError: object is not iterable")
|
||||
};
|
||||
curr_frame.stack.push(Rc::new(iter));
|
||||
None
|
||||
},
|
||||
|
||||
("FOR_ITER", Some(delta)) => {
|
||||
// This function should be rewrote to use Rust native iterator
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let result = match *tos {
|
||||
NativeType::Iter(ref v) => {
|
||||
if v.len() > 0 {
|
||||
Some(v.clone()) // Unnessary clone here
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => panic!("FOR_ITER: Not an iterator")
|
||||
};
|
||||
if let Some(vec) = result {
|
||||
let (first, rest) = vec.split_first().unwrap();
|
||||
// Unnessary clone here
|
||||
curr_frame.stack.push(Rc::new(NativeType::Iter(rest.to_vec())));
|
||||
curr_frame.stack.push(Rc::new(first.clone()));
|
||||
}
|
||||
else {
|
||||
// Iterator was already poped in the first line of this function
|
||||
let last_offset = curr_frame.get_bytecode_offset().unwrap();
|
||||
curr_frame.lasti = curr_frame.labels.get(&(last_offset + delta)).unwrap().clone();
|
||||
|
||||
}
|
||||
None
|
||||
},
|
||||
|
||||
("COMPARE_OP", Some(cmp_op_i)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match CMP_OP[cmp_op_i] {
|
||||
// To avoid branch explotion, use an array of callables instead
|
||||
"==" => {
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(ref v1i), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2i == v1i)));
|
||||
},
|
||||
(&NativeType::Float(ref v1f), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2f == v1f)));
|
||||
},
|
||||
(&NativeType::Str(ref v1s), &NativeType::Str(ref v2s)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2s == v1s)));
|
||||
},
|
||||
(&NativeType::Int(ref v1i), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2f == &(*v1i as f64))));
|
||||
},
|
||||
(&NativeType::List(ref l1), &NativeType::List(ref l2)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(l2 == l1)));
|
||||
},
|
||||
_ => panic!("TypeError in COMPARE_OP: can't compare {:?} with {:?}", v1, v2)
|
||||
};
|
||||
}
|
||||
">" => {
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(ref v1i), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2i < v1i)));
|
||||
},
|
||||
(&NativeType::Float(ref v1f), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2f < v1f)));
|
||||
},
|
||||
_ => panic!("TypeError in COMPARE_OP")
|
||||
};
|
||||
}
|
||||
_ => panic!("Unimplemented COMPARE_OP operator")
|
||||
|
||||
}
|
||||
None
|
||||
|
||||
},
|
||||
("POP_JUMP_IF_TRUE", Some(ref target)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
if *v == NativeType::Boolean(true) {
|
||||
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
|
||||
}
|
||||
None
|
||||
|
||||
}
|
||||
("POP_JUMP_IF_FALSE", Some(ref target)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
if *v == NativeType::Boolean(false) {
|
||||
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
|
||||
}
|
||||
None
|
||||
|
||||
}
|
||||
("JUMP_FORWARD", Some(ref delta)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let last_offset = curr_frame.get_bytecode_offset().unwrap();
|
||||
curr_frame.lasti = curr_frame.labels.get(&(last_offset + delta)).unwrap().clone();
|
||||
None
|
||||
},
|
||||
("JUMP_ABSOLUTE", Some(ref target)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
|
||||
None
|
||||
},
|
||||
("BREAK_LOOP", None) => {
|
||||
// Do we still need to return the why if we use unwind from jsapy?
|
||||
self.unwind("break".to_string());
|
||||
None //?
|
||||
},
|
||||
("RAISE_VARARGS", Some(argc)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
// let (exception, params, traceback) = match argc {
|
||||
let exception = match argc {
|
||||
1 => curr_frame.stack.pop().unwrap(),
|
||||
0 | 2 | 3 => panic!("Not implemented!"),
|
||||
_ => panic!("Invalid paramter for RAISE_VARARGS, must be between 0 to 3")
|
||||
};
|
||||
panic!("{:?}", exception);
|
||||
}
|
||||
("INPLACE_ADD", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
match (tos.deref(), tos1.deref()) {
|
||||
(&NativeType::Int(ref tosi), &NativeType::Int(ref tos1i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(tos1i + tosi)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_ADD")
|
||||
}
|
||||
None
|
||||
},
|
||||
|
||||
("STORE_SUBSCR", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
let tos2 = curr_frame.stack.pop().unwrap();
|
||||
match (tos1.deref(), tos.deref()) {
|
||||
(&NativeType::List(ref refl), &NativeType::Int(index)) => {
|
||||
refl.borrow_mut()[index as usize] = (*tos2).clone();
|
||||
},
|
||||
(&NativeType::Str(_), &NativeType::Int(_)) => {
|
||||
// TODO: raise TypeError: 'str' object does not support item assignment
|
||||
panic!("TypeError: 'str' object does not support item assignment")
|
||||
},
|
||||
_ => panic!("TypeError in STORE_SUBSCR")
|
||||
}
|
||||
curr_frame.stack.push(tos1);
|
||||
None
|
||||
},
|
||||
|
||||
("BINARY_ADD", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(ref v1i), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i + v1i)));
|
||||
}
|
||||
(&NativeType::Float(ref v1f), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(*v2i as f64 + v1f)));
|
||||
}
|
||||
(&NativeType::Int(ref v1i), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f + *v1i as f64)));
|
||||
}
|
||||
(&NativeType::Float(ref v1f), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f + v1f)));
|
||||
}
|
||||
(&NativeType::Str(ref str1), &NativeType::Str(ref str2)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Str(format!("{}{}", str2, str1))));
|
||||
}
|
||||
(&NativeType::List(ref l1), &NativeType::List(ref l2)) => {
|
||||
let mut new_l = l2.clone();
|
||||
// TODO: remove unnessary copy
|
||||
new_l.borrow_mut().append(&mut l1.borrow().clone());
|
||||
curr_frame.stack.push(Rc::new(NativeType::List(new_l)));
|
||||
|
||||
}
|
||||
_ => panic!("TypeError in BINARY_ADD")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_POWER", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i.pow(v1i as u32))));
|
||||
}
|
||||
(&NativeType::Float(v1f), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float((v2i as f64).powf(v1f))));
|
||||
}
|
||||
(&NativeType::Int(v1i), &NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f.powi(v1i))));
|
||||
}
|
||||
(&NativeType::Float(v1f), &NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f.powf(v1f))));
|
||||
}
|
||||
_ => panic!("TypeError in BINARY_POWER")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_MULTIPLY", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i * v1i)));
|
||||
},
|
||||
/*
|
||||
(NativeType::Float(v1f), NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(NativeType::Float((v2i as f64) * v1f));
|
||||
},
|
||||
(NativeType::Int(v1i), NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(NativeType::Float(v2f * (v1i as f64)));
|
||||
},
|
||||
(NativeType::Float(v1f), NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(NativeType::Float(v2f * v1f));
|
||||
},
|
||||
*/
|
||||
//TODO: String multiply
|
||||
_ => panic!("TypeError in BINARY_MULTIPLY")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_TRUE_DIVIDE", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i / v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_DIVIDE")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_MODULO", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i % v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_MODULO")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_SUBTRACT", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i - v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_SUBSTRACT")
|
||||
}
|
||||
None
|
||||
},
|
||||
|
||||
("BINARY_SUBSCR", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
debug!("tos: {:?}, tos1: {:?}", tos, tos1);
|
||||
match (tos1.deref(), tos.deref()) {
|
||||
(&NativeType::List(ref l), &NativeType::Int(ref index)) => {
|
||||
let pos_index = (index + l.borrow().len() as i32) % l.borrow().len() as i32;
|
||||
curr_frame.stack.push(Rc::new(l.borrow()[pos_index as usize].clone()))
|
||||
},
|
||||
(&NativeType::List(ref l), &NativeType::Slice(ref opt_start, ref opt_stop, ref opt_step)) => {
|
||||
let start = match opt_start {
|
||||
&Some(start) => ((start + l.borrow().len() as i32) % l.borrow().len() as i32) as usize,
|
||||
&None => 0,
|
||||
};
|
||||
let stop = match opt_stop {
|
||||
&Some(stop) => ((stop + l.borrow().len() as i32) % l.borrow().len() as i32) as usize,
|
||||
&None => l.borrow().len() as usize,
|
||||
};
|
||||
let step = match opt_step {
|
||||
//Some(step) => step as usize,
|
||||
&None => 1 as usize,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
// TODO: we could potentially avoid this copy and use slice
|
||||
curr_frame.stack.push(Rc::new(NativeType::List(RefCell::new(l.borrow()[start..stop].to_vec()))));
|
||||
},
|
||||
(&NativeType::Tuple(ref t), &NativeType::Int(ref index)) => curr_frame.stack.push(Rc::new(t[*index as usize].clone())),
|
||||
(&NativeType::Str(ref s), &NativeType::Int(ref index)) => {
|
||||
let idx = (index + s.len() as i32) % s.len() as i32;
|
||||
curr_frame.stack.push(Rc::new(NativeType::Str(s.chars().nth(idx as usize).unwrap().to_string())));
|
||||
},
|
||||
(&NativeType::Str(ref s), &NativeType::Slice(ref opt_start, ref opt_stop, ref opt_step)) => {
|
||||
let start = match opt_start {
|
||||
&Some(start) if start > s.len() as i32 => s.len(),
|
||||
&Some(start) if start <= s.len() as i32 => ((start + s.len() as i32) % s.len() as i32) as usize,
|
||||
&Some(_) => panic!("Bad start index for string slicing"),
|
||||
&Some(start) => ((start + s.len() as i32) % s.len() as i32) as usize,
|
||||
&None => 0,
|
||||
};
|
||||
let stop = match opt_stop {
|
||||
&Some(stop) if stop > s.len() as i32 => s.len(),
|
||||
&Some(stop) if stop <= s.len() as i32 => ((stop + s.len() as i32) % s.len() as i32) as usize, // Do we need this modding?
|
||||
&Some(_) => panic!("Bad stop index for string slicing"),
|
||||
&None => s.len() as usize,
|
||||
};
|
||||
let step = match opt_step {
|
||||
//Some(step) => step as usize,
|
||||
&None => 1 as usize,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
curr_frame.stack.push(Rc::new(NativeType::Str(s[start..stop].to_string())));
|
||||
},
|
||||
// TODO: implement other Slice possibilities
|
||||
_ => panic!("TypeError: indexing type {:?} with index {:?} is not supported (yet?)", tos1, tos)
|
||||
};
|
||||
None
|
||||
},
|
||||
("ROT_TWO", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
curr_frame.stack.push(tos);
|
||||
curr_frame.stack.push(tos1);
|
||||
None
|
||||
}
|
||||
("UNARY_NEGATIVE", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
match v.deref() {
|
||||
&NativeType::Int(v1i) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(-v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in UINARY_NEGATIVE")
|
||||
}
|
||||
None
|
||||
},
|
||||
("UNARY_POSITIVE", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
// Any case that is not just push back?
|
||||
curr_frame.stack.push(v);
|
||||
None
|
||||
},
|
||||
("PRINT_ITEM", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
// TODO: Print without the (...)
|
||||
println!("{:?}", curr_frame.stack.pop().unwrap());
|
||||
None
|
||||
},
|
||||
("PRINT_NEWLINE", None) => {
|
||||
print!("\n");
|
||||
None
|
||||
},
|
||||
("MAKE_FUNCTION", Some(argc)) => {
|
||||
// https://docs.python.org/3.4/library/dis.html#opcode-MAKE_FUNCTION
|
||||
let curr_frame = self.curr_frame();
|
||||
let qualified_name = curr_frame.stack.pop().unwrap();
|
||||
let code_obj = match curr_frame.stack.pop().unwrap().deref() {
|
||||
&NativeType::Code(ref code) => code.clone(),
|
||||
_ => panic!("Second item on the stack should be a code object")
|
||||
};
|
||||
// pop argc arguments
|
||||
// argument: name, args, globals
|
||||
let func = Function::new(code_obj);
|
||||
curr_frame.stack.push(Rc::new(NativeType::Function(func)));
|
||||
None
|
||||
},
|
||||
("CALL_FUNCTION", Some(argc)) => {
|
||||
let kw_count = (argc >> 8) as u8;
|
||||
let pos_count = (argc & 0xFF) as u8;
|
||||
// Pop the arguments based on argc
|
||||
let mut kw_args = HashMap::new();
|
||||
let mut pos_args = Vec::new();
|
||||
{
|
||||
let curr_frame = self.curr_frame();
|
||||
for _ in 0..kw_count {
|
||||
let native_val = curr_frame.stack.pop().unwrap();
|
||||
let native_key = curr_frame.stack.pop().unwrap();
|
||||
if let (ref val, &NativeType::Str(ref key)) = (native_val, native_key.deref()) {
|
||||
|
||||
kw_args.insert(key.clone(), val.clone());
|
||||
}
|
||||
else {
|
||||
panic!("Incorrect type found while building keyword argument list")
|
||||
}
|
||||
}
|
||||
for _ in 0..pos_count {
|
||||
pos_args.push(curr_frame.stack.pop().unwrap());
|
||||
}
|
||||
}
|
||||
let locals = {
|
||||
// FIXME: no clone here
|
||||
self.curr_frame().locals.clone()
|
||||
};
|
||||
|
||||
let func = {
|
||||
match self.curr_frame().stack.pop().unwrap().deref() {
|
||||
&NativeType::Function(ref func) => {
|
||||
// pop argc arguments
|
||||
// argument: name, args, globals
|
||||
// build the callargs hashmap
|
||||
pos_args.reverse();
|
||||
let mut callargs = HashMap::new();
|
||||
for (name, val) in func.code.co_varnames.iter().zip(pos_args) {
|
||||
callargs.insert(name.to_string(), val);
|
||||
}
|
||||
// merge callargs with kw_args
|
||||
let return_value = {
|
||||
let frame = self.make_frame(func.code.clone(), callargs, Some(locals));
|
||||
self.run_frame(frame)
|
||||
};
|
||||
self.curr_frame().stack.push(Rc::new(return_value));
|
||||
},
|
||||
&NativeType::NativeFunction(func) => {
|
||||
pos_args.reverse();
|
||||
let return_value = func(pos_args);
|
||||
self.curr_frame().stack.push(Rc::new(return_value));
|
||||
},
|
||||
_ => panic!("The item on the stack should be a code object")
|
||||
}
|
||||
};
|
||||
None
|
||||
},
|
||||
("RETURN_VALUE", None) => {
|
||||
// Hmmm... what is this used?
|
||||
// I believe we need to push this to the next frame
|
||||
self.curr_frame().return_value = (*self.curr_frame().stack.pop().unwrap()).clone();
|
||||
Some("return".to_string())
|
||||
},
|
||||
("SETUP_LOOP", Some(delta)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let curr_offset = curr_frame.get_bytecode_offset().unwrap();
|
||||
curr_frame.blocks.push(Block {
|
||||
block_type: "loop".to_string(),
|
||||
handler: *curr_frame.labels.get(&(curr_offset + delta)).unwrap(),
|
||||
});
|
||||
None
|
||||
},
|
||||
("POP_BLOCK", None) => {
|
||||
self.curr_frame().blocks.pop();
|
||||
None
|
||||
}
|
||||
("SetLineno", _) | ("LABEL", _)=> {
|
||||
// Skip
|
||||
None
|
||||
},
|
||||
(name, _) => {
|
||||
panic!("Unrecongnizable op code: {}", name);
|
||||
}
|
||||
} // end match
|
||||
} // end dispatch function
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PyCodeObject {
|
||||
co_consts: Vec<NativeType>,
|
||||
co_names: Vec<String>,
|
||||
co_code: Vec<(usize, String, Option<usize>)>, //size, name, args
|
||||
co_varnames: Vec<String>,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
fn parse_native_type(val_str: &str) -> Result<NativeType, ()> {
|
||||
// println!("{:?}", val_str);
|
||||
match val_str {
|
||||
"None" => Ok(NativeType::NoneType),
|
||||
"True" => Ok(NativeType::Boolean(true)),
|
||||
"False" => Ok(NativeType::Boolean(false)),
|
||||
_ => {
|
||||
if let Ok(int) = val_str.parse::<i32>() {
|
||||
return Ok(NativeType::Int(int))
|
||||
}
|
||||
|
||||
if let Ok(float) = val_str.parse::<f64>() {
|
||||
return Ok(NativeType::Float(float))
|
||||
}
|
||||
|
||||
if val_str.starts_with("\'") && val_str.ends_with("\'") {
|
||||
return Ok(NativeType::Str(val_str[1..val_str.len()-1].to_string()))
|
||||
}
|
||||
|
||||
if val_str.starts_with("u\'") && val_str.ends_with("\'") {
|
||||
return Ok(NativeType::Unicode(val_str[2..val_str.len()-1].to_string()))
|
||||
}
|
||||
|
||||
if val_str.starts_with("(") && val_str.ends_with(")") {
|
||||
return Ok(NativeType::Str(val_str[1..val_str.len()-1].to_string()))
|
||||
}
|
||||
|
||||
Err(())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_bytecode(s: &str) -> Code {
|
||||
let lines: Vec<&str> = s.split('\n').collect();
|
||||
|
||||
let (metadata, ops) = lines.split_at(2);
|
||||
// Parsing the first line CONSTS
|
||||
let consts_str: &str = metadata[0]; // line 0 is empty
|
||||
let values_str = &consts_str[("CONSTS: (".len())..(consts_str.len()-1)];
|
||||
let values: Vec<&str> = values_str.split(",").collect();
|
||||
// We need better type definition here
|
||||
let consts: Vec<NativeType>= values.into_iter()
|
||||
.map(|x| x.trim())
|
||||
.filter(|x| x.len() > 0)
|
||||
.map(|x| parse_native_type(x).unwrap())
|
||||
.collect();
|
||||
|
||||
// Parsing the second line NAMES
|
||||
let names_str: &str = metadata[1]; // line 0 is empty
|
||||
let values_str = &names_str[("NAMES: (".len())..(names_str.len()-1)];
|
||||
let values: Vec<&str> = values_str.split(",").collect();
|
||||
// We are assuming the first and last chars are \'
|
||||
let names: Vec<&str>= values.into_iter().map(|x| x.trim())
|
||||
.filter(|x| x.len() > 0)
|
||||
.map(|x| &x[1..(x.len()-1)]).collect();
|
||||
|
||||
// Parsing the op_codes
|
||||
let op_codes: Vec<(&str, Option<usize>)>= ops.into_iter()
|
||||
.map(|x| x.trim())
|
||||
.filter(|x| x.len() > 0)
|
||||
.map(|x| {
|
||||
let op: Vec<&str> = x.split(", ").collect();
|
||||
// println!("{:?}", op);
|
||||
(op[0], op[1].parse::<usize>().ok())
|
||||
}).collect();
|
||||
|
||||
|
||||
Code {
|
||||
consts: consts,
|
||||
op_codes: op_codes,
|
||||
names: names,
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn test_parse_native_type() {
|
||||
|
||||
assert_eq!(NativeType::NoneType, parse_native_type("None").unwrap());
|
||||
assert_eq!(NativeType::Boolean(true), parse_native_type("True").unwrap());
|
||||
assert_eq!(NativeType::Boolean(false), parse_native_type("False").unwrap());
|
||||
assert_eq!(NativeType::Int(3), parse_native_type("3").unwrap());
|
||||
assert_eq!(NativeType::Float(3.0), parse_native_type("3.0").unwrap());
|
||||
assert_eq!(NativeType::Float(3.5), parse_native_type("3.5").unwrap());
|
||||
assert_eq!(NativeType::Str("foo".to_string()), parse_native_type("\'foo\'").unwrap());
|
||||
assert_eq!(NativeType::Unicode("foo".to_string()), parse_native_type("u\'foo\'").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_bytecode() {
|
||||
|
||||
let input = "CONSTS: (1, None, 2)
|
||||
NAMES: ('a', 'b')
|
||||
SetLineno, 1
|
||||
LOAD_CONST, 2
|
||||
PRINT_ITEM, None
|
||||
PRINT_NEWLINE, None
|
||||
LOAD_CONST, None
|
||||
RETURN_VALUE, None
|
||||
";
|
||||
let expected = Code { // Fill me with a more sensible data
|
||||
consts: vec![NativeType::Int(1), NativeType::NoneType, NativeType::Int(2)],
|
||||
names: vec!["a", "b"],
|
||||
op_codes: vec![
|
||||
("SetLineno", Some(1)),
|
||||
("LOAD_CONST", Some(2)),
|
||||
("PRINT_ITEM", None),
|
||||
("PRINT_NEWLINE", None),
|
||||
("LOAD_CONST", None),
|
||||
("RETURN_VALUE", None)
|
||||
]
|
||||
};
|
||||
|
||||
assert_eq!(expected, parse_bytecode(input));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_const_tuple() {
|
||||
let input = "CONSTS: (None,)
|
||||
NAMES: ()
|
||||
SetLineno, 1
|
||||
LOAD_CONST, 0
|
||||
RETURN_VALUE, None
|
||||
";
|
||||
let expected = Code { // Fill me with a more sensible data
|
||||
consts: vec![NativeType::NoneType],
|
||||
names: vec![],
|
||||
op_codes: vec![
|
||||
("SetLineno", Some(1)),
|
||||
("LOAD_CONST", Some(0)),
|
||||
("RETURN_VALUE", None)
|
||||
]
|
||||
};
|
||||
|
||||
assert_eq!(expected, parse_bytecode(input));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vm() {
|
||||
|
||||
let code = PyCodeObject {
|
||||
co_consts: vec![NativeType::Int(1), NativeType::NoneType, NativeType::Int(2)],
|
||||
co_names: vec![],
|
||||
co_code: vec![
|
||||
(3, "LOAD_CONST".to_string(), Some(2)),
|
||||
(1, "PRINT_ITEM".to_string(), None),
|
||||
(1, "PRINT_NEWLINE".to_string(), None),
|
||||
(3, "LOAD_CONST".to_string(), None),
|
||||
(1, "RETURN_VALUE".to_string(), None)
|
||||
]
|
||||
};
|
||||
let mut vm = VirtualMachine::new();
|
||||
assert_eq!((), vm.exec(&code));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_parse_jsonbytecode() {
|
||||
|
||||
let input = "{\"co_consts\":[{\"Int\":1},\"NoneType\",{\"Int\":2}],\"co_names\":[\"print\"],\"co_code\":[[3,\"LOAD_CONST\",2],[1,\"PRINT_ITEM\",null],[1,\"PRINT_NEWLINE\",null],[3,\"LOAD_CONST\",null],[1,\"RETURN_VALUE\",null]]}";
|
||||
// let input = "{\"co_names\": [\"print\"], \"co_code\": [[\"LOAD_CONST\", 0], [\"LOAD_CONST\", 0], [\"COMPARE_OP\", 2], [\"POP_JUMP_IF_FALSE\", 25], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 1], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"JUMP_FORWARD\", 10], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 2], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"LOAD_CONST\", 0], [\"LOAD_CONST\", 3], [\"COMPARE_OP\", 2], [\"POP_JUMP_IF_FALSE\", 60], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 1], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"JUMP_FORWARD\", 10], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 2], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"LOAD_CONST\", 4], [\"RETURN_VALUE\", null]], \"co_consts\": [{\"Int\": 1}, {\"Str\": \"equal\"}, {\"Str\": \"not equal\"}, {\"Int\": 2}, {\"NoneType\": null}]}";
|
||||
|
||||
let expected = PyCodeObject { // Fill me with a more sensible data
|
||||
co_consts: vec![NativeType::Int(1), NativeType::NoneType, NativeType::Int(2)],
|
||||
co_names: vec!["print".to_string()],
|
||||
co_code: vec![
|
||||
(3, "LOAD_CONST".to_string(), Some(2)),
|
||||
(1, "PRINT_ITEM".to_string(), None),
|
||||
(1, "PRINT_NEWLINE".to_string(), None),
|
||||
(3, "LOAD_CONST".to_string(), None),
|
||||
(1, "RETURN_VALUE".to_string(), None)
|
||||
]
|
||||
};
|
||||
println!("{}", serde_json::to_string(&expected).unwrap());
|
||||
|
||||
let deserialized: PyCodeObject = serde_json::from_str(&input).unwrap();
|
||||
assert_eq!(expected, deserialized)
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_tuple_serialization(){
|
||||
let tuple = NativeType::Tuple(vec![NativeType::Int(1),NativeType::Int(2)]);
|
||||
println!("{}", serde_json::to_string(&tuple).unwrap());
|
||||
}
|
||||
@@ -1,861 +1,16 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate env_logger;
|
||||
|
||||
extern crate rustpython_vm;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
|
||||
//extern crate eval; use eval::eval::*;
|
||||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
use rustpython_vm::*;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::rc::Rc;
|
||||
use std::ops::Deref;
|
||||
|
||||
mod builtins;
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum NativeType{
|
||||
NoneType,
|
||||
Boolean(bool),
|
||||
Int(i32),
|
||||
Float(f64),
|
||||
Str(String),
|
||||
Unicode(String),
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
List(RefCell<Vec<NativeType>>),
|
||||
Tuple(Vec<NativeType>),
|
||||
Iter(Vec<NativeType>), // TODO: use Iterator instead
|
||||
Code(PyCodeObject),
|
||||
Function(Function),
|
||||
Slice(Option<i32>, Option<i32>, Option<i32>), // start, stop, step
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
NativeFunction(fn(Vec<Rc<NativeType>>) -> NativeType ),
|
||||
}
|
||||
|
||||
const CMP_OP: &'static [&'static str] = &[">",
|
||||
"<=",
|
||||
"==",
|
||||
"!=",
|
||||
">",
|
||||
">=",
|
||||
"in",
|
||||
"not in",
|
||||
"is",
|
||||
"is not",
|
||||
"exception match",
|
||||
"BAD"
|
||||
];
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Block {
|
||||
block_type: String, //Enum?
|
||||
handler: usize // The destination we should jump to if the block finishes
|
||||
// level?
|
||||
}
|
||||
|
||||
struct Frame {
|
||||
// TODO: We are using Option<i32> in stack for handline None return value
|
||||
code: PyCodeObject,
|
||||
// We need 1 stack per frame
|
||||
stack: Vec<Rc<NativeType>>, // The main data frame of the stack machine
|
||||
blocks: Vec<Block>, // Block frames, for controling loops and exceptions
|
||||
globals: HashMap<String, Rc<NativeType>>, // Variables
|
||||
locals: HashMap<String, Rc<NativeType>>, // Variables
|
||||
labels: HashMap<usize, usize>, // Maps label id to line number, just for speedup
|
||||
lasti: usize, // index of last instruction ran
|
||||
return_value: NativeType,
|
||||
why: String, //Not sure why we need this //Maybe use a enum if we have fininte options
|
||||
// cmp_op: Vec<&'a Fn(NativeType, NativeType) -> bool>, // TODO: change compare to a function list
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
/// Get the current bytecode offset calculated from curr_frame.lasti
|
||||
fn get_bytecode_offset(&self) -> Option<usize> {
|
||||
// Linear search the labels HashMap, inefficient. Consider build a reverse HashMap
|
||||
let mut last_offset = None;
|
||||
for (offset, instr_idx) in self.labels.iter() {
|
||||
if *instr_idx == self.lasti {
|
||||
last_offset = Some(*offset)
|
||||
}
|
||||
}
|
||||
last_offset
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Function {
|
||||
code: PyCodeObject
|
||||
}
|
||||
|
||||
impl Function {
|
||||
fn new(code: PyCodeObject) -> Function {
|
||||
Function {
|
||||
code: code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct VirtualMachine{
|
||||
frames: Vec<Frame>,
|
||||
}
|
||||
|
||||
impl VirtualMachine {
|
||||
fn new() -> VirtualMachine {
|
||||
VirtualMachine {
|
||||
frames: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn curr_frame(&mut self) -> &mut Frame {
|
||||
self.frames.last_mut().unwrap()
|
||||
}
|
||||
|
||||
fn pop_frame(&mut self) {
|
||||
self.frames.pop().unwrap();
|
||||
}
|
||||
|
||||
fn unwind(&mut self, reason: String) {
|
||||
let curr_frame = self.curr_frame();
|
||||
let curr_block = curr_frame.blocks[curr_frame.blocks.len()-1].clone(); // use last?
|
||||
curr_frame.why = reason; // Why do we need this?
|
||||
debug!("block status: {:?}, {:?}", curr_block.block_type, curr_frame.why);
|
||||
match (curr_block.block_type.as_ref(), curr_frame.why.as_ref()) {
|
||||
("loop", "break") => {
|
||||
curr_frame.lasti = curr_block.handler; //curr_frame.labels[curr_block.handler]; // Jump to the end
|
||||
// Return the why as None
|
||||
curr_frame.blocks.pop();
|
||||
},
|
||||
("loop", "none") => (), //skipped
|
||||
_ => panic!("block stack operation not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
// Can we get rid of the code paramter?
|
||||
|
||||
fn make_frame(&self, code: PyCodeObject, callargs: HashMap<String, Rc<NativeType>>, globals: Option<HashMap<String, Rc<NativeType>>>) -> Frame {
|
||||
//populate the globals and locals
|
||||
let mut labels = HashMap::new();
|
||||
let mut curr_offset = 0;
|
||||
for (idx, op) in code.co_code.iter().enumerate() {
|
||||
labels.insert(curr_offset, idx);
|
||||
curr_offset += op.0;
|
||||
}
|
||||
//TODO: This is wrong, check https://github.com/nedbat/byterun/blob/31e6c4a8212c35b5157919abff43a7daa0f377c6/byterun/pyvm2.py#L95
|
||||
let globals = match globals {
|
||||
Some(g) => g,
|
||||
None => HashMap::new(),
|
||||
};
|
||||
let mut locals = globals;
|
||||
locals.extend(callargs);
|
||||
|
||||
//TODO: move this into the __builtin__ module when we have a module type
|
||||
locals.insert("print".to_string(), Rc::new(NativeType::NativeFunction(builtins::print)));
|
||||
locals.insert("len".to_string(), Rc::new(NativeType::NativeFunction(builtins::len)));
|
||||
Frame {
|
||||
code: code,
|
||||
stack: vec![],
|
||||
blocks: vec![],
|
||||
// save the callargs as locals
|
||||
globals: locals.clone(),
|
||||
locals: locals,
|
||||
labels: labels,
|
||||
lasti: 0,
|
||||
return_value: NativeType::NoneType,
|
||||
why: "none".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
// The Option<i32> is the return value of the frame, remove when we have implemented frame
|
||||
// TODO: read the op codes directly from the internal code object
|
||||
fn run_frame(&mut self, frame: Frame) -> NativeType {
|
||||
self.frames.push(frame);
|
||||
|
||||
//let mut why = None;
|
||||
// Change this to a loop for jump
|
||||
loop {
|
||||
//while curr_frame.lasti < curr_frame.code.co_code.len() {
|
||||
let op_code = {
|
||||
let curr_frame = self.curr_frame();
|
||||
let op_code = curr_frame.code.co_code[curr_frame.lasti].clone();
|
||||
curr_frame.lasti += 1;
|
||||
op_code
|
||||
};
|
||||
let why = self.dispatch(op_code);
|
||||
/*if curr_frame.blocks.len() > 0 {
|
||||
self.manage_block_stack(&why);
|
||||
}
|
||||
*/
|
||||
if let Some(_) = why {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let return_value = {
|
||||
//let curr_frame = self.frames.last_mut().unwrap();
|
||||
self.curr_frame().return_value.clone()
|
||||
};
|
||||
self.pop_frame();
|
||||
return_value
|
||||
}
|
||||
|
||||
fn run_code(&mut self, code: PyCodeObject) {
|
||||
let frame = self.make_frame(code, HashMap::new(), None);
|
||||
self.run_frame(frame);
|
||||
// check if there are any leftover frame, fail if any
|
||||
}
|
||||
|
||||
fn dispatch(&mut self, op_code: (usize, String, Option<usize>)) -> Option<String> {
|
||||
{
|
||||
debug!("stack:{:?}", self.curr_frame().stack);
|
||||
debug!("env :{:?}", self.curr_frame().locals);
|
||||
debug!("Executing op code: {:?}", op_code);
|
||||
}
|
||||
match (op_code.1.as_ref(), op_code.2) {
|
||||
("LOAD_CONST", Some(consti)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
curr_frame.stack.push(Rc::new(curr_frame.code.co_consts[consti].clone()));
|
||||
None
|
||||
},
|
||||
|
||||
// TODO: universal stack element type
|
||||
("LOAD_CONST", None) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
self.curr_frame().stack.push(Rc::new(NativeType::NoneType));
|
||||
None
|
||||
},
|
||||
("POP_TOP", None) => {
|
||||
self.curr_frame().stack.pop();
|
||||
None
|
||||
},
|
||||
("LOAD_FAST", Some(var_num)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
let ref name = curr_frame.code.co_varnames[var_num];
|
||||
curr_frame.stack.push(curr_frame.locals.get::<str>(name).unwrap().clone());
|
||||
None
|
||||
},
|
||||
("STORE_NAME", Some(namei)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
curr_frame.locals.insert(curr_frame.code.co_names[namei].clone(), curr_frame.stack.pop().unwrap().clone());
|
||||
None
|
||||
},
|
||||
("LOAD_NAME", Some(namei)) => {
|
||||
// println!("Loading const at index: {}", consti);
|
||||
let curr_frame = self.curr_frame();
|
||||
if let Some(code) = curr_frame.locals.get::<str>(&curr_frame.code.co_names[namei]) {
|
||||
curr_frame.stack.push(code.clone());
|
||||
}
|
||||
else {
|
||||
panic!("Can't find symbol {:?} in the current frame", &curr_frame.code.co_names[namei]);
|
||||
}
|
||||
None
|
||||
},
|
||||
("LOAD_GLOBAL", Some(namei)) => {
|
||||
// We need to load the underlying value the name points to, but stuff like
|
||||
// AssertionError is in the names right after compile, so we load the string
|
||||
// instead for now
|
||||
let curr_frame = self.curr_frame();
|
||||
let name = &curr_frame.code.co_names[namei];
|
||||
curr_frame.stack.push(curr_frame.globals.get::<str>(name).unwrap().clone());
|
||||
None
|
||||
},
|
||||
|
||||
("BUILD_LIST", Some(count)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let mut vec = vec!();
|
||||
for _ in 0..count {
|
||||
vec.push((*curr_frame.stack.pop().unwrap()).clone());
|
||||
}
|
||||
vec.reverse();
|
||||
curr_frame.stack.push(Rc::new(NativeType::List(RefCell::new(vec))));
|
||||
None
|
||||
},
|
||||
|
||||
("BUILD_SLICE", Some(count)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
assert!(count == 2 || count == 3);
|
||||
let mut vec = vec!();
|
||||
for _ in 0..count {
|
||||
vec.push(curr_frame.stack.pop().unwrap());
|
||||
}
|
||||
vec.reverse();
|
||||
let mut out:Vec<Option<i32>> = vec.into_iter().map(|x| match *x {
|
||||
NativeType::Int(n) => Some(n),
|
||||
NativeType::NoneType => None,
|
||||
_ => panic!("Expect Int or None as BUILD_SLICE arguments, got {:?}", x),
|
||||
}).collect();
|
||||
|
||||
if out.len() == 2 {
|
||||
out.push(None);
|
||||
}
|
||||
assert!(out.len() == 3);
|
||||
// TODO: assert the stop start and step are NativeType::Int
|
||||
// See https://users.rust-lang.org/t/how-do-you-assert-enums/1187/8
|
||||
curr_frame.stack.push(Rc::new(NativeType::Slice(out[0], out[1], out[2])));
|
||||
None
|
||||
},
|
||||
|
||||
("GET_ITER", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let iter = match *tos {
|
||||
//TODO: is this clone right?
|
||||
// Return a Iterator instead vvv
|
||||
NativeType::Tuple(ref vec) => NativeType::Iter(vec.clone()),
|
||||
NativeType::List(ref vec) => NativeType::Iter(vec.borrow().clone()),
|
||||
_ => panic!("TypeError: object is not iterable")
|
||||
};
|
||||
curr_frame.stack.push(Rc::new(iter));
|
||||
None
|
||||
},
|
||||
|
||||
("FOR_ITER", Some(delta)) => {
|
||||
// This function should be rewrote to use Rust native iterator
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let result = match *tos {
|
||||
NativeType::Iter(ref v) => {
|
||||
if v.len() > 0 {
|
||||
Some(v.clone()) // Unnessary clone here
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => panic!("FOR_ITER: Not an iterator")
|
||||
};
|
||||
if let Some(vec) = result {
|
||||
let (first, rest) = vec.split_first().unwrap();
|
||||
// Unnessary clone here
|
||||
curr_frame.stack.push(Rc::new(NativeType::Iter(rest.to_vec())));
|
||||
curr_frame.stack.push(Rc::new(first.clone()));
|
||||
}
|
||||
else {
|
||||
// Iterator was already poped in the first line of this function
|
||||
let last_offset = curr_frame.get_bytecode_offset().unwrap();
|
||||
curr_frame.lasti = curr_frame.labels.get(&(last_offset + delta)).unwrap().clone();
|
||||
|
||||
}
|
||||
None
|
||||
},
|
||||
|
||||
("COMPARE_OP", Some(cmp_op_i)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match CMP_OP[cmp_op_i] {
|
||||
// To avoid branch explotion, use an array of callables instead
|
||||
"==" => {
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(ref v1i), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2i == v1i)));
|
||||
},
|
||||
(&NativeType::Float(ref v1f), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2f == v1f)));
|
||||
},
|
||||
(&NativeType::Str(ref v1s), &NativeType::Str(ref v2s)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2s == v1s)));
|
||||
},
|
||||
(&NativeType::Int(ref v1i), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2f == &(*v1i as f64))));
|
||||
},
|
||||
(&NativeType::List(ref l1), &NativeType::List(ref l2)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(l2 == l1)));
|
||||
},
|
||||
_ => panic!("TypeError in COMPARE_OP: can't compare {:?} with {:?}", v1, v2)
|
||||
};
|
||||
}
|
||||
">" => {
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(ref v1i), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2i < v1i)));
|
||||
},
|
||||
(&NativeType::Float(ref v1f), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Boolean(v2f < v1f)));
|
||||
},
|
||||
_ => panic!("TypeError in COMPARE_OP")
|
||||
};
|
||||
}
|
||||
_ => panic!("Unimplemented COMPARE_OP operator")
|
||||
|
||||
}
|
||||
None
|
||||
|
||||
},
|
||||
("POP_JUMP_IF_TRUE", Some(ref target)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
if *v == NativeType::Boolean(true) {
|
||||
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
|
||||
}
|
||||
None
|
||||
|
||||
}
|
||||
("POP_JUMP_IF_FALSE", Some(ref target)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
if *v == NativeType::Boolean(false) {
|
||||
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
|
||||
}
|
||||
None
|
||||
|
||||
}
|
||||
("JUMP_FORWARD", Some(ref delta)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let last_offset = curr_frame.get_bytecode_offset().unwrap();
|
||||
curr_frame.lasti = curr_frame.labels.get(&(last_offset + delta)).unwrap().clone();
|
||||
None
|
||||
},
|
||||
("JUMP_ABSOLUTE", Some(ref target)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
curr_frame.lasti = curr_frame.labels.get(target).unwrap().clone();
|
||||
None
|
||||
},
|
||||
("BREAK_LOOP", None) => {
|
||||
// Do we still need to return the why if we use unwind from jsapy?
|
||||
self.unwind("break".to_string());
|
||||
None //?
|
||||
},
|
||||
("RAISE_VARARGS", Some(argc)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
// let (exception, params, traceback) = match argc {
|
||||
let exception = match argc {
|
||||
1 => curr_frame.stack.pop().unwrap(),
|
||||
0 | 2 | 3 => panic!("Not implemented!"),
|
||||
_ => panic!("Invalid paramter for RAISE_VARARGS, must be between 0 to 3")
|
||||
};
|
||||
panic!("{:?}", exception);
|
||||
}
|
||||
("INPLACE_ADD", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
match (tos.deref(), tos1.deref()) {
|
||||
(&NativeType::Int(ref tosi), &NativeType::Int(ref tos1i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(tos1i + tosi)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_ADD")
|
||||
}
|
||||
None
|
||||
},
|
||||
|
||||
("STORE_SUBSCR", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
let tos2 = curr_frame.stack.pop().unwrap();
|
||||
match (tos1.deref(), tos.deref()) {
|
||||
(&NativeType::List(ref refl), &NativeType::Int(index)) => {
|
||||
refl.borrow_mut()[index as usize] = (*tos2).clone();
|
||||
},
|
||||
(&NativeType::Str(_), &NativeType::Int(_)) => {
|
||||
// TODO: raise TypeError: 'str' object does not support item assignment
|
||||
panic!("TypeError: 'str' object does not support item assignment")
|
||||
},
|
||||
_ => panic!("TypeError in STORE_SUBSCR")
|
||||
}
|
||||
curr_frame.stack.push(tos1);
|
||||
None
|
||||
},
|
||||
|
||||
("BINARY_ADD", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(ref v1i), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i + v1i)));
|
||||
}
|
||||
(&NativeType::Float(ref v1f), &NativeType::Int(ref v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(*v2i as f64 + v1f)));
|
||||
}
|
||||
(&NativeType::Int(ref v1i), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f + *v1i as f64)));
|
||||
}
|
||||
(&NativeType::Float(ref v1f), &NativeType::Float(ref v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f + v1f)));
|
||||
}
|
||||
(&NativeType::Str(ref str1), &NativeType::Str(ref str2)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Str(format!("{}{}", str2, str1))));
|
||||
}
|
||||
(&NativeType::List(ref l1), &NativeType::List(ref l2)) => {
|
||||
let mut new_l = l2.clone();
|
||||
// TODO: remove unnessary copy
|
||||
new_l.borrow_mut().append(&mut l1.borrow().clone());
|
||||
curr_frame.stack.push(Rc::new(NativeType::List(new_l)));
|
||||
|
||||
}
|
||||
_ => panic!("TypeError in BINARY_ADD")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_POWER", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i.pow(v1i as u32))));
|
||||
}
|
||||
(&NativeType::Float(v1f), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float((v2i as f64).powf(v1f))));
|
||||
}
|
||||
(&NativeType::Int(v1i), &NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f.powi(v1i))));
|
||||
}
|
||||
(&NativeType::Float(v1f), &NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Float(v2f.powf(v1f))));
|
||||
}
|
||||
_ => panic!("TypeError in BINARY_POWER")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_MULTIPLY", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i * v1i)));
|
||||
},
|
||||
/*
|
||||
(NativeType::Float(v1f), NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(NativeType::Float((v2i as f64) * v1f));
|
||||
},
|
||||
(NativeType::Int(v1i), NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(NativeType::Float(v2f * (v1i as f64)));
|
||||
},
|
||||
(NativeType::Float(v1f), NativeType::Float(v2f)) => {
|
||||
curr_frame.stack.push(NativeType::Float(v2f * v1f));
|
||||
},
|
||||
*/
|
||||
//TODO: String multiply
|
||||
_ => panic!("TypeError in BINARY_MULTIPLY")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_TRUE_DIVIDE", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i / v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_DIVIDE")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_MODULO", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i % v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_MODULO")
|
||||
}
|
||||
None
|
||||
},
|
||||
("BINARY_SUBTRACT", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v1 = curr_frame.stack.pop().unwrap();
|
||||
let v2 = curr_frame.stack.pop().unwrap();
|
||||
match (v1.deref(), v2.deref()) {
|
||||
(&NativeType::Int(v1i), &NativeType::Int(v2i)) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(v2i - v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in BINARY_SUBSTRACT")
|
||||
}
|
||||
None
|
||||
},
|
||||
|
||||
("BINARY_SUBSCR", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
debug!("tos: {:?}, tos1: {:?}", tos, tos1);
|
||||
match (tos1.deref(), tos.deref()) {
|
||||
(&NativeType::List(ref l), &NativeType::Int(ref index)) => {
|
||||
let pos_index = (index + l.borrow().len() as i32) % l.borrow().len() as i32;
|
||||
curr_frame.stack.push(Rc::new(l.borrow()[pos_index as usize].clone()))
|
||||
},
|
||||
(&NativeType::List(ref l), &NativeType::Slice(ref opt_start, ref opt_stop, ref opt_step)) => {
|
||||
let start = match opt_start {
|
||||
&Some(start) => ((start + l.borrow().len() as i32) % l.borrow().len() as i32) as usize,
|
||||
&None => 0,
|
||||
};
|
||||
let stop = match opt_stop {
|
||||
&Some(stop) => ((stop + l.borrow().len() as i32) % l.borrow().len() as i32) as usize,
|
||||
&None => l.borrow().len() as usize,
|
||||
};
|
||||
let step = match opt_step {
|
||||
//Some(step) => step as usize,
|
||||
&None => 1 as usize,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
// TODO: we could potentially avoid this copy and use slice
|
||||
curr_frame.stack.push(Rc::new(NativeType::List(RefCell::new(l.borrow()[start..stop].to_vec()))));
|
||||
},
|
||||
(&NativeType::Tuple(ref t), &NativeType::Int(ref index)) => curr_frame.stack.push(Rc::new(t[*index as usize].clone())),
|
||||
(&NativeType::Str(ref s), &NativeType::Int(ref index)) => {
|
||||
let idx = (index + s.len() as i32) % s.len() as i32;
|
||||
curr_frame.stack.push(Rc::new(NativeType::Str(s.chars().nth(idx as usize).unwrap().to_string())));
|
||||
},
|
||||
(&NativeType::Str(ref s), &NativeType::Slice(ref opt_start, ref opt_stop, ref opt_step)) => {
|
||||
let start = match opt_start {
|
||||
&Some(start) if start > s.len() as i32 => s.len(),
|
||||
&Some(start) if start <= s.len() as i32 => ((start + s.len() as i32) % s.len() as i32) as usize,
|
||||
&Some(_) => panic!("Bad start index for string slicing"),
|
||||
&Some(start) => ((start + s.len() as i32) % s.len() as i32) as usize,
|
||||
&None => 0,
|
||||
};
|
||||
let stop = match opt_stop {
|
||||
&Some(stop) if stop > s.len() as i32 => s.len(),
|
||||
&Some(stop) if stop <= s.len() as i32 => ((stop + s.len() as i32) % s.len() as i32) as usize, // Do we need this modding?
|
||||
&Some(_) => panic!("Bad stop index for string slicing"),
|
||||
&None => s.len() as usize,
|
||||
};
|
||||
let step = match opt_step {
|
||||
//Some(step) => step as usize,
|
||||
&None => 1 as usize,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
curr_frame.stack.push(Rc::new(NativeType::Str(s[start..stop].to_string())));
|
||||
},
|
||||
// TODO: implement other Slice possibilities
|
||||
_ => panic!("TypeError: indexing type {:?} with index {:?} is not supported (yet?)", tos1, tos)
|
||||
};
|
||||
None
|
||||
},
|
||||
("ROT_TWO", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let tos = curr_frame.stack.pop().unwrap();
|
||||
let tos1 = curr_frame.stack.pop().unwrap();
|
||||
curr_frame.stack.push(tos);
|
||||
curr_frame.stack.push(tos1);
|
||||
None
|
||||
}
|
||||
("UNARY_NEGATIVE", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
match v.deref() {
|
||||
&NativeType::Int(v1i) => {
|
||||
curr_frame.stack.push(Rc::new(NativeType::Int(-v1i)));
|
||||
},
|
||||
_ => panic!("TypeError in UINARY_NEGATIVE")
|
||||
}
|
||||
None
|
||||
},
|
||||
("UNARY_POSITIVE", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let v = curr_frame.stack.pop().unwrap();
|
||||
// Any case that is not just push back?
|
||||
curr_frame.stack.push(v);
|
||||
None
|
||||
},
|
||||
("PRINT_ITEM", None) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
// TODO: Print without the (...)
|
||||
println!("{:?}", curr_frame.stack.pop().unwrap());
|
||||
None
|
||||
},
|
||||
("PRINT_NEWLINE", None) => {
|
||||
print!("\n");
|
||||
None
|
||||
},
|
||||
("MAKE_FUNCTION", Some(argc)) => {
|
||||
// https://docs.python.org/3.4/library/dis.html#opcode-MAKE_FUNCTION
|
||||
let curr_frame = self.curr_frame();
|
||||
let qualified_name = curr_frame.stack.pop().unwrap();
|
||||
let code_obj = match curr_frame.stack.pop().unwrap().deref() {
|
||||
&NativeType::Code(ref code) => code.clone(),
|
||||
_ => panic!("Second item on the stack should be a code object")
|
||||
};
|
||||
// pop argc arguments
|
||||
// argument: name, args, globals
|
||||
let func = Function::new(code_obj);
|
||||
curr_frame.stack.push(Rc::new(NativeType::Function(func)));
|
||||
None
|
||||
},
|
||||
("CALL_FUNCTION", Some(argc)) => {
|
||||
let kw_count = (argc >> 8) as u8;
|
||||
let pos_count = (argc & 0xFF) as u8;
|
||||
// Pop the arguments based on argc
|
||||
let mut kw_args = HashMap::new();
|
||||
let mut pos_args = Vec::new();
|
||||
{
|
||||
let curr_frame = self.curr_frame();
|
||||
for _ in 0..kw_count {
|
||||
let native_val = curr_frame.stack.pop().unwrap();
|
||||
let native_key = curr_frame.stack.pop().unwrap();
|
||||
if let (ref val, &NativeType::Str(ref key)) = (native_val, native_key.deref()) {
|
||||
|
||||
kw_args.insert(key.clone(), val.clone());
|
||||
}
|
||||
else {
|
||||
panic!("Incorrect type found while building keyword argument list")
|
||||
}
|
||||
}
|
||||
for _ in 0..pos_count {
|
||||
pos_args.push(curr_frame.stack.pop().unwrap());
|
||||
}
|
||||
}
|
||||
let locals = {
|
||||
// FIXME: no clone here
|
||||
self.curr_frame().locals.clone()
|
||||
};
|
||||
|
||||
let func = {
|
||||
match self.curr_frame().stack.pop().unwrap().deref() {
|
||||
&NativeType::Function(ref func) => {
|
||||
// pop argc arguments
|
||||
// argument: name, args, globals
|
||||
// build the callargs hashmap
|
||||
pos_args.reverse();
|
||||
let mut callargs = HashMap::new();
|
||||
for (name, val) in func.code.co_varnames.iter().zip(pos_args) {
|
||||
callargs.insert(name.to_string(), val);
|
||||
}
|
||||
// merge callargs with kw_args
|
||||
let return_value = {
|
||||
let frame = self.make_frame(func.code.clone(), callargs, Some(locals));
|
||||
self.run_frame(frame)
|
||||
};
|
||||
self.curr_frame().stack.push(Rc::new(return_value));
|
||||
},
|
||||
&NativeType::NativeFunction(func) => {
|
||||
pos_args.reverse();
|
||||
let return_value = func(pos_args);
|
||||
self.curr_frame().stack.push(Rc::new(return_value));
|
||||
},
|
||||
_ => panic!("The item on the stack should be a code object")
|
||||
}
|
||||
};
|
||||
None
|
||||
},
|
||||
("RETURN_VALUE", None) => {
|
||||
// Hmmm... what is this used?
|
||||
// I believe we need to push this to the next frame
|
||||
self.curr_frame().return_value = (*self.curr_frame().stack.pop().unwrap()).clone();
|
||||
Some("return".to_string())
|
||||
},
|
||||
("SETUP_LOOP", Some(delta)) => {
|
||||
let curr_frame = self.curr_frame();
|
||||
let curr_offset = curr_frame.get_bytecode_offset().unwrap();
|
||||
curr_frame.blocks.push(Block {
|
||||
block_type: "loop".to_string(),
|
||||
handler: *curr_frame.labels.get(&(curr_offset + delta)).unwrap(),
|
||||
});
|
||||
None
|
||||
},
|
||||
("POP_BLOCK", None) => {
|
||||
self.curr_frame().blocks.pop();
|
||||
None
|
||||
}
|
||||
("SetLineno", _) | ("LABEL", _)=> {
|
||||
// Skip
|
||||
None
|
||||
},
|
||||
(name, _) => {
|
||||
panic!("Unrecongnizable op code: {}", name);
|
||||
}
|
||||
} // end match
|
||||
} // end dispatch function
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PyCodeObject {
|
||||
co_consts: Vec<NativeType>,
|
||||
co_names: Vec<String>,
|
||||
co_code: Vec<(usize, String, Option<usize>)>, //size, name, args
|
||||
co_varnames: Vec<String>,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
fn parse_native_type(val_str: &str) -> Result<NativeType, ()> {
|
||||
// println!("{:?}", val_str);
|
||||
match val_str {
|
||||
"None" => Ok(NativeType::NoneType),
|
||||
"True" => Ok(NativeType::Boolean(true)),
|
||||
"False" => Ok(NativeType::Boolean(false)),
|
||||
_ => {
|
||||
if let Ok(int) = val_str.parse::<i32>() {
|
||||
return Ok(NativeType::Int(int))
|
||||
}
|
||||
|
||||
if let Ok(float) = val_str.parse::<f64>() {
|
||||
return Ok(NativeType::Float(float))
|
||||
}
|
||||
|
||||
if val_str.starts_with("\'") && val_str.ends_with("\'") {
|
||||
return Ok(NativeType::Str(val_str[1..val_str.len()-1].to_string()))
|
||||
}
|
||||
|
||||
if val_str.starts_with("u\'") && val_str.ends_with("\'") {
|
||||
return Ok(NativeType::Unicode(val_str[2..val_str.len()-1].to_string()))
|
||||
}
|
||||
|
||||
if val_str.starts_with("(") && val_str.ends_with(")") {
|
||||
return Ok(NativeType::Str(val_str[1..val_str.len()-1].to_string()))
|
||||
}
|
||||
|
||||
Err(())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_bytecode(s: &str) -> Code {
|
||||
let lines: Vec<&str> = s.split('\n').collect();
|
||||
|
||||
let (metadata, ops) = lines.split_at(2);
|
||||
// Parsing the first line CONSTS
|
||||
let consts_str: &str = metadata[0]; // line 0 is empty
|
||||
let values_str = &consts_str[("CONSTS: (".len())..(consts_str.len()-1)];
|
||||
let values: Vec<&str> = values_str.split(",").collect();
|
||||
// We need better type definition here
|
||||
let consts: Vec<NativeType>= values.into_iter()
|
||||
.map(|x| x.trim())
|
||||
.filter(|x| x.len() > 0)
|
||||
.map(|x| parse_native_type(x).unwrap())
|
||||
.collect();
|
||||
|
||||
// Parsing the second line NAMES
|
||||
let names_str: &str = metadata[1]; // line 0 is empty
|
||||
let values_str = &names_str[("NAMES: (".len())..(names_str.len()-1)];
|
||||
let values: Vec<&str> = values_str.split(",").collect();
|
||||
// We are assuming the first and last chars are \'
|
||||
let names: Vec<&str>= values.into_iter().map(|x| x.trim())
|
||||
.filter(|x| x.len() > 0)
|
||||
.map(|x| &x[1..(x.len()-1)]).collect();
|
||||
|
||||
// Parsing the op_codes
|
||||
let op_codes: Vec<(&str, Option<usize>)>= ops.into_iter()
|
||||
.map(|x| x.trim())
|
||||
.filter(|x| x.len() > 0)
|
||||
.map(|x| {
|
||||
let op: Vec<&str> = x.split(", ").collect();
|
||||
// println!("{:?}", op);
|
||||
(op[0], op[1].parse::<usize>().ok())
|
||||
}).collect();
|
||||
|
||||
|
||||
Code {
|
||||
consts: consts,
|
||||
op_codes: op_codes,
|
||||
names: names,
|
||||
}
|
||||
}
|
||||
*/
|
||||
fn main() {
|
||||
env_logger::init().unwrap();
|
||||
// TODO: read this from args
|
||||
@@ -876,115 +31,3 @@ fn main() {
|
||||
vm.run_code(code);
|
||||
// println!("Done");
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn test_parse_native_type() {
|
||||
|
||||
assert_eq!(NativeType::NoneType, parse_native_type("None").unwrap());
|
||||
assert_eq!(NativeType::Boolean(true), parse_native_type("True").unwrap());
|
||||
assert_eq!(NativeType::Boolean(false), parse_native_type("False").unwrap());
|
||||
assert_eq!(NativeType::Int(3), parse_native_type("3").unwrap());
|
||||
assert_eq!(NativeType::Float(3.0), parse_native_type("3.0").unwrap());
|
||||
assert_eq!(NativeType::Float(3.5), parse_native_type("3.5").unwrap());
|
||||
assert_eq!(NativeType::Str("foo".to_string()), parse_native_type("\'foo\'").unwrap());
|
||||
assert_eq!(NativeType::Unicode("foo".to_string()), parse_native_type("u\'foo\'").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_bytecode() {
|
||||
|
||||
let input = "CONSTS: (1, None, 2)
|
||||
NAMES: ('a', 'b')
|
||||
SetLineno, 1
|
||||
LOAD_CONST, 2
|
||||
PRINT_ITEM, None
|
||||
PRINT_NEWLINE, None
|
||||
LOAD_CONST, None
|
||||
RETURN_VALUE, None
|
||||
";
|
||||
let expected = Code { // Fill me with a more sensible data
|
||||
consts: vec![NativeType::Int(1), NativeType::NoneType, NativeType::Int(2)],
|
||||
names: vec!["a", "b"],
|
||||
op_codes: vec![
|
||||
("SetLineno", Some(1)),
|
||||
("LOAD_CONST", Some(2)),
|
||||
("PRINT_ITEM", None),
|
||||
("PRINT_NEWLINE", None),
|
||||
("LOAD_CONST", None),
|
||||
("RETURN_VALUE", None)
|
||||
]
|
||||
};
|
||||
|
||||
assert_eq!(expected, parse_bytecode(input));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_const_tuple() {
|
||||
let input = "CONSTS: (None,)
|
||||
NAMES: ()
|
||||
SetLineno, 1
|
||||
LOAD_CONST, 0
|
||||
RETURN_VALUE, None
|
||||
";
|
||||
let expected = Code { // Fill me with a more sensible data
|
||||
consts: vec![NativeType::NoneType],
|
||||
names: vec![],
|
||||
op_codes: vec![
|
||||
("SetLineno", Some(1)),
|
||||
("LOAD_CONST", Some(0)),
|
||||
("RETURN_VALUE", None)
|
||||
]
|
||||
};
|
||||
|
||||
assert_eq!(expected, parse_bytecode(input));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vm() {
|
||||
|
||||
let code = PyCodeObject {
|
||||
co_consts: vec![NativeType::Int(1), NativeType::NoneType, NativeType::Int(2)],
|
||||
co_names: vec![],
|
||||
co_code: vec![
|
||||
(3, "LOAD_CONST".to_string(), Some(2)),
|
||||
(1, "PRINT_ITEM".to_string(), None),
|
||||
(1, "PRINT_NEWLINE".to_string(), None),
|
||||
(3, "LOAD_CONST".to_string(), None),
|
||||
(1, "RETURN_VALUE".to_string(), None)
|
||||
]
|
||||
};
|
||||
let mut vm = VirtualMachine::new();
|
||||
assert_eq!((), vm.exec(&code));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_parse_jsonbytecode() {
|
||||
|
||||
let input = "{\"co_consts\":[{\"Int\":1},\"NoneType\",{\"Int\":2}],\"co_names\":[\"print\"],\"co_code\":[[3,\"LOAD_CONST\",2],[1,\"PRINT_ITEM\",null],[1,\"PRINT_NEWLINE\",null],[3,\"LOAD_CONST\",null],[1,\"RETURN_VALUE\",null]]}";
|
||||
// let input = "{\"co_names\": [\"print\"], \"co_code\": [[\"LOAD_CONST\", 0], [\"LOAD_CONST\", 0], [\"COMPARE_OP\", 2], [\"POP_JUMP_IF_FALSE\", 25], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 1], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"JUMP_FORWARD\", 10], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 2], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"LOAD_CONST\", 0], [\"LOAD_CONST\", 3], [\"COMPARE_OP\", 2], [\"POP_JUMP_IF_FALSE\", 60], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 1], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"JUMP_FORWARD\", 10], [\"LOAD_NAME\", 0], [\"LOAD_CONST\", 2], [\"CALL_FUNCTION\", 1], [\"POP_TOP\", null], [\"LOAD_CONST\", 4], [\"RETURN_VALUE\", null]], \"co_consts\": [{\"Int\": 1}, {\"Str\": \"equal\"}, {\"Str\": \"not equal\"}, {\"Int\": 2}, {\"NoneType\": null}]}";
|
||||
|
||||
let expected = PyCodeObject { // Fill me with a more sensible data
|
||||
co_consts: vec![NativeType::Int(1), NativeType::NoneType, NativeType::Int(2)],
|
||||
co_names: vec!["print".to_string()],
|
||||
co_code: vec![
|
||||
(3, "LOAD_CONST".to_string(), Some(2)),
|
||||
(1, "PRINT_ITEM".to_string(), None),
|
||||
(1, "PRINT_NEWLINE".to_string(), None),
|
||||
(3, "LOAD_CONST".to_string(), None),
|
||||
(1, "RETURN_VALUE".to_string(), None)
|
||||
]
|
||||
};
|
||||
println!("{}", serde_json::to_string(&expected).unwrap());
|
||||
|
||||
let deserialized: PyCodeObject = serde_json::from_str(&input).unwrap();
|
||||
assert_eq!(expected, deserialized)
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_tuple_serialization(){
|
||||
let tuple = NativeType::Tuple(vec![NativeType::Int(1),NativeType::Int(2)]);
|
||||
println!("{}", serde_json::to_string(&tuple).unwrap());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user