Add documentation to std

This commit is contained in:
Sofia 2025-08-14 17:34:08 +03:00
parent 89b6fc1a71
commit aa1de16f4c
6 changed files with 101 additions and 111 deletions

View File

@ -64,10 +64,6 @@ _deprecated: Use `String::concat()`_
## General ## 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 ## Maths
#### `pub fn clamp(min: f32, max: f32, value: f32) -> f32` #### `pub fn clamp(min: f32, max: f32, value: f32) -> f32`

View File

@ -21,6 +21,11 @@ impl i32 {
} }
} }
/// Hello there!
fn test() {
}
fn main() -> u32 { fn main() -> u32 {
let otus = Otus { field: 17 }; let otus = Otus { field: 17 };
print(from_str("otus: ") + Otus::test(&otus) as u64); print(from_str("otus: ") + Otus::test(&otus) as u64);

View File

@ -276,8 +276,10 @@ pub struct AnalysisScope<'a> {
tokens: &'a Vec<FullToken>, tokens: &'a Vec<FullToken>,
variables: HashMap<String, SymbolId>, variables: HashMap<String, SymbolId>,
types: HashMap<TypeKind, (SourceModuleId, SymbolId)>, types: HashMap<TypeKind, (SourceModuleId, SymbolId)>,
functions: HashMap<String, (SourceModuleId, SymbolId, Hover)>, functions: HashMap<String, (SourceModuleId, SymbolId)>,
associated_functions: HashMap<(TypeKind, String), (SourceModuleId, SymbolId, Hover)>, associated_functions: HashMap<(TypeKind, String), (SourceModuleId, SymbolId)>,
function_hovers: HashMap<String, Hover>,
assoc_function_hovers: HashMap<(TypeKind, String), Hover>,
map: &'a StateMap, map: &'a StateMap,
} }
@ -290,7 +292,9 @@ impl<'a> AnalysisScope<'a> {
variables: self.variables.clone(), variables: self.variables.clone(),
types: self.types.clone(), types: self.types.clone(),
functions: self.functions.clone(), functions: self.functions.clone(),
function_hovers: self.function_hovers.clone(),
associated_functions: self.associated_functions.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); return Ok(None);
} }
// pub fn find_documentation(meta: &Metadata, tokens: &Vec<FullToken>) -> Option<String> {
// 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( pub fn analyze_context(
context: &mir::Context, context: &mir::Context,
module: &mir::Module, module: &mir::Module,
@ -500,7 +477,9 @@ pub fn analyze_context(
map, map,
types: HashMap::new(), types: HashMap::new(),
functions: HashMap::new(), functions: HashMap::new(),
function_hovers: HashMap::new(),
associated_functions: HashMap::new(), associated_functions: HashMap::new(),
assoc_function_hovers: HashMap::new(),
}; };
for (i, token) in module.tokens.iter().enumerate() { for (i, token) in module.tokens.iter().enumerate() {
@ -684,20 +663,19 @@ pub fn analyze_context(
if source_id != module.module_id { if source_id != module.module_id {
if let Some(state) = map.get(&source_id) { if let Some(state) = map.get(&source_id) {
if let Some(symbol) = state.associated_functions.get(&(ty.clone(), function.name.clone())) { 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()), (ty.clone(), function.name.clone()),
( Hover {
source_id, documentation: function.documentation.clone(),
*symbol, kind: Some(HoverKind::Function(
Hover { function.name.clone(),
documentation: function.documentation.clone(), function.parameters.clone(),
kind: Some(HoverKind::Function( function.return_type.clone(),
function.name.clone(), )),
function.parameters.clone(), },
function.return_type.clone(),
)),
},
),
); );
} }
} }
@ -714,20 +692,19 @@ pub fn analyze_context(
.state .state
.associated_functions .associated_functions
.insert((ty.clone(), function.name.clone()), symbol); .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()), (ty.clone(), function.name.clone()),
( Hover {
module.module_id, documentation: function.documentation.clone(),
symbol, kind: Some(HoverKind::Function(
Hover { function.name.clone(),
documentation: function.documentation.clone(), function.parameters.clone(),
kind: Some(HoverKind::Function( function.return_type.clone(),
function.name.clone(), )),
function.parameters.clone(), },
function.return_type.clone(),
)),
},
),
); );
} }
@ -750,27 +727,26 @@ pub fn analyze_context(
} }
for function in &module.functions { 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 let Some(source_id) = function.source {
if source_id != module.module_id { if let Some(state) = map.get(&source_id) {
if let Some(state) = map.get(&source_id) { if let Some(symbol) = state.functions.get(&function.name) {
if let Some(symbol) = state.functions.get(&function.name) { scope.functions.insert(function.name.clone(), (source_id, *symbol));
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 source_id != module.module_id {
continue; continue;
} }
} }
@ -789,21 +765,9 @@ pub fn analyze_context(
let function_symbol = scope.state.new_symbol(idx, SemanticKind::Function); let function_symbol = scope.state.new_symbol(idx, SemanticKind::Function);
scope.state.set_symbol(idx, function_symbol); scope.state.set_symbol(idx, function_symbol);
scope.state.functions.insert(function.name.clone(), function_symbol); scope.state.functions.insert(function.name.clone(), function_symbol);
scope.functions.insert( scope
function.name.clone(), .functions
( .insert(function.name.clone(), (module.module_id, function_symbol));
module.module_id,
function_symbol,
Hover {
documentation: function.documentation.clone(),
kind: Some(HoverKind::Function(
function.name.clone(),
function.parameters.clone(),
function.return_type.clone(),
)),
},
),
);
} }
for function in &module.functions { 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 = if let Some((source_id, symbol_id)) = scope.functions.get(&import_name) {
let symbol_id = scope scope
.state .state
.new_symbol(import_idx, SemanticKind::Reference(*source_id, *symbol_id)); .new_symbol(import_idx, SemanticKind::Reference(*source_id, *symbol_id))
scope.state.set_hover(import_idx, hover.clone());
symbol_id
} else if let Some(module_source) = scope.map.values().find(|s| s.module_name == *module_name) { } 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( if let Some((source_id, symbol_id)) = scope.types.get(&TypeKind::CustomType(CustomTypeKey(
import_name.clone(), import_name.clone(),
@ -894,6 +856,9 @@ pub fn analyze_context(
scope.state.new_symbol(import_idx, SemanticKind::Default) scope.state.new_symbol(import_idx, SemanticKind::Default)
}; };
scope.state.set_symbol(import_idx, symbol); 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); scope.state.set_autocomplete(import_meta.range.end, autocompletes);
} }
@ -1181,16 +1146,18 @@ pub fn analyze_expr(
let idx = scope let idx = scope
.token_idx(&meta, |t| matches!(t, Token::Identifier(_))) .token_idx(&meta, |t| matches!(t, Token::Identifier(_)))
.unwrap_or(meta.range.end); .unwrap_or(meta.range.end);
let symbol = if let Some((module_id, symbol_id, hover)) = scope.functions.get(name) { let symbol = if let Some((module_id, symbol_id)) = scope.functions.get(name) {
let symbol = scope scope
.state .state
.new_symbol(idx, SemanticKind::Reference(*module_id, *symbol_id)); .new_symbol(idx, SemanticKind::Reference(*module_id, *symbol_id))
scope.state.set_hover(idx, hover.clone());
symbol
} else { } else {
scope.state.new_symbol(idx, SemanticKind::Function) scope.state.new_symbol(idx, SemanticKind::Function)
}; };
scope.state.set_symbol(idx, symbol); 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( mir::ExprKind::AssociatedFunctionCall(
ty, ty,
@ -1230,14 +1197,12 @@ pub fn analyze_expr(
let intrinsics = get_intrinsic_assoc_functions(&invoked_ty); let intrinsics = get_intrinsic_assoc_functions(&invoked_ty);
let intrinsic_fn = intrinsics.iter().find(|i| i.name == *name); 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())) scope.associated_functions.get(&(invoked_ty.clone(), name.clone()))
{ {
let symbol = scope scope
.state .state
.new_symbol(fn_idx, SemanticKind::Reference(*module_id, *symbol_id)); .new_symbol(fn_idx, SemanticKind::Reference(*module_id, *symbol_id))
scope.state.set_hover(fn_idx, hover.clone());
symbol
} else if let Some(intrinsic) = intrinsic_fn { } else if let Some(intrinsic) = intrinsic_fn {
let symbol = scope.state.new_symbol(fn_idx, SemanticKind::Function); let symbol = scope.state.new_symbol(fn_idx, SemanticKind::Function);
scope.state.set_hover( scope.state.set_hover(
@ -1256,6 +1221,9 @@ pub fn analyze_expr(
scope.state.new_symbol(fn_idx, SemanticKind::Function) scope.state.new_symbol(fn_idx, SemanticKind::Function)
}; };
scope.state.set_symbol(fn_idx, fn_symbol); 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 { for expr in parameters {
analyze_expr(context, source_module, expr, scope); analyze_expr(context, source_module, expr, scope);

View File

@ -3,6 +3,7 @@ extern fn puts(message: *char) -> i32;
extern fn free(ptr: *u8); extern fn free(ptr: *u8);
extern fn div(numerator: i32, denominator: i32) -> div_t; extern fn div(numerator: i32, denominator: i32) -> div_t;
/// Editable string value that can be printed and extended
struct String { struct String {
inner: *char, inner: *char,
length: u64, length: u64,
@ -11,6 +12,7 @@ struct String {
} }
impl String { impl String {
/// Returns a new empty `String`-object, which must later be manually freed.
pub fn new() -> String { pub fn new() -> String {
String { String {
inner: char::malloc(0), 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 { pub fn from(str: *char) -> String {
let length = str_length(str) as u64; let length = str_length(str) as u64;
let mut new = String::new(); let mut new = String::new();
@ -33,12 +37,14 @@ impl String {
return new; return new;
} }
/// Same as `concat`
pub fn push(&mut self, other: String) { pub fn push(&mut self, other: String) {
for i in 0 .. (str_length(other.inner) - 1) { for i in 0 .. (str_length(other.inner) - 1) {
add_char(self, other.inner[i]); add_char(self, other.inner[i]);
} }
} }
/// Adds a character to the end of this string
pub fn add_char(&mut self, c: char) { pub fn add_char(&mut self, c: char) {
if ((*self).length + 1) >= (*self).max_length { if ((*self).length + 1) >= (*self).max_length {
let new = char::malloc((*self).max_length + 4); let new = char::malloc((*self).max_length + 4);
@ -57,6 +63,7 @@ impl String {
(*self).length = (*self).length + 1; (*self).length = (*self).length + 1;
} }
/// Formats the given number into the end of the string.
pub fn push_num(&mut self, num: u64) { pub fn push_num(&mut self, num: u64) {
if num >= 10 { if num >= 10 {
self.push_num(num / 10) self.push_num(num / 10)
@ -75,18 +82,22 @@ impl String {
else if rem == 9 { self.add_char('9'); } else if rem == 9 { self.add_char('9'); }
} }
/// Concatenates `source` to the end of `destination`.
pub fn concat(&mut self, other: &String) { pub fn concat(&mut self, other: &String) {
for i in 0 .. *other.length { for i in 0 .. *other.length {
self.add_char(*other.inner[i]); 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) { pub fn set(&mut self, c: char, position: u64) {
if position <= (*self).length { if position <= (*self).length {
(*self).inner[position] = c; (*self).inner[position] = c;
} }
} }
/// Frees this given string
pub fn free(&self) { pub fn free(&self) {
free((*self).inner as *u8); free((*self).inner as *u8);
} }
@ -111,14 +122,17 @@ struct div_t {
remainder: i32, remainder: i32,
} }
/// Print given string to stdout
pub fn print(message: String) { pub fn print(message: String) {
puts(message.inner); puts(message.inner);
} }
/// Divide an integer, returning the quotient and remainder.
pub fn int_div(numerator: i32, denominator: i32) -> div_t { pub fn int_div(numerator: i32, denominator: i32) -> div_t {
return div(numerator, denominator); return div(numerator, denominator);
} }
/// (deprecated) creates a new editable string
pub fn new_string() -> String { pub fn new_string() -> String {
String { String {
inner: char::malloc(0), 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 { pub fn from_str(str: *char) -> String {
let length = str_length(str) as u64; let length = str_length(str) as u64;
let mut new = new_string(); let mut new = new_string();
@ -141,6 +157,7 @@ pub fn from_str(str: *char) -> String {
return new; return new;
} }
/// (deprecated) Adds a character to the end of a given string
pub fn add_char(string: &mut String, c: char) { pub fn add_char(string: &mut String, c: char) {
if ((*string).length + 1) >= (*string).max_length { if ((*string).length + 1) >= (*string).max_length {
let new = char::malloc((*string).max_length + 4); 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; (*string).length = (*string).length + 1;
} }
/// (deprecated) sets a character in a string
pub fn set_char(string: &mut String, c: char, position: u64) { pub fn set_char(string: &mut String, c: char, position: u64) {
if position <= (*string).length { if position <= (*string).length {
(*string).inner[position] = c; (*string).inner[position] = c;
} }
} }
/// (deprecated) frees given string
pub fn free_string(string: &String) { pub fn free_string(string: &String) {
free((*string).inner as *u8); free((*string).inner as *u8);
} }
@ -183,6 +202,7 @@ fn str_length(string: *char) -> u32 {
return pos + 1; return pos + 1;
} }
/// (deprecated) concatenates number to the end of this string.
pub fn add_num_to_str(string: &mut String, num: u64) { pub fn add_num_to_str(string: &mut String, num: u64) {
if num >= 10 { if num >= 10 {
add_num_to_str(string, 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'); } else if rem == 9 { add_char(string, '9'); }
} }
/// (deprecated) concatenates two strings to the destination
pub fn concat_strings(destination: &mut String, source: String) { pub fn concat_strings(destination: &mut String, source: String) {
for i in 0 .. (str_length(source.inner) - 1) { for i in 0 .. (str_length(source.inner) - 1) {
add_char(destination, source.inner[i]); 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 { pub fn clamp(min: f32, max: f32, value: f32) -> f32 {
if value > max { if value > max {
return max; return max;
@ -217,6 +240,7 @@ pub fn clamp(min: f32, max: f32, value: f32) -> f32 {
return value; return value;
} }
/// Returns the absolute value of `value`.
pub fn abs(f: f32) -> f32 { pub fn abs(f: f32) -> f32 {
if f < 0.0 { if f < 0.0 {
return f * (0.0 - 1.0); return f * (0.0 - 1.0);

View File

@ -697,8 +697,6 @@ impl Parse for ImportStatement {
impl Parse for FunctionDefinition { impl Parse for FunctionDefinition {
fn parse(mut stream: TokenStream) -> Result<Self, Error> { fn parse(mut stream: TokenStream) -> Result<Self, Error> {
let documentation = stream.find_documentation(); let documentation = stream.find_documentation();
dbg!(&stream.get_range());
dbg!(&documentation);
let is_pub = if let Some(Token::PubKeyword) = stream.peek() { let is_pub = if let Some(Token::PubKeyword) = stream.peek() {
stream.next(); // Consume pub stream.next(); // Consume pub

View File

@ -105,7 +105,6 @@ impl<'a, 'b> TokenStream<'a, 'b> {
break; break;
} }
} }
dbg!(self.position, from, &documentation);
documentation documentation
} }