public object VisitClassSTatement(Class statement) { HlangClassDeclaration parentClass = null; HlangClassDeclaration newClass = new HlangClassDeclaration(statement.Name.Lexeme); if (statement.ParentClass != null) { parentClass = (HlangClassDeclaration)Evaluate(statement.ParentClass); if (!(parentClass is HlangClassDeclaration)) { throw new RuntimeError(statement.ParentClass.Name, "Must inherit from a class"); } newClass.ClassEnv.Add("parent", parentClass); } newClass.ClassEnv.Add(newClass.Name, newClass); foreach (Function method in statement.Methods) { HlangFunction func = new HlangFunction(method, newClass.ClassEnv, method.IsPrivate); if (method.IsStatic) { newClass.ClassEnv.Add(method.Name.Lexeme, func); newClass.EnvTracker.Add(method.Name.Lexeme, new ClassField(method.Name.Lexeme, func, method.IsStatic, method.IsPrivate)); } else { newClass.Methods.Add(method.Name.Lexeme, func); } } foreach (Assign assignment in statement.Fields) { var name = assignment.Name.Lexeme; var value = Evaluate(assignment.Value); if (assignment.IsStatic) { newClass.ClassEnv.Add(name, value); newClass.EnvTracker.Add(name, new ClassField(name, value, assignment.IsStatic, assignment.IsPrivate)); } else { newClass.Fields.Add(name, new ClassField(name, value, assignment.IsStatic, assignment.IsPrivate)); } } newClass.ParentClass = parentClass; Environment.Add(statement.Name.Lexeme, newClass); return(null); }
public object VisitClassSTatement(Class statement) { _callingBodyStack.Push(CallingBody.CLASS); HlangClassDeclaration parentClass = null; var newClass = new HlangClassDeclaration(statement.Name.Lexeme); BeginSCope(); if (statement.ParentClass != null) { if (statement.Name.Lexeme == statement.ParentClass.Name.Lexeme) { throw new SemanticError(statement.Name, "Class can't inherit from itself"); } _callingBodyStack.Push(CallingBody.SUBCLASS); parentClass = (HlangClassDeclaration)Resolve(statement.ParentClass); _env.Add("parent", parentClass); } _env.Add(newClass.Name, newClass); foreach (Function method in statement.Methods) { if (method.Name.Lexeme == statement.Name.Lexeme) { ResolveFunction(method, FunctionType.INIT, CallingBody.FUNCTION); } else { ResolveFunction(method, FunctionType.METHOD, CallingBody.FUNCTION); } } EndScope(); _callingBodyStack.Pop(); newClass.ParentClass = parentClass; newClass.ClassEnv = _env; Define(statement.Name, newClass); return(null); }