diff --git a/documentation/standard_library.md b/documentation/standard_library.md index 2cdf206..d20d019 100644 --- a/documentation/standard_library.md +++ b/documentation/standard_library.md @@ -64,10 +64,6 @@ _deprecated: Use `String::concat()`_ ## General -#### `pub fn allocate(size: u64) -> *u8` - -Unsafely allocates `size` bytes of memory from the stack, and returns a pointer to it, which must be manually freed. - ## Maths #### `pub fn clamp(min: f32, max: f32, value: f32) -> f32` diff --git a/examples/associated_functions.reid b/examples/associated_functions.reid index f399626..8c7a087 100644 --- a/examples/associated_functions.reid +++ b/examples/associated_functions.reid @@ -21,6 +21,11 @@ impl i32 { } } +/// Hello there! +fn test() { + +} + fn main() -> u32 { let otus = Otus { field: 17 }; print(from_str("otus: ") + Otus::test(&otus) as u64); diff --git a/reid-lsp/src/analysis.rs b/reid-lsp/src/analysis.rs index dad5c4a..6699908 100644 --- a/reid-lsp/src/analysis.rs +++ b/reid-lsp/src/analysis.rs @@ -276,8 +276,10 @@ pub struct AnalysisScope<'a> { tokens: &'a Vec, variables: HashMap, types: HashMap, - functions: HashMap, - associated_functions: HashMap<(TypeKind, String), (SourceModuleId, SymbolId, Hover)>, + functions: HashMap, + associated_functions: HashMap<(TypeKind, String), (SourceModuleId, SymbolId)>, + function_hovers: HashMap, + assoc_function_hovers: HashMap<(TypeKind, String), Hover>, map: &'a StateMap, } @@ -290,7 +292,9 @@ impl<'a> AnalysisScope<'a> { variables: self.variables.clone(), types: self.types.clone(), functions: self.functions.clone(), + function_hovers: self.function_hovers.clone(), associated_functions: self.associated_functions.clone(), + assoc_function_hovers: self.assoc_function_hovers.clone(), } } @@ -448,33 +452,6 @@ pub fn analyze( return Ok(None); } -// pub fn find_documentation(meta: &Metadata, tokens: &Vec) -> Option { -// let mut documentation = None; -// for idx in meta.range.start..=meta.range.end { -// if let Some(token) = tokens.get(idx) { -// dbg!(&token); -// if matches!(token.token, Token::Whitespace(_) | Token::Doc(_) | Token::Comment(_)) { -// if let Token::Doc(doctext) = &token.token { -// documentation = Some( -// match documentation { -// Some(t) => t + " ", -// None => String::new(), -// } + doctext.trim(), -// ); -// } -// } else { -// dbg!(&token); -// break; -// } -// } else { -// dbg!(&idx); -// break; -// } -// } -// dbg!(&documentation); -// documentation -// } - pub fn analyze_context( context: &mir::Context, module: &mir::Module, @@ -500,7 +477,9 @@ pub fn analyze_context( map, types: HashMap::new(), functions: HashMap::new(), + function_hovers: HashMap::new(), associated_functions: HashMap::new(), + assoc_function_hovers: HashMap::new(), }; for (i, token) in module.tokens.iter().enumerate() { @@ -684,20 +663,19 @@ pub fn analyze_context( if source_id != module.module_id { if let Some(state) = map.get(&source_id) { if let Some(symbol) = state.associated_functions.get(&(ty.clone(), function.name.clone())) { - scope.associated_functions.insert( + scope + .associated_functions + .insert((ty.clone(), function.name.clone()), (source_id, *symbol)); + scope.assoc_function_hovers.insert( (ty.clone(), function.name.clone()), - ( - source_id, - *symbol, - Hover { - documentation: function.documentation.clone(), - kind: Some(HoverKind::Function( - function.name.clone(), - function.parameters.clone(), - function.return_type.clone(), - )), - }, - ), + Hover { + documentation: function.documentation.clone(), + kind: Some(HoverKind::Function( + function.name.clone(), + function.parameters.clone(), + function.return_type.clone(), + )), + }, ); } } @@ -714,20 +692,19 @@ pub fn analyze_context( .state .associated_functions .insert((ty.clone(), function.name.clone()), symbol); - scope.associated_functions.insert( + scope + .associated_functions + .insert((ty.clone(), function.name.clone()), (module.module_id, symbol)); + scope.assoc_function_hovers.insert( (ty.clone(), function.name.clone()), - ( - module.module_id, - symbol, - Hover { - documentation: function.documentation.clone(), - kind: Some(HoverKind::Function( - function.name.clone(), - function.parameters.clone(), - function.return_type.clone(), - )), - }, - ), + Hover { + documentation: function.documentation.clone(), + kind: Some(HoverKind::Function( + function.name.clone(), + function.parameters.clone(), + function.return_type.clone(), + )), + }, ); } @@ -750,27 +727,26 @@ pub fn analyze_context( } for function in &module.functions { + dbg!(&function.name); + scope.function_hovers.insert( + function.name.clone(), + Hover { + documentation: function.documentation.clone(), + kind: Some(HoverKind::Function( + function.name.clone(), + function.parameters.clone(), + function.return_type.clone(), + )), + }, + ); + if let Some(source_id) = function.source { - if source_id != module.module_id { - if let Some(state) = map.get(&source_id) { - if let Some(symbol) = state.functions.get(&function.name) { - scope.functions.insert( - function.name.clone(), - ( - source_id, - *symbol, - Hover { - documentation: function.documentation.clone(), - kind: Some(HoverKind::Function( - function.name.clone(), - function.parameters.clone(), - function.return_type.clone(), - )), - }, - ), - ); - } + if let Some(state) = map.get(&source_id) { + if let Some(symbol) = state.functions.get(&function.name) { + scope.functions.insert(function.name.clone(), (source_id, *symbol)); } + } + if source_id != module.module_id { continue; } } @@ -789,21 +765,9 @@ pub fn analyze_context( let function_symbol = scope.state.new_symbol(idx, SemanticKind::Function); scope.state.set_symbol(idx, function_symbol); scope.state.functions.insert(function.name.clone(), function_symbol); - scope.functions.insert( - function.name.clone(), - ( - module.module_id, - function_symbol, - Hover { - documentation: function.documentation.clone(), - kind: Some(HoverKind::Function( - function.name.clone(), - function.parameters.clone(), - function.return_type.clone(), - )), - }, - ), - ); + scope + .functions + .insert(function.name.clone(), (module.module_id, function_symbol)); } for function in &module.functions { @@ -873,12 +837,10 @@ pub fn analyze_context( } } - let symbol = if let Some((source_id, symbol_id, hover)) = scope.functions.get(&import_name) { - let symbol_id = scope + let symbol = if let Some((source_id, symbol_id)) = scope.functions.get(&import_name) { + scope .state - .new_symbol(import_idx, SemanticKind::Reference(*source_id, *symbol_id)); - scope.state.set_hover(import_idx, hover.clone()); - symbol_id + .new_symbol(import_idx, SemanticKind::Reference(*source_id, *symbol_id)) } else if let Some(module_source) = scope.map.values().find(|s| s.module_name == *module_name) { if let Some((source_id, symbol_id)) = scope.types.get(&TypeKind::CustomType(CustomTypeKey( import_name.clone(), @@ -894,6 +856,9 @@ pub fn analyze_context( scope.state.new_symbol(import_idx, SemanticKind::Default) }; scope.state.set_symbol(import_idx, symbol); + if let Some(hover) = scope.function_hovers.get(&import_name) { + scope.state.set_hover(import_idx, hover.clone()); + } scope.state.set_autocomplete(import_meta.range.end, autocompletes); } @@ -1181,16 +1146,18 @@ pub fn analyze_expr( let idx = scope .token_idx(&meta, |t| matches!(t, Token::Identifier(_))) .unwrap_or(meta.range.end); - let symbol = if let Some((module_id, symbol_id, hover)) = scope.functions.get(name) { - let symbol = scope + let symbol = if let Some((module_id, symbol_id)) = scope.functions.get(name) { + scope .state - .new_symbol(idx, SemanticKind::Reference(*module_id, *symbol_id)); - scope.state.set_hover(idx, hover.clone()); - symbol + .new_symbol(idx, SemanticKind::Reference(*module_id, *symbol_id)) } else { scope.state.new_symbol(idx, SemanticKind::Function) }; + scope.state.set_symbol(idx, symbol); + if let Some(hover) = scope.function_hovers.get(name) { + scope.state.set_hover(idx, hover.clone()); + } } mir::ExprKind::AssociatedFunctionCall( ty, @@ -1230,14 +1197,12 @@ pub fn analyze_expr( let intrinsics = get_intrinsic_assoc_functions(&invoked_ty); let intrinsic_fn = intrinsics.iter().find(|i| i.name == *name); - let fn_symbol = if let Some((module_id, symbol_id, hover)) = + let fn_symbol = if let Some((module_id, symbol_id)) = scope.associated_functions.get(&(invoked_ty.clone(), name.clone())) { - let symbol = scope + scope .state - .new_symbol(fn_idx, SemanticKind::Reference(*module_id, *symbol_id)); - scope.state.set_hover(fn_idx, hover.clone()); - symbol + .new_symbol(fn_idx, SemanticKind::Reference(*module_id, *symbol_id)) } else if let Some(intrinsic) = intrinsic_fn { let symbol = scope.state.new_symbol(fn_idx, SemanticKind::Function); scope.state.set_hover( @@ -1256,6 +1221,9 @@ pub fn analyze_expr( scope.state.new_symbol(fn_idx, SemanticKind::Function) }; scope.state.set_symbol(fn_idx, fn_symbol); + if let Some(hover) = scope.function_hovers.get(name) { + scope.state.set_hover(fn_idx, hover.clone()); + } for expr in parameters { analyze_expr(context, source_module, expr, scope); diff --git a/reid/lib/std.reid b/reid/lib/std.reid index d7022ad..960dccf 100644 --- a/reid/lib/std.reid +++ b/reid/lib/std.reid @@ -3,6 +3,7 @@ extern fn puts(message: *char) -> i32; extern fn free(ptr: *u8); extern fn div(numerator: i32, denominator: i32) -> div_t; +/// Editable string value that can be printed and extended struct String { inner: *char, length: u64, @@ -11,6 +12,7 @@ struct String { } impl String { + /// Returns a new empty `String`-object, which must later be manually freed. pub fn new() -> String { String { inner: char::malloc(0), @@ -20,6 +22,8 @@ impl String { } } + /// Creates a new `String`-object containing initially data from the given + /// string-literal which must be later freed. pub fn from(str: *char) -> String { let length = str_length(str) as u64; let mut new = String::new(); @@ -33,12 +37,14 @@ impl String { return new; } + /// Same as `concat` pub fn push(&mut self, other: String) { for i in 0 .. (str_length(other.inner) - 1) { add_char(self, other.inner[i]); } } + /// Adds a character to the end of this string pub fn add_char(&mut self, c: char) { if ((*self).length + 1) >= (*self).max_length { let new = char::malloc((*self).max_length + 4); @@ -57,6 +63,7 @@ impl String { (*self).length = (*self).length + 1; } + /// Formats the given number into the end of the string. pub fn push_num(&mut self, num: u64) { if num >= 10 { self.push_num(num / 10) @@ -75,18 +82,22 @@ impl String { else if rem == 9 { self.add_char('9'); } } + /// Concatenates `source` to the end of `destination`. pub fn concat(&mut self, other: &String) { for i in 0 .. *other.length { self.add_char(*other.inner[i]); } } + /// Edits given `string` by setting the character at index `position` to be + /// `c`. pub fn set(&mut self, c: char, position: u64) { if position <= (*self).length { (*self).inner[position] = c; } } + /// Frees this given string pub fn free(&self) { free((*self).inner as *u8); } @@ -111,14 +122,17 @@ struct div_t { remainder: i32, } +/// Print given string to stdout pub fn print(message: String) { puts(message.inner); } +/// Divide an integer, returning the quotient and remainder. pub fn int_div(numerator: i32, denominator: i32) -> div_t { return div(numerator, denominator); } +/// (deprecated) creates a new editable string pub fn new_string() -> String { String { inner: char::malloc(0), @@ -128,6 +142,8 @@ pub fn new_string() -> String { } } +/// Creates a new `String`-object containing initially data from the given +/// string-literal which must be later freed. pub fn from_str(str: *char) -> String { let length = str_length(str) as u64; let mut new = new_string(); @@ -141,6 +157,7 @@ pub fn from_str(str: *char) -> String { return new; } +/// (deprecated) Adds a character to the end of a given string pub fn add_char(string: &mut String, c: char) { if ((*string).length + 1) >= (*string).max_length { let new = char::malloc((*string).max_length + 4); @@ -159,12 +176,14 @@ pub fn add_char(string: &mut String, c: char) { (*string).length = (*string).length + 1; } +/// (deprecated) sets a character in a string pub fn set_char(string: &mut String, c: char, position: u64) { if position <= (*string).length { (*string).inner[position] = c; } } +/// (deprecated) frees given string pub fn free_string(string: &String) { free((*string).inner as *u8); } @@ -183,6 +202,7 @@ fn str_length(string: *char) -> u32 { return pos + 1; } +/// (deprecated) concatenates number to the end of this string. pub fn add_num_to_str(string: &mut String, num: u64) { if num >= 10 { add_num_to_str(string, num / 10) @@ -201,12 +221,15 @@ pub fn add_num_to_str(string: &mut String, num: u64) { else if rem == 9 { add_char(string, '9'); } } +/// (deprecated) concatenates two strings to the destination pub fn concat_strings(destination: &mut String, source: String) { for i in 0 .. (str_length(source.inner) - 1) { add_char(destination, source.inner[i]); } } +/// Returns `value` as clamped between `min` and `max`. Equivalent to +/// `max(min(value, max), min)` pub fn clamp(min: f32, max: f32, value: f32) -> f32 { if value > max { return max; @@ -217,6 +240,7 @@ pub fn clamp(min: f32, max: f32, value: f32) -> f32 { return value; } +/// Returns the absolute value of `value`. pub fn abs(f: f32) -> f32 { if f < 0.0 { return f * (0.0 - 1.0); diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index cb57710..72eaf1f 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -697,8 +697,6 @@ impl Parse for ImportStatement { impl Parse for FunctionDefinition { fn parse(mut stream: TokenStream) -> Result { let documentation = stream.find_documentation(); - dbg!(&stream.get_range()); - dbg!(&documentation); let is_pub = if let Some(Token::PubKeyword) = stream.peek() { stream.next(); // Consume pub diff --git a/reid/src/ast/token_stream.rs b/reid/src/ast/token_stream.rs index 530d649..3f731de 100644 --- a/reid/src/ast/token_stream.rs +++ b/reid/src/ast/token_stream.rs @@ -105,7 +105,6 @@ impl<'a, 'b> TokenStream<'a, 'b> { break; } } - dbg!(self.position, from, &documentation); documentation }