diff --git a/ModData/About/About.xml b/ModData/About/About.xml
new file mode 100644
index 0000000..464e823
--- /dev/null
+++ b/ModData/About/About.xml
@@ -0,0 +1,70 @@
+
+
+ StationeersSlang
+ JoeDiertay
+ 0.1.0
+
+ Slang (Stationeers Language) is a high-level programming language that compiles directly into IC10 within the game.
+
+ Features:
+ - In-Game Compilation: Write C-style code directly in the IC editor.
+ - Automatic Register Management: Define variables with 'let' (e.g., let x = 10) without managing r0-r15.
+ - Standard Control Flow: Use if/else, while, loop, break, and continue.
+ - Functions: Define and call functions with arguments.
+ - Smart Editor: Real-time syntax highlighting and error checking (red text for errors).
+ - Persistent Source: Your high-level source code is saved inside the chip data, so you can edit it later.
+ - Constant Folding: Mathematical operations on constants are calculated at compile time to save instructions.
+ - Device Aliasing: Easy device mapping (e.g., device sensor = "d0").
+
+ Installation:
+ This is a StationeersLaunchPad Plugin Mod. It requires BepInEx to be installed.
+
+ Usage:
+ 1. Open any IC10 housing or editor.
+ 2. Write Slang code.
+ 3. Press Confirm to compile and run.
+
+
+ Logic
+ Scripting
+ Code
+ BepInEx
+ StationeersLaunchPad
+ Quality of Life
+
+ Slang - High Level Language Compiler
+ A modern programming experience for Stationeers. Write C-style code that compiles to MIPS assembly instantly.
+
+ Features
+ - In-Game Compilation: Write high-level logic directly in the chip editor.
+ - Automatic Registers: Stop juggling r0-r15. Just use let variables.
+ - Control Flow: Full support for if, else, while, and loop.
+ - Smart Editor: Integrated syntax highlighting and real-time error checking.
+ - Persistent Code: Your Slang source code is saved with the chip, so you never lose your work.
+ - Optimization: The compiler automatically optimizes constant math (e.g., 1 + 2 becomes 3).
+
+ Example Code
+ device sensor = "d0";
+ const MAX_TEMP = 300k;
+
+ loop {
+ let temp = sensor.Temperature;
+ if (temp > MAX_TEMP) {
+ // Do logic here
+ }
+ yield();
+ }
+
+ Installation
+ This is a StationeersLaunchPad Plugin Mod. It requires BepInEx to be installed.
+ See: https://github.com/StationeersLaunchPad/StationeersLaunchPad
+
+ Source Code: https://github.com/dbidwell94/stationeers_lang
+ ]]>
+
+
+ IC10Editor
+
+ IC10Editor
+
diff --git a/ModData/About/Preview.png b/ModData/About/Preview.png
new file mode 100644
index 0000000..252edb7
Binary files /dev/null and b/ModData/About/Preview.png differ
diff --git a/ModData/About/thumb.png b/ModData/About/thumb.png
new file mode 100644
index 0000000..252edb7
Binary files /dev/null and b/ModData/About/thumb.png differ
diff --git a/ModData/Bepinex b/ModData/Bepinex
new file mode 100644
index 0000000..e69de29
diff --git a/build.sh b/build.sh
index f0e2866..3f0e9a7 100755
--- a/build.sh
+++ b/build.sh
@@ -5,6 +5,7 @@ set -e
RUST_DIR="rust_compiler"
CSHARP_DIR="csharp_mod"
RELEASE_DIR="release"
+METADATA_DIR="ModData"
export RUSTFLAGS="--remap-path-prefix=${PWD}=. --remap-path-prefix=${HOME}/.cargo=~/.cargo"
@@ -39,9 +40,13 @@ echo "--------------------"
RUST_WIN_EXE="$RUST_DIR/target/x86_64-pc-windows-gnu/release/slang.exe"
RUST_WIN_DLL="$RUST_DIR/target/x86_64-pc-windows-gnu/release/slang.dll"
RUST_LINUX_BIN="$RUST_DIR/target/x86_64-unknown-linux-gnu/release/slang"
-CHARP_DLL="$CSHARP_DIR/bin/Release/net48/StationeersSlang.dll"
+CSHARP_DLL="$CSHARP_DIR/bin/Release/net48/StationeersSlang.dll"
+
+# Remove the release directory if it exists so we have a fresh build dir
+if [[ -d "$RELEASE_DIR" ]]; then
+ rm -rd "$RELEASE_DIR"
+fi
-# Check if the release dir exists, if not: create it.
if [[ ! -d "$RELEASE_DIR" ]]; then
mkdir "$RELEASE_DIR"
fi
@@ -51,6 +56,9 @@ cp "$RUST_WIN_EXE" "$RELEASE_DIR/slang.exe"
# This is the linux executable
cp "$RUST_LINUX_BIN" "$RELEASE_DIR/slang"
# This is the DLL mod itself
-cp "$CHARP_DLL" "$RELEASE_DIR/StationeersSlang.dll"
+cp "$CSHARP_DLL" "$RELEASE_DIR/StationeersSlang.dll"
# This is the rust-only compiler for use in injecting into the mod
cp "$RUST_WIN_DLL" "$RELEASE_DIR/rust_slang.dll"
+# This is the whole bundled workshop release version of the mod
+cp -r "$METADATA_DIR" "$RELEASE_DIR/workshop"
+cp "$CSHARP_DLL" "$RELEASE_DIR/workshop/StationeersSlang.dll"
diff --git a/rust_compiler/libs/parser/src/lib.rs b/rust_compiler/libs/parser/src/lib.rs
index a973494..1f26db9 100644
--- a/rust_compiler/libs/parser/src/lib.rs
+++ b/rust_compiler/libs/parser/src/lib.rs
@@ -1349,11 +1349,24 @@ impl<'a> Parser<'a> {
}
fn literal(&mut self) -> Result {
- let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?;
+ let current_token = self.current_token.clone().ok_or(Error::UnexpectedEOF)?;
let literal = match current_token.token_type {
TokenType::Number(num) => Literal::Number(num),
TokenType::String(ref string) => Literal::String(string.clone()),
TokenType::Boolean(boolean) => Literal::Boolean(boolean),
+ TokenType::Symbol(Symbol::Minus) => match self.get_next()? {
+ Some(Token {
+ token_type: TokenType::Number(num),
+ ..
+ }) => Literal::Number(-*num),
+ Some(wrong_token) => {
+ return Err(Error::UnexpectedToken(
+ Self::token_to_span(wrong_token),
+ wrong_token.clone(),
+ ));
+ }
+ None => return Err(Error::UnexpectedEOF),
+ },
_ => {
return Err(Error::UnexpectedToken(
self.current_span(),
diff --git a/rust_compiler/libs/parser/src/test/mod.rs b/rust_compiler/libs/parser/src/test/mod.rs
index a0fd10d..c78111a 100644
--- a/rust_compiler/libs/parser/src/test/mod.rs
+++ b/rust_compiler/libs/parser/src/test/mod.rs
@@ -151,3 +151,12 @@ fn test_const_hash_expression() -> Result<()> {
assert_eq!("(const i = hash(\"item\"))", expr.to_string());
Ok(())
}
+
+#[test]
+fn test_negative_literal_const() -> Result<()> {
+ let expr = parser!(r#"const i = -123"#).parse()?.unwrap();
+
+ assert_eq!("(const i = -123)", expr.to_string());
+
+ Ok(())
+}