public object visit_super(SuperExpr super_expr) { // Get the superclass and the 'this' object PlutoClass superclass = (PlutoClass)local_scope.get(new Token(Token.Type.Super, "super")); PlutoObject obj = (PlutoObject)local_scope.get(new Token(Token.Type.This, "this")); // Get the method from the superclass PlutoFunction method = superclass.find_method(obj, (string)super_expr.identifier.value); if (method == null) { throw new RuntimeException("Undefined method of superclass '" + super_expr.identifier.value + "'"); } return(method); }
// Get a method or member public object get(Token identifier) { // Check class methods PlutoFunction method = the_class.find_method(this, (string)identifier.value); if (method != null) { return(method); } // Check object members object member = find_member((string)identifier.value); if (member != null) { return(member); } throw new RuntimeException("Class member/method cannot be found '" + identifier.value + "'"); }
public void visit_trycatch(TryCatchStmt trycatch_stmt) { try { execute(trycatch_stmt.try_body); }catch (PlutoException exception) { PlutoFunction function = new PlutoFunction(trycatch_stmt.catch_body, this.local_scope, false); // We want to create a new instance of a plutoexception here Callable exception_class = (Callable)namespaces["exception"].get(new Token(Token.Type.Identifier, "Exception")); function.call(this, new List <object>() { exception_class.call(this, new List <object>() { "[Caught Exception] " + exception.error_msg }) } );; } }
public void visit_class(ClassStmt class_stmt) { object superclass = null; // Check if we have a superclass, and if so, evaluate that if (class_stmt.superclass != null) { superclass = evaluate(class_stmt.superclass); if (!(superclass is PlutoClass)) { throw new RuntimeException("Superclass must be a class type"); } } this.local_scope.define((string)class_stmt.name.value, null); if (class_stmt.superclass != null) { // Create a new scope for the superclass class local_scope = new Scope(local_scope); // Define super as the superclass local_scope.define("super", superclass); } // Create a dictionary of methods for the class Dictionary <string, PlutoFunction> methods = new Dictionary <string, PlutoFunction>(); foreach (FunctionStmt method in class_stmt.methods) { bool is_constructor = ((string)method.name.value) == (string)class_stmt.name.value; PlutoFunction function = new PlutoFunction(method, this.local_scope, is_constructor); methods.Add((string)method.name.value, function); } // Create the class object and assign it to the scope PlutoClass p_class = new PlutoClass((string)class_stmt.name.value, (PlutoClass)superclass, methods); if (superclass != null) { // Reset the scope local_scope = local_scope.enclosing_scope; } local_scope.assign(class_stmt.name, p_class); }
public void visit_function(FunctionStmt function_stmt) { PlutoFunction func = new PlutoFunction(function_stmt, this.local_scope, false); local_scope.define((string)function_stmt.name.value, func); }