MCPcopy Index your code
hub / github.com/aiscriptdev/aiscript / generate_class

Method generate_class

aiscript-vm/src/compiler/codegen.rs:1330–1393  ·  view source on GitHub ↗
(
        &mut self,
        ClassDecl {
            name,
            superclass,
            methods,
            visibility,
            ..
        }: ClassDecl<'gc>,
    )

Source from the content-addressed store, hash-verified

1328 }
1329
1330 fn generate_class(
1331 &mut self,
1332 ClassDecl {
1333 name,
1334 superclass,
1335 methods,
1336 visibility,
1337 ..
1338 }: ClassDecl<'gc>,
1339 ) -> Result<(), VmError> {
1340 // Emit class declaration
1341 let name_constant = self.identifier_constant(name.lexeme);
1342 self.emit(OpCode::Class(name_constant as u8));
1343 self.emit(OpCode::DefineGlobal {
1344 name_constant: name_constant as u8,
1345 visibility,
1346 });
1347
1348 let has_superclass = superclass.is_some();
1349 // Handle inheritance
1350 if let Some(superclass) = superclass {
1351 // Begin a new scope for 'super'
1352 self.begin_scope();
1353
1354 // First get the superclass
1355 self.generate_expr(superclass)?;
1356
1357 // Creating a new lexical scope ensures that if we declare two classes in the same scope,
1358 // each has a different local slot to store its superclass. Since we always name this
1359 // variable “super”, if we didn’t make a scope for each subclass, the variables would collide.
1360 let super_token = Token::new(TokenType::Super, "super", name.line);
1361 self.declare_variable(super_token, Mutability::Immutable);
1362 self.mark_initialized();
1363
1364 // Then get the class we just defined
1365 self.emit(OpCode::GetGlobal(name_constant as u8));
1366
1367 // Emit inherit instruction
1368 self.emit(OpCode::Inherit);
1369
1370 // Load class again for method definitions
1371 self.emit(OpCode::GetGlobal(name_constant as u8));
1372 } else {
1373 // Load class for method definitions
1374 self.emit(OpCode::GetGlobal(name_constant as u8));
1375 }
1376
1377 // Generate methods
1378 for method in methods {
1379 if let Stmt::Function(function_decl) = method {
1380 self.generate_method(function_decl)?;
1381 }
1382 }
1383
1384 // Once we’ve reached the end of the methods, we no longer need
1385 // the class and tell the VM to pop it off the stack.
1386 self.emit(OpCode::Pop(1));
1387

Callers 1

generate_stmtMethod · 0.80

Calls 9

ClassClass · 0.85
identifier_constantMethod · 0.80
emitMethod · 0.80
begin_scopeMethod · 0.80
generate_exprMethod · 0.80
declare_variableMethod · 0.80
mark_initializedMethod · 0.80
generate_methodMethod · 0.80
end_scopeMethod · 0.80

Tested by

no test coverage detected