Refactoring of name-analysis.
This commit is contained in:
parent
c606432be2
commit
abb7aab3a4
@ -1,17 +1,11 @@
|
|||||||
ns greeter
|
ns greeter;
|
||||||
|
|
||||||
fn main(x: String) {
|
class Array<T> {}
|
||||||
let x = 'Hello';
|
|
||||||
let y = 'World';
|
class String {}
|
||||||
{
|
|
||||||
let test = 'test';
|
platform fn println(msg: Any) -> Void;
|
||||||
let x = 'x';
|
|
||||||
let y = 'y';
|
fn main(args: Array<String>) {
|
||||||
let z = 'z';
|
println(args);
|
||||||
let test = 'oops.';
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod test {
|
|
||||||
|
|
||||||
}
|
|
@ -57,12 +57,18 @@ pub enum SuffixUnaryOperator {
|
|||||||
/* Names */
|
/* Names */
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum SavedSymbol {
|
||||||
|
Declaration(Symbol),
|
||||||
|
Linking(Symbol),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Identifier {
|
pub struct Identifier {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub file_id: usize,
|
pub file_id: usize,
|
||||||
pub range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
scope_id: Option<usize>,
|
scope_id: Option<usize>,
|
||||||
symbol: Option<Symbol>,
|
saved_symbol: Option<SavedSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Identifier {
|
impl Identifier {
|
||||||
@ -72,7 +78,7 @@ impl Identifier {
|
|||||||
file_id,
|
file_id,
|
||||||
range,
|
range,
|
||||||
scope_id: None,
|
scope_id: None,
|
||||||
symbol: None,
|
saved_symbol: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,16 +90,12 @@ impl Identifier {
|
|||||||
self.scope_id
|
self.scope_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_symbol(&mut self, symbol: Symbol) {
|
pub fn set_saved_symbol(&mut self, saved_symbol: SavedSymbol) {
|
||||||
self.symbol = Some(symbol);
|
self.saved_symbol = Some(saved_symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn symbol(&self) -> &Option<Symbol> {
|
pub fn saved_symbol(&self) -> Option<SavedSymbol> {
|
||||||
&self.symbol
|
self.saved_symbol.clone()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn symbol_mut(&mut self) -> Option<Symbol> {
|
|
||||||
self.symbol.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,8 +467,6 @@ pub struct UseStatement {
|
|||||||
pub last: UseStatementLast,
|
pub last: UseStatementLast,
|
||||||
pub file_id: usize,
|
pub file_id: usize,
|
||||||
pub range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
scope_id: Option<usize>,
|
|
||||||
symbol: Option<Symbol>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UseStatementImport<'a> {
|
pub struct UseStatementImport<'a> {
|
||||||
@ -487,8 +487,6 @@ impl UseStatement {
|
|||||||
last,
|
last,
|
||||||
file_id,
|
file_id,
|
||||||
range,
|
range,
|
||||||
scope_id: None,
|
|
||||||
symbol: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,22 +517,6 @@ impl UseStatement {
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_scope_id(&mut self, scope_id: usize) {
|
|
||||||
self.scope_id = Some(scope_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scope_id(&self) -> Option<usize> {
|
|
||||||
self.scope_id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_symbol(&mut self, symbol: Symbol) {
|
|
||||||
self.symbol = Some(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn symbol(&self) -> &Option<Symbol> {
|
|
||||||
&self.symbol
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -6,6 +6,7 @@ use crate::name_analysis::symbol::*;
|
|||||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::ops::DerefMut;
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -41,6 +42,10 @@ fn handle_insert_error(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gather_identifier(identifier: &mut Identifier, symbol_table: &mut SymbolTable) {
|
||||||
|
identifier.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
}
|
||||||
|
|
||||||
fn gather_fully_qualified_name(
|
fn gather_fully_qualified_name(
|
||||||
fully_qualified_name: &mut FullyQualifiedName,
|
fully_qualified_name: &mut FullyQualifiedName,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -153,28 +158,30 @@ fn handle_use_statement_import(
|
|||||||
&declared_name,
|
&declared_name,
|
||||||
Some(identifier.clone()),
|
Some(identifier.clone()),
|
||||||
));
|
));
|
||||||
if let Err(err) = insert_result {
|
|
||||||
handle_insert_error(
|
match insert_result {
|
||||||
err,
|
Ok(use_statement_symbol) => {
|
||||||
&declared_name,
|
drop(borrowed_identifier);
|
||||||
borrowed_identifier.file_id,
|
|
||||||
borrowed_identifier.range,
|
let mut mutable_borrowed_identifier = identifier.borrow_mut();
|
||||||
"Use statement",
|
|
||||||
diagnostics,
|
gather_identifier(mutable_borrowed_identifier.deref_mut(), symbol_table);
|
||||||
);
|
|
||||||
|
mutable_borrowed_identifier.set_saved_symbol(SavedSymbol::Linking(
|
||||||
|
Symbol::UseStatement(use_statement_symbol),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
handle_insert_error(
|
||||||
|
err,
|
||||||
|
&declared_name,
|
||||||
|
borrowed_identifier.file_id,
|
||||||
|
borrowed_identifier.range,
|
||||||
|
"Use statement",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drop(borrowed_identifier);
|
|
||||||
let mut mutable_borrowed_identifier = identifier.borrow_mut();
|
|
||||||
mutable_borrowed_identifier.set_scope_id(symbol_table.current_scope_id());
|
|
||||||
|
|
||||||
let use_statement_symbol = symbol_table
|
|
||||||
.lookup(
|
|
||||||
&declared_name,
|
|
||||||
mutable_borrowed_identifier.scope_id().unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
mutable_borrowed_identifier.set_symbol(use_statement_symbol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_use_statement(
|
fn gather_use_statement(
|
||||||
@ -321,30 +328,55 @@ fn gather_function_definition(
|
|||||||
Some(&function.identifier),
|
Some(&function.identifier),
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Err(err) = insert_result {
|
match insert_result {
|
||||||
handle_insert_error(
|
Ok(function_symbol) => {
|
||||||
err,
|
function
|
||||||
&declared_name,
|
.identifier
|
||||||
function.identifier.file_id,
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
function.identifier.range,
|
|
||||||
"function/variable",
|
symbol_table.push_scope(&format!("FunctionParameterScope({})", resolved_name));
|
||||||
diagnostics,
|
|
||||||
)
|
let parameters_result = gather_parameters(
|
||||||
|
&mut function.parameters,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
match parameters_result {
|
||||||
|
Some(parameter_symbols) => {
|
||||||
|
function_symbol
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parameters(parameter_symbols);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
gather_return_type(
|
||||||
|
&mut function.return_type,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
symbol_table.push_scope(&format!("FunctionBodyScope({})", resolved_name));
|
||||||
|
|
||||||
|
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
|
||||||
|
|
||||||
|
symbol_table.pop_scope(); // body
|
||||||
|
symbol_table.pop_scope(); // parameters
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
handle_insert_error(
|
||||||
|
err,
|
||||||
|
&declared_name,
|
||||||
|
function.identifier.file_id,
|
||||||
|
function.identifier.range,
|
||||||
|
"function/variable",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
|
||||||
.identifier
|
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("FunctionScope({})", resolved_name));
|
|
||||||
gather_parameters(
|
|
||||||
&mut function.parameters,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
|
|
||||||
symbol_table.pop_scope();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_platform_function_definition(
|
fn gather_platform_function_definition(
|
||||||
@ -364,31 +396,56 @@ fn gather_platform_function_definition(
|
|||||||
Some(&platform_function_declaration.identifier),
|
Some(&platform_function_declaration.identifier),
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Err(err) = insert_result {
|
match insert_result {
|
||||||
handle_insert_error(
|
Ok(function_symbol) => {
|
||||||
err,
|
let declared_name_as_string =
|
||||||
&declared_name,
|
platform_function_declaration.identifier.name().to_string();
|
||||||
platform_function_declaration.identifier.file_id,
|
|
||||||
platform_function_declaration.identifier.range,
|
platform_function_declaration
|
||||||
"(Platform-) Function",
|
.identifier
|
||||||
diagnostics,
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
);
|
|
||||||
|
symbol_table.push_scope(&format!(
|
||||||
|
"FunctionParameterScope({})",
|
||||||
|
declared_name_as_string
|
||||||
|
));
|
||||||
|
|
||||||
|
let parameter_symbols_result = gather_parameters(
|
||||||
|
&mut platform_function_declaration.parameters,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
match parameter_symbols_result {
|
||||||
|
Some(parameter_symbols) => {
|
||||||
|
function_symbol
|
||||||
|
.borrow_mut()
|
||||||
|
.set_parameters(parameter_symbols);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
gather_return_type(
|
||||||
|
&mut platform_function_declaration.return_type,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
handle_insert_error(
|
||||||
|
err,
|
||||||
|
&declared_name,
|
||||||
|
platform_function_declaration.identifier.file_id,
|
||||||
|
platform_function_declaration.identifier.range,
|
||||||
|
"(Platform-) Function",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let declared_name_as_string = platform_function_declaration.identifier.name().to_string();
|
|
||||||
|
|
||||||
platform_function_declaration
|
|
||||||
.identifier
|
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("FunctionScope({})", declared_name_as_string));
|
|
||||||
gather_parameters(
|
|
||||||
&mut platform_function_declaration.parameters,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
symbol_table.pop_scope();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_parameters(
|
fn gather_parameters(
|
||||||
@ -396,10 +453,12 @@ fn gather_parameters(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) -> Option<Vec<Rc<ParameterSymbol>>> {
|
||||||
for parameter in &mut parameters.0 {
|
parameters
|
||||||
gather_parameter(parameter, symbol_table, fqn_context, diagnostics);
|
.0
|
||||||
}
|
.iter_mut()
|
||||||
|
.map(|parameter| gather_parameter(parameter, symbol_table, fqn_context, diagnostics))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_parameter(
|
fn gather_parameter(
|
||||||
@ -407,7 +466,7 @@ fn gather_parameter(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) -> Option<Rc<ParameterSymbol>> {
|
||||||
let parameter_name = parameter.identifier.name();
|
let parameter_name = parameter.identifier.name();
|
||||||
|
|
||||||
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
|
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
|
||||||
@ -415,27 +474,63 @@ fn gather_parameter(
|
|||||||
Some(¶meter.identifier),
|
Some(¶meter.identifier),
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Err(err) = insert_result {
|
match insert_result {
|
||||||
handle_insert_error(
|
Ok(parameter_symbol) => {
|
||||||
err,
|
parameter
|
||||||
¶meter_name,
|
.identifier
|
||||||
parameter.identifier.file_id,
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
parameter.identifier.range,
|
|
||||||
"function/variable",
|
gather_type_use(
|
||||||
diagnostics,
|
&mut parameter.type_use,
|
||||||
)
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
Some(parameter_symbol)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
handle_insert_error(
|
||||||
|
err,
|
||||||
|
¶meter_name,
|
||||||
|
parameter.identifier.file_id,
|
||||||
|
parameter.identifier.range,
|
||||||
|
"function/variable",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parameter
|
fn gather_return_type(
|
||||||
.identifier
|
return_type: &mut ReturnType,
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
gather_type_use(
|
gather_type_use(
|
||||||
&mut parameter.type_use,
|
&mut return_type.declared_type,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
)
|
);
|
||||||
|
gather_references(
|
||||||
|
&mut return_type.references,
|
||||||
|
symbol_table,
|
||||||
|
fqn_context,
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_references(
|
||||||
|
references: &mut References,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
for identifier in &mut references.0 {
|
||||||
|
gather_identifier(identifier, symbol_table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_function_body(
|
fn gather_function_body(
|
||||||
@ -673,7 +768,7 @@ fn gather_object_access(
|
|||||||
gather_expression(index_expression, symbol_table, diagnostics);
|
gather_expression(index_expression, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
ObjectNavigation::Identifier(identifier) => {
|
ObjectNavigation::Identifier(identifier) => {
|
||||||
identifier.set_scope_id(symbol_table.current_scope_id());
|
gather_identifier(identifier, symbol_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,10 +105,6 @@ mod tests {
|
|||||||
"main.dm",
|
"main.dm",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
use test::Greeter;
|
use test::Greeter;
|
||||||
|
|
||||||
fn main(args: Array<String>) {
|
|
||||||
println(\"Hello, World!\");
|
|
||||||
}
|
|
||||||
"},
|
"},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -123,4 +119,18 @@ mod tests {
|
|||||||
|
|
||||||
assert_no_diagnostics(sources);
|
assert_no_diagnostics(sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sees_std_core_println() {
|
||||||
|
let sources: HashMap<&str, &str> = HashMap::from([(
|
||||||
|
"main.dm",
|
||||||
|
indoc! {"
|
||||||
|
fn main(args: Array<String>) {
|
||||||
|
println(args)
|
||||||
|
}
|
||||||
|
"},
|
||||||
|
)]);
|
||||||
|
|
||||||
|
assert_no_diagnostics(sources);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ use crate::ast::*;
|
|||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::symbol_table::SymbolTable;
|
use crate::name_analysis::symbol_table::SymbolTable;
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::range::Range;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
fn resolve_fully_qualified_name(
|
fn resolve_fully_qualified_name(
|
||||||
fully_qualified_name: &mut FullyQualifiedName,
|
fully_qualified_name: &mut FullyQualifiedName,
|
||||||
@ -152,44 +155,74 @@ fn resolve_references(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_use_statement_identifier(
|
||||||
|
identifier: &Rc<RefCell<Identifier>>,
|
||||||
|
base_name: &str,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
file_id: usize,
|
||||||
|
error_range: Range<usize>,
|
||||||
|
) {
|
||||||
|
let borrowed_identifier = identifier.borrow();
|
||||||
|
let declared_name = borrowed_identifier.name().to_string();
|
||||||
|
let fqn = format!("{}::{}", base_name, &declared_name);
|
||||||
|
let lookup_result =
|
||||||
|
symbol_table.lookup_usable_by_fqn(&fqn, borrowed_identifier.scope_id().unwrap());
|
||||||
|
|
||||||
|
match lookup_result {
|
||||||
|
Ok(referenced_symbol) => match borrowed_identifier.saved_symbol() {
|
||||||
|
Some(saved_symbol) => match saved_symbol {
|
||||||
|
SavedSymbol::Linking(symbol) => {
|
||||||
|
let use_statement_symbol = symbol.unwrap_use_statement_symbol();
|
||||||
|
use_statement_symbol
|
||||||
|
.borrow_mut()
|
||||||
|
.set_referenced_symbol(referenced_symbol);
|
||||||
|
}
|
||||||
|
_ => panic!("Expected to find SavedSymbol::Linking."),
|
||||||
|
},
|
||||||
|
None => panic!("Expected to find saved_symbol"),
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
diagnostics.push(
|
||||||
|
Diagnostic::error()
|
||||||
|
.with_message(&format!("Unable to find symbol '{}'.", fqn))
|
||||||
|
.with_label(Label::primary(file_id, error_range)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_use_statement(
|
fn resolve_use_statement(
|
||||||
use_statement: &mut UseStatement,
|
use_statement: &mut UseStatement,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
if use_statement.is_star() {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
let base_name = use_statement.base_name().to_string();
|
let base_name = use_statement.base_name().to_string();
|
||||||
|
|
||||||
match &use_statement.last {
|
match &use_statement.last {
|
||||||
UseStatementLast::Identifier(identifier) => {
|
UseStatementLast::Identifier(identifier) => {
|
||||||
let borrowed_identifier = identifier.borrow();
|
handle_use_statement_identifier(
|
||||||
let declared_name = borrowed_identifier.name().to_string();
|
identifier,
|
||||||
let fqn = format!("{}::{}", &base_name, &declared_name);
|
&base_name,
|
||||||
let lookup_result =
|
symbol_table,
|
||||||
symbol_table.lookup_usable_by_fqn(&fqn, borrowed_identifier.scope_id().unwrap());
|
diagnostics,
|
||||||
drop(borrowed_identifier);
|
use_statement.file_id,
|
||||||
|
use_statement.range,
|
||||||
if let Err(_) = lookup_result {
|
);
|
||||||
diagnostics.push(
|
}
|
||||||
Diagnostic::error()
|
UseStatementLast::Identifiers(identifiers) => {
|
||||||
.with_message(&format!("Unable to find symbol '{}'.", fqn))
|
for identifier in identifiers {
|
||||||
.with_label(Label::primary(use_statement.file_id, use_statement.range)),
|
handle_use_statement_identifier(
|
||||||
);
|
identifier,
|
||||||
} else {
|
&base_name,
|
||||||
let mut mutable_borrowed_identifier = identifier.borrow_mut();
|
symbol_table,
|
||||||
let use_statement_symbol = mutable_borrowed_identifier
|
diagnostics,
|
||||||
.symbol_mut()
|
use_statement.file_id,
|
||||||
.unwrap()
|
identifier.borrow().range,
|
||||||
.unwrap_use_statement_symbol();
|
)
|
||||||
let mut mutable_borrowed_use_statement_symbol = use_statement_symbol.borrow_mut();
|
|
||||||
mutable_borrowed_use_statement_symbol.set_referenced_symbol(lookup_result.unwrap())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UseStatementLast::Identifiers(identifiers) => {}
|
UseStatementLast::Star => todo!(),
|
||||||
UseStatementLast::Star => panic!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use crate::ast::{Identifier, UseStatement};
|
use crate::ast::{Identifier, UseStatement};
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -17,7 +17,7 @@ impl SourceDefinition {
|
|||||||
range: identifier.range,
|
range: identifier.range,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_identifier_rc(identifier: Rc<RefCell<Identifier>>) -> Self {
|
pub fn from_identifier_rc(identifier: Rc<RefCell<Identifier>>) -> Self {
|
||||||
let borrowed = identifier.borrow();
|
let borrowed = identifier.borrow();
|
||||||
SourceDefinition {
|
SourceDefinition {
|
||||||
@ -55,7 +55,7 @@ pub enum Symbol {
|
|||||||
UseStatement(Rc<RefCell<UseStatementSymbol>>),
|
UseStatement(Rc<RefCell<UseStatementSymbol>>),
|
||||||
Module(Rc<ModuleSymbol>),
|
Module(Rc<ModuleSymbol>),
|
||||||
Type(Rc<TypeSymbol>),
|
Type(Rc<TypeSymbol>),
|
||||||
Function(Rc<FunctionSymbol>),
|
Function(Rc<RefCell<FunctionSymbol>>),
|
||||||
Parameter(Rc<ParameterSymbol>),
|
Parameter(Rc<ParameterSymbol>),
|
||||||
Variable(Rc<VariableSymbol>),
|
Variable(Rc<VariableSymbol>),
|
||||||
}
|
}
|
||||||
@ -63,15 +63,15 @@ pub enum Symbol {
|
|||||||
impl Symbol {
|
impl Symbol {
|
||||||
pub fn definition(&self) -> Option<SourceDefinition> {
|
pub fn definition(&self) -> Option<SourceDefinition> {
|
||||||
match self {
|
match self {
|
||||||
Symbol::UseStatement(s) => s.borrow().definition.clone(),
|
Symbol::UseStatement(s) => s.borrow().definition(),
|
||||||
Symbol::Module(s) => s.definition(),
|
Symbol::Module(s) => s.definition(),
|
||||||
Symbol::Type(s) => s.definition(),
|
Symbol::Type(s) => s.definition(),
|
||||||
Symbol::Function(s) => s.definition(),
|
Symbol::Function(s) => s.borrow().definition(),
|
||||||
Symbol::Parameter(s) => s.definition(),
|
Symbol::Parameter(s) => s.definition(),
|
||||||
Symbol::Variable(s) => s.definition(),
|
Symbol::Variable(s) => s.definition(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_use_statement_symbol(&self) -> Rc<RefCell<UseStatementSymbol>> {
|
pub fn unwrap_use_statement_symbol(&self) -> Rc<RefCell<UseStatementSymbol>> {
|
||||||
match self {
|
match self {
|
||||||
Symbol::UseStatement(s) => s.clone(),
|
Symbol::UseStatement(s) => s.clone(),
|
||||||
@ -87,7 +87,7 @@ impl Display for Symbol {
|
|||||||
UseStatement(use_statement_symbol) => write!(f, "{}", use_statement_symbol.borrow()),
|
UseStatement(use_statement_symbol) => write!(f, "{}", use_statement_symbol.borrow()),
|
||||||
Module(module_symbol) => write!(f, "{}", module_symbol),
|
Module(module_symbol) => write!(f, "{}", module_symbol),
|
||||||
Type(class_symbol) => write!(f, "{}", class_symbol),
|
Type(class_symbol) => write!(f, "{}", class_symbol),
|
||||||
Function(function_symbol) => write!(f, "{}", function_symbol),
|
Function(function_symbol) => write!(f, "{}", function_symbol.borrow()),
|
||||||
Parameter(parameter_symbol) => write!(f, "{}", parameter_symbol),
|
Parameter(parameter_symbol) => write!(f, "{}", parameter_symbol),
|
||||||
Variable(variable_symbol) => write!(f, "{}", variable_symbol),
|
Variable(variable_symbol) => write!(f, "{}", variable_symbol),
|
||||||
}
|
}
|
||||||
@ -101,11 +101,15 @@ pub struct UseStatementSymbol {
|
|||||||
pub fqn: String,
|
pub fqn: String,
|
||||||
pub declared_name: String,
|
pub declared_name: String,
|
||||||
definition: Option<SourceDefinition>,
|
definition: Option<SourceDefinition>,
|
||||||
referenced_symbol: Option<Box<Symbol>>
|
referenced_symbol: Option<Box<Symbol>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UseStatementSymbol {
|
impl UseStatementSymbol {
|
||||||
pub fn new(fqn: &str, declared_name: &str, identifier: Option<Rc<RefCell<Identifier>>>) -> Self {
|
pub fn new(
|
||||||
|
fqn: &str,
|
||||||
|
declared_name: &str,
|
||||||
|
identifier: Option<Rc<RefCell<Identifier>>>,
|
||||||
|
) -> Self {
|
||||||
UseStatementSymbol {
|
UseStatementSymbol {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
@ -143,7 +147,6 @@ impl Display for UseStatementSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Module */
|
/* Module */
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -201,7 +204,12 @@ pub struct TypeSymbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TypeSymbol {
|
impl TypeSymbol {
|
||||||
pub fn new(fqn: &str, declared_name: &str, is_public: bool, identifier: Option<&Identifier>) -> Self {
|
pub fn new(
|
||||||
|
fqn: &str,
|
||||||
|
declared_name: &str,
|
||||||
|
is_public: bool,
|
||||||
|
identifier: Option<&Identifier>,
|
||||||
|
) -> Self {
|
||||||
TypeSymbol {
|
TypeSymbol {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
@ -248,6 +256,8 @@ pub struct FunctionSymbol {
|
|||||||
is_public: bool,
|
is_public: bool,
|
||||||
is_platform: bool,
|
is_platform: bool,
|
||||||
definition: Option<SourceDefinition>,
|
definition: Option<SourceDefinition>,
|
||||||
|
parameters: Vec<Rc<ParameterSymbol>>,
|
||||||
|
return_type: Option<Rc<TypeSymbol>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionSymbol {
|
impl FunctionSymbol {
|
||||||
@ -264,19 +274,53 @@ impl FunctionSymbol {
|
|||||||
is_public,
|
is_public,
|
||||||
is_platform,
|
is_platform,
|
||||||
definition: identifier.map(SourceDefinition::from_identifier),
|
definition: identifier.map(SourceDefinition::from_identifier),
|
||||||
|
parameters: Vec::new(),
|
||||||
|
return_type: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_parameters(self, parameters: Vec<ParameterSymbol>) -> Self {
|
||||||
|
Self {
|
||||||
|
fqn: self.fqn,
|
||||||
|
declared_name: self.declared_name,
|
||||||
|
is_public: self.is_public,
|
||||||
|
is_platform: self.is_platform,
|
||||||
|
definition: self.definition,
|
||||||
|
parameters: parameters.into_iter().map(|parameter| Rc::new(parameter)).collect(),
|
||||||
|
return_type: self.return_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_return_type(self, return_type: TypeSymbol) -> Self {
|
||||||
|
Self {
|
||||||
|
fqn: self.fqn,
|
||||||
|
declared_name: self.declared_name,
|
||||||
|
is_public: self.is_public,
|
||||||
|
is_platform: self.is_platform,
|
||||||
|
definition: self.definition,
|
||||||
|
parameters: self.parameters,
|
||||||
|
return_type: Some(Rc::new(return_type)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fqn(&self) -> &str {
|
pub fn fqn(&self) -> &str {
|
||||||
&self.fqn
|
&self.fqn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_parameters(&mut self, parameters: Vec<Rc<ParameterSymbol>>) {
|
||||||
|
self.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_return_type(&mut self, return_type: Rc<TypeSymbol>) {
|
||||||
|
self.return_type = Some(return_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymbolInner for FunctionSymbol {
|
impl SymbolInner for FunctionSymbol {
|
||||||
fn declared_name(&self) -> &str {
|
fn declared_name(&self) -> &str {
|
||||||
self.declared_name.as_str()
|
self.declared_name.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
fn definition(&self) -> Option<SourceDefinition> {
|
||||||
self.definition.clone()
|
self.definition.clone()
|
||||||
}
|
}
|
||||||
@ -313,7 +357,7 @@ impl SymbolInner for ParameterSymbol {
|
|||||||
fn declared_name(&self) -> &str {
|
fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
fn definition(&self) -> Option<SourceDefinition> {
|
||||||
self.definition.clone()
|
self.definition.clone()
|
||||||
}
|
}
|
||||||
@ -321,11 +365,7 @@ impl SymbolInner for ParameterSymbol {
|
|||||||
|
|
||||||
impl Display for ParameterSymbol {
|
impl Display for ParameterSymbol {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(
|
write!(f, "ParameterSymbol({})", self.declared_name)
|
||||||
f,
|
|
||||||
"ParameterSymbol({})",
|
|
||||||
self.declared_name
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +392,7 @@ impl SymbolInner for VariableSymbol {
|
|||||||
fn declared_name(&self) -> &str {
|
fn declared_name(&self) -> &str {
|
||||||
self.declared_name.as_str()
|
self.declared_name.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn definition(&self) -> Option<SourceDefinition> {
|
fn definition(&self) -> Option<SourceDefinition> {
|
||||||
self.definition.clone()
|
self.definition.clone()
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ struct Scope {
|
|||||||
use_statement_symbols: HashMap<String, Rc<RefCell<UseStatementSymbol>>>,
|
use_statement_symbols: HashMap<String, Rc<RefCell<UseStatementSymbol>>>,
|
||||||
module_symbols: HashMap<String, Rc<ModuleSymbol>>,
|
module_symbols: HashMap<String, Rc<ModuleSymbol>>,
|
||||||
type_symbols: HashMap<String, Rc<TypeSymbol>>,
|
type_symbols: HashMap<String, Rc<TypeSymbol>>,
|
||||||
function_symbols: HashMap<String, Rc<FunctionSymbol>>,
|
function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>,
|
||||||
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
|
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
|
||||||
variable_symbols: HashMap<String, Rc<VariableSymbol>>,
|
variable_symbols: HashMap<String, Rc<VariableSymbol>>,
|
||||||
debug_name: String,
|
debug_name: String,
|
||||||
@ -57,7 +57,7 @@ impl Scope {
|
|||||||
|
|
||||||
fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
fn get_usable_symbol_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
||||||
for function_symbol in self.function_symbols.values() {
|
for function_symbol in self.function_symbols.values() {
|
||||||
if function_symbol.fqn() == fqn {
|
if function_symbol.borrow().fqn() == fqn {
|
||||||
return Some(Symbol::Function(function_symbol.clone()));
|
return Some(Symbol::Function(function_symbol.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ impl Scope {
|
|||||||
|
|
||||||
fn get_usable_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> {
|
fn get_usable_symbol_by_declared_name(&self, declared_name: &str) -> Option<Symbol> {
|
||||||
for function_symbol in self.function_symbols.values() {
|
for function_symbol in self.function_symbols.values() {
|
||||||
if function_symbol.declared_name() == declared_name {
|
if function_symbol.borrow().declared_name() == declared_name {
|
||||||
return Some(Symbol::Function(function_symbol.clone()));
|
return Some(Symbol::Function(function_symbol.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,18 +152,21 @@ impl SymbolTable {
|
|||||||
pub fn insert_use_statement_symbol(
|
pub fn insert_use_statement_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
use_statement_symbol: UseStatementSymbol,
|
use_statement_symbol: UseStatementSymbol,
|
||||||
) -> Result<(), SymbolInsertError> {
|
) -> Result<Rc<RefCell<UseStatementSymbol>>, SymbolInsertError> {
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) =
|
||||||
current_scope.get_usable_symbol_by_declared_name(use_statement_symbol.declared_name())
|
current_scope.get_usable_symbol_by_declared_name(use_statement_symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
} else {
|
} else {
|
||||||
|
let declared_name = use_statement_symbol.declared_name().to_string();
|
||||||
|
let to_insert = Rc::new(RefCell::new(use_statement_symbol));
|
||||||
|
let to_return = to_insert.clone();
|
||||||
current_scope.use_statement_symbols.insert(
|
current_scope.use_statement_symbols.insert(
|
||||||
use_statement_symbol.declared_name().to_string(),
|
declared_name,
|
||||||
Rc::new(RefCell::new(use_statement_symbol)),
|
to_insert,
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(to_return)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,36 +206,41 @@ impl SymbolTable {
|
|||||||
pub fn insert_function_symbol(
|
pub fn insert_function_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
function_symbol: FunctionSymbol,
|
function_symbol: FunctionSymbol,
|
||||||
) -> Result<(), SymbolInsertError> {
|
) -> Result<Rc<RefCell<FunctionSymbol>>, SymbolInsertError> {
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) =
|
||||||
current_scope.get_usable_symbol_by_declared_name(function_symbol.declared_name())
|
current_scope.get_usable_symbol_by_declared_name(function_symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
} else {
|
} else {
|
||||||
|
let declared_name = function_symbol.declared_name().to_string();
|
||||||
|
let to_insert = Rc::new(RefCell::new(function_symbol));
|
||||||
|
let to_return = to_insert.clone();
|
||||||
current_scope.function_symbols.insert(
|
current_scope.function_symbols.insert(
|
||||||
function_symbol.declared_name().to_string(),
|
declared_name,
|
||||||
Rc::new(function_symbol),
|
to_insert
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(to_return)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_parameter_symbol(
|
pub fn insert_parameter_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
parameter_symbol: ParameterSymbol,
|
parameter_symbol: ParameterSymbol,
|
||||||
) -> Result<(), SymbolInsertError> {
|
) -> Result<Rc<ParameterSymbol>, SymbolInsertError> {
|
||||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) =
|
||||||
current_scope.get_value_symbol_by_declared_name(parameter_symbol.declared_name())
|
current_scope.get_value_symbol_by_declared_name(parameter_symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
} else {
|
} else {
|
||||||
|
let to_insert = Rc::new(parameter_symbol);
|
||||||
|
let to_return = to_insert.clone();
|
||||||
current_scope.parameter_symbols.insert(
|
current_scope.parameter_symbols.insert(
|
||||||
parameter_symbol.declared_name().to_string(),
|
to_insert.declared_name().to_string(),
|
||||||
Rc::new(parameter_symbol),
|
to_insert,
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(to_return)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +306,9 @@ impl Display for SymbolTable {
|
|||||||
writeln!(f, " {}({})", name, symbol)?;
|
writeln!(f, " {}({})", name, symbol)?;
|
||||||
}
|
}
|
||||||
for (name, symbol) in &scope.function_symbols {
|
for (name, symbol) in &scope.function_symbols {
|
||||||
|
writeln!(f, " {}({})", name, symbol.borrow())?;
|
||||||
|
}
|
||||||
|
for (name, symbol) in &scope.parameter_symbols {
|
||||||
writeln!(f, " {}({})", name, symbol)?;
|
writeln!(f, " {}({})", name, symbol)?;
|
||||||
}
|
}
|
||||||
for (name, symbol) in &scope.variable_symbols {
|
for (name, symbol) in &scope.variable_symbols {
|
||||||
|
@ -1,23 +1,17 @@
|
|||||||
use crate::name_analysis::symbol::{FunctionSymbol, TypeSymbol};
|
use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol, TypeSymbol};
|
||||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
|
|
||||||
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
||||||
symbol_table.insert_type_symbol(TypeSymbol::new("std::core:Array", "Array", true, None))?;
|
symbol_table.insert_type_symbol(TypeSymbol::new("std::core:Array", "Array", true, None))?;
|
||||||
// todo: make this primitive
|
// todo: make this primitive
|
||||||
symbol_table.insert_type_symbol(TypeSymbol::new("std::core::String", "String", true, None))?;
|
symbol_table.insert_type_symbol(TypeSymbol::new("std::core::String", "String", true, None))?;
|
||||||
symbol_table.insert_function_symbol(FunctionSymbol::new(
|
symbol_table.insert_function_symbol(
|
||||||
"std::core::println",
|
FunctionSymbol::new("std::core::println", "println", true, true, None)
|
||||||
"println",
|
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||||
true,
|
)?;
|
||||||
true,
|
symbol_table.insert_function_symbol(
|
||||||
None,
|
FunctionSymbol::new("std::core::print", "print", true, true, None)
|
||||||
))?;
|
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
||||||
symbol_table.insert_function_symbol(FunctionSymbol::new(
|
)?;
|
||||||
"std::core::print",
|
|
||||||
"print",
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
None,
|
|
||||||
))?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user