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