Track various symbols in the parse stage of Slang

This commit is contained in:
2026-01-02 17:06:43 -07:00
parent 6dc4342ac3
commit 4ff0ff1b66
4 changed files with 163 additions and 31 deletions

View File

@@ -173,7 +173,7 @@ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.111", "syn 2.0.112",
] ]
[[package]] [[package]]
@@ -224,9 +224,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.53" version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -234,9 +234,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.53" version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -253,7 +253,7 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.111", "syn 2.0.112",
] ]
[[package]] [[package]]
@@ -523,9 +523,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
@@ -571,7 +571,7 @@ dependencies = [
"regex-automata", "regex-automata",
"regex-syntax", "regex-syntax",
"rustc_version", "rustc_version",
"syn 2.0.111", "syn 2.0.112",
] ]
[[package]] [[package]]
@@ -726,9 +726,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.103" version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -909,12 +909,6 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]] [[package]]
name = "safer-ffi" name = "safer-ffi"
version = "0.1.13" version = "0.1.13"
@@ -992,20 +986,20 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.111", "syn 2.0.112",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.145" version = "1.0.148"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
"ryu",
"serde", "serde",
"serde_core", "serde_core",
"zmij",
] ]
[[package]] [[package]]
@@ -1016,7 +1010,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.111", "syn 2.0.112",
] ]
[[package]] [[package]]
@@ -1108,9 +1102,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.111" version = "2.0.112"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1153,7 +1147,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.111", "syn 2.0.112",
] ]
[[package]] [[package]]
@@ -1185,9 +1179,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.7.4+spec-1.0.0" version = "0.7.5+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe3cea6b2aa3b910092f6abd4053ea464fab5f9c170ba5e9a6aead16ec4af2b6" checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
dependencies = [ dependencies = [
"serde_core", "serde_core",
] ]
@@ -1206,9 +1200,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_parser" name = "toml_parser"
version = "1.0.5+spec-1.0.0" version = "1.0.6+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c03bee5ce3696f31250db0bbaff18bc43301ce0e8db2ed1f07cbb2acf89984c" checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
dependencies = [ dependencies = [
"winnow", "winnow",
] ]
@@ -1303,7 +1297,7 @@ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.111", "syn 2.0.112",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@@ -1471,5 +1465,11 @@ checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.111", "syn 2.0.112",
] ]
[[package]]
name = "zmij"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "317f17ff091ac4515f17cc7a190d2769a8c9a96d227de5d64b500b01cda8f2cd"

View File

@@ -21,6 +21,7 @@ impl<'a> SymbolInfo<'a> {
lsp_types::SymbolInformation { lsp_types::SymbolInformation {
name: self.name.to_string(), name: self.name.to_string(),
kind: self.kind.to_lsp_symbol_kind(), kind: self.kind.to_lsp_symbol_kind(),
#[allow(deprecated)]
deprecated: None, deprecated: None,
location: lsp_types::Location { location: lsp_types::Location {
uri, uri,

View File

@@ -704,6 +704,10 @@ impl<'a> Compiler<'a> {
let name_str = var_name.node; let name_str = var_name.node;
let name_span = var_name.span; let name_span = var_name.span;
// Track the variable in metadata
self.metadata
.add_variable(name_str.clone(), Some(name_span));
// optimization. Check for a negated numeric literal (including nested negations) // optimization. Check for a negated numeric literal (including nested negations)
// e.g., -5, -(-5), -(-(5)), etc. // e.g., -5, -(-5), -(-(5)), etc.
if let Some(num) = self.try_fold_negation(&expr.node) { if let Some(num) = self.try_fold_negation(&expr.node) {
@@ -1063,6 +1067,10 @@ impl<'a> Compiler<'a> {
value: const_value, value: const_value,
} = expr; } = expr;
// Track the const variable in metadata
self.metadata
.add_variable(const_name.node.clone(), Some(const_name.span));
// check for a hash expression or a literal // check for a hash expression or a literal
let value = match const_value { let value = match const_value {
LiteralOr::Or(Spanned { LiteralOr::Or(Spanned {
@@ -1486,6 +1494,14 @@ impl<'a> Compiler<'a> {
) -> Result<(), Error<'a>> { ) -> Result<(), Error<'a>> {
let TupleDeclarationExpression { names, value } = tuple_decl; let TupleDeclarationExpression { names, value } = tuple_decl;
// Track each variable in the tuple declaration
for name_spanned in &names {
if name_spanned.node.as_ref() != "_" {
self.metadata
.add_variable(name_spanned.node.clone(), Some(name_spanned.span));
}
}
match value.node { match value.node {
Expression::Invocation(invoke_expr) => { Expression::Invocation(invoke_expr) => {
// Execute the function call - tuple values will be on the stack // Execute the function call - tuple values will be on the stack
@@ -1924,6 +1940,10 @@ impl<'a> Compiler<'a> {
&mut self, &mut self,
expr: DeviceDeclarationExpression<'a>, expr: DeviceDeclarationExpression<'a>,
) -> Result<(), Error<'a>> { ) -> Result<(), Error<'a>> {
// Track the device declaration in metadata
self.metadata
.add_variable(expr.name.node.clone(), Some(expr.name.span));
if self.devices.contains_key(&expr.name.node) { if self.devices.contains_key(&expr.name.node) {
self.errors.push(Error::DuplicateIdentifier( self.errors.push(Error::DuplicateIdentifier(
expr.name.node.clone(), expr.name.node.clone(),
@@ -2928,6 +2948,15 @@ impl<'a> Compiler<'a> {
span: Span, span: Span,
scope: &mut VariableScope<'a, '_>, scope: &mut VariableScope<'a, '_>,
) -> Result<Option<CompileLocation<'a>>, Error<'a>> { ) -> Result<Option<CompileLocation<'a>>, Error<'a>> {
// Track the syscall in metadata
let syscall_name = expr.name();
self.metadata.add_syscall(
Cow::Borrowed(syscall_name),
crate::SyscallType::System,
expr.arg_count(),
Some(span),
);
macro_rules! cleanup { macro_rules! cleanup {
($($to_clean:expr),*) => { ($($to_clean:expr),*) => {
$( $(
@@ -3325,6 +3354,15 @@ impl<'a> Compiler<'a> {
span: Span, span: Span,
scope: &mut VariableScope<'a, '_>, scope: &mut VariableScope<'a, '_>,
) -> Result<Option<CompileLocation<'a>>, Error<'a>> { ) -> Result<Option<CompileLocation<'a>>, Error<'a>> {
// Track the syscall in metadata
let syscall_name = expr.name();
self.metadata.add_syscall(
Cow::Borrowed(syscall_name),
crate::SyscallType::Math,
expr.arg_count(),
Some(span),
);
macro_rules! cleanup { macro_rules! cleanup {
($($to_clean:expr),*) => { ($($to_clean:expr),*) => {
$( $(
@@ -3585,6 +3623,11 @@ impl<'a> Compiler<'a> {
let span = expr.span; let span = expr.span;
// Track the function definition in metadata
let param_names: Vec<Cow<'a, str>> = arguments.iter().map(|a| a.node.clone()).collect();
self.metadata
.add_function(name.node.clone(), param_names, Some(name.span));
if self.function_meta.locations.contains_key(&name.node) { if self.function_meta.locations.contains_key(&name.node) {
self.errors self.errors
.push(Error::DuplicateIdentifier(name.node.clone(), name.span)); .push(Error::DuplicateIdentifier(name.node.clone(), name.span));

View File

@@ -127,6 +127,52 @@ impl<'a> std::fmt::Display for Math<'a> {
} }
} }
impl<'a> Math<'a> {
/// Returns the name of this math function (e.g., "acos", "sin", "sqrt", etc.)
pub fn name(&self) -> &'static str {
match self {
Math::Acos(_) => "acos",
Math::Asin(_) => "asin",
Math::Atan(_) => "atan",
Math::Atan2(_, _) => "atan2",
Math::Abs(_) => "abs",
Math::Ceil(_) => "ceil",
Math::Cos(_) => "cos",
Math::Floor(_) => "floor",
Math::Log(_) => "log",
Math::Max(_, _) => "max",
Math::Min(_, _) => "min",
Math::Rand => "rand",
Math::Sin(_) => "sin",
Math::Sqrt(_) => "sqrt",
Math::Tan(_) => "tan",
Math::Trunc(_) => "trunc",
}
}
/// Returns the number of arguments this math function expects
pub fn arg_count(&self) -> usize {
match self {
Math::Acos(_) => 1,
Math::Asin(_) => 1,
Math::Atan(_) => 1,
Math::Atan2(_, _) => 2,
Math::Abs(_) => 1,
Math::Ceil(_) => 1,
Math::Cos(_) => 1,
Math::Floor(_) => 1,
Math::Log(_) => 1,
Math::Max(_, _) => 2,
Math::Min(_, _) => 2,
Math::Rand => 0,
Math::Sin(_) => 1,
Math::Sqrt(_) => 1,
Math::Tan(_) => 1,
Math::Trunc(_) => 1,
}
}
}
documented! { documented! {
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum System<'a> { pub enum System<'a> {
@@ -297,6 +343,48 @@ impl<'a> std::fmt::Display for System<'a> {
} }
} }
impl<'a> System<'a> {
/// Returns the name of this syscall (e.g., "yield", "sleep", "hash", etc.)
pub fn name(&self) -> &'static str {
match self {
System::Yield => "yield",
System::Sleep(_) => "sleep",
System::Clr(_) => "clr",
System::Hash(_) => "hash",
System::LoadFromDevice(_, _) => "loadFromDevice",
System::LoadBatch(_, _, _) => "loadBatch",
System::LoadBatchNamed(_, _, _, _) => "loadBatchNamed",
System::SetOnDevice(_, _, _) => "setOnDevice",
System::SetOnDeviceBatched(_, _, _) => "setOnDeviceBatched",
System::SetOnDeviceBatchedNamed(_, _, _, _) => "setOnDeviceBatchedNamed",
System::LoadSlot(_, _, _) => "loadSlot",
System::SetSlot(_, _, _, _) => "setSlot",
System::LoadReagent(_, _, _) => "loadReagent",
System::Rmap(_, _) => "rmap",
}
}
/// Returns the number of arguments this syscall expects
pub fn arg_count(&self) -> usize {
match self {
System::Yield => 0,
System::Sleep(_) => 1,
System::Clr(_) => 1,
System::Hash(_) => 1,
System::LoadFromDevice(_, _) => 2,
System::LoadBatch(_, _, _) => 3,
System::LoadBatchNamed(_, _, _, _) => 4,
System::SetOnDevice(_, _, _) => 3,
System::SetOnDeviceBatched(_, _, _) => 3,
System::SetOnDeviceBatchedNamed(_, _, _, _) => 4,
System::LoadSlot(_, _, _) => 3,
System::SetSlot(_, _, _, _) => 4,
System::LoadReagent(_, _, _) => 3,
System::Rmap(_, _) => 2,
}
}
}
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
/// This represents built in functions that cannot be overwritten, but can be invoked by the user as functions. /// This represents built in functions that cannot be overwritten, but can be invoked by the user as functions.