More documentation
This commit is contained in:
7
rust_compiler/Cargo.lock
generated
7
rust_compiler/Cargo.lock
generated
@@ -360,6 +360,10 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "helpers"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.12.1"
|
||||
@@ -495,6 +499,7 @@ name = "parser"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"helpers",
|
||||
"lsp-types",
|
||||
"pretty_assertions",
|
||||
"quick-error",
|
||||
@@ -829,6 +834,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"compiler",
|
||||
"helpers",
|
||||
"lsp-types",
|
||||
"parser",
|
||||
"quick-error",
|
||||
@@ -926,6 +932,7 @@ name = "tokenizer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"helpers",
|
||||
"lsp-types",
|
||||
"quick-error",
|
||||
"rust_decimal",
|
||||
|
||||
@@ -40,6 +40,7 @@ rust_decimal = { workspace = true }
|
||||
tokenizer = { path = "libs/tokenizer" }
|
||||
parser = { path = "libs/parser" }
|
||||
compiler = { path = "libs/compiler" }
|
||||
helpers = { path = "libs/helpers" }
|
||||
safer-ffi = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
6
rust_compiler/libs/helpers/Cargo.toml
Normal file
6
rust_compiler/libs/helpers/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "helpers"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
12
rust_compiler/libs/helpers/src/lib.rs
Normal file
12
rust_compiler/libs/helpers/src/lib.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
mod macros;
|
||||
|
||||
/// This trait will allow the LSP to emit documentation for various tokens and expressions.
|
||||
/// You can easily create documentation for large enums with the `documented!` macro.
|
||||
pub trait Documentation {
|
||||
/// Retreive documentation for this specific item.
|
||||
fn docs(&self) -> String;
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::{Documentation, documented};
|
||||
}
|
||||
@@ -82,4 +82,3 @@ macro_rules! documented {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ edition = "2024"
|
||||
[dependencies]
|
||||
quick-error = { workspace = true }
|
||||
tokenizer = { path = "../tokenizer" }
|
||||
helpers = { path = "../helpers" }
|
||||
lsp-types = { workspace = true }
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
mod macros;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::LiteralOrVariable;
|
||||
use crate::tree_node::{Expression, Literal, Spanned};
|
||||
use crate::{Documentation, documented};
|
||||
use helpers::prelude::*;
|
||||
|
||||
documented! {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
@@ -48,7 +48,7 @@ documented! {
|
||||
/// `(number|var).cos();`
|
||||
Cos(LiteralOrVariable),
|
||||
/// Rounds a number down to the nearest whole number.
|
||||
/// ## In Game
|
||||
/// ## IC10
|
||||
/// `floor r? a(r?|num)`
|
||||
/// ## Slang
|
||||
/// `(number|var).floor();`
|
||||
@@ -131,30 +131,35 @@ documented! {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum System {
|
||||
/// Pauses execution for exactly 1 tick and then resumes.
|
||||
/// ## In Game
|
||||
/// yield
|
||||
/// ## IC10
|
||||
/// `yield`
|
||||
/// ## Slang
|
||||
/// `yield();`
|
||||
Yield,
|
||||
/// Represents a function that can be called to sleep for a certain amount of time.
|
||||
/// ## In Game
|
||||
/// ## IC10
|
||||
/// `sleep a(r?|num)`
|
||||
/// ## Slang
|
||||
/// `sleep(number|var);`
|
||||
Sleep(Box<Spanned<Expression>>),
|
||||
/// Gets the in-game hash for a specific prefab name.
|
||||
/// ## In Game
|
||||
/// ## IC10
|
||||
/// `HASH("prefabName")`
|
||||
/// ## Slang
|
||||
/// `HASH("prefabName");`
|
||||
Hash(Literal),
|
||||
/// Represents a function which loads a device variable into a register.
|
||||
/// ## In Game
|
||||
/// ## IC10
|
||||
/// `l r? d? var`
|
||||
/// ## Examples
|
||||
/// `l r0 d0 Setting`
|
||||
/// `l r1 d5 Pressure`
|
||||
/// ## Slang
|
||||
/// `loadFromDevice(deviceType, "LogicType");`
|
||||
LoadFromDevice(LiteralOrVariable, Literal),
|
||||
/// Function which gets a LogicType from all connected network devices that match
|
||||
/// the provided device hash and name, aggregating them via a batchMode
|
||||
/// ## In Game
|
||||
/// lbn r? deviceHash nameHash logicType batchMode
|
||||
/// ## Examples
|
||||
/// lbn r0 HASH("StructureWallLight") HASH("wallLight") On Minimum
|
||||
/// ## IC10
|
||||
/// `lbn r? deviceHash nameHash logicType batchMode`
|
||||
/// ## Slang
|
||||
/// `loadFromDeviceBatchedNamed(deviceHash, deviceName, "LogicType", "BatchMode");`
|
||||
LoadBatchNamed(
|
||||
LiteralOrVariable,
|
||||
Box<Spanned<Expression>>,
|
||||
@@ -163,30 +168,28 @@ documented! {
|
||||
),
|
||||
/// Loads a LogicType from all connected network devices, aggregating them via a
|
||||
/// batchMode
|
||||
/// ## In Game
|
||||
/// lb r? deviceHash logicType batchMode
|
||||
/// ## Examples
|
||||
/// lb r0 HASH("StructureWallLight") On Minimum
|
||||
/// ## IC10
|
||||
/// `lb r? deviceHash logicType batchMode`
|
||||
/// ## Slang
|
||||
/// `loadFromDeviceBatched(deviceHash, "Variable", "LogicType");`
|
||||
LoadBatch(LiteralOrVariable, Literal, Literal),
|
||||
/// Represents a function which stores a setting into a specific device.
|
||||
/// ## In Game
|
||||
/// ## IC10
|
||||
/// `s d? logicType r?`
|
||||
/// ## Example
|
||||
/// `s d0 Setting r0`
|
||||
/// ## Slang
|
||||
/// `setOnDevice(deviceType, "Variable", (number|var));`
|
||||
SetOnDevice(LiteralOrVariable, Literal, Box<Spanned<Expression>>),
|
||||
/// Represents a function which stores a setting to all devices that match
|
||||
/// the given deviceHash
|
||||
/// ## In Game
|
||||
/// ## IC10
|
||||
/// `sb deviceHash logicType r?`
|
||||
/// ## Example
|
||||
/// `sb HASH("Doors") Lock 1`
|
||||
SetOnDeviceBatched(LiteralOrVariable, Literal, Box<Spanned<Expression>>),
|
||||
/// Represents a function which stores a setting to all devices that match
|
||||
/// both the given deviceHash AND the given nameHash
|
||||
/// ## In Game
|
||||
/// ## IC10
|
||||
/// `sbn deviceHash nameHash logicType r?`
|
||||
/// ## Example
|
||||
/// `sbn HASH("Doors") HASH("Exterior") Lock 1`
|
||||
/// ## Slang
|
||||
/// `setOnDeviceBatchedNamed(deviceType, nameHash, "LogicType", (number|var))`
|
||||
SetOnDeviceBatchedNamed(
|
||||
LiteralOrVariable,
|
||||
LiteralOrVariable,
|
||||
@@ -226,6 +229,15 @@ pub enum SysCall {
|
||||
Math(Math),
|
||||
}
|
||||
|
||||
impl Documentation for SysCall {
|
||||
fn docs(&self) -> String {
|
||||
match self {
|
||||
Self::System(s) => s.docs(),
|
||||
Self::Math(m) => m.docs(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SysCall {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::Documentation;
|
||||
use crate::sys_call;
|
||||
use helpers::Documentation;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2024"
|
||||
rust_decimal = { workspace = true }
|
||||
quick-error = { workspace = true }
|
||||
lsp-types = { workspace = true }
|
||||
helpers = { path = "../helpers" }
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = { version = "^1" }
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use helpers::prelude::*;
|
||||
use rust_decimal::Decimal;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -264,28 +265,130 @@ impl std::fmt::Display for Symbol {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Hash, Eq, Clone, Copy)]
|
||||
pub enum Keyword {
|
||||
/// Represents the `continue` keyword
|
||||
documented! {
|
||||
#[derive(Debug, PartialEq, Hash, Eq, Clone, Copy)]
|
||||
pub enum Keyword {
|
||||
/// Represents the `continue` keyword. This will allow you to bypass the current iteration in a loop and start the next one.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// let item = 0;
|
||||
/// loop {
|
||||
/// if (item % 2 == 0) {
|
||||
/// // This will NOT increment `item` and will continue with the next iteration of the
|
||||
/// // loop
|
||||
/// continue;
|
||||
/// }
|
||||
/// item = item + 1;
|
||||
/// }
|
||||
/// ```
|
||||
Continue,
|
||||
/// Represents the `let` keyword
|
||||
/// Represents the `let` keyword, used to declare variables within Slang.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// // This variable now exists either in a register or the stack depending on how many
|
||||
/// // free registers were available when declaring it.
|
||||
/// let item = 0;
|
||||
/// ```
|
||||
Let,
|
||||
/// Represents the `fn` keyword
|
||||
/// Represents the `fn` keyword, used to declare functions within Slang.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// // This allows you to now call `doSomething` with specific arguments.
|
||||
/// fn doSomething(arg1, arg2) {
|
||||
///
|
||||
/// }
|
||||
/// ```
|
||||
Fn,
|
||||
/// Represents the `if` keyword
|
||||
/// Represents the `if` keyword, allowing you to create branched logic.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// let i = 0;
|
||||
/// if (i == 0) {
|
||||
/// i = 1;
|
||||
/// }
|
||||
/// // At this line, `i` is now `1`
|
||||
/// ```
|
||||
If,
|
||||
/// Represents the `device` keyword. Useful for defining a device at a specific address (ex. d0, d1, d2, etc.)
|
||||
/// Represents the `device` keyword. Useful for defining a device at a specific address
|
||||
/// (ex. d0, d1, d2, etc.). This also allows you to perform direct operations ON a device.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// device self = "db";
|
||||
///
|
||||
/// // This is the same as `s db Setting 123`
|
||||
/// self.Setting = 123;
|
||||
/// ```
|
||||
Device,
|
||||
/// Represents the `else` keyword
|
||||
/// Represents the `else` keyword. Useful if you want to check a condition but run run
|
||||
/// seperate logic in case that condition fails.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// device self = "db";
|
||||
/// let i = 0;
|
||||
/// if (i < 0) {
|
||||
/// self.Setting = 0;
|
||||
/// } else {
|
||||
/// self.Setting = 1;
|
||||
/// }
|
||||
/// // Here, the `Setting` on the current housing is `1` because i was NOT less than 0
|
||||
/// ```
|
||||
Else,
|
||||
/// Represents the `return` keyword
|
||||
/// Represents the `return` keyword. Allows you to pass values from a function back to
|
||||
/// the caller.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// fn doSomething() {
|
||||
/// return 1 + 2;
|
||||
/// }
|
||||
///
|
||||
/// // `returnedValue` now holds the value `3`
|
||||
/// let returnedValue = doSomething();
|
||||
/// ```
|
||||
Return,
|
||||
/// Represents the `enum` keyword
|
||||
/// Represents the `enum` keyword. This is currently not supported, but is kept as a
|
||||
/// reserved keyword in the future case that this is implemented.
|
||||
Enum,
|
||||
/// Represents the `loop` keyword
|
||||
/// Represents the `loop` keyword. This allows you to create an infinate loop, but can be
|
||||
/// broken with the `break` keyword.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// device self = "db";
|
||||
/// let i = 0;
|
||||
/// loop {
|
||||
/// i = i + 1;
|
||||
/// // The current housing will infinately increment it's `Setting` value.
|
||||
/// self.Setting = i;
|
||||
/// }
|
||||
/// ```
|
||||
Loop,
|
||||
/// Represents the `break` keyword
|
||||
/// Represents the `break` keyword. This allows you to "break out of" a loop prematurely,
|
||||
/// such as when an if() conditon is true, etc.
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// let i = 0;
|
||||
/// // This loop will run until the value of `i` is greater than 10,000,
|
||||
/// // which will then trigger the `break` keyword and it will stop looping
|
||||
/// loop {
|
||||
/// if (i > 10_000) {
|
||||
/// break;
|
||||
/// }
|
||||
/// i = i + 1;
|
||||
/// }
|
||||
/// ```
|
||||
Break,
|
||||
/// Represents the `while` keyword
|
||||
/// Represents the `while` keyword. This is similar to the `loop` keyword but different in
|
||||
/// that you don't need an `if` statement to break out of a loop, that is handled
|
||||
/// automatically when invoking `while`
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// let i = 0;
|
||||
/// // This loop will run until the value of `i` is greater than 10,000, in which case the
|
||||
/// // while loop will automatically stop running and code will continue AFTER the last
|
||||
/// // bracket.
|
||||
/// while (i < 10_000) {
|
||||
/// i = i + 1;
|
||||
/// }
|
||||
/// ```
|
||||
While,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user