• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rieske / trans / 28379938466

29 Jun 2026 02:35PM UTC coverage: 90.44% (-0.2%) from 90.635%
28379938466

push

github

web-flow
Merge pull request #41 from rieske/feature/file-scope-globals

Add file-scope global variables

300 of 358 new or added lines in 19 files covered. (83.8%)

8 existing lines in 2 files now uncovered.

5052 of 5586 relevant lines covered (90.44%)

242657.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.48
/src/semantic_analyzer/SymbolTable.cpp
1
#include "SymbolTable.h"
2
#include "util/Logger.h"
3
#include "util/LogManager.h"
4

5
namespace {
6

7
static Logger& out = LogManager::getOutputLogger();
8

9
const std::string LABEL_PREFIX = "__L";
10
unsigned nextLabel { 0 };
11

12
const std::string CONSTANT_PREFIX = "$c";
13
unsigned nextConstant { 0 };
14

15
std::string generateLabelName() {
596✔
16
    return LABEL_PREFIX + std::to_string(++nextLabel);
596✔
17
}
18

19
std::string generateConstantName() {
774✔
20
    return CONSTANT_PREFIX + std::to_string(++nextConstant);
774✔
21
}
22

23
} // namespace
24

25
namespace semantic_analyzer {
26

27
const std::string SymbolTable::SCOPE_PREFIX = "$s";
28

29
bool SymbolTable::insertSymbol(std::string name, const type::Type& type, translation_unit::Context context) {
606✔
30
    if (isAtFileScope()) {
606✔
31
        return globalScope.insertSymbol(name, type, context, true);
86✔
32
    }
33
    return functionScopes.back().insertSymbol(scopePrefix(currentScopeId()) + name, type, context);
520✔
34
}
35

36
std::string SymbolTable::newConstant(const std::string& value) {
774✔
37
    std::string constantSymbol = generateConstantName();
774✔
38
    constants.insert({constantSymbol, value});
774✔
39
    return constantSymbol;
774✔
40
}
×
41

42
void SymbolTable::insertFunctionArgument(std::string name, type::Type type, translation_unit::Context context) {
166✔
43
    functionScopes.back().insertFunctionArgument(scopePrefix(currentScopeId()) + name, type, context);
166✔
44
}
166✔
45

46
FunctionEntry SymbolTable::insertFunction(std::string name, type::Function functionType, translation_unit::Context context) {
1,164✔
47
    FunctionEntry function = functions.insert(std::make_pair(name, FunctionEntry { name, functionType, context })).first->second;
1,164✔
48
    globalScope.insertSymbol(function.getName(), type::function(functionType.getReturnType(), functionType.getArguments()), function.getContext());
1,164✔
49
    return function;
1,164✔
50
}
×
51

52
FunctionEntry SymbolTable::findFunction(std::string name) const {
1,764✔
53
    return functions.at(name);
1,764✔
54
}
55

56
bool SymbolTable::hasFunction(const std::string& name) const {
532✔
57
    return functions.find(name) != functions.end();
532✔
58
}
59

60
bool SymbolTable::isAtFileScope() const {
1,254✔
61
    return scopeIdStack.empty();
1,254✔
62
}
63

64
bool SymbolTable::hasGlobalVariable(const std::string& name) const {
446✔
65
    try {
66
        return !globalScope.lookup(name).getType().isFunction();
890✔
67
    } catch (std::out_of_range&) {
444✔
68
        return false;
444✔
69
    }
444✔
70
}
71

72
void SymbolTable::setGlobalInitializer(const std::string& name, long constantValue) {
28✔
73
    globalScope.setConstantInitializer(name, constantValue);
28✔
74
}
28✔
75

76
bool SymbolTable::hasSymbol(std::string symbolName) const {
2,560✔
77
    try {
78
        lookup(symbolName);
2,562✔
79
        return true;
2,558✔
80
    } catch (std::out_of_range&) {
2✔
81
        return false;
2✔
82
    }
2✔
83
}
84

85
ValueEntry SymbolTable::lookup(std::string name) const {
5,724✔
86
    if (!functionScopes.empty()) {
5,724✔
87
        for (auto it = scopeIdStack.rbegin(); it != scopeIdStack.rend(); ++it) {
8,232✔
88
            try {
89
                return functionScopes.back().lookup(scopePrefix(*it) + name);
11,306✔
90
            } catch (std::out_of_range&) {
2,594✔
91
            }
2,594✔
92
        }
93
    }
94
    return globalScope.lookup(name);
2,200✔
95
}
96

97
ValueEntry SymbolTable::createTemporarySymbol(type::Type type) {
3,782✔
98
    if (functionScopes.empty()) {
3,782✔
99
        return globalScope.createTemporarySymbol(type);
76✔
100
    }
101
    return functionScopes.back().createTemporarySymbol(type);
3,706✔
102
}
103

104
LabelEntry SymbolTable::newLabel() {
596✔
105
    std::string labelName = generateLabelName();
596✔
106
    LabelEntry label { labelName };
596✔
107
    labels.insert(std::make_pair(labelName, label));
596✔
108
    return label;
1,192✔
109
}
596✔
110

111
void SymbolTable::startFunction(std::string name, std::vector<std::string> formalArguments) {
444✔
112
    functionScopes.push_back(ValueScope { });
444✔
113
    scopeIdStack.clear();
444✔
114
    scopeIdStack.push_back(++nextScopeId);
444✔
115
    auto function = findFunction(name);
444✔
116
    size_t i { 0 };
444✔
117
    for (auto& argument : function.arguments()) {
610✔
118
        if (i < formalArguments.size()) {
166✔
119
            insertFunctionArgument(formalArguments.at(i), argument, function.getContext());
166✔
120
        }
121
        ++i;
166✔
122
    }
444✔
123
}
444✔
124

125
void SymbolTable::endFunction() {
444✔
126
    scopeIdStack.clear();
444✔
127
}
444✔
128

129
void SymbolTable::enterBlockScope() {
112✔
130
    scopeIdStack.push_back(++nextScopeId);
112✔
131
}
112✔
132

133
void SymbolTable::exitBlockScope() {
112✔
134
    scopeIdStack.pop_back();
112✔
135
}
112✔
136

137
unsigned SymbolTable::currentScopeId() const {
686✔
138
    return scopeIdStack.back();
686✔
139
}
140

141
std::map<std::string, ValueEntry> SymbolTable::getCurrentScopeSymbols() const {
444✔
142
    return functionScopes.back().getSymbols();
444✔
143
}
144

145
std::vector<ValueEntry> SymbolTable::getCurrentScopeArguments() const {
444✔
146
    return functionScopes.back().getArguments();
444✔
147
}
148

149
std::map<std::string, std::string> SymbolTable::getConstants() const {
348✔
150
    return constants;
348✔
151
}
152

153
std::vector<ValueEntry> SymbolTable::getGlobalVariables() const {
348✔
154
    std::vector<ValueEntry> globals;
348✔
155
    for (const auto& entry : globalScope.getSymbols()) {
1,634✔
156
        if (entry.second.isGlobal()) {
1,286✔
157
            globals.push_back(entry.second);
84✔
158
        }
159
    }
348✔
160
    return globals;
348✔
NEW
161
}
×
162

163
void SymbolTable::printTable() const {
348✔
164
    for (auto constant : constants) {
1,118✔
165
        out << "\t" << constant.first << "\t\t\t\t" << constant.second << "\n";
770✔
166
    }
770✔
167
    for (auto function : functions) {
1,474✔
168
        out << "\t" << function.first << "\t\t\t\t" << function.second.getType().to_string() << "\n";
1,126✔
169
    }
1,126✔
170
    for (auto label : labels) {
944✔
171
        out << "\t" << label.second.getName() << "\t\ttemp\t0\t\tlabel\n";
596✔
172
    }
596✔
173
    for (unsigned i = 0; i < functionScopes.size(); i++) {
778✔
174
        out << "BEGIN SCOPE\n"
430✔
175
            << "--arguments--\n";
430✔
176
        for (const auto& value : functionScopes[i].getArguments()) {
594✔
177
            out << value.to_string();
164✔
178
        }
430✔
179
        out << "--locals--\n";
430✔
180
        for (const auto& value : functionScopes[i].getSymbols()) {
4,618✔
181
            out << value.second.to_string();
4,188✔
182
        }
430✔
183
        out << "END SCOPE\n";
430✔
184
    }
185
}
348✔
186

187
std::string SymbolTable::scopePrefix(unsigned scopeId) const {
6,804✔
188
    return SCOPE_PREFIX + std::to_string(scopeId);
6,804✔
189
}
190

191
} // namespace semantic_analyzer
192

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc