Skip to content

Commit

Permalink
Fix an issue with classes that lack type definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
jac3km4 committed Apr 9, 2021
1 parent e3c254d commit 9ffa48f
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 11 deletions.
2 changes: 1 addition & 1 deletion compiler/src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ impl Assembler {
}
},
Expr::MethodCall(expr, fun_idx, args, _) => match *expr {
Expr::Ident(Reference::Class(_), pos) => {
Expr::Ident(Reference::Class(_) | Reference::Struct(_), pos) => {
let fun = pool.function(fun_idx)?;
if fun.flags.is_static() {
self.assemble_call(fun_idx, args, scope, pool, true)?
Expand Down
1 change: 1 addition & 0 deletions compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ pub enum Reference {
Local(PoolIndex<Local>),
Parameter(PoolIndex<Parameter>),
Class(PoolIndex<Class>),
Struct(PoolIndex<Class>),
Enum(PoolIndex<Enum>),
}

Expand Down
24 changes: 14 additions & 10 deletions compiler/src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ impl Scope {
.filter_map(|(idx, def)| {
let ident = Ident::Owned(pool.definition_name(idx).ok()?);
match def.value {
DefinitionValue::Class(ref class) if class.flags.is_struct() => {
Some((ident, Reference::Struct(idx.cast())))
}
DefinitionValue::Class(_) => Some((ident, Reference::Class(idx.cast()))),
DefinitionValue::Enum(_) => Some((ident, Reference::Enum(idx.cast()))),
_ => None,
Expand Down Expand Up @@ -229,7 +232,12 @@ impl Scope {
("wref", [nested]) => TypeId::WeakRef(Box::new(self.resolve_type(nested, pool, pos)?)),
("script_ref", [nested]) => TypeId::ScriptRef(Box::new(self.resolve_type(nested, pool, pos)?)),
("array", [nested]) => TypeId::Array(Box::new(self.resolve_type(nested, pool, pos)?)),
_ => return Err(Error::CompileError(format!("Unresolved type {}", name), pos)),
_ => match self.references.get(&name.repr()) {
Some(Reference::Class(idx)) => TypeId::Class(*idx),
Some(Reference::Struct(idx)) => TypeId::Struct(*idx),
Some(Reference::Enum(idx)) => TypeId::Enum(*idx),
_ => return Err(Error::CompileError(format!("Unresolved type {}", name), pos)),
},
}
};
Ok(result)
Expand All @@ -245,15 +253,11 @@ impl Scope {
Type::Prim => TypeId::Prim(index),
Type::Class => {
let ident = Ident::Owned(pool.definition_name(index)?);
if let Some(Reference::Class(class_idx)) = self.references.get(&ident) {
match pool.class(*class_idx) {
Ok(class) if class.flags.is_struct() => TypeId::Struct(*class_idx),
_ => TypeId::Class(*class_idx),
}
} else if let Some(Reference::Enum(enum_idx)) = self.references.get(&ident) {
TypeId::Enum(*enum_idx)
} else {
return Err(Error::CompileError(format!("Class {} not found", ident), pos));
match self.references.get(&ident) {
Some(Reference::Class(class_idx)) => TypeId::Class(*class_idx),
Some(Reference::Struct(struct_idx)) => TypeId::Struct(*struct_idx),
Some(Reference::Enum(enum_idx)) => TypeId::Enum(*enum_idx),
_ => return Err(Error::CompileError(format!("Unresolved reference to {}", ident), pos)),
}
}
Type::Ref(type_) => {
Expand Down
1 change: 1 addition & 0 deletions compiler/src/typechecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ pub fn type_of(expr: &Expr<TypedAst>, scope: &Scope, pool: &ConstantPool) -> Res
Reference::Local(idx) => scope.resolve_type_from_pool(pool.local(*idx)?.type_, pool, *pos)?,
Reference::Parameter(idx) => scope.resolve_type_from_pool(pool.parameter(*idx)?.type_, pool, *pos)?,
Reference::Class(idx) => TypeId::Class(*idx),
Reference::Struct(idx) => TypeId::Struct(*idx),
Reference::Enum(idx) => TypeId::Enum(*idx),
},
Expr::Constant(cons, pos) => match cons {
Expand Down

0 comments on commit 9ffa48f

Please sign in to comment.