Compare commits
4 Commits
dcb4e76a40
...
f4bce14299
Author | SHA1 | Date | |
---|---|---|---|
f4bce14299 | |||
aa1de16f4c | |||
89b6fc1a71 | |||
ceee2f286a |
@ -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`
|
||||||
|
@ -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);
|
||||||
|
@ -6,7 +6,7 @@ use reid::{
|
|||||||
lexer::{FullToken, Token},
|
lexer::{FullToken, Token},
|
||||||
token_stream::TokenRange,
|
token_stream::TokenRange,
|
||||||
},
|
},
|
||||||
codegen::intrinsics::get_intrinsic_assoc_functions,
|
codegen::intrinsics::{self, get_intrinsic_assoc_functions},
|
||||||
compile_module,
|
compile_module,
|
||||||
error_raporting::{ErrorModules, ReidError},
|
error_raporting::{ErrorModules, ReidError},
|
||||||
mir::{
|
mir::{
|
||||||
@ -85,7 +85,7 @@ impl StaticAnalysis {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SemanticToken {
|
pub struct SemanticToken {
|
||||||
pub hover: Option<Hover>,
|
pub hover: Hover,
|
||||||
pub autocomplete: Vec<Autocomplete>,
|
pub autocomplete: Vec<Autocomplete>,
|
||||||
pub symbol: Option<SymbolId>,
|
pub symbol: Option<SymbolId>,
|
||||||
}
|
}
|
||||||
@ -162,15 +162,19 @@ impl AnalysisState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AnalysisState {
|
impl AnalysisState {
|
||||||
pub fn init_hover(&mut self, meta: &mir::Metadata, kind: Option<HoverKind>, documentation: Option<String>) {
|
pub fn set_hover_meta(&mut self, meta: &mir::Metadata, hover: Hover) {
|
||||||
for token in meta.range.start..=meta.range.end {
|
for token in meta.range.start..=meta.range.end {
|
||||||
|
self.set_hover(token, hover.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn set_hover(&mut self, token_idx: usize, hover: Hover) {
|
||||||
|
if let Some(token) = self.map.get_mut(&token_idx) {
|
||||||
|
token.hover = hover.clone();
|
||||||
|
} else {
|
||||||
self.map.insert(
|
self.map.insert(
|
||||||
token,
|
token_idx,
|
||||||
SemanticToken {
|
SemanticToken {
|
||||||
hover: Some(Hover {
|
hover: hover.clone(),
|
||||||
documentation: documentation.clone(),
|
|
||||||
kind: kind.clone(),
|
|
||||||
}),
|
|
||||||
autocomplete: Vec::new(),
|
autocomplete: Vec::new(),
|
||||||
symbol: Default::default(),
|
symbol: Default::default(),
|
||||||
},
|
},
|
||||||
@ -185,7 +189,10 @@ impl AnalysisState {
|
|||||||
self.map.insert(
|
self.map.insert(
|
||||||
token_idx,
|
token_idx,
|
||||||
SemanticToken {
|
SemanticToken {
|
||||||
hover: None,
|
hover: Hover {
|
||||||
|
documentation: None,
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
autocomplete: autocomplete.clone(),
|
autocomplete: autocomplete.clone(),
|
||||||
symbol: Default::default(),
|
symbol: Default::default(),
|
||||||
},
|
},
|
||||||
@ -196,22 +203,15 @@ impl AnalysisState {
|
|||||||
pub fn set_documentation(&mut self, token_idx: usize, documentation: Option<String>) {
|
pub fn set_documentation(&mut self, token_idx: usize, documentation: Option<String>) {
|
||||||
if let Some(documentation) = documentation {
|
if let Some(documentation) = documentation {
|
||||||
if let Some(token) = self.map.get_mut(&token_idx) {
|
if let Some(token) = self.map.get_mut(&token_idx) {
|
||||||
if let Some(hover) = &mut token.hover {
|
token.hover.documentation = Some(documentation);
|
||||||
hover.documentation = Some(documentation);
|
|
||||||
} else {
|
|
||||||
token.hover = Some(Hover {
|
|
||||||
documentation: Some(documentation),
|
|
||||||
kind: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
self.map.insert(
|
self.map.insert(
|
||||||
token_idx,
|
token_idx,
|
||||||
SemanticToken {
|
SemanticToken {
|
||||||
hover: Some(Hover {
|
hover: Hover {
|
||||||
documentation: Some(documentation),
|
documentation: Some(documentation),
|
||||||
kind: None,
|
kind: None,
|
||||||
}),
|
},
|
||||||
autocomplete: Vec::new(),
|
autocomplete: Vec::new(),
|
||||||
symbol: Default::default(),
|
symbol: Default::default(),
|
||||||
},
|
},
|
||||||
@ -228,7 +228,10 @@ impl AnalysisState {
|
|||||||
self.map.insert(
|
self.map.insert(
|
||||||
idx,
|
idx,
|
||||||
SemanticToken {
|
SemanticToken {
|
||||||
hover: None,
|
hover: Hover {
|
||||||
|
documentation: None,
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
autocomplete: Vec::new(),
|
autocomplete: Vec::new(),
|
||||||
symbol: Some(symbol),
|
symbol: Some(symbol),
|
||||||
},
|
},
|
||||||
@ -273,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, Option<String>)>,
|
functions: HashMap<String, (SourceModuleId, SymbolId)>,
|
||||||
associated_functions: HashMap<(TypeKind, String), (SourceModuleId, SymbolId, Option<String>)>,
|
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,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,
|
||||||
@ -497,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() {
|
||||||
@ -576,7 +558,7 @@ pub fn analyze_context(
|
|||||||
.token_idx(&field.2, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&field.2, |t| matches!(t, Token::Identifier(_)))
|
||||||
.unwrap_or(field.2.range.end);
|
.unwrap_or(field.2.range.end);
|
||||||
|
|
||||||
scope.state.init_hover(
|
scope.state.set_hover_meta(
|
||||||
&Metadata {
|
&Metadata {
|
||||||
source_module_id: field.2.source_module_id,
|
source_module_id: field.2.source_module_id,
|
||||||
range: TokenRange {
|
range: TokenRange {
|
||||||
@ -585,8 +567,10 @@ pub fn analyze_context(
|
|||||||
},
|
},
|
||||||
position: None,
|
position: None,
|
||||||
},
|
},
|
||||||
Some(HoverKind::Type(field.1.clone())),
|
Hover {
|
||||||
None,
|
kind: Some(HoverKind::Type(field.1.clone())),
|
||||||
|
documentation: None,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let field_symbol = scope.state.new_symbol(field_idx, SemanticKind::Property);
|
let field_symbol = scope.state.new_symbol(field_idx, SemanticKind::Property);
|
||||||
@ -628,7 +612,7 @@ pub fn analyze_context(
|
|||||||
scope.state.new_symbol(field_ty_idx, SemanticKind::Type)
|
scope.state.new_symbol(field_ty_idx, SemanticKind::Type)
|
||||||
};
|
};
|
||||||
|
|
||||||
scope.state.init_hover(
|
scope.state.set_hover_meta(
|
||||||
&Metadata {
|
&Metadata {
|
||||||
source_module_id: field.2.source_module_id,
|
source_module_id: field.2.source_module_id,
|
||||||
range: TokenRange {
|
range: TokenRange {
|
||||||
@ -637,8 +621,10 @@ pub fn analyze_context(
|
|||||||
},
|
},
|
||||||
position: None,
|
position: None,
|
||||||
},
|
},
|
||||||
Some(HoverKind::Type(field.1.clone())),
|
Hover {
|
||||||
None,
|
kind: Some(HoverKind::Type(field.1.clone())),
|
||||||
|
documentation: None,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
scope.state.set_symbol(field_ty_idx, field_ty_symbol);
|
scope.state.set_symbol(field_ty_idx, field_ty_symbol);
|
||||||
}
|
}
|
||||||
@ -649,9 +635,13 @@ pub fn analyze_context(
|
|||||||
for binop in &module.binop_defs {
|
for binop in &module.binop_defs {
|
||||||
if binop.meta.source_module_id == module.module_id {
|
if binop.meta.source_module_id == module.module_id {
|
||||||
for param in [&binop.lhs, &binop.rhs] {
|
for param in [&binop.lhs, &binop.rhs] {
|
||||||
scope
|
scope.state.set_hover_meta(
|
||||||
.state
|
¶m.meta,
|
||||||
.init_hover(¶m.meta, Some(HoverKind::Type(param.ty.clone())), None);
|
Hover {
|
||||||
|
kind: Some(HoverKind::Type(param.ty.clone())),
|
||||||
|
documentation: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(¶m.meta, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(¶m.meta, |t| matches!(t, Token::Identifier(_)))
|
||||||
.unwrap_or(param.meta.range.end);
|
.unwrap_or(param.meta.range.end);
|
||||||
@ -673,9 +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()),
|
||||||
(source_id, *symbol, function.documentation.clone()),
|
Hover {
|
||||||
|
documentation: function.documentation.clone(),
|
||||||
|
kind: Some(HoverKind::Function(
|
||||||
|
function.name.clone(),
|
||||||
|
function.parameters.clone(),
|
||||||
|
function.return_type.clone(),
|
||||||
|
)),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,9 +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()),
|
||||||
(module.module_id, symbol, function.documentation.clone()),
|
Hover {
|
||||||
|
documentation: function.documentation.clone(),
|
||||||
|
kind: Some(HoverKind::Function(
|
||||||
|
function.name.clone(),
|
||||||
|
function.parameters.clone(),
|
||||||
|
function.return_type.clone(),
|
||||||
|
)),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,24 +727,36 @@ 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(
|
scope.functions.insert(function.name.clone(), (source_id, *symbol));
|
||||||
function.name.clone(),
|
|
||||||
(source_id, *symbol, function.documentation.clone()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if source_id != module.module_id {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.state.init_hover(
|
scope.state.set_hover_meta(
|
||||||
&function.signature(),
|
&function.signature(),
|
||||||
Some(HoverKind::Type(function.return_type.clone())),
|
Hover {
|
||||||
function.documentation.clone(),
|
kind: Some(HoverKind::Type(function.return_type.clone())),
|
||||||
|
documentation: None,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let idx = scope
|
let idx = scope
|
||||||
@ -743,10 +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
|
||||||
(module.module_id, function_symbol, function.documentation.clone()),
|
.insert(function.name.clone(), (module.module_id, function_symbol));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for function in &module.functions {
|
for function in &module.functions {
|
||||||
@ -768,7 +789,13 @@ pub fn analyze_context(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for import in &module.imports {
|
for import in &module.imports {
|
||||||
scope.state.init_hover(&import.1, None, None);
|
scope.state.set_hover_meta(
|
||||||
|
&import.1,
|
||||||
|
Hover {
|
||||||
|
kind: None,
|
||||||
|
documentation: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
if let Some((module_name, _)) = import.0.get(0) {
|
if let Some((module_name, _)) = import.0.get(0) {
|
||||||
let module_idx = scope
|
let module_idx = scope
|
||||||
.token_idx(&import.1, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&import.1, |t| matches!(t, Token::Identifier(_)))
|
||||||
@ -810,12 +837,10 @@ pub fn analyze_context(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let symbol = if let Some((source_id, symbol_id, doc)) = 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_documentation(import_idx, doc.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(),
|
||||||
@ -831,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);
|
||||||
}
|
}
|
||||||
@ -850,9 +878,13 @@ pub fn analyze_function_parameters(
|
|||||||
scope: &mut AnalysisScope,
|
scope: &mut AnalysisScope,
|
||||||
) {
|
) {
|
||||||
for param in &function.parameters {
|
for param in &function.parameters {
|
||||||
scope
|
scope.state.set_hover_meta(
|
||||||
.state
|
¶m.meta,
|
||||||
.init_hover(¶m.meta, Some(HoverKind::Type(param.ty.clone())), None);
|
Hover {
|
||||||
|
kind: Some(HoverKind::Type(param.ty.clone())),
|
||||||
|
documentation: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if param.meta.source_module_id == module.module_id {
|
if param.meta.source_module_id == module.module_id {
|
||||||
let param_var_idx = scope
|
let param_var_idx = scope
|
||||||
@ -891,14 +923,16 @@ pub fn analyze_block(
|
|||||||
for statement in &block.statements {
|
for statement in &block.statements {
|
||||||
match &statement.0 {
|
match &statement.0 {
|
||||||
mir::StmtKind::Let(named_variable_ref, _, expression) => {
|
mir::StmtKind::Let(named_variable_ref, _, expression) => {
|
||||||
scope.state.init_hover(
|
scope.state.set_hover_meta(
|
||||||
&named_variable_ref.2,
|
&named_variable_ref.2,
|
||||||
expression
|
Hover {
|
||||||
|
documentation: None,
|
||||||
|
kind: expression
|
||||||
.return_type(&TypeRefs::unknown(), source_module.module_id)
|
.return_type(&TypeRefs::unknown(), source_module.module_id)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|(_, ty)| ty)
|
.map(|(_, ty)| ty)
|
||||||
.map(|t| HoverKind::Type(t)),
|
.map(|t| HoverKind::Type(t)),
|
||||||
None,
|
},
|
||||||
);
|
);
|
||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(&named_variable_ref.2, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&named_variable_ref.2, |t| matches!(t, Token::Identifier(_)))
|
||||||
@ -949,19 +983,26 @@ pub fn analyze_expr(
|
|||||||
expr: &mir::Expression,
|
expr: &mir::Expression,
|
||||||
scope: &mut AnalysisScope,
|
scope: &mut AnalysisScope,
|
||||||
) {
|
) {
|
||||||
scope.state.init_hover(
|
scope.state.set_hover_meta(
|
||||||
&expr.1,
|
&expr.1,
|
||||||
expr.return_type(&TypeRefs::unknown(), source_module.module_id)
|
Hover {
|
||||||
|
documentation: None,
|
||||||
|
kind: expr
|
||||||
|
.return_type(&TypeRefs::unknown(), source_module.module_id)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|(_, t)| HoverKind::Type(t)),
|
.map(|(_, t)| HoverKind::Type(t)),
|
||||||
None,
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
match &expr.0 {
|
match &expr.0 {
|
||||||
mir::ExprKind::Variable(var_ref) => {
|
mir::ExprKind::Variable(var_ref) => {
|
||||||
scope
|
scope.state.set_hover_meta(
|
||||||
.state
|
&var_ref.2,
|
||||||
.init_hover(&var_ref.2, Some(HoverKind::Type(var_ref.0.clone())), None);
|
Hover {
|
||||||
|
documentation: None,
|
||||||
|
kind: Some(HoverKind::Type(var_ref.0.clone())),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(&var_ref.2, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&var_ref.2, |t| matches!(t, Token::Identifier(_)))
|
||||||
@ -1105,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, doc)) = 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_documentation(idx, doc.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,
|
||||||
@ -1139,22 +1182,48 @@ pub fn analyze_expr(
|
|||||||
scope.state.new_symbol(type_idx, SemanticKind::Type)
|
scope.state.new_symbol(type_idx, SemanticKind::Type)
|
||||||
};
|
};
|
||||||
scope.state.set_symbol(type_idx, type_symbol);
|
scope.state.set_symbol(type_idx, type_symbol);
|
||||||
|
scope.state.set_hover(
|
||||||
|
type_idx,
|
||||||
|
Hover {
|
||||||
|
documentation: None,
|
||||||
|
kind: Some(HoverKind::Type(invoked_ty.clone())),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let fn_idx = scope
|
let fn_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 fn_symbol = if let Some((module_id, symbol_id, doc)) =
|
|
||||||
|
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)) =
|
||||||
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_documentation(fn_idx, doc.clone());
|
} else if let Some(intrinsic) = intrinsic_fn {
|
||||||
|
let symbol = scope.state.new_symbol(fn_idx, SemanticKind::Function);
|
||||||
|
scope.state.set_hover(
|
||||||
|
fn_idx,
|
||||||
|
Hover {
|
||||||
|
documentation: intrinsic.documentation.clone(),
|
||||||
|
kind: Some(HoverKind::Function(
|
||||||
|
intrinsic.name.clone(),
|
||||||
|
intrinsic.parameters.clone(),
|
||||||
|
intrinsic.return_type.clone(),
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
);
|
||||||
symbol
|
symbol
|
||||||
} else {
|
} else {
|
||||||
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);
|
||||||
|
@ -213,12 +213,13 @@ impl LanguageServer for Backend {
|
|||||||
character: (end.0 as i32 - 1).max(0) as u32,
|
character: (end.0 as i32 - 1).max(0) as u32,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if let Some(hover) = analysis.hover.clone() {
|
if let Some(kind) = &analysis.hover.kind {
|
||||||
if let Some(kind) = hover.kind {
|
|
||||||
match kind {
|
match kind {
|
||||||
analysis::HoverKind::Type(type_kind) => {
|
analysis::HoverKind::Type(type_kind) => (
|
||||||
(Some(range), format!("{}", type_kind), hover.documentation)
|
Some(range),
|
||||||
}
|
format!("{}", type_kind),
|
||||||
|
analysis.hover.documentation.clone(),
|
||||||
|
),
|
||||||
analysis::HoverKind::Function(name, function_params, return_type) => (
|
analysis::HoverKind::Function(name, function_params, return_type) => (
|
||||||
Some(range),
|
Some(range),
|
||||||
format!(
|
format!(
|
||||||
@ -231,14 +232,15 @@ impl LanguageServer for Backend {
|
|||||||
.join(", "),
|
.join(", "),
|
||||||
return_type
|
return_type
|
||||||
),
|
),
|
||||||
hover.documentation,
|
analysis.hover.documentation.clone(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(Some(range), String::from("No type"), hover.documentation)
|
(
|
||||||
}
|
Some(range),
|
||||||
} else {
|
String::from("No type"),
|
||||||
(Some(range), String::from("No hover"), None)
|
analysis.hover.documentation.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(None, String::from("no type"), None)
|
(None, String::from("no type"), None)
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -105,7 +105,6 @@ impl<'a, 'b> TokenStream<'a, 'b> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbg!(self.position, from, &documentation);
|
|
||||||
documentation
|
documentation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,12 +66,18 @@ pub enum LLVMIntrinsicKind {
|
|||||||
const INTRINSIC_IDENT: &str = "reid.intrinsic";
|
const INTRINSIC_IDENT: &str = "reid.intrinsic";
|
||||||
const MALLOC_IDENT: &str = "malloc";
|
const MALLOC_IDENT: &str = "malloc";
|
||||||
|
|
||||||
|
macro_rules! doc {
|
||||||
|
($str:expr) => {
|
||||||
|
Some($str.to_string())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
||||||
let mut intrinsics = Vec::new();
|
let mut intrinsics = Vec::new();
|
||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: MALLOC_IDENT.to_owned(),
|
name: MALLOC_IDENT.to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Allocates `size` bytes and returns a `u8`-pointer."),
|
||||||
linkage_name: Some("malloc".to_owned()),
|
linkage_name: Some("malloc".to_owned()),
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: true,
|
is_imported: true,
|
||||||
@ -91,13 +97,14 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
pub fn simple_intrinsic<T: Into<String> + Clone>(
|
pub fn simple_intrinsic<T: Into<String> + Clone>(
|
||||||
name: T,
|
name: T,
|
||||||
|
doc: T,
|
||||||
params: Vec<T>,
|
params: Vec<T>,
|
||||||
ret: TypeKind,
|
ret: TypeKind,
|
||||||
intrisic: LLVMIntrinsicKind,
|
intrisic: LLVMIntrinsicKind,
|
||||||
) -> FunctionDefinition {
|
) -> FunctionDefinition {
|
||||||
FunctionDefinition {
|
FunctionDefinition {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: Some(doc.into()),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -117,7 +124,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
if let TypeKind::Array(_, len) = ty {
|
if let TypeKind::Array(_, len) = ty {
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "length".to_owned(),
|
name: "length".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Returns the length of this given array"),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -135,127 +142,147 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
if ty.category() == TypeCategory::Real {
|
if ty.category() == TypeCategory::Real {
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"sqrt",
|
"sqrt",
|
||||||
|
"Calculates the square-root of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Sqrt(ty.clone()),
|
LLVMIntrinsicKind::Sqrt(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"sin",
|
"sin",
|
||||||
|
"Calculates sine of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Sin(ty.clone()),
|
LLVMIntrinsicKind::Sin(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"cos",
|
"cos",
|
||||||
|
"Calculates cosine of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Cos(ty.clone()),
|
LLVMIntrinsicKind::Cos(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"tan",
|
"tan",
|
||||||
|
"Calculates tangent of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Tan(ty.clone()),
|
LLVMIntrinsicKind::Tan(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"sinh",
|
"sinh",
|
||||||
|
"Calculates hyperbolic sine of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::SinH(ty.clone()),
|
LLVMIntrinsicKind::SinH(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"cosh",
|
"cosh",
|
||||||
|
"Calculates hyperbolic cosine of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::CosH(ty.clone()),
|
LLVMIntrinsicKind::CosH(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"tanh",
|
"tanh",
|
||||||
|
"Calculates hyperbolic tangent of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::TanH(ty.clone()),
|
LLVMIntrinsicKind::TanH(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"asin",
|
"asin",
|
||||||
|
"Calculates arcsine of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::ASin(ty.clone()),
|
LLVMIntrinsicKind::ASin(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"acos",
|
"acos",
|
||||||
|
"Calculates arccosine of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::ACos(ty.clone()),
|
LLVMIntrinsicKind::ACos(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"atan",
|
"atan",
|
||||||
|
"Calculates arctangent of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::ATan(ty.clone()),
|
LLVMIntrinsicKind::ATan(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"atan2",
|
"atan2",
|
||||||
|
"Calculates 2-argument arctangent of `value`",
|
||||||
vec!["self", "other"],
|
vec!["self", "other"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::ATan2(ty.clone()),
|
LLVMIntrinsicKind::ATan2(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"log",
|
"log",
|
||||||
|
"Returns logₑ of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Log(ty.clone()),
|
LLVMIntrinsicKind::Log(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"log2",
|
"log2",
|
||||||
|
"Returns log₂ of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Log2(ty.clone()),
|
LLVMIntrinsicKind::Log2(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"log10",
|
"log10",
|
||||||
|
"Returns log₁₀ of `value`",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Log10(ty.clone()),
|
LLVMIntrinsicKind::Log10(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"floor",
|
"floor",
|
||||||
|
"Rounds `value` towards negative infinity.",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Floor(ty.clone()),
|
LLVMIntrinsicKind::Floor(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"ceil",
|
"ceil",
|
||||||
|
"Rounds `value` towards positive infinity.",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Ceil(ty.clone()),
|
LLVMIntrinsicKind::Ceil(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"trunc",
|
"trunc",
|
||||||
|
"Truncates `value` to the integer nearest to `0`.",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Trunc(ty.clone()),
|
LLVMIntrinsicKind::Trunc(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"round",
|
"round",
|
||||||
|
"Rounds `value` to the closest even integer.",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Round(ty.clone()),
|
LLVMIntrinsicKind::Round(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"even",
|
"even",
|
||||||
|
"Rounds `value` to the closest even integer.",
|
||||||
vec!["self"],
|
vec!["self"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::RoundEven(ty.clone()),
|
LLVMIntrinsicKind::RoundEven(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"pow",
|
"pow",
|
||||||
|
"Returns `value` raised to the exponent of `exponent`.",
|
||||||
vec!["self", "exponent"],
|
vec!["self", "exponent"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Pow(ty.clone()),
|
LLVMIntrinsicKind::Pow(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "powi".to_owned(),
|
name: "powi".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Returns `value` raised to the exponent of `exponent`."),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -284,12 +311,14 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
TypeCategory::Integer | TypeCategory::Real | TypeCategory::Bool => {
|
TypeCategory::Integer | TypeCategory::Real | TypeCategory::Bool => {
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"max",
|
"max",
|
||||||
|
"Returns the larger of `a` and `b`.",
|
||||||
vec!["self", "other"],
|
vec!["self", "other"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Max(ty.clone()),
|
LLVMIntrinsicKind::Max(ty.clone()),
|
||||||
));
|
));
|
||||||
intrinsics.push(simple_intrinsic(
|
intrinsics.push(simple_intrinsic(
|
||||||
"min",
|
"min",
|
||||||
|
"Returns the smaller of `a` and `b`.",
|
||||||
vec!["self", "other"],
|
vec!["self", "other"],
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
LLVMIntrinsicKind::Min(ty.clone()),
|
LLVMIntrinsicKind::Min(ty.clone()),
|
||||||
@ -297,7 +326,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
if ty.signed() {
|
if ty.signed() {
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "abs".to_owned(),
|
name: "abs".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Returns the absolute value of `value`."),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -328,7 +357,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
}
|
}
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "sizeof".to_owned(),
|
name: "sizeof".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Simply returns the size of type `T` in bytes."),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -340,7 +369,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
});
|
});
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "malloc".to_owned(),
|
name: "malloc".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Allocates `T::sizeof() * size` bytes and returns a pointer to `T`."),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -357,7 +386,10 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "memcpy".to_owned(),
|
name: "memcpy".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!(
|
||||||
|
"Copies `T::sizeof() * size` bytes from pointer `source` to pointer
|
||||||
|
`destination`."
|
||||||
|
),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -386,7 +418,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "null".to_owned(),
|
name: "null".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Returns a null-pointer of type `T`."),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -399,7 +431,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "is_null".to_owned(),
|
name: "is_null".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
documentation: doc!("Returns a boolean representing if `val` is a nullptr or not."),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user