Skip to content

Commit

Permalink
fix: parse annotations for data types
Browse files Browse the repository at this point in the history
  • Loading branch information
jac3km4 committed Mar 26, 2024
1 parent f6f5dec commit 5c35e1b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
27 changes: 14 additions & 13 deletions compiler/src/parser.rs
Expand Up @@ -29,17 +29,18 @@ pub enum SourceEntry {
impl SourceEntry {
pub fn annotations(&self) -> &[Annotation] {
match self {
Self::Class(class) => &class.declaration.annotations,
Self::Struct(class) => &class.declaration.annotations,
Self::Function(fun) => &fun.declaration.annotations,
Self::GlobalLet(field) => &field.declaration.annotations,
_ => &[],
Self::Enum(enum_) => &enum_.declaration.annotations,
}
}
}

#[derive(Debug)]
pub struct ClassSource {
pub qualifiers: Qualifiers,
pub name: Ident,
pub declaration: Declaration,
pub base: Option<Ident>,
pub members: Vec<MemberSource>,
pub span: Span,
Expand Down Expand Up @@ -76,7 +77,7 @@ pub struct ParameterSource {

#[derive(Debug)]
pub struct EnumSource {
pub name: Ident,
pub declaration: Declaration,
pub members: Vec<EnumMember>,
pub span: Span,
}
Expand Down Expand Up @@ -298,21 +299,21 @@ peg::parser! {
rule extends() -> Ident = keyword("extends") _ name:ident() { name }

pub rule class() -> ClassSource
= pos:pos() qualifiers:qualifiers() _ keyword("class") _ name:ident() _ base:extends()? _ "{" _ members:member()**_ _ "}" end:pos()
{ ClassSource { qualifiers, name, base, members, span: Span::new(pos, end) } }
= pos:pos() declaration:decl(<keyword("class")>) _ base:extends()? _ "{" _ members:member()**_ _ "}" end:pos()
{ ClassSource { declaration, base, members, span: Span::new(pos, end) } }

pub rule struct_() -> ClassSource
= pos:pos() qualifiers:qualifiers() _ keyword("struct") _ name:ident() _ "{" _ members:member()**_ _ "}" end:pos()
{ ClassSource { qualifiers, name, base: None, members, span: Span::new(pos, end) } }
= pos:pos() declaration:decl(<keyword("struct")>) _ "{" _ members:member()**_ _ "}" end:pos()
{ ClassSource { declaration, base: None, members, span: Span::new(pos, end) } }

rule member() -> MemberSource
= fun:function() { MemberSource::Function(fun) }
/ field:field() { MemberSource::Field(field) }
/ expected!("a method or a field")

pub rule enum_() -> EnumSource
= pos:pos() keyword("enum") _ name:ident() _ "{" _ members:commasep(<enum_member()>) _ ","? _ "}" end:pos()
{ EnumSource { name, members, span: Span::new(pos, end) } }
= pos:pos() declaration:decl(<keyword("enum")>) _ "{" _ members:commasep(<enum_member()>) _ ","? _ "}" end:pos()
{ EnumSource { declaration, members, span: Span::new(pos, end) } }

rule enum_member() -> EnumMember
= name:ident() _ "=" _ value:number()
Expand Down Expand Up @@ -520,7 +521,7 @@ mod tests {
.unwrap();
assert_eq!(
format!("{:?}", module.entries),
r#"[Class(ClassSource { qualifiers: Qualifiers([Public]), name: "A", base: Some("IScriptable"), members: [Field(FieldSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Private, Const]), name: "m_field", span: Span { low: Pos(53), high: Pos(78) } }, type_: TypeName { name: "Int32", arguments: None }, default: None }), Function(FunctionSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Public]), name: "GetField", span: Span { low: Pos(104), high: Pos(124) } }, type_: Some(TypeName { name: "Int32", arguments: None }), parameters: [], body: Some(Seq { exprs: [Return(Some(Member(This(Span { low: Pos(165), high: Pos(169) }), "m_field", Span { low: Pos(165), high: Pos(177) })), Span { low: Pos(158), high: Pos(178) })] }), span: Span { low: Pos(104), high: Pos(196) } })], span: Span { low: Pos(0), high: Pos(211) } })]"#
r#"[Class(ClassSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Public]), name: "A", span: Span { low: Pos(0), high: Pos(14) } }, base: Some("IScriptable"), members: [Field(FieldSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Private, Const]), name: "m_field", span: Span { low: Pos(53), high: Pos(78) } }, type_: TypeName { name: "Int32", arguments: None }, default: None }), Function(FunctionSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Public]), name: "GetField", span: Span { low: Pos(104), high: Pos(124) } }, type_: Some(TypeName { name: "Int32", arguments: None }), parameters: [], body: Some(Seq { exprs: [Return(Some(Member(This(Span { low: Pos(165), high: Pos(169) }), "m_field", Span { low: Pos(165), high: Pos(177) })), Span { low: Pos(158), high: Pos(178) })] }), span: Span { low: Pos(104), high: Pos(196) } })], span: Span { low: Pos(0), high: Pos(211) } })]"#
);
}

Expand Down Expand Up @@ -630,7 +631,7 @@ mod tests {
.unwrap();
assert_eq!(
format!("{:?}", module.entries),
r#"[Class(ClassSource { qualifiers: Qualifiers([]), name: "Test", base: None, members: [Field(FieldSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Private]), name: "m_field", span: Span { low: Pos(130), high: Pos(149) } }, type_: TypeName { name: "String", arguments: None }, default: None })], span: Span { low: Pos(101), high: Pos(189) } })]"#
r#"[Class(ClassSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([]), name: "Test", span: Span { low: Pos(101), high: Pos(111) } }, base: None, members: [Field(FieldSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Private]), name: "m_field", span: Span { low: Pos(130), high: Pos(149) } }, type_: TypeName { name: "String", arguments: None }, default: None })], span: Span { low: Pos(101), high: Pos(189) } })]"#
);
}

Expand All @@ -648,7 +649,7 @@ mod tests {
.unwrap();
assert_eq!(
format!("{:?}", module.entries),
r#"[Class(ClassSource { qualifiers: Qualifiers([]), name: "Test", base: None, members: [Field(FieldSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Private]), name: "m_field", span: Span { low: Pos(114), high: Pos(133) } }, type_: TypeName { name: "String", arguments: None }, default: None })], span: Span { low: Pos(13), high: Pos(156) } })]"#
r#"[Class(ClassSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([]), name: "Test", span: Span { low: Pos(13), high: Pos(23) } }, base: None, members: [Field(FieldSource { declaration: Declaration { annotations: [], qualifiers: Qualifiers([Private]), name: "m_field", span: Span { low: Pos(114), high: Pos(133) } }, type_: TypeName { name: "String", arguments: None }, default: None })], span: Span { low: Pos(13), high: Pos(156) } })]"#
);
}

Expand Down
28 changes: 16 additions & 12 deletions compiler/src/unit.rs
Expand Up @@ -333,8 +333,9 @@ impl<'a> CompilationUnit<'a> {
fn define_symbol(&mut self, entry: SourceEntry, module: &ModulePath, permissive: bool) -> Result<Slot, Error> {
match entry {
SourceEntry::Class(source) => {
let path = module.with_child(source.name.clone());
let visibility = source.qualifiers.visibility().unwrap_or(Visibility::Private);
let decl = &source.declaration;
let path = module.with_child(decl.name.clone());
let visibility = decl.qualifiers.visibility().unwrap_or(Visibility::Private);

if let Ok(Symbol::Class(_, _) | Symbol::Struct(_, _)) =
self.symbols.get_symbol(&path).with_span(source.span)
Expand All @@ -351,7 +352,7 @@ impl<'a> CompilationUnit<'a> {
// add to globals when no module
if module.is_empty() {
self.scope
.add_symbol(source.name.clone(), Symbol::Class(index, visibility));
.add_symbol(decl.name.clone(), Symbol::Class(index, visibility));
}

let slot = Slot::Class {
Expand All @@ -362,8 +363,9 @@ impl<'a> CompilationUnit<'a> {
Ok(slot)
}
SourceEntry::Struct(source) => {
let path = module.with_child(source.name.clone());
let visibility = source.qualifiers.visibility().unwrap_or(Visibility::Private);
let decl = &source.declaration;
let path = module.with_child(decl.name.clone());
let visibility = decl.qualifiers.visibility().unwrap_or(Visibility::Private);

if let Ok(Symbol::Class(_, _) | Symbol::Struct(_, _)) =
self.symbols.get_symbol(&path).with_span(source.span)
Expand All @@ -380,7 +382,7 @@ impl<'a> CompilationUnit<'a> {
// add to globals when no module
if module.is_empty() {
self.scope
.add_symbol(source.name.clone(), Symbol::Struct(index, visibility));
.add_symbol(decl.name.clone(), Symbol::Struct(index, visibility));
}

let slot = Slot::Struct {
Expand Down Expand Up @@ -411,15 +413,16 @@ impl<'a> CompilationUnit<'a> {
Ok(slot)
}
SourceEntry::Enum(source) => {
let path = module.with_child(source.name.clone());
let decl = &source.declaration;
let path = module.with_child(decl.name.clone());
let name_index = self.pool.names.add(path.render().to_heap());
let index = self.pool.stub_definition(name_index);

self.symbols.add_enum(&path, index);

// add to globals when no module
if module.is_empty() {
self.scope.add_symbol(source.name.clone(), Symbol::Enum(index));
self.scope.add_symbol(decl.name.clone(), Symbol::Enum(index));
}

let slot = Slot::Enum { index, source };
Expand All @@ -439,10 +442,11 @@ impl<'a> CompilationUnit<'a> {
scope: &mut Scope,
ctx: &cte::Context,
) -> Result<(), Error> {
let is_import_only = source.qualifiers.contain(Qualifier::ImportOnly);
let is_class_native = is_import_only || source.qualifiers.contain(Qualifier::Native);
let is_class_abstract = !is_struct && source.qualifiers.contain(Qualifier::Abstract);
let is_class_final = source.qualifiers.contain(Qualifier::Final);
let qualifiers = &source.declaration.qualifiers;
let is_import_only = qualifiers.contain(Qualifier::ImportOnly);
let is_class_native = is_import_only || qualifiers.contain(Qualifier::Native);
let is_class_abstract = !is_struct && qualifiers.contain(Qualifier::Abstract);
let is_class_final = qualifiers.contain(Qualifier::Final);

let flags = ClassFlags::new()
.with_is_abstract(is_class_abstract)
Expand Down

0 comments on commit 5c35e1b

Please sign in to comment.