From 39980c2d1cb9d76e08fe022a9568bf191f472c48 Mon Sep 17 00:00:00 2001 From: water Date: Tue, 29 Jun 2021 20:04:26 -0400 Subject: [PATCH 1/3] fix a few small bugs --- common/goos/Reader.cpp | 53 ++- common/goos/Reader.h | 7 +- common/type_system/TypeSystem.cpp | 2 +- common/util/Trie.h | 14 +- decompiler/IR2/FormExpressionAnalysis.cpp | 8 +- decompiler/util/data_decompile.cpp | 2 + goal_src/engine/entity/entity-table.gc | 341 +++++++++--------- goal_src/kernel/gkernel.gc | 18 +- goalc/compiler/Compiler.h | 2 + goalc/compiler/SymbolInfo.h | 6 +- .../compiler/compilation/CompilerControl.cpp | 25 +- goalc/compiler/compilation/ControlFlow.cpp | 4 + .../reference/engine/anim/aligner-h_REF.gc | 17 +- .../engine/entity/entity-table_REF.gc | 17 +- .../reference/kernel/gkernel_REF.gc | 18 +- .../reference/kernel/gstring_REF.gc | 78 ++-- .../source_templates/kernel/kernel-test.gc | 3 +- 17 files changed, 329 insertions(+), 286 deletions(-) diff --git a/common/goos/Reader.cpp b/common/goos/Reader.cpp index 1bc27248c7..7783854126 100644 --- a/common/goos/Reader.cpp +++ b/common/goos/Reader.cpp @@ -110,27 +110,38 @@ Reader::Reader() { add_reader_macro(",@", "unquote-splicing"); // setup table of which characters are valid for starting a symbol - for (auto& x : valid_symbols_chars) { + for (auto& x : m_valid_symbols_chars) { x = false; } for (char x = 'a'; x <= 'z'; x++) { - valid_symbols_chars[(int)x] = true; + m_valid_symbols_chars[(int)x] = true; } for (char x = 'A'; x <= 'Z'; x++) { - valid_symbols_chars[(int)x] = true; + m_valid_symbols_chars[(int)x] = true; } for (char x = '0'; x <= '9'; x++) { - valid_symbols_chars[(int)x] = true; + m_valid_symbols_chars[(int)x] = true; } const char bonus[] = "!$%&*+-/\\.,@^_-;:<>?~=#"; for (const char* c = bonus; *c; c++) { - valid_symbols_chars[(int)*c] = true; + m_valid_symbols_chars[(int)*c] = true; } + + // table of characters that are valid in source code: + for (auto& x : m_valid_source_text_chars) { + x = false; + } + for (int i = ' '; i <= '~'; i++) { + m_valid_source_text_chars[i] = true; + } + m_valid_source_text_chars[(int)'\n'] = true; + m_valid_source_text_chars[(int)'\t'] = true; + m_valid_source_text_chars[(int)'\r'] = true; } /*! @@ -190,6 +201,17 @@ Object Reader::read_from_file(const std::vector& file_path) { * Common read for a SourceText */ Object Reader::internal_read(std::shared_ptr text, bool add_top_level) { + // validate the input; + for (int offset = 0; offset < text->get_size(); offset++) { + if (!m_valid_source_text_chars[(u8)text->get_text()[offset]]) { + // failed. + int line_number = text->get_line_idx(offset) + 1; + throw std::runtime_error(fmt::format("Invalid character found on line {} of {}: 0x{:x}", + line_number, text->get_description(), + (u32)text->get_text()[offset])); + } + } + // first create stream TextStream ts(text); @@ -205,6 +227,15 @@ Object Reader::internal_read(std::shared_ptr text, bool add_top_leve } } +bool Reader::check_string_is_valid(const std::string& str) const { + for (auto c : str) { + if (!m_valid_source_text_chars[(u8)c]) { + return false; + } + } + return true; +} + /*! * Given a stream starting at the first character of a token, get the token. Doesn't consume * whitespace at the end and leaves the stream on the first character after the token. @@ -258,7 +289,7 @@ Token Reader::get_next_token(TextStream& stream) { * These are used to make 'x turn into (quote x) and similar. */ void Reader::add_reader_macro(const std::string& shortcut, std::string replacement) { - reader_macros[shortcut] = std::move(replacement); + m_reader_macros[shortcut] = std::move(replacement); } /*! @@ -377,16 +408,16 @@ Object Reader::read_list(TextStream& ts, bool expect_close_paren) { // reader macro thing: std::vector reader_macro_string_stack; - auto kv = reader_macros.find(tok.text); - if (kv != reader_macros.end()) { - while (kv != reader_macros.end()) { + auto kv = m_reader_macros.find(tok.text); + if (kv != m_reader_macros.end()) { + while (kv != m_reader_macros.end()) { // build a stack of reader macros to apply to this form. reader_macro_string_stack.push_back(kv->second); if (!ts.text_remains()) { throw_reader_error(ts, "Something must follow a reader macro", 0); } tok = get_next_token(ts); - kv = reader_macros.find(tok.text); + kv = m_reader_macros.find(tok.text); } } else { // only look for the dot when we aren't following a quote. @@ -506,7 +537,7 @@ bool Reader::try_token_as_symbol(const Token& tok, Object& obj) { // check start character is valid: assert(!tok.text.empty()); char start = tok.text[0]; - if (valid_symbols_chars[(int)start]) { + if (m_valid_symbols_chars[(int)start]) { obj = SymbolObject::make_new(symbolTable, tok.text); return true; } else { diff --git a/common/goos/Reader.h b/common/goos/Reader.h index 09dcc734a1..12e9ddab84 100644 --- a/common/goos/Reader.h +++ b/common/goos/Reader.h @@ -73,7 +73,7 @@ class Reader { Object read_from_string(const std::string& str, bool add_top_level = true); std::optional read_from_stdin(const std::string& prompt, ReplWrapper& repl); Object read_from_file(const std::vector& file_path); - + bool check_string_is_valid(const std::string& str) const; std::string get_source_dir(); SymbolTable symbolTable; @@ -97,9 +97,10 @@ class Reader { bool read_string(TextStream& stream, Object& obj); void add_reader_macro(const std::string& shortcut, std::string replacement); - char valid_symbols_chars[256]; + bool m_valid_symbols_chars[256]; + bool m_valid_source_text_chars[256]; - std::unordered_map reader_macros; + std::unordered_map m_reader_macros; }; std::string get_readable_string(const char* in); diff --git a/common/type_system/TypeSystem.cpp b/common/type_system/TypeSystem.cpp index b4036a40de..89bb97321f 100644 --- a/common/type_system/TypeSystem.cpp +++ b/common/type_system/TypeSystem.cpp @@ -161,7 +161,7 @@ void TypeSystem::forward_declare_type_as(const std::string& new_type, auto old_parent_it = m_types.find(fwd_it->second); auto new_parent_it = m_types.find(parent_type); - auto old_ts = TypeSpec(old_parent_it->second->get_name()); + auto old_ts = TypeSpec(fwd_it->second); if (old_parent_it != m_types.end() && new_parent_it != m_types.end()) { auto new_ts = TypeSpec(new_parent_it->second->get_name()); diff --git a/common/util/Trie.h b/common/util/Trie.h index aa81216430..4e633e26e7 100644 --- a/common/util/Trie.h +++ b/common/util/Trie.h @@ -27,13 +27,13 @@ class Trie { T* operator[](const std::string& str); // Lookup an existing object. If none exists, return nullptr. - T* lookup(const std::string& str); + T* lookup(const std::string& str) const; // return the number of entries. int size() const { return m_size; } // Get all objects starting with the given prefix. - std::vector lookup_prefix(const std::string& str); + std::vector lookup_prefix(const std::string& str) const; ~Trie(); private: @@ -111,7 +111,7 @@ class Trie { } } - T* lookup(const char* str) { + T* lookup(const char* str) const { if (!*str) { return value; } @@ -121,7 +121,7 @@ class Trie { return nullptr; } - void get_all_children(std::vector& result) { + void get_all_children(std::vector& result) const { if (value) { result.push_back(value); } @@ -132,7 +132,7 @@ class Trie { } } - std::vector lookup_prefix(const char* str) { + std::vector lookup_prefix(const char* str) const { if (!*str) { std::vector result; get_all_children(result); @@ -165,7 +165,7 @@ void Trie::insert(const std::string& str, const T& obj) { } template -T* Trie::lookup(const std::string& str) { +T* Trie::lookup(const std::string& str) const { return m_root.lookup(str.c_str()); } @@ -180,6 +180,6 @@ T* Trie::operator[](const std::string& str) { } template -std::vector Trie::lookup_prefix(const std::string& str) { +std::vector Trie::lookup_prefix(const std::string& str) const { return m_root.lookup_prefix(str.c_str()); } \ No newline at end of file diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index 1acd9b92a9..37bf16f136 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -3187,10 +3187,14 @@ void ReturnElement::push_to_stack(const Env& env, FormPool& pool, FormStack& sta std::vector new_entries; new_entries = rewrite_to_get_var(temp_stack, pool, env.end_var(), env); + assert(!new_entries.empty()); return_code->clear(); - for (auto e : new_entries) { - return_code->push_back(e); + + for (int i = 0; i < ((int)new_entries.size()) - 1; i++) { + stack.push_form_element(new_entries.at(i), true); } + + return_code->push_back(new_entries.back()); stack.push_form_element(this, true); } diff --git a/decompiler/util/data_decompile.cpp b/decompiler/util/data_decompile.cpp index 3b9c7f4fd7..011470d401 100644 --- a/decompiler/util/data_decompile.cpp +++ b/decompiler/util/data_decompile.cpp @@ -724,6 +724,8 @@ goos::Object decompile_boxed_array(const DecompilerLabel& label, } else if (word.kind == LinkedWord::PTR) { result.push_back( decompile_at_label(content_type, labels.at(word.label_id), labels, words, ts)); + } else if (word.kind == LinkedWord::SYM_PTR) { + result.push_back(pretty_print::to_symbol(fmt::format("'{}", word.symbol_name))); } else { throw std::runtime_error( fmt::format("Unknown content type in boxed array of references, word idx {}", diff --git a/goal_src/engine/entity/entity-table.gc b/goal_src/engine/entity/entity-table.gc index 67543495b5..1e4130d59b 100644 --- a/goal_src/engine/entity/entity-table.gc +++ b/goal_src/engine/entity/entity-table.gc @@ -5,182 +5,175 @@ ;; name in dgo: entity-table ;; dgos: GAME, ENGINE -;; definition for symbol *entity-info*, type (array entity-info) -(define - *entity-info* - (the-as (array entity-info) - (new - 'static - 'boxed-array - :type entity-info :length 19 :allocated-length 19 - (new 'static 'entity-info - :ptype - (type-ref sage-finalboss :method-count 53) - :package "l1" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x8000 - ) - (new 'static 'entity-info - :ptype (type-ref robotboss :method-count 21) - :package "l1" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x8000 - ) - (new 'static 'entity-info - :ptype - (type-ref assistant-levitator :method-count 53) - :package "l1" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x8000 - ) - (new 'static 'entity-info - :ptype (type-ref babak :method-count 76) - :package "l1" - :art-group '("babak") - :pool '*16k-dead-pool* - :heap-size #x2800 - ) - (new 'static 'entity-info - :ptype (type-ref racer :method-count 24) - :package "game" - :art-group '("racer") - :pool '*16k-dead-pool* - :heap-size #x4000 - ) - (new 'static 'entity-info - :ptype (type-ref springbox :method-count 20) - :package "game" - :art-group '("bounceytarp") - :pool '*16k-dead-pool* - :heap-size #x1400 - ) - (new 'static 'entity-info - :ptype (type-ref launcher :method-count 20) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x400 - ) - (new 'static 'entity-info - :ptype - (type-ref pickup-spawner :method-count 30) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #xc00 - ) - (new 'static 'entity-info - :ptype (type-ref bucket :method-count 30) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #xc00 - ) - (new 'static 'entity-info - :ptype (type-ref barrel :method-count 30) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #xc00 - ) - (new 'static 'entity-info - :ptype (type-ref crate :method-count 30) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #xc00 - ) - (new 'static 'entity-info - :ptype - (type-ref orb-cache-top :method-count 29) - :package "game" - :art-group '("orb-cache-top") - :pool '*16k-dead-pool* - :heap-size #x1000 - ) - (new 'static 'entity-info - :ptype (type-ref eco :method-count 31) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x1000 - ) - (new 'static 'entity-info - :ptype (type-ref ecovent :method-count 21) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x1000 - ) - (new 'static 'entity-info - :ptype (type-ref fuel-cell :method-count 31) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x1400 - ) - (new 'static 'entity-info - :ptype (type-ref buzzer :method-count 31) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x1000 - ) - (new 'static 'entity-info - :ptype (type-ref money :method-count 31) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x800 - ) - (new 'static 'entity-info - :ptype (type-ref water-vol :method-count 30) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #xc00 - ) - (new 'static 'entity-info - :ptype - (type-ref target-start :method-count 15) - :package "game" - :art-group '() - :pool '*16k-dead-pool* - :heap-size #x400 - ) - ) - ) +(define *entity-info* + (new 'static 'boxed-array :type entity-info :length 19 :allocated-length 19 + (new 'static 'entity-info + :ptype + (type-ref sage-finalboss :method-count 53) + :package "l1" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x8000 + ) + (new 'static 'entity-info + :ptype (type-ref robotboss :method-count 21) + :package "l1" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x8000 + ) + (new 'static 'entity-info + :ptype + (type-ref assistant-levitator :method-count 53) + :package "l1" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x8000 + ) + (new 'static 'entity-info + :ptype (type-ref babak :method-count 76) + :package "l1" + :art-group '("babak") + :pool '*16k-dead-pool* + :heap-size #x2800 + ) + (new 'static 'entity-info + :ptype (type-ref racer :method-count 24) + :package "game" + :art-group '("racer") + :pool '*16k-dead-pool* + :heap-size #x4000 + ) + (new 'static 'entity-info + :ptype (type-ref springbox :method-count 20) + :package "game" + :art-group '("bounceytarp") + :pool '*16k-dead-pool* + :heap-size #x1400 + ) + (new 'static 'entity-info + :ptype (type-ref launcher :method-count 20) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x400 + ) + (new 'static 'entity-info + :ptype + (type-ref pickup-spawner :method-count 30) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #xc00 + ) + (new 'static 'entity-info + :ptype (type-ref bucket :method-count 30) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #xc00 + ) + (new 'static 'entity-info + :ptype (type-ref barrel :method-count 30) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #xc00 + ) + (new 'static 'entity-info + :ptype (type-ref crate :method-count 30) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #xc00 + ) + (new 'static 'entity-info + :ptype + (type-ref orb-cache-top :method-count 29) + :package "game" + :art-group '("orb-cache-top") + :pool '*16k-dead-pool* + :heap-size #x1000 + ) + (new 'static 'entity-info + :ptype (type-ref eco :method-count 31) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x1000 + ) + (new 'static 'entity-info + :ptype (type-ref ecovent :method-count 21) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x1000 + ) + (new 'static 'entity-info + :ptype (type-ref fuel-cell :method-count 31) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x1400 + ) + (new 'static 'entity-info + :ptype (type-ref buzzer :method-count 31) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x1000 + ) + (new 'static 'entity-info + :ptype (type-ref money :method-count 31) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x800 + ) + (new 'static 'entity-info + :ptype (type-ref water-vol :method-count 30) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #xc00 + ) + (new 'static 'entity-info + :ptype + (type-ref target-start :method-count 15) + :package "game" + :art-group '() + :pool '*16k-dead-pool* + :heap-size #x400 + ) + ) ) -;; definition for function entity-info-lookup -;; INFO: Return type mismatch basic vs entity-info. (defun entity-info-lookup ((arg0 type)) - (the-as entity-info (cond - ((nonzero? (-> arg0 method-table 13)) - (-> arg0 method-table 13) - ) - (else - (let ((v1-1 *entity-info*)) - (dotimes (a1-0 (-> v1-1 length)) - (if (= arg0 (-> v1-1 a1-0 ptype)) - (return (begin - (set! - (-> arg0 method-table 13) - (the-as function (-> v1-1 a1-0)) - ) - (-> v1-1 a1-0) - ) - ) - ) - ) - ) - (set! (-> arg0 method-table 13) #f) - #f - ) - ) - ) + "Look up the entity-info for a given type. + to speed-up the lookup in the future, + this caches the result in the method table..." + (the-as entity-info + (cond + ((nonzero? (-> arg0 method-table 13)) + (-> arg0 method-table 13) + ) + (else + (let ((v1-1 *entity-info*)) + (dotimes (a1-0 (-> v1-1 length)) + (when (= arg0 (-> v1-1 a1-0 ptype)) + (set! + (-> arg0 method-table 13) + (the-as function (-> v1-1 a1-0)) + ) + (return (-> v1-1 a1-0)) + ) + ) + ) + (set! (-> arg0 method-table 13) #f) + #f + ) + ) + ) ) + diff --git a/goal_src/kernel/gkernel.gc b/goal_src/kernel/gkernel.gc index 74cd3550af..50d23a848f 100644 --- a/goal_src/kernel/gkernel.gc +++ b/goal_src/kernel/gkernel.gc @@ -108,6 +108,13 @@ ;; without executing anything, to find a process for instance. (define *null-kernel-context* (new 'static 'kernel-context)) +(#when PC_PORT + ;; We will move stacks on the scratchpad to here. + ;; it might be possible to also throw them on the *dram-stack*, but they might depend on these + ;; not overlapping. We can spare the 16k of memory. + (define *fake-scratchpad-stack* (new 'global 'array 'uint8 (* 16 1024))) + ) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Thread and CPU Thread @@ -1699,7 +1706,7 @@ ;; check for deadness (when (eq? (-> obj status) 'dead) (set! (-> context current-process) #f) - (return-from #f 'dead) + (return 'dead) ) ) ) @@ -1732,7 +1739,7 @@ (when (eq? (-> obj status) 'dead) ;; oops we died. (set! (-> context current-process) #f) - (return-from #f 'dead) + (return 'dead) ) (set! (-> obj status) 'suspended) ) @@ -2200,6 +2207,13 @@ (defmethod activate process ((obj process) (dest process-tree) (name basic) (stack-top pointer)) "Activate a process! Put it on the given active tree and set up the main thread." + (#when PC_PORT + (when (= stack-top *scratch-memory-top*) + ;; (format #t "Process ~A requested a stack on the scratchpad, moving to fake scratch~%") + (set! stack-top (&+ *fake-scratchpad-stack* (* 16 1024))) + ) + ) + (set! (-> obj mask) (logand (-> dest mask) PROCESS_CLEAR_MASK)) (set! (-> obj status) 'ready) (let ((pid (-> *kernel-context* next-pid))) diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index fed49a3f09..8f6ef2268d 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -58,6 +58,8 @@ class Compiler { std::vector> const& user_data); private: + std::set lookup_symbol_infos_starting_with(const std::string& prefix) const; + std::vector* lookup_exact_name_info(const std::string& name) const; bool get_true_or_false(const goos::Object& form, const goos::Object& boolean); bool try_getting_macro_from_goos(const goos::Object& macro_name, goos::Object* dest); bool expand_macro_once(const goos::Object& src, goos::Object* out, Env* env); diff --git a/goalc/compiler/SymbolInfo.h b/goalc/compiler/SymbolInfo.h index 91d96769c5..997bae7727 100644 --- a/goalc/compiler/SymbolInfo.h +++ b/goalc/compiler/SymbolInfo.h @@ -150,9 +150,11 @@ class SymbolInfoMap { m_map[method_name]->push_back(SymbolInfo::make_method(method_name, type_name, defining_form)); } - std::vector* lookup_exact_name(const std::string& name) { return m_map.lookup(name); } + std::vector* lookup_exact_name(const std::string& name) const { + return m_map.lookup(name); + } - std::set lookup_symbols_starting_with(const std::string& prefix) { + std::set lookup_symbols_starting_with(const std::string& prefix) const { std::set result; auto lookup = m_map.lookup_prefix(prefix); for (auto& x : lookup) { diff --git a/goalc/compiler/compilation/CompilerControl.cpp b/goalc/compiler/compilation/CompilerControl.cpp index ae0b561b66..5b3b9c73df 100644 --- a/goalc/compiler/compilation/CompilerControl.cpp +++ b/goalc/compiler/compilation/CompilerControl.cpp @@ -427,8 +427,8 @@ Replxx::completions_t Compiler::find_symbols_by_prefix(std::string const& contex std::vector const& user_data) { (void)contextLen; (void)user_data; - auto token = m_repl.get()->get_current_repl_token(context); - auto possible_forms = m_symbol_info.lookup_symbols_starting_with(token.first); + auto token = m_repl->get_current_repl_token(context); + auto possible_forms = lookup_symbol_infos_starting_with(token.first); Replxx::completions_t completions; for (auto& x : possible_forms) { completions.push_back(token.second ? "(" + x : x); @@ -442,8 +442,8 @@ Replxx::hints_t Compiler::find_hints_by_prefix(std::string const& context, std::vector const& user_data) { (void)contextLen; (void)user_data; - auto token = m_repl.get()->get_current_repl_token(context); - auto possible_forms = m_symbol_info.lookup_symbols_starting_with(token.first); + auto token = m_repl->get_current_repl_token(context); + auto possible_forms = lookup_symbol_infos_starting_with(token.first); Replxx::hints_t hints; @@ -482,7 +482,7 @@ void Compiler::repl_coloring( curr_symbol.second.erase(0, 1); curr_symbol.first++; } - std::vector* sym_match = m_symbol_info.lookup_exact_name(curr_symbol.second); + std::vector* sym_match = lookup_exact_name_info(curr_symbol.second); if (sym_match != nullptr && sym_match->size() == 1) { SymbolInfo sym_info = sym_match->at(0); for (int pos = curr_symbol.first; pos <= int(i); pos++) { @@ -557,3 +557,18 @@ Val* Compiler::compile_add_macro_to_autocomplete(const goos::Object& form, m_symbol_info.add_macro(args.unnamed.at(0).as_symbol()->name, form); return get_none(); } + +std::set Compiler::lookup_symbol_infos_starting_with(const std::string& prefix) const { + if (m_goos.reader.check_string_is_valid(prefix)) { + return m_symbol_info.lookup_symbols_starting_with(prefix); + } + return {}; +} + +std::vector* Compiler::lookup_exact_name_info(const std::string& name) const { + if (m_goos.reader.check_string_is_valid(name)) { + return m_symbol_info.lookup_exact_name(name); + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/goalc/compiler/compilation/ControlFlow.cpp b/goalc/compiler/compilation/ControlFlow.cpp index 123eee1fad..98ecf1021e 100644 --- a/goalc/compiler/compilation/ControlFlow.cpp +++ b/goalc/compiler/compilation/ControlFlow.cpp @@ -242,6 +242,10 @@ Val* Compiler::compile_cond(const goos::Object& form, const goos::Object& rest, } }); + if (case_result_types.empty()) { + throw_compiler_error(form, "Cond must have at least one case"); + } + if (!got_else) { // if no else, clause, return #f. But don't retype. todo what does goal do here? auto get_false = std::make_unique(result, "#f"); diff --git a/test/decompiler/reference/engine/anim/aligner-h_REF.gc b/test/decompiler/reference/engine/anim/aligner-h_REF.gc index 88ec4fd844..7e14f4ed0e 100644 --- a/test/decompiler/reference/engine/anim/aligner-h_REF.gc +++ b/test/decompiler/reference/engine/anim/aligner-h_REF.gc @@ -53,17 +53,14 @@ (object-new allocation type-to-make (the-as int (-> type-to-make size))) ) ) - (if (zero? obj) - (return (begin - (let ((t9-1 (the-as (function object object) enter-state)) - (a0-1 "memory") - ) - (set! (-> pp next-state) process-drawable-art-error) - (t9-1 a0-1) - ) - (the-as align-control 0) - ) + (when (zero? obj) + (let ((t9-1 (the-as (function object object) enter-state)) + (a0-1 "memory") + ) + (set! (-> pp next-state) process-drawable-art-error) + (t9-1 a0-1) ) + (return (the-as align-control 0)) ) (set! (-> obj process) arg0) obj diff --git a/test/decompiler/reference/engine/entity/entity-table_REF.gc b/test/decompiler/reference/engine/entity/entity-table_REF.gc index c2a02f75e7..f982fce174 100644 --- a/test/decompiler/reference/engine/entity/entity-table_REF.gc +++ b/test/decompiler/reference/engine/entity/entity-table_REF.gc @@ -161,15 +161,12 @@ (else (let ((v1-1 *entity-info*)) (dotimes (a1-0 (-> v1-1 length)) - (if (= arg0 (-> v1-1 a1-0 ptype)) - (return (begin - (set! - (-> arg0 method-table 13) - (the-as function (-> v1-1 a1-0)) - ) - (-> v1-1 a1-0) - ) + (when (= arg0 (-> v1-1 a1-0 ptype)) + (set! + (-> arg0 method-table 13) + (the-as function (-> v1-1 a1-0)) ) + (return (-> v1-1 a1-0)) ) ) ) @@ -179,7 +176,3 @@ ) ) ) - - - - diff --git a/test/decompiler/reference/kernel/gkernel_REF.gc b/test/decompiler/reference/kernel/gkernel_REF.gc index 10a4afeff2..412cce9bfb 100644 --- a/test/decompiler/reference/kernel/gkernel_REF.gc +++ b/test/decompiler/reference/kernel/gkernel_REF.gc @@ -1377,12 +1377,9 @@ (reset-and-call s4-0 (-> a0-0 trans-hook)) (delete s4-0) ) - (if (= (-> a0-0 status) 'dead) - (return (begin - (set! (-> s5-0 current-process) #f) - 'dead - ) - ) + (when (= (-> a0-0 status) 'dead) + (set! (-> s5-0 current-process) #f) + (return 'dead) ) ) (if @@ -1419,12 +1416,9 @@ (reset-and-call s4-1 (-> a0-0 post-hook)) (delete s4-1) ) - (if (= (-> a0-0 status) 'dead) - (return (begin - (set! (-> s5-0 current-process) #f) - 'dead - ) - ) + (when (= (-> a0-0 status) 'dead) + (set! (-> s5-0 current-process) #f) + (return 'dead) ) (set! (-> a0-0 status) 'suspended) ) diff --git a/test/decompiler/reference/kernel/gstring_REF.gc b/test/decompiler/reference/kernel/gstring_REF.gc index 3bb9633e07..4b7e5a9891 100644 --- a/test/decompiler/reference/kernel/gstring_REF.gc +++ b/test/decompiler/reference/kernel/gstring_REF.gc @@ -452,54 +452,44 @@ (let ((arg-word-start (string-skip-whitespace (-> arg data)))) (cond ((= (-> arg-word-start 0) 34) - (return (begin - (let ((arg-end (&-> arg-word-start 1))) - (let ((arg-start arg-end)) - (while (and (nonzero? (-> arg-end 0)) (!= (-> arg-end 0) 34)) - (set! arg-end (&-> arg-end 1)) - ) - (copyn-string<-charp - a-str - arg-start - (&- arg-end (the-as uint arg-start)) - ) - ) - (if (= (-> arg-end 0) 34) - (set! arg-end (&-> arg-end 1)) - ) - (let ((a1-3 (string-skip-whitespace arg-end))) - (string-suck-up! arg a1-3) - ) - ) - #t - ) + (let ((arg-end (&-> arg-word-start 1))) + (let ((arg-start arg-end)) + (while (and (nonzero? (-> arg-end 0)) (!= (-> arg-end 0) 34)) + (set! arg-end (&-> arg-end 1)) + ) + (copyn-string<-charp + a-str + arg-start + (&- arg-end (the-as uint arg-start)) + ) + ) + (if (= (-> arg-end 0) 34) + (set! arg-end (&-> arg-end 1)) + ) + (let ((a1-3 (string-skip-whitespace arg-end))) + (string-suck-up! arg a1-3) + ) ) + (return #t) ) ((nonzero? (-> arg-word-start 0)) - (return (begin - (let ((v1-11 arg-word-start)) - (while - (and - (nonzero? (-> arg-word-start 0)) - (!= (-> arg-word-start 0) 32) - (!= (-> arg-word-start 0) 9) - (!= (-> arg-word-start 0) 13) - (!= (-> arg-word-start 0) 10) - ) - (set! arg-word-start (&-> arg-word-start 1)) - ) - (copyn-string<-charp - a-str - v1-11 - (&- arg-word-start (the-as uint v1-11)) - ) - ) - (let ((a1-9 (string-skip-whitespace arg-word-start))) - (string-suck-up! arg a1-9) - ) - #t - ) + (let ((v1-11 arg-word-start)) + (while + (and + (nonzero? (-> arg-word-start 0)) + (!= (-> arg-word-start 0) 32) + (!= (-> arg-word-start 0) 9) + (!= (-> arg-word-start 0) 13) + (!= (-> arg-word-start 0) 10) + ) + (set! arg-word-start (&-> arg-word-start 1)) + ) + (copyn-string<-charp a-str v1-11 (&- arg-word-start (the-as uint v1-11))) + ) + (let ((a1-9 (string-skip-whitespace arg-word-start))) + (string-suck-up! arg a1-9) ) + (return #t) ) ) ) diff --git a/test/goalc/source_templates/kernel/kernel-test.gc b/test/goalc/source_templates/kernel/kernel-test.gc index 5c4e89153d..aac293a67e 100644 --- a/test/goalc/source_templates/kernel/kernel-test.gc +++ b/test/goalc/source_templates/kernel/kernel-test.gc @@ -50,7 +50,8 @@ ) (define test-process-2 (get-process *nk-dead-pool* process 1024)) - (activate test-process-2 *active-pool* 'test-2 *kernel-dram-stack*) + ;; test that the kernel fakes having process stacks on the scratchpad. + (activate test-process-2 *active-pool* 'test-2 (the pointer #x70004000)) (set-to-run (-> test-process-2 main-thread) target-function-2 0 0 0 0 0 0) From fb5776804cd87235830ae1197f7fb8b3a9599ee6 Mon Sep 17 00:00:00 2001 From: water Date: Tue, 29 Jun 2021 20:35:28 -0400 Subject: [PATCH 2/3] fi --- goalc/compiler/compilation/ControlFlow.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/goalc/compiler/compilation/ControlFlow.cpp b/goalc/compiler/compilation/ControlFlow.cpp index ea4c665603..d7625d34ce 100644 --- a/goalc/compiler/compilation/ControlFlow.cpp +++ b/goalc/compiler/compilation/ControlFlow.cpp @@ -242,10 +242,6 @@ Val* Compiler::compile_cond(const goos::Object& form, const goos::Object& rest, } }); - if (case_result_types.empty()) { - throw_compiler_error(form, "Cond must have at least one case"); - } - if (!got_else) { // if no else, clause, return #f. But don't retype. todo what does goal do here? auto get_false = std::make_unique(result, "#f"); From f374dda0ec1debcc8a919dd0d663372da7793677 Mon Sep 17 00:00:00 2001 From: water Date: Tue, 29 Jun 2021 20:37:32 -0400 Subject: [PATCH 3/3] fix merge conflict --- .../reference/engine/debug/assert-h_REF.gc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/decompiler/reference/engine/debug/assert-h_REF.gc b/test/decompiler/reference/engine/debug/assert-h_REF.gc index 6f56e55f44..38e6151317 100644 --- a/test/decompiler/reference/engine/debug/assert-h_REF.gc +++ b/test/decompiler/reference/engine/debug/assert-h_REF.gc @@ -11,8 +11,8 @@ :size-assert #x8 :flag-assert #xb00000008 (:methods - (set-private-assert-info (_type_ string uint16 uint16) int 9) - (print-private-assert-info (_type_) int 10) + (set-pos (_type_ string uint uint) int 9) + (print-pos (_type_) int 10) ) ) @@ -30,22 +30,22 @@ ;; definition for method 9 of type __assert-info-private-struct (defmethod - set-private-assert-info + set-pos __assert-info-private-struct ((obj __assert-info-private-struct) (filename string) - (line-num uint16) - (column-num uint16) + (line-num uint) + (column-num uint) ) (set! (-> obj filename) filename) - (set! (-> obj line-num) (the-as uint line-num)) - (set! (-> obj column-num) (the-as uint column-num)) + (set! (-> obj line-num) line-num) + (set! (-> obj column-num) column-num) 0 ) ;; definition for method 10 of type __assert-info-private-struct (defmethod - print-private-assert-info + print-pos __assert-info-private-struct ((obj __assert-info-private-struct)) (format