diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c0f6c829..049baa8a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ - new dependency: fmtlib ### Changed +- instructions are on 4 bytes: 1 byte for the instruction, 1 byte of padding, 2 bytes for an immediate argument +- enhanced the bytecode reader and its command line interface - added the padding/instruction/argumentation values when displaying instructions in the bytecode reader - fixed underline bug in the error context - the str:format functions now expects strings following this syntax: https://fmt.dev/latest/syntax.html @@ -82,8 +84,6 @@ - moved the frame counter of the VM to the ExecutionContext as this should be local to the context, not to the VM - changing the way we count received arguments in arity / type errors for failed function call - the CLI can now take a list of paths to the standard library, separated by ';' -- instructions are on 4 bytes: 1 byte for the instruction, 1 byte of padding, 2 bytes for an immediate argument -- enhanced the bytecode reader and its command line interface ## [3.2.0] - 2022-02-19 ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 797276978..a1822cd57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,7 +212,7 @@ if (ARK_BUILD_EXE) CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF) - enable_ipo(arkscript) + enable_lto(arkscript) # Installs the arkscript executable. install(TARGETS arkscript diff --git a/include/Ark/Compiler/Compiler.hpp b/include/Ark/Compiler/Compiler.hpp index e2b7cf12c..a5a8d4524 100644 --- a/include/Ark/Compiler/Compiler.hpp +++ b/include/Ark/Compiler/Compiler.hpp @@ -205,6 +205,14 @@ namespace Ark */ bool mayBeFromPlugin(const std::string& name) noexcept; + /** + * @brief Display a warning message + * + * @param message + * @param node + */ + void compilerWarning(const std::string& message, const internal::Node& node); + /** * @brief Throw a nice error message * diff --git a/src/arkreactor/Builtins/String.cpp b/src/arkreactor/Builtins/String.cpp index 1a0d567e8..809504212 100644 --- a/src/arkreactor/Builtins/String.cpp +++ b/src/arkreactor/Builtins/String.cpp @@ -56,7 +56,7 @@ namespace Ark::internal::Builtins::String else { std::stringstream ss; - ss << (*it); + it->toString(ss, *vm); current = fmt::format(current, ss.str()); } diff --git a/src/arkreactor/Compiler/Compiler.cpp b/src/arkreactor/Compiler/Compiler.cpp index ce580c1c0..53b1e331f 100644 --- a/src/arkreactor/Compiler/Compiler.cpp +++ b/src/arkreactor/Compiler/Compiler.cpp @@ -250,7 +250,7 @@ namespace Ark } } - void Compiler::pushSpecificInstArgc(Instruction inst, uint16_t previous, int p) noexcept + uint16_t Compiler::computeSpecificInstArgc(Instruction inst, uint16_t previous) noexcept { switch (inst) { @@ -278,6 +278,12 @@ namespace Ark return it != m_plugins.end(); } + void Compiler::compilerWarning(const std::string& message, const Node& node) + { + if (m_options & FeatureShowWarnings) + std::cout << termcolor::yellow << "Warning " << termcolor::reset << makeNodeBasedErrorCtx(message, node) << "\n"; + } + void Compiler::throwCompilerError(const std::string& message, const Node& node) { throw CompilationError(makeNodeBasedErrorCtx(message, node)); @@ -387,7 +393,10 @@ namespace Ark page(p).emplace_back(Instruction::LOAD_SYMBOL, addSymbol(x)); // using the variable if (is_result_unused) + { + compilerWarning("Statement has no effect", x); page(p).push_back(Instruction::POP); + } } void Compiler::compileSpecific(const Node& c0, const Node& x, int p, bool is_result_unused) @@ -420,8 +429,11 @@ namespace Ark // put inst and number of arguments page(p).emplace_back(inst, computeSpecificInstArgc(inst, argc)); - if (is_result_unused && name != "pop!") // pop! never pushes a value + if (is_result_unused && name.back() != '!') // in-place functions never push a value + { + compilerWarning("Ignoring return value of function", x); page(p).push_back(Instruction::POP); + } } void Compiler::compileIf(const Node& x, int p, bool is_result_unused, bool is_terminal, const std::string& var_name) @@ -492,7 +504,10 @@ namespace Ark // if the computed function is unused, pop it if (is_result_unused) + { + compilerWarning("Unused declared function", x); page(p).push_back(Instruction::POP); + } } void Compiler::compileLetMutSet(Keyword n, const Node& x, int p) @@ -547,7 +562,10 @@ namespace Ark page(p).emplace_back(Instruction::LOAD_CONST, id); if (is_result_unused) + { + compilerWarning("Unused quote expression", x); page(p).push_back(Instruction::POP); + } } void Compiler::compilePluginImport(const Node& x, int p) @@ -647,8 +665,8 @@ namespace Ark if (exp_count == 1) { - if (isUnaryInst(static_cast(op_inst))) - page(p).push_back(op_inst); + if (isUnaryInst(static_cast(op.opcode))) + page(p).push_back(op.opcode); else throwCompilerError("Operator needs two arguments, but was called with only one", x.constList()[0]); } diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp index 8b94764c7..906aa523b 100644 --- a/src/arkreactor/VM/VM.cpp +++ b/src/arkreactor/VM/VM.cpp @@ -458,7 +458,7 @@ namespace Ark Value* ptr = (*context.locals.back())[arg]; if (!ptr) - throwVMError("Couldn't capture '" + m_state.m_symbols[id] + "' as it is currently unbound"); + throwVMError("Couldn't capture '" + m_state.m_symbols[arg] + "' as it is currently unbound"); ptr = ptr->valueType() == ValueType::Reference ? ptr->reference() : ptr; (*context.saved_scope.value()).push_back(arg, *ptr); diff --git a/src/arkreactor/VM/Value.cpp b/src/arkreactor/VM/Value.cpp index aeca605f9..f54401a39 100644 --- a/src/arkreactor/VM/Value.cpp +++ b/src/arkreactor/VM/Value.cpp @@ -149,13 +149,13 @@ namespace Ark { case ValueType::Number: { - double d = V.number(); + double d = number(); os << fmt::format("{}", d); break; } case ValueType::String: - os << V.string(); + os << string(); break; case ValueType::PageAddr: