Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create new type resolution system that will support new import-based namespaces #28

Merged
merged 15 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ast/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use num::BigInt;

#[derive(Clone, Debug)]
pub struct Enum {
pub name: String,
pub backing_type: Option<Type>,
pub source: Source,
pub members: IndexMap<String, EnumMember>,
Expand Down
8 changes: 4 additions & 4 deletions src/ast/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use indexmap::IndexMap;
pub struct AstFile {
pub functions: Vec<Function>,
pub structures: Vec<Structure>,
pub type_aliases: IndexMap<Name, TypeAlias>,
pub type_aliases: Vec<TypeAlias>,
pub global_variables: Vec<GlobalVar>,
pub enums: IndexMap<Name, Enum>,
pub enums: Vec<Enum>,
pub helper_exprs: IndexMap<Name, HelperExpr>,
pub settings: Option<SettingsId>,
}
Expand All @@ -21,9 +21,9 @@ impl AstFile {
AstFile {
functions: vec![],
structures: vec![],
type_aliases: IndexMap::default(),
type_aliases: vec![],
global_variables: vec![],
enums: IndexMap::default(),
enums: vec![],
helper_exprs: IndexMap::default(),
settings: None,
}
Expand Down
1 change: 1 addition & 0 deletions src/ast/type_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::source_files::Source;

#[derive(Clone, Debug)]
pub struct TypeAlias {
pub name: String,
pub value: Type,
pub source: Source,
pub privacy: Privacy,
Expand Down
36 changes: 18 additions & 18 deletions src/ast/workspace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,6 @@ pub struct AstWorkspace<'a> {
impl<'a> AstWorkspace<'a> {
pub const DEFAULT_SETTINGS_ID: SettingsId = SettingsId(0);

pub fn get_owning_module(&self, fs_node_id: FsNodeId) -> Option<FsNodeId> {
let mut fs_node_id = fs_node_id;

loop {
if self.module_folders.contains_key(&fs_node_id) {
return Some(fs_node_id);
}

if let Some(parent) = self.fs.get(fs_node_id).parent {
fs_node_id = parent;
} else {
break;
}
}

None
}

pub fn new(
fs: Fs,
files: IndexMap<FsNodeId, AstFile>,
Expand Down Expand Up @@ -70,6 +52,24 @@ impl<'a> AstWorkspace<'a> {
workspace
}

pub fn get_owning_module(&self, fs_node_id: FsNodeId) -> Option<FsNodeId> {
let mut fs_node_id = fs_node_id;

loop {
if self.module_folders.contains_key(&fs_node_id) {
return Some(fs_node_id);
}

if let Some(parent) = self.fs.get(fs_node_id).parent {
fs_node_id = parent;
} else {
break;
}
}

None
}

pub fn get_mut(&mut self, id: FsNodeId) -> Option<&mut AstFile> {
self.files.get_mut(&id)
}
Expand Down
15 changes: 6 additions & 9 deletions src/c/translation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::{
ast::{self, AstFile, Privacy},
c::parser::{CTypedef, DeclarationSpecifiers, Declarator, ParseError},
diagnostics::Diagnostics,
name::Name,
};
use std::collections::HashMap;

Expand All @@ -32,14 +31,12 @@ pub fn declare_named_declaration(
)?;

if is_typedef {
ast_file.type_aliases.insert(
Name::plain(name.clone()),
ast::TypeAlias {
value: ast_type.clone(),
source: declarator.source,
privacy: Privacy::Public,
},
);
ast_file.type_aliases.push(ast::TypeAlias {
name: name.clone(),
value: ast_type.clone(),
source: declarator.source,
privacy: Privacy::Public,
});

typedefs.insert(name, CTypedef { ast_type });
return Ok(());
Expand Down
46 changes: 22 additions & 24 deletions src/interpreter_env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,30 +106,28 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) {
privacy: Privacy::Public,
});

file.enums.insert(
Name::plain("ProjectKind"),
Enum {
backing_type: Some(TypeKind::u64().at(source)),
source,
members: IndexMap::from_iter([
(
"ConsoleApp".into(),
EnumMember {
value: (ProjectKind::ConsoleApp as u64).into(),
explicit_value: true,
},
),
(
"WindowedApp".into(),
EnumMember {
value: (ProjectKind::WindowedApp as u64).into(),
explicit_value: true,
},
),
]),
privacy: Privacy::Private,
},
);
file.enums.push(Enum {
name: "ProjectKind".into(),
backing_type: Some(TypeKind::u64().at(source)),
source,
members: IndexMap::from_iter([
(
"ConsoleApp".into(),
EnumMember {
value: (ProjectKind::ConsoleApp as u64).into(),
explicit_value: true,
},
),
(
"WindowedApp".into(),
EnumMember {
value: (ProjectKind::WindowedApp as u64).into(),
explicit_value: true,
},
),
]),
privacy: Privacy::Private,
});

file.structures.push(Structure {
name: Name::plain("Project"),
Expand Down
42 changes: 24 additions & 18 deletions src/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fn lower_global(
let mangled_name = if global.is_foreign {
global.name.plain().to_string()
} else {
global.name.display(resolved_ast.fs).to_string()
global.name.display(&resolved_ast.workspace.fs).to_string()
};

ir_module.globals.insert(
Expand Down Expand Up @@ -167,7 +167,10 @@ fn lower_function(
} else {
return Err(LowerErrorKind::MustReturnValueOfTypeBeforeExitingFunction {
return_type: function.return_type.to_string(),
function: function.name.display(resolved_ast.fs).to_string(),
function: function
.name
.display(&resolved_ast.workspace.fs)
.to_string(),
}
.at(function.source));
}
Expand Down Expand Up @@ -200,7 +203,10 @@ fn lower_function(
} else if function.is_foreign {
function.name.plain().to_string()
} else {
function.name.display(resolved_ast.fs).to_string()
function
.name
.display(&resolved_ast.workspace.fs)
.to_string()
};

let is_main = mangled_name == "main";
Expand Down Expand Up @@ -341,6 +347,7 @@ fn lower_type(
use resolved::{IntegerBits as Bits, IntegerSign as Sign};

match &resolved_type.kind {
resolved::TypeKind::Unresolved => panic!("got unresolved type during lower_type!"),
resolved::TypeKind::Boolean => Ok(ir::Type::Boolean),
resolved::TypeKind::Integer(bits, sign) => Ok(match (bits, sign) {
(Bits::Bits8, Sign::Signed) => ir::Type::S8,
Expand Down Expand Up @@ -395,14 +402,22 @@ fn lower_type(
})))
}
resolved::TypeKind::FunctionPointer(_function_pointer) => Ok(ir::Type::FunctionPointer),
resolved::TypeKind::Enum(enum_name) => {
resolved::TypeKind::Enum(_human_name, enum_ref) => {
let enum_definition = resolved_ast
.enums
.get(enum_name)
.get(*enum_ref)
.expect("referenced enum to exist");

lower_type(target, &enum_definition.resolved_type, resolved_ast)
}
resolved::TypeKind::TypeAlias(_, type_alias_ref) => {
let resolved_type = resolved_ast
.type_aliases
.get(*type_alias_ref)
.expect("referenced type alias to exist");

lower_type(target, resolved_type, resolved_ast)
}
}
}

Expand Down Expand Up @@ -888,18 +903,15 @@ fn lower_expr(
ExprKind::EnumMemberLiteral(enum_member_literal) => {
let enum_definition = resolved_ast
.enums
.get(&enum_member_literal.enum_name)
.get(enum_member_literal.enum_ref)
.expect("referenced enum to exist for enum member literal");

let member = enum_definition
.members
.get(&enum_member_literal.variant_name)
.ok_or_else(|| {
LowerErrorKind::NoSuchEnumMember {
enum_name: enum_member_literal
.enum_name
.display(resolved_ast.fs)
.to_string(),
enum_name: enum_member_literal.human_name.to_string(),
variant_name: enum_member_literal.variant_name.clone(),
}
.at(enum_member_literal.source)
Expand All @@ -916,10 +928,7 @@ fn lower_expr(
let make_error = |_| {
LowerErrorKind::CannotFit {
value: value.to_string(),
expected_type: enum_member_literal
.enum_name
.display(resolved_ast.fs)
.to_string(),
expected_type: enum_member_literal.human_name.to_string(),
}
.at(enum_definition.source)
};
Expand Down Expand Up @@ -951,10 +960,7 @@ fn lower_expr(
}
_ => {
return Err(LowerErrorKind::EnumBackingTypeMustBeInteger {
enum_name: enum_member_literal
.enum_name
.display(resolved_ast.fs)
.to_string(),
enum_name: enum_member_literal.human_name.to_string(),
}
.at(enum_definition.source))
}
Expand Down
6 changes: 3 additions & 3 deletions src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ impl Display for DisplayResolvedName<'_> {
#[allow(dead_code)]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let filename = &self.fs.get(self.name.fs_node_id).filename;
let prefix = if cfg!(target_os = "windows") { "/" } else { "" };
let prefix = if cfg!(target_os = "windows") { "" } else { "/" };

write!(
f,
"{}{} ::: {}",
"{}{} - {}",
prefix,
filename.to_string_lossy(),
self.name.plain()
self.name.plain(),
)?;

Ok(())
Expand Down
21 changes: 8 additions & 13 deletions src/parser/parse_enum.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
use super::{annotation::Annotation, error::ParseError, Parser};
use crate::{
ast::{Enum, EnumMember, Named, Privacy},
ast::{Enum, EnumMember, Privacy},
inflow::Inflow,
name::Name,
parser::annotation::AnnotationKind,
token::{Token, TokenKind},
};
use indexmap::IndexMap;
use num::{BigInt, Zero};

impl<'a, I: Inflow<Token>> Parser<'a, I> {
pub fn parse_enum(&mut self, annotations: Vec<Annotation>) -> Result<Named<Enum>, ParseError> {
pub fn parse_enum(&mut self, annotations: Vec<Annotation>) -> Result<Enum, ParseError> {
let source = self.source_here();
assert!(self.input.advance().is_enum_keyword());

let mut privacy = Privacy::Private;
let mut namespace = None;
let name = self.parse_identifier(Some("for enum name after 'enum' keyword"))?;
self.ignore_newlines();

for annotation in annotations {
match annotation.kind {
AnnotationKind::Namespace(new_namespace) => namespace = Some(new_namespace),
AnnotationKind::Public => privacy = Privacy::Public,
_ => return Err(self.unexpected_annotation(&annotation, Some("for enum"))),
}
Expand Down Expand Up @@ -58,14 +55,12 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {

self.parse_token(TokenKind::CloseParen, Some("to close enum body"))?;

Ok(Named::<Enum> {
name: Name::new(namespace, name),
value: Enum {
backing_type: None,
members,
source,
privacy,
},
Ok(Enum {
name,
backing_type: None,
members,
source,
privacy,
})
}
}
28 changes: 5 additions & 23 deletions src/parser/parse_top_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{
Parser,
};
use crate::{
ast::{AstFile, Enum, HelperExpr, Named, TypeAlias},
ast::{AstFile, HelperExpr, Named},
index_map_ext::IndexMapExt,
inflow::Inflow,
token::{Token, TokenKind},
Expand Down Expand Up @@ -60,31 +60,13 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
ast_file.structures.push(self.parse_structure(annotations)?)
}
TokenKind::TypeAliasKeyword => {
let Named::<TypeAlias> { name, value: alias } =
self.parse_type_alias(annotations)?;
let source = alias.source;

ast_file.type_aliases.try_insert(name, alias, |name| {
ParseErrorKind::TypeAliasHasMultipleDefinitions {
name: name.to_string(),
}
.at(source)
})?;
let type_alias = self.parse_type_alias(annotations)?;
ast_file.type_aliases.push(type_alias);
}
TokenKind::EnumKeyword => {
let Named::<Enum> {
name,
value: enum_definition,
} = self.parse_enum(annotations)?;
let enum_definition = self.parse_enum(annotations)?;

let source = enum_definition.source;

ast_file.enums.try_insert(name, enum_definition, |name| {
ParseErrorKind::EnumHasMultipleDefinitions {
name: name.to_string(),
}
.at(source)
})?;
ast_file.enums.push(enum_definition);
}
TokenKind::DefineKeyword => {
let Named::<HelperExpr> {
Expand Down
Loading
Loading