public override object Get(Token name) { if (Fields.ContainsKey(name.Lexeme)) { var foundField = Fields[name.Lexeme]; if (foundField.IsPrivate) { throw new RuntimeError(name, $"'{name.Lexeme}' is inaccessible due to it's protection level"); } return(foundField.Value); } HlangFunction method = GetMethod(name); if (method != null) { return(method.Bind(this)); } if (ParentClass != null) { return(ParentClass.Get(name)); } throw new RuntimeError(name, $"Can't get undefined property '{name.Lexeme}'"); }
/// <summary> /// Execute new function statement. Adds function to environment /// </summary> /// <param name="statement">Function statement to add</param> public object visitFunctionStatement(Function statement) { HlangFunction function = new HlangFunction(statement, Environment); Environment.Add(statement.Name.Lexeme, function); return(null); }
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); }