Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 73e08b9896 | |||
|
e83ff67af8
|
|||
| cacff4ff55 | |||
|
7295b14f6a
|
|||
|
93873dfa93
|
|||
| 15752fde3d | |||
|
badcdd3c31
|
|||
|
f0e7506905
|
|||
|
0962b3a5e7
|
|||
|
1439f9ee7e
|
|||
|
3f105ef35c
|
|||
|
45a7a6b38b
|
@@ -4,6 +4,7 @@ name: CI/CD Pipeline
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["master"]
|
branches: ["master"]
|
||||||
|
tags: ["*.*.*"]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: ["master"]
|
branches: ["master"]
|
||||||
|
|
||||||
@@ -57,6 +58,10 @@ jobs:
|
|||||||
slang-builder \
|
slang-builder \
|
||||||
./build.sh
|
./build.sh
|
||||||
|
|
||||||
|
- name: Zip Workshop Folder
|
||||||
|
run: |
|
||||||
|
zip -r release/workshop.zip release/workshop/
|
||||||
|
|
||||||
# 3. Fix Permissions
|
# 3. Fix Permissions
|
||||||
# Docker writes files as root. We need to own them to upload them.
|
# Docker writes files as root. We need to own them to upload them.
|
||||||
- name: Fix Permissions
|
- name: Fix Permissions
|
||||||
@@ -65,7 +70,36 @@ jobs:
|
|||||||
|
|
||||||
# 4. Upload to GitHub
|
# 4. Upload to GitHub
|
||||||
- name: Upload Release Artifacts
|
- name: Upload Release Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: StationeersSlang-Release
|
name: StationeersSlang-Release
|
||||||
path: release/
|
path: release/
|
||||||
|
|
||||||
|
release:
|
||||||
|
needs: build
|
||||||
|
runs-on: self-hosted
|
||||||
|
# ONLY run this job if we pushed a tag (e.g., v1.0.1)
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# We download the artifact from the previous 'build' job
|
||||||
|
- name: Download Build Artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: StationeersSlang-Release
|
||||||
|
path: ./release-files
|
||||||
|
|
||||||
|
- name: Create Gitea Release
|
||||||
|
uses: https://gitea.com/actions/gitea-release-action@v1
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
./release-files/workshop.zip
|
||||||
|
./release-files/slang
|
||||||
|
./release-files/slang.exe
|
||||||
|
name: ${{ github.ref_name }}
|
||||||
|
tag_name: ${{ github.ref_name }}
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
17
Changelog.md
17
Changelog.md
@@ -1,5 +1,22 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
[0.4.1]
|
||||||
|
|
||||||
|
- Update syscalls for `loadSlot` and `setSlot` to support expressions instead of
|
||||||
|
just variables for the slot index
|
||||||
|
- Moved the main repository from GitHub to a self-hosted Gitea
|
||||||
|
- Restructured workflow files to support this change
|
||||||
|
- GitHub will still remain as a mirrored repository of the new
|
||||||
|
Gitea instance.
|
||||||
|
- This is in response to the new upcoming changes to the pricing model
|
||||||
|
for self-hosted GitHub action runners.
|
||||||
|
|
||||||
|
[0.4.0]
|
||||||
|
|
||||||
|
- First pass getting compiled IC10 to output along side the Slang source code
|
||||||
|
- IC10 side is currently not scrollable, and text might be cut off from the bottom,
|
||||||
|
requiring newlines to be added to the bottom of the Slang source if needed
|
||||||
|
|
||||||
[0.3.4]
|
[0.3.4]
|
||||||
|
|
||||||
- Added support for `loadReagent`, which maps to the `lr` IC10 instruction
|
- Added support for `loadReagent`, which maps to the `lr` IC10 instruction
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<ModMetadata xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<ModMetadata xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<Name>Slang</Name>
|
<Name>Slang</Name>
|
||||||
<Author>JoeDiertay</Author>
|
<Author>JoeDiertay</Author>
|
||||||
<Version>0.3.4</Version>
|
<Version>0.4.1</Version>
|
||||||
<Description>
|
<Description>
|
||||||
[h1]Slang: High-Level Programming for Stationeers[/h1]
|
[h1]Slang: High-Level Programming for Stationeers[/h1]
|
||||||
|
|
||||||
@@ -23,6 +23,8 @@ Slang (Stationeers Language) brings modern programming to Stationeers. It allows
|
|||||||
[*] [b]Optimizations:[/b] Features like Constant Folding calculate math at compile time to save instructions.
|
[*] [b]Optimizations:[/b] Features like Constant Folding calculate math at compile time to save instructions.
|
||||||
[*] [b]Device Aliasing:[/b] Simple mapping: device sensor = "d0".
|
[*] [b]Device Aliasing:[/b] Simple mapping: device sensor = "d0".
|
||||||
[*] [b]Temperature Literals:[/b] Don't worry about converting Celsius to Kelvin anymore. Define your temperatures as whatever you want and append the proper suffix at the end (ex. 20c, 68f, 293.15k)
|
[*] [b]Temperature Literals:[/b] Don't worry about converting Celsius to Kelvin anymore. Define your temperatures as whatever you want and append the proper suffix at the end (ex. 20c, 68f, 293.15k)
|
||||||
|
[*] [b]Side-by-side IC10 output:[/b] Preview the compiled IC10 alongside the Slang source code. What you see is what you get.
|
||||||
|
[*] [b]Compiler Optimizations:[/b] Slang now does its best to safely optimize the output IC10, removing labels, unnecessary moves, etc.
|
||||||
[/list]
|
[/list]
|
||||||
|
|
||||||
[h2]Installation[/h2]
|
[h2]Installation[/h2]
|
||||||
@@ -50,16 +52,12 @@ loop {
|
|||||||
|
|
||||||
[h2]Known Issues (Beta)[/h2]
|
[h2]Known Issues (Beta)[/h2]
|
||||||
[list]
|
[list]
|
||||||
[*] [b]Code Size:[/b] Compiled output is currently more verbose than hand-optimized assembly. Optimization passes are planned.
|
[*] [b]Stack Access:[/b] Direct stack memory access is disabled to prevent conflicts with the compiler's internal memory management. A workaround is being planned.
|
||||||
[*] [b]Stack Access:[/b] Direct stack memory access is disabled to prevent conflicts with the compiler's internal memory management.
|
|
||||||
[*] [b]Documentation:[/b] In-game tooltips for syscalls (like load, set) are WIP. Check the "Slang" entry in the Stationpedia (F1) for help.
|
[*] [b]Documentation:[/b] In-game tooltips for syscalls (like load, set) are WIP. Check the "Slang" entry in the Stationpedia (F1) for help.
|
||||||
[*] [b]Debugging:[/b] Runtime errors currently point to the compiled IC10 line number, not your Slang source line. Source mapping is coming soon.
|
|
||||||
[/list]
|
[/list]
|
||||||
|
|
||||||
[h2]Planned Features[/h2]
|
[h2]Planned Features[/h2]
|
||||||
[list]
|
[list]
|
||||||
[*] Side-by-side view: Slang vs. Compiled IC10.
|
|
||||||
[*] Compiler optimizations (dead code elimination, smarter register allocation).
|
|
||||||
[*] Enhanced LSP features (Autocomplete, Go to Definition).
|
[*] Enhanced LSP features (Autocomplete, Go to Definition).
|
||||||
[*] Full feature parity with all IC10 instructions.
|
[*] Full feature parity with all IC10 instructions.
|
||||||
[*] Tutorials and beginner script examples.
|
[*] Tutorials and beginner script examples.
|
||||||
|
|||||||
@@ -5,13 +5,20 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using ImGuiNET;
|
||||||
using StationeersIC10Editor;
|
using StationeersIC10Editor;
|
||||||
|
using StationeersIC10Editor.IC10;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
public class SlangFormatter : ICodeFormatter
|
public class SlangFormatter : ICodeFormatter
|
||||||
{
|
{
|
||||||
private CancellationTokenSource? _lspCancellationToken;
|
private CancellationTokenSource? _lspCancellationToken;
|
||||||
private object _tokenLock = new();
|
private object _tokenLock = new();
|
||||||
|
|
||||||
|
private IC10CodeFormatter iC10CodeFormatter = new IC10CodeFormatter();
|
||||||
|
private string ic10CompilationResult = "";
|
||||||
|
private List<SourceMapEntry> ic10SourceMap = new();
|
||||||
|
|
||||||
// VS Code Dark Theme Palette
|
// VS Code Dark Theme Palette
|
||||||
public static readonly uint ColorControl = ColorFromHTML("#C586C0"); // Pink (if, return, loop)
|
public static readonly uint ColorControl = ColorFromHTML("#C586C0"); // Pink (if, return, loop)
|
||||||
public static readonly uint ColorDeclaration = ColorFromHTML("#569CD6"); // Blue (let, device, fn)
|
public static readonly uint ColorDeclaration = ColorFromHTML("#569CD6"); // Blue (let, device, fn)
|
||||||
@@ -33,6 +40,7 @@ public class SlangFormatter : ICodeFormatter
|
|||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
OnCodeChanged += HandleCodeChanged;
|
OnCodeChanged += HandleCodeChanged;
|
||||||
|
OnCaretMoved += UpdateIc10Formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double MatchingScore(string input)
|
public static double MatchingScore(string input)
|
||||||
@@ -70,6 +78,34 @@ public class SlangFormatter : ICodeFormatter
|
|||||||
return this.Lines.RawText;
|
return this.Lines.RawText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void DrawLine(int lineIndex, TextRange selection, bool drawLineNumber = true)
|
||||||
|
{
|
||||||
|
Vector2 cursorPos = ImGui.GetCursorScreenPos();
|
||||||
|
Vector2 space = ImGui.GetContentRegionAvail();
|
||||||
|
base.DrawLine(lineIndex, selection, drawLineNumber);
|
||||||
|
|
||||||
|
var charWidth = Settings.CharWidth;
|
||||||
|
|
||||||
|
var width = Mathf.Max(Lines.Width + 10.0f + LineNumberOffset * charWidth, space.x / 2);
|
||||||
|
|
||||||
|
ImGui
|
||||||
|
.GetWindowDrawList()
|
||||||
|
.AddLine(
|
||||||
|
new Vector2(cursorPos.x + width + 4.5f * charWidth, cursorPos.y),
|
||||||
|
new Vector2(
|
||||||
|
cursorPos.x + width + 4.5f * charWidth,
|
||||||
|
cursorPos.y + space.y + Settings.LineHeight
|
||||||
|
),
|
||||||
|
ColorLineNumber,
|
||||||
|
1.0f
|
||||||
|
);
|
||||||
|
|
||||||
|
cursorPos.x += width;
|
||||||
|
ImGui.SetCursorScreenPos(cursorPos);
|
||||||
|
if (lineIndex < iC10CodeFormatter.Lines.Count)
|
||||||
|
iC10CodeFormatter.DrawLine(lineIndex, new TextRange(), true);
|
||||||
|
}
|
||||||
|
|
||||||
public override StyledLine ParseLine(string line)
|
public override StyledLine ParseLine(string line)
|
||||||
{
|
{
|
||||||
// We create the line first
|
// We create the line first
|
||||||
@@ -126,6 +162,32 @@ public class SlangFormatter : ICodeFormatter
|
|||||||
);
|
);
|
||||||
|
|
||||||
ApplyDiagnostics(dict);
|
ApplyDiagnostics(dict);
|
||||||
|
|
||||||
|
// If we have valid code, update the IC10 output
|
||||||
|
if (dict.Count > 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var (compilationSuccess, compiled, sourceMap) = await Task.Run(
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
var successful = Marshal.CompileFromString(
|
||||||
|
inputSrc,
|
||||||
|
out var compiled,
|
||||||
|
out var sourceMap
|
||||||
|
);
|
||||||
|
return (successful, compiled, sourceMap);
|
||||||
|
},
|
||||||
|
cancellationToken
|
||||||
|
);
|
||||||
|
|
||||||
|
if (compilationSuccess)
|
||||||
|
{
|
||||||
|
ic10CompilationResult = compiled;
|
||||||
|
ic10SourceMap = sourceMap;
|
||||||
|
UpdateIc10Formatter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException) { }
|
catch (OperationCanceledException) { }
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -134,6 +196,53 @@ public class SlangFormatter : ICodeFormatter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateIc10Formatter()
|
||||||
|
{
|
||||||
|
iC10CodeFormatter.Editor = Editor;
|
||||||
|
var caretPos = Editor.CaretPos.Line;
|
||||||
|
|
||||||
|
// get the slang sourceMap at the current editor line
|
||||||
|
var lines = ic10SourceMap.FindAll(entry =>
|
||||||
|
entry.SlangSource.StartLine == caretPos || entry.SlangSource.EndLine == caretPos
|
||||||
|
);
|
||||||
|
|
||||||
|
// extract the current "context" of the ic10 compilation. The current Slang source line
|
||||||
|
// should be directly next to the compiled IC10 source line, and we should highlight the
|
||||||
|
// IC10 code that directly represents the Slang source
|
||||||
|
|
||||||
|
iC10CodeFormatter.ResetCode(ic10CompilationResult);
|
||||||
|
|
||||||
|
if (lines.Count() < 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// get the total range of the IC10 source for the selected Slang line
|
||||||
|
var max = lines.Max(line => line.Ic10Line);
|
||||||
|
var min = lines.Min(line => line.Ic10Line);
|
||||||
|
|
||||||
|
// highlight all the IC10 lines that are within the specified range
|
||||||
|
foreach (var index in Enumerable.Range((int)min, (int)(max - min) + 1))
|
||||||
|
{
|
||||||
|
var lineText = iC10CodeFormatter.Lines[index].Text;
|
||||||
|
|
||||||
|
var newLine = new StyledLine(
|
||||||
|
lineText,
|
||||||
|
[
|
||||||
|
new SemanticToken
|
||||||
|
{
|
||||||
|
Column = 0,
|
||||||
|
Length = lineText.Length,
|
||||||
|
Line = index,
|
||||||
|
Background = ColorIdentifier,
|
||||||
|
Color = ColorFromHTML("black"),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
iC10CodeFormatter.Lines[index] = newLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This runs on the Main Thread
|
// This runs on the Main Thread
|
||||||
private void ApplyDiagnostics(Dictionary<uint, IGrouping<uint, Diagnostic>> dict)
|
private void ApplyDiagnostics(Dictionary<uint, IGrouping<uint, Diagnostic>> dict)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Slang
|
|||||||
{
|
{
|
||||||
public const string PluginGuid = "com.biddydev.slang";
|
public const string PluginGuid = "com.biddydev.slang";
|
||||||
public const string PluginName = "Slang";
|
public const string PluginName = "Slang";
|
||||||
public const string PluginVersion = "0.3.4";
|
public const string PluginVersion = "0.4.1";
|
||||||
|
|
||||||
public static Mod MOD = new Mod(PluginName, PluginVersion);
|
public static Mod MOD = new Mod(PluginName, PluginVersion);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<AssemblyName>StationeersSlang</AssemblyName>
|
<AssemblyName>StationeersSlang</AssemblyName>
|
||||||
<Description>Slang Compiler Bridge</Description>
|
<Description>Slang Compiler Bridge</Description>
|
||||||
<Version>0.3.2</Version>
|
<Version>0.4.0</Version>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -39,6 +39,10 @@
|
|||||||
<HintPath>./ref/Assembly-CSharp.dll</HintPath>
|
<HintPath>./ref/Assembly-CSharp.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="RG.ImGui">
|
||||||
|
<HintPath>./ref/RG.ImGui.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
|
||||||
<Reference Include="IC10Editor.dll">
|
<Reference Include="IC10Editor.dll">
|
||||||
<HintPath>./ref/IC10Editor.dll</HintPath>
|
<HintPath>./ref/IC10Editor.dll</HintPath>
|
||||||
|
|||||||
2
rust_compiler/Cargo.lock
generated
2
rust_compiler/Cargo.lock
generated
@@ -930,7 +930,7 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slang"
|
name = "slang"
|
||||||
version = "0.3.4"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "slang"
|
name = "slang"
|
||||||
version = "0.3.4"
|
version = "0.4.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|||||||
@@ -13,6 +13,6 @@ lsp-types = { workspace = true }
|
|||||||
rust_decimal = { workspace = true }
|
rust_decimal = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { version = "1.0" }
|
||||||
indoc = { version = "2.0" }
|
indoc = { version = "2.0" }
|
||||||
pretty_assertions = "1"
|
pretty_assertions = "1"
|
||||||
|
|||||||
@@ -2233,10 +2233,7 @@ impl<'a> Compiler<'a> {
|
|||||||
System::LoadSlot(dev_name, slot_index, logic_type) => {
|
System::LoadSlot(dev_name, slot_index, logic_type) => {
|
||||||
let (dev_hash, hash_cleanup) =
|
let (dev_hash, hash_cleanup) =
|
||||||
self.compile_literal_or_variable(dev_name.node, scope)?;
|
self.compile_literal_or_variable(dev_name.node, scope)?;
|
||||||
let (slot_index, slot_cleanup) = self.compile_literal_or_variable(
|
let (slot_index, slot_cleanup) = self.compile_operand(*slot_index, scope)?;
|
||||||
LiteralOrVariable::Literal(slot_index.node),
|
|
||||||
scope,
|
|
||||||
)?;
|
|
||||||
let (logic_type, logic_cleanup) = self.compile_literal_or_variable(
|
let (logic_type, logic_cleanup) = self.compile_literal_or_variable(
|
||||||
LiteralOrVariable::Literal(logic_type.node),
|
LiteralOrVariable::Literal(logic_type.node),
|
||||||
scope,
|
scope,
|
||||||
@@ -2261,10 +2258,7 @@ impl<'a> Compiler<'a> {
|
|||||||
System::SetSlot(dev_name, slot_index, logic_type, var) => {
|
System::SetSlot(dev_name, slot_index, logic_type, var) => {
|
||||||
let (dev_name, name_cleanup) =
|
let (dev_name, name_cleanup) =
|
||||||
self.compile_literal_or_variable(dev_name.node, scope)?;
|
self.compile_literal_or_variable(dev_name.node, scope)?;
|
||||||
let (slot_index, index_cleanup) = self.compile_literal_or_variable(
|
let (slot_index, index_cleanup) = self.compile_operand(*slot_index, scope)?;
|
||||||
LiteralOrVariable::Literal(slot_index.node),
|
|
||||||
scope,
|
|
||||||
)?;
|
|
||||||
let (logic_type, type_cleanup) = self.compile_literal_or_variable(
|
let (logic_type, type_cleanup) = self.compile_literal_or_variable(
|
||||||
LiteralOrVariable::Literal(logic_type.node),
|
LiteralOrVariable::Literal(logic_type.node),
|
||||||
scope,
|
scope,
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ impl<'a> Parser<'a> {
|
|||||||
Ok(Some(lhs))
|
Ok(Some(lhs))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles dot notation chains (x.y.z()) and array indexing (x[0])
|
/// Handles dot notation chains: x.y.z()
|
||||||
fn parse_postfix(
|
fn parse_postfix(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut lhs: Spanned<Expression<'a>>,
|
mut lhs: Spanned<Expression<'a>>,
|
||||||
@@ -411,9 +411,6 @@ impl<'a> Parser<'a> {
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else if self_matches_peek!(self, TokenType::Symbol(Symbol::LBracket)) {
|
|
||||||
// consume the `[` token
|
|
||||||
self.assign_next()?;
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1837,20 +1834,8 @@ impl<'a> Parser<'a> {
|
|||||||
let mut args = args!(3);
|
let mut args = args!(3);
|
||||||
let next = args.next();
|
let next = args.next();
|
||||||
let dev_name = literal_or_variable!(next);
|
let dev_name = literal_or_variable!(next);
|
||||||
let next = args.next();
|
let slot_index = args.next().ok_or(Error::UnexpectedEOF)?;
|
||||||
let slot_index = get_arg!(Literal, literal_or_variable!(next));
|
|
||||||
if !matches!(
|
|
||||||
slot_index,
|
|
||||||
Spanned {
|
|
||||||
node: Literal::Number(_),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
return Err(Error::InvalidSyntax(
|
|
||||||
slot_index.span,
|
|
||||||
"Expected a number".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let next = args.next();
|
let next = args.next();
|
||||||
let slot_logic = get_arg!(Literal, literal_or_variable!(next));
|
let slot_logic = get_arg!(Literal, literal_or_variable!(next));
|
||||||
if !matches!(
|
if !matches!(
|
||||||
@@ -1867,27 +1852,17 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(SysCall::System(System::LoadSlot(
|
Ok(SysCall::System(System::LoadSlot(
|
||||||
dev_name, slot_index, slot_logic,
|
dev_name,
|
||||||
|
boxed!(slot_index),
|
||||||
|
slot_logic,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
"setSlot" | "ss" => {
|
"setSlot" | "ss" => {
|
||||||
let mut args = args!(4);
|
let mut args = args!(4);
|
||||||
let next = args.next();
|
let next = args.next();
|
||||||
let dev_name = literal_or_variable!(next);
|
let dev_name = literal_or_variable!(next);
|
||||||
let next = args.next();
|
let slot_index = args.next().ok_or(Error::UnexpectedEOF)?;
|
||||||
let slot_index = get_arg!(Literal, literal_or_variable!(next));
|
|
||||||
if !matches!(
|
|
||||||
slot_index,
|
|
||||||
Spanned {
|
|
||||||
node: Literal::Number(_),
|
|
||||||
..
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
return Err(Error::InvalidSyntax(
|
|
||||||
slot_index.span,
|
|
||||||
"Expected a number".into(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let next = args.next();
|
let next = args.next();
|
||||||
let slot_logic = get_arg!(Literal, literal_or_variable!(next));
|
let slot_logic = get_arg!(Literal, literal_or_variable!(next));
|
||||||
if !matches!(
|
if !matches!(
|
||||||
@@ -1907,9 +1882,9 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
Ok(SysCall::System(System::SetSlot(
|
Ok(SysCall::System(System::SetSlot(
|
||||||
dev_name,
|
dev_name,
|
||||||
slot_index,
|
boxed!(slot_index),
|
||||||
slot_logic,
|
slot_logic,
|
||||||
Box::new(expr),
|
boxed!(expr),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
"loadReagent" | "lr" => {
|
"loadReagent" | "lr" => {
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ documented! {
|
|||||||
/// `let isOccupied = ls(deviceHash, 2, "Occupied");`
|
/// `let isOccupied = ls(deviceHash, 2, "Occupied");`
|
||||||
LoadSlot(
|
LoadSlot(
|
||||||
Spanned<LiteralOrVariable<'a>>,
|
Spanned<LiteralOrVariable<'a>>,
|
||||||
Spanned<Literal<'a>>,
|
Box<Spanned<Expression<'a>>>,
|
||||||
Spanned<Literal<'a>>
|
Spanned<Literal<'a>>
|
||||||
),
|
),
|
||||||
/// Stores a value of LogicType on a device by the index value
|
/// Stores a value of LogicType on a device by the index value
|
||||||
@@ -234,7 +234,7 @@ documented! {
|
|||||||
/// `ss(deviceHash, 0, "Open", true);`
|
/// `ss(deviceHash, 0, "Open", true);`
|
||||||
SetSlot(
|
SetSlot(
|
||||||
Spanned<LiteralOrVariable<'a>>,
|
Spanned<LiteralOrVariable<'a>>,
|
||||||
Spanned<Literal<'a>>,
|
Box<Spanned<Expression<'a>>>,
|
||||||
Spanned<Literal<'a>>,
|
Spanned<Literal<'a>>,
|
||||||
Box<Spanned<Expression<'a>>>
|
Box<Spanned<Expression<'a>>>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -174,18 +174,6 @@ impl<'a> std::fmt::Display for MemberAccessExpression<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub struct MemberIndexingExpression<'a> {
|
|
||||||
pub object: LiteralOrVariable<'a>,
|
|
||||||
pub index_of: Box<Spanned<Expression<'a>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> std::fmt::Display for MemberIndexingExpression<'a> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}[{}]", self.object, self.index_of)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct MethodCallExpression<'a> {
|
pub struct MethodCallExpression<'a> {
|
||||||
pub object: Box<Spanned<Expression<'a>>>,
|
pub object: Box<Spanned<Expression<'a>>>,
|
||||||
|
|||||||
Reference in New Issue
Block a user