Small state fixes (#901)

* small fixes

* catch uncaught exception
This commit is contained in:
water111
2021-10-15 21:31:22 -04:00
committed by GitHub
parent 08e98b49c6
commit f87646e8ce
7 changed files with 118 additions and 18 deletions
+48
View File
@@ -1,4 +1,5 @@
#include "state.h"
#include "common/type_system/TypeSystem.h"
/*!
* Convert a (state <blah> ...) to the function required to go. Must be state.
@@ -81,4 +82,51 @@ TypeSpec get_state_handler_type(StateHandler kind, const TypeSpec& state_type) {
}
result.add_or_modify_tag("behavior", state_type.last_arg().base_type());
return result;
}
namespace {
TypeSpec func_to_state_type(const TypeSpec& func_type, const TypeSpec& proc_type) {
TypeSpec result("state");
for (int i = 0; i < ((int)func_type.arg_count()) - 1; i++) {
result.add_arg(func_type.get_arg(i));
}
result.add_arg(proc_type);
return result;
}
} // namespace
std::optional<TypeSpec> get_state_type_from_enter_and_code(const TypeSpec& enter_func_type,
const TypeSpec& code_func_type,
const TypeSpec& proc_type,
const TypeSystem& ts) {
bool enter_real_func =
enter_func_type.base_type() == "function" && enter_func_type.arg_count() > 0;
bool code_real_func = code_func_type.base_type() == "function" && code_func_type.arg_count() > 0;
if (enter_real_func && code_real_func) {
int i = 0;
TypeSpec result("state");
for (; i < std::min((int)enter_func_type.arg_count(), (int)code_func_type.arg_count()) - 1;
i++) {
result.add_arg(
ts.lowest_common_ancestor(enter_func_type.get_arg(i), code_func_type.get_arg(i)));
}
for (; i < ((int)enter_func_type.arg_count()) - 1; i++) {
result.add_arg(enter_func_type.get_arg(i));
}
for (; i < ((int)code_func_type.arg_count()) - 1; i++) {
result.add_arg(code_func_type.get_arg(i));
}
result.add_arg(proc_type);
return result;
} else if (enter_real_func) {
return func_to_state_type(enter_func_type, proc_type);
} else if (code_real_func) {
return func_to_state_type(code_func_type, proc_type);
} else {
return {};
}
}
+9 -1
View File
@@ -1,5 +1,6 @@
#pragma once
#include <optional>
#include "common/type_system/TypeSpec.h"
/*!
@@ -8,8 +9,15 @@
enum class StateHandler { ENTER, EXIT, CODE, TRANS, POST, EVENT };
class TypeSystem;
TypeSpec state_to_go_function(const TypeSpec& state_type);
StateHandler handler_name_to_kind(const std::string& name);
std::string handler_kind_to_name(StateHandler kind);
TypeSpec get_state_handler_type(const std::string& handler_name, const TypeSpec& state_type);
TypeSpec get_state_handler_type(StateHandler kind, const TypeSpec& state_type);
TypeSpec get_state_handler_type(StateHandler kind, const TypeSpec& state_type);
std::optional<TypeSpec> get_state_type_from_enter_and_code(const TypeSpec& enter_func_type,
const TypeSpec& code_func_type,
const TypeSpec& proc_type,
const TypeSystem& ts);
+12 -3
View File
@@ -2700,9 +2700,18 @@ void FunctionCallElement::update_from_stack(const Env& env,
std::swap(all_pop_vars.at(0), all_pop_vars.at(1));
}
if (tp_type.kind == TP_Type::Kind::RUN_FUNCTION_IN_PROCESS_FUNCTION &&
unstacked.at(0)->to_string(env) == "run-function-in-process") {
unstacked.at(0) = pool.form<ConstantTokenElement>("run-now-in-process");
if (tp_type.kind == TP_Type::Kind::RUN_FUNCTION_IN_PROCESS_FUNCTION) {
if (unstacked.at(0)->to_string(env) == "run-function-in-process") {
unstacked.at(0) = pool.form<ConstantTokenElement>("run-now-in-process");
} else {
// couldn't pop. need to add a cast.
TypeSpec failed_cast("function");
for (int i = 0; i < ((int)unstacked.size()) - 1; i++) {
failed_cast.add_arg(TypeSpec("object"));
}
failed_cast.add_arg(TypeSpec("none"));
unstacked.at(0) = pool.form<CastElement>(failed_cast, unstacked.at(0));
}
}
if (tp_type.kind == TP_Type::Kind::SET_TO_RUN_FUNCTION) {
+8 -1
View File
@@ -26,7 +26,14 @@ int main(int argc, char** argv) {
}
// collect all files to process
auto config = read_config_file(argv[1]);
Config config;
try {
config = read_config_file(argv[1]);
} catch (const std::exception& e) {
lg::error("Failed to parse config");
return 1;
}
std::string in_folder = argv[2];
std::string out_folder = argv[3];
+23 -10
View File
@@ -60,20 +60,33 @@ Val* Compiler::compile_define_state_hook(const goos::Object& form,
do_set(form, code_field, code_value->to_gpr(form, env), code_value, env);
// state name
TypeSpec state_type("state");
auto state_type = get_state_type_from_enter_and_code(enter_value->type(), code_value->type(),
state_parent_type, m_ts);
for (int i = 0; i < (int)code_value->type().arg_count() - 1; i++) {
state_type.add_arg(code_value->type().get_arg(i));
}
state_type.add_arg(state_parent_type);
auto state_name = args.unnamed.at(0).as_symbol()->name;
auto existing_var = m_symbol_types.find(state_name);
if (existing_var != m_symbol_types.end() && existing_var->second != state_type) {
throw_compiler_error(form, "define-state would redefine the type of symbol {} from {} to {}",
state_name, existing_var->second.print(), state_type.print());
TypeSpec type_to_use;
if (existing_var == m_symbol_types.end()) {
// we're a new state. we must have a type.
if (!state_type) {
throw_compiler_error(form,
"define-state doesn't have enough information to determine the type of "
"state {}, and it was not forward declared.",
state_name);
}
type_to_use = *state_type;
m_symbol_types[state_name] = *state_type;
} else {
type_to_use = existing_var->second;
if (state_type) {
typecheck(form, existing_var->second, *state_type,
fmt::format("type of state {}", state_name));
}
}
m_symbol_types[state_name] = state_type;
auto sym_val = env->function_env()->alloc_val<SymbolVal>(state_name, state_type);
auto sym_val = env->function_env()->alloc_val<SymbolVal>(state_name, type_to_use);
env->emit_ir<IR_SetSymbolValue>(form, sym_val, state_object);
return get_none();
+17 -2
View File
@@ -476,7 +476,10 @@
)
)
)
(s2-1
((the-as
(function object object object object object object object object none)
s2-1
)
s1-0
s0-0
(the-as sparticle-launch-group s3-0)
@@ -577,7 +580,19 @@
)
)
)
(s2-3 s1-2 s0-2 s3-0 sv-224 sv-240 sv-256 sv-272 t3-1)
((the-as
(function object object object object object object object object none)
s2-3
)
s1-2
s0-2
s3-0
sv-224
sv-240
sv-256
sv-272
t3-1
)
)
)
(-> s4-3 ppointer)
+1 -1
View File
@@ -293,7 +293,7 @@ CompareResult compare(Decompiler& dc, const std::vector<DecompilerFile>& refs, b
compare_result.failing_files.push_back(file.unique_name);
compare_result.total_pass = false;
fmt::print("Reference test failure on {}:\n", file.unique_name);
fmt::print("{}\n", diff_strings(result, ref));
fmt::print("{}\n", diff_strings(ref, result));
if (dump_mode) {
file_util::create_dir_if_needed("./failures");