Compare commits
No commits in common. "f614d00575eb8f42fc9115b8759afda26c7542e8" and "c606432be2d482e806e8970fe8ec750e9de6b34a" have entirely different histories.
f614d00575
...
c606432be2
@ -1,5 +1,17 @@
|
|||||||
ns greeter;
|
ns greeter
|
||||||
|
|
||||||
|
fn main(x: String) {
|
||||||
|
let x = 'Hello';
|
||||||
|
let y = 'World';
|
||||||
|
{
|
||||||
|
let test = 'test';
|
||||||
|
let x = 'x';
|
||||||
|
let y = 'y';
|
||||||
|
let z = 'z';
|
||||||
|
let test = 'oops.';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod test {
|
||||||
|
|
||||||
fn main(args: Array<String>) {
|
|
||||||
println(args);
|
|
||||||
}
|
}
|
@ -1,7 +0,0 @@
|
|||||||
ns std::core;
|
|
||||||
|
|
||||||
class Array<T> {}
|
|
||||||
|
|
||||||
class String {}
|
|
||||||
|
|
||||||
platform fn println(msg: Any) -> Void;
|
|
@ -1 +1,3 @@
|
|||||||
|
use std::core::println;
|
||||||
|
use std::core::*;
|
||||||
use std::core::{print, println};
|
use std::core::{print, println};
|
||||||
|
@ -55,9 +55,7 @@ fn build_fqn(file_id: usize, fqn_pair: Pair<Rule>) -> FullyQualifiedName {
|
|||||||
fn build_type_use(file_id: usize, type_use_pair: Pair<Rule>) -> TypeUse {
|
fn build_type_use(file_id: usize, type_use_pair: Pair<Rule>) -> TypeUse {
|
||||||
let inner_pair = type_use_pair.into_inner().next().unwrap();
|
let inner_pair = type_use_pair.into_inner().next().unwrap();
|
||||||
match inner_pair.as_rule() {
|
match inner_pair.as_rule() {
|
||||||
Rule::PrimitiveType => {
|
Rule::Void => TypeUse::Void,
|
||||||
TypeUse::Primitive(build_primitive_type(file_id, inner_pair))
|
|
||||||
},
|
|
||||||
Rule::InterfaceOrClassTypeUse => {
|
Rule::InterfaceOrClassTypeUse => {
|
||||||
TypeUse::InterfaceOrClass(build_interface_or_class_type_use(file_id, inner_pair))
|
TypeUse::InterfaceOrClass(build_interface_or_class_type_use(file_id, inner_pair))
|
||||||
}
|
}
|
||||||
@ -67,35 +65,6 @@ fn build_type_use(file_id: usize, type_use_pair: Pair<Rule>) -> TypeUse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_primitive_type(
|
|
||||||
file_id: usize,
|
|
||||||
primitive_type_pair: Pair<Rule>,
|
|
||||||
) -> PrimitiveTypeUse {
|
|
||||||
let mut inner = primitive_type_pair.into_inner();
|
|
||||||
match inner.next().unwrap().as_rule() {
|
|
||||||
Rule::Byte => PrimitiveTypeUse::Byte,
|
|
||||||
Rule::Short => PrimitiveTypeUse::Short,
|
|
||||||
Rule::Char => PrimitiveTypeUse::Char,
|
|
||||||
Rule::Int => PrimitiveTypeUse::Int,
|
|
||||||
Rule::Long => PrimitiveTypeUse::Long,
|
|
||||||
Rule::Double => PrimitiveTypeUse::Double,
|
|
||||||
Rule::Bool => PrimitiveTypeUse::Bool,
|
|
||||||
Rule::String => PrimitiveTypeUse::String,
|
|
||||||
Rule::Array => {
|
|
||||||
if let Some(generic_arguments_pair) = inner.next() {
|
|
||||||
PrimitiveTypeUse::Array(
|
|
||||||
Some(Box::new(build_generic_arguments(file_id, generic_arguments_pair)))
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
PrimitiveTypeUse::Array(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rule::Any => PrimitiveTypeUse::Any,
|
|
||||||
Rule::Void => PrimitiveTypeUse::Void,
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_interface_or_class_type_use(file_id: usize, pair: Pair<Rule>) -> InterfaceOrClassTypeUse {
|
fn build_interface_or_class_type_use(file_id: usize, pair: Pair<Rule>) -> InterfaceOrClassTypeUse {
|
||||||
let mut borrow_count = 0;
|
let mut borrow_count = 0;
|
||||||
let mut is_mutable = false;
|
let mut is_mutable = false;
|
||||||
|
241
src/ast/mod.rs
241
src/ast/mod.rs
@ -10,8 +10,7 @@ pub mod build;
|
|||||||
pub mod named;
|
pub mod named;
|
||||||
pub mod pretty_print;
|
pub mod pretty_print;
|
||||||
pub mod unparse;
|
pub mod unparse;
|
||||||
|
// Operators
|
||||||
/* Operators */
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Operator {
|
pub enum Operator {
|
||||||
@ -57,13 +56,13 @@ pub enum SuffixUnaryOperator {
|
|||||||
|
|
||||||
/* Names */
|
/* Names */
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Identifier {
|
pub struct Identifier {
|
||||||
name: String,
|
pub name: String,
|
||||||
file_id: usize,
|
pub file_id: usize,
|
||||||
range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
scope_id: Option<usize>,
|
scope_id: Option<usize>,
|
||||||
saved_symbol: Option<Symbol>,
|
symbol: Option<Symbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Identifier {
|
impl Identifier {
|
||||||
@ -73,18 +72,38 @@ impl Identifier {
|
|||||||
file_id,
|
file_id,
|
||||||
range,
|
range,
|
||||||
scope_id: None,
|
scope_id: None,
|
||||||
saved_symbol: None,
|
symbol: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_scope_id(&mut self, id: usize) {
|
||||||
|
self.scope_id = Some(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
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn symbol_mut(&mut self) -> Option<Symbol> {
|
||||||
|
self.symbol.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FullyQualifiedName {
|
pub struct FullyQualifiedName {
|
||||||
identifiers: Vec<Identifier>,
|
pub identifiers: Vec<Identifier>,
|
||||||
file_id: usize,
|
pub file_id: usize,
|
||||||
range: Range<usize>,
|
pub range: Range<usize>,
|
||||||
scope_id: Option<usize>,
|
scope_id: Option<usize>,
|
||||||
saved_symbol: Option<Symbol>,
|
symbol: Option<Symbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FullyQualifiedName {
|
impl FullyQualifiedName {
|
||||||
@ -94,25 +113,24 @@ impl FullyQualifiedName {
|
|||||||
range,
|
range,
|
||||||
file_id,
|
file_id,
|
||||||
scope_id: None,
|
scope_id: None,
|
||||||
saved_symbol: None,
|
symbol: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last(&self) -> &Identifier {
|
pub fn set_scope_id(&mut self, scope_id: usize) {
|
||||||
&self.identifiers[self.identifiers.len() - 1]
|
self.scope_id = Some(scope_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_mut(&mut self) -> &mut Identifier {
|
pub fn scope_id(&self) -> Option<usize> {
|
||||||
let last_index = self.identifiers.len() - 1;
|
self.scope_id
|
||||||
&mut self.identifiers[last_index]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn set_symbol(&mut self, symbol: Symbol) {
|
||||||
self.identifiers.len()
|
self.symbol = Some(symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_single_identifier(&self) -> bool {
|
pub fn symbol(&self) -> &Option<Symbol> {
|
||||||
self.identifiers.len() == 1
|
&self.symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,27 +138,12 @@ impl FullyQualifiedName {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TypeUse {
|
pub enum TypeUse {
|
||||||
Primitive(PrimitiveTypeUse),
|
Void,
|
||||||
InterfaceOrClass(InterfaceOrClassTypeUse),
|
InterfaceOrClass(InterfaceOrClassTypeUse),
|
||||||
Tuple(TupleTypeUse),
|
Tuple(TupleTypeUse),
|
||||||
Function(FunctionTypeUse),
|
Function(FunctionTypeUse),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum PrimitiveTypeUse {
|
|
||||||
Byte,
|
|
||||||
Short,
|
|
||||||
Char,
|
|
||||||
Int,
|
|
||||||
Long,
|
|
||||||
Double,
|
|
||||||
Bool,
|
|
||||||
String,
|
|
||||||
Array(Option<Box<GenericArguments>>),
|
|
||||||
Any,
|
|
||||||
Void,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InterfaceOrClassTypeUse {
|
pub struct InterfaceOrClassTypeUse {
|
||||||
pub borrow_count: usize,
|
pub borrow_count: usize,
|
||||||
@ -165,7 +168,7 @@ pub struct FunctionTypeUse {
|
|||||||
pub return_type: ReturnType,
|
pub return_type: ReturnType,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic arguments */
|
// Generic arguments
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct GenericArguments(pub Vec<TypeUse>);
|
pub struct GenericArguments(pub Vec<TypeUse>);
|
||||||
@ -265,7 +268,7 @@ pub struct ReturnType {
|
|||||||
impl ReturnType {
|
impl ReturnType {
|
||||||
pub fn void() -> Self {
|
pub fn void() -> Self {
|
||||||
ReturnType {
|
ReturnType {
|
||||||
declared_type: Box::new(TypeUse::Primitive(PrimitiveTypeUse::Void)),
|
declared_type: Box::new(TypeUse::Void),
|
||||||
references: References::default(),
|
references: References::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,68 +302,7 @@ pub struct CompilationUnit {
|
|||||||
pub declarations: Vec<ModuleLevelDeclaration>,
|
pub declarations: Vec<ModuleLevelDeclaration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use Statement */
|
// Declarations allowed in each level
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct UseStatement {
|
|
||||||
pub identifiers: Vec<Identifier>,
|
|
||||||
pub last: UseStatementLast,
|
|
||||||
pub file_id: usize,
|
|
||||||
pub range: Range<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UseStatement {
|
|
||||||
pub fn new(
|
|
||||||
identifiers: Vec<Identifier>,
|
|
||||||
last: UseStatementLast,
|
|
||||||
file_id: usize,
|
|
||||||
range: Range<usize>,
|
|
||||||
) -> Self {
|
|
||||||
UseStatement {
|
|
||||||
identifiers,
|
|
||||||
last,
|
|
||||||
file_id,
|
|
||||||
range,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn base_name(&self) -> Cow<'_, str> {
|
|
||||||
use UseStatementLast::*;
|
|
||||||
if self.identifiers.is_empty() {
|
|
||||||
match &self.last {
|
|
||||||
Identifier(_) => Cow::from(""),
|
|
||||||
Star | Identifiers(_) => panic!(), // should never get here because of grammar
|
|
||||||
}
|
|
||||||
} else if self.identifiers.len() == 1 {
|
|
||||||
self.identifiers[0].name()
|
|
||||||
} else {
|
|
||||||
let mut acc = String::new();
|
|
||||||
for (i, identifier) in self.identifiers.iter().enumerate() {
|
|
||||||
acc.push_str(&identifier.name());
|
|
||||||
if i != self.identifiers.len() - 1 {
|
|
||||||
acc.push_str("::");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Cow::from(acc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_star(&self) -> bool {
|
|
||||||
match &self.last {
|
|
||||||
UseStatementLast::Star => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum UseStatementLast {
|
|
||||||
Identifier(Rc<RefCell<Identifier>>),
|
|
||||||
Identifiers(Vec<Rc<RefCell<Identifier>>>),
|
|
||||||
Star,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Declarations allowed in each level */
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ModuleLevelDeclaration {
|
pub enum ModuleLevelDeclaration {
|
||||||
@ -392,7 +334,7 @@ pub enum ClassLevelDeclaration {
|
|||||||
Field(FieldDeclaration),
|
Field(FieldDeclaration),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main Declarations */
|
// Declarations
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ModuleDeclaration {
|
pub struct ModuleDeclaration {
|
||||||
@ -420,7 +362,7 @@ pub struct ClassDeclaration {
|
|||||||
pub declarations: Vec<ClassLevelDeclaration>,
|
pub declarations: Vec<ClassLevelDeclaration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function declarations and components */
|
// Function declarations and components
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionDefinition {
|
pub struct FunctionDefinition {
|
||||||
@ -490,7 +432,7 @@ pub enum FunctionBody {
|
|||||||
Alias(Identifier),
|
Alias(Identifier),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Class components */
|
// Class components
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
|
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
|
||||||
@ -515,7 +457,92 @@ pub struct FieldDeclaration {
|
|||||||
pub declared_type: TypeUse,
|
pub declared_type: TypeUse,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Statements */
|
// Statements
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct UseStatement {
|
||||||
|
pub identifiers: Vec<Identifier>,
|
||||||
|
pub last: UseStatementLast,
|
||||||
|
pub file_id: usize,
|
||||||
|
pub range: Range<usize>,
|
||||||
|
scope_id: Option<usize>,
|
||||||
|
symbol: Option<Symbol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UseStatementImport<'a> {
|
||||||
|
pub declared_name: String,
|
||||||
|
pub fqn: String,
|
||||||
|
pub identifier: &'a mut Identifier,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UseStatement {
|
||||||
|
pub fn new(
|
||||||
|
identifiers: Vec<Identifier>,
|
||||||
|
last: UseStatementLast,
|
||||||
|
file_id: usize,
|
||||||
|
range: Range<usize>,
|
||||||
|
) -> Self {
|
||||||
|
UseStatement {
|
||||||
|
identifiers,
|
||||||
|
last,
|
||||||
|
file_id,
|
||||||
|
range,
|
||||||
|
scope_id: None,
|
||||||
|
symbol: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn base_name(&self) -> Cow<'_, str> {
|
||||||
|
use UseStatementLast::*;
|
||||||
|
if self.identifiers.is_empty() {
|
||||||
|
match &self.last {
|
||||||
|
Identifier(_) => Cow::from(""),
|
||||||
|
Star | Identifiers(_) => panic!(), // should never get here because of grammar
|
||||||
|
}
|
||||||
|
} else if self.identifiers.len() == 1 {
|
||||||
|
self.identifiers[0].name()
|
||||||
|
} else {
|
||||||
|
let mut acc = String::new();
|
||||||
|
for (i, identifier) in self.identifiers.iter().enumerate() {
|
||||||
|
acc.push_str(&identifier.name());
|
||||||
|
if i != self.identifiers.len() - 1 {
|
||||||
|
acc.push_str("::");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cow::from(acc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_star(&self) -> bool {
|
||||||
|
match &self.last {
|
||||||
|
UseStatementLast::Star => true,
|
||||||
|
_ => 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)]
|
||||||
|
pub enum UseStatementLast {
|
||||||
|
Identifier(Rc<RefCell<Identifier>>),
|
||||||
|
Identifiers(Vec<Rc<RefCell<Identifier>>>),
|
||||||
|
Star,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BlockStatement {
|
pub struct BlockStatement {
|
||||||
@ -588,7 +615,7 @@ pub struct ForStatement {
|
|||||||
pub body: BlockStatement,
|
pub body: BlockStatement,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expressions */
|
// Expressions
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Expression {
|
pub enum Expression {
|
||||||
|
@ -1,49 +1,14 @@
|
|||||||
use crate::ast::{FullyQualifiedName, Identifier};
|
use crate::ast::{FullyQualifiedName, Identifier};
|
||||||
use crate::name_analysis::symbol::Symbol;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::range::Range;
|
|
||||||
|
|
||||||
pub trait Named {
|
pub trait Named {
|
||||||
fn name(&self) -> Cow<'_, str>;
|
fn name(&self) -> Cow<'_, str>;
|
||||||
|
|
||||||
fn file_id(&self) -> usize;
|
|
||||||
fn range(&self) -> Range<usize>;
|
|
||||||
|
|
||||||
fn set_scope_id(&mut self, scope_id: usize);
|
|
||||||
fn scope_id(&self) -> Option<usize>;
|
|
||||||
|
|
||||||
fn set_saved_symbol(&mut self, symbol: Symbol);
|
|
||||||
fn saved_symbol(&self) -> Option<Symbol>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Named for Identifier {
|
impl Named for Identifier {
|
||||||
fn name(&self) -> Cow<'_, str> {
|
fn name(&self) -> Cow<'_, str> {
|
||||||
Cow::Borrowed(&self.name)
|
Cow::Borrowed(&self.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_id(&self) -> usize {
|
|
||||||
self.file_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn range(&self) -> Range<usize> {
|
|
||||||
self.range
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_scope_id(&mut self, id: usize) {
|
|
||||||
self.scope_id = Some(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scope_id(&self) -> Option<usize> {
|
|
||||||
self.scope_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_saved_symbol(&mut self, saved_symbol: Symbol) {
|
|
||||||
self.saved_symbol = Some(saved_symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn saved_symbol(&self) -> Option<Symbol> {
|
|
||||||
self.saved_symbol.clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Named for FullyQualifiedName {
|
impl Named for FullyQualifiedName {
|
||||||
@ -61,28 +26,4 @@ impl Named for FullyQualifiedName {
|
|||||||
Cow::Owned(acc)
|
Cow::Owned(acc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_id(&self) -> usize {
|
|
||||||
self.file_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn range(&self) -> Range<usize> {
|
|
||||||
self.range
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_scope_id(&mut self, id: usize) {
|
|
||||||
self.scope_id = Some(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn scope_id(&self) -> Option<usize> {
|
|
||||||
self.scope_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_saved_symbol(&mut self, symbol: Symbol) {
|
|
||||||
self.saved_symbol = Some(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn saved_symbol(&self) -> Option<Symbol> {
|
|
||||||
self.saved_symbol.clone()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use deimos::name_analysis::symbol_table::SymbolTable;
|
|||||||
use deimos::parser::{DeimosParser, Rule};
|
use deimos::parser::{DeimosParser, Rule};
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use deimos::std_core::add_std_core_symbols;
|
|
||||||
|
|
||||||
pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> {
|
pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut compilation_units = vec![];
|
let mut compilation_units = vec![];
|
||||||
@ -30,7 +29,6 @@ pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Err
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
|
||||||
|
|
||||||
let diagnostics = analyze_names(&mut compilation_units, &mut symbol_table);
|
let diagnostics = analyze_names(&mut compilation_units, &mut symbol_table);
|
||||||
if diagnostics.is_empty() {
|
if diagnostics.is_empty() {
|
||||||
|
@ -6,6 +6,6 @@ pub mod module;
|
|||||||
pub mod name_analysis;
|
pub mod name_analysis;
|
||||||
pub mod object_file;
|
pub mod object_file;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod std_core;
|
mod std_core;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod vm;
|
pub mod vm;
|
||||||
|
@ -6,7 +6,6 @@ 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;
|
||||||
|
|
||||||
@ -42,21 +41,13 @@ fn handle_insert_error(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Names */
|
|
||||||
|
|
||||||
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,
|
||||||
) {
|
) {
|
||||||
gather_identifier(fully_qualified_name.last_mut(), symbol_table);
|
fully_qualified_name.set_scope_id(symbol_table.current_scope_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type Use */
|
|
||||||
|
|
||||||
fn gather_type_use(
|
fn gather_type_use(
|
||||||
type_use: &mut TypeUse,
|
type_use: &mut TypeUse,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -64,9 +55,7 @@ fn gather_type_use(
|
|||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
match type_use {
|
match type_use {
|
||||||
TypeUse::Primitive(primitive_type_use) => {
|
TypeUse::Void => {}
|
||||||
gather_primitive_type_use(primitive_type_use, symbol_table, fqn_context, diagnostics)
|
|
||||||
}
|
|
||||||
TypeUse::InterfaceOrClass(interface_or_class_type_use) => {
|
TypeUse::InterfaceOrClass(interface_or_class_type_use) => {
|
||||||
gather_interface_or_class_type_use(
|
gather_interface_or_class_type_use(
|
||||||
interface_or_class_type_use,
|
interface_or_class_type_use,
|
||||||
@ -84,22 +73,6 @@ fn gather_type_use(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_primitive_type_use(
|
|
||||||
primitive_type_use: &mut PrimitiveTypeUse,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
match primitive_type_use {
|
|
||||||
PrimitiveTypeUse::Array(generic_arguments_opt) => {
|
|
||||||
if let Some(generic_arguments) = generic_arguments_opt {
|
|
||||||
gather_generic_arguments(generic_arguments, symbol_table, fqn_context, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_interface_or_class_type_use(
|
fn gather_interface_or_class_type_use(
|
||||||
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
|
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -132,28 +105,9 @@ fn gather_function_type_use(
|
|||||||
fqn_context: &mut FqnContext,
|
fqn_context: &mut FqnContext,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
gather_generic_parameters(
|
todo!()
|
||||||
&mut function_type_use.generics,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
gather_parameters(
|
|
||||||
&mut function_type_use.parameters,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
gather_return_type(
|
|
||||||
&mut function_type_use.return_type,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic Arguments */
|
|
||||||
|
|
||||||
fn gather_generic_arguments(
|
fn gather_generic_arguments(
|
||||||
generic_arguments: &mut GenericArguments,
|
generic_arguments: &mut GenericArguments,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -165,123 +119,6 @@ fn gather_generic_arguments(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic Parameters */
|
|
||||||
|
|
||||||
fn gather_generic_parameters(
|
|
||||||
generic_parameters: &mut GenericParameters,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!("Add each Identifier as a type to the current scope; make sure caller's push/pop before/after")
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implements List */
|
|
||||||
|
|
||||||
fn gather_implements_list(
|
|
||||||
implements_list: &mut ImplementsList,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
for type_use in &mut implements_list.0 {
|
|
||||||
gather_type_use(type_use, symbol_table, fqn_context, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function Parameters */
|
|
||||||
|
|
||||||
fn gather_parameters(
|
|
||||||
parameters: &mut Parameters,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) -> Option<Vec<Rc<ParameterSymbol>>> {
|
|
||||||
parameters
|
|
||||||
.0
|
|
||||||
.iter_mut()
|
|
||||||
.map(|parameter| gather_parameter(parameter, symbol_table, fqn_context, diagnostics))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_parameter(
|
|
||||||
parameter: &mut Parameter,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) -> Option<Rc<ParameterSymbol>> {
|
|
||||||
let parameter_name = parameter.identifier.name();
|
|
||||||
|
|
||||||
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
|
|
||||||
¶meter_name,
|
|
||||||
Some(¶meter.identifier),
|
|
||||||
));
|
|
||||||
|
|
||||||
match insert_result {
|
|
||||||
Ok(parameter_symbol) => {
|
|
||||||
parameter
|
|
||||||
.identifier
|
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
|
||||||
|
|
||||||
gather_type_use(
|
|
||||||
&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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return Type */
|
|
||||||
|
|
||||||
fn gather_return_type(
|
|
||||||
return_type: &mut ReturnType,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
gather_type_use(
|
|
||||||
&mut return_type.declared_type,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
gather_references(
|
|
||||||
&mut return_type.references,
|
|
||||||
symbol_table,
|
|
||||||
fqn_context,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* References */
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compilation Unit/Top-level construct */
|
|
||||||
|
|
||||||
pub(super) fn gather_compilation_unit(
|
pub(super) fn gather_compilation_unit(
|
||||||
compilation_unit: &mut CompilationUnit,
|
compilation_unit: &mut CompilationUnit,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -303,8 +140,6 @@ pub(super) fn gather_compilation_unit(
|
|||||||
assert_eq!(symbol_table.current_scope_id(), 0);
|
assert_eq!(symbol_table.current_scope_id(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use Statement */
|
|
||||||
|
|
||||||
fn handle_use_statement_import(
|
fn handle_use_statement_import(
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
base_name: &str,
|
base_name: &str,
|
||||||
@ -318,29 +153,28 @@ fn handle_use_statement_import(
|
|||||||
&declared_name,
|
&declared_name,
|
||||||
Some(identifier.clone()),
|
Some(identifier.clone()),
|
||||||
));
|
));
|
||||||
|
if let Err(err) = insert_result {
|
||||||
match insert_result {
|
|
||||||
Ok(use_statement_symbol) => {
|
|
||||||
drop(borrowed_identifier);
|
|
||||||
|
|
||||||
let mut mutable_borrowed_identifier = identifier.borrow_mut();
|
|
||||||
|
|
||||||
gather_identifier(mutable_borrowed_identifier.deref_mut(), symbol_table);
|
|
||||||
|
|
||||||
mutable_borrowed_identifier
|
|
||||||
.set_saved_symbol(Symbol::UseStatement(use_statement_symbol));
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
handle_insert_error(
|
handle_insert_error(
|
||||||
err,
|
err,
|
||||||
&declared_name,
|
&declared_name,
|
||||||
borrowed_identifier.file_id(),
|
borrowed_identifier.file_id,
|
||||||
borrowed_identifier.range(),
|
borrowed_identifier.range,
|
||||||
"Use statement",
|
"Use statement",
|
||||||
diagnostics,
|
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(
|
||||||
@ -371,8 +205,6 @@ fn gather_use_statement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Declarations allowed in each level */
|
|
||||||
|
|
||||||
fn gather_module_level_declaration(
|
fn gather_module_level_declaration(
|
||||||
declaration: &mut ModuleLevelDeclaration,
|
declaration: &mut ModuleLevelDeclaration,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -402,26 +234,6 @@ fn gather_module_level_declaration(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_interface_level_declaration(
|
|
||||||
declaration: &mut InterfaceLevelDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_class_level_declaration(
|
|
||||||
declaration: &mut ClassLevelDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main Declarations */
|
|
||||||
|
|
||||||
fn gather_module_declaration(
|
fn gather_module_declaration(
|
||||||
declaration: &mut ModuleDeclaration,
|
declaration: &mut ModuleDeclaration,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -447,8 +259,8 @@ fn gather_module_declaration(
|
|||||||
handle_insert_error(
|
handle_insert_error(
|
||||||
err,
|
err,
|
||||||
&module_name,
|
&module_name,
|
||||||
declaration.identifier.file_id(),
|
declaration.identifier.file_id,
|
||||||
declaration.identifier.range(),
|
declaration.identifier.range,
|
||||||
"module/type",
|
"module/type",
|
||||||
diagnostics,
|
diagnostics,
|
||||||
)
|
)
|
||||||
@ -482,8 +294,8 @@ fn gather_class_declaration(
|
|||||||
handle_insert_error(
|
handle_insert_error(
|
||||||
err,
|
err,
|
||||||
&declared_name,
|
&declared_name,
|
||||||
class_declaration.identifier.file_id(),
|
class_declaration.identifier.file_id,
|
||||||
class_declaration.identifier.range(),
|
class_declaration.identifier.range,
|
||||||
"interface/class",
|
"interface/class",
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
@ -492,8 +304,6 @@ fn gather_class_declaration(
|
|||||||
// todo: scopes, generics, etc.
|
// todo: scopes, generics, etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function declarations and components */
|
|
||||||
|
|
||||||
fn gather_function_definition(
|
fn gather_function_definition(
|
||||||
function: &mut FunctionDefinition,
|
function: &mut FunctionDefinition,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -511,64 +321,30 @@ fn gather_function_definition(
|
|||||||
Some(&function.identifier),
|
Some(&function.identifier),
|
||||||
));
|
));
|
||||||
|
|
||||||
match insert_result {
|
if let Err(err) = insert_result {
|
||||||
Ok(function_symbol) => {
|
handle_insert_error(
|
||||||
|
err,
|
||||||
|
&declared_name,
|
||||||
|
function.identifier.file_id,
|
||||||
|
function.identifier.range,
|
||||||
|
"function/variable",
|
||||||
|
diagnostics,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
.identifier
|
.identifier
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("FunctionParameterScope({})", resolved_name));
|
symbol_table.push_scope(&format!("FunctionScope({})", resolved_name));
|
||||||
|
gather_parameters(
|
||||||
let parameters_result = gather_parameters(
|
|
||||||
&mut function.parameters,
|
&mut function.parameters,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
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);
|
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
|
||||||
|
symbol_table.pop_scope();
|
||||||
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_operator_function_definition(
|
|
||||||
operator_function_definition: &mut OperatorFunctionDefinition,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_platform_function_definition(
|
fn gather_platform_function_definition(
|
||||||
@ -588,74 +364,78 @@ fn gather_platform_function_definition(
|
|||||||
Some(&platform_function_declaration.identifier),
|
Some(&platform_function_declaration.identifier),
|
||||||
));
|
));
|
||||||
|
|
||||||
match insert_result {
|
if let Err(err) = insert_result {
|
||||||
Ok(function_symbol) => {
|
handle_insert_error(
|
||||||
let declared_name_as_string =
|
err,
|
||||||
platform_function_declaration.identifier.name().to_string();
|
&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
|
platform_function_declaration
|
||||||
.identifier
|
.identifier
|
||||||
.set_scope_id(symbol_table.current_scope_id());
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
|
||||||
symbol_table.push_scope(&format!(
|
symbol_table.push_scope(&format!("FunctionScope({})", declared_name_as_string));
|
||||||
"FunctionParameterScope({})",
|
gather_parameters(
|
||||||
declared_name_as_string
|
|
||||||
));
|
|
||||||
|
|
||||||
let parameter_symbols_result = gather_parameters(
|
|
||||||
&mut platform_function_declaration.parameters,
|
&mut platform_function_declaration.parameters,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
|
symbol_table.pop_scope();
|
||||||
match parameter_symbols_result {
|
|
||||||
Some(parameter_symbols) => {
|
|
||||||
function_symbol
|
|
||||||
.borrow_mut()
|
|
||||||
.set_parameters(parameter_symbols);
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gather_return_type(
|
fn gather_parameters(
|
||||||
&mut platform_function_declaration.return_type,
|
parameters: &mut Parameters,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
for parameter in &mut parameters.0 {
|
||||||
|
gather_parameter(parameter, symbol_table, fqn_context, diagnostics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gather_parameter(
|
||||||
|
parameter: &mut Parameter,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
fqn_context: &mut FqnContext,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let parameter_name = parameter.identifier.name();
|
||||||
|
|
||||||
|
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
|
||||||
|
¶meter_name,
|
||||||
|
Some(¶meter.identifier),
|
||||||
|
));
|
||||||
|
|
||||||
|
if let Err(err) = insert_result {
|
||||||
|
handle_insert_error(
|
||||||
|
err,
|
||||||
|
¶meter_name,
|
||||||
|
parameter.identifier.file_id,
|
||||||
|
parameter.identifier.range,
|
||||||
|
"function/variable",
|
||||||
|
diagnostics,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
parameter
|
||||||
|
.identifier
|
||||||
|
.set_scope_id(symbol_table.current_scope_id());
|
||||||
|
|
||||||
|
gather_type_use(
|
||||||
|
&mut parameter.type_use,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
fqn_context,
|
fqn_context,
|
||||||
diagnostics,
|
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,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_interface_function_declaration(
|
|
||||||
declaration: &mut InterfaceFunctionDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_interface_operator_function_declaration(
|
|
||||||
declaration: &mut InterfaceOperatorFunctionDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_function_body(
|
fn gather_function_body(
|
||||||
@ -671,37 +451,6 @@ fn gather_function_body(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Class Components */
|
|
||||||
|
|
||||||
fn gather_class_constructor(
|
|
||||||
class_constructor: &mut ClassConstructor,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_property_declaration(
|
|
||||||
property_declaration: &mut PropertyDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_field_declaration(
|
|
||||||
field_declaration: &mut FieldDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Statements */
|
|
||||||
|
|
||||||
fn gather_block_statement(
|
fn gather_block_statement(
|
||||||
block: &mut BlockStatement,
|
block: &mut BlockStatement,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -768,8 +517,8 @@ fn gather_variable_declaration(
|
|||||||
handle_insert_error(
|
handle_insert_error(
|
||||||
err,
|
err,
|
||||||
&variable_name,
|
&variable_name,
|
||||||
variable_declaration.identifier.file_id(),
|
variable_declaration.identifier.file_id,
|
||||||
variable_declaration.identifier.range(),
|
variable_declaration.identifier.range,
|
||||||
"function/variable",
|
"function/variable",
|
||||||
diagnostics,
|
diagnostics,
|
||||||
)
|
)
|
||||||
@ -802,55 +551,6 @@ fn gather_call_statement(
|
|||||||
gather_expression(&mut call_statement.0, symbol_table, diagnostics);
|
gather_expression(&mut call_statement.0, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_return_statement(
|
|
||||||
return_statement: &mut ReturnStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
if let Some(expression) = &mut return_statement.0 {
|
|
||||||
gather_expression(expression, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_if_statement(
|
|
||||||
if_statement: &mut IfStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_if_else_statement(
|
|
||||||
if_else_statement: &mut IfElseStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_while_statement(
|
|
||||||
while_statement: &mut WhileStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gather_for_statement(
|
|
||||||
for_statement: &mut ForStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
fqn_context: &mut FqnContext,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expressions */
|
|
||||||
|
|
||||||
fn gather_expression(
|
fn gather_expression(
|
||||||
expression: &mut Expression,
|
expression: &mut Expression,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -973,8 +673,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) => {
|
||||||
// TODO: use a special gather for names belonging to a struct
|
identifier.set_scope_id(symbol_table.current_scope_id());
|
||||||
gather_identifier(identifier, symbol_table);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -986,18 +685,8 @@ fn gather_literal(
|
|||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
match literal {
|
match literal {
|
||||||
Literal::DString(d_string) => gather_d_string(d_string, symbol_table, diagnostics),
|
Literal::DString(d_string) => todo!(),
|
||||||
Literal::BacktickString(backtick_string) => {
|
Literal::BacktickString(backtick_string) => todo!(),
|
||||||
gather_d_string(backtick_string, symbol_table, diagnostics)
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gather_d_string(
|
|
||||||
d_string: &mut DString,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
@ -1,24 +1,3 @@
|
|||||||
/*!
|
|
||||||
# Name Analysis
|
|
||||||
|
|
||||||
There are two phases in name analysis.
|
|
||||||
|
|
||||||
## 1. Gather
|
|
||||||
|
|
||||||
The gather phases has three responsibilities:
|
|
||||||
|
|
||||||
1. Add all declared symbols to the symbol table.
|
|
||||||
2. Set the `scope_id` property of all identifiers and fully-qualified-names.
|
|
||||||
3. For the main identifiers of `UseStatement`s (i.e., the last identifier in the `UseStatement`):
|
|
||||||
set a 'linking' symbol on the identifier, which will later be filled in with the linked-to
|
|
||||||
symbol (probably in another file, or from the standard library).
|
|
||||||
|
|
||||||
## 2. Resolve
|
|
||||||
|
|
||||||
The resolve phase has one main responsibility: resolve all references based on the identifier's
|
|
||||||
`scope_id` property.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use crate::ast::named::Named;
|
use crate::ast::named::Named;
|
||||||
use crate::ast::CompilationUnit;
|
use crate::ast::CompilationUnit;
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
@ -64,11 +43,7 @@ mod tests {
|
|||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn assert_number_of_diagnostics(
|
fn assert_no_diagnostics(sources: HashMap<&str, &str>) -> SymbolTable {
|
||||||
sources: HashMap<&str, &str>,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
n_diagnostics: usize,
|
|
||||||
) {
|
|
||||||
let mut files = SimpleFiles::new();
|
let mut files = SimpleFiles::new();
|
||||||
let mut compilation_units = vec![];
|
let mut compilation_units = vec![];
|
||||||
|
|
||||||
@ -86,7 +61,10 @@ mod tests {
|
|||||||
compilation_units.push(build_ast(file_name, file_id, pairs.next().unwrap()))
|
compilation_units.push(build_ast(file_name, file_id, pairs.next().unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
let diagnostics = analyze_names(&mut compilation_units, symbol_table);
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
add_std_core_symbols(&mut symbol_table).expect("Failed to add std_core_symbols");
|
||||||
|
|
||||||
|
let diagnostics = analyze_names(&mut compilation_units, &mut symbol_table);
|
||||||
|
|
||||||
if !diagnostics.is_empty() {
|
if !diagnostics.is_empty() {
|
||||||
let writer = StandardStream::stderr(ColorChoice::Always);
|
let writer = StandardStream::stderr(ColorChoice::Always);
|
||||||
@ -97,17 +75,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("{}", symbol_table);
|
eprintln!("{}", symbol_table);
|
||||||
|
panic!("Diagnostics was not empty!");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(n_diagnostics, diagnostics.len());
|
|
||||||
|
|
||||||
for compilation_unit in &compilation_units {
|
for compilation_unit in &compilation_units {
|
||||||
dbg!(compilation_unit);
|
dbg!(compilation_unit);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn assert_no_diagnostics(sources: HashMap<&str, &str>, symbol_table: &mut SymbolTable) {
|
symbol_table
|
||||||
assert_number_of_diagnostics(sources, symbol_table, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -120,7 +95,7 @@ mod tests {
|
|||||||
}"},
|
}"},
|
||||||
)]);
|
)]);
|
||||||
|
|
||||||
assert_no_diagnostics(sources, &mut SymbolTable::new());
|
assert_no_diagnostics(sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -130,6 +105,10 @@ mod tests {
|
|||||||
"main.dm",
|
"main.dm",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
use test::Greeter;
|
use test::Greeter;
|
||||||
|
|
||||||
|
fn main(args: Array<String>) {
|
||||||
|
println(\"Hello, World!\");
|
||||||
|
}
|
||||||
"},
|
"},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -142,81 +121,6 @@ mod tests {
|
|||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert_no_diagnostics(sources, &mut SymbolTable::new());
|
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)
|
|
||||||
}
|
|
||||||
"},
|
|
||||||
)]);
|
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
|
||||||
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
|
||||||
assert_no_diagnostics(sources, &mut symbol_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sees_duplicate_fn() {
|
|
||||||
let sources: HashMap<&str, &str> = HashMap::from([(
|
|
||||||
"main.dm",
|
|
||||||
indoc! {"
|
|
||||||
fn main(args: Array<String>) {}
|
|
||||||
fn main(args: Array<String>) {}
|
|
||||||
"},
|
|
||||||
)]);
|
|
||||||
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn use_class_from_other_file() {
|
|
||||||
let sources: HashMap<&str, &str> = HashMap::from([
|
|
||||||
(
|
|
||||||
"main.dm",
|
|
||||||
indoc! {"
|
|
||||||
use greeter::Greeter;
|
|
||||||
|
|
||||||
fn test(greeter: Greeter) {}
|
|
||||||
"},
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"greeter.dm",
|
|
||||||
indoc! {"
|
|
||||||
ns greeter;
|
|
||||||
|
|
||||||
class Greeter {}
|
|
||||||
"},
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
|
||||||
assert_no_diagnostics(sources, &mut symbol_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn shadow_import() {
|
|
||||||
let sources: HashMap<&str, &str> = HashMap::from([
|
|
||||||
(
|
|
||||||
"main.dm",
|
|
||||||
indoc! {"
|
|
||||||
use greeter::Greeter;
|
|
||||||
|
|
||||||
class Greeter {}
|
|
||||||
"}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"greeter.dm",
|
|
||||||
indoc! {"
|
|
||||||
ns greeter;
|
|
||||||
|
|
||||||
class Greeter {}
|
|
||||||
"}
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,38 @@
|
|||||||
use crate::ast::named::Named;
|
use crate::ast::named::Named;
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::symbol::Symbol;
|
use crate::name_analysis::symbol_table::SymbolTable;
|
||||||
use crate::name_analysis::symbol_table::{SymbolLookupError, 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;
|
|
||||||
|
|
||||||
/* Type Use */
|
fn resolve_fully_qualified_name(
|
||||||
|
fully_qualified_name: &mut FullyQualifiedName,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let lookup_result = symbol_table.lookup(
|
||||||
|
fully_qualified_name.name().as_ref(),
|
||||||
|
fully_qualified_name.scope_id().expect(&format!(
|
||||||
|
"FullyQualifiedName has no scope_id set: {:?}",
|
||||||
|
fully_qualified_name
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
match lookup_result {
|
||||||
|
Ok(symbol) => {
|
||||||
|
fully_qualified_name.set_symbol(symbol.clone());
|
||||||
|
}
|
||||||
|
Err(e) => diagnostics.push(
|
||||||
|
Diagnostic::error()
|
||||||
|
.with_message(format!(
|
||||||
|
"No symbol with name '{}' found in current scope.",
|
||||||
|
fully_qualified_name.name()
|
||||||
|
))
|
||||||
|
.with_label(Label::primary(
|
||||||
|
fully_qualified_name.file_id,
|
||||||
|
fully_qualified_name.range,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_type_use(
|
fn resolve_type_use(
|
||||||
type_use: &mut TypeUse,
|
type_use: &mut TypeUse,
|
||||||
@ -16,9 +40,7 @@ fn resolve_type_use(
|
|||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
match type_use {
|
match type_use {
|
||||||
TypeUse::Primitive(primitive_type_use) => {
|
TypeUse::Void => {}
|
||||||
resolve_primitive_type_use(primitive_type_use, symbol_table, diagnostics)
|
|
||||||
}
|
|
||||||
TypeUse::InterfaceOrClass(interface_or_class_type_use) => {
|
TypeUse::InterfaceOrClass(interface_or_class_type_use) => {
|
||||||
resolve_interface_or_class_type_use(
|
resolve_interface_or_class_type_use(
|
||||||
interface_or_class_type_use,
|
interface_or_class_type_use,
|
||||||
@ -35,56 +57,16 @@ fn resolve_type_use(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_primitive_type_use(
|
|
||||||
primitive_type_use: &mut PrimitiveTypeUse,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
match primitive_type_use {
|
|
||||||
PrimitiveTypeUse::Array(generic_arguments_opt) => {
|
|
||||||
if let Some(generic_arguments) = generic_arguments_opt {
|
|
||||||
resolve_generic_arguments(generic_arguments, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_interface_or_class_type_use(
|
fn resolve_interface_or_class_type_use(
|
||||||
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
|
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
// 1. handle main name
|
resolve_fully_qualified_name(
|
||||||
let fqn = &mut interface_or_class_type_use.fqn;
|
&mut interface_or_class_type_use.fqn,
|
||||||
let lookup_result = if fqn.is_single_identifier() {
|
symbol_table,
|
||||||
let identifier = fqn.last();
|
diagnostics,
|
||||||
symbol_table.lookup_type_by_declared_name(
|
|
||||||
&identifier.name(),
|
|
||||||
identifier
|
|
||||||
.scope_id()
|
|
||||||
.expect("Identifier's scope id not set."),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
todo!("Fully-qualified-name type uses sensitive to imports and so on")
|
|
||||||
};
|
|
||||||
match lookup_result {
|
|
||||||
Ok(type_symbol) => {
|
|
||||||
fqn.last_mut().set_saved_symbol(Symbol::Type(type_symbol));
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
diagnostics.push(
|
|
||||||
Diagnostic::error()
|
|
||||||
.with_message(&format!(
|
|
||||||
"No type symbol '{}' found in current scope.",
|
|
||||||
fqn.name()
|
|
||||||
))
|
|
||||||
.with_label(Label::primary(fqn.file_id(), fqn.range())),
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. generics
|
|
||||||
resolve_generic_arguments(
|
resolve_generic_arguments(
|
||||||
&mut interface_or_class_type_use.generics,
|
&mut interface_or_class_type_use.generics,
|
||||||
symbol_table,
|
symbol_table,
|
||||||
@ -113,8 +95,6 @@ fn resolve_function_type_use(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic arguments */
|
|
||||||
|
|
||||||
fn resolve_generic_arguments(
|
fn resolve_generic_arguments(
|
||||||
generic_arguments: &mut GenericArguments,
|
generic_arguments: &mut GenericArguments,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -125,10 +105,6 @@ fn resolve_generic_arguments(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic parameters: todo: no resolution needed? */
|
|
||||||
|
|
||||||
/* Tuple arguments */
|
|
||||||
|
|
||||||
fn resolve_tuple_arguments(
|
fn resolve_tuple_arguments(
|
||||||
tuple_type_use: &mut TupleArguments,
|
tuple_type_use: &mut TupleArguments,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -139,8 +115,6 @@ fn resolve_tuple_arguments(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implements list */
|
|
||||||
|
|
||||||
fn resolve_implements_list(
|
fn resolve_implements_list(
|
||||||
implements_list: &mut ImplementsList,
|
implements_list: &mut ImplementsList,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -149,8 +123,6 @@ fn resolve_implements_list(
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function parameters */
|
|
||||||
|
|
||||||
fn resolve_parameters(
|
fn resolve_parameters(
|
||||||
parameters: &mut Parameters,
|
parameters: &mut Parameters,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -161,8 +133,6 @@ fn resolve_parameters(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Type */
|
|
||||||
|
|
||||||
fn resolve_return_type(
|
fn resolve_return_type(
|
||||||
return_type: &mut ReturnType,
|
return_type: &mut ReturnType,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -172,8 +142,6 @@ fn resolve_return_type(
|
|||||||
resolve_references(&mut return_type.references, symbol_table, diagnostics);
|
resolve_references(&mut return_type.references, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* References */
|
|
||||||
|
|
||||||
fn resolve_references(
|
fn resolve_references(
|
||||||
references: &mut References,
|
references: &mut References,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -184,7 +152,46 @@ fn resolve_references(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compilation Unit/Top-level construct */
|
fn resolve_use_statement(
|
||||||
|
use_statement: &mut UseStatement,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
if use_statement.is_star() {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
let base_name = use_statement.base_name().to_string();
|
||||||
|
|
||||||
|
match &use_statement.last {
|
||||||
|
UseStatementLast::Identifier(identifier) => {
|
||||||
|
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());
|
||||||
|
drop(borrowed_identifier);
|
||||||
|
|
||||||
|
if let Err(_) = lookup_result {
|
||||||
|
diagnostics.push(
|
||||||
|
Diagnostic::error()
|
||||||
|
.with_message(&format!("Unable to find symbol '{}'.", fqn))
|
||||||
|
.with_label(Label::primary(use_statement.file_id, use_statement.range)),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let mut mutable_borrowed_identifier = identifier.borrow_mut();
|
||||||
|
let use_statement_symbol = mutable_borrowed_identifier
|
||||||
|
.symbol_mut()
|
||||||
|
.unwrap()
|
||||||
|
.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 => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn resolve_compilation_unit(
|
pub(super) fn resolve_compilation_unit(
|
||||||
compilation_unit: &mut CompilationUnit,
|
compilation_unit: &mut CompilationUnit,
|
||||||
@ -199,79 +206,7 @@ pub(super) fn resolve_compilation_unit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use Statement */
|
pub(super) fn resolve_module_level_declaration(
|
||||||
|
|
||||||
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) => {
|
|
||||||
let saved_symbol = borrowed_identifier
|
|
||||||
.saved_symbol()
|
|
||||||
.expect("Identifier's saved_symbol is not set.");
|
|
||||||
let use_statement_symbol = saved_symbol.unwrap_use_statement_symbol();
|
|
||||||
use_statement_symbol
|
|
||||||
.borrow_mut()
|
|
||||||
.set_referenced_symbol(referenced_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(
|
|
||||||
use_statement: &mut UseStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
let base_name = use_statement.base_name().to_string();
|
|
||||||
|
|
||||||
match &use_statement.last {
|
|
||||||
UseStatementLast::Identifier(identifier) => {
|
|
||||||
handle_use_statement_identifier(
|
|
||||||
identifier.clone(),
|
|
||||||
&base_name,
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
use_statement.file_id,
|
|
||||||
use_statement.range,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
UseStatementLast::Identifiers(identifiers) => {
|
|
||||||
for identifier in identifiers {
|
|
||||||
handle_use_statement_identifier(
|
|
||||||
identifier.clone(),
|
|
||||||
&base_name,
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
use_statement.file_id,
|
|
||||||
identifier.borrow().range(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UseStatementLast::Star => todo!("star imports"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Declarations allowed in each level */
|
|
||||||
|
|
||||||
fn resolve_module_level_declaration(
|
|
||||||
declaration: &mut ModuleLevelDeclaration,
|
declaration: &mut ModuleLevelDeclaration,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
@ -293,65 +228,6 @@ fn resolve_module_level_declaration(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_interface_level_declaration(
|
|
||||||
declaration: &mut InterfaceLevelDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_class_level_declaration(
|
|
||||||
declaration: &mut ClassLevelDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main Declarations */
|
|
||||||
|
|
||||||
fn resolve_module_declaration(
|
|
||||||
module_declaration: &mut ModuleDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
for declaration in &mut module_declaration.declarations {
|
|
||||||
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_interface_declaration(
|
|
||||||
interface_declaration: &mut InterfaceDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
resolve_implements_list(
|
|
||||||
&mut interface_declaration.implements,
|
|
||||||
symbol_table,
|
|
||||||
diagnostics,
|
|
||||||
);
|
|
||||||
for declaration in &mut interface_declaration.declarations {
|
|
||||||
resolve_interface_level_declaration(declaration, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_class_declaration(
|
|
||||||
class_declaration: &mut ClassDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
if let Some(class_constructor) = &mut class_declaration.class_constructor {
|
|
||||||
resolve_class_constructor(class_constructor, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
resolve_implements_list(&mut class_declaration.implements, symbol_table, diagnostics);
|
|
||||||
for declaration in &mut class_declaration.declarations {
|
|
||||||
resolve_class_level_declaration(declaration, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function declarations and components */
|
|
||||||
|
|
||||||
fn resolve_function_definition(
|
fn resolve_function_definition(
|
||||||
function_definition: &mut FunctionDefinition,
|
function_definition: &mut FunctionDefinition,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -370,14 +246,6 @@ fn resolve_function_definition(
|
|||||||
resolve_function_body(&mut function_definition.body, symbol_table, diagnostics);
|
resolve_function_body(&mut function_definition.body, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_operator_function_definition(
|
|
||||||
operator_function_definition: &mut OperatorFunctionDefinition,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_platform_function_declaration(
|
fn resolve_platform_function_declaration(
|
||||||
platform_function_declaration: &mut PlatformFunctionDeclaration,
|
platform_function_declaration: &mut PlatformFunctionDeclaration,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -395,22 +263,6 @@ fn resolve_platform_function_declaration(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_interface_function_declaration(
|
|
||||||
interface_function_declaration: &mut InterfaceFunctionDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_interface_operator_function_declaration(
|
|
||||||
interface_operator_function_declaration: &mut InterfaceOperatorFunctionDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_function_body(
|
fn resolve_function_body(
|
||||||
function_body: &mut FunctionBody,
|
function_body: &mut FunctionBody,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -418,49 +270,12 @@ fn resolve_function_body(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::FunctionBody::*;
|
use crate::ast::FunctionBody::*;
|
||||||
match function_body {
|
match function_body {
|
||||||
Equals(expression) => resolve_expression(expression, symbol_table, diagnostics),
|
Block(block) => resolve_block(block, symbol_table, diagnostics),
|
||||||
Block(block) => resolve_block_statement(block, symbol_table, diagnostics),
|
_ => todo!(),
|
||||||
Alias(identifier) => resolve_function_alias(identifier, symbol_table, diagnostics),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_function_alias(
|
fn resolve_block(
|
||||||
identifier: &mut Identifier,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Class components */
|
|
||||||
|
|
||||||
fn resolve_class_constructor(
|
|
||||||
class_constructor: &mut ClassConstructor,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_property_declaration(
|
|
||||||
property_declaration: &mut PropertyDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_field_declaration(
|
|
||||||
field_declaration: &mut FieldDeclaration,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Statements */
|
|
||||||
|
|
||||||
fn resolve_block_statement(
|
|
||||||
block_statement: &mut BlockStatement,
|
block_statement: &mut BlockStatement,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
@ -480,7 +295,7 @@ fn resolve_statement(
|
|||||||
) {
|
) {
|
||||||
use crate::ast::Statement::*;
|
use crate::ast::Statement::*;
|
||||||
match statement {
|
match statement {
|
||||||
BlockStatement(block) => resolve_block_statement(block, symbol_table, diagnostics),
|
BlockStatement(block) => resolve_block(block, symbol_table, diagnostics),
|
||||||
VariableDeclarationStatement(variable_declaration) => {
|
VariableDeclarationStatement(variable_declaration) => {
|
||||||
resolve_variable_declaration(variable_declaration, symbol_table, diagnostics)
|
resolve_variable_declaration(variable_declaration, symbol_table, diagnostics)
|
||||||
}
|
}
|
||||||
@ -521,42 +336,6 @@ fn resolve_call_statement(
|
|||||||
resolve_expression(&mut call_statement.0, symbol_table, diagnostics)
|
resolve_expression(&mut call_statement.0, symbol_table, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_return_statement(
|
|
||||||
return_statement: &mut ReturnStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
if let Some(expression) = &mut return_statement.0 {
|
|
||||||
resolve_expression(expression, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_if_statement(
|
|
||||||
if_statement: &mut IfStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_while_statement(
|
|
||||||
while_statement: &mut WhileStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_for_statement(
|
|
||||||
for_statement: &mut ForStatement,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expressions */
|
|
||||||
|
|
||||||
fn resolve_expression(
|
fn resolve_expression(
|
||||||
expression: &mut Expression,
|
expression: &mut Expression,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -582,13 +361,7 @@ fn resolve_expression(
|
|||||||
ObjectAccess(object_access) => {
|
ObjectAccess(object_access) => {
|
||||||
resolve_object_access(object_access, symbol_table, diagnostics);
|
resolve_object_access(object_access, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
FullyQualifiedName(fqn) => {
|
FullyQualifiedName(fqn) => resolve_fully_qualified_name(fqn, symbol_table, diagnostics),
|
||||||
if fqn.is_single_identifier() {
|
|
||||||
resolve_identifier_expression(fqn.last_mut(), symbol_table, diagnostics);
|
|
||||||
} else {
|
|
||||||
resolve_fqn_expression(fqn, symbol_table, diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Literal(literal) => {
|
Literal(literal) => {
|
||||||
resolve_literal(literal, symbol_table, diagnostics);
|
resolve_literal(literal, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
@ -598,48 +371,6 @@ fn resolve_expression(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_named_lookup_result(
|
|
||||||
lookup_result: Result<Symbol, SymbolLookupError>,
|
|
||||||
named: &mut impl Named,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
match lookup_result {
|
|
||||||
Ok(referenced_symbol) => {
|
|
||||||
named.set_saved_symbol(referenced_symbol);
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
diagnostics.push(
|
|
||||||
DmDiagnostic::error()
|
|
||||||
.with_message(&format!(
|
|
||||||
"Unable to find expressible symbol {} in current scope.",
|
|
||||||
named.name()
|
|
||||||
))
|
|
||||||
.with_label(Label::primary(named.file_id(), named.range())),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_identifier_expression(
|
|
||||||
identifier: &mut Identifier,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
let lookup_result = symbol_table
|
|
||||||
.lookup_expressible_by_declared_name(&identifier.name(), identifier.scope_id().unwrap());
|
|
||||||
handle_named_lookup_result(lookup_result, identifier, diagnostics);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_fqn_expression(
|
|
||||||
fqn: &mut FullyQualifiedName,
|
|
||||||
symbol_table: &mut SymbolTable,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
|
||||||
) {
|
|
||||||
let lookup_result =
|
|
||||||
symbol_table.lookup_expressible_by_fqn(&fqn.name(), fqn.last().scope_id().unwrap());
|
|
||||||
handle_named_lookup_result(lookup_result, fqn, diagnostics);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_ternary_expression(
|
fn resolve_ternary_expression(
|
||||||
ternary_expression: &mut TernaryExpression,
|
ternary_expression: &mut TernaryExpression,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -700,7 +431,7 @@ fn resolve_turbo_fish(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
resolve_generic_arguments(&mut turbo_fish.0, symbol_table, diagnostics);
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_call_arguments(
|
fn resolve_call_arguments(
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use crate::ast::{Identifier, UseStatement};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use crate::ast::{Identifier, UseStatement};
|
||||||
|
use std::fmt::Display;
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::ast::named::Named;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SourceDefinition {
|
pub struct SourceDefinition {
|
||||||
@ -14,16 +13,16 @@ pub struct SourceDefinition {
|
|||||||
impl SourceDefinition {
|
impl SourceDefinition {
|
||||||
pub fn from_identifier(identifier: &Identifier) -> Self {
|
pub fn from_identifier(identifier: &Identifier) -> Self {
|
||||||
SourceDefinition {
|
SourceDefinition {
|
||||||
file_id: identifier.file_id(),
|
file_id: identifier.file_id,
|
||||||
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 {
|
||||||
file_id: borrowed.file_id(),
|
file_id: borrowed.file_id,
|
||||||
range: borrowed.range(),
|
range: borrowed.range,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,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<RefCell<FunctionSymbol>>),
|
Function(Rc<FunctionSymbol>),
|
||||||
Parameter(Rc<ParameterSymbol>),
|
Parameter(Rc<ParameterSymbol>),
|
||||||
Variable(Rc<VariableSymbol>),
|
Variable(Rc<VariableSymbol>),
|
||||||
}
|
}
|
||||||
@ -64,10 +63,10 @@ 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(),
|
Symbol::UseStatement(s) => s.borrow().definition.clone(),
|
||||||
Symbol::Module(s) => s.definition(),
|
Symbol::Module(s) => s.definition(),
|
||||||
Symbol::Type(s) => s.definition(),
|
Symbol::Type(s) => s.definition(),
|
||||||
Symbol::Function(s) => s.borrow().definition(),
|
Symbol::Function(s) => s.definition(),
|
||||||
Symbol::Parameter(s) => s.definition(),
|
Symbol::Parameter(s) => s.definition(),
|
||||||
Symbol::Variable(s) => s.definition(),
|
Symbol::Variable(s) => s.definition(),
|
||||||
}
|
}
|
||||||
@ -81,21 +80,32 @@ impl Symbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Symbol {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
use Symbol::*;
|
||||||
|
match self {
|
||||||
|
UseStatement(use_statement_symbol) => write!(f, "{}", use_statement_symbol.borrow()),
|
||||||
|
Module(module_symbol) => write!(f, "{}", module_symbol),
|
||||||
|
Type(class_symbol) => write!(f, "{}", class_symbol),
|
||||||
|
Function(function_symbol) => write!(f, "{}", function_symbol),
|
||||||
|
Parameter(parameter_symbol) => write!(f, "{}", parameter_symbol),
|
||||||
|
Variable(variable_symbol) => write!(f, "{}", variable_symbol),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Use-statement */
|
/* Use-statement */
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct UseStatementSymbol {
|
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(
|
pub fn new(fqn: &str, declared_name: &str, identifier: Option<Rc<RefCell<Identifier>>>) -> Self {
|
||||||
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(),
|
||||||
@ -123,18 +133,20 @@ impl SymbolInner for UseStatementSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for UseStatementSymbol {
|
impl Display for UseStatementSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("UseStatementSymbol")
|
write!(
|
||||||
.field("fqn", &self.fqn)
|
f,
|
||||||
.field("declared_name", &self.declared_name)
|
"UseStatementSymbol(fqn = {}, declared_name = {})",
|
||||||
.field("referenced_symbol", &self.referenced_symbol)
|
self.fqn, self.declared_name
|
||||||
.finish()
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Module */
|
/* Module */
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ModuleSymbol {
|
pub struct ModuleSymbol {
|
||||||
fqn: String,
|
fqn: String,
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
@ -168,18 +180,19 @@ impl SymbolInner for ModuleSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ModuleSymbol {
|
impl Display for ModuleSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("ModuleSymbol")
|
write!(
|
||||||
.field("fqn", &self.fqn)
|
f,
|
||||||
.field("declared_name", &self.declared_name)
|
"ModuleSymbol(name = {}, is_public = {})",
|
||||||
.field("is_public", &self.is_public)
|
self.fqn, self.is_public
|
||||||
.finish()
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TypeSymbol */
|
/* Class */
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct TypeSymbol {
|
pub struct TypeSymbol {
|
||||||
fqn: String,
|
fqn: String,
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
@ -188,12 +201,7 @@ pub struct TypeSymbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TypeSymbol {
|
impl TypeSymbol {
|
||||||
pub fn new(
|
pub fn new(fqn: &str, declared_name: &str, is_public: bool, identifier: Option<&Identifier>) -> Self {
|
||||||
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(),
|
||||||
@ -221,26 +229,25 @@ impl SymbolInner for TypeSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for TypeSymbol {
|
impl Display for TypeSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("TypeSymbol")
|
write!(
|
||||||
.field("fqn", &self.fqn)
|
f,
|
||||||
.field("declared_name", &self.declared_name)
|
"TypeSymbol(fqn = {}, declared_name = {})",
|
||||||
.field("is_public", &self.is_public)
|
self.fqn, self.declared_name
|
||||||
.finish()
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function */
|
/* Function */
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct FunctionSymbol {
|
pub struct FunctionSymbol {
|
||||||
fqn: String,
|
fqn: String,
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
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 {
|
||||||
@ -257,49 +264,12 @@ 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 {
|
||||||
@ -312,21 +282,19 @@ impl SymbolInner for FunctionSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for FunctionSymbol {
|
impl Display for FunctionSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("FunctionSymbol")
|
write!(
|
||||||
.field("fqn", &self.fqn)
|
f,
|
||||||
.field("declared_name", &self.declared_name)
|
"FunctionSymbol(fqn = {}, declared_name = {}, is_public = {})",
|
||||||
.field("is_public", &self.is_public)
|
self.fqn, self.declared_name, self.is_public
|
||||||
.field("is_platform", &self.is_platform)
|
)
|
||||||
.field("parameters", &self.parameters)
|
|
||||||
.field("return_type", &self.return_type)
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parameter */
|
/* Parameter */
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ParameterSymbol {
|
pub struct ParameterSymbol {
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
definition: Option<SourceDefinition>,
|
definition: Option<SourceDefinition>,
|
||||||
@ -351,16 +319,19 @@ impl SymbolInner for ParameterSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ParameterSymbol {
|
impl Display for ParameterSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("ParameterSymbol")
|
write!(
|
||||||
.field("declared_name", &self.declared_name)
|
f,
|
||||||
.finish()
|
"ParameterSymbol({})",
|
||||||
|
self.declared_name
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Variable */
|
/* Variable */
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct VariableSymbol {
|
pub struct VariableSymbol {
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
is_mutable: bool,
|
is_mutable: bool,
|
||||||
@ -387,11 +358,12 @@ impl SymbolInner for VariableSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for VariableSymbol {
|
impl Display for VariableSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
f.debug_struct("VariableSymbol")
|
write!(
|
||||||
.field("declared_name", &self.declared_name)
|
f,
|
||||||
.field("is_mutable", &self.is_mutable)
|
"VariableSymbol(name = {}, is_mutable = {})",
|
||||||
.finish()
|
self.declared_name, self.is_mutable
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
use crate::name_analysis::symbol::{
|
use crate::name_analysis::symbol::{
|
||||||
FunctionSymbol, ModuleSymbol, ParameterSymbol, Symbol, SymbolInner, TypeSymbol,
|
FunctionSymbol, ModuleSymbol, ParameterSymbol, Symbol, SymbolInner, TypeSymbol,
|
||||||
UseStatementSymbol, VariableSymbol,
|
UseStatementSymbol, VariableSymbol,
|
||||||
};
|
};
|
||||||
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
||||||
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -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<RefCell<FunctionSymbol>>>,
|
function_symbols: HashMap<String, Rc<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,
|
||||||
@ -37,34 +37,13 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_any_symbol(&self, name: &str) -> Option<Symbol> {
|
fn get_any_symbol(&self, name: &str) -> Option<Symbol> {
|
||||||
self.variable_symbols
|
self.variable_symbols.get(name)
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Variable(s.clone()))
|
.map(|s| Symbol::Variable(s.clone()))
|
||||||
.or_else(|| {
|
.or_else(|| self.parameter_symbols.get(name).map(|s| Symbol::Parameter(s.clone())))
|
||||||
self.parameter_symbols
|
.or_else(|| self.function_symbols.get(name).map(|s| Symbol::Function(s.clone())))
|
||||||
.get(name)
|
.or_else(|| self.type_symbols.get(name).map(|ts| Symbol::Type(ts.clone())))
|
||||||
.map(|s| Symbol::Parameter(s.clone()))
|
.or_else(|| self.module_symbols.get(name).map(|ms| Symbol::Module(ms.clone())))
|
||||||
})
|
.or_else(|| self.use_statement_symbols.get(name).map(|us| Symbol::UseStatement(us.clone())))
|
||||||
.or_else(|| {
|
|
||||||
self.function_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|s| Symbol::Function(s.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.type_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|ts| Symbol::Type(ts.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.module_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|ms| Symbol::Module(ms.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.use_statement_symbols
|
|
||||||
.get(name)
|
|
||||||
.map(|us| Symbol::UseStatement(us.clone()))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> {
|
fn get_module_symbol_by_declared_name(&self, name: &str) -> Option<Rc<ModuleSymbol>> {
|
||||||
@ -76,32 +55,9 @@ impl Scope {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_type_symbol_by_declared_name(&self, declared_name: &str) -> Option<Rc<TypeSymbol>> {
|
|
||||||
if let Some(type_symbol) = self.type_symbols.get(declared_name) {
|
|
||||||
Some(type_symbol.clone())
|
|
||||||
} else {
|
|
||||||
for use_statement_symbol in self.use_statement_symbols.values() {
|
|
||||||
let borrowed = use_statement_symbol.borrow();
|
|
||||||
if borrowed.declared_name() == declared_name {
|
|
||||||
if let Some(referenced_symbol) = borrowed.referenced_symbol() {
|
|
||||||
match *referenced_symbol {
|
|
||||||
Symbol::Type(type_symbol) => return Some(type_symbol.clone()),
|
|
||||||
_ => continue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<TypeSymbol>> {
|
|
||||||
self.type_symbols.values().find(|s| s.fqn() == fqn).cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
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.borrow().fqn() == fqn {
|
if function_symbol.fqn() == fqn {
|
||||||
return Some(Symbol::Function(function_symbol.clone()));
|
return Some(Symbol::Function(function_symbol.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,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.borrow().declared_name() == declared_name {
|
if function_symbol.declared_name() == declared_name {
|
||||||
return Some(Symbol::Function(function_symbol.clone()));
|
return Some(Symbol::Function(function_symbol.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,45 +96,6 @@ impl Scope {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_expressible_by_declared_name(&self, declared_name: &str) -> Option<Symbol> {
|
|
||||||
self.variable_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|s| Symbol::Variable(s.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
self.parameter_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|p| Symbol::Parameter(p.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.function_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|f| Symbol::Function(f.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.type_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|t| Symbol::Type(t.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
self.use_statement_symbols
|
|
||||||
.get(declared_name)
|
|
||||||
.map(|us| Symbol::UseStatement(us.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_expressible_by_fqn(&self, fqn: &str) -> Option<Symbol> {
|
|
||||||
self.function_symbols
|
|
||||||
.values()
|
|
||||||
.find(|fs| fs.borrow().fqn() == fqn)
|
|
||||||
.map(|f| Symbol::Function(f.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
self.type_symbols
|
|
||||||
.values()
|
|
||||||
.find(|ts| ts.fqn() == fqn)
|
|
||||||
.map(|ts| Symbol::Type(ts.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbol table */
|
/* Symbol table */
|
||||||
@ -235,20 +152,18 @@ 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<Rc<RefCell<UseStatementSymbol>>, SymbolInsertError> {
|
) -> Result<(), 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();
|
current_scope.use_statement_symbols.insert(
|
||||||
let to_insert = Rc::new(RefCell::new(use_statement_symbol));
|
use_statement_symbol.declared_name().to_string(),
|
||||||
let to_return = to_insert.clone();
|
Rc::new(RefCell::new(use_statement_symbol)),
|
||||||
current_scope
|
);
|
||||||
.use_statement_symbols
|
Ok(())
|
||||||
.insert(declared_name, to_insert);
|
|
||||||
Ok(to_return)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,39 +203,36 @@ impl SymbolTable {
|
|||||||
pub fn insert_function_symbol(
|
pub fn insert_function_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
function_symbol: FunctionSymbol,
|
function_symbol: FunctionSymbol,
|
||||||
) -> Result<Rc<RefCell<FunctionSymbol>>, SymbolInsertError> {
|
) -> Result<(), 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();
|
current_scope.function_symbols.insert(
|
||||||
let to_insert = Rc::new(RefCell::new(function_symbol));
|
function_symbol.declared_name().to_string(),
|
||||||
let to_return = to_insert.clone();
|
Rc::new(function_symbol),
|
||||||
current_scope
|
);
|
||||||
.function_symbols
|
Ok(())
|
||||||
.insert(declared_name, to_insert);
|
|
||||||
Ok(to_return)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_parameter_symbol(
|
pub fn insert_parameter_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
parameter_symbol: ParameterSymbol,
|
parameter_symbol: ParameterSymbol,
|
||||||
) -> Result<Rc<ParameterSymbol>, SymbolInsertError> {
|
) -> Result<(), 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);
|
current_scope.parameter_symbols.insert(
|
||||||
let to_return = to_insert.clone();
|
parameter_symbol.declared_name().to_string(),
|
||||||
current_scope
|
Rc::new(parameter_symbol),
|
||||||
.parameter_symbols
|
);
|
||||||
.insert(to_insert.declared_name().to_string(), to_insert);
|
Ok(())
|
||||||
Ok(to_return)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +254,6 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(note = "Use more specific lookup methods.")]
|
|
||||||
pub fn lookup(&self, name: &str, scope_id: usize) -> Result<Symbol, SymbolLookupError> {
|
pub fn lookup(&self, name: &str, scope_id: usize) -> Result<Symbol, SymbolLookupError> {
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
let mut scope_opt = Some(&self.scopes[scope_id]);
|
||||||
while let Some(scope) = scope_opt {
|
while let Some(scope) = scope_opt {
|
||||||
@ -358,44 +269,6 @@ impl SymbolTable {
|
|||||||
Err(NoDefinition)
|
Err(NoDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_type_by_declared_name(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Rc<TypeSymbol>, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_type_symbol_by_declared_name(declared_name) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_type_by_fqn(
|
|
||||||
&self,
|
|
||||||
fqn: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Rc<TypeSymbol>, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_type_symbol_by_fqn(fqn) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_usable_by_fqn(
|
pub fn lookup_usable_by_fqn(
|
||||||
&self,
|
&self,
|
||||||
fully_qualified_name: &str,
|
fully_qualified_name: &str,
|
||||||
@ -408,68 +281,27 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
Err(NoDefinition)
|
Err(NoDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_expressible_by_declared_name(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Symbol, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_expressible_by_declared_name(declared_name) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_expressible_by_fqn(
|
|
||||||
&self,
|
|
||||||
fqn: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Symbol, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = scope.get_expressible_by_fqn(fqn) {
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SymbolTable {
|
impl Display for SymbolTable {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
writeln!(f, "SymbolTable(current_scope = {})", self.current_scope_id)?;
|
writeln!(f, "SymbolTable(current_scope = {})", self.current_scope_id)?;
|
||||||
for (i, scope) in self.scopes.iter().enumerate() {
|
for (i, scope) in self.scopes.iter().enumerate() {
|
||||||
writeln!(f, "----Scope {} {}----", i, scope.debug_name)?;
|
writeln!(f, "Scope {} {}", i, scope.debug_name)?;
|
||||||
for symbol in scope.use_statement_symbols.values() {
|
for (name, symbol) in &scope.use_statement_symbols {
|
||||||
writeln!(f, "{:#?}", symbol.borrow())?;
|
writeln!(f, " {}({})", name, symbol.borrow())?;
|
||||||
}
|
}
|
||||||
for symbol in scope.module_symbols.values() {
|
for (name, symbol) in &scope.module_symbols {
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
writeln!(f, " {}({})", name, symbol)?;
|
||||||
}
|
}
|
||||||
for symbol in scope.type_symbols.values() {
|
for (name, symbol) in &scope.type_symbols {
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
writeln!(f, " {}({})", name, symbol)?;
|
||||||
}
|
}
|
||||||
for symbol in scope.function_symbols.values() {
|
for (name, symbol) in &scope.function_symbols {
|
||||||
writeln!(f, "{:#?}", symbol.borrow())?;
|
writeln!(f, " {}({})", name, symbol)?;
|
||||||
}
|
}
|
||||||
for symbol in scope.parameter_symbols.values() {
|
for (name, symbol) in &scope.variable_symbols {
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
writeln!(f, " {}({})", name, symbol)?;
|
||||||
}
|
|
||||||
for symbol in scope.variable_symbols.values() {
|
|
||||||
writeln!(f, "{:#?}", symbol)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Ns = { "ns" }
|
Ns = { "ns" }
|
||||||
TypeKw = { "type" }
|
TypeKw = { "type" }
|
||||||
Mod = { "mod" }
|
Mod = { "mod" }
|
||||||
IntKw = { "int" }
|
Int = { "int" }
|
||||||
ClassKw = { "class" }
|
ClassKw = { "class" }
|
||||||
Platform = { "platform" }
|
Platform = { "platform" }
|
||||||
Pub = { "pub" }
|
Pub = { "pub" }
|
||||||
@ -15,6 +15,7 @@ Ref = { "ref" }
|
|||||||
Def = { "def" }
|
Def = { "def" }
|
||||||
Where = { "where" }
|
Where = { "where" }
|
||||||
Infer = { "infer" }
|
Infer = { "infer" }
|
||||||
|
Void = { "Void" }
|
||||||
Delegate = { "delegate" }
|
Delegate = { "delegate" }
|
||||||
Let = { "let" }
|
Let = { "let" }
|
||||||
Fn = { "fn" }
|
Fn = { "fn" }
|
||||||
@ -31,25 +32,12 @@ True = { "true" }
|
|||||||
False = { "false" }
|
False = { "false" }
|
||||||
Use = { "use" }
|
Use = { "use" }
|
||||||
|
|
||||||
// Keywords: primitive types
|
|
||||||
Byte = { "Byte" }
|
|
||||||
Short = { "Short" }
|
|
||||||
Char = { "Char" }
|
|
||||||
Int = { "Int" }
|
|
||||||
Long = { "Long" }
|
|
||||||
Double = { "Double" }
|
|
||||||
Bool = { "Bool" }
|
|
||||||
String = { "String" }
|
|
||||||
Array = { "Array" }
|
|
||||||
Any = { "Any" }
|
|
||||||
Void = { "Void" }
|
|
||||||
|
|
||||||
// Keywords as a rule (for preventing identifiers with keywords, etc.)
|
// Keywords as a rule (for preventing identifiers with keywords, etc.)
|
||||||
Keyword = {
|
Keyword = {
|
||||||
Ns
|
Ns
|
||||||
| TypeKw
|
| TypeKw
|
||||||
| Mod
|
| Mod
|
||||||
| IntKw
|
| Int
|
||||||
| ClassKw
|
| ClassKw
|
||||||
| Platform
|
| Platform
|
||||||
| Pub
|
| Pub
|
||||||
@ -62,6 +50,7 @@ Keyword = {
|
|||||||
| Def
|
| Def
|
||||||
| Where
|
| Where
|
||||||
| Infer
|
| Infer
|
||||||
|
| Void
|
||||||
| Delegate
|
| Delegate
|
||||||
| Let
|
| Let
|
||||||
| Fn
|
| Fn
|
||||||
@ -77,17 +66,6 @@ Keyword = {
|
|||||||
| True
|
| True
|
||||||
| False
|
| False
|
||||||
| Use
|
| Use
|
||||||
| Byte
|
|
||||||
| Short
|
|
||||||
| Char
|
|
||||||
| Int
|
|
||||||
| Long
|
|
||||||
| Double
|
|
||||||
| Bool
|
|
||||||
| String
|
|
||||||
| Array
|
|
||||||
| Any
|
|
||||||
| Void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Symbols
|
// Symbols
|
||||||
@ -202,26 +180,12 @@ ParenthesesOptionalTypeUseList = {
|
|||||||
// Parameters = declaration
|
// Parameters = declaration
|
||||||
|
|
||||||
TypeUse = {
|
TypeUse = {
|
||||||
PrimitiveType
|
Void
|
||||||
| InterfaceOrClassTypeUse
|
| InterfaceOrClassTypeUse
|
||||||
| TupleTypeUse
|
| TupleTypeUse
|
||||||
| FunctionTypeUse
|
| FunctionTypeUse
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimitiveType = {
|
|
||||||
Byte
|
|
||||||
| Short
|
|
||||||
| Char
|
|
||||||
| Int
|
|
||||||
| Long
|
|
||||||
| Double
|
|
||||||
| Bool
|
|
||||||
| String
|
|
||||||
| Array ~ GenericArguments?
|
|
||||||
| Any
|
|
||||||
| Void
|
|
||||||
}
|
|
||||||
|
|
||||||
InterfaceOrClassTypeUse = {
|
InterfaceOrClassTypeUse = {
|
||||||
Borrow*
|
Borrow*
|
||||||
~ Mut?
|
~ Mut?
|
||||||
@ -371,7 +335,7 @@ Module = {
|
|||||||
|
|
||||||
Interface = {
|
Interface = {
|
||||||
Pub?
|
Pub?
|
||||||
~ IntKw
|
~ Int
|
||||||
~ Identifier
|
~ Identifier
|
||||||
~ GenericParameters?
|
~ GenericParameters?
|
||||||
~ ImplementsList?
|
~ ImplementsList?
|
||||||
|
@ -1,14 +1,23 @@
|
|||||||
use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol, TypeSymbol};
|
use crate::name_analysis::symbol::{FunctionSymbol, 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_function_symbol(
|
symbol_table.insert_type_symbol(TypeSymbol::new("std::core:Array", "Array", true, None))?;
|
||||||
FunctionSymbol::new("std::core::println", "println", true, true, None)
|
// todo: make this primitive
|
||||||
.with_parameters(vec![ParameterSymbol::new("msg", 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::print", "print", true, true, None)
|
"println",
|
||||||
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
true,
|
||||||
)?;
|
true,
|
||||||
|
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