diff --git a/.gitignore b/.gitignore
index b7c3df2..8764920 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
-/target
-*.ic10
\ No newline at end of file
+target
+*.ic10
+release
+bin
+obj
diff --git a/build.sh b/build.sh
index 22273a4..436cfbd 100755
--- a/build.sh
+++ b/build.sh
@@ -2,21 +2,46 @@
set -e
+RUST_DIR="rust_compiler"
+CSHARP_DIR="csharp_mod"
+RELEASE_DIR="release"
+
export RUSTFLAGS="--remap-path-prefix=${PWD}=. --remap-path-prefix=${HOME}/.cargo=~/.cargo"
-# -- Build for Native (Linux x86-64) --
-echo "Building native (Linux x86-64) executable..."
-cargo build --release --target=x86_64-unknown-linux-gnu
-echo "Native build complete."
echo "--------------------"
+cd "$RUST_DIR"
+echo "Building native Rust binaries and libs"
+
+# -- Build for Native (Linux x86-64) --
+cargo build --release --target=x86_64-unknown-linux-gnu
# -- Build for Windows (x86-64) --
-echo "Building Windows (x86-64) dll and executable..."
cargo build --release --target=x86_64-pc-windows-gnu
-echo "Windows build successful."
+
+cd ..
echo "--------------------"
-echo "All builds successful"
-echo "Linux executable at target/x86_64-unknown-linux-gnu/release/slang"
-echo "Windows .exe at target/x86_64-pc-windows-gnu/release/slang.exe"
-echo "Windows .dll at target/x86_64-pc-windows-gnu/release/slang.dll"
+echo "Building C# mod"
+echo "--------------------"
+
+cd "$CSHARP_DIR"
+dotnet build -c Release
+
+cd ..
+echo "--------------------"
+
+echo "Copying Release files to output directory"
+echo "--------------------"
+
+RUST_WIN_EXE="$RUST_DIR/target/x86_64-pc-windows-gnu/release/slang.exe"
+RUST_LINUX_BIN="$RUST_DIR/target/x86_64-unknown-linux-gnu/release/slang"
+CHARP_DLL="$CSHARP_DIR/bin/Release/net46/StationeersSlang.dll"
+
+# Check if the release dir exists, if not: create it.
+if [[ ! -d "$RELEASE_DIR" ]]; then
+ mkdir "$RELEASE_DIR"
+fi
+
+cp "$RUST_WIN_EXE" "$RELEASE_DIR/slang.exe"
+cp "$RUST_LINUX_BIN" "$RELEASE_DIR/slang"
+cp "$CHARP_DLL" "$RELEASE_DIR/StationeersSlang.dll"
diff --git a/csharp_mod/Patches.cs b/csharp_mod/Patches.cs
new file mode 100644
index 0000000..3ea5f7f
--- /dev/null
+++ b/csharp_mod/Patches.cs
@@ -0,0 +1,36 @@
+using Assets.Scripts.Objects.Motherboards;
+using HarmonyLib;
+
+namespace Slang
+{
+ [HarmonyPatch]
+ public static class SlangPatches
+ {
+ [HarmonyPatch(
+ typeof(ProgrammableChipMotherboard),
+ nameof(ProgrammableChipMotherboard.InputFinished)
+ )]
+ [HarmonyPrefix]
+ public static void PGM_InputFinished(ref string result)
+ {
+ if (string.IsNullOrEmpty(result) || !SlangPlugin.IsSlangSource(ref result))
+ {
+ return;
+ }
+
+ L.Info("Detected Slang source, compiling...");
+
+ // Compile the Slang source into IC10
+ string compiled = SlangPlugin.Compile(result);
+
+ // Ensure that the string is correct
+ if (string.IsNullOrEmpty(compiled))
+ {
+ return;
+ }
+
+ // Set the result to be the compiled source so the rest of the function can continue as normal
+ result = compiled;
+ }
+ }
+}
diff --git a/csharp_mod/SlangPlugin.cs b/csharp_mod/SlangPlugin.cs
new file mode 100644
index 0000000..9038960
--- /dev/null
+++ b/csharp_mod/SlangPlugin.cs
@@ -0,0 +1,119 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using BepInEx;
+using HarmonyLib;
+
+namespace Slang
+{
+ class L
+ {
+ private static BepInEx.Logging.ManualLogSource _logger;
+
+ public static void SetLogger(BepInEx.Logging.ManualLogSource logger)
+ {
+ _logger = logger;
+ }
+
+ public static void Debug(string message)
+ {
+ _logger.LogDebug(message);
+ }
+
+ public static void Info(string message)
+ {
+ _logger.LogInfo(message);
+ }
+
+ public static void Error(string message)
+ {
+ _logger.LogError(message);
+ }
+
+ public static void Warning(string message)
+ {
+ _logger.LogWarning(message);
+ }
+ }
+
+ [BepInPlugin(PluginGuid, PluginName, "0.1.0")]
+ public class SlangPlugin : BaseUnityPlugin
+ {
+ public const string PluginGuid = "com.dbidwell94.slang";
+ public const string PluginName = "Slang";
+
+ const string RUST_DLL_NAME = "slang.dll";
+
+ private readonly string[] SLANG_KEYWORDS = { "let ", "fn " };
+
+ /// Takes raw `Slang` source code and compiles it into IC10
+ [DllImport(RUST_DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
+ private static extern IntPtr compile_from_string(string input);
+
+ /// Frees memory that was allocated by the FFI call to `compile_from_string`
+ [DllImport(RUST_DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
+ private static extern void free_slang_string(IntPtr ptr);
+
+ public static string Compile(string source)
+ {
+ if (string.IsNullOrEmpty(source))
+ return "";
+
+ IntPtr ptr = compile_from_string(source);
+ try
+ {
+ return Marshal.PtrToStringAnsi(ptr);
+ }
+ finally
+ {
+ free_slang_string(ptr);
+ }
+ }
+
+ public static bool IsSlangSource(ref string input)
+ {
+ return true;
+ }
+
+ private void Awake()
+ {
+ L.SetLogger(Logger);
+ ExtractNativeDll(RUST_DLL_NAME);
+ var harmony = new Harmony("com.dbidwell94.slang");
+ harmony.PatchAll();
+ }
+
+ private void ExtractNativeDll(string fileName)
+ {
+ string destinationPath = Path.Combine(Path.GetDirectoryName(Info.Location), fileName);
+
+ Assembly assembly = Assembly.GetExecutingAssembly();
+
+ using (Stream stream = assembly.GetManifestResourceStream(fileName))
+ {
+ if (stream == null)
+ {
+ Logger.LogError(
+ $"{RUST_DLL_NAME} compiler not found. This means it was not embedded in the mod. Please contact the mod author!"
+ );
+ return;
+ }
+
+ try
+ {
+ using (FileStream fileStream = new FileStream(destinationPath, FileMode.Create))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ catch (IOException e)
+ {
+ Logger.LogWarning(
+ $"Could not overwrite {fileName} (it might be in use): {e.Message}"
+ );
+ }
+ }
+ }
+ }
+}
diff --git a/csharp_mod/stationeersSlang.csproj b/csharp_mod/stationeersSlang.csproj
new file mode 100644
index 0000000..20ec76f
--- /dev/null
+++ b/csharp_mod/stationeersSlang.csproj
@@ -0,0 +1,57 @@
+
+
+
+ net46
+ enable
+ StationeersSlang
+ Slang Compiler Bridge
+ 0.1.0
+ true
+ latest
+
+
+
+ /home/dbidwell/.local/share/Steam/steamapps/common/Stationeers/
+ $(GameDir)/rocketstation_Data/Managed
+ $(GameDir)/BepInEx/core
+
+
+
+
+ $(ManagedDir)/netstandard.dll
+ False
+
+
+ $(BepInExDir)/BepInEx.dll
+ False
+
+
+ $(BepInExDir)/0Harmony.dll
+ False
+
+
+
+ $(ManagedDir)/UnityEngine.dll
+ False
+
+
+ $(ManagedDir)/UnityEngine.CoreModule.dll
+ False
+
+
+ $(ManagedDir)/Assembly-CSharp.dll
+ False
+
+
+ $(ManagedDir)/Assembly-CSharp-firstpass.dll
+ False
+
+
+
+
+
+ slang.dll
+
+
+
+
diff --git a/Cargo.lock b/rust_compiler/Cargo.lock
similarity index 100%
rename from Cargo.lock
rename to rust_compiler/Cargo.lock
diff --git a/Cargo.toml b/rust_compiler/Cargo.toml
similarity index 100%
rename from Cargo.toml
rename to rust_compiler/Cargo.toml
diff --git a/libs/compiler/Cargo.toml b/rust_compiler/libs/compiler/Cargo.toml
similarity index 100%
rename from libs/compiler/Cargo.toml
rename to rust_compiler/libs/compiler/Cargo.toml
diff --git a/libs/compiler/src/lib.rs b/rust_compiler/libs/compiler/src/lib.rs
similarity index 100%
rename from libs/compiler/src/lib.rs
rename to rust_compiler/libs/compiler/src/lib.rs
diff --git a/libs/compiler/src/test/binary_expression.rs b/rust_compiler/libs/compiler/src/test/binary_expression.rs
similarity index 100%
rename from libs/compiler/src/test/binary_expression.rs
rename to rust_compiler/libs/compiler/src/test/binary_expression.rs
diff --git a/libs/compiler/src/test/branching.rs b/rust_compiler/libs/compiler/src/test/branching.rs
similarity index 100%
rename from libs/compiler/src/test/branching.rs
rename to rust_compiler/libs/compiler/src/test/branching.rs
diff --git a/libs/compiler/src/test/declaration_function_invocation.rs b/rust_compiler/libs/compiler/src/test/declaration_function_invocation.rs
similarity index 100%
rename from libs/compiler/src/test/declaration_function_invocation.rs
rename to rust_compiler/libs/compiler/src/test/declaration_function_invocation.rs
diff --git a/libs/compiler/src/test/declaration_literal.rs b/rust_compiler/libs/compiler/src/test/declaration_literal.rs
similarity index 100%
rename from libs/compiler/src/test/declaration_literal.rs
rename to rust_compiler/libs/compiler/src/test/declaration_literal.rs
diff --git a/libs/compiler/src/test/function_declaration.rs b/rust_compiler/libs/compiler/src/test/function_declaration.rs
similarity index 100%
rename from libs/compiler/src/test/function_declaration.rs
rename to rust_compiler/libs/compiler/src/test/function_declaration.rs
diff --git a/libs/compiler/src/test/logic_expression.rs b/rust_compiler/libs/compiler/src/test/logic_expression.rs
similarity index 100%
rename from libs/compiler/src/test/logic_expression.rs
rename to rust_compiler/libs/compiler/src/test/logic_expression.rs
diff --git a/libs/compiler/src/test/loops.rs b/rust_compiler/libs/compiler/src/test/loops.rs
similarity index 100%
rename from libs/compiler/src/test/loops.rs
rename to rust_compiler/libs/compiler/src/test/loops.rs
diff --git a/libs/compiler/src/test/mod.rs b/rust_compiler/libs/compiler/src/test/mod.rs
similarity index 100%
rename from libs/compiler/src/test/mod.rs
rename to rust_compiler/libs/compiler/src/test/mod.rs
diff --git a/libs/compiler/src/test/syscall.rs b/rust_compiler/libs/compiler/src/test/syscall.rs
similarity index 100%
rename from libs/compiler/src/test/syscall.rs
rename to rust_compiler/libs/compiler/src/test/syscall.rs
diff --git a/libs/compiler/src/v1.rs b/rust_compiler/libs/compiler/src/v1.rs
similarity index 100%
rename from libs/compiler/src/v1.rs
rename to rust_compiler/libs/compiler/src/v1.rs
diff --git a/libs/compiler/src/variable_manager.rs b/rust_compiler/libs/compiler/src/variable_manager.rs
similarity index 100%
rename from libs/compiler/src/variable_manager.rs
rename to rust_compiler/libs/compiler/src/variable_manager.rs
diff --git a/libs/compiler/test_files/deviceIo.slang b/rust_compiler/libs/compiler/test_files/deviceIo.slang
similarity index 100%
rename from libs/compiler/test_files/deviceIo.slang
rename to rust_compiler/libs/compiler/test_files/deviceIo.slang
diff --git a/libs/parser/Cargo.toml b/rust_compiler/libs/parser/Cargo.toml
similarity index 100%
rename from libs/parser/Cargo.toml
rename to rust_compiler/libs/parser/Cargo.toml
diff --git a/libs/parser/src/lib.rs b/rust_compiler/libs/parser/src/lib.rs
similarity index 99%
rename from libs/parser/src/lib.rs
rename to rust_compiler/libs/parser/src/lib.rs
index 8eca23a..481524b 100644
--- a/libs/parser/src/lib.rs
+++ b/rust_compiler/libs/parser/src/lib.rs
@@ -4,6 +4,7 @@ mod test;
pub mod sys_call;
pub mod tree_node;
+use crate::sys_call::System;
use quick_error::quick_error;
use std::io::SeekFrom;
use sys_call::SysCall;
@@ -13,8 +14,6 @@ use tokenizer::{
};
use tree_node::*;
-use crate::sys_call::System;
-
#[macro_export]
/// A macro to create a boxed value.
macro_rules! boxed {
diff --git a/libs/parser/src/sys_call.rs b/rust_compiler/libs/parser/src/sys_call.rs
similarity index 100%
rename from libs/parser/src/sys_call.rs
rename to rust_compiler/libs/parser/src/sys_call.rs
diff --git a/libs/parser/src/test/blocks.rs b/rust_compiler/libs/parser/src/test/blocks.rs
similarity index 100%
rename from libs/parser/src/test/blocks.rs
rename to rust_compiler/libs/parser/src/test/blocks.rs
diff --git a/libs/parser/src/test/mod.rs b/rust_compiler/libs/parser/src/test/mod.rs
similarity index 100%
rename from libs/parser/src/test/mod.rs
rename to rust_compiler/libs/parser/src/test/mod.rs
diff --git a/libs/parser/src/tree_node.rs b/rust_compiler/libs/parser/src/tree_node.rs
similarity index 100%
rename from libs/parser/src/tree_node.rs
rename to rust_compiler/libs/parser/src/tree_node.rs
diff --git a/libs/tokenizer/Cargo.toml b/rust_compiler/libs/tokenizer/Cargo.toml
similarity index 100%
rename from libs/tokenizer/Cargo.toml
rename to rust_compiler/libs/tokenizer/Cargo.toml
diff --git a/libs/tokenizer/src/lib.rs b/rust_compiler/libs/tokenizer/src/lib.rs
similarity index 100%
rename from libs/tokenizer/src/lib.rs
rename to rust_compiler/libs/tokenizer/src/lib.rs
diff --git a/libs/tokenizer/src/token.rs b/rust_compiler/libs/tokenizer/src/token.rs
similarity index 100%
rename from libs/tokenizer/src/token.rs
rename to rust_compiler/libs/tokenizer/src/token.rs
diff --git a/libs/tokenizer/tests/file.stlg b/rust_compiler/libs/tokenizer/tests/file.stlg
similarity index 100%
rename from libs/tokenizer/tests/file.stlg
rename to rust_compiler/libs/tokenizer/tests/file.stlg
diff --git a/rust-toolchain.toml b/rust_compiler/rust-toolchain.toml
similarity index 100%
rename from rust-toolchain.toml
rename to rust_compiler/rust-toolchain.toml
diff --git a/src/lib.rs b/rust_compiler/src/lib.rs
similarity index 100%
rename from src/lib.rs
rename to rust_compiler/src/lib.rs
diff --git a/src/main.rs b/rust_compiler/src/main.rs
similarity index 100%
rename from src/main.rs
rename to rust_compiler/src/main.rs