Skip to content

Commit

Permalink
Implemented parsing for generically named trait implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacShelton committed Dec 30, 2024
1 parent 20de27c commit 4705e27
Show file tree
Hide file tree
Showing 23 changed files with 191 additions and 98 deletions.
2 changes: 1 addition & 1 deletion src/ast/datatype/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::Type;
use crate::ast::Expr;

#[derive(Clone, Debug)]
pub enum CompileTimeArgument {
pub enum TypeArg {
Type(Type),
Expr(Expr),
}
6 changes: 3 additions & 3 deletions src/ast/datatype/kind/display.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::TypeKind;
use crate::{
ast::{fmt_c_integer, CompileTimeArgument, FloatSize, IntegerBits},
ast::{fmt_c_integer, FloatSize, IntegerBits, TypeArg},
ir::IntegerSign,
};
use itertools::Itertools;
Expand Down Expand Up @@ -41,8 +41,8 @@ impl Display for &TypeKind {

for (i, argument) in arguments.iter().enumerate() {
match argument {
CompileTimeArgument::Type(ty) => write!(f, "{}", ty)?,
CompileTimeArgument::Expr(expr) => write!(f, "({:?})", expr)?, // TODO: Implement display for ast::Expr
TypeArg::Type(ty) => write!(f, "{}", ty)?,
TypeArg::Expr(expr) => write!(f, "({:?})", expr)?, // TODO: Implement display for ast::Expr
}

if i + 1 < arguments.len() {
Expand Down
6 changes: 3 additions & 3 deletions src/ast/datatype/kind/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ mod common;
mod display;

use super::{
AnonymousEnum, AnonymousStruct, AnoymousUnion, CInteger, CompileTimeArgument, FixedArray,
FloatSize, FuncPtr, IntegerBits, IntegerSign, Type,
AnonymousEnum, AnonymousStruct, AnoymousUnion, CInteger, FixedArray, FloatSize, FuncPtr,
IntegerBits, IntegerSign, Type, TypeArg,
};
use crate::{name::Name, source_files::Source};

Expand All @@ -16,7 +16,7 @@ pub enum TypeKind {
Ptr(Box<Type>),
FixedArray(Box<FixedArray>),
Void,
Named(Name, Vec<CompileTimeArgument>),
Named(Name, Vec<TypeArg>),
AnonymousStruct(AnonymousStruct),
AnonymousUnion(AnoymousUnion),
AnonymousEnum(AnonymousEnum),
Expand Down
4 changes: 2 additions & 2 deletions src/ast/datatype/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ impl Type {
TypeKind::Named(_, args) => args
.iter()
.flat_map(|arg| match arg {
CompileTimeArgument::Type(ty) => ty.contains_polymorph(),
CompileTimeArgument::Expr(_) => todo!("ast::Type::contains_polymorph"),
TypeArg::Type(ty) => ty.contains_polymorph(),
TypeArg::Expr(_) => todo!("ast::Type::contains_polymorph"),
})
.next(),
TypeKind::AnonymousStruct(_) => None,
Expand Down
4 changes: 2 additions & 2 deletions src/ast/expr/call.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::Expr;
use crate::{
ast::{CompileTimeArgument, Type},
ast::{Type, TypeArg},
name::Name,
};

Expand All @@ -9,5 +9,5 @@ pub struct Call {
pub name: Name,
pub args: Vec<Expr>,
pub expected_to_return: Option<Type>,
pub generics: Vec<CompileTimeArgument>,
pub generics: Vec<TypeArg>,
}
3 changes: 2 additions & 1 deletion src/ast/implementation.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use super::{Func, Privacy, Type};
use super::{Func, Privacy, Type, TypeParams};
use crate::source_files::Source;

#[derive(Clone, Debug)]
pub struct Impl {
pub name: Option<String>,
pub params: TypeParams,
pub target: Type,
pub source: Source,
pub privacy: Privacy,
Expand Down
4 changes: 4 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ mod given;
mod global_variable;
mod helper_expr;
mod implementation;
mod privacy;
mod stmt;
mod structs;
mod traits;
mod type_alias;
mod type_params;
mod workspace;

pub use block::*;
Expand All @@ -26,9 +28,11 @@ pub use given::*;
pub use global_variable::*;
pub use helper_expr::*;
pub use implementation::*;
pub use privacy::*;
#[allow(unused_imports)]
pub use stmt::*;
pub use structs::*;
pub use traits::*;
pub use type_alias::*;
pub use type_params::*;
pub use workspace::*;
8 changes: 8 additions & 0 deletions src/ast/privacy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use derive_more::IsVariant;

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, IsVariant)]
pub enum Privacy {
#[default]
Public,
Private,
}
23 changes: 2 additions & 21 deletions src/ast/structs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,17 @@
use super::Type;
use super::{Privacy, Type, TypeParams};
use crate::source_files::Source;
use derive_more::IsVariant;
use indexmap::IndexMap;

#[derive(Clone, Debug)]
pub struct Struct {
pub name: String,
pub params: TypeParams,
pub fields: IndexMap<String, Field>,
pub params: IndexMap<String, TypeParameter>,
pub is_packed: bool,
pub source: Source,
pub privacy: Privacy,
}

#[derive(Clone, Debug)]
pub struct TypeParameter {
pub constraints: Vec<Type>,
}

impl TypeParameter {
pub fn new(constraints: Vec<Type>) -> Self {
Self { constraints }
}
}

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, IsVariant)]
pub enum Privacy {
#[default]
Public,
Private,
}

#[derive(Clone, Debug)]
pub struct Field {
pub ast_type: Type,
Expand Down
75 changes: 75 additions & 0 deletions src/ast/type_params.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use super::{Type, TypeArg};
use crate::source_files::Source;
use indexmap::IndexMap;

#[derive(Clone, Debug)]
pub struct TypeParam {
pub constraints: Vec<Type>,
}

impl TypeParam {
pub fn new(constraints: Vec<Type>) -> Self {
Self { constraints }
}
}

#[derive(Clone, Debug, Default)]
pub struct TypeParams {
pub params: IndexMap<String, TypeParam>,
}

impl TypeParams {
pub fn iter(&self) -> impl Iterator<Item = (&String, &TypeParam)> {
self.params.iter()
}

pub fn keys(&self) -> impl Iterator<Item = &String> {
self.params.keys()
}

pub fn values(&self) -> impl Iterator<Item = &TypeParam> {
self.params.values()
}
}

impl From<IndexMap<String, TypeParam>> for TypeParams {
fn from(params: IndexMap<String, TypeParam>) -> Self {
Self { params }
}
}

impl TryFrom<Vec<TypeArg>> for TypeParams {
type Error = (String, Source);

fn try_from(mut args: Vec<TypeArg>) -> Result<Self, Self::Error> {
let mut params = IndexMap::<String, TypeParam>::new();

for arg in args.drain(..) {
match arg {
TypeArg::Type(ty) => match ty.kind {
super::TypeKind::Polymorph(name, constraints) => {
if let Some(existing) = params.get_mut(&name) {
existing.constraints.extend(constraints);
} else {
params.insert(name, TypeParam { constraints });
}
}
_ => {
return Err((
"Cannot use non-polymorph as type parameter".into(),
ty.source,
))
}
},
TypeArg::Expr(expr) => {
return Err((
"Cannot use expression as type parameter".into(),
expr.source,
))
}
}
}

Ok(params.into())
}
}
4 changes: 2 additions & 2 deletions src/c/translation/types/composite.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::get_name_and_type;
use crate::{
ast::{AnonymousStruct, AstFile, Field, Privacy, Struct, TypeKind},
ast::{AnonymousStruct, AstFile, Field, Privacy, Struct, TypeKind, TypeParams},
c::parser::{
error::ParseErrorKind, CTypedef, Composite, CompositeKind, DeclarationSpecifiers,
MemberDeclaration, MemberDeclarator, ParseError,
Expand Down Expand Up @@ -98,9 +98,9 @@ pub fn make_composite(

ast_file.structs.push(Struct {
name: name.clone(),
params: TypeParams::default(),
fields,
is_packed,
params: IndexMap::default(),
source: composite.source,
privacy: Privacy::Private,
});
Expand Down
6 changes: 3 additions & 3 deletions src/interpreter_env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
ast::{
AstFile, Call, Enum, EnumMember, ExprKind, Field, FieldInitializer, FillBehavior, Func,
FuncHead, InterpreterSyscall, Language, Param, Params, Privacy, StmtKind, Struct,
StructLiteral, TypeKind,
StructLiteral, TypeKind, TypeParams,
},
interpreter::{
syscall_handler::{BuildSystemSyscallHandler, ProjectKind},
Expand Down Expand Up @@ -140,6 +140,7 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) {

file.structs.push(Struct {
name: "Project".into(),
params: TypeParams::default(),
fields: IndexMap::from_iter([(
"kind".into(),
Field {
Expand All @@ -148,14 +149,14 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) {
source,
},
)]),
params: IndexMap::default(),
is_packed: false,
source,
privacy: Privacy::Private,
});

file.structs.push(Struct {
name: "Dependency".into(),
params: TypeParams::default(),
fields: IndexMap::from_iter([(
"name".into(),
Field {
Expand All @@ -164,7 +165,6 @@ pub fn setup_build_system_interpreter_symbols(file: &mut AstFile) {
source,
},
)]),
params: IndexMap::default(),
is_packed: false,
source,
privacy: Privacy::Private,
Expand Down
2 changes: 1 addition & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ mod parse_top_level;
mod parse_trait;
mod parse_type;
mod parse_type_alias;
mod parse_type_parameters;
mod parse_type_params;
mod parse_util;

use self::error::ParseError;
Expand Down
2 changes: 1 addition & 1 deletion src/parser/parse_expr/post/member.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
let source = self.parse_token(TokenKind::Member, Some("for member expression"))?;
let member_name = self.parse_name(Some("for member name"))?;

let generics = self.parse_generics()?;
let generics = self.parse_type_args()?;

if !generics.is_empty()
|| self.input.peek_is(TokenKind::OpenParen)
Expand Down
10 changes: 5 additions & 5 deletions src/parser/parse_expr/primary/call.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::Parser;
use crate::{
ast::{Call, CompileTimeArgument, Expr, ExprKind},
ast::{Call, Expr, ExprKind, TypeArg},
inflow::Inflow,
name::Name,
parser::error::ParseError,
Expand All @@ -12,7 +12,7 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
pub fn parse_call(
&mut self,
name: Name,
generics: Vec<CompileTimeArgument>,
generics: Vec<TypeArg>,
source: Source,
) -> Result<Expr, ParseError> {
self.parse_call_raw_with(name, generics, vec![])
Expand All @@ -22,7 +22,7 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
pub fn parse_call_with(
&mut self,
name: Name,
generics: Vec<CompileTimeArgument>,
generics: Vec<TypeArg>,
prefix_args: Vec<Expr>,
source: Source,
) -> Result<Expr, ParseError> {
Expand All @@ -33,15 +33,15 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
pub fn parse_call_raw(
&mut self,
name: Name,
generics: Vec<CompileTimeArgument>,
generics: Vec<TypeArg>,
) -> Result<Call, ParseError> {
self.parse_call_raw_with(name, generics, vec![])
}

pub fn parse_call_raw_with(
&mut self,
name: Name,
generics: Vec<CompileTimeArgument>,
generics: Vec<TypeArg>,
prefix_args: Vec<Expr>,
) -> Result<Call, ParseError> {
// function_name(arg1, arg2, arg3)
Expand Down
2 changes: 1 addition & 1 deletion src/parser/parse_expr/primary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
// namespaces and generic parsing that applies to all cases

let name = self.parse_name(None::<&str>).unwrap();
let generics = self.parse_generics()?;
let generics = self.parse_type_args()?;

match self.input.peek().kind {
TokenKind::StaticMember => self.parse_static_member(name, generics, source),
Expand Down
9 changes: 3 additions & 6 deletions src/parser/parse_expr/primary/static_member.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use super::Parser;
use crate::{
ast::{
CompileTimeArgument, Expr, ExprKind, StaticMember, StaticMemberAction,
StaticMemberActionKind,
},
ast::{Expr, ExprKind, StaticMember, StaticMemberAction, StaticMemberActionKind, TypeArg},
inflow::Inflow,
name::Name,
parser::error::{ParseError, ParseErrorKind},
Expand All @@ -15,7 +12,7 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
pub fn parse_static_member(
&mut self,
type_name: Name,
generics: Vec<CompileTimeArgument>,
generics: Vec<TypeArg>,
source: Source,
) -> Result<Expr, ParseError> {
// EnumName::EnumVariant
Expand All @@ -35,7 +32,7 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
|| self.input.peek_is(TokenKind::OpenAngle)
{
let name = Name::plain(action_name);
let generics = self.parse_generics()?;
let generics = self.parse_type_args()?;
StaticMemberActionKind::Call(self.parse_call_raw(name, generics)?)
} else {
StaticMemberActionKind::Value(action_name)
Expand Down
Loading

0 comments on commit 4705e27

Please sign in to comment.