Fixed bug where negative consts were not valid slang, revised build script to build the workshop folder to the release folder.
This commit is contained in:
70
ModData/About/About.xml
Normal file
70
ModData/About/About.xml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ModMetadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<Name>StationeersSlang</Name>
|
||||||
|
<Author>JoeDiertay</Author>
|
||||||
|
<Version>0.1.0</Version>
|
||||||
|
<Description>
|
||||||
|
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.
|
||||||
|
</Description>
|
||||||
|
<Tags>
|
||||||
|
<Tag>Logic</Tag>
|
||||||
|
<Tag>Scripting</Tag>
|
||||||
|
<Tag>Code</Tag>
|
||||||
|
<Tag>BepInEx</Tag>
|
||||||
|
<Tag>StationeersLaunchPad</Tag>
|
||||||
|
<Tag>Quality of Life</Tag>
|
||||||
|
</Tags>
|
||||||
|
<InGameDescription><![CDATA[
|
||||||
|
<size=30><color=#ffff00>Slang - High Level Language Compiler</color></size>
|
||||||
|
A modern programming experience for Stationeers. Write C-style code that compiles to MIPS assembly instantly.
|
||||||
|
|
||||||
|
<color=#ffa500><b>Features</b></color>
|
||||||
|
- <b>In-Game Compilation:</b> Write high-level logic directly in the chip editor.
|
||||||
|
- <b>Automatic Registers:</b> Stop juggling <color=#add8e6>r0-r15</color>. Just use <color=#569cd6>let</color> variables.
|
||||||
|
- <b>Control Flow:</b> Full support for <color=#c586c0>if</color>, <color=#c586c0>else</color>, <color=#c586c0>while</color>, and <color=#c586c0>loop</color>.
|
||||||
|
- <b>Smart Editor:</b> Integrated syntax highlighting and real-time error checking.
|
||||||
|
- <b>Persistent Code:</b> Your Slang source code is saved with the chip, so you never lose your work.
|
||||||
|
- <b>Optimization:</b> The compiler automatically optimizes constant math (e.g., <color=#b5cea8>1 + 2</color> becomes <color=#b5cea8>3</color>).
|
||||||
|
|
||||||
|
<color=#ffa500><b>Example Code</b></color>
|
||||||
|
<color=#569cd6>device</color> sensor = <color=#ce9178>"d0"</color>;
|
||||||
|
<color=#569cd6>const</color> MAX_TEMP = <color=#b5cea8>300k</color>;
|
||||||
|
|
||||||
|
<color=#c586c0>loop</color> {
|
||||||
|
<color=#569cd6>let</color> temp = sensor.Temperature;
|
||||||
|
<color=#c586c0>if</color> (temp > MAX_TEMP) {
|
||||||
|
<color=#6a9955>// Do logic here</color>
|
||||||
|
}
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
<b><color=#ffff00>Installation</color></b>
|
||||||
|
This is a <color=#ffa500>StationeersLaunchPad</color> Plugin Mod. It requires BepInEx to be installed.
|
||||||
|
See: https://github.com/StationeersLaunchPad/StationeersLaunchPad
|
||||||
|
|
||||||
|
Source Code: https://github.com/dbidwell94/stationeers_lang
|
||||||
|
]]>
|
||||||
|
</InGameDescription>
|
||||||
|
<Dependencies>
|
||||||
|
<Dependency>IC10Editor</Dependency>
|
||||||
|
</Dependencies>
|
||||||
|
<LoadAfter>IC10Editor</LoadAfter>
|
||||||
|
</ModMetadata>
|
||||||
BIN
ModData/About/Preview.png
Normal file
BIN
ModData/About/Preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 481 KiB |
BIN
ModData/About/thumb.png
Normal file
BIN
ModData/About/thumb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 481 KiB |
0
ModData/Bepinex
Normal file
0
ModData/Bepinex
Normal file
14
build.sh
14
build.sh
@@ -5,6 +5,7 @@ set -e
|
|||||||
RUST_DIR="rust_compiler"
|
RUST_DIR="rust_compiler"
|
||||||
CSHARP_DIR="csharp_mod"
|
CSHARP_DIR="csharp_mod"
|
||||||
RELEASE_DIR="release"
|
RELEASE_DIR="release"
|
||||||
|
METADATA_DIR="ModData"
|
||||||
|
|
||||||
export RUSTFLAGS="--remap-path-prefix=${PWD}=. --remap-path-prefix=${HOME}/.cargo=~/.cargo"
|
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_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_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"
|
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
|
if [[ ! -d "$RELEASE_DIR" ]]; then
|
||||||
mkdir "$RELEASE_DIR"
|
mkdir "$RELEASE_DIR"
|
||||||
fi
|
fi
|
||||||
@@ -51,6 +56,9 @@ cp "$RUST_WIN_EXE" "$RELEASE_DIR/slang.exe"
|
|||||||
# This is the linux executable
|
# This is the linux executable
|
||||||
cp "$RUST_LINUX_BIN" "$RELEASE_DIR/slang"
|
cp "$RUST_LINUX_BIN" "$RELEASE_DIR/slang"
|
||||||
# This is the DLL mod itself
|
# 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
|
# This is the rust-only compiler for use in injecting into the mod
|
||||||
cp "$RUST_WIN_DLL" "$RELEASE_DIR/rust_slang.dll"
|
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"
|
||||||
|
|||||||
@@ -1349,11 +1349,24 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn literal(&mut self) -> Result<Literal, Error> {
|
fn literal(&mut self) -> Result<Literal, Error> {
|
||||||
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 {
|
let literal = match current_token.token_type {
|
||||||
TokenType::Number(num) => Literal::Number(num),
|
TokenType::Number(num) => Literal::Number(num),
|
||||||
TokenType::String(ref string) => Literal::String(string.clone()),
|
TokenType::String(ref string) => Literal::String(string.clone()),
|
||||||
TokenType::Boolean(boolean) => Literal::Boolean(boolean),
|
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(
|
return Err(Error::UnexpectedToken(
|
||||||
self.current_span(),
|
self.current_span(),
|
||||||
|
|||||||
@@ -151,3 +151,12 @@ fn test_const_hash_expression() -> Result<()> {
|
|||||||
assert_eq!("(const i = hash(\"item\"))", expr.to_string());
|
assert_eq!("(const i = hash(\"item\"))", expr.to_string());
|
||||||
Ok(())
|
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(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user