add get-enum-vals (#737)

This commit is contained in:
water111
2021-08-02 22:01:10 -04:00
committed by GitHub
parent 906db513cd
commit 4d76d2f11a
5 changed files with 58 additions and 1 deletions
+2 -1
View File
@@ -186,4 +186,5 @@
- Inline arrays of structures are now allowed with `stack-no-clear`.
- Creating arrays on the stack now must be done with `stack-no-clear` as they are not memset to 0 or constructed in any way.
- The register allocator has been dramatically improved and generates ~5x fewer spill instructions and is able to eliminate more moves.
- Added a `(print-debug-compiler-stats)` form to print out statistics related to register allocation and move elimination
- Added a `(print-debug-compiler-stats)` form to print out statistics related to register allocation and move elimination
- Added `get-enum-vals` which returns a list of pairs. Each pair is the name (symbol) and value (int) for each value in the enum
+35
View File
@@ -34,6 +34,9 @@ Compiler::Compiler(std::unique_ptr<ReplWrapper> repl)
if (m_repl) {
m_repl->load_history();
}
// add GOOS forms that get info from the compiler
setup_goos_forms();
}
ReplStatus Compiler::execute_repl(bool auto_listen) {
@@ -445,4 +448,36 @@ void Compiler::typecheck_reg_type_allow_false(const goos::Object& form,
bool Compiler::knows_object_file(const std::string& name) {
return m_debugger.knows_object(name);
}
void Compiler::setup_goos_forms() {
m_goos.register_form("get-enum-vals", [&](const goos::Object& form, goos::Arguments& args,
const std::shared_ptr<goos::EnvironmentObject>& env) {
m_goos.eval_args(&args, env);
va_check(form, args, {goos::ObjectType::SYMBOL}, {});
std::vector<Object> enum_vals;
const auto& enum_name = args.unnamed.at(0).as_symbol()->name;
auto enum_type = m_ts.try_enum_lookup(enum_name);
if (!enum_type) {
throw_compiler_error(form, "Unknown enum {} in get-enum-vals", enum_name);
}
std::vector<std::pair<std::string, s64>> sorted_values;
for (auto& val : enum_type->entries()) {
sorted_values.emplace_back(val.first, val.second);
}
std::sort(sorted_values.begin(), sorted_values.end(),
[](const std::pair<std::string, s64>& a, const std::pair<std::string, s64>& b) {
return a.second < b.second;
});
for (auto& thing : sorted_values) {
enum_vals.push_back(PairObject::make_new(m_goos.intern(thing.first),
goos::Object::make_integer(thing.second)));
}
return goos::build_list(enum_vals);
});
}
+1
View File
@@ -87,6 +87,7 @@ class Compiler {
int funcs_requiring_v1_allocator = 0;
} m_debug_stats;
void setup_goos_forms();
std::set<std::string> lookup_symbol_infos_starting_with(const std::string& prefix) const;
std::vector<SymbolInfo>* lookup_exact_name_info(const std::string& name) const;
bool get_true_or_false(const goos::Object& form, const goos::Object& boolean);
@@ -0,0 +1,14 @@
(defenum test-val-enum
(thing1 1)
(thing3 3)
(thing5 5)
)
(defmacro test-enum-vals ()
(let ((enum-list (get-enum-vals 'test-val-enum)))
`(quote ,enum-list)
)
)
(printl (test-enum-vals))
0
+6
View File
@@ -824,6 +824,12 @@ TEST_F(WithGameTests, StackInlineArray) {
"#x30\n0\n"});
}
TEST_F(WithGameTests, GetEnumVals) {
runner.run_static_test(env, testCategory, "test-get-enum-vals.gc",
{"((thing1 . #<invalid object #x1>) (thing3 . #<invalid object #x3>) "
"(thing5 . #<invalid object #x5>))\n0\n"});
}
TEST(TypeConsistency, TypeConsistency) {
Compiler compiler;
compiler.enable_throw_on_redefines();