full typescript conversion

This commit is contained in:
Rachel
2024-03-31 16:12:21 -07:00
parent ddb964f4dc
commit 60332b498d
29 changed files with 976 additions and 606 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@ dist/
mode_modules/
target/
Session.vim
*.pyc

View File

@@ -58,6 +58,7 @@
"brnez",
"Circuitboard",
"codegen",
"conv",
"cstyle",
"endpos",
"getd",
@@ -123,6 +124,7 @@
"thiserror",
"tokentype",
"trunc",
"Tsify",
"whos"
]
}

View File

@@ -17,7 +17,7 @@ pub mod generated {
use strum::EnumProperty;
use strum::EnumString;
use strum::IntoEnumIterator;
include!(concat!(env!("OUT_DIR"), "/instructions.rs"));
include!(concat!(env!("OUT_DIR"), "/logictypes.rs"));
include!(concat!(env!("OUT_DIR"), "/modes.rs"));

View File

@@ -228,6 +228,19 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "gloo-utils"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e"
dependencies = [
"js-sys",
"serde",
"serde_json",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
@@ -303,8 +316,10 @@ dependencies = [
"itertools",
"js-sys",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.6.5",
"serde_with",
"thiserror",
"tsify",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
@@ -621,6 +636,17 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde-wasm-bindgen"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e"
dependencies = [
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]]
name = "serde-wasm-bindgen"
version = "0.6.5"
@@ -643,6 +669,17 @@ dependencies = [
"syn 2.0.55",
]
[[package]]
name = "serde_derive_internals"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.55",
]
[[package]]
name = "serde_json"
version = "1.0.115"
@@ -804,6 +841,32 @@ dependencies = [
"time-core",
]
[[package]]
name = "tsify"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0"
dependencies = [
"gloo-utils",
"serde",
"serde-wasm-bindgen 0.5.0",
"serde_json",
"tsify-macros",
"wasm-bindgen",
]
[[package]]
name = "tsify-macros"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47"
dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.55",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"

View File

@@ -18,6 +18,8 @@ serde-wasm-bindgen = "0.6.5"
itertools = "0.12.1"
serde = { version = "1.0.197", features = ["derive"] }
serde_with = "3.7.0"
tsify = { version = "0.4.5", default-Vfeatures = false, features = ["js", "wasm-bindgen"] }
thiserror = "1.0.58"
[features]
default = ["console_error_panic_hook"]

23
ic10emu_wasm/build.rs Normal file
View File

@@ -0,0 +1,23 @@
use std::{
env,
fs::{self, File},
io::{BufWriter, Write},
path::Path,
};
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("ts_types.rs");
let output_file = File::create(dest_path).unwrap();
let mut writer = BufWriter::new(&output_file);
let infile = Path::new("src/types.ts");
let contents = fs::read_to_string(infile).unwrap();
write!(
&mut writer,
"#[wasm_bindgen(typescript_custom_section)]\n\
const TYPES: &'static str = r#\"{contents}\"#;
"
)
.unwrap();
}

View File

@@ -1,18 +1,15 @@
#[macro_use]
mod utils;
mod types;
use types::{Stack, Registers};
use std::{cell::RefCell, rc::Rc};
use itertools::Itertools;
// use itertools::Itertools;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
use serde_with::serde_as;
#[serde_as]
#[derive(Serialize, Deserialize)]
struct Stack(#[serde_as(as = "[_; 512]")] [f64; 512]);
#[wasm_bindgen]
extern "C" {
@@ -46,22 +43,22 @@ impl DeviceRef {
self.device.borrow().name_hash
}
#[wasm_bindgen(getter)]
#[wasm_bindgen(getter, skip_typescript)]
pub fn fields(&self) -> JsValue {
serde_wasm_bindgen::to_value(&self.device.borrow().fields).unwrap()
}
#[wasm_bindgen(getter)]
#[wasm_bindgen(getter, skip_typescript)]
pub fn slots(&self) -> JsValue {
serde_wasm_bindgen::to_value(&self.device.borrow().slots).unwrap()
}
#[wasm_bindgen(getter)]
#[wasm_bindgen(getter, skip_typescript)]
pub fn reagents(&self) -> JsValue {
serde_wasm_bindgen::to_value(&self.device.borrow().reagents).unwrap()
}
#[wasm_bindgen(getter)]
#[wasm_bindgen(getter, skip_typescript)]
pub fn connections(&self) -> JsValue {
serde_wasm_bindgen::to_value(&self.device.borrow().connections).unwrap()
}
@@ -99,46 +96,38 @@ impl DeviceRef {
}
#[wasm_bindgen(getter, js_name = "stack")]
pub fn ic_stack(&self) -> JsValue {
serde_wasm_bindgen::to_value(
&self
.device
.borrow()
.ic
.as_ref()
.map(|ic| {
self.vm
.borrow()
.ics
.get(ic)
.map(|ic| Stack(ic.as_ref().borrow().stack))
})
.flatten(),
)
.unwrap()
pub fn ic_stack(&self) -> Option<Stack> {
self.device
.borrow()
.ic
.as_ref()
.map(|ic| {
self.vm
.borrow()
.ics
.get(ic)
.map(|ic| Stack(ic.as_ref().borrow().stack))
})
.flatten()
}
#[wasm_bindgen(getter, js_name = "registers")]
pub fn ic_registers(&self) -> JsValue {
serde_wasm_bindgen::to_value(
&self
.device
.borrow()
.ic
.as_ref()
.map(|ic| {
self.vm
.borrow()
.ics
.get(ic)
.map(|ic| ic.as_ref().borrow().registers)
})
.flatten(),
)
.unwrap()
pub fn ic_registers(&self) -> Option<Registers> {
self.device
.borrow()
.ic
.as_ref()
.map(|ic| {
self.vm
.borrow()
.ics
.get(ic)
.map(|ic| Registers(ic.as_ref().borrow().registers))
})
.flatten()
}
#[wasm_bindgen(getter, js_name = "aliases")]
#[wasm_bindgen(getter, js_name = "aliases", skip_typescript)]
pub fn ic_aliases(&self) -> JsValue {
serde_wasm_bindgen::to_value(
&self
@@ -158,7 +147,7 @@ impl DeviceRef {
.unwrap()
}
#[wasm_bindgen(getter, js_name = "defines")]
#[wasm_bindgen(getter, js_name = "defines", skip_typescript)]
pub fn ic_defines(&self) -> JsValue {
serde_wasm_bindgen::to_value(
&self
@@ -178,7 +167,7 @@ impl DeviceRef {
.unwrap()
}
#[wasm_bindgen(getter, js_name = "pins")]
#[wasm_bindgen(getter, js_name = "pins", skip_typescript)]
pub fn ic_pins(&self) -> JsValue {
serde_wasm_bindgen::to_value(
&self
@@ -268,7 +257,7 @@ impl DeviceRef {
.as_ref()
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;
let vm_borrow = self.vm.borrow();
let ic = vm_borrow
let ic = vm_borrow
.ics
.get(&ic_id)
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;
@@ -285,7 +274,7 @@ impl DeviceRef {
.as_ref()
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;
let vm_borrow = self.vm.borrow();
let ic = vm_borrow
let ic = vm_borrow
.ics
.get(&ic_id)
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;

17
ic10emu_wasm/src/types.rs Normal file
View File

@@ -0,0 +1,17 @@
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use tsify::Tsify;
use wasm_bindgen::prelude::*;
#[serde_as]
#[derive(Tsify, Serialize, Deserialize)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Stack(#[serde_as(as = "[_; 512]")] pub [f64; 512]);
#[serde_as]
#[derive(Tsify, Serialize, Deserialize)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Registers(#[serde_as(as = "[_; 18]")] pub [f64; 18]);
include!(concat!(env!("OUT_DIR"), "/ts_types.rs"));

36
ic10emu_wasm/src/types.ts Normal file
View File

@@ -0,0 +1,36 @@
type FieldType = 'Read' | 'Write' | 'ReadWrite';
interface LogicField {
field_type: FieldType,
value: number,
}
type Fields = Map<string, LogicField>;
type SlotType = 'AccessCard' | 'Appliance' | 'Back' | 'Battery' | 'Blocked' | 'Bottle' | 'Cartridge' | 'Circuitboard' | 'CreditCard' | 'DataDisk' | 'DrillHead' | 'Egg' | 'Entity' | 'Flare' | 'GasCanister' | 'GasFilter' | 'Helmet' | 'Ingot' | 'LiquidBottle' | 'LiquidCanister' | 'Magazine' | 'Ore' | 'Organ' | 'Plant' | 'ProgramableChip' | 'ScanningHead' | 'SensorProcessingUnit' | 'SoundCartridge' | 'Suit' | 'Tool' | 'Torpedo' | 'None';
interface Slot {
typ: SlotType,
fields: Fields,
}
type Reagents = Map<string, Map<number, number>>;
type Connection = { CableNetwork: number } | 'Other' ;
type Alias = { RegisterSpec: {indirection: number, target: number} } | { DeviceSpec: { device: "Db" | { Numbered: number } | { Indirect: { indirection: number, target: number } } }, connection: number | undefined };
type Aliases = Map<string, Alias>;
type Defines = Map<string, number>;
type Pins = (number | undefined)[]
export interface DeviceRef {
readonly fields: Fields | undefined;
readonly slots: Slot[] | undefined;
readonly reagents: Reagents | undefined;
readonly connections: Connection[] | undefined;
readonly aliases: Aliases | undefined;
readonly defines: Defines | undefined;
readonly pins: Pins;
}

View File

@@ -30,4 +30,4 @@ opt-level = "s"
lto = true
[build]
target = "wasm32-unknown-unknown"
target = "wasm32-unknown-unknown"

View File

@@ -54,6 +54,7 @@
"brnez",
"Circuitboard",
"codegen",
"Depressurising",
"endpos",
"getd",
"Hardsuit",
@@ -64,22 +65,28 @@
"Keybind",
"lbns",
"logicable",
"logicslottypes",
"logictype",
"logictypes",
"lparen",
"Mineables",
"modelist",
"ninf",
"noconflict",
"offcanvas",
"overcolumn",
"Overlength",
"pedia",
"pinf",
"popperjs",
"preproc",
"Pressurising",
"putd",
"QUICKFIX",
"reagentmode",
"reagentmodes",
"rocketstation",
"rparen",
"sapz",
"sattellite",
"sdns",

View File

@@ -25,6 +25,9 @@
"homepage": "https://github.com/ryex/ic10emu#readme",
"devDependencies": {
"@oneidentity/zstd-js": "^1.0.3",
"@types/ace": "^0.0.52",
"@types/bootstrap": "^5.2.10",
"@types/wicg-file-system-access": "^2023.10.5",
"autoprefixer": "^10.4.19",
"copy-webpack-plugin": "^12.0.2",
"css-loader": "^6.10.0",
@@ -49,7 +52,7 @@
},
"dependencies": {
"@popperjs/core": "^2.11.8",
"ace-code": "^1.32.9",
"ace-builds": "^1.32.9",
"ace-linters": "^1.1.2",
"bootstrap": "^5.3.3",
"bson": "^6.5.0",

31
www/pnpm-lock.yaml generated
View File

@@ -8,7 +8,7 @@ dependencies:
'@popperjs/core':
specifier: ^2.11.8
version: 2.11.8
ace-code:
ace-builds:
specifier: ^1.32.9
version: 1.32.9
ace-linters:
@@ -52,6 +52,15 @@ devDependencies:
'@oneidentity/zstd-js':
specifier: ^1.0.3
version: 1.0.3
'@types/ace':
specifier: ^0.0.52
version: 0.0.52
'@types/bootstrap':
specifier: ^5.2.10
version: 5.2.10
'@types/wicg-file-system-access':
specifier: ^2023.10.5
version: 2023.10.5
autoprefixer:
specifier: ^10.4.19
version: 10.4.19(postcss@8.4.38)
@@ -235,7 +244,6 @@ packages:
/@popperjs/core@2.11.8:
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
dev: false
/@sindresorhus/is@0.7.0:
resolution: {integrity: sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==}
@@ -256,6 +264,10 @@ packages:
engines: {node: '>=10.13.0'}
dev: true
/@types/ace@0.0.52:
resolution: {integrity: sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==}
dev: true
/@types/body-parser@1.19.5:
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
dependencies:
@@ -269,6 +281,12 @@ packages:
'@types/node': 20.11.30
dev: true
/@types/bootstrap@5.2.10:
resolution: {integrity: sha512-F2X+cd6551tep0MvVZ6nM8v7XgGN/twpdNDjqS1TUM7YFNEtQYWk+dKAnH+T1gr6QgCoGMPl487xw/9hXooa2g==}
dependencies:
'@popperjs/core': 2.11.8
dev: true
/@types/connect-history-api-fallback@1.5.4:
resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==}
dependencies:
@@ -411,6 +429,10 @@ packages:
'@types/node': 20.11.30
dev: true
/@types/wicg-file-system-access@2023.10.5:
resolution: {integrity: sha512-e9kZO9kCdLqT2h9Tw38oGv9UNzBBWaR1MzuAavxPcsV/7FJ3tWbU6RI3uB+yKIDPGLkGVbplS52ub0AcRLvrhA==}
dev: true
/@types/ws@8.5.10:
resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
dependencies:
@@ -631,9 +653,8 @@ packages:
negotiator: 0.6.3
dev: true
/ace-code@1.32.9:
resolution: {integrity: sha512-MgjfSoJ8tV72v9NZntxM/z9txHizagzNczrb1zMtPOKzmGkJChm+ywDQV8INAKRla1vt9gmbAJMSTPpUZHrlew==}
engines: {node: '>= 0.6.0'}
/ace-builds@1.32.9:
resolution: {integrity: sha512-dqBLPj//Gq0b92YUtRIsdWsORf4J+4xW3r8/4Wr2Vqid7O1j7YBV/ZsVvWBjZFy+EnvMCRFCFOEIM1cbt4BQ/g==}
dev: false
/ace-linters@1.1.2:

View File

@@ -1,316 +1,401 @@
"use strict";
var oop = require("ace-code/src/lib/oop");
var TextHighlightRules = require("ace-code/src/mode/text_highlight_rules").TextHighlightRules;
var IC10HighlightRules = function() {
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
var ops = (
"abs|acos|add|alias|and|asin|atan|atan2|bap|bapal|bapz|bapzal|bdns|" +
"bdnsal|bdse|bdseal|beq|beqal|beqz|beqzal|bge|bgeal|bgez|bgezal|bgt|" +
"bgtal|bgtz|bgtzal|ble|bleal|blez|blezal|blt|bltal|bltz|bltzal|bna|" +
"bnaal|bnan|bnaz|bnazal|bne|bneal|bnez|bnezal|brap|brapz|brdns|brdse|" +
"breq|breqz|brge|brgez|brgt|brgtz|brle|brlez|brlt|brltz|brna|brnan|" +
"brnaz|brne|brnez|ceil|cos|define|div|exp|floor|get|getd|hcf|j|jal|jr|" +
"l|label|lb|lbn|lbns|lbs|ld|log|lr|ls|max|min|mod|move|mul|nor|not|or|" +
"peek|poke|pop|push|put|putd|rand|round|s|sap|sapz|sb|sbn|sbs|sd|sdns|" +
"sdse|select|seq|seqz|sge|sgez|sgt|sgtz|sin|sla|sle|sleep|slez|sll|" +
"slt|sltz|sna|snan|snanz|snaz|sne|snez|sqrt|sra|srl|ss|sub|tan|trunc|" +
"xor|yield"
);
var ops = (
"abs|acos|add|alias|and|asin|atan|atan2|bap|bapal|bapz|bapzal|bdns|"+
"bdnsal|bdse|bdseal|beq|beqal|beqz|beqzal|bge|bgeal|bgez|bgezal|bgt|"+
"bgtal|bgtz|bgtzal|ble|bleal|blez|blezal|blt|bltal|bltz|bltzal|bna|"+
"bnaal|bnan|bnaz|bnazal|bne|bneal|bnez|bnezal|brap|brapz|brdns|brdse|"+
"breq|breqz|brge|brgez|brgt|brgtz|brle|brlez|brlt|brltz|brna|brnan|"+
"brnaz|brne|brnez|ceil|cos|define|div|exp|floor|get|getd|hcf|j|jal|jr|"+
"l|label|lb|lbn|lbns|lbs|ld|log|lr|ls|max|min|mod|move|mul|nor|not|or|"+
"peek|poke|pop|push|put|putd|rand|round|s|sap|sapz|sb|sbn|sbs|sd|sdns|"+
"sdse|select|seq|seqz|sge|sgez|sgt|sgtz|sin|sla|sle|sleep|slez|sll|"+
"slt|sltz|sna|snan|snanz|snaz|sne|snez|sqrt|sra|srl|ss|sub|tan|trunc|"+
"xor|yield"
);
var enums = (
"LogicType\\.Power|LogicType\\.Open|LogicType\\.Mode|LogicType\\.Error|"+
"LogicType\\.Pressure|LogicType\\.Temperature|LogicType\\.PressureExternal|"+
"LogicType\\.PressureInternal|LogicType\\.Activate|LogicType\\.Lock|"+
"LogicType\\.Charge|LogicType\\.Setting|LogicType\\.Reagents|"+
"LogicType\\.RatioOxygen|LogicType\\.RatioCarbonDioxide|"+
"LogicType\\.RatioNitrogen|LogicType\\.RatioPollutant|"+
"LogicType\\.RatioVolatiles|LogicType\\.RatioWater|LogicType\\.Horizontal|"+
"LogicType\\.Vertical|LogicType\\.SolarAngle|LogicType\\.Maximum|"+
"LogicType\\.Ratio|LogicType\\.PowerPotential|LogicType\\.PowerActual|"+
"LogicType\\.Quantity|LogicType\\.On|LogicType\\.RequiredPower|"+
"LogicType\\.HorizontalRatio|LogicType\\.VerticalRatio|"+
"LogicType\\.PowerRequired|LogicType\\.Idle|LogicType\\.Color|"+
"LogicType\\.ElevatorSpeed|LogicType\\.ElevatorLevel|"+
"LogicType\\.RecipeHash|LogicType\\.RequestHash|LogicType\\.CompletionRatio|"+
"LogicType\\.ClearMemory|LogicType\\.ExportCount|LogicType\\.ImportCount|"+
"LogicType\\.PowerGeneration|LogicType\\.TotalMoles|LogicType\\.Volume|"+
"LogicType\\.Plant|LogicType\\.Harvest|LogicType\\.Output|"+
"LogicType\\.PressureSetting|LogicType\\.TemperatureSetting|"+
"LogicType\\.TemperatureExternal|LogicType\\.Filtration|"+
"LogicType\\.AirRelease|LogicType\\.PositionX|LogicType\\.PositionZ|"+
"LogicType\\.VelocityMagnitude|LogicType\\.VelocityRelativeX|"+
"LogicType\\.VelocityRelativeY|LogicType\\.VelocityRelativeZ|"+
"LogicType\\.RatioNitrousOxide|LogicType\\.PrefabHash|"+
"LogicType\\.ForceWrite|LogicType\\.SignalStrength|LogicType\\.SignalID|"+
"LogicType\\.TargetX|LogicType\\.TargetY|LogicType\\.TargetZ|"+
"LogicType\\.SettingInput|LogicType\\.SettingOutput|"+
"LogicType\\.CurrentResearchPodType|LogicType\\.ManualResearchRequiredPod|"+
"LogicType\\.MineablesInVicinity|LogicType\\.MineablesInQueue|"+
"LogicType\\.NextWeatherEventTime|LogicType\\.Combustion|LogicType\\.Fuel|"+
"LogicType\\.ReturnFuelCost|LogicType\\.CollectableGoods|LogicType\\.Time|"+
"LogicType\\.Bpm|LogicType\\.EnvironmentEfficiency|"+
"LogicType\\.WorkingGasEfficiency|LogicType\\.PressureInput|"+
"LogicType\\.TemperatureInput|LogicType\\.RatioOxygenInput|"+
"LogicType\\.RatioCarbonDioxideInput|LogicType\\.RatioNitrogenInput|"+
"LogicType\\.RatioPollutantInput|LogicType\\.RatioVolatilesInput|"+
"LogicType\\.RatioWaterInput|LogicType\\.RatioNitrousOxideInput|"+
"LogicType\\.TotalMolesInput|LogicType\\.PressureInput2|"+
"LogicType\\.TemperatureInput2|LogicType\\.RatioOxygenInput2|"+
"LogicType\\.RatioCarbonDioxideInput2|"+
"LogicType\\.RatioLiquidCarbonDioxide|LogicType\\.RatioNitrogenInput2|"+
"LogicType\\.RatioPollutantInput2|LogicType\\.RatioVolatilesInput2|"+
"LogicType\\.RatioWaterInput2|LogicType\\.RatioNitrousOxideInput2|"+
"LogicType\\.TotalMolesInput2|LogicType\\.PressureOutput|"+
"LogicType\\.TemperatureOutput|LogicType\\.RatioOxygenOutput|"+
"LogicType\\.RatioCarbonDioxideOutput|LogicType\\.RatioNitrogenOutput|"+
"LogicType\\.RatioPollutantOutput|LogicType\\.RatioVolatilesOutput|"+
"LogicType\\.RatioWaterOutput|LogicType\\.RatioNitrousOxideOutput|"+
"LogicType\\.TotalMolesOutput|LogicType\\.PressureOutput2|"+
"LogicType\\.TemperatureOutput2|LogicType\\.RatioOxygenOutput2|"+
"LogicType\\.RatioCarbonDioxideOutput2|LogicType\\.RatioNitrogenOutput2|"+
"LogicType\\.RatioPollutantOutput2|LogicType\\.RatioVolatilesOutput2|"+
"LogicType\\.RatioWaterOutput2|LogicType\\.RatioNitrousOxideOutput2|"+
"LogicType\\.TotalMolesOutput2|LogicType\\.CombustionInput|"+
"LogicType\\.CombustionInput2|LogicType\\.CombustionOutput|"+
"LogicType\\.CombustionOutput2|"+
"LogicType\\.OperationalTemperatureEfficiency|"+
"LogicType\\.TemperatureDifferentialEfficiency|"+
"LogicType\\.PressureEfficiency|LogicType\\.CombustionLimiter|"+
"LogicType\\.Throttle|LogicType\\.Rpm|LogicType\\.Stress|"+
"LogicType\\.InterrogationProgress|LogicType\\.TargetPadIndex|"+
"LogicType\\.SizeX|LogicType\\.SizeY|LogicType\\.SizeZ|"+
"LogicType\\.MinimumWattsToContact|LogicType\\.WattsReachingContact|"+
"LogicType\\.Channel0|LogicType\\.Channel1|LogicType\\.Channel2|"+
"LogicType\\.Channel3|LogicType\\.Channel4|LogicType\\.Channel5|"+
"LogicType\\.Channel6|LogicType\\.LineNumber|LogicType\\.Flush|"+
"LogicType\\.Channel7|LogicType\\.SoundAlert|LogicType\\.SolarIrradiance|"+
"LogicType\\.RatioLiquidNitrogen|LogicType\\.RatioLiquidNitrogenInput|"+
"LogicType\\.RatioLiquidNitrogenInput2|"+
"LogicType\\.RatioLiquidNitrogenOutput|"+
"LogicType\\.RatioLiquidNitrogenOutput2|"+
"LogicType\\.VolumeOfLiquid|LogicType\\.RatioLiquidOxygen|"+
"LogicType\\.RatioLiquidOxygenInput|LogicType\\.RatioLiquidOxygenInput2|"+
"LogicType\\.RatioLiquidOxygenOutput|"+
"LogicType\\.RatioLiquidOxygenOutput2|LogicType\\.RatioLiquidVolatiles|"+
"LogicType\\.RatioLiquidVolatilesInput|"+
"LogicType\\.RatioLiquidVolatilesInput2|"+
"LogicType\\.RatioLiquidVolatilesOutput|"+
"LogicType\\.RatioLiquidVolatilesOutput2|LogicType\\.RatioSteam|"+
"LogicType\\.RatioSteamInput|LogicType\\.RatioSteamInput2|"+
"LogicType\\.RatioSteamOutput|LogicType\\.RatioSteamOutput2|"+
"LogicType\\.ContactTypeId|LogicType\\.RatioLiquidCarbonDioxideInput|"+
"LogicType\\.RatioLiquidCarbonDioxideInput2|"+
"LogicType\\.RatioLiquidCarbonDioxideOutput|"+
"LogicType\\.RatioLiquidCarbonDioxideOutput2|"+
"LogicType\\.RatioLiquidPollutant|LogicType\\.RatioLiquidPollutantInput|"+
"LogicType\\.RatioLiquidPollutantInput2|"+
"LogicType\\.RatioLiquidPollutantOutput|"+
"LogicType\\.RatioLiquidPollutantOutput2|"+
"LogicType\\.RatioLiquidNitrousOxide|"+
"LogicType\\.RatioLiquidNitrousOxideInput|"+
"LogicType\\.RatioLiquidNitrousOxideInput2|"+
"LogicType\\.RatioLiquidNitrousOxideOutput|"+
"LogicType\\.RatioLiquidNitrousOxideOutput2|"+
"LogicType\\.Progress|LogicType\\.DestinationCode|"+
"LogicType\\.Acceleration|LogicType\\.ReferenceId|"+
"LogicType\\.AutoShutOff|LogicType\\.Mass|LogicType\\.DryMass|"+
"LogicType\\.Thrust|LogicType\\.Weight|LogicType\\.ThrustToWeight|"+
"LogicType\\.TimeToDestination|LogicType\\.BurnTimeRemaining|"+
"LogicType\\.AutoLand|LogicType\\.ForwardX|LogicType\\.ForwardY|"+
"LogicType\\.ForwardZ|LogicType\\.Orientation|LogicType\\.VelocityX|"+
"LogicType\\.VelocityY|LogicType\\.VelocityZ|LogicType\\.PassedMoles|"+
"LogicType\\.ExhaustVelocity|LogicType\\.FlightControlRule|"+
"LogicType\\.ReEntryAltitude|LogicType\\.Apex|LogicType\\.EntityState|"+
"LogicType\\.DrillCondition|LogicType\\.Index|LogicType\\.CelestialHash|"+
"LogicType\\.AlignmentError|LogicType\\.DistanceAu|LogicType\\.OrbitPeriod|"+
"LogicType\\.Inclination|LogicType\\.Eccentricity|LogicType\\.SemiMajorAxis|"+
"LogicType\\.DistanceKm|LogicType\\.CelestialParentHash|"+
"LogicType\\.TrueAnomaly|"+
"LogicSlotType\\.None|LogicSlotType\\.Occupied|LogicSlotType\\.OccupantHash|"+
"LogicSlotType\\.Quantity|LogicSlotType\\.Damage|LogicSlotType\\.Efficiency|"+
"LogicSlotType\\.Health|LogicSlotType\\.Growth|LogicSlotType\\.Pressure|"+
"LogicSlotType\\.Temperature|LogicSlotType\\.Charge|"+
"LogicSlotType\\.ChargeRatio|LogicSlotType\\.Class|"+
"LogicSlotType\\.PressureWaste|LogicSlotType\\.PressureAir|"+
"LogicSlotType\\.MaxQuantity|LogicSlotType\\.Mature|"+
"LogicSlotType\\.PrefabHash|LogicSlotType\\.Seeding|"+
"LogicSlotType\\.LineNumber|LogicSlotType\\.Volume|"+
"LogicSlotType\\.Open|LogicSlotType\\.On|LogicSlotType\\.Lock|"+
"LogicSlotType\\.SortingClass|LogicSlotType\\.FilterType|"+
"LogicSlotType\\.ReferenceId|"+
"SlotClass\\.None|SlotClass\\.Helmet|SlotClass\\.Suit|SlotClass\\.Back|"+
"SlotClass\\.GasFilter|SlotClass\\.Motherboard|SlotClass\\.Circuitboard|"+
"SlotClass\\.DataDisk|SlotClass\\.Organ|SlotClass\\.Ore|SlotClass\\.Plant|"+
"SlotClass\\.Uniform|SlotClass\\.Battery|SlotClass\\.Egg|SlotClass\\.Belt|"+
"SlotClass\\.Tool|SlotClass\\.Appliance|SlotClass\\.Ingot|SlotClass\\.Torpedo|"+
"SlotClass\\.Cartridge|SlotClass\\.AccessCard|SlotClass\\.Magazine|"+
"SlotClass\\.Circuit|SlotClass\\.Bottle|SlotClass\\.ProgrammableChip|"+
"SlotClass\\.Glasses|SlotClass\\.CreditCard|SlotClass\\.DirtCanister|"+
"SlotClass\\.SensorProcessingUnit|SlotClass\\.LiquidCanister|"+
"SlotClass\\.LiquidBottle|SlotClass\\.Wreckage|SlotClass\\.SoundCartridge|"+
"SlotClass\\.DrillHead|SlotClass\\.ScanningHead|SlotClass\\.Flare|"+
"SlotClass\\.Blocked|GasType\\.Undefined|GasType\\.Oxygen|GasType\\.Nitrogen|"+
"GasType\\.CarbonDioxide|GasType\\.Volatiles|GasType\\.Pollutant|"+
"GasType\\.Water|GasType\\.NitrousOxide|GasType\\.LiquidNitrogen|"+
"GasType\\.LiquidVolatiles|GasType\\.Steam|GasType\\.LiquidCarbonDioxide|"+
"GasType\\.LiquidPollutant|GasType\\.LiquidNitrousOxide|"+
"Equals|Greater|Less|NotEquals|"+
"AirCon\\.Cold|AirCon\\.Hot|AirControl\\.None|AirControl\\.Offline|"+
"AirControl\\.Pressure|AirControl\\.Draught|"+
"Color\\.Blue|Color\\.Gray|Color\\.Green|Color\\.Orange|Color\\.Red|Color\\.Yellow|"+
"Color\\.White|Color\\.Black|Color\\.Brown|Color\\.Khaki|Color\\.Pink|"+
"Color\\.Purple|"+
"DaylightSensorMode\\.Default|DaylightSensorMode\\.Horizontal|"+
"DaylightSensorMode\\.Vertical|"+
"ElevatorMode\\.Stationary|ElevatorMode\\.Upward|ElevatorMode\\.Downward|"+
"EntityState\\.Alive|EntityState\\.Dead|EntityState\\.Unconscious"+
"|EntityState\\.Decay|"+
"PowerMode\\.Idle|PowerMode\\.Discharged|PowerMode\\.Discharging|"+
"PowerMode\\.Charging|PowerMode\\.Charged|"+
"RobotMode\\.None|RobotMode\\.Follow|RobotMode\\.MoveToTarget|"+
"RobotMode\\.Roam|RobotMode\\.Unload|RobotMode\\.PathToTarget|"+
"RobotMode\\.StorageFull|"+
"SortingClass\\.Default|SortingClass\\.Kits|SortingClass\\.Tools|"+
"SortingClass\\.Resources|SortingClass\\.Food|SortingClass\\.Clothing|"+
"SortingClass\\.Appliances|SortingClass\\.Atmospherics|"+
"SortingClass\\.Storage|SortingClass\\.Ores|SortingClass\\.Ices|"+
"TransmitterMode\\.Passive|TransmitterMode\\.Active|"+
"Vent\\.Outward|Vent\\.Inward"
);
var logictypes = (
"Acceleration|Activate|AirRelease|AlignmentError|Apex|AutoLand|"+
"AutoShutOff|Average|Bpm|BurnTimeRemaining|Bypass|CelestialHash|"+
"CelestialParentHash|Channel|Channel0|Channel1|Channel2|Channel3|"+
"Channel4|Channel5|Channel6|Channel7|Charge|ChargeRatio|Class|"+
"ClearMemory|CollectableGoods|Color|Combustion|CombustionInput|"+
"CombustionInput2|CombustionLimiter|CombustionOutput|CombustionOutput2|"+
"CompletionRatio|ContactTypeId|Contents|CurrentResearchPodType|Damage|"+
"DestinationCode|DistanceAu|DistanceKm|DrillCondition|DryMass|"+
"Eccentricity|Efficiency|ElevatorLevel|ElevatorSpeed|EntityState|"+
"EnvironmentEfficiency|Error|ExhaustVelocity|ExportCount|"+
"ExportQuantity|ExportSlotHash|ExportSlotOccupant|FilterType|"+
"Filtration|FlightControlRule|Flush|ForceWrite|ForwardX|ForwardY|"+
"ForwardZ|Fuel|Growth|Harvest|Health|Horizontal|HorizontalRatio|"+
"Idle|ImportCount|ImportQuantity|ImportSlotHash|ImportSlotOccupant|"+
"Inclination|Index|InterrogationProgress|LineNumber|Lock|"+
"ManualResearchRequiredPod|Mass|Mature|MaxQuantity|Maximum|"+
"MinWattsToContact|MineablesInQueue|MineablesInVicinity|Minimum|"+
"MinimumWattsToContact|Mode|NextWeatherEventTime|None|OccupantHash|"+
"Occupied|On|Open|OperationalTemperatureEfficiency|OrbitPeriod|"+
"Orientation|Output|OverShootTarget|PassedMoles|Plant|"+
"PlantEfficiency1|PlantEfficiency2|PlantEfficiency3|PlantEfficiency4|"+
"PlantGrowth1|PlantGrowth2|PlantGrowth3|PlantGrowth4|PlantHash1|"+
"PlantHash2|PlantHash3|PlantHash4|PlantHealth1|PlantHealth2|"+
"PlantHealth3|PlantHealth4|PositionX|PositionY|PositionZ|Power|"+
"PowerActual|PowerGeneration|PowerPotential|PowerRequired|"+
"PrefabHash|Pressure|PressureAir|PressureEfficiency|PressureExternal|"+
"PressureInput|PressureInput2|PressureInternal|PressureOutput|"+
"PressureOutput2|PressureSetting|PressureWaste|Progress|Quantity|"+
"Ratio|RatioCarbonDioxide|RatioCarbonDioxideInput|"+
"RatioCarbonDioxideInput2|RatioCarbonDioxideOutput|"+
"RatioCarbonDioxideOutput2|RatioLiquidCarbonDioxide|"+
"RatioLiquidCarbonDioxideInput|RatioLiquidCarbonDioxideInput2|"+
"RatioLiquidCarbonDioxideOutput|RatioLiquidCarbonDioxideOutput2|"+
"RatioLiquidNitrogen|RatioLiquidNitrogenInput|"+
"RatioLiquidNitrogenInput2|RatioLiquidNitrogenOutput|"+
"RatioLiquidNitrogenOutput2|RatioLiquidNitrousOxide|"+
"RatioLiquidNitrousOxideInput|RatioLiquidNitrousOxideInput2|"+
"RatioLiquidNitrousOxideOutput|RatioLiquidNitrousOxideOutput2|"+
"RatioLiquidOxygen|RatioLiquidOxygenInput|RatioLiquidOxygenInput2|"+
"RatioLiquidOxygenOutput|RatioLiquidOxygenOutput2|"+
"RatioLiquidPollutant|RatioLiquidPollutantInput|"+
"RatioLiquidPollutantInput2|RatioLiquidPollutantOutput|"+
"RatioLiquidPollutantOutput2|RatioLiquidVolatiles|"+
"RatioLiquidVolatilesInput|RatioLiquidVolatilesInput2|"+
"RatioLiquidVolatilesOutput|RatioLiquidVolatilesOutput2|"+
"RatioNitrogen|RatioNitrogenInput|RatioNitrogenInput2|"+
"RatioNitrogenOutput|RatioNitrogenOutput2|RatioNitrousOxide|"+
"RatioNitrousOxideInput|RatioNitrousOxideInput2|"+
"RatioNitrousOxideOutput|RatioNitrousOxideOutput2|RatioOxygen|"+
"RatioOxygenInput|RatioOxygenInput2|RatioOxygenOutput|"+
"RatioOxygenOutput2|RatioPollutant|RatioPollutantInput|"+
"RatioPollutantInput2|RatioPollutantOutput|RatioPollutantOutput2|"+
"RatioSteam|RatioSteamInput|RatioSteamInput2|RatioSteamOutput|"+
"RatioSteamOutput2|RatioVolatiles|RatioVolatilesInput|"+
"RatioVolatilesInput2|RatioVolatilesOutput|RatioVolatilesOutput2|"+
"RatioWater|RatioWaterInput|RatioWaterInput2|RatioWaterOutput|"+
"RatioWaterOutput2|ReEntryAltitude|Reagents|Recipe|RecipeHash|"+
"ReferenceId|RequestHash|Required|RequiredPower|ReturnFuelCost|Rpm|"+
"Seeding|SemiMajorAxis|Setting|SettingInput|SettingInputHash|"+
"SettingOutput|SettingOutputHash|SignalID|SignalStrength|SizeX|SizeY|"+
"SizeZ|SolarAngle|SolarConstant|SolarIrradiance|SortingClass|"+
"SoundAlert|Stress|Sum|TargetPadIndex|TargetX|TargetY|TargetZ|"+
"Temperature|TemperatureDifferentialEfficiency|TemperatureExternal|"+
"TemperatureInput|TemperatureInput2|TemperatureOutput|"+
"TemperatureOutput2|TemperatureSetting|Throttle|Thrust|ThrustToWeight|"+
"Time|TimeToDestination|TotalMoles|TotalMolesInput|TotalMolesInput2|"+
"TotalMolesOutput|TotalMolesOutput2|TrueAnomaly|Unknown|"+
"VelocityMagnitude|VelocityRelativeX|VelocityRelativeY|"+
"VelocityRelativeZ|VelocityX|VelocityY|VelocityZ|Vertical|"+
"VerticalRatio|Volume|VolumeOfLiquid|WattsReachingContact|Weight"+
"|WorkingGasEfficiency"
);
var constants = ("nan|pinf|ninf|pi|deg2rad|rad2deg|epsilon")
var enums = (
"AirCon\\.Cold|AirCon\\.Hot|AirControl\\.Draught|AirControl\\.None|" +
"AirControl\\.Offline|AirControl\\.Pressure|Color\\.Black|Color\\.Blue|" +
"Color\\.Brown|Color\\.Gray|Color\\.Green|Color\\.Khaki|Color\\.Orange|" +
"Color\\.Pink|Color\\.Purple|Color\\.Red|Color\\.White|Color\\.Yellow|" +
"DaylightSensorMode\\.Default|DaylightSensorMode\\.Horizontal|" +
"DaylightSensorMode\\.Vertical|ElevatorMode\\.Downward|" +
"ElevatorMode\\.Stationary|ElevatorMode\\.Upward|EntityState\\.Alive|" +
"EntityState\\.Dead|EntityState\\.Decay|EntityState\\.Unconscious|" +
"Equals|GasType\\.CarbonDioxide|GasType\\.Hydrogen|GasType\\.LiquidCarbonDioxide|" +
"GasType\\.LiquidHydrogen|GasType\\.LiquidNitrogen|GasType\\.LiquidNitrousOxide|" +
"GasType\\.LiquidOxygen|GasType\\.LiquidPollutant|GasType\\.LiquidVolatiles|" +
"GasType\\.Nitrogen|GasType\\.NitrousOxide|GasType\\.Oxygen|" +
"GasType\\.Pollutant|GasType\\.PollutedWater|GasType\\.Steam|" +
"GasType\\.Undefined|GasType\\.Volatiles|GasType\\.Water|" +
"Greater|Less|LogicSlotType\\.Charge|LogicSlotType\\.ChargeRatio|" +
"LogicSlotType\\.Class|LogicSlotType\\.Damage|LogicSlotType\\.Efficiency|" +
"LogicSlotType\\.FilterType|LogicSlotType\\.Growth|LogicSlotType\\.Health|" +
"LogicSlotType\\.LineNumber|LogicSlotType\\.Lock|LogicSlotType\\.Mature|" +
"LogicSlotType\\.MaxQuantity|LogicSlotType\\.None|LogicSlotType\\.OccupantHash|" +
"LogicSlotType\\.Occupied|LogicSlotType\\.On|LogicSlotType\\.Open|" +
"LogicSlotType\\.PrefabHash|LogicSlotType\\.Pressure|" +
"LogicSlotType\\.PressureAir|LogicSlotType\\.PressureWaste|" +
"LogicSlotType\\.Quantity|LogicSlotType\\.ReferenceId|" +
"LogicSlotType\\.Seeding|LogicSlotType\\.SortingClass|" +
"LogicSlotType\\.Temperature|LogicSlotType\\.Volume|" +
"LogicType\\.Acceleration|LogicType\\.Activate|LogicType\\.AirRelease|" +
"LogicType\\.AlignmentError|LogicType\\.Apex|LogicType\\.AutoLand|" +
"LogicType\\.AutoShutOff|LogicType\\.Bpm|LogicType\\.BurnTimeRemaining|" +
"LogicType\\.CelestialHash|LogicType\\.CelestialParentHash|" +
"LogicType\\.Channel1|LogicType\\.Channel1|LogicType\\.Channel2|" +
"LogicType\\.Channel3|LogicType\\.Channel4|LogicType\\.Channel5|" +
"LogicType\\.Channel6|LogicType\\.Channel7|LogicType\\.Charge|" +
"LogicType\\.Chart|LogicType\\.ChartedNavPoints|LogicType\\.ClearMemory|" +
"LogicType\\.CollectableGoods|LogicType\\.Color|LogicType\\.Combustion|" +
"LogicType\\.CombustionInput|LogicType\\.CombustionInput2|" +
"LogicType\\.CombustionLimiter|LogicType\\.CombustionOutput|" +
"LogicType\\.CombustionOutput2|LogicType\\.CompletionRatio|" +
"LogicType\\.ContactTypeId|LogicType\\.CurrentCode|LogicType\\.CurrentResearchPodType|" +
"LogicType\\.Density|LogicType\\.DestinationCode|LogicType\\.Discover|" +
"LogicType\\.DistanceAu|LogicType\\.DistanceKm|LogicType\\.DrillCondition|" +
"LogicType\\.DryMass|LogicType\\.Eccentricity|LogicType\\.ElevatorLevel|" +
"LogicType\\.ElevatorSpeed|LogicType\\.EntityState|LogicType\\.EnvironmentEfficiency|" +
"LogicType\\.Error|LogicType\\.ExhaustVelocity|LogicType\\.ExportCount|" +
"LogicType\\.ExportQuantity|LogicType\\.ExportSlotHash|" +
"LogicType\\.ExportSlotOccupant|LogicType\\.Filtration|" +
"LogicType\\.FlightControlRule|LogicType\\.Flush|LogicType\\.ForceWrite|" +
"LogicType\\.ForwardX|LogicType\\.ForwardY|LogicType\\.ForwardZ|" +
"LogicType\\.Fuel|LogicType\\.Harvest|LogicType\\.Horizontal|" +
"LogicType\\.HorizontalRatio|LogicType\\.Idle|LogicType\\.ImportCount|" +
"LogicType\\.ImportQuantity|LogicType\\.ImportSlotHash|" +
"LogicType\\.ImportSlotOccupant|LogicType\\.Inclination|" +
"LogicType\\.Index|LogicType\\.InterrogationProgress|" +
"LogicType\\.LineNumber|LogicType\\.Lock|LogicType\\.ManualResearchRequiredPod|" +
"LogicType\\.Mass|LogicType\\.Maximum|LogicType\\.MineablesInQueue|" +
"LogicType\\.MineablesInVicinity|LogicType\\.MinedQuantity|" +
"LogicType\\.MinimumWattsToContact|LogicType\\.Mode|" +
"LogicType\\.NavPoints|LogicType\\.NextWeatherEventTime|" +
"LogicType\\.None|LogicType\\.On|LogicType\\.Open|LogicType\\.OperationalTemperatureEfficiency|" +
"LogicType\\.OrbitPeriod|LogicType\\.Orientation|LogicType\\.Output|" +
"LogicType\\.PassedMoles|LogicType\\.Plant|LogicType\\.PlantEfficiency1|" +
"LogicType\\.PlantEfficiency2|LogicType\\.PlantEfficiency3|" +
"LogicType\\.PlantEfficiency4|LogicType\\.PlantGrowth1|" +
"LogicType\\.PlantGrowth2|LogicType\\.PlantGrowth3|LogicType\\.PlantGrowth4|" +
"LogicType\\.PlantHash1|LogicType\\.PlantHash2|LogicType\\.PlantHash3|" +
"LogicType\\.PlantHash4|LogicType\\.PlantHealth1|LogicType\\.PlantHealth2|" +
"LogicType\\.PlantHealth3|LogicType\\.PlantHealth4|LogicType\\.PositionX|" +
"LogicType\\.PositionY|LogicType\\.PositionZ|LogicType\\.Power|" +
"LogicType\\.PowerActual|LogicType\\.PowerGeneration|" +
"LogicType\\.PowerPotential|LogicType\\.PowerRequired|" +
"LogicType\\.PrefabHash|LogicType\\.Pressure|LogicType\\.PressureEfficiency|" +
"LogicType\\.PressureExternal|LogicType\\.PressureInput|" +
"LogicType\\.PressureInput2|LogicType\\.PressureInternal|" +
"LogicType\\.PressureOutput|LogicType\\.PressureOutput2|" +
"LogicType\\.PressureSetting|LogicType\\.Progress|LogicType\\.Quantity|" +
"LogicType\\.Ratio|LogicType\\.RatioCarbonDioxide|LogicType\\.RatioCarbonDioxideInput|" +
"LogicType\\.RatioCarbonDioxideInput2|LogicType\\.RatioCarbonDioxideOutput|" +
"LogicType\\.RatioCarbonDioxideOutput2|LogicType\\.RatioHydrogen|" +
"LogicType\\.RatioLiquidCarbonDioxide|LogicType\\.RatioLiquidCarbonDioxideInput|" +
"LogicType\\.RatioLiquidCarbonDioxideInput2|LogicType\\.RatioLiquidCarbonDioxideOutput|" +
"LogicType\\.RatioLiquidCarbonDioxideOutput2|LogicType\\.RatioLiquidHydrogen|" +
"LogicType\\.RatioLiquidNitrogen|LogicType\\.RatioLiquidNitrogenInput|" +
"LogicType\\.RatioLiquidNitrogenInput2|LogicType\\.RatioLiquidNitrogenOutput|" +
"LogicType\\.RatioLiquidNitrogenOutput2|LogicType\\.RatioLiquidNitrousOxide|" +
"LogicType\\.RatioLiquidNitrousOxideInput|LogicType\\.RatioLiquidNitrousOxideInput2|" +
"LogicType\\.RatioLiquidNitrousOxideOutput|LogicType\\.RatioLiquidNitrousOxideOutput2|" +
"LogicType\\.RatioLiquidOxygen|LogicType\\.RatioLiquidOxygenInput|" +
"LogicType\\.RatioLiquidOxygenInput2|LogicType\\.RatioLiquidOxygenOutput|" +
"LogicType\\.RatioLiquidOxygenOutput2|LogicType\\.RatioLiquidPollutant|" +
"LogicType\\.RatioLiquidPollutantInput|LogicType\\.RatioLiquidPollutantInput2|" +
"LogicType\\.RatioLiquidPollutantOutput|LogicType\\.RatioLiquidPollutantOutput2|" +
"LogicType\\.RatioLiquidVolatiles|LogicType\\.RatioLiquidVolatilesInput|" +
"LogicType\\.RatioLiquidVolatilesInput2|LogicType\\.RatioLiquidVolatilesOutput|" +
"LogicType\\.RatioLiquidVolatilesOutput2|LogicType\\.RatioNitrogen|" +
"LogicType\\.RatioNitrogenInput|LogicType\\.RatioNitrogenInput2|" +
"LogicType\\.RatioNitrogenOutput|LogicType\\.RatioNitrogenOutput2|" +
"LogicType\\.RatioNitrousOxide|LogicType\\.RatioNitrousOxideInput|" +
"LogicType\\.RatioNitrousOxideInput2|LogicType\\.RatioNitrousOxideOutput|" +
"LogicType\\.RatioNitrousOxideOutput2|LogicType\\.RatioOxygen|" +
"LogicType\\.RatioOxygenInput|LogicType\\.RatioOxygenInput2|" +
"LogicType\\.RatioOxygenOutput|LogicType\\.RatioOxygenOutput2|" +
"LogicType\\.RatioPollutant|LogicType\\.RatioPollutantInput|" +
"LogicType\\.RatioPollutantInput2|LogicType\\.RatioPollutantOutput|" +
"LogicType\\.RatioPollutantOutput2|LogicType\\.RatioPollutedWater|" +
"LogicType\\.RatioSteam|LogicType\\.RatioSteamInput|" +
"LogicType\\.RatioSteamInput2|LogicType\\.RatioSteamOutput|" +
"LogicType\\.RatioSteamOutput2|LogicType\\.RatioVolatiles|" +
"LogicType\\.RatioVolatilesInput|LogicType\\.RatioVolatilesInput2|" +
"LogicType\\.RatioVolatilesOutput|LogicType\\.RatioVolatilesOutput2|" +
"LogicType\\.RatioWater|LogicType\\.RatioWaterInput|" +
"LogicType\\.RatioWaterInput2|LogicType\\.RatioWaterOutput|" +
"LogicType\\.RatioWaterOutput2|LogicType\\.ReEntryAltitude|" +
"LogicType\\.Reagents|LogicType\\.RecipeHash|LogicType\\.ReferenceId|" +
"LogicType\\.RequestHash|LogicType\\.RequiredPower|LogicType\\.ReturnFuelCost|" +
"LogicType\\.Richness|LogicType\\.Rpm|LogicType\\.SemiMajorAxis|" +
"LogicType\\.Setting|LogicType\\.SettingInput|LogicType\\.SettingOutput|" +
"LogicType\\.SignalID|LogicType\\.SignalStrength|LogicType\\.Sites|" +
"LogicType\\.Size|LogicType\\.SizeX|LogicType\\.SizeY|" +
"LogicType\\.SizeZ|LogicType\\.SolarAngle|LogicType\\.SolarIrradiance|" +
"LogicType\\.SoundAlert|LogicType\\.Stress|LogicType\\.Survey|" +
"LogicType\\.TargetPadIndex|LogicType\\.TargetX|LogicType\\.TargetY|" +
"LogicType\\.TargetZ|LogicType\\.Temperature|LogicType\\.TemperatureDifferentialEfficiency|" +
"LogicType\\.TemperatureExternal|LogicType\\.TemperatureInput|" +
"LogicType\\.TemperatureInput2|LogicType\\.TemperatureOutput|" +
"LogicType\\.TemperatureOutput2|LogicType\\.TemperatureSetting|" +
"LogicType\\.Throttle|LogicType\\.Thrust|LogicType\\.ThrustToWeight|" +
"LogicType\\.Time|LogicType\\.TimeToDestination|LogicType\\.TotalMoles|" +
"LogicType\\.TotalMolesInput|LogicType\\.TotalMolesInput2|" +
"LogicType\\.TotalMolesOutput|LogicType\\.TotalMolesOutput2|" +
"LogicType\\.TotalQuantity|LogicType\\.TrueAnomaly|LogicType\\.VelocityMagnitude|" +
"LogicType\\.VelocityRelativeX|LogicType\\.VelocityRelativeY|" +
"LogicType\\.VelocityRelativeZ|LogicType\\.VelocityX|" +
"LogicType\\.VelocityY|LogicType\\.VelocityZ|LogicType\\.Vertical|" +
"LogicType\\.VerticalRatio|LogicType\\.Volume|LogicType\\.VolumeOfLiquid|" +
"LogicType\\.WattsReachingContact|LogicType\\.Weight|" +
"LogicType\\.WorkingGasEfficiency|NotEquals|PowerMode\\.Charged|" +
"PowerMode\\.Charging|PowerMode\\.Discharged|PowerMode\\.Discharging|" +
"PowerMode\\.Idle|RobotMode\\.Follow|RobotMode\\.MoveToTarget|" +
"RobotMode\\.None|RobotMode\\.PathToTarget|RobotMode\\.Roam|" +
"RobotMode\\.StorageFull|RobotMode\\.Unload|SlotClass\\.AccessCard|" +
"SlotClass\\.Appliance|SlotClass\\.Back|SlotClass\\.Battery|" +
"SlotClass\\.Belt|SlotClass\\.Blocked|SlotClass\\.Bottle|" +
"SlotClass\\.Cartridge|SlotClass\\.Circuit|SlotClass\\.Circuitboard|" +
"SlotClass\\.CreditCard|SlotClass\\.DataDisk|SlotClass\\.DirtCanister|" +
"SlotClass\\.DrillHead|SlotClass\\.Egg|SlotClass\\.Entity|" +
"SlotClass\\.Flare|SlotClass\\.GasCanister|SlotClass\\.GasFilter|" +
"SlotClass\\.Glasses|SlotClass\\.Helmet|SlotClass\\.Ingot|" +
"SlotClass\\.LiquidBottle|SlotClass\\.LiquidCanister|" +
"SlotClass\\.Magazine|SlotClass\\.Motherboard|SlotClass\\.None|" +
"SlotClass\\.Ore|SlotClass\\.Organ|SlotClass\\.Plant|" +
"SlotClass\\.ProgrammableChip|SlotClass\\.ScanningHead|" +
"SlotClass\\.SensorProcessingUnit|SlotClass\\.SoundCartridge|" +
"SlotClass\\.Suit|SlotClass\\.Tool|SlotClass\\.Torpedo|" +
"SlotClass\\.Uniform|SlotClass\\.Wreckage|SortingClass\\.Appliances|" +
"SortingClass\\.Atmospherics|SortingClass\\.Clothing|" +
"SortingClass\\.Default|SortingClass\\.Food|SortingClass\\.Ices|" +
"SortingClass\\.Kits|SortingClass\\.Ores|SortingClass\\.Resources|" +
"SortingClass\\.Storage|SortingClass\\.Tools|Sound\\.AirlockCycling|" +
"Sound\\.Alarm1|Sound\\.Alarm10|Sound\\.Alarm11|Sound\\.Alarm12|" +
"Sound\\.Alarm2|Sound\\.Alarm3|Sound\\.Alarm4|Sound\\.Alarm5|" +
"Sound\\.Alarm6|Sound\\.Alarm7|Sound\\.Alarm8|Sound\\.Alarm9|" +
"Sound\\.Alert|Sound\\.Danger|Sound\\.Depressurising|" +
"Sound\\.FireFireFire|Sound\\.Five|Sound\\.Floor|Sound\\.Four|" +
"Sound\\.HaltWhoGoesThere|Sound\\.HighCarbonDioxide|" +
"Sound\\.IntruderAlert|Sound\\.LiftOff|Sound\\.MalfunctionDetected|" +
"Sound\\.Music1|Sound\\.Music2|Sound\\.Music3|Sound\\.None|" +
"Sound\\.One|Sound\\.PollutantsDetected|Sound\\.PowerLow|" +
"Sound\\.PressureHigh|Sound\\.PressureLow|Sound\\.Pressurising|" +
"Sound\\.RocketLaunching|Sound\\.StormIncoming|Sound\\.SystemFailure|" +
"Sound\\.TemperatureHigh|Sound\\.TemperatureLow|Sound\\.Three|" +
"Sound\\.TraderIncoming|Sound\\.TraderLanded|Sound\\.Two|" +
"Sound\\.Warning|Sound\\.Welcome|TransmitterMode\\.Active|" +
"TransmitterMode\\.Passive|Vent\\.Inward|Vent\\.Outward");
this.$rules = {
start: [{
token : "comment.line.number-sign",
regex: /#.*$/,
}, {
token: ["text", "keyword", "text", "entity.name.tag"],
regex: /^(\s*)(j(?:al)?)(\s+)([a-zA-Z_.][a-zA-Z0-9_.]*)/,
comment: "absolute jumps | branches with a label"
}, {
token: "keyword",
regex: "^\\s*(?:" + ops + ")\\b",
}, {
token: "entity.name.tag",
regex: /^\s*[a-zA-Z_.][a-zA-Z0-9_.]*\b:/,
comment: "Labels at line start: begin_repeat: add ..."
}, {
token: "variable.parameter",
regex: /\b(?:sp|r(?:a|r*)(?:[0-9]|1[0-7]))\b/,
}, {
token: "variable.language",
regex: /\b(?:d(?:b|[0-5]|r*(?:[0-9]|1[0-7]))(?::[0-9]+)?)\b/,
}, {
token: "support.type",
regex: "\\b(?:" + logictypes + ")\\b",
}, {
token: "constant.language",
regex: "\\b(?:" + constants + ")\\b",
}, {
token: "variable.language",
regex: "\\b(?:" + enums + ")\\b",
}, {
token: "constant.numeric.ic10",
regex: /\-?[0-9]+(?:\.[0-9]+)?|\$[a-fA-F0-9_]+|%[01_]+/,
comment: "Numbers like 12, -3.0, 55, $3F, %1000"
}, {
token: ["support.function", "paren.lparen", "string.quoted", "paren.rparen"],
regex: /\b(HASH)(\()(\".*\")(\))/,
}, {
token: "entity.name",
regex: /\b[a-zA-Z_.][a-zA-Z0-9_.]*\b/,
}]
};
var logictypes = (
"Acceleration|Activate|AirRelease|AlignmentError|Apex|AutoLand|" +
"AutoShutOff|Bpm|BurnTimeRemaining|CelestialHash|CelestialParentHash|" +
"Channel0|Channel1|Channel2|Channel3|Channel4|Channel5|Channel6|" +
"Channel7|Charge|Chart|ChartedNavPoints|ClearMemory|CollectableGoods|" +
"Color|Combustion|CombustionInput|CombustionInput2|CombustionLimiter|" +
"CombustionOutput|CombustionOutput2|CompletionRatio|ContactTypeId|" +
"CurrentCode|CurrentResearchPodType|Density|DestinationCode|Discover|" +
"DistanceAu|DistanceKm|DrillCondition|DryMass|Eccentricity|ElevatorLevel|" +
"ElevatorSpeed|EntityState|EnvironmentEfficiency|Error|ExhaustVelocity|" +
"ExportCount|ExportQuantity|ExportSlotHash|ExportSlotOccupant|" +
"Filtration|FlightControlRule|Flush|ForceWrite|ForwardX|ForwardY|" +
"ForwardZ|Fuel|Harvest|Horizontal|HorizontalRatio|Idle|ImportCount|" +
"ImportQuantity|ImportSlotHash|ImportSlotOccupant|Inclination|" +
"Index|InterrogationProgress|LineNumber|Lock|ManualResearchRequiredPod|" +
"Mass|Maximum|MineablesInQueue|MineablesInVicinity|MinedQuantity|" +
"MinimumWattsToContact|Mode|NavPoints|NextWeatherEventTime|None|" +
"On|Open|OperationalTemperatureEfficiency|OrbitPeriod|Orientation|" +
"Output|PassedMoles|Plant|PlantEfficiency1|PlantEfficiency2|PlantEfficiency3|" +
"PlantEfficiency4|PlantGrowth1|PlantGrowth2|PlantGrowth3|PlantGrowth4|" +
"PlantHash1|PlantHash2|PlantHash3|PlantHash4|PlantHealth1|PlantHealth2|" +
"PlantHealth3|PlantHealth4|PositionX|PositionY|PositionZ|Power|" +
"PowerActual|PowerGeneration|PowerPotential|PowerRequired|PrefabHash|" +
"Pressure|PressureEfficiency|PressureExternal|PressureInput|PressureInput2|" +
"PressureInternal|PressureOutput|PressureOutput2|PressureSetting|" +
"Progress|Quantity|Ratio|RatioCarbonDioxide|RatioCarbonDioxideInput|" +
"RatioCarbonDioxideInput2|RatioCarbonDioxideOutput|RatioCarbonDioxideOutput2|" +
"RatioHydrogen|RatioLiquidCarbonDioxide|RatioLiquidCarbonDioxideInput|" +
"RatioLiquidCarbonDioxideInput2|RatioLiquidCarbonDioxideOutput|" +
"RatioLiquidCarbonDioxideOutput2|RatioLiquidHydrogen|RatioLiquidNitrogen|" +
"RatioLiquidNitrogenInput|RatioLiquidNitrogenInput2|RatioLiquidNitrogenOutput|" +
"RatioLiquidNitrogenOutput2|RatioLiquidNitrousOxide|RatioLiquidNitrousOxideInput|" +
"RatioLiquidNitrousOxideInput2|RatioLiquidNitrousOxideOutput|RatioLiquidNitrousOxideOutput2|" +
"RatioLiquidOxygen|RatioLiquidOxygenInput|RatioLiquidOxygenInput2|" +
"RatioLiquidOxygenOutput|RatioLiquidOxygenOutput2|RatioLiquidPollutant|" +
"RatioLiquidPollutantInput|RatioLiquidPollutantInput2|RatioLiquidPollutantOutput|" +
"RatioLiquidPollutantOutput2|RatioLiquidVolatiles|RatioLiquidVolatilesInput|" +
"RatioLiquidVolatilesInput2|RatioLiquidVolatilesOutput|RatioLiquidVolatilesOutput2|" +
"RatioNitrogen|RatioNitrogenInput|RatioNitrogenInput2|RatioNitrogenOutput|" +
"RatioNitrogenOutput2|RatioNitrousOxide|RatioNitrousOxideInput|" +
"RatioNitrousOxideInput2|RatioNitrousOxideOutput|RatioNitrousOxideOutput2|" +
"RatioOxygen|RatioOxygenInput|RatioOxygenInput2|RatioOxygenOutput|" +
"RatioOxygenOutput2|RatioPollutant|RatioPollutantInput|RatioPollutantInput2|" +
"RatioPollutantOutput|RatioPollutantOutput2|RatioPollutedWater|" +
"RatioSteam|RatioSteamInput|RatioSteamInput2|RatioSteamOutput|" +
"RatioSteamOutput2|RatioVolatiles|RatioVolatilesInput|RatioVolatilesInput2|" +
"RatioVolatilesOutput|RatioVolatilesOutput2|RatioWater|RatioWaterInput|" +
"RatioWaterInput2|RatioWaterOutput|RatioWaterOutput2|ReEntryAltitude|" +
"Reagents|RecipeHash|ReferenceId|RequestHash|RequiredPower|ReturnFuelCost|" +
"Richness|Rpm|SemiMajorAxis|Setting|SettingInput|SettingOutput|" +
"SignalID|SignalStrength|Sites|Size|SizeX|SizeY|SizeZ|SolarAngle|" +
"SolarIrradiance|SoundAlert|Stress|Survey|TargetPadIndex|TargetX|" +
"TargetY|TargetZ|Temperature|TemperatureDifferentialEfficiency|" +
"TemperatureExternal|TemperatureInput|TemperatureInput2|TemperatureOutput|" +
"TemperatureOutput2|TemperatureSetting|Throttle|Thrust|ThrustToWeight|" +
"Time|TimeToDestination|TotalMoles|TotalMolesInput|TotalMolesInput2|" +
"TotalMolesOutput|TotalMolesOutput2|TotalQuantity|TrueAnomaly|" +
"VelocityMagnitude|VelocityRelativeX|VelocityRelativeY|VelocityRelativeZ|" +
"VelocityX|VelocityY|VelocityZ|Vertical|VerticalRatio|Volume|VolumeOfLiquid|" +
"WattsReachingContact|Weight|WorkingGasEfficiency");
this.normalizeRules();
var logictypes = (
"Acceleration|Activate|AirRelease|AlignmentError|Apex|AutoLand|" +
"AutoShutOff|Average|Bpm|BurnTimeRemaining|Bypass|CelestialHash|" +
"CelestialParentHash|Channel|Channel0|Channel1|Channel2|Channel3|" +
"Channel4|Channel5|Channel6|Channel7|Charge|ChargeRatio|Class|" +
"ClearMemory|CollectableGoods|Color|Combustion|CombustionInput|" +
"CombustionInput2|CombustionLimiter|CombustionOutput|CombustionOutput2|" +
"CompletionRatio|ContactTypeId|Contents|CurrentResearchPodType|Damage|" +
"DestinationCode|DistanceAu|DistanceKm|DrillCondition|DryMass|" +
"Eccentricity|Efficiency|ElevatorLevel|ElevatorSpeed|EntityState|" +
"EnvironmentEfficiency|Error|ExhaustVelocity|ExportCount|" +
"ExportQuantity|ExportSlotHash|ExportSlotOccupant|FilterType|" +
"Filtration|FlightControlRule|Flush|ForceWrite|ForwardX|ForwardY|" +
"ForwardZ|Fuel|Growth|Harvest|Health|Horizontal|HorizontalRatio|" +
"Idle|ImportCount|ImportQuantity|ImportSlotHash|ImportSlotOccupant|" +
"Inclination|Index|InterrogationProgress|LineNumber|Lock|" +
"ManualResearchRequiredPod|Mass|Mature|MaxQuantity|Maximum|" +
"MinWattsToContact|MineablesInQueue|MineablesInVicinity|Minimum|" +
"MinimumWattsToContact|Mode|NextWeatherEventTime|None|OccupantHash|" +
"Occupied|On|Open|OperationalTemperatureEfficiency|OrbitPeriod|" +
"Orientation|Output|OverShootTarget|PassedMoles|Plant|" +
"PlantEfficiency1|PlantEfficiency2|PlantEfficiency3|PlantEfficiency4|" +
"PlantGrowth1|PlantGrowth2|PlantGrowth3|PlantGrowth4|PlantHash1|" +
"PlantHash2|PlantHash3|PlantHash4|PlantHealth1|PlantHealth2|" +
"PlantHealth3|PlantHealth4|PositionX|PositionY|PositionZ|Power|" +
"PowerActual|PowerGeneration|PowerPotential|PowerRequired|" +
"PrefabHash|Pressure|PressureAir|PressureEfficiency|PressureExternal|" +
"PressureInput|PressureInput2|PressureInternal|PressureOutput|" +
"PressureOutput2|PressureSetting|PressureWaste|Progress|Quantity|" +
"Ratio|RatioCarbonDioxide|RatioCarbonDioxideInput|" +
"RatioCarbonDioxideInput2|RatioCarbonDioxideOutput|" +
"RatioCarbonDioxideOutput2|RatioLiquidCarbonDioxide|" +
"RatioLiquidCarbonDioxideInput|RatioLiquidCarbonDioxideInput2|" +
"RatioLiquidCarbonDioxideOutput|RatioLiquidCarbonDioxideOutput2|" +
"RatioLiquidNitrogen|RatioLiquidNitrogenInput|" +
"RatioLiquidNitrogenInput2|RatioLiquidNitrogenOutput|" +
"RatioLiquidNitrogenOutput2|RatioLiquidNitrousOxide|" +
"RatioLiquidNitrousOxideInput|RatioLiquidNitrousOxideInput2|" +
"RatioLiquidNitrousOxideOutput|RatioLiquidNitrousOxideOutput2|" +
"RatioLiquidOxygen|RatioLiquidOxygenInput|RatioLiquidOxygenInput2|" +
"RatioLiquidOxygenOutput|RatioLiquidOxygenOutput2|" +
"RatioLiquidPollutant|RatioLiquidPollutantInput|" +
"RatioLiquidPollutantInput2|RatioLiquidPollutantOutput|" +
"RatioLiquidPollutantOutput2|RatioLiquidVolatiles|" +
"RatioLiquidVolatilesInput|RatioLiquidVolatilesInput2|" +
"RatioLiquidVolatilesOutput|RatioLiquidVolatilesOutput2|" +
"RatioNitrogen|RatioNitrogenInput|RatioNitrogenInput2|" +
"RatioNitrogenOutput|RatioNitrogenOutput2|RatioNitrousOxide|" +
"RatioNitrousOxideInput|RatioNitrousOxideInput2|" +
"RatioNitrousOxideOutput|RatioNitrousOxideOutput2|RatioOxygen|" +
"RatioOxygenInput|RatioOxygenInput2|RatioOxygenOutput|" +
"RatioOxygenOutput2|RatioPollutant|RatioPollutantInput|" +
"RatioPollutantInput2|RatioPollutantOutput|RatioPollutantOutput2|" +
"RatioSteam|RatioSteamInput|RatioSteamInput2|RatioSteamOutput|" +
"RatioSteamOutput2|RatioVolatiles|RatioVolatilesInput|" +
"RatioVolatilesInput2|RatioVolatilesOutput|RatioVolatilesOutput2|" +
"RatioWater|RatioWaterInput|RatioWaterInput2|RatioWaterOutput|" +
"RatioWaterOutput2|ReEntryAltitude|Reagents|Recipe|RecipeHash|" +
"ReferenceId|RequestHash|Required|RequiredPower|ReturnFuelCost|Rpm|" +
"Seeding|SemiMajorAxis|Setting|SettingInput|SettingInputHash|" +
"SettingOutput|SettingOutputHash|SignalID|SignalStrength|SizeX|SizeY|" +
"SizeZ|SolarAngle|SolarConstant|SolarIrradiance|SortingClass|" +
"SoundAlert|Stress|Sum|TargetPadIndex|TargetX|TargetY|TargetZ|" +
"Temperature|TemperatureDifferentialEfficiency|TemperatureExternal|" +
"TemperatureInput|TemperatureInput2|TemperatureOutput|" +
"TemperatureOutput2|TemperatureSetting|Throttle|Thrust|ThrustToWeight|" +
"Time|TimeToDestination|TotalMoles|TotalMolesInput|TotalMolesInput2|" +
"TotalMolesOutput|TotalMolesOutput2|TrueAnomaly|Unknown|" +
"VelocityMagnitude|VelocityRelativeX|VelocityRelativeY|" +
"VelocityRelativeZ|VelocityX|VelocityY|VelocityZ|Vertical|" +
"VerticalRatio|Volume|VolumeOfLiquid|WattsReachingContact|Weight" +
"|WorkingGasEfficiency"
);
var logicslottypes = (
"Charge|ChargeRatio|Class|Damage|Efficiency|FilterType|Growth|" +
"Health|LineNumber|Lock|Mature|MaxQuantity|None|OccupantHash|" +
"Occupied|On|Open|PrefabHash|Pressure|PressureAir|PressureWaste|" +
"Quantity|ReferenceId|Seeding|SortingClass|Temperature|Volume"
);
var batchmodes = ("Average|Maximum|Minimum|Sum");
var reagentmodes = ("Contents|Recipe|Required|TotalContents");
var constants = ("nan|pinf|ninf|pi|deg2rad|rad2deg|epsilon");
var deprecated = (
"ExportSlotHash|ExportSlotOccupant|ImportSlotHash|ImportSlotOccupant|" +
"LogicType.ExportSlotHash|LogicType.ExportSlotOccupant|LogicType.ImportSlotHash|" +
"LogicType.ImportSlotOccupant|LogicType.PlantEfficiency1|LogicType.PlantEfficiency2|" +
"LogicType.PlantEfficiency3|LogicType.PlantEfficiency4|LogicType.PlantGrowth1|" +
"LogicType.PlantGrowth2|LogicType.PlantGrowth3|LogicType.PlantGrowth4|" +
"LogicType.PlantHash1|LogicType.PlantHash2|LogicType.PlantHash3|LogicType.PlantHash4|" +
"LogicType.PlantHealth1|LogicType.PlantHealth2|LogicType.PlantHealth3|LogicType.PlantHealth4|" +
"PlantEfficiency1|PlantEfficiency2|PlantEfficiency3|PlantEfficiency4|" +
"PlantGrowth1|PlantGrowth2|PlantGrowth3|PlantGrowth4|PlantHash1|PlantHash2|" +
"PlantHash3|PlantHash4|PlantHealth1|PlantHealth2|PlantHealth3|PlantHealth4"
);
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
var rules = {
start: [{
token: "comment.line.number-sign",
regex: /#.*$/,
}, {
token: ["text", "keyword", "text", "entity.name.tag"],
regex: /^(\s*)(j(?:al)?)(\s+)([a-zA-Z_.][a-zA-Z0-9_.]*)/,
comment: "absolute jumps | branches with a label"
}, {
token: "keyword",
regex: "^\\s*(?:" + ops + ")\\b",
}, {
token: "entity.name.tag",
regex: /^\s*[a-zA-Z_.][a-zA-Z0-9_.]*\b:/,
comment: "Labels at line start: begin_repeat: add ..."
}, {
token: "variable.parameter",
regex: /\b(?:sp|r(?:a|r*)(?:[0-9]|1[0-7]))\b/,
}, {
token: "variable.language",
regex: /\b(?:d(?:b|[0-5]|r*(?:[0-9]|1[0-7]))(?::[0-9]+)?)\b/,
}, {
token: "support.type",
regex: "\\b(?:" + logictypes + "|" + logicslottypes + "|" + batchmodes + "|" + reagentmodes + ")\\b",
}, {
token: "invalid.deprecated",
regex: "\\b(?:" + deprecated + ")\\b",
},
{
token: "constant.language",
regex: "\\b(?:" + constants + ")\\b",
}, {
token: "variable.language",
regex: "\\b(?:" + enums + ")\\b",
}, {
token: "constant.numeric.ic10",
regex: /\-?[0-9]+(?:\.[0-9]+)?|\$[a-fA-F0-9_]+|%[01_]+/,
comment: "Numbers like 12, -3.0, 55, $3F, %1000"
}, {
token: ["support.function", "paren.lparen", "string.quoted", "paren.rparen"],
regex: /\b(HASH)(\()(\".*\")(\))/,
}, {
token: "entity.name",
regex: /\b[a-zA-Z_.][a-zA-Z0-9_.]*\b/,
}]
};
IC10HighlightRules.metaData = {
fileTypes: ["ic10"],
name: "ic10",
scopeName: "source.ic10"
};
oop.inherits(IC10HighlightRules, TextHighlightRules);
exports.IC10HighlightRules = IC10HighlightRules;
export { rules };

View File

@@ -1,22 +1,51 @@
"use strict";
import ace from 'ace-builds';
import { rules as highlightRules } from "./ic10_highlight_rules";
var oop = require("ace-code/src/lib/oop");
var TextMode = require("ace-code/src/mode/text").Mode;
var FoldMode = require("ace-code/src/mode/folding/cstyle").FoldMode;
var IC10HighlightRules = require("./ic10_highlight_rules.js").IC10HighlightRules;
//Support function to create Ace mode
function createAceMode(modeName: string, highlighterObj: ace.Ace.HighlightRulesMap) {
(ace as any).define(modeName, ["require", "exports", "module"], function (require: any, exports: any, module: any) {
console.log(require);
var oop = require("ace/lib/oop");
var TextMode = require("ace/mode/text").Mode;
var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
var WorkerClient = require("ace/worker/worker_client").WorkerClient;
var Mode = function() {
this.HighlightRules = IC10HighlightRules;
this.foldingRules = new FoldMode();
var HighlightRules = function () {
this.$rules = highlighterObj;
this.normalizeRules();
};
oop.inherits(HighlightRules, TextHighlightRules);
(HighlightRules as any).metaData = {
fileTypes: [modeName],
name: modeName,
scopeName: `source.${modeName}`
};
var CustomMode = function () {
this.HighlightRules = HighlightRules;
};
oop.inherits(CustomMode, TextMode);
(function () {
//Create worker for live syntax checking
this.createWorker = function (session: ace.Ace.EditSession) {
session.on("change", function () {
session.clearAnnotations();
let annotations: ace.Ace.Annotation[] = [];
for (let row = 0; row < session.getLength(); row++) {
let tokens = session.getTokens(row);
if (!tokens || tokens.length == 0) continue;
tokens.forEach(token => {
if (token.type === "invalid") annotations.push({ row: row, column: 0, text: "This need to be fixed!", type: "error" });
});
}
session.setAnnotations(annotations);
});
}
this.lineCommentStart = ["#"];
this.$id = modeName;
}).call(CustomMode.prototype);
exports.Mode = CustomMode;
});
}
oop.inherits(Mode, TextMode);
(function() {
// configure comment start/end characters
this.lineCommentStart = ["#"];
this.$id = "ace/mode/ic10";
}).call(Mode.prototype);
exports.Mode = Mode;
createAceMode("ace/mode/ic10", highlightRules);

View File

@@ -1,18 +1,35 @@
import { ace } from "./ace.js"
import { Mode as IC10Mode } from "./ic10_mode.js";
import * as one_dark from "ace-code/src/theme/one_dark";
// import { ace } from "./ace.js"
import ace from "ace-builds";
import "ace-builds/esm-resolver";
// patch prompt ext
ace.config.setModuleLoader('ace/ext/prompt', () => import('./prompt_patch'));
ace.config.setDefaultValue("session", "theme", "ace/theme/one_dark");
import "ace-builds/src-noconflict/ext-language_tools";
ace.require("ace/ext/language_tools");
import "./ic10_mode";
import { AceLanguageClient } from "ace-linters/build/ace-language-client";
import { IC10EditorUI } from './ui.js';
import { Range } from 'ace-code/src/range.js';
import { IC10EditorUI } from './ui';
import { Range } from 'ace-builds';
import { App } from "../index";
import { Session } from "../session";
// import { Mode as TextMode } from 'ace-code/src/mode/text';
// to make sure language tools are loaded
import _ace_ext_langue_tools from "ace-code/src/ext/language_tools";
ace.config.loadModule("ace/ext/language_tools");
import { Mode as TextMode } from "ace-builds/src-noconflict/mode-text";
async function setupLspWorker() {
// Create a web worker
let worker = new Worker(new URL('./lspWorker.js', import.meta.url));
let worker = new Worker(new URL('./lspWorker.ts', import.meta.url));
const loaded = w =>
const loaded = (w: Worker) =>
new Promise(r => w.addEventListener("message", r, { once: true }));
await Promise.all([loaded(worker)]);
@@ -20,11 +37,22 @@ async function setupLspWorker() {
return worker;
}
declare global {
interface Window { Editor: IC10Editor }
}
class IC10Editor {
constructor(session_id) {
mode: string;
settings: { keyboard: string; cursor: string; fontSize: number; relativeLineNumbers: boolean; };
aceEditor: ace.Ace.Editor;
sessions: Map<number, ace.Ace.EditSession>;
active_session: number;
active_line_markers: Map<number, number | null>;
languageProvider: null | AceLanguageClient;
ui: IC10EditorUI;
constructor(session_id: number) {
window.Editor = this;
this.mode = new IC10Mode();
this.mode = "ace/mode/ic10";
this.settings = {
keyboard: "ace",
@@ -39,19 +67,19 @@ class IC10Editor {
enableLiveAutocompletion: true,
enableSnippets: true,
theme: "ace/theme/one_dark",
fontSize: "16px",
fontSize: 16,
customScrollbar: false,
firstLineNumber: 0,
printMarginColumn: 52,
placeholder: "Your code goes here ...",
});
this.sessions = {};
this.sessions[session_id] = this.aceEditor.getSession();
this.sessions = new Map();
this.sessions.set(session_id, this.aceEditor.getSession());
this.active_session = session_id;
this.bindSession(session_id, this.sessions[session_id]);
this.active_line_markers = {};
this.active_line_markers[session_id] = null;
this.bindSession(session_id, this.sessions.get(session_id));
this.active_line_markers = new Map();
this.active_line_markers.set(session_id, null);
this.languageProvider = null;
@@ -59,35 +87,37 @@ class IC10Editor {
const that = this;
App.session.onLoad((session) => {
App.session.onLoad((session: Session ) => {
const updated_ids = [];
for (const id in session.programs) {
for (const [id, _] of session.programs) {
updated_ids.push(id);
that.createOrSetSession(id, session.programs[id]);
that.createOrSetSession(id, session.programs.get(id));
}
for (const id in that.sessions) {
that.activateSession(that.active_session);
for (const [id, _] of that.sessions) {
if (!updated_ids.includes(id)) {
that.destroySession(id);
}
}
});
App.session.loadFromFragment();
App.session.onActiveLine(session => {
for (const id in Object.keys(session.programs)) {
App.session.onActiveLine((session: Session) => {
for (const id of session.programs.keys()) {
const active_line = session.getActiveLine(id);
if (typeof active_line !== "undefined") {
const marker = that.active_line_markers[id];
const marker = that.active_line_markers.get(id);
if (marker) {
that.sessions[id].removeMarker(marker);
that.active_line_markers[id] = null;
that.sessions.get(id).removeMarker(marker);
that.active_line_markers.set(id, null);
}
const session = that.sessions[id];
const session = that.sessions.get(id);
if (session) {
that.active_line_markers[id] = session.addMarker(new Range(active_line, 0, active_line, 1), "vm_ic_active_line", "fullLine", true);
that.active_line_markers.set(id, session.addMarker(new Range(active_line, 0, active_line, 1), "vm_ic_active_line", "fullLine", true));
if (that.active_session == id) {
// editor.resize(true);
that.aceEditor.scrollToLine(active_line, true, true)
that.aceEditor.scrollToLine(active_line, true, true, ()=>{})
}
}
}
@@ -96,34 +126,26 @@ class IC10Editor {
}
createOrSetSession(session_id, content) {
createOrSetSession(session_id: number, content: any) {
if (!this.sessions.hasOwnProperty(session_id)) {
this.newSession(session_id);
}
this.sessions[session_id].setValue(content);
this.sessions.get(session_id).setValue(content);
}
newSession(session_id) {
newSession(session_id: number) {
if (this.sessions.hasOwnProperty(session_id)) {
return false;
}
const session = ace.createEditSession("", this.mode);
const session = ace.createEditSession("", this.mode as any);
session.setOptions({
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
theme: "ace/theme/one_dark",
fontSize: "16px",
customScrollbar: false,
firstLineNumber: 0,
printMarginColumn: 52,
placeholder: "Your code goes here ...",
})
this.sessions[session_id] = session;
this.sessions.set(session_id, session);
this.bindSession(session_id, session);
}
setupLsp(lsp_worker) {
setupLsp(lsp_worker: Worker) {
const serverData = {
module: () => import("ace-linters/build/language-client"),
modes: "ic10",
@@ -131,26 +153,22 @@ class IC10Editor {
worker: lsp_worker,
};
// Create a language provider for web worker
this.languageProvider = AceLanguageClient.for(serverData);
this.languageProvider.registerEditor(this.aceEditor);
this.languageProvider = AceLanguageClient.for(serverData as any);
(this.languageProvider as any).registerEditor(this.aceEditor);
for (const session_id in this.sessions) {
let options = this.mode.options ?? {};
this.languageProvider.setSessionOptions(this.sessions[session_id], options);
}
// for (const session_id of this.sessions.keys()) {
// let options = {};
// (this.languageProvider as any).setSessionOptions(this.sessions.get(session_id), options);
// }
}
activateSession(session_id) {
if (!this.sessions.hasOwnProperty(session_id)) {
activateSession(session_id: number) {
if (!this.sessions.get(session_id)) {
return false;
}
this.aceEditor.setSession(this.sessions[session_id]);
this.aceEditor.setSession(this.sessions.get(session_id));
this.active_session = session_id;
let options = this.mode.options ?? {};
if (this.languageProvider !== null) {
this.languageProvider.setSessionOptions(this.sessions[session_id], options);
}
return true;
}
@@ -172,23 +190,23 @@ class IC10Editor {
window.localStorage.setItem("editorSettings", toSave);
}
destroySession(session_id) {
destroySession(session_id: number) {
if (!this.sessions.hasOwnProperty(session_id)) {
return false;
}
if (!(Object.keys(this.sessions).length > 1)) {
return false;
}
const session = this.sessions[session_id];
delete this.sessions[session_id];
const session = this.sessions.get(session_id);
this.sessions.delete(session_id);
if (this.active_session = session_id) {
this.activateSession(Object.keys(this.sessions)[0]);
this.activateSession(this.sessions.entries().next().value);
}
session.destroy();
return true;
}
bindSession(session_id, session) {
bindSession(session_id: number, session: ace.Ace.EditSession) {
session.on('change', () => {
var val = session.getValue();
window.App.session.setProgramCode(session_id, val);

View File

@@ -1,21 +1,20 @@
import { ServerConfig, serve } from "ic10lsp_wasm";
import { v4 as uuidv4 } from 'uuid';
export const encoder = new TextEncoder();
export const decoder = new TextDecoder();
export default class Bytes {
static encode(input) {
static encode(input: string) {
return encoder.encode(input);
}
static decode(input) {
static decode(input: Uint8Array) {
return decoder.decode(input);
}
static append(
constructor,
...arrays
constructor: Uint8ArrayConstructor,
...arrays: Uint8Array[]
) {
let totalLength = 0;
for (const arr of arrays) {
@@ -31,23 +30,23 @@ export default class Bytes {
}
}
export class AsyncStreamQueue {
export class AsyncStreamQueue implements AsyncIterator<Uint8Array, undefined, Uint8Array> {
promises = [];
resolvers = [];
observers = [];
promises: Promise<Uint8Array>[] = [];
resolvers: Promise<Uint8Array>[] = [];
observers: any = [];
closed = false;
locked = false;
tag = "";
stream: WritableStream<Uint8Array>;
static __add(promises, resolvers) {
static __add(promises: any[], resolvers: any[]) {
promises.push(new Promise((resolve) => {
resolvers.push(resolve);
}))
}
static __enqueue(closed, promises, resolvers, item) {
static __enqueue(closed: boolean, promises: any[], resolvers: any[], item: any) {
if (!closed) {
if (!resolvers.length) AsyncStreamQueue.__add(promises, resolvers);
const resolve = resolvers.shift();
@@ -55,7 +54,7 @@ export class AsyncStreamQueue {
}
}
constructor(tag) {
constructor(tag: string) {
this.tag = tag;
const closed = this.closed;
// invariant: at least one of the arrays is empty
@@ -72,7 +71,7 @@ export class AsyncStreamQueue {
return AsyncStreamQueue.__add(this.promises, this.resolvers);
}
enqueue(item) {
enqueue(item: Uint8Array) {
return AsyncStreamQueue.__enqueue(this.closed, this.promises, this.resolvers, item);
}
@@ -95,17 +94,17 @@ export class AsyncStreamQueue {
return this.promises.length - this.resolvers.length;
}
return() {
/* return() {
return new Promise(() => { })
}
throw(err) {
throw(err: any) {
return new Promise((_resolve, reject) => {
reject(err);
})
}
} */
async next() {
async next(): Promise<IteratorResult<Uint8Array>> {
const done = false;
// console.log(`AsyncStream(${this.tag}) waiting for message`)
const value = await this.dequeue();
@@ -117,11 +116,11 @@ export class AsyncStreamQueue {
return this;
}
locked() {
get locked() {
return this.stream.locked;
}
abort(reason) {
abort(reason: any) {
return this.stream.abort(reason);
}
@@ -142,8 +141,7 @@ async function start() {
await serve(config);
}
function fixup(data) {
// data.id = uuidv4();
function fixup(data: { hasOwnProperty: (arg0: string) => any; params: { hasOwnProperty: (arg0: string) => any; rootUri: string; textDocument: { hasOwnProperty: (arg0: string) => any; uri: string; }; }; }) {
if (data.hasOwnProperty("params") && data.params.hasOwnProperty("rootUri") && data.params.rootUri === "") {
data.params.rootUri = null
}
@@ -159,7 +157,7 @@ function fixup(data) {
return data
}
function sendClient(data) {
function sendClient(data: any) {
data = fixup(data);
const data_j = JSON.stringify(data);
const msg = `Content-Length: ${data_j.length}\r\n\r\n${data_j}`
@@ -212,7 +210,7 @@ listen();
postMessage("ready");
onmessage = function(e) {
onmessage = function (e) {
console.log("Client Message:", e.data);
sendClient(e.data)
}

View File

@@ -1,11 +1,12 @@
const ace_prompt = require('ace-code/src/ext/prompt.js').prompt;
import { prompt as ace_prompt } from "ace-builds/src-noconflict/ext-prompt"
console.log(ace_prompt);
function prompt(editor, message, options, callback) {
function prompt(editor: { cmdLine: { setTheme: (arg0: string) => void; }; }, message: any, options: any, callback: any) {
ace_prompt(editor, message, options, callback);
if (editor.cmdLine) {
editor.cmdLine.setTheme("ace/theme/one_dark");
}
}
exports.prompt = prompt;
export { prompt };

View File

@@ -1,9 +1,11 @@
import { ace } from "./ace";
import { IC10Editor } from ".";
import * as ace from "ace-builds";
import { Offcanvas } from 'bootstrap';
class IC10EditorUI {
ic10editor: IC10Editor;
constructor(ic10editor) {
constructor(ic10editor: IC10Editor) {
const that = this;
@@ -13,11 +15,11 @@ class IC10EditorUI {
name: "showSettingsMenu",
description: "Show settings menu",
bindKey: { win: "Ctrl-,", mac: "Command-," },
exec: (_editor) => {
exec: (_editor: ace.Ace.Editor) => {
const offCanvas = new Offcanvas(document.getElementById("editorSettings"));
offCanvas.toggle();
}
});
} as any);
ace.config.loadModule("ace/ext/keyboard_menu", function (module) {
console.log("keybinding_menu loaded");
@@ -32,7 +34,7 @@ class IC10EditorUI {
document.getElementsByName("editorKeybindRadio").forEach((el) => {
el.addEventListener('change', (e) => {
that.ic10editor.settings.keyboard = e.target.value;
that.ic10editor.settings.keyboard = (e.target as any).value;
that.ic10editor.saveEditorSettings();
that.updateEditorSettings();
});
@@ -40,18 +42,18 @@ class IC10EditorUI {
document.getElementsByName("editorCursorRadio").forEach((el) => {
el.addEventListener('change', (e) => {
that.ic10editor.settings.cursor = e.target.value;
that.ic10editor.settings.cursor = (e.target as any).value;
that.ic10editor.saveEditorSettings();
that.updateEditorSettings();
});
});
document.getElementById("editorSettingsFontSize").addEventListener('change', (e) => {
window.App.editorSettings.fontSize = e.target.value;
window.App.editorSettings.fontSize = parseInt((e.target as any).value);
that.ic10editor.saveEditorSettings();
that.updateEditorSettings();
});
document.getElementById("editorSettingsRelativeLineNumbers").addEventListener('change', (e) => {
window.App.editorSettings.relativeLineNumbers = e.target.checked;
window.App.editorSettings.relativeLineNumbers = (e.target as any).checked;
that.ic10editor.saveEditorSettings();
that.updateEditorSettings();
});
@@ -76,21 +78,21 @@ class IC10EditorUI {
} else {
editor.setOption('keyboardHandler', `ace/keyboard/${settings.keyboard}`);
}
editor.setOption('cursorStyle', settings.cursor);
editor.setOption('fontSize', `${settings.fontSize}px`);
editor.setOption('cursorStyle', settings.cursor as any);
editor.setOption('fontSize', settings.fontSize);
editor.setOption('relativeLineNumbers', settings.relativeLineNumbers);
}
displayEditorSettings() {
const settings = this.ic10editor.settings;
document.getElementsByName("editorKeybindRadio").forEach((el) => {
document.getElementsByName("editorKeybindRadio").forEach((el: any) => {
el.checked = el.value === settings.keyboard;
});
document.getElementsByName("editorCursorRadio").forEach((el) => {
document.getElementsByName("editorCursorRadio").forEach((el: any) => {
el.checked = el.value === settings.cursor;
});
document.getElementById("editorSettingsFontSize").value = settings.fontSize;
document.getElementById("editorSettingsRelativeLineNumbers").checked = settings.relativeLineNumbers;
(document.getElementById("editorSettingsFontSize") as any).value = settings.fontSize;
(document.getElementById("editorSettingsRelativeLineNumbers") as any).checked = settings.relativeLineNumbers;
}
reCalcEditorSize() {

View File

@@ -3,25 +3,35 @@ import { Session } from './session';
import { VirtualMachine } from "./virtual_machine";
import { docReady, openFile, saveFile } from "./utils";
// import { makeRequest } from "./utils";
declare global {
interface Window { App: App }
}
const App = {
type App = {
editorSettings: { fontSize: number, relativeLineNumbers: boolean }; editor: IC10Editor, vm: VirtualMachine, session: Session
}
export const App: App = {
editor: null,
vm: null,
session: new Session()
session: new Session(),
editorSettings: { fontSize: 16, relativeLineNumbers: false }
};
window.App = App;
// const dbPromise = makeRequest({ method: "GET", url: "/data/database.json"});
const dbPromise = fetch("/data/database.json").then(resp => resp.json());
// const dbPromise = fetch("/data/database.json").then(resp => resp.json());
const dbPromise = import("../../data/database.json")
docReady(() => {
docReady(() => {
App.vm = new VirtualMachine();
dbPromise.then(db => App.vm.setupDeviceDatabase(db))
const init_session_id = App.vm.devices[0];
const init_session_id = App.vm.devices.get(0).id;
App.editor = new IC10Editor(init_session_id);
@@ -32,26 +42,26 @@ docReady(() => {
// Menu
document.getElementById("mainMenuShare").addEventListener('click', (_event) => {
const link = document.getElementById("shareLinkText");
link.setAttribute('value', window.location);
const link = document.getElementById("shareLinkText") as HTMLInputElement;
link.setAttribute('value', window.location.href);
link.setSelectionRange(0, 0);
}, { capture: true });
document.getElementById("shareLinkCopyButton").addEventListener('click', (event) => {
event.preventDefault();
const link = document.getElementById("shareLinkText");
const link = document.getElementById("shareLinkText") as HTMLInputElement;
link.select();
link.setSelectionRange(0, 99999);
navigator.clipboard.writeText(link.value);
}, { capture: true });
document.getElementById("mainMenuOpenFile").addEventListener('click', (_event) => {
openFile(editor);
openFile(App.editor.aceEditor);
}, { capture: true });
document.getElementById("mainMenuSaveAs").addEventListener('click', (_event) => {
saveFile(editor.getSession().getValue())
saveFile(App.editor.aceEditor.getSession().getValue())
}, { capture: true });
document.getElementById("mainMenuKeyboardShortcuts").addEventListener('click', (_event) => {
App.editor.editor.execCommand("showKeyboardShortcuts");
App.editor.aceEditor.execCommand("showKeyboardShortcuts");
}, { capture: true });
});

View File

@@ -1,10 +1,10 @@
import '@popperjs/core';
import '../scss/styles.scss';
import { Dropdown, Model, ButtonGroup } from 'bootstrap';
import { Dropdown, Modal } from 'bootstrap';
// A dependency graph that contains any wasm must all be imported
// asynchronously. This `bootstrap.js` file does the single async import, so
// asynchronously. This `main.js` file does the single async import, so
// that no one else needs to worry about it again.
import("./index.js")
.catch(e => console.error("Error importing `index.js`:", e));
import("./index")
.catch(e => console.error("Error importing `index.ts`:", e));

View File

@@ -61,10 +61,21 @@ j ra
`
interface SessionCbFn {
(param: Session): void;
}
class Session {
_programs: Map<number, string>;
_onLoadCallbacks: SessionCbFn[];
_activeSession: number;
_activeLines: Map<number, number>;
_onActiveLineCallbacks: SessionCbFn[];
_activeLine: number;
private _save_timeout: ReturnType<typeof setTimeout>;
constructor() {
this._programs = new Map();
this._save_timeout = 0;
this._save_timeout = null;
this._onLoadCallbacks = [];
this._activeSession = 0;
this._activeLines = new Map();
@@ -89,25 +100,25 @@ class Session {
return this._activeSession;
}
getActiveLine(id) {
getActiveLine(id: number) {
return this._activeLines.get(id);
}
setActiveLine(id, line) {
setActiveLine(id: number, line: number) {
this._activeLines.set(id, line);
this._fireOnActiveLine();
}
set activeLine(line) {
set activeLine(line: number) {
this._activeLine = line;
}
setProgramCode(id, code) {
setProgramCode(id: number, code: string) {
this._programs.set(id, code);
this.save();
}
onLoad(callback) {
onLoad(callback: SessionCbFn) {
this._onLoadCallbacks.push(callback);
}
@@ -117,7 +128,7 @@ class Session {
}
}
onActiveLine(callback) {
onActiveLine(callback: SessionCbFn) {
this._onActiveLineCallbacks.push(callback);
}
@@ -134,7 +145,7 @@ class Session {
if (window.App.vm) {
window.App.vm.updateCode();
}
this._save_timeout = null;
}, 1000);
}
@@ -182,7 +193,7 @@ class Session {
}
}
async function decompressFragment(c_bytes) {
async function decompressFragment(c_bytes: ArrayBuffer) {
try {
const bytes = await decompress(c_bytes);
return bytes;
@@ -192,7 +203,7 @@ async function decompressFragment(c_bytes) {
}
}
function getJson(value) {
function getJson(value: any) {
try {
return JSON.parse(value);
} catch (_) {
@@ -200,7 +211,7 @@ function getJson(value) {
}
}
async function* streamAsyncIterator(stream) {
async function* streamAsyncIterator(stream: ReadableStream) {
// Get a lock on the stream
const reader = stream.getReader();
@@ -217,14 +228,14 @@ async function* streamAsyncIterator(stream) {
}
}
function base64url_encode(buffer) {
function base64url_encode(buffer: ArrayBuffer) {
return btoa(Array.from(new Uint8Array(buffer), b => String.fromCharCode(b)).join(''))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
function base64url_decode(value) {
function base64url_decode(value: string): ArrayBuffer {
const m = value.length % 4;
return Uint8Array.from(atob(
value.replace(/-/g, '+')
@@ -233,13 +244,13 @@ function base64url_decode(value) {
), c => c.charCodeAt(0)).buffer
}
async function concatUintArrays(arrays) {
async function concatUintArrays(arrays: Uint8Array[]) {
const blob = new Blob(arrays);
const buffer = await blob.arrayBuffer();
return new Uint8Array(buffer);
}
async function compress(bytes) {
async function compress(bytes: ArrayBuffer) {
const s = new Blob([bytes]).stream();
const cs = s.pipeThrough(
new CompressionStream('deflate-raw')
@@ -251,7 +262,7 @@ async function compress(bytes) {
return await concatUintArrays(chunks);
}
async function decompress(bytes) {
async function decompress(bytes: ArrayBuffer) {
const s = new Blob([bytes]).stream();
const ds = s.pipeThrough(
new DecompressionStream('deflate-raw')
@@ -263,4 +274,4 @@ async function decompress(bytes) {
return await concatUintArrays(chunks);
}
export { Session };
export { Session, SessionCbFn };

View File

@@ -1,6 +1,7 @@
import { Ace } from "ace-builds";
function docReady(fn) {
function docReady(fn: ()=> void) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
setTimeout(fn, 1);
@@ -10,8 +11,7 @@ function docReady(fn) {
}
// probably not needed, fetch() exists now
function makeRequest (opts) {
const req = new Request()
function makeRequest(opts: { method: string, url: string, headers: { [key: string]: string }, params: any }) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(opts.method, opts.url);
@@ -46,22 +46,21 @@ function makeRequest (opts) {
});
}
async function saveFile(content) {
async function saveFile(content: BlobPart) {
const blob = new Blob([content], { type: "text/plain" });
if (typeof window.showSaveFilePicker !== "undefined") {
console.log("Saving via FileSystem API")
const options = {
const saveHandle = await window.showSaveFilePicker({
types: [
{
suggestedName: "code.ic10",
// suggestedName: "code.ic10",
description: 'Text Files',
accept: {
'text/plain': ['.txt', '.ic10'],
},
},
],
};
const saveHandle = await window.showSaveFilePicker(options);
});
const ws = await saveHandle.createWritable();
await ws.write(blob);
await ws.close();
@@ -74,7 +73,7 @@ async function saveFile(content) {
}
}
async function openFile(editor) {
async function openFile(editor: Ace.Editor) {
if (typeof window.showOpenFilePicker !== "undefined") {
console.log("opening file via FileSystem Api");
const [fileHandle] = await window.showOpenFilePicker();
@@ -93,7 +92,7 @@ async function openFile(editor) {
const file = files[0];
var reader = new FileReader();
reader.onload = (e) => {
const contents = e.target.result;
const contents = e.target.result as string;
const session = editor.getSession();
// session.id = file.name;
session.setValue(contents);

View File

@@ -1,9 +1,16 @@
import { Offcanvas } from 'bootstrap';
import { VirtualMachine, VirtualMachineUI } from '.';
import { DeviceRef } from 'ic10emu_wasm';
class VMDeviceUI {
ui: VirtualMachineUI;
root: HTMLDivElement;
canvasEl: HTMLElement;
deviceCountEl: HTMLElement;
canvas: Offcanvas;
constructor(ui) {
constructor(ui: VirtualMachineUI) {
const that = this;
that.ui = ui;
this.root = document.createElement('div');
@@ -13,7 +20,7 @@ class VMDeviceUI {
}
update(active_ic) {
update(active_ic: DeviceRef) {
const devices = window.VM.devices;
@@ -22,7 +29,11 @@ class VMDeviceUI {
}
class VMDeviceCard {
constructor(deviceUI, device) {
root: HTMLDivElement;
viewBtn: HTMLButtonElement;
deviceUI: VMDeviceUI;
device: DeviceRef;
constructor(deviceUI: VMDeviceUI, device: DeviceRef) {
const that = this;
this.deviceUI = deviceUI;
this.device = device;

View File

@@ -1,8 +1,34 @@
import { init } from "ic10emu_wasm";
import { DeviceRef, VM, init } from "ic10emu_wasm";
import { VMDeviceUI } from "./device";
// import { Card } from 'bootstrap';
declare global {
interface Window { VM: VirtualMachine }
}
type DeviceDB = {
logic_enabled: string[];
slot_logic_enabled: string[];
devices: string[];
items: {
[key: string]: {
name: string,
hash: number,
desc: string,
logic?: { [key: string]: string },
slots?: { name: string, type: string }[],
modes?: { [key: string]: string },
conn?: { [key: string]: string[] },
}
}
}
class VirtualMachine {
ic10vm: VM;
ui: VirtualMachineUI;
_devices: Map<number, DeviceRef>;
_ics: Map<number, DeviceRef>;
db: any;
constructor() {
const vm = init();
@@ -21,27 +47,27 @@ class VirtualMachine {
}
get devices () {
get devices() {
return this._devices;
}
get ics () {
get ics() {
return this._ics;
}
get activeIC () {
get activeIC() {
return this._ics.get(window.App.session.activeSession);
}
updateDevices() {
const device_ids = this.ic10vm.devices;
for (const id of device_ids) {
if (!this._devices.has(id)){
if (!this._devices.has(id)) {
this._devices.set(id, this.ic10vm.getDevice(id));
}
}
for(const id of this._devices) {
for (const id of this._devices.keys()) {
if (!device_ids.includes(id)) {
this._devices.delete(id);
}
@@ -49,11 +75,11 @@ class VirtualMachine {
const ics = this.ic10vm.ics;
for (const id of ics) {
if (!this._ics.has(id)){
if (!this._ics.has(id)) {
this._ics.set(id, this._devices.get(id));
}
}
for(const id of this._ics) {
for (const id of this._ics.keys()) {
if (!ics.includes(id)) {
this._ics.delete(id);
}
@@ -63,17 +89,17 @@ class VirtualMachine {
updateCode() {
const progs = window.App.session.programs;
for (const id of Object.keys(progs)) {
for (const id of progs.keys()) {
const attempt = Date.now().toString(16)
const ic = this._ics.get(id);
const prog = progs[id];
const prog = progs.get(id);
if (ic && prog) {
console.time(`CompileProgram_${id}_${attempt}`);
try {
this.ics[id].setCode(progs[id]);
this.ics.get(id).setCode(progs.get(id));
} catch (e) {
console.log(e);
}
}
console.timeEnd(`CompileProgram_${id}_${attempt}`);
}
}
@@ -119,7 +145,7 @@ class VirtualMachine {
this.ui.update(ic);
}
setRegister(index, val) {
setRegister(index: number, val: number) {
const ic = this.activeIC;
try {
ic.setRegister(index, val);
@@ -128,7 +154,7 @@ class VirtualMachine {
}
}
setStack(addr, val) {
setStack(addr: number, val: number) {
const ic = this.activeIC;
try {
ic.setStack(addr, val);
@@ -137,7 +163,7 @@ class VirtualMachine {
}
}
setupDeviceDatabase(db) {
setupDeviceDatabase(db: DeviceDB) {
this.db = db;
console.log("Loaded Device Database", this.db);
}
@@ -145,7 +171,13 @@ class VirtualMachine {
class VirtualMachineUI {
constructor(vm) {
vm: VirtualMachine;
state: VMStateUI;
registers: VMRegistersUI;
stack: VMStackUI;
devices: VMDeviceUI;
constructor(vm: VirtualMachine) {
this.vm = vm
this.state = new VMStateUI(this);
this.registers = new VMRegistersUI(this);
@@ -166,7 +198,7 @@ class VirtualMachineUI {
}
update(ic) {
update(ic: DeviceRef) {
this.state.update(ic);
this.registers.update(ic);
this.stack.update(ic);
@@ -176,7 +208,11 @@ class VirtualMachineUI {
}
class VMStateUI {
constructor(ui) {
ui: VirtualMachineUI;
instructionPointer: HTMLElement;
instructionCounter: HTMLElement;
lastState: HTMLElement;
constructor(ui: VirtualMachineUI) {
this.ui = ui;
this.instructionPointer = document.getElementById("vmActiveICStateIP");
@@ -184,7 +220,7 @@ class VMStateUI {
this.lastState = document.getElementById("vmActiveICStateLastRun");
}
update(ic) {
update(ic: { ip: { toString: () => string; }; instructionCount: { toString: () => string; }; state: { toString: () => string; }; }) {
if (ic) {
this.instructionPointer.innerText = ic.ip.toString();
this.instructionCounter.innerText = ic.instructionCount.toString();
@@ -194,7 +230,18 @@ class VMStateUI {
}
class VMRegistersUI {
constructor(ui) {
ui: VirtualMachineUI;
tbl: HTMLDivElement;
regCells: {
cell: HTMLDivElement,
nameLabel: HTMLSpanElement,
aliasesLabel: HTMLSpanElement,
input: HTMLInputElement
}[];
default_aliases: Map<string, number>;
ic_aliases: Map<string, number>;
constructor(ui: VirtualMachineUI) {
const that = this;
this.ui = ui;
const regDom = document.getElementById("vmActiveRegisters");
this.tbl = document.createElement("div");
@@ -212,8 +259,8 @@ class VMRegistersUI {
cell.appendChild(nameLabel);
const input = document.createElement("input");
input.type = "text"
input.value = 0;
input.dataset.index = i;
input.value = (0).toString();
input.dataset.index = i.toString();
cell.appendChild(input);
const aliasesLabel = document.createElement("span");
aliasesLabel.classList.add("input-group-text", "reg_label")
@@ -228,72 +275,74 @@ class VMRegistersUI {
this.tbl.appendChild(container);
}
this.regCells.forEach(cell => {
cell.input.addEventListener('change', this.onCellUpdate);
cell.input.addEventListener('change', that.onCellUpdate);
});
this.default_aliases = { "sp": 16, "ra": 17 }
this.ic_aliases = {}
this.default_aliases = new Map([["sp", 16], ["ra", 17]]);
this.ic_aliases = new Map();
regDom.appendChild(this.tbl);
}
onCellUpdate(e) {
onCellUpdate(e: Event) {
let index;
let val;
let target = (e.target as HTMLInputElement);
try {
index = parseInt(e.target.dataset.index);
val = parseFloat(e.target.value);
index = parseInt(target.dataset.index);
val = parseFloat(target.value);
} catch (e) {
// reset the edit
console.log(e);
VM.update();
window.VM.update();
return;
}
VM.setRegister(index, val);
window.VM.setRegister(index, val);
}
update(ic) {
update(ic: DeviceRef) {
const that = this;
if (ic) {
const registers = ic.registers;
if (registers) {
for (var i = 0; i < registers.length; i++) {
this.regCells[i].input.value = registers[i];
this.regCells[i].input.value = registers[i].toString();
}
}
const aliases = ic.aliases;
if (aliases) {
this.ic_aliases = {};
aliases.forEach( (target, alias, _map) => {
// const target = aliases.get(alias);
if (target.RegisterSpec && target.RegisterSpec.indirection == 0) {
this.ic_aliases = new Map();
aliases.forEach((target, alias, _map) => {
if (("RegisterSpec" in target) && target.RegisterSpec.indirection == 0) {
const index = target.RegisterSpec.target;
this.ic_aliases[alias] = index;
this.ic_aliases.set(alias, index);
}
})
}
console.log(aliases);
}
this.updateAliases();
}
updateAliases () {
const aliases = Object.assign({}, this.default_aliases, this.ic_aliases);
const labels = {}
for (const [alias, target] of Object.entries(aliases)) {
updateAliases() {
const aliases = new Map([...Array.from(this.default_aliases), ...Array.from(this.ic_aliases)]);
const labels = new Map<number, string[]>();
for (const [alias, target] of aliases) {
if (labels.hasOwnProperty(target)) {
labels[target].push(alias)
labels.get(target).push(alias)
} else {
labels[target] = [alias]
labels.set(target, [alias]);
}
}
for(const [index, label] of Object.entries(labels)) {
this.regCells[index].aliasesLabel.innerText = label.join(", ")
for (const [index, label_list] of labels) {
this.regCells[index].aliasesLabel.innerText = label_list.join(", ")
}
}
}
class VMStackUI {
constructor(ui) {
ui: VirtualMachineUI;
tbl: HTMLDivElement;
stackCells: { cell: HTMLDivElement, nameLabel: HTMLSpanElement, input: HTMLInputElement }[];
constructor(ui: VirtualMachineUI) {
this.ui = ui;
const stackDom = document.getElementById("vmActiveStack");
this.tbl = document.createElement("div");
@@ -310,10 +359,10 @@ class VMStackUI {
cell.appendChild(nameLabel);
const input = document.createElement("input");
input.type = "text"
input.value = 0;
input.dataset.index = i;
input.value = (0).toString();
input.dataset.index = i.toString();
cell.appendChild(input);
this.stackCells.push({
cell,
nameLabel,
@@ -328,22 +377,22 @@ class VMStackUI {
stackDom.appendChild(this.tbl);
}
onCellUpdate(e) {
onCellUpdate(e: Event) {
let index;
let val;
let target = e.target as HTMLInputElement;
try {
index = parseInt(e.target.dataset.index);
val = parseFloat(e.target.value);
index = parseInt(target.dataset.index);
val = parseFloat(target.value);
} catch (e) {
// reset the edit
console.log(e);
VM.update();
window.VM.update();
return;
}
VM.setStack(index, val);
window.VM.setStack(index, val);
}
update(ic) {
update(ic: { stack: any; registers: any[]; }) {
const that = this;
if (ic) {
const stack = ic.stack;
@@ -363,4 +412,4 @@ class VMStackUI {
}
export { VirtualMachine }
export { VirtualMachine, VirtualMachineUI , DeviceDB };

View File

@@ -3,10 +3,11 @@
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "es6",
"target": "es6",
"jsx": "react",
"module": "es2022",
"target": "es2020",
"allowJs": true,
"moduleResolution": "node"
"moduleResolution": "bundler",
"resolveJsonModule": true,
"types": ["@types/wicg-file-system-access", "@types/ace"]
}
}

View File

@@ -6,10 +6,11 @@ const miniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
module.exports = {
entry: "./src/js/main.js",
entry: "./src/js/main.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
clean: true,
},
devServer: {
static: path.resolve(__dirname, 'dist'),
@@ -79,9 +80,4 @@ module.exports = {
asyncWebAssembly: true,
syncWebAssembly: true,
},
output: {
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};

View File

@@ -6,10 +6,11 @@ const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const path = require('path');
module.exports = {
entry: "./src/js/main.js",
entry: "./src/js/main.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
clean: true
},
devServer: {
static: path.resolve(__dirname, 'dist'),
@@ -120,9 +121,4 @@ module.exports = {
})
]
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
};