-
Notifications
You must be signed in to change notification settings - Fork 8
Add extending to classes #67
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -214,10 +214,14 @@ impl Compiler { | |
| if let Expr::PropertyAccess { object, property: _ } = &callee.node { | ||
| let (target_local, target_global) = match &object.node { | ||
| Expr::Identifier(name) => { | ||
| match self.scope.resolve(name) { | ||
| Variable::Local(index) => (Some(index), None), | ||
| Variable::Global(_) => (None, Some(name.to_string())), | ||
| } | ||
| if name == "super" { | ||
| (Some(0), None) | ||
| } else { | ||
| match self.scope.resolve(name) { | ||
| Variable::Local(index) => (Some(index), None), | ||
| Variable::Global(_) => (None, Some(name.to_string())), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| _ => (None, None), | ||
|
|
@@ -230,11 +234,15 @@ impl Compiler { | |
| } | ||
|
|
||
| Expr::PropertyAccess { object, property } => { | ||
| self.compile_expr(*object.clone())?; | ||
| self.emit(Instruction::GetProperty(property.clone()), span); | ||
| if matches!(&object.node, Expr::Identifier(n) if n == "super") { | ||
| self.emit(Instruction::LoadLocal(0), span); | ||
| self.emit(Instruction::GetSuper(property.clone()), span); | ||
| } else { | ||
| self.compile_expr(*object.clone())?; | ||
| self.emit(Instruction::GetProperty(property.clone()), span); | ||
| } | ||
|
Comment on lines
+237
to
+243
|
||
| } | ||
|
|
||
|
|
||
| Expr::IndexAccess { object, index } => { | ||
| self.compile_expr(*object.clone())?; | ||
| self.compile_expr(*index.clone())?; | ||
|
|
@@ -655,7 +663,7 @@ impl Compiler { | |
| self.emit(Instruction::Import { path: name.clone(), alias: alias.clone() }, span); | ||
| } | ||
|
|
||
| Expr::Class { name, methods } => { | ||
| Expr::Class { name, methods, parent } => { | ||
| let mut methods_map = HashMap::new(); | ||
|
|
||
| for f in methods { | ||
|
|
@@ -696,10 +704,19 @@ impl Compiler { | |
| } | ||
| } | ||
|
|
||
| let class_value = Value::Class { name: name.clone(), methods: methods_map }; | ||
| let class_value = Value::Class { name: name.clone(), methods: methods_map, parent_methods: HashMap::new() }; | ||
| let index = self.add_constant(class_value); | ||
|
|
||
| self.emit(Instruction::Push(index), span); | ||
|
|
||
| if let Some(name) = parent { | ||
| match self.scope.resolve(&name) { | ||
| Variable::Local(index) => self.emit(Instruction::LoadLocal(index), span), | ||
| Variable::Global(name) => self.emit(Instruction::LoadGlobal(name), span), | ||
| } | ||
|
|
||
| self.emit(Instruction::Extend, span); | ||
| } | ||
|
|
||
| self.store_variable(name, span); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For
super.method()calls, the compiler hard-codestarget_local = Some(0). Outside a class method this slot may not exist or won’t be the receiver being invoked, which can lead to incorrectself_targetreplacement behavior on return. Consider reusing the same compile-time validation as forsuperproperty access (only allow in methods where local 0 isself) and otherwise emit a compile error.