diff --git a/rust_compiler/libs/helpers/src/macros.rs b/rust_compiler/libs/helpers/src/macros.rs index 9c51e46..ca9d260 100644 --- a/rust_compiler/libs/helpers/src/macros.rs +++ b/rust_compiler/libs/helpers/src/macros.rs @@ -3,15 +3,10 @@ macro_rules! documented { // ------------------------------------------------------------------------- // Internal Helper: Filter doc comments // ------------------------------------------------------------------------- - - // Case 1: Doc comment. Return Some("string"). - // We match the specific structure of a doc attribute. (@doc_filter #[doc = $doc:expr]) => { Some($doc) }; - // Case 2: Other attributes (derives, etc.). Return None. - // We catch any other token sequence inside the brackets. (@doc_filter #[$($attr:tt)*]) => { None }; @@ -30,23 +25,59 @@ macro_rules! documented { }; // ------------------------------------------------------------------------- - // Main Macro Entry Point + // Entry Point 1: Enum with a single Lifetime (e.g. enum Foo<'a>) + // ------------------------------------------------------------------------- + ( + $(#[$enum_attr:meta])* $vis:vis enum $name:ident < $lt:lifetime > { + $($body:tt)* + } + ) => { + documented!(@generate + meta: [$(#[$enum_attr])*], + vis: [$vis], + name: [$name], + generics: [<$lt>], + body: [$($body)*] + ); + }; + + // ------------------------------------------------------------------------- + // Entry Point 2: Regular Enum (No Generics) // ------------------------------------------------------------------------- ( $(#[$enum_attr:meta])* $vis:vis enum $name:ident { + $($body:tt)* + } + ) => { + documented!(@generate + meta: [$(#[$enum_attr])*], + vis: [$vis], + name: [$name], + generics: [], + body: [$($body)*] + ); + }; + + // ------------------------------------------------------------------------- + // Code Generator (Shared Logic) + // ------------------------------------------------------------------------- + (@generate + meta: [$(#[$enum_attr:meta])*], + vis: [$vis:vis], + name: [$name:ident], + generics: [$($generics:tt)*], + body: [ $( - // Capture attributes as a sequence of token trees inside brackets - // to avoid "local ambiguity" and handle multi-token attributes (like doc="..."). $(#[ $($variant_attr:tt)* ])* $variant:ident $( ($($tuple:tt)*) )? $( {$($structure:tt)*} )? ),* $(,)? - } + ] ) => { - // 1. Generate the actual Enum definition + // 1. Generate the Enum Definition $(#[$enum_attr])* - $vis enum $name { + $vis enum $name $($generics)* { $( $(#[ $($variant_attr)* ])* $variant @@ -55,20 +86,19 @@ macro_rules! documented { )* } - // 2. Implement the Documentation Trait - impl Documentation for $name { + // 2. Implement Documentation Trait + // We apply the captured generics (e.g., <'a>) to both the impl and the type + impl $($generics)* Documentation for $name $($generics)* { fn docs(&self) -> String { match self { $( documented!(@arm $name $variant $( ($($tuple)*) )? $( {$($structure)*} )? ) => { - // Create a temporary array of Option<&str> for all attributes let doc_lines: &[Option<&str>] = &[ $( documented!(@doc_filter #[ $($variant_attr)* ]) ),* ]; - // Filter out the Nones (non-doc attributes), join, and return doc_lines.iter() .filter_map(|&d| d) .collect::>() @@ -80,7 +110,6 @@ macro_rules! documented { } } - // 3. Implement Static Documentation Provider #[allow(dead_code)] fn get_all_documentation() -> Vec<(&'static str, String)> { vec![ @@ -88,7 +117,6 @@ macro_rules! documented { ( stringify!($variant), { - // Re-use the same extraction logic let doc_lines: &[Option<&str>] = &[ $( documented!(@doc_filter #[ $($variant_attr)* ]) diff --git a/rust_compiler/libs/parser/src/lib.rs b/rust_compiler/libs/parser/src/lib.rs index 968dbf2..f6da1b5 100644 --- a/rust_compiler/libs/parser/src/lib.rs +++ b/rust_compiler/libs/parser/src/lib.rs @@ -4,7 +4,7 @@ mod test; pub mod tree_node; use crate::sys_call::{Math, System}; -use std::io::SeekFrom; +use std::{borrow::Cow, io::SeekFrom}; use sys_call::SysCall; use thiserror::Error; use tokenizer::{ @@ -119,7 +119,7 @@ impl<'a> Parser<'a> { } /// Calculates a Span from a given Token reference. - fn token_to_span<'t>(t: &'t Token<'a>) -> Span { + fn token_to_span(t: &Token<'a>) -> Span { Span { start_line: t.line, start_col: t.span.start, @@ -141,7 +141,7 @@ impl<'a> Parser<'a> { } /// Helper to run a parsing closure and wrap the result in a Spanned struct - fn spanned(&mut self, parser: F) -> Result, Error> + fn spanned(&mut self, parser: F) -> Result, Error<'a>> where F: FnOnce(&mut Self) -> Result, { @@ -176,7 +176,7 @@ impl<'a> Parser<'a> { }) } - fn synchronize(&mut self) -> Result<(), Error> { + fn synchronize(&mut self) -> Result<(), Error<'a>> { self.assign_next()?; while let Some(token) = &self.current_token { @@ -202,14 +202,14 @@ impl<'a> Parser<'a> { Ok(()) } - pub fn parse_all(&mut self) -> Result, Error> { + pub fn parse_all(&mut self) -> Result>, Error<'a>> { let first_token = self.tokenizer.peek().unwrap_or(None); let (start_line, start_col) = first_token .as_ref() .map(|tok| (tok.line, tok.span.start)) .unwrap_or((0, 0)); - let mut expressions = Vec::>::new(); + let mut expressions = Vec::>>::new(); loop { match self.tokenizer.peek() { @@ -253,7 +253,7 @@ impl<'a> Parser<'a> { }))) } - pub fn parse(&mut self) -> Result>, Error> { + pub fn parse(&mut self) -> Result>>, Error<'a>> { self.assign_next()?; if self.current_token.is_none() { @@ -269,17 +269,17 @@ impl<'a> Parser<'a> { Ok(expr) } - fn assign_next(&'a mut self) -> Result<(), Error> { + fn assign_next(&'a mut self) -> Result<(), Error<'a>> { self.current_token = self.tokenizer.next_token()?; Ok(()) } - fn get_next(&'a mut self) -> Result, Error> { + fn get_next(&'a mut self) -> Result>, Error<'a>> { self.assign_next()?; Ok(self.current_token.clone()) } - fn expression(&mut self) -> Result>, Error> { + fn expression(&mut self) -> Result>>, Error<'a>> { // Parse the Left Hand Side (unary/primary expression) let lhs = self.unary()?; @@ -310,8 +310,8 @@ impl<'a> Parser<'a> { /// Handles dot notation chains: x.y.z() fn parse_postfix( &mut self, - mut lhs: Spanned, - ) -> Result, Error> { + mut lhs: Spanned>, + ) -> Result>, Error<'a>> { loop { if self_matches_peek!(self, TokenType::Symbol(Symbol::Dot)) { self.assign_next()?; // consume Dot @@ -332,7 +332,7 @@ impl<'a> Parser<'a> { if self_matches_peek!(self, TokenType::Symbol(Symbol::LParen)) { // Method Call self.assign_next()?; // consume '(' - let mut arguments = Vec::>::new(); + let mut arguments = Vec::>>::new(); while !token_matches!( self.get_next()?.ok_or(Error::UnexpectedEOF)?, @@ -417,7 +417,7 @@ impl<'a> Parser<'a> { Ok(lhs) } - fn unary(&mut self) -> Result>, Error> { + fn unary(&mut self) -> Result>>, Error<'a>> { macro_rules! matches_keyword { ($keyword:expr, $($pattern:pat),+) => { matches!($keyword, $($pattern)|+) @@ -574,17 +574,6 @@ impl<'a> Parser<'a> { let start_span = self.current_span(); self.assign_next()?; let inner_expr = self.unary()?.ok_or(Error::UnexpectedEOF)?; - // NOTE: Unary negation can also have postfix applied to the inner expression - // But generally -a.b parses as -(a.b), which is what parse_postfix ensures if called here. - // However, we call parse_postfix on the RESULT of unary in expression(), so - // `expression` sees `Negation`. `parse_postfix` doesn't apply to Negation node unless we allow it? - // Actually, `x.y` binds tighter than `-`. `postfix` logic belongs inside `unary` logic or - // `expression` logic. - // If I have `-x.y`, standard precedence says `-(x.y)`. - // `unary` returns `Negation(x)`. Then `expression` calls `postfix` on `Negation(x)`. - // `postfix` loop runs on `Negation`. This implies `(-x).y`. This is usually WRONG. - // `.` binds tighter than `-`. - // So `unary` must call `postfix` on the *operand* of the negation. let inner_with_postfix = self.parse_postfix(inner_expr)?; @@ -631,7 +620,7 @@ impl<'a> Parser<'a> { Ok(expr) } - fn get_infix_child_node(&mut self) -> Result, Error> { + fn get_infix_child_node(&mut self) -> Result>, Error<'a>> { let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; let start_span = self.current_span(); @@ -715,7 +704,7 @@ impl<'a> Parser<'a> { self.parse_postfix(expr) } - fn device(&mut self) -> Result { + fn device(&mut self) -> Result, Error<'a>> { let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; if !self_matches_current!(self, TokenType::Keyword(Keyword::Device)) { return Err(Error::UnexpectedToken( @@ -730,7 +719,7 @@ impl<'a> Parser<'a> { TokenType::Identifier(ref id) => id.clone(), _ => { return Err(Error::UnexpectedToken( - Self::token_to_span(identifier_token), + Self::token_to_span(&identifier_token), identifier_token.clone(), )); } @@ -739,7 +728,7 @@ impl<'a> Parser<'a> { let current_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(current_token, TokenType::Symbol(Symbol::Assign)) { return Err(Error::UnexpectedToken( - Self::token_to_span(current_token), + Self::token_to_span(¤t_token), current_token.clone(), )); } @@ -749,7 +738,7 @@ impl<'a> Parser<'a> { TokenType::String(ref id) => id.clone(), _ => { return Err(Error::UnexpectedToken( - Self::token_to_span(device_token), + Self::token_to_span(&device_token), device_token.clone(), )); } @@ -764,7 +753,10 @@ impl<'a> Parser<'a> { }) } - fn infix(&mut self, previous: Spanned) -> Result, Error> { + fn infix( + &mut self, + previous: Spanned>, + ) -> Result>, Error<'a>> { let current_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?.clone(); match previous.node { @@ -1072,7 +1064,7 @@ impl<'a> Parser<'a> { expressions.pop().ok_or(Error::UnexpectedEOF) } - fn priority(&mut self) -> Result>>, Error> { + fn priority(&mut self) -> Result>>>, Error<'a>> { let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; if !token_matches!(current_token, TokenType::Symbol(Symbol::LParen)) { return Err(Error::UnexpectedToken( @@ -1087,15 +1079,15 @@ impl<'a> Parser<'a> { let current_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(current_token, TokenType::Symbol(Symbol::RParen)) { return Err(Error::UnexpectedToken( - Self::token_to_span(current_token), - current_token.clone(), + Self::token_to_span(¤t_token), + current_token, )); } Ok(Some(boxed!(expression))) } - fn invocation(&mut self) -> Result { + fn invocation(&mut self) -> Result, Error<'a>> { let identifier_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; let identifier_span = Self::token_to_span(identifier_token); let identifier = match identifier_token.token_type { @@ -1111,8 +1103,8 @@ impl<'a> Parser<'a> { let current_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(current_token, TokenType::Symbol(Symbol::LParen)) { return Err(Error::UnexpectedToken( - Self::token_to_span(current_token), - current_token.clone(), + Self::token_to_span(¤t_token), + current_token, )); } @@ -1138,8 +1130,8 @@ impl<'a> Parser<'a> { { let next_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; return Err(Error::UnexpectedToken( - Self::token_to_span(next_token), - next_token.clone(), + Self::token_to_span(&next_token), + next_token, )); } @@ -1157,7 +1149,7 @@ impl<'a> Parser<'a> { }) } - fn block(&mut self) -> Result { + fn block(&mut self) -> Result, Error<'a>> { let mut expressions = Vec::>::new(); let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; @@ -1180,7 +1172,7 @@ impl<'a> Parser<'a> { if token_matches!(current_token, TokenType::Keyword(Keyword::Return)) { // Need to capture return span - let ret_start_span = Self::token_to_span(current_token); + let ret_start_span = Self::token_to_span(¤t_token); self.assign_next()?; let expression = self.expression()?.ok_or(Error::UnexpectedEOF)?; @@ -1199,25 +1191,19 @@ impl<'a> Parser<'a> { let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::Semicolon)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::RBrace)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } } Ok(BlockExpression(expressions)) } - fn const_declaration(&mut self) -> Result { + fn const_declaration(&mut self) -> Result, Error<'a>> { // const let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; if !self_matches_current!(self, TokenType::Keyword(Keyword::Const)) { @@ -1229,7 +1215,7 @@ impl<'a> Parser<'a> { // variable_name let ident_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; - let ident_span = Self::token_to_span(ident_token); + let ident_span = Self::token_to_span(&ident_token); let ident = match ident_token.token_type { TokenType::Identifier(ref id) => id.clone(), _ => return Err(Error::UnexpectedToken(ident_span, ident_token.clone())), @@ -1287,7 +1273,7 @@ impl<'a> Parser<'a> { } } - fn declaration(&mut self) -> Result { + fn declaration(&mut self) -> Result, Error<'a>> { let current_token = self.current_token.as_ref().ok_or(Error::UnexpectedEOF)?; if !self_matches_current!(self, TokenType::Keyword(Keyword::Let)) { return Err(Error::UnexpectedToken( @@ -1296,13 +1282,13 @@ impl<'a> Parser<'a> { )); } let identifier_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; - let identifier_span = Self::token_to_span(identifier_token); + let identifier_span = Self::token_to_span(&identifier_token); let identifier = match identifier_token.token_type { TokenType::Identifier(ref id) => id.clone(), _ => { return Err(Error::UnexpectedToken( - Self::token_to_span(identifier_token), - identifier_token.clone(), + Self::token_to_span(&identifier_token), + identifier_token, )); } }; @@ -1322,8 +1308,8 @@ impl<'a> Parser<'a> { let current_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(current_token, TokenType::Symbol(Symbol::Semicolon)) { return Err(Error::UnexpectedToken( - Self::token_to_span(current_token), - current_token.clone(), + Self::token_to_span(¤t_token), + current_token, )); } @@ -1336,7 +1322,7 @@ impl<'a> Parser<'a> { )) } - fn literal(&mut self) -> Result { + fn literal(&mut self) -> Result, Error<'a>> { let current_token = self.current_token.clone().ok_or(Error::UnexpectedEOF)?; let literal = match current_token.token_type { TokenType::Number(num) => Literal::Number(num), @@ -1346,11 +1332,11 @@ impl<'a> Parser<'a> { Some(Token { token_type: TokenType::Number(num), .. - }) => Literal::Number(-*num), + }) => Literal::Number(-num), Some(wrong_token) => { return Err(Error::UnexpectedToken( - Self::token_to_span(wrong_token), - wrong_token.clone(), + Self::token_to_span(&wrong_token), + wrong_token, )); } None => return Err(Error::UnexpectedEOF), @@ -1366,14 +1352,11 @@ impl<'a> Parser<'a> { Ok(literal) } - fn if_expression(&mut self) -> Result { + fn if_expression(&mut self) -> Result, Error<'a>> { // 'if' is current let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::LParen)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } self.assign_next()?; @@ -1381,18 +1364,12 @@ impl<'a> Parser<'a> { let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::RParen)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::LBrace)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } let body = self.spanned(|p| p.block())?; @@ -1417,10 +1394,7 @@ impl<'a> Parser<'a> { })) } else { let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } } else { None @@ -1433,13 +1407,10 @@ impl<'a> Parser<'a> { }) } - fn loop_expression(&mut self) -> Result { + fn loop_expression(&mut self) -> Result, Error<'a>> { let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::LBrace)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } let body = self.spanned(|p| p.block())?; @@ -1447,13 +1418,10 @@ impl<'a> Parser<'a> { Ok(LoopExpression { body }) } - fn while_expression(&mut self) -> Result { + fn while_expression(&mut self) -> Result, Error<'a>> { let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::LParen)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } self.assign_next()?; @@ -1461,18 +1429,12 @@ impl<'a> Parser<'a> { let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::RParen)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(next, TokenType::Symbol(Symbol::LBrace)) { - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } let body = self.block()?; @@ -1483,29 +1445,26 @@ impl<'a> Parser<'a> { }) } - fn function(&mut self) -> Result { + fn function(&mut self) -> Result, Error<'a>> { // 'fn' is current let fn_ident_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; - let fn_ident_span = Self::token_to_span(fn_ident_token); + let fn_ident_span = Self::token_to_span(&fn_ident_token); let fn_ident = match fn_ident_token.token_type { TokenType::Identifier(ref id) => id.clone(), _ => { - return Err(Error::UnexpectedToken( - Self::token_to_span(fn_ident_token), - fn_ident_token.clone(), - )); + return Err(Error::UnexpectedToken(fn_ident_span, fn_ident_token)); } }; let current_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(current_token, TokenType::Symbol(Symbol::LParen)) { return Err(Error::UnexpectedToken( - Self::token_to_span(current_token), - current_token.clone(), + Self::token_to_span(¤t_token), + current_token, )); } - let mut arguments = Vec::>::new(); + let mut arguments = Vec::>>::new(); while !token_matches!( self.get_next()?.ok_or(Error::UnexpectedEOF)?, @@ -1516,10 +1475,7 @@ impl<'a> Parser<'a> { let argument = match current_token.token_type { TokenType::Identifier(ref id) => id.clone(), _ => { - return Err(Error::UnexpectedToken( - Self::token_to_span(current_token), - current_token.clone(), - )); + return Err(Error::UnexpectedToken(arg_span, current_token.clone())); } }; @@ -1541,10 +1497,7 @@ impl<'a> Parser<'a> { && !self_matches_peek!(self, TokenType::Symbol(Symbol::RParen)) { let next = self.get_next()?.ok_or(Error::UnexpectedEOF)?; - return Err(Error::UnexpectedToken( - Self::token_to_span(next), - next.clone(), - )); + return Err(Error::UnexpectedToken(Self::token_to_span(&next), next)); } if !self_matches_peek!(self, TokenType::Symbol(Symbol::RParen)) { @@ -1555,8 +1508,8 @@ impl<'a> Parser<'a> { let current_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?; if !token_matches!(current_token, TokenType::Symbol(Symbol::LBrace)) { return Err(Error::UnexpectedToken( - Self::token_to_span(current_token), - current_token.clone(), + Self::token_to_span(¤t_token), + current_token, )); }; @@ -1570,12 +1523,12 @@ impl<'a> Parser<'a> { }) } - fn syscall(&mut self) -> Result { - fn check_length( - parser: &Parser, - arguments: &[Spanned], + fn syscall(&mut self) -> Result, Error<'a>> { + fn check_length<'a>( + parser: &'a Parser, + arguments: &[Spanned>], length: usize, - ) -> Result<(), Error> { + ) -> Result<(), Error<'a>> { if arguments.len() != length { return Err(Error::InvalidSyntax( parser.current_span(), @@ -1636,7 +1589,7 @@ impl<'a> Parser<'a> { let invocation = self.invocation()?; - match invocation.name.node.as_str() { + match invocation.name.node.as_ref() { // System SysCalls "yield" => { check_length(self, &invocation.arguments, 0)?; @@ -1764,7 +1717,9 @@ impl<'a> Parser<'a> { Ok(SysCall::System(sys_call::System::SetOnDevice( device, Spanned { - node: Literal::String(logic_type.node.to_string().replace("\"", "")), + node: Literal::String(Cow::from( + logic_type.node.to_string().replace("\"", ""), + )), span: logic_type.span, }, boxed!(variable), @@ -1783,7 +1738,7 @@ impl<'a> Parser<'a> { Ok(SysCall::System(sys_call::System::SetOnDeviceBatched( device_hash, Spanned { - node: Literal::String(logic_type.to_string().replace("\"", "")), + node: Literal::String(Cow::from(logic_type.to_string().replace("\"", ""))), span: logic_type.span, }, boxed!(variable), diff --git a/rust_compiler/libs/parser/src/sys_call.rs b/rust_compiler/libs/parser/src/sys_call.rs index c44ec95..e90e837 100644 --- a/rust_compiler/libs/parser/src/sys_call.rs +++ b/rust_compiler/libs/parser/src/sys_call.rs @@ -4,73 +4,73 @@ use helpers::prelude::*; documented! { #[derive(Debug, PartialEq, Eq)] - pub enum Math { + pub enum Math<'a> { /// Returns the angle in radians whose cosine is the specified number. /// ## IC10 /// `acos r? a(r?|num)` /// ## Slang /// `let item = acos(number|var|expression);` - Acos(Box>), + Acos(Box>>), /// Returns the angle in radians whose sine is the specified number. /// ## IC10 /// `asin r? a(r?|num)` /// ## Slang /// `let item = asin(number|var|expression);` - Asin(Box>), + Asin(Box>>), /// Returns the angle in radians whose tangent is the specified number. /// ## IC10 /// `atan r? a(r?|num)` /// ## Slang /// `let item = atan(number|var|expression);` - Atan(Box>), + Atan(Box>>), /// Returns the angle in radians whose tangent is the quotient of the specified numbers. /// ## IC10 /// `atan2 r? a(r?|num) b(r?|num)` /// ## Slang /// `let item = atan2((number|var|expression), (number|var|expression));` - Atan2(Box>, Box>), + Atan2(Box>>, Box>>), /// Gets the absolute value of a number. /// ## IC10 /// `abs r? a(r?|num)` /// ## Slang /// `let item = abs((number|var|expression));` - Abs(Box>), + Abs(Box>>), /// Rounds a number up to the nearest whole number. /// ## IC10 /// `ceil r? a(r?|num)` /// ## Slang /// `let item = ceil((number|var|expression));` - Ceil(Box>), + Ceil(Box>>), /// Returns the cosine of the specified angle in radians. /// ## IC10 /// `cos r? a(r?|num)` /// ## Slang /// `let item = cos((number|var|expression));` - Cos(Box>), + Cos(Box>>), /// Rounds a number down to the nearest whole number. /// ## IC10 /// `floor r? a(r?|num)` /// ## Slang /// `let item = floor((number|var|expression));` - Floor(Box>), + Floor(Box>>), /// Computes the natural logarithm of a number. /// ## IC10 /// `log r? a(r?|num)` /// ## Slang /// `let item = log((number|var|expression));` - Log(Box>), + Log(Box>>), /// Computes the maximum of two numbers. /// ## IC10 /// `max r? a(r?|num) b(r?|num)` /// ## Slang /// `let item = max((number|var|expression), (number|var|expression));` - Max(Box>, Box>), + Max(Box>>, Box>>), /// Computes the minimum of two numbers. /// ## IC10 /// `min r? a(r?|num) b(r?|num)` /// ## Slang /// `let item = min((number|var|expression), (number|var|expression));` - Min(Box>, Box>), + Min(Box>>, Box>>), /// Gets a random number between 0 and 1. /// ## IC10 /// `rand r?` @@ -82,29 +82,29 @@ documented! { /// `sin r? a(r?|num)` /// ## Slang /// `let item = sin((number|var|expression));` - Sin(Box>), + Sin(Box>>), /// Computes the square root of a number. /// ## IC10 /// `sqrt r? a(r?|num)` /// ## Slang /// `let item = sqrt((number|var|expression));` - Sqrt(Box>), + Sqrt(Box>>), /// Returns the tangent of the specified angle in radians. /// ## IC10 /// `tan r? a(r?|num)` /// ## Slang /// `let item = tan((number|var|expression));` - Tan(Box>), + Tan(Box>>), /// Truncates a number by removing the decimal portion. /// ## IC10 /// `trunc r? a(r?|num)` /// ## Slang /// `let item = trunc((number|var|expression));` - Trunc(Box>), + Trunc(Box>>), } } -impl std::fmt::Display for Math { +impl<'a> std::fmt::Display for Math<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Math::Acos(a) => write!(f, "acos({})", a), @@ -129,7 +129,7 @@ impl std::fmt::Display for Math { documented! { #[derive(Debug, PartialEq, Eq)] - pub enum System { + pub enum System<'a> { /// Pauses execution for exactly 1 tick and then resumes. /// ## IC10 /// `yield` @@ -141,7 +141,7 @@ documented! { /// `sleep a(r?|num)` /// ## Slang /// `sleep(number|var);` - Sleep(Box>), + Sleep(Box>>), /// Gets the in-game hash for a specific prefab name. NOTE! This call is COMPLETELY /// optimized away unless you bind it to a `let` variable. If you use a `const` variable /// however, the hash is correctly computed at compile time and substitued automatically. @@ -155,7 +155,7 @@ documented! { /// const compDoor = hash("StructureCompositeDoor"); /// setOnDeviceBatched(compDoor, "Lock", true); /// ``` - Hash(Spanned), + Hash(Spanned>), /// Represents a function which loads a device variable into a register. /// ## IC10 /// `l r? d? var` @@ -163,7 +163,7 @@ documented! { /// `let item = load(deviceHash, "LogicType");` /// `let item = l(deviceHash, "LogicType");` /// `let item = deviceAlias.LogicType;` - LoadFromDevice(Spanned, Spanned), + LoadFromDevice(Spanned>, Spanned>), /// Function which gets a LogicType from all connected network devices that match /// the provided device hash and name, aggregating them via a batchMode /// ## IC10 @@ -172,10 +172,10 @@ documented! { /// `loadBatchedNamed(deviceHash, deviceName, "LogicType", "BatchMode");` /// `lbn(deviceHash, deviceName, "LogicType", "BatchMode");` LoadBatchNamed( - Spanned, - Spanned, - Spanned, - Spanned, + Spanned>, + Spanned>, + Spanned>, + Spanned>, ), /// Loads a LogicType from all connected network devices, aggregating them via a /// BatchMode @@ -184,7 +184,7 @@ documented! { /// ## Slang /// `loadBatched(deviceHash, "Variable", "LogicType");` /// `lb(deviceHash, "Variable", "LogicType");` - LoadBatch(Spanned, Spanned, Spanned), + LoadBatch(Spanned>, Spanned>, Spanned>), /// Represents a function which stores a setting into a specific device. /// ## IC10 /// `s d? logicType r?` @@ -192,7 +192,7 @@ documented! { /// `set(deviceHash, "LogicType", (number|var));` /// `s(deviceHash, "LogicType", (number|var));` /// `deviceAlias.LogicType = (number|var);` - SetOnDevice(Spanned, Spanned, Box>), + SetOnDevice(Spanned>, Spanned>, Box>>), /// Represents a function which stores a setting to all devices that match /// the given deviceHash /// ## IC10 @@ -200,7 +200,7 @@ documented! { /// ## Slang /// `setBatched(deviceHash, "LogicType", (number|var));` /// `sb(deviceHash, "LogicType", (number|var));` - SetOnDeviceBatched(Spanned, Spanned, Box>), + SetOnDeviceBatched(Spanned>, Spanned>, Box>>), /// Represents a function which stores a setting to all devices that match /// both the given deviceHash AND the given nameHash /// ## IC10 @@ -209,15 +209,15 @@ documented! { /// `setBatchedNamed(deviceHash, nameHash, "LogicType", (number|var));` /// `sbn(deviceHash, nameHash, "LogicType", (number|var));` SetOnDeviceBatchedNamed( - Spanned, - Spanned, - Spanned, - Box>, + Spanned>, + Spanned>, + Spanned>, + Box>>, ), } } -impl std::fmt::Display for System { +impl<'a> std::fmt::Display for System<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { System::Yield => write!(f, "yield()"), @@ -242,13 +242,13 @@ impl std::fmt::Display for System { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq)] /// This represents built in functions that cannot be overwritten, but can be invoked by the user as functions. -pub enum SysCall { - System(System), +pub enum SysCall<'a> { + System(System<'a>), /// Represents any mathmatical function that can be called. - Math(Math), + Math(Math<'a>), } -impl Documentation for SysCall { +impl<'a> Documentation for SysCall<'a> { fn docs(&self) -> String { match self { Self::System(s) => s.docs(), @@ -264,7 +264,7 @@ impl Documentation for SysCall { } } -impl std::fmt::Display for SysCall { +impl<'a> std::fmt::Display for SysCall<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { SysCall::System(s) => write!(f, "{}", s), @@ -273,7 +273,7 @@ impl std::fmt::Display for SysCall { } } -impl SysCall { +impl<'a> SysCall<'a> { pub fn is_syscall(identifier: &str) -> bool { tokenizer::token::is_syscall(identifier) } diff --git a/rust_compiler/libs/parser/src/tree_node.rs b/rust_compiler/libs/parser/src/tree_node.rs index 963975a..8e221a8 100644 --- a/rust_compiler/libs/parser/src/tree_node.rs +++ b/rust_compiler/libs/parser/src/tree_node.rs @@ -213,7 +213,7 @@ impl<'a> std::fmt::Display for LiteralOrVariable<'a> { #[derive(Debug, PartialEq, Eq)] pub struct ConstDeclarationExpression<'a> { pub name: Spanned>, - pub value: LiteralOr<'a, SysCall>, + pub value: LiteralOr<'a, SysCall<'a>>, } impl<'a> ConstDeclarationExpression<'a> { @@ -365,8 +365,8 @@ pub enum Expression<'a> { Negation(Box>>), Priority(Box>>), Return(Box>>), - Syscall(Spanned), - Variable(Spanned), + Syscall(Spanned>), + Variable(Spanned>), While(Spanned>), }