1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Collections.Generic; 9 using System.Linq; 10 using Antmicro.Renode.PlatformDescription.Syntax; 11 using Sprache; 12 13 namespace Antmicro.Renode.PlatformDescription 14 { 15 public sealed class VariableStore 16 { VariableStore()17 public VariableStore() 18 { 19 globalVariables = new Dictionary<string, Variable>(); 20 localVariables = new Dictionary<Tuple<string, string>, Variable>(); 21 } 22 AddBuiltinOrAlreadyRegisteredVariable(string name, object value)23 public void AddBuiltinOrAlreadyRegisteredVariable(string name, object value) 24 { 25 var variable = new Variable(value.GetType(), DeclarationPlace.BuiltinOrAlreadyRegistered) { Value = value }; 26 globalVariables.Add(name, variable); 27 } 28 DeclareVariable(string name, Type type, Position position, bool local = false)29 public Variable DeclareVariable(string name, Type type, Position position, bool local = false) 30 { 31 var variable = new Variable(type, new DeclarationPlace(position, CurrentScope)); 32 if(local) 33 { 34 localVariables.Add(Tuple.Create(CurrentScope, name), variable); 35 return variable; 36 } 37 globalVariables.Add(name, variable); 38 return variable; 39 } 40 TryGetVariableInLocalScope(string name, out Variable variable)41 public bool TryGetVariableInLocalScope(string name, out Variable variable) 42 { 43 return globalVariables.TryGetValue(name, out variable) || localVariables.TryGetValue(Tuple.Create(CurrentScope, name), out variable); 44 } 45 GetVariableInLocalScope(string name)46 public Variable GetVariableInLocalScope(string name) 47 { 48 Variable result; 49 if(!TryGetVariableInLocalScope(name, out result)) 50 { 51 throw new KeyNotFoundException(string.Format("No variable named '{0}' in local scope.", name)); 52 } 53 return result; 54 } 55 TryGetVariableFromReference(ReferenceValue reference, out Variable variable)56 public bool TryGetVariableFromReference(ReferenceValue reference, out Variable variable) 57 { 58 return globalVariables.TryGetValue(reference.Value, out variable) || 59 localVariables.TryGetValue(Tuple.Create(reference.Scope, reference.Value), out variable); 60 } 61 GetVariableFromReference(ReferenceValue reference)62 public Variable GetVariableFromReference(ReferenceValue reference) 63 { 64 Variable result; 65 if(!TryGetVariableFromReference(reference, out result)) 66 { 67 throw new KeyNotFoundException(string.Format("No variable from reference '{0}'.", reference)); 68 } 69 return result; 70 } 71 GetMergedEntries()72 public IEnumerable<Entry> GetMergedEntries() 73 { 74 var result = new List<Entry>(); 75 foreach(var variable in globalVariables.Select(x => x.Value).Concat(localVariables.Select(x => x.Value))) 76 { 77 var mergedEntry = variable.GetMergedEntry(); 78 if(mergedEntry != null) 79 { 80 result.Add(mergedEntry); 81 } 82 } 83 return result; 84 } 85 Clear()86 public void Clear() 87 { 88 CurrentScope = null; 89 globalVariables.Clear(); 90 localVariables.Clear(); 91 } 92 93 public string CurrentScope { get; set; } 94 95 private readonly Dictionary<string, Variable> globalVariables; 96 private readonly Dictionary<Tuple<string, string>, Variable> localVariables; 97 } 98 } 99