Vm working. simple interface built
- still need stack view - still ned to work with devices
This commit is contained in:
104
ic10emu/Cargo.lock
generated
104
ic10emu/Cargo.lock
generated
@@ -38,6 +38,16 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.10.0"
|
||||
@@ -75,10 +85,11 @@ dependencies = [
|
||||
"phf_codegen",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"thiserror",
|
||||
"web-time",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -90,6 +101,12 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.69"
|
||||
@@ -117,6 +134,21 @@ version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
@@ -205,6 +237,12 @@ dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
@@ -300,6 +338,26 @@ version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
@@ -371,6 +429,40 @@ dependencies = [
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
@@ -442,13 +534,3 @@ name = "wasm-bindgen-shared"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "web-time"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
@@ -9,21 +9,30 @@ edition = "2021"
|
||||
crate-type = ["lib"]
|
||||
|
||||
|
||||
|
||||
|
||||
[dependencies]
|
||||
const-crc32 = "1.3.0"
|
||||
itertools = "0.12.1"
|
||||
phf = "0.11.2"
|
||||
rand = "0.8.5"
|
||||
regex = "1.10.3"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
strum = { version = "0.26.2", features = ["derive", "phf", "strum_macros"] }
|
||||
strum_macros = "0.26.2"
|
||||
thiserror = "1.0.58"
|
||||
time = { version = "0.3.34", features = [
|
||||
"formatting",
|
||||
"serde",
|
||||
"local-offset",
|
||||
] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
web-time = "1.1.0"
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
time = { version = "0.3.34", features = [
|
||||
"formatting",
|
||||
"serde",
|
||||
"local-offset",
|
||||
"wasm-bindgen",
|
||||
] }
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -44,7 +44,7 @@ fn write_repr_enum<T: std::io::Write, I, P>(
|
||||
let additional_strum = if use_phf { "#[strum(use_phf)]\n" } else { "" };
|
||||
write!(
|
||||
writer,
|
||||
"#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash, EnumString, AsRefStr, EnumProperty, EnumIter)]\n\
|
||||
"#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Hash, EnumString, AsRefStr, EnumProperty, EnumIter, Serialize, Deserialize)]\n\
|
||||
{additional_strum}\
|
||||
pub enum {name} {{\n"
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::interpreter;
|
||||
use crate::tokens::SplitConsecutiveIndicesExt;
|
||||
use crate::tokens::{SplitConsecutiveIndicesExt, SplitConsecutiveWithIndices};
|
||||
use itertools::Itertools;
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
@@ -16,6 +16,7 @@ pub mod generated {
|
||||
use strum::EnumProperty;
|
||||
use strum::EnumString;
|
||||
use strum::IntoEnumIterator;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/instructions.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/logictypes.rs"));
|
||||
@@ -85,8 +86,9 @@ pub mod generated {
|
||||
}
|
||||
|
||||
pub use generated::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ParseError {
|
||||
pub line: usize,
|
||||
pub start: usize,
|
||||
@@ -233,29 +235,15 @@ impl FromStr for Instruction {
|
||||
})
|
||||
}
|
||||
}?;
|
||||
let mut operand_tokens = Vec::new();
|
||||
let mut string_start = None;
|
||||
for (index, token) in tokens_iter {
|
||||
if token.starts_with("HASH(\"") {
|
||||
string_start = Some(index);
|
||||
}
|
||||
if let Some(start) = string_start {
|
||||
if token.ends_with("\")") {
|
||||
operand_tokens.push((start, &s[start..(index + token.len())]));
|
||||
string_start = None;
|
||||
}
|
||||
} else {
|
||||
operand_tokens.push((index, token));
|
||||
}
|
||||
}
|
||||
let operands = operand_tokens
|
||||
.into_iter()
|
||||
|
||||
let operands = get_operand_tokens(s, tokens_iter)
|
||||
.iter()
|
||||
.map(|(index, token)| {
|
||||
token
|
||||
.parse::<Operand>()
|
||||
.map_err(|e| e.offset(index).span(token.len()))
|
||||
.map_err(|e| e.offset(*index).span(token.len()))
|
||||
})
|
||||
.collect::<Result<Vec<_>, ParseError>>()?;
|
||||
.try_collect()?;
|
||||
Ok(Instruction {
|
||||
instruction,
|
||||
operands,
|
||||
@@ -263,14 +251,33 @@ impl FromStr for Instruction {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
fn get_operand_tokens<'a>(s: &'a str, tokens_iter: SplitConsecutiveWithIndices<'a>) -> Vec<(usize, &'a str)> {
|
||||
let mut operand_tokens = Vec::with_capacity(8);
|
||||
let mut string_start = None;
|
||||
for (index, token) in tokens_iter {
|
||||
if token.starts_with("HASH(\"") {
|
||||
string_start = Some(index);
|
||||
}
|
||||
if let Some(start) = string_start {
|
||||
if token.ends_with("\")") {
|
||||
operand_tokens.push((start, &s[start..(index + token.len())]));
|
||||
string_start = None;
|
||||
}
|
||||
} else {
|
||||
operand_tokens.push((index, token));
|
||||
}
|
||||
}
|
||||
operand_tokens
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum Device {
|
||||
Db,
|
||||
Numbered(u32),
|
||||
Indirect { indirection: u32, target: u32 },
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Operand {
|
||||
RegisterSpec {
|
||||
indirection: u32,
|
||||
@@ -349,7 +356,7 @@ impl Operand {
|
||||
) -> Result<(Option<u16>, Option<u32>), interpreter::ICError> {
|
||||
match &self {
|
||||
&Operand::DeviceSpec { device, connection } => match device {
|
||||
Device::Db => Ok((Some(ic.id), *connection)),
|
||||
Device::Db => Ok((Some(ic.device), *connection)),
|
||||
Device::Numbered(p) => {
|
||||
let dp = ic
|
||||
.pins
|
||||
@@ -598,6 +605,7 @@ impl FromStr for Operand {
|
||||
.collect::<String>();
|
||||
if !float_str.is_empty() {
|
||||
if rest_iter.peek() == Some(&&'.') {
|
||||
rest_iter.next();
|
||||
let decimal_str = rest_iter
|
||||
.take_while_ref(|c| c.is_digit(10))
|
||||
.collect::<String>();
|
||||
@@ -684,7 +692,7 @@ impl FromStr for Label {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Identifier {
|
||||
// #[rust_sitter::leaf(pattern = r"[a-zA-Z_.][\w\d.]*", transform = |id| id.to_string())]
|
||||
pub name: String,
|
||||
@@ -732,7 +740,7 @@ impl FromStr for Identifier {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Number {
|
||||
Float(f64),
|
||||
Binary(f64),
|
||||
@@ -757,7 +765,6 @@ impl Number {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::generated::*;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,47 +1,56 @@
|
||||
use core::f64;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::{HashMap, HashSet},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
mod grammar;
|
||||
mod interpreter;
|
||||
pub mod grammar;
|
||||
pub mod interpreter;
|
||||
mod rand_mscorlib;
|
||||
mod tokens;
|
||||
pub mod tokens;
|
||||
|
||||
use grammar::{BatchMode, LogicType, ReagentMode, SlotLogicType};
|
||||
use interpreter::ICError;
|
||||
use interpreter::{ICError, LineError};
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[derive(Error, Debug, Serialize, Deserialize)]
|
||||
pub enum VMError {
|
||||
#[error("Device with id '{0}' does not exist")]
|
||||
UnknownId(u16),
|
||||
#[error("IC with id '{0}' does not exist")]
|
||||
UnknownIcId(u16),
|
||||
#[error("Device with id '{0}' does not have a IC Slot")]
|
||||
NoIC(u16),
|
||||
#[error("IC encoutered an error: {0}")]
|
||||
ICError(#[from] ICError),
|
||||
#[error("IC encoutered an error: {0}")]
|
||||
LineError(#[from] LineError),
|
||||
#[error("Invalid network ID {0}")]
|
||||
InvalidNetwork(u16),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum FieldType {
|
||||
Read,
|
||||
Write,
|
||||
ReadWrite,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LogicField {
|
||||
pub field_type: FieldType,
|
||||
pub value: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct Slot {
|
||||
pub fields: HashMap<grammar::SlotLogicType, LogicField>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum Connection {
|
||||
CableNetwork(Option<u16>),
|
||||
#[default]
|
||||
@@ -56,12 +65,12 @@ pub struct Device {
|
||||
pub fields: HashMap<grammar::LogicType, LogicField>,
|
||||
pub slots: Vec<Slot>,
|
||||
pub reagents: HashMap<ReagentMode, HashMap<i32, f64>>,
|
||||
pub ic: Option<interpreter::IC>,
|
||||
pub ic: Option<u16>,
|
||||
pub connections: [Connection; 8],
|
||||
pub prefab_hash: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Network {
|
||||
pub devices: HashSet<u16>,
|
||||
pub channels: [f64; 8],
|
||||
@@ -74,7 +83,7 @@ struct IdSequenceGenerator {
|
||||
|
||||
impl Default for IdSequenceGenerator {
|
||||
fn default() -> Self {
|
||||
IdSequenceGenerator { next: 1 }
|
||||
IdSequenceGenerator { next: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,13 +97,13 @@ impl IdSequenceGenerator {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VM {
|
||||
pub ics: HashSet<u16>,
|
||||
pub devices: HashMap<u16, Device>,
|
||||
pub networks: HashMap<u16, Network>,
|
||||
pub ics: HashMap<u16, Rc<RefCell<interpreter::IC>>>,
|
||||
pub devices: HashMap<u16, Rc<RefCell<Device>>>,
|
||||
pub networks: HashMap<u16, Rc<RefCell<Network>>>,
|
||||
pub default_network: u16,
|
||||
id_gen: IdSequenceGenerator,
|
||||
network_id_gen: IdSequenceGenerator,
|
||||
random: crate::rand_mscorlib::Random,
|
||||
random: Rc<RefCell<crate::rand_mscorlib::Random>>,
|
||||
}
|
||||
|
||||
impl Default for Network {
|
||||
@@ -146,7 +155,7 @@ impl Network {
|
||||
|
||||
impl Device {
|
||||
pub fn new(id: u16) -> Self {
|
||||
Device {
|
||||
let mut device = Device {
|
||||
id,
|
||||
name: None,
|
||||
name_hash: None,
|
||||
@@ -156,12 +165,36 @@ impl Device {
|
||||
ic: None,
|
||||
connections: [Connection::default(); 8],
|
||||
prefab_hash: None,
|
||||
}
|
||||
};
|
||||
device.connections[0] = Connection::CableNetwork(None);
|
||||
device
|
||||
}
|
||||
|
||||
pub fn with_ic(id: u16) -> Self {
|
||||
pub fn with_ic(id: u16, ic: u16) -> Self {
|
||||
let mut device = Device::new(id);
|
||||
device.ic = Some(interpreter::IC::new(id));
|
||||
device.ic = Some(ic);
|
||||
device.fields.insert(
|
||||
LogicType::Setting,
|
||||
LogicField {
|
||||
field_type: FieldType::ReadWrite,
|
||||
value: 0.0,
|
||||
},
|
||||
);
|
||||
device.fields.insert(
|
||||
LogicType::Error,
|
||||
LogicField {
|
||||
field_type: FieldType::ReadWrite,
|
||||
value: 0.0,
|
||||
},
|
||||
);
|
||||
device.fields.insert(
|
||||
LogicType::PrefabHash,
|
||||
LogicField {
|
||||
field_type: FieldType::Read,
|
||||
value: -128473777.0,
|
||||
},
|
||||
);
|
||||
device.prefab_hash = Some(-128473777);
|
||||
device
|
||||
}
|
||||
|
||||
@@ -262,19 +295,19 @@ impl VM {
|
||||
pub fn new() -> Self {
|
||||
let id_gen = IdSequenceGenerator::default();
|
||||
let mut network_id_gen = IdSequenceGenerator::default();
|
||||
let default_network = Network::default();
|
||||
let default_network = Rc::new(RefCell::new(Network::default()));
|
||||
let mut networks = HashMap::new();
|
||||
let default_network_key = network_id_gen.next();
|
||||
networks.insert(default_network_key, default_network);
|
||||
|
||||
let mut vm = VM {
|
||||
ics: HashSet::new(),
|
||||
ics: HashMap::new(),
|
||||
devices: HashMap::new(),
|
||||
networks,
|
||||
default_network: default_network_key,
|
||||
id_gen,
|
||||
network_id_gen,
|
||||
random: crate::rand_mscorlib::Random::new(),
|
||||
random: Rc::new(RefCell::new(crate::rand_mscorlib::Random::new())),
|
||||
};
|
||||
let _ = vm.add_ic(None);
|
||||
vm
|
||||
@@ -284,8 +317,11 @@ impl VM {
|
||||
Device::new(self.id_gen.next())
|
||||
}
|
||||
|
||||
fn new_ic(&mut self) -> Device {
|
||||
Device::with_ic(self.id_gen.next())
|
||||
fn new_ic(&mut self) -> (Device, interpreter::IC) {
|
||||
let id = self.id_gen.next();
|
||||
let ic = interpreter::IC::new(id, id);
|
||||
let device = Device::with_ic(id, id);
|
||||
(device, ic)
|
||||
}
|
||||
|
||||
pub fn add_device(&mut self, network: Option<u16>) -> Result<u16, VMError> {
|
||||
@@ -314,7 +350,15 @@ impl VM {
|
||||
});
|
||||
}
|
||||
let id = device.id;
|
||||
self.devices.insert(id, device);
|
||||
self.devices.insert(id, Rc::new(RefCell::new(device)));
|
||||
let _ = self.add_device_to_network(
|
||||
id,
|
||||
if let Some(network) = network {
|
||||
network
|
||||
} else {
|
||||
self.default_network
|
||||
},
|
||||
);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
@@ -324,7 +368,7 @@ impl VM {
|
||||
return Err(VMError::InvalidNetwork(*n));
|
||||
}
|
||||
}
|
||||
let mut device = self.new_ic();
|
||||
let (mut device, ic) = self.new_ic();
|
||||
if let Some(first_network) = device
|
||||
.connections
|
||||
.iter_mut()
|
||||
@@ -344,45 +388,117 @@ impl VM {
|
||||
});
|
||||
}
|
||||
let id = device.id;
|
||||
self.devices.insert(id, device);
|
||||
self.ics.insert(id);
|
||||
let ic_id = ic.id;
|
||||
self.devices.insert(id, Rc::new(RefCell::new(device)));
|
||||
self.ics.insert(ic_id, Rc::new(RefCell::new(ic)));
|
||||
let _ = self.add_device_to_network(
|
||||
id,
|
||||
if let Some(network) = network {
|
||||
network
|
||||
} else {
|
||||
self.default_network
|
||||
},
|
||||
);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub fn add_network(&mut self) -> u16 {
|
||||
let next_id = self.network_id_gen.next();
|
||||
self.networks.insert(next_id, Network::default());
|
||||
self.networks
|
||||
.insert(next_id, Rc::new(RefCell::new(Network::default())));
|
||||
next_id
|
||||
}
|
||||
|
||||
pub fn get_default_network(&mut self) -> &mut Network {
|
||||
self.networks.get_mut(&self.default_network).unwrap()
|
||||
pub fn get_default_network(&self) -> Rc<RefCell<Network>> {
|
||||
self.networks.get(&self.default_network).cloned().unwrap()
|
||||
}
|
||||
|
||||
pub fn get_network(&mut self, id: u16) -> Option<&mut Network> {
|
||||
self.networks.get_mut(&id)
|
||||
pub fn get_network(&self, id: u16) -> Option<Rc<RefCell<Network>>> {
|
||||
self.networks.get(&id).cloned()
|
||||
}
|
||||
|
||||
pub fn remove_ic(&mut self, id: u16) {
|
||||
if self.ics.remove(&id) {
|
||||
if self.ics.remove(&id).is_some() {
|
||||
self.devices.remove(&id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_code(&mut self, id: u16, code: &str) -> Result<bool, VMError> {
|
||||
let device = self.devices.get_mut(&id).ok_or(VMError::UnknownId(id))?;
|
||||
let ic = device.ic.as_mut().ok_or(VMError::NoIC(id))?;
|
||||
pub fn set_code(&self, id: u16, code: &str) -> Result<bool, VMError> {
|
||||
let device = self
|
||||
.devices
|
||||
.get(&id)
|
||||
.ok_or(VMError::UnknownId(id))?
|
||||
.borrow();
|
||||
let ic_id = *device.ic.as_ref().ok_or(VMError::NoIC(id))?;
|
||||
let mut ic = self
|
||||
.ics
|
||||
.get(&ic_id)
|
||||
.ok_or(VMError::UnknownIcId(ic_id))?
|
||||
.borrow_mut();
|
||||
let new_prog = interpreter::Program::try_from_code(code)?;
|
||||
ic.program = new_prog;
|
||||
ic.ip = 0;
|
||||
ic.code = code.to_string();
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn get_device(&mut self, id: u16) -> Option<&mut Device> {
|
||||
self.devices.get_mut(&id)
|
||||
pub fn step_ic(&self, id: u16) -> Result<bool, VMError> {
|
||||
let device = self.devices.get(&id).ok_or(VMError::UnknownId(id))?.clone();
|
||||
let ic_id = *device.borrow().ic.as_ref().ok_or(VMError::NoIC(id))?;
|
||||
let ic = self
|
||||
.ics
|
||||
.get(&ic_id)
|
||||
.ok_or(VMError::UnknownIcId(ic_id))?
|
||||
.clone();
|
||||
ic.borrow_mut().ic = 0;
|
||||
let result = ic.borrow_mut().step(self)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn get_device_same_network(&mut self, source: u16, other: u16) -> Option<&mut Device> {
|
||||
/// returns true if exacuted 128 lines, false if returned early.
|
||||
pub fn run_ic(&self, id: u16, ignore_errors: bool) -> Result<bool, VMError> {
|
||||
let device = self.devices.get(&id).ok_or(VMError::UnknownId(id))?.clone();
|
||||
let ic_id = *device.borrow().ic.as_ref().ok_or(VMError::NoIC(id))?;
|
||||
let ic = self
|
||||
.ics
|
||||
.get(&ic_id)
|
||||
.ok_or(VMError::UnknownIcId(ic_id))?
|
||||
.clone();
|
||||
ic.borrow_mut().ic = 0;
|
||||
for _i in 0..128 {
|
||||
if let Err(err) = ic.borrow_mut().step(self) {
|
||||
if !ignore_errors {
|
||||
return Err(err.into());
|
||||
}
|
||||
}
|
||||
if let interpreter::ICState::Yield = ic.borrow().state {
|
||||
return Ok(false);
|
||||
} else if let interpreter::ICState::Sleep(_then, _sleep_for) = ic.borrow().state {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
ic.borrow_mut().state = interpreter::ICState::Yield;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn reset_ic(&self, id: u16) -> Result<bool, VMError> {
|
||||
let device = self.devices.get(&id).ok_or(VMError::UnknownId(id))?.clone();
|
||||
let ic_id = *device.borrow().ic.as_ref().ok_or(VMError::NoIC(id))?;
|
||||
let ic = self
|
||||
.ics
|
||||
.get(&ic_id)
|
||||
.ok_or(VMError::UnknownIcId(ic_id))?
|
||||
.clone();
|
||||
ic.borrow_mut().ic = 0;
|
||||
ic.borrow_mut().reset();
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn get_device(&self, id: u16) -> Option<Rc<RefCell<Device>>> {
|
||||
self.devices.get(&id).cloned()
|
||||
}
|
||||
|
||||
pub fn get_device_same_network(&self, source: u16, other: u16) -> Option<Rc<RefCell<Device>>> {
|
||||
if self.devices_on_same_network(&[source, other]) {
|
||||
self.get_device(other)
|
||||
} else {
|
||||
@@ -395,29 +511,41 @@ impl VM {
|
||||
.networks
|
||||
.get(&(id as u16))
|
||||
.ok_or(ICError::BadNetworkId(id as u32))?;
|
||||
Ok(network.channels[channel])
|
||||
Ok(network.borrow().channels[channel])
|
||||
}
|
||||
|
||||
pub fn set_network_channel(&mut self, id: usize, channel: usize, val: f64) -> Result<(), ICError> {
|
||||
pub fn set_network_channel(&self, id: usize, channel: usize, val: f64) -> Result<(), ICError> {
|
||||
let network = self
|
||||
.networks
|
||||
.get_mut(&(id as u16))
|
||||
.get(&(id as u16))
|
||||
.ok_or(ICError::BadNetworkId(id as u32))?;
|
||||
network.channels[channel] = val;
|
||||
network.borrow_mut().channels[channel] = val;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn devices_on_same_network(&self, ids: &[u16]) -> bool {
|
||||
for (_id, net) in self.networks.iter() {
|
||||
if net.contains(ids) {
|
||||
if net.borrow().contains(ids) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn add_device_to_network(&self, id: u16, network_id: u16) -> Result<bool, VMError> {
|
||||
if !self.devices.contains_key(&id) {
|
||||
return Err(VMError::UnknownId(id));
|
||||
};
|
||||
if let Some(network) = self.networks.get(&network_id) {
|
||||
network.borrow_mut().add(id);
|
||||
Ok(true)
|
||||
} else {
|
||||
Err(VMError::InvalidNetwork(network_id))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_batch_device_field(
|
||||
&mut self,
|
||||
&self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
typ: LogicType,
|
||||
@@ -425,14 +553,19 @@ impl VM {
|
||||
) -> Result<(), ICError> {
|
||||
let networks = &self.networks;
|
||||
self.devices
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
if device
|
||||
.borrow()
|
||||
.fields
|
||||
.get(&LogicType::PrefabHash)
|
||||
.map(|f| f.value)
|
||||
== Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
.any(|(_net_id, net)| net.borrow().contains(&[source, *id]))
|
||||
{
|
||||
device.set_field(typ, val)
|
||||
device.clone().borrow_mut().set_field(typ, val)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@@ -441,7 +574,7 @@ impl VM {
|
||||
}
|
||||
|
||||
pub fn set_batch_device_slot_field(
|
||||
&mut self,
|
||||
&self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
index: f64,
|
||||
@@ -450,14 +583,19 @@ impl VM {
|
||||
) -> Result<(), ICError> {
|
||||
let networks = &self.networks;
|
||||
self.devices
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
if device
|
||||
.borrow()
|
||||
.fields
|
||||
.get(&LogicType::PrefabHash)
|
||||
.map(|f| f.value)
|
||||
== Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
.any(|(_net_id, net)| net.borrow().contains(&[source, *id]))
|
||||
{
|
||||
device.set_slot_field(index, typ, val)
|
||||
device.borrow_mut().set_slot_field(index, typ, val)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@@ -466,7 +604,7 @@ impl VM {
|
||||
}
|
||||
|
||||
pub fn set_batch_name_device_field(
|
||||
&mut self,
|
||||
&self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
name: f64,
|
||||
@@ -475,15 +613,20 @@ impl VM {
|
||||
) -> Result<(), ICError> {
|
||||
let networks = &self.networks;
|
||||
self.devices
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& Some(name) == device.name_hash
|
||||
if device
|
||||
.borrow()
|
||||
.fields
|
||||
.get(&LogicType::PrefabHash)
|
||||
.map(|f| f.value)
|
||||
== Some(prefab)
|
||||
&& Some(name) == device.borrow().name_hash
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
.any(|(_net_id, net)| net.borrow().contains(&[source, *id]))
|
||||
{
|
||||
device.set_field(typ, val)
|
||||
device.borrow_mut().set_field(typ, val)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@@ -492,7 +635,7 @@ impl VM {
|
||||
}
|
||||
|
||||
pub fn get_batch_device_field(
|
||||
&mut self,
|
||||
&self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
typ: LogicType,
|
||||
@@ -501,14 +644,19 @@ impl VM {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
if device
|
||||
.borrow()
|
||||
.fields
|
||||
.get(&LogicType::PrefabHash)
|
||||
.map(|f| f.value)
|
||||
== Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
.any(|(_net_id, net)| net.borrow().contains(&[source, *id]))
|
||||
{
|
||||
device.get_field(typ).map(|val| Some(val))
|
||||
device.borrow_mut().get_field(typ).map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@@ -535,7 +683,7 @@ impl VM {
|
||||
}
|
||||
|
||||
pub fn get_batch_name_device_field(
|
||||
&mut self,
|
||||
&self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
name: f64,
|
||||
@@ -545,15 +693,20 @@ impl VM {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& Some(name) == device.name_hash
|
||||
if device
|
||||
.borrow()
|
||||
.fields
|
||||
.get(&LogicType::PrefabHash)
|
||||
.map(|f| f.value)
|
||||
== Some(prefab)
|
||||
&& Some(name) == device.borrow().name_hash
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
.any(|(_net_id, net)| net.borrow().contains(&[source, *id]))
|
||||
{
|
||||
device.get_field(typ).map(|val| Some(val))
|
||||
device.borrow().get_field(typ).map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@@ -580,7 +733,7 @@ impl VM {
|
||||
}
|
||||
|
||||
pub fn get_batch_name_device_slot_field(
|
||||
&mut self,
|
||||
&self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
name: f64,
|
||||
@@ -591,15 +744,23 @@ impl VM {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
&& Some(name) == device.name_hash
|
||||
if device
|
||||
.borrow()
|
||||
.fields
|
||||
.get(&LogicType::PrefabHash)
|
||||
.map(|f| f.value)
|
||||
== Some(prefab)
|
||||
&& Some(name) == device.borrow().name_hash
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
.any(|(_net_id, net)| net.borrow().contains(&[source, *id]))
|
||||
{
|
||||
device.get_slot_field(index, typ).map(|val| Some(val))
|
||||
device
|
||||
.borrow()
|
||||
.get_slot_field(index, typ)
|
||||
.map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@@ -626,7 +787,7 @@ impl VM {
|
||||
}
|
||||
|
||||
pub fn get_batch_device_slot_field(
|
||||
&mut self,
|
||||
&self,
|
||||
source: u16,
|
||||
prefab: f64,
|
||||
index: f64,
|
||||
@@ -636,14 +797,22 @@ impl VM {
|
||||
let networks = &self.networks;
|
||||
let samples = self
|
||||
.devices
|
||||
.iter_mut()
|
||||
.iter()
|
||||
.map(|(id, device)| {
|
||||
if device.fields.get(&LogicType::PrefabHash).map(|f| f.value) == Some(prefab)
|
||||
if device
|
||||
.borrow()
|
||||
.fields
|
||||
.get(&LogicType::PrefabHash)
|
||||
.map(|f| f.value)
|
||||
== Some(prefab)
|
||||
&& networks
|
||||
.iter()
|
||||
.any(|(_net_id, net)| net.contains(&[source, *id]))
|
||||
.any(|(_net_id, net)| net.borrow().contains(&[source, *id]))
|
||||
{
|
||||
device.get_slot_field(index, typ).map(|val| Some(val))
|
||||
device
|
||||
.borrow()
|
||||
.get_slot_field(index, typ)
|
||||
.map(|val| Some(val))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
use std::usize;
|
||||
|
||||
const MSEED: i32 = 161803398;
|
||||
// const MZ: i32 = 0;
|
||||
// const MZ: i32 = 0;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Random {
|
||||
inext: i32,
|
||||
inextp: i32,
|
||||
inext: usize,
|
||||
inextp: usize,
|
||||
seed_array: [i32; 56],
|
||||
}
|
||||
|
||||
|
||||
/// Partial implementation of mscorlib System.Random
|
||||
/// https://github.com/microsoft/referencesource/blob/master/mscorlib/system/random.cs#L94
|
||||
impl Random {
|
||||
@@ -29,20 +28,20 @@ impl Random {
|
||||
seed_array[55] = mj;
|
||||
let mut mk: i32 = 1;
|
||||
|
||||
for i in 1_usize..55 {
|
||||
let ii = (21 * i) % 55;
|
||||
for i in 1..55 {
|
||||
let ii = 21 * i % 55;
|
||||
seed_array[ii] = mk;
|
||||
mk = mj - mk;
|
||||
mk = mj.wrapping_sub(mk);
|
||||
if mk < 0 {
|
||||
mk += i32::MAX;
|
||||
mk = mk.wrapping_add(i32::MAX);
|
||||
}
|
||||
mj = seed_array[ii];
|
||||
}
|
||||
for _k in 1_usize..5 {
|
||||
for i in 1_usize..56 {
|
||||
seed_array[i] -= seed_array[1 + (i + 30) % 55];
|
||||
seed_array[i] = seed_array[i].wrapping_sub(seed_array[1 + (i + 30) % 55]);
|
||||
if seed_array[i] < 0 {
|
||||
seed_array[i] += i32::MAX;
|
||||
seed_array[i] = seed_array[i].wrapping_add(i32::MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,28 +63,24 @@ impl Random {
|
||||
let mut inext = self.inext;
|
||||
let mut inextp = self.inextp;
|
||||
|
||||
if {
|
||||
inext += 1;
|
||||
inext
|
||||
} >= 56
|
||||
{
|
||||
inext += 1;
|
||||
|
||||
if inext >= 56 {
|
||||
inext = 1;
|
||||
}
|
||||
if {
|
||||
inextp += 1;
|
||||
inextp
|
||||
} >= 56
|
||||
{
|
||||
inextp += 1;
|
||||
if inextp >= 56 {
|
||||
inextp = 1;
|
||||
}
|
||||
|
||||
let mut retval = self.seed_array[inext as usize] - self.seed_array[inextp as usize];
|
||||
let mut retval =
|
||||
self.seed_array[inext as usize].wrapping_sub(self.seed_array[inextp as usize]);
|
||||
|
||||
if retval == i32::MAX {
|
||||
retval -= 1;
|
||||
}
|
||||
if retval < 0 {
|
||||
retval += i32::MAX;
|
||||
retval = retval.wrapping_add(i32::MAX);
|
||||
}
|
||||
self.seed_array[inext as usize] = retval;
|
||||
|
||||
@@ -103,6 +98,26 @@ impl Random {
|
||||
pub fn next_f64(&mut self) -> f64 {
|
||||
self.sample()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn create() {
|
||||
let mut rand = Random::with_seed(0);
|
||||
assert_eq!(rand.next(), 1559595546);
|
||||
assert_eq!(rand.next(), 1755192844);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify() {
|
||||
let mut rand = Random::with_seed(1919810);
|
||||
assert_eq!(rand.next(), 147482110);
|
||||
assert_eq!(rand.next(), 1747108798);
|
||||
assert_eq!(rand.next(), 1937076328);
|
||||
assert_eq!(rand.next(), 924982271);
|
||||
assert_eq!(rand.next_f64(), 0.044092261252967765);
|
||||
assert_eq!(rand.next(), 659561101);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,14 +47,16 @@ impl<'a> Iterator for SplitConsecutiveWithIndices<'a> {
|
||||
}
|
||||
} else {
|
||||
let s = &self.haystack[self.start..start];
|
||||
let index = self.start;
|
||||
self.start = start;
|
||||
Some((self.start, s))
|
||||
Some((index, s))
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let s = &self.haystack[self.start..];
|
||||
let index = self.start;
|
||||
self.start = self.haystack.len();
|
||||
Some((self.start, s))
|
||||
Some((index, s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
147
ic10emu/verify_mscorlib_rand.ipynb
Normal file
147
ic10emu/verify_mscorlib_rand.ipynb
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"dotnet_interactive": {
|
||||
"language": "csharp"
|
||||
},
|
||||
"polyglot_notebook": {
|
||||
"kernelName": "csharp"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div class=\"dni-plaintext\"><pre>[ 1559595546, 1755192844 ]</pre></div><style>\r\n",
|
||||
".dni-code-hint {\r\n",
|
||||
" font-style: italic;\r\n",
|
||||
" overflow: hidden;\r\n",
|
||||
" white-space: nowrap;\r\n",
|
||||
"}\r\n",
|
||||
".dni-treeview {\r\n",
|
||||
" white-space: nowrap;\r\n",
|
||||
"}\r\n",
|
||||
".dni-treeview td {\r\n",
|
||||
" vertical-align: top;\r\n",
|
||||
" text-align: start;\r\n",
|
||||
"}\r\n",
|
||||
"details.dni-treeview {\r\n",
|
||||
" padding-left: 1em;\r\n",
|
||||
"}\r\n",
|
||||
"table td {\r\n",
|
||||
" text-align: start;\r\n",
|
||||
"}\r\n",
|
||||
"table tr { \r\n",
|
||||
" vertical-align: top; \r\n",
|
||||
" margin: 0em 0px;\r\n",
|
||||
"}\r\n",
|
||||
"table tr td pre \r\n",
|
||||
"{ \r\n",
|
||||
" vertical-align: top !important; \r\n",
|
||||
" margin: 0em 0px !important;\r\n",
|
||||
"} \r\n",
|
||||
"table th {\r\n",
|
||||
" text-align: start;\r\n",
|
||||
"}\r\n",
|
||||
"</style>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"var rand = new System.Random(0);\n",
|
||||
"int[] two_rands = [rand.Next(), rand.Next()];\n",
|
||||
"\n",
|
||||
"two_rands"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"dotnet_interactive": {
|
||||
"language": "csharp"
|
||||
},
|
||||
"polyglot_notebook": {
|
||||
"kernelName": "csharp"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div class=\"dni-plaintext\"><pre>[ 147482110, 1747108798, 1937076328, 924982271, 0.044092261252967765, 659561101 ]</pre></div><style>\r\n",
|
||||
".dni-code-hint {\r\n",
|
||||
" font-style: italic;\r\n",
|
||||
" overflow: hidden;\r\n",
|
||||
" white-space: nowrap;\r\n",
|
||||
"}\r\n",
|
||||
".dni-treeview {\r\n",
|
||||
" white-space: nowrap;\r\n",
|
||||
"}\r\n",
|
||||
".dni-treeview td {\r\n",
|
||||
" vertical-align: top;\r\n",
|
||||
" text-align: start;\r\n",
|
||||
"}\r\n",
|
||||
"details.dni-treeview {\r\n",
|
||||
" padding-left: 1em;\r\n",
|
||||
"}\r\n",
|
||||
"table td {\r\n",
|
||||
" text-align: start;\r\n",
|
||||
"}\r\n",
|
||||
"table tr { \r\n",
|
||||
" vertical-align: top; \r\n",
|
||||
" margin: 0em 0px;\r\n",
|
||||
"}\r\n",
|
||||
"table tr td pre \r\n",
|
||||
"{ \r\n",
|
||||
" vertical-align: top !important; \r\n",
|
||||
" margin: 0em 0px !important;\r\n",
|
||||
"} \r\n",
|
||||
"table th {\r\n",
|
||||
" text-align: start;\r\n",
|
||||
"}\r\n",
|
||||
"</style>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"var rand = new System.Random(1919810);\n",
|
||||
"double[] samples = [rand.Next(), rand.Next(), rand.Next(), rand.Next(), rand.NextDouble(), rand.Next()];\n",
|
||||
"\n",
|
||||
"samples"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".NET (C#)",
|
||||
"language": "C#",
|
||||
"name": ".net-csharp"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "polyglot-notebook"
|
||||
},
|
||||
"polyglot_notebook": {
|
||||
"kernelInfo": {
|
||||
"defaultKernelName": "csharp",
|
||||
"items": [
|
||||
{
|
||||
"aliases": [],
|
||||
"name": "csharp"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
Reference in New Issue
Block a user