packages feed

zeolite-lang 0.20.0.1 → 0.21.0.0

raw patch · 135 files changed

+2731/−1823 lines, 135 filesdep ~mtlPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: mtl

API changes (from Hackage documentation)

- Cli.Compiler: [ltPath] :: LoadedTests -> FilePath
- Cli.Compiler: [ltRoot] :: LoadedTests -> FilePath
- Config.LocalConfig: instance Cli.Programs.CompilerBackend Config.LocalConfig.Backend
- Config.LocalConfig: instance GHC.Read.Read Config.LocalConfig.Backend
- Config.LocalConfig: instance GHC.Read.Read Config.LocalConfig.LocalConfig
- Config.LocalConfig: instance GHC.Read.Read Config.LocalConfig.Resolver
- Config.LocalConfig: instance GHC.Show.Show Config.LocalConfig.Backend
- Config.LocalConfig: instance GHC.Show.Show Config.LocalConfig.LocalConfig
- Config.LocalConfig: instance GHC.Show.Show Config.LocalConfig.Resolver
- Config.LocalConfig: instance Module.Paths.PathIOHandler Config.LocalConfig.Resolver
+ Config.CompilerConfig: LocalConfig :: Resolver -> Backend -> LocalConfig
+ Config.CompilerConfig: SimpleResolver :: [FilePath] -> [FilePath] -> Resolver
+ Config.CompilerConfig: UnixBackend :: FilePath -> [String] -> [String] -> [String] -> FilePath -> Backend
+ Config.CompilerConfig: [lcBackend] :: LocalConfig -> Backend
+ Config.CompilerConfig: [lcResolver] :: LocalConfig -> Resolver
+ Config.CompilerConfig: [srExtraPaths] :: Resolver -> [FilePath]
+ Config.CompilerConfig: [srVisibleSystem] :: Resolver -> [FilePath]
+ Config.CompilerConfig: [ucArBinary] :: Backend -> FilePath
+ Config.CompilerConfig: [ucBinaryFlags] :: Backend -> [String]
+ Config.CompilerConfig: [ucCompileFlags] :: Backend -> [String]
+ Config.CompilerConfig: [ucCxxBinary] :: Backend -> FilePath
+ Config.CompilerConfig: [ucLibraryFlags] :: Backend -> [String]
+ Config.CompilerConfig: data Backend
+ Config.CompilerConfig: data LocalConfig
+ Config.CompilerConfig: data Resolver
+ Config.CompilerConfig: instance GHC.Classes.Eq Config.CompilerConfig.Backend
+ Config.CompilerConfig: instance GHC.Classes.Eq Config.CompilerConfig.LocalConfig
+ Config.CompilerConfig: instance GHC.Classes.Eq Config.CompilerConfig.Resolver
+ Config.CompilerConfig: instance GHC.Show.Show Config.CompilerConfig.Backend
+ Config.CompilerConfig: instance GHC.Show.Show Config.CompilerConfig.LocalConfig
+ Config.CompilerConfig: instance GHC.Show.Show Config.CompilerConfig.Resolver
+ Config.LoadConfig: saveConfig :: (MonadIO m, CollectErrorsM m) => (Resolver, Backend) -> m ()
+ Config.LocalConfig: instance Cli.Programs.CompilerBackend Config.CompilerConfig.Backend
+ Config.LocalConfig: instance Module.Paths.PathIOHandler Config.CompilerConfig.Resolver
+ Config.ParseConfig: instance Module.ParseMetadata.ConfigFormat Config.CompilerConfig.Backend
+ Config.ParseConfig: instance Module.ParseMetadata.ConfigFormat Config.CompilerConfig.LocalConfig
+ Config.ParseConfig: instance Module.ParseMetadata.ConfigFormat Config.CompilerConfig.Resolver
+ Module.CompileMetadata: [cmRoot] :: CompileMetadata -> FilePath
+ Module.ParseMetadata: indent :: String -> String
+ Module.ParseMetadata: indents :: [String] -> [String]
+ Module.ParseMetadata: parseList :: TextParser a -> TextParser [a]
+ Module.ParseMetadata: parseOptional :: String -> a -> TextParser a -> Permutation TextParser a
+ Module.ParseMetadata: parseQuoted :: TextParser String
+ Module.ParseMetadata: parseRequired :: String -> TextParser a -> Permutation TextParser a
+ Module.ParseMetadata: prependFirst :: String -> [String] -> [String]
+ Module.ParseMetadata: readConfig :: ConfigFormat a => TextParser a
+ Module.ParseMetadata: structClose :: TextParser ()
+ Module.ParseMetadata: structOpen :: TextParser ()
+ Module.ParseMetadata: writeConfig :: (ConfigFormat a, CollectErrorsM m) => a -> m [String]
+ Module.ProcessMetadata: isPrivateSource :: FilePath -> Bool
+ Module.ProcessMetadata: isPublicSource :: FilePath -> Bool
+ Module.ProcessMetadata: isTestSource :: FilePath -> Bool
+ Test.Common: checkWriteFail :: ConfigFormat a => String -> a -> IO (TrackedErrors ())
+ Test.Common: checkWriteThenRead :: (Eq a, Show a, ConfigFormat a) => a -> IO (TrackedErrors ())
+ Test.ParseConfig: tests :: [IO (TrackedErrors ())]
+ Types.Builtin: isOpaqueMulti :: ExpressionValue -> Bool
+ Types.DefinedCategory: FlatCleanup :: [c] -> VariableName -> PragmaDefined c
+ Types.DefinedCategory: [fcContext] :: PragmaDefined c -> [c]
+ Types.DefinedCategory: [fcMember] :: PragmaDefined c -> VariableName
+ Types.DefinedCategory: isFlatCleanup :: PragmaDefined c -> Bool
+ Types.Procedure: SelectReturn :: [c] -> Int -> ValueOperation c
- Cli.Compiler: LoadedTests :: FilePath -> FilePath -> CompileMetadata -> ExprMap SourceContext -> [CompileMetadata] -> [CompileMetadata] -> LoadedTests
+ Cli.Compiler: LoadedTests :: CompileMetadata -> ExprMap SourceContext -> [CompileMetadata] -> [CompileMetadata] -> LoadedTests
- Cli.Programs: getCompilerHash :: CompilerBackend b => b -> VersionHash
+ Cli.Programs: getCompilerHash :: (CompilerBackend b, MonadIO m, CollectErrorsM m) => b -> m VersionHash
- Cli.Programs: runCxxCommand :: (CompilerBackend b, MonadIO m, ErrorContextM m) => b -> CxxCommand -> m FilePath
+ Cli.Programs: runCxxCommand :: (CompilerBackend b, MonadIO m, CollectErrorsM m) => b -> CxxCommand -> m FilePath
- Cli.Programs: runTestCommand :: (CompilerBackend b, MonadIO m, ErrorContextM m) => b -> TestCommand -> m TestCommandResult
+ Cli.Programs: runTestCommand :: (CompilerBackend b, MonadIO m, CollectErrorsM m) => b -> TestCommand -> m TestCommandResult
- Config.LoadConfig: loadConfig :: (MonadIO m, ErrorContextM m) => m (Resolver, Backend)
+ Config.LoadConfig: loadConfig :: (MonadIO m, CollectErrorsM m) => m (Resolver, Backend)
- Config.LocalConfig: LocalConfig :: Backend -> Resolver -> LocalConfig
+ Config.LocalConfig: LocalConfig :: Resolver -> Backend -> LocalConfig
- Module.CompileMetadata: CompileMetadata :: VersionHash -> FilePath -> [FilePath] -> Namespace -> Namespace -> [FilePath] -> [FilePath] -> [CategoryName] -> [CategoryName] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [ObjectFile] -> CompileMetadata
+ Module.CompileMetadata: CompileMetadata :: VersionHash -> FilePath -> FilePath -> [FilePath] -> Namespace -> Namespace -> [FilePath] -> [FilePath] -> [CategoryName] -> [CategoryName] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [ObjectFile] -> CompileMetadata
- Module.ProcessMetadata: loadModuleGlobals :: PathIOHandler r => r -> FilePath -> (Namespace, Namespace) -> [FilePath] -> Maybe CompileMetadata -> [CompileMetadata] -> [CompileMetadata] -> TrackedErrorsIO [WithVisibility (AnyCategory SourceContext)]
+ Module.ProcessMetadata: loadModuleGlobals :: PathIOHandler r => r -> FilePath -> (Namespace, Namespace) -> [FilePath] -> Maybe CompileMetadata -> [CompileMetadata] -> [CompileMetadata] -> TrackedErrorsIO ([WithVisibility (AnyCategory SourceContext)], Set FilePath)

Files

ChangeLog.md view
@@ -1,5 +1,82 @@ # Revision history for zeolite-lang +## 0.21.0.0  -- 2021-11-19++### Compiler CLI++* **[breaking]** Combines params and args in function calls into a single+  object. This breaks all C++ extensions.++  - `Call_foo` for function `foo` must now take `const ParamsArgs& params_args`+    as its only argument.+    - Access param `n` using `params_args.GetParam(n)`.+    - Access arg `n` using `params_args.GetArg(n)`.+  - Function calls must group params and args with+    `PassParamsArgs(params..., args...)` rather than with+    `ParamTuple(params...)` and `ArgTuple(args...)`.+  - To directly pass the returns from another function call, use that function+    call in place of `args...`, e.g.+    `PassParamsArgs(params..., TypeValue::Call(Var_foo, Function_Foo_bar, ...))`.+  - Value initialization should be changed to take `ParamsArgs` instead of+    `ValueTuple`, since the latter has been removed. (Alternatively, just pass a+    custom set of arguments.)+  - `ReturnTuple` usage for returns remains unchanged.++* **[new]** Updates dependency check to skip checking the modification times of+  `$ModuleOnly$` `.0rp` source files when determining if the target module needs+  to be recompiled.++* **[new]** Adds `--clean` mode to `zeolite` to clear cached data for a module.++* **[new]** Allows specifying a root path with `-p` in special `zeolite`+  execution modes, e.g., `--missed-lines`.++### Libraries++* **[breaking]** Makes `LinkedNode` in `lib/container` weak in the reverse+  direction to avoid reference cycles.++* **[new]** Adds `Token` to `lib/math`, for more efficient comparison of strings+  when used in algorithms.++* **[new]** Gives `Testing.checkEmpty` in `lib/testing` a parameter to allow+  values that do not refine `Formatted`. (This is not breaking because of the+  new language feature that infers params by default.)++* **[new]** Adds `getAll` to `TypeMap` in `lib/container` to read all values of+  a specified type.++* **[new]** Adds `checkTrue` and `checkFalse` to `Testing` in `lib/testing`.++### Language++* **[new]** Makes param inference the default when no params are specified in a+  function call. For example, `call<?>(foo)` can now be `call(foo)`.++* **[new]** Adds syntax to select a single return value from a function that+  returns multiple values.++  ```text+  // Previous method:+  scoped {+    Foo foo, _ <- call()+  } in \ foo.bar()++  // New method:+  \ call(){0}.bar()+  ```++* **[new]** Adds the `$FlatCleanup[`*`memberName`*`]$` pragma to enable+  non-recursive cleanup for deeply-recursive types like linked lists.++* **[behavior]** Removes all dynamic allocation when passing params and+  arguments in function calls.++* **[behavior]** Improves efficiency of returning values from function calls.++* **[behavior]** Improves efficiency of `Bool`, `Char`, `Float`, and `Int`+  values when used in function calls and containers.+ ## 0.20.0.1  -- 2021-11-14  ### Language
base/.zeolite-module view
@@ -34,11 +34,12 @@   "base/thread-capture.h"   "base/thread-crosser.h"   "base/pooled.hpp"+  "base/returns.hpp"   "base/types.hpp"   "base/src/boxed.cpp"   "base/src/category-source.cpp"   "base/src/logging.cpp"+  "base/src/returns.cpp"   "base/src/thread-crosser.cc"-  "base/src/types.cpp" ] mode: incremental {}
base/boxed.hpp view
@@ -23,10 +23,12 @@ #include <cstdlib> #include <atomic> -#include "function.hpp" #include "types.hpp"  +class ParamsArgs;+class ValueFunction;+ namespace zeolite_internal {  struct UnionValue {@@ -79,7 +81,9 @@    inline BoxedValue& operator = (const BoxedValue& other) {     if (&other != this) {-      Cleanup();+      if (union_.type_ == UnionValue::Type::BOXED) {+        Cleanup();+      }       union_ = other.union_;       switch (union_.type_) {         case UnionValue::Type::BOXED:@@ -100,7 +104,9 @@    inline BoxedValue& operator = (BoxedValue&& other) {     if (&other != this) {-      Cleanup();+      if (union_.type_ == UnionValue::Type::BOXED) {+        Cleanup();+      }       union_ = other.union_;       other.union_.type_  = UnionValue::Type::EMPTY;       other.union_.value_.as_pointer_ = nullptr;@@ -133,7 +139,9 @@   }    inline ~BoxedValue() {-    Cleanup();+    if (union_.type_ == UnionValue::Type::BOXED) {+      Cleanup();+    }   }    inline PrimBool AsBool() const {@@ -228,8 +236,7 @@     return value;   } -  ReturnTuple Dispatch(-    const ValueFunction& label, const ParamTuple& params, const ValueTuple& args) const;+  ReturnTuple Dispatch(const ::ValueFunction& label, const ::ParamsArgs& params_args) const;    void Cleanup(); 
base/category-source.hpp view
@@ -26,13 +26,14 @@  #include "boxed.hpp" #include "cycle-check.hpp"-#include "types.hpp" #include "function.hpp"+#include "returns.hpp"+#include "types.hpp"   #define BUILTIN_FAIL(e) { \   FAIL() << TypeValue::Call((e), Function_Formatted_formatted, \-                            ParamTuple(), ArgTuple()).Only().AsString(); \+                            PassParamsArgs()).At(0).AsString(); \   __builtin_unreachable(); \   } @@ -62,9 +63,8 @@  class TypeCategory {  public:-  inline ReturnTuple Call(const CategoryFunction& label,-                          const ParamTuple& params, const ValueTuple& args) {-    return Dispatch(label, params, args);+  inline ReturnTuple Call(const CategoryFunction& label, const ParamsArgs& params_args) {+    return Dispatch(label, params_args);   }    virtual std::string CategoryName() const = 0;@@ -75,19 +75,17 @@  protected:   TypeCategory() = default; -  virtual ReturnTuple Dispatch(const CategoryFunction& label,-                               const ParamTuple& params, const ValueTuple& args);+  virtual ReturnTuple Dispatch(const CategoryFunction& label, const ParamsArgs& params_args); };  class TypeInstance {  public:   inline static ReturnTuple Call(const S<const TypeInstance>& target,-                                 const TypeFunction& label,-                                 const ParamTuple& params, const ValueTuple& args) {+                                 const TypeFunction& label, const ParamsArgs& params_args) {     if (target == nullptr) {       FAIL() << "Function called on null value";     }-    return target->Dispatch(label, params, args);+    return target->Dispatch(label, params_args);   }    virtual std::string CategoryName() const = 0;@@ -117,8 +115,7 @@  protected:   TypeInstance() = default; -  virtual ReturnTuple Dispatch(const TypeFunction& label,-                               const ParamTuple& params, const ValueTuple& args) const;+  virtual ReturnTuple Dispatch(const TypeFunction& label, const ParamsArgs& params_args) const;    virtual bool CanConvertFrom(const S<const TypeInstance>& from) const   { return false; }@@ -161,8 +158,8 @@ class TypeValue {  public:   inline static ReturnTuple Call(const BoxedValue& target, const ValueFunction& label,-                                 const ParamTuple& params, const ValueTuple& args) {-    return target.Dispatch(label, params, args);+                                 const ParamsArgs& params_args) {+    return target.Dispatch(label, params_args);   }    virtual const PrimString& AsString() const;@@ -188,8 +185,9 @@   // NOTE: For some reason, making this private causes a segfault.   virtual std::string CategoryName() const = 0; -  virtual ReturnTuple Dispatch(-    const ValueFunction& label, const ParamTuple& params, const ValueTuple& args);+  virtual BoxedValue FlatCleanup() { return BoxedValue(); }++  virtual ReturnTuple Dispatch(const ValueFunction& label, const ParamsArgs& params_args);   private:   // Creating a BoxedValue from a TypeValue won't have the correct offset.
base/function.hpp view
@@ -21,6 +21,7 @@  #include <ostream> +#include "returns.hpp" #include "types.hpp"  @@ -64,6 +65,148 @@  inline std::ostream& operator << (std::ostream& output, const ValueFunction& func) {   return output << func.category << "." << func.function;+}++struct ParamsArgs {+  virtual int NumParams() const = 0;+  virtual const S<const TypeInstance>& GetParam(int pos) const = 0;+  virtual int NumArgs() const = 0;+  virtual const BoxedValue& GetArg(int pos) const = 0;+};++template<int P, int A>+struct PassArgs : public ParamsArgs {+  template<class... Ps>+  PassArgs(const Ps&... passed) {+    Init<0, 0>(passed...);+  }++  template<int Pn, int An>+  void Init() {}++  template<int Pn, int An, class... Ps>+  void Init(const S<const TypeInstance>& param, const Ps&... passed) {+    params[Pn] = &param;+    Init<Pn+1, An>(passed...);+  }++  template<int Pn, int An, class... Ps>+  void Init(const BoxedValue& arg, const Ps&... passed) {+    args[An] = &arg;+    Init<Pn, An+1>(passed...);+  }++  int NumParams() const final { return P; }++  const S<const TypeInstance>& GetParam(int pos) const final {+    if (pos < 0 || pos >= P) {+      FAIL() << "Bad param index";+    }+    return *params[pos];+  }++  int NumArgs() const final { return A; }++  const BoxedValue& GetArg(int pos) const final {+    if (pos < 0 || pos >= A) {+      FAIL() << "Bad arg index";+    }+    return *args[pos];+  }++  const S<const TypeInstance>* params[P];+  const BoxedValue*   args[A];+};++template<>+struct PassArgs<0, 0> : public ParamsArgs {+  constexpr PassArgs() {}++  int NumParams() const final { return 0; }++  const S<const TypeInstance>& GetParam(int pos) const final {+    FAIL() << "Bad param index";+    __builtin_unreachable();+  }++  int NumArgs() const final { return 0; }++  const BoxedValue& GetArg(int pos) const final {+    FAIL() << "Bad arg index";+    __builtin_unreachable();+  }+};++template<int P>+struct PassReturns : public ParamsArgs {+  template<class... Ps>+  PassReturns(const Ps&... passed) {+    Init<0>(passed...);+  }++  template<int Pn, class... Ps>+  void Init(const S<const TypeInstance>& param, const Ps&... passed) {+    params[Pn] = &param;+    Init<Pn+1>(passed...);+  }++  template<int Pn>+  void Init(const ReturnTuple& forward) {+    returns = &forward;+  }++  int NumParams() const final { return P; }++  const S<const TypeInstance>& GetParam(int pos) const final {+    if (pos < 0 || pos >= P) {+      FAIL() << "Bad param index";+    }+    return *params[pos];+  }++  int NumArgs() const final                     { return returns->Size(); }+  const BoxedValue& GetArg(int pos) const final { return returns->At(pos); }++  const S<const TypeInstance>* params[P];+  const ReturnTuple* returns;+};++template<int P, int A, class... Ps>+struct AutoArgs;++template<int P, int A>+struct AutoArgs<P, A> {+  using Type = PassArgs<P, A>;+};++template<int P, int A, class... Ps>+struct AutoArgs<P, A, BoxedValue, Ps...> {+  using Type = typename AutoArgs<P, A+1, Ps...>::Type;+};++template<int P, class... Ps>+struct AutoCall {+  using Type = typename AutoArgs<P, 0, Ps...>::Type;+};++template<int P>+struct AutoCall<P, ReturnTuple> {+  using Type = PassReturns<P>;+};++template<int P, class... Ps>+struct AutoCall<P, S<const TypeInstance>, Ps...> {+  using Type = typename AutoCall<P+1, Ps...>::Type;+};++template<class... Ps>+struct GetCall {+  using Type = typename AutoCall<0, Ps...>::Type;+};++template<class... Ps>+typename GetCall<Ps...>::Type PassParamsArgs(const Ps&... passed) {+  return typename GetCall<Ps...>::Type(passed...); }  #endif  // FUNCTION_HPP_
base/pooled.hpp view
@@ -20,9 +20,7 @@ #define POOLED_HPP_  -class ArgTuple; class ReturnTuple;-class ParamTuple;  namespace zeolite_internal { @@ -39,6 +37,7 @@   PoolStorage* next = nullptr;  private:+  template<class> friend class PoolCache;   template<class> friend class PoolManager;    inline PoolStorage(int s, PoolStorage* n) : size(s), next(n) {}@@ -56,9 +55,7 @@  template<class T> class PoolArray {-  friend class ::ArgTuple;   friend class ::ReturnTuple;-  friend class ::ParamTuple;    constexpr PoolArray() : size_(0), array_(nullptr) {} @@ -114,6 +111,53 @@    int size_;   PoolStorage<T>* array_;+};++template<class T>+class PoolCache {+ public:+  PoolCache(int max) : max_(max) {}++  ~PoolCache() {+    while (pool_) {+      --size_;+      auto* current = pool_;+      pool_ = pool_->next;+      current->~PoolStorage<T>();+      delete[] (unsigned char*) current;+    }+  }++ private:+  template<class> friend class PoolManager;++  inline PoolStorage<T>* Take() {+    PoolStorage<T>* const storage = pool_;+    if (storage == nullptr) {+      return nullptr;+    } else {+      --size_;+      pool_ = storage->next;+      storage->next = nullptr;+      return storage;+    }+  }++  inline bool Return(PoolStorage<T>* storage) {+    PoolStorage<T>* const head = pool_;+    if (size_ < max_) {+      ++size_;+      storage->next = head;+      pool_ = storage;+      return true;+    } else {+      return false;+    }+  }++  PoolStorage<T>* pool_;+  int size_ = 0;+  const int max_; };  }  // namespace zeolite_internal
+ base/returns.hpp view
@@ -0,0 +1,78 @@+/* -----------------------------------------------------------------------------+Copyright 2019-2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++#ifndef RETURNS_HPP_+#define RETURNS_HPP_++#include "boxed.hpp"+#include "pooled.hpp"+++namespace zeolite_internal {++template<>+class PoolManager<BoxedValue> {+  using PoolEntry = PoolStorage<BoxedValue>;+  using Managed = PoolEntry::Managed;++  template<class> friend class PoolArray;+  template<class> friend struct PoolCache;++  static PoolEntry* Take(int size);+  static void Return(PoolEntry* storage, int size);++  static thread_local PoolCache<BoxedValue> cache3_;+};++}  // namespace zeolite_internal+++class ReturnTuple {+ public:+  constexpr ReturnTuple() : data_() {}++  explicit ReturnTuple(int size) : data_(size-1) {}++  explicit ReturnTuple(BoxedValue first) : first_(std::move(first)), data_() {}++  template<class...Ts>+  explicit ReturnTuple(BoxedValue first, Ts... returns)+    : first_(std::move(first)), data_(sizeof...(Ts)) {+    data_.Init(std::move(returns)...);+  }++  ReturnTuple(ReturnTuple&&) = default;++  void TransposeFrom(ReturnTuple&& other);++  // NOTE: This will never be 0.+  int Size() const;+  BoxedValue& At(int pos);+  const BoxedValue& At(int pos) const;++ private:+  ReturnTuple(const ReturnTuple&) = delete;+  ReturnTuple& operator =(ReturnTuple&&) = delete;+  ReturnTuple& operator =(const ReturnTuple&) = delete;+  void* operator new(std::size_t size) = delete;++  BoxedValue first_;+  zeolite_internal::PoolArray<BoxedValue> data_;+};++#endif  // RETURNS_HPP_
base/src/Extension_Bool.cpp view
@@ -39,21 +39,21 @@ struct ExtType_Bool : public Type_Bool {   inline ExtType_Bool(Category_Bool& p, Params<0>::Type params) : Type_Bool(p, params) {} -  ReturnTuple Call_default(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_default(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Bool.default")     return ReturnTuple(Box_Bool(false));   } -  ReturnTuple Call_equals(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_equals(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Bool.equals")-    const PrimBool Var_arg1 = (args.At(0)).AsBool();-    const PrimBool Var_arg2 = (args.At(1)).AsBool();+    const PrimBool Var_arg1 = (params_args.GetArg(0)).AsBool();+    const PrimBool Var_arg2 = (params_args.GetArg(1)).AsBool();     return ReturnTuple(Box_Bool(Var_arg1==Var_arg2));   } };  ReturnTuple DispatchBool(PrimBool value, const ValueFunction& label,-                         const ParamTuple& params, const ValueTuple& args) {+                         const ParamsArgs& params_args) {   switch (label.collection) {     case CategoryId_AsBool:       return ReturnTuple(Box_Bool(value));
base/src/Extension_Char.cpp view
@@ -42,38 +42,38 @@ struct ExtType_Char : public Type_Char {   inline ExtType_Char(Category_Char& p, Params<0>::Type params) : Type_Char(p, params) {} -  ReturnTuple Call_maxBound(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_maxBound(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Char.maxBound")     return ReturnTuple(Box_Char('\xff'));   } -  ReturnTuple Call_minBound(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_minBound(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Char.minBound")     return ReturnTuple(Box_Char('\0'));   } -  ReturnTuple Call_default(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_default(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Char.default")     return ReturnTuple(Box_Char('\0'));   } -  ReturnTuple Call_equals(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_equals(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Char.equals")-    const PrimChar Var_arg1 = (args.At(0)).AsChar();-    const PrimChar Var_arg2 = (args.At(1)).AsChar();+    const PrimChar Var_arg1 = (params_args.GetArg(0)).AsChar();+    const PrimChar Var_arg2 = (params_args.GetArg(1)).AsChar();     return ReturnTuple(Box_Bool(Var_arg1==Var_arg2));   } -  ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_lessThan(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Char.lessThan")-    const PrimChar Var_arg1 = (args.At(0)).AsChar();-    const PrimChar Var_arg2 = (args.At(1)).AsChar();+    const PrimChar Var_arg1 = (params_args.GetArg(0)).AsChar();+    const PrimChar Var_arg2 = (params_args.GetArg(1)).AsChar();     return ReturnTuple(Box_Bool(Var_arg1<Var_arg2));   } };  ReturnTuple DispatchChar(PrimChar value, const ValueFunction& label,-                         const ParamTuple& params, const ValueTuple& args) {+                         const ParamsArgs& params_args) {   switch (label.collection) {     case CategoryId_AsBool:       return ReturnTuple(Box_Bool(value != '\0'));
base/src/Extension_CharBuffer.cpp view
@@ -37,9 +37,9 @@ struct ExtType_CharBuffer : public Type_CharBuffer {   inline ExtType_CharBuffer(Category_CharBuffer& p, Params<0>::Type params) : Type_CharBuffer(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("CharBuffer.new")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0) {       FAIL() << "Buffer size " << Var_arg1 << " is invalid";     }@@ -51,18 +51,18 @@   inline ExtValue_CharBuffer(S<const Type_CharBuffer> p, PrimCharBuffer value)     : Value_CharBuffer(std::move(p)), value_(std::move(value)) {} -  ReturnTuple Call_readAt(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_readAt(const ParamsArgs& params_args) final {     TRACE_FUNCTION("CharBuffer.readAt")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0 || Var_arg1 >= AsCharBuffer().size()) {       FAIL() << "Read position " << Var_arg1 << " is out of bounds";     }     return ReturnTuple(Box_Char(AsCharBuffer()[Var_arg1]));   } -  ReturnTuple Call_resize(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_resize(const ParamsArgs& params_args) final {     TRACE_FUNCTION("CharBuffer.resize")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0) {       FAIL() << "Buffer size " << Var_arg1 << " is invalid";     } else {@@ -71,15 +71,15 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_size(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_size(const ParamsArgs& params_args) final {     TRACE_FUNCTION("CharBuffer.size")     return ReturnTuple(Box_Int(value_.size()));   } -  ReturnTuple Call_writeAt(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_writeAt(const ParamsArgs& params_args) final {     TRACE_FUNCTION("CharBuffer.writeAt")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();-    const PrimChar Var_arg2 = (args.At(1)).AsChar();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();+    const PrimChar Var_arg2 = (params_args.GetArg(1)).AsChar();     if (Var_arg1 < 0 || Var_arg1 >= value_.size()) {       FAIL() << "Write position " << Var_arg1 << " is out of bounds";     } else {
base/src/Extension_Float.cpp view
@@ -42,28 +42,28 @@ struct ExtType_Float : public Type_Float {   inline ExtType_Float(Category_Float& p, Params<0>::Type params) : Type_Float(p, params) {} -  ReturnTuple Call_default(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_default(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Float.default")     return ReturnTuple(Box_Float(0.0));   } -  ReturnTuple Call_equals(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_equals(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Float.equals")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();-    const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();+    const PrimFloat Var_arg2 = (params_args.GetArg(1)).AsFloat();     return ReturnTuple(Box_Bool(Var_arg1==Var_arg2));   } -  ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_lessThan(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Float.lessThan")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();-    const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();+    const PrimFloat Var_arg2 = (params_args.GetArg(1)).AsFloat();     return ReturnTuple(Box_Bool(Var_arg1<Var_arg2));   } };  ReturnTuple DispatchFloat(PrimFloat value, const ValueFunction& label,-                          const ParamTuple& params, const ValueTuple& args) {+                          const ParamsArgs& params_args) {   switch (label.collection) {     case CategoryId_AsBool:       return ReturnTuple(Box_Bool(value != 0.0));
base/src/Extension_Int.cpp view
@@ -45,38 +45,38 @@ struct ExtType_Int : public Type_Int {   inline ExtType_Int(Category_Int& p, Params<0>::Type params) : Type_Int(p, params) {} -  ReturnTuple Call_maxBound(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_maxBound(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Int.maxBound")     return ReturnTuple(Box_Int(9223372036854775807LL));   } -  ReturnTuple Call_minBound(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_minBound(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Int.minBound")     return ReturnTuple(Box_Int(-9223372036854775807LL - 1LL));   } -  ReturnTuple Call_default(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_default(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Int.default")     return ReturnTuple(Box_Int(0));   } -  ReturnTuple Call_equals(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_equals(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Int.equals")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();-    const PrimInt Var_arg2 = (args.At(1)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();+    const PrimInt Var_arg2 = (params_args.GetArg(1)).AsInt();     return ReturnTuple(Box_Bool(Var_arg1==Var_arg2));   } -  ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_lessThan(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Int.lessThan")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();-    const PrimInt Var_arg2 = (args.At(1)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();+    const PrimInt Var_arg2 = (params_args.GetArg(1)).AsInt();     return ReturnTuple(Box_Bool(Var_arg1<Var_arg2));   } };  ReturnTuple DispatchInt(PrimInt value, const ValueFunction& label,-                        const ParamTuple& params, const ValueTuple& args) {+                        const ParamsArgs& params_args) {   switch (label.collection) {     case CategoryId_AsBool:       return ReturnTuple(Box_Bool(value != 0));
base/src/Extension_String.cpp view
@@ -48,17 +48,11 @@   std::string CategoryName() const final { return "StringBuilder"; }    ReturnTuple Dispatch(const ValueFunction& label,-                       const ParamTuple& params, const ValueTuple& args) final {-    if (args.Size() != label.arg_count) {-      FAIL() << "Wrong number of args";-    }-    if (params.Size() != label.param_count){-      FAIL() << "Wrong number of params";-    }+                       const ParamsArgs& params_args) final {     if (&label == &Function_Append_append) {       TRACE_FUNCTION("StringBuilder.append")       std::lock_guard<std::mutex> lock(mutex);-      output_ << TypeValue::Call(args.At(0), Function_Formatted_formatted, ParamTuple(), ArgTuple()).Only().AsString();+      output_ << TypeValue::Call(params_args.GetArg(0), Function_Formatted_formatted, PassParamsArgs()).At(0).AsString();       return ReturnTuple(VAR_SELF);     }     if (&label == &Function_Build_build) {@@ -66,7 +60,7 @@       std::lock_guard<std::mutex> lock(mutex);       return ReturnTuple(Box_String(output_.str()));     }-    return TypeValue::Dispatch(label, params, args);+    return TypeValue::Dispatch(label, params_args);   }   private:@@ -77,33 +71,33 @@ struct ExtType_String : public Type_String {   inline ExtType_String(Category_String& p, Params<0>::Type params) : Type_String(p, params) {} -  ReturnTuple Call_builder(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_builder(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.builder")     return ReturnTuple(BoxedValue::New<Value_StringBuilder>());   } -  ReturnTuple Call_default(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_default(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.default")     return ReturnTuple(Box_String(""));   } -  ReturnTuple Call_equals(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_equals(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.equals")-    const BoxedValue& Var_arg1 = (args.At(0));-    const BoxedValue& Var_arg2 = (args.At(1));+    const BoxedValue& Var_arg1 = (params_args.GetArg(0));+    const BoxedValue& Var_arg2 = (params_args.GetArg(1));     return ReturnTuple(Box_Bool(Var_arg1.AsString()==Var_arg2.AsString()));   } -  ReturnTuple Call_fromCharBuffer(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_fromCharBuffer(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.fromCharBuffer")-    const BoxedValue& Var_arg1 = (args.At(0));+    const BoxedValue& Var_arg1 = (params_args.GetArg(0));     return ReturnTuple(Box_String(PrimString(Var_arg1.AsCharBuffer())));   } -  ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_lessThan(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.lessThan")-    const BoxedValue& Var_arg1 = (args.At(0));-    const BoxedValue& Var_arg2 = (args.At(1));+    const BoxedValue& Var_arg1 = (params_args.GetArg(0));+    const BoxedValue& Var_arg2 = (params_args.GetArg(1));     return ReturnTuple(Box_Bool(Var_arg1.AsString()<Var_arg2.AsString()));   } };@@ -115,9 +109,7 @@    std::string CategoryName() const final { return "StringOrder"; } -  ReturnTuple Dispatch(const ValueFunction& label,-                       const ParamTuple& params,-                       const ValueTuple& args) final {+  ReturnTuple Dispatch(const ValueFunction& label, const ParamsArgs& params_args) final {     if (&label == &Function_Order_next) {       TRACE_FUNCTION("StringOrder.next")       if (index_+1 >= value_.size()) {@@ -134,7 +126,7 @@       }       return ReturnTuple(Box_Char(value_[index_]));     }-    return TypeValue::Dispatch(label, params, args);+    return TypeValue::Dispatch(label, params_args);   }   private:@@ -147,12 +139,12 @@   inline ExtValue_String(S<const Type_String> p, const PrimString& value)     : Value_String(std::move(p)), value_(value) {} -  ReturnTuple Call_asBool(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_asBool(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.asBool")     return ReturnTuple(Box_Bool(value_.size() != 0));   } -  ReturnTuple Call_defaultOrder(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_defaultOrder(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.defaultOrder")     if (value_.empty()) {       return ReturnTuple(Var_empty);@@ -161,29 +153,29 @@     }   } -  ReturnTuple Call_formatted(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_formatted(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.formatted")     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_readAt(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_readAt(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.readAt")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0 || Var_arg1 >= value_.size()) {       FAIL() << "Read position " << Var_arg1 << " is out of bounds";     }     return ReturnTuple(Box_Char(value_[Var_arg1]));   } -  ReturnTuple Call_size(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_size(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.size")     return ReturnTuple(Box_Int(value_.size()));   } -  ReturnTuple Call_subSequence(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_subSequence(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("String.subSequence")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();-    const PrimInt Var_arg2 = (args.At(1)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();+    const PrimInt Var_arg2 = (params_args.GetArg(1)).AsInt();     if (Var_arg1 < 0 || Var_arg1 > value_.size()) {       FAIL() << "Subsequence position " << Var_arg1 << " is out of bounds";     }
base/src/boxed.cpp view
@@ -28,16 +28,16 @@ #endif  // ZEOLITE_PUBLIC_NAMESPACE  ReturnTuple DispatchBool(PrimBool value, const ValueFunction& label,-                         const ParamTuple& params, const ValueTuple& args);+                         const ParamsArgs& params_args);  ReturnTuple DispatchChar(PrimChar value, const ValueFunction& label,-                         const ParamTuple& params, const ValueTuple& args);+                         const ParamsArgs& params_args);  ReturnTuple DispatchInt(PrimInt value, const ValueFunction& label,-                        const ParamTuple& params, const ValueTuple& args);+                        const ParamsArgs& params_args);  ReturnTuple DispatchFloat(PrimFloat value, const ValueFunction& label,-                          const ParamTuple& params, const ValueTuple& args);+                          const ParamsArgs& params_args);  #ifdef ZEOLITE_PUBLIC_NAMESPACE }  // namespace ZEOLITE_PUBLIC_NAMESPACE@@ -145,49 +145,50 @@ }  ReturnTuple BoxedValue::Dispatch(-  const ValueFunction& label, const ParamTuple& params, const ValueTuple& args) const {+  const ValueFunction& label, const ParamsArgs& params_args) const {   switch (union_.type_) {     case UnionValue::Type::EMPTY:       FAIL() << "Function called on empty value";       __builtin_unreachable();       break;     case UnionValue::Type::BOOL:-      return DispatchBool(union_.value_.as_bool_, label, params, args);+      return DispatchBool(union_.value_.as_bool_, label, params_args);     case UnionValue::Type::CHAR:-      return DispatchChar(union_.value_.as_char_, label, params, args);+      return DispatchChar(union_.value_.as_char_, label, params_args);     case UnionValue::Type::INT:-      return DispatchInt(union_.value_.as_int_, label, params, args);+      return DispatchInt(union_.value_.as_int_, label, params_args);     case UnionValue::Type::FLOAT:-      return DispatchFloat(union_.value_.as_float_, label, params, args);+      return DispatchFloat(union_.value_.as_float_, label, params_args);     case UnionValue::Type::BOXED:       if (!union_.value_.as_pointer_ || !union_.value_.as_pointer_->object_) {         FAIL() << "Function called on null pointer";       }-      return union_.value_.as_pointer_->object_->Dispatch(label, params, args);+      return union_.value_.as_pointer_->object_->Dispatch(label, params_args);   } }  void BoxedValue::Cleanup() {-  switch (union_.type_) {-    case UnionValue::Type::BOXED:-      while (union_.value_.as_pointer_->lock_.test_and_set(std::memory_order_acquire));-      if (--union_.value_.as_pointer_->strong_ == 0) {-        TypeValue* const object = union_.value_.as_pointer_->object_;-        union_.value_.as_pointer_->object_ = nullptr;-        union_.value_.as_pointer_->lock_.clear(std::memory_order_release);-        object->~TypeValue();-        if (--union_.value_.as_pointer_->weak_ == 0) {-          // NOTE: as_bytes_ contains object => ~TypeValue() must happen first.-          free(union_.value_.as_bytes_);-        }-      } else {-        union_.value_.as_pointer_->lock_.clear(std::memory_order_release);+  while (union_.type_ == UnionValue::Type::BOXED) {+    while (union_.value_.as_pointer_->lock_.test_and_set(std::memory_order_acquire));+    if (--union_.value_.as_pointer_->strong_ == 0) {+      TypeValue* const object = union_.value_.as_pointer_->object_;+      union_.value_.as_pointer_->object_ = nullptr;+      union_.value_.as_pointer_->lock_.clear(std::memory_order_release);+      BoxedValue next = object->FlatCleanup();+      object->~TypeValue();+      if (--union_.value_.as_pointer_->weak_ == 0) {+        // NOTE: as_bytes_ contains object => ~TypeValue() must happen first.+        free(union_.value_.as_bytes_);       }-      break;-    default:+      union_ = next.union_;+      // This is only to skip cleanup of next.+      next.union_.type_ = UnionValue::Type::EMPTY;+    } else {+      union_.value_.as_pointer_->lock_.clear(std::memory_order_release);       break;+    }   }-  union_.type_  = UnionValue::Type::EMPTY;+  union_.type_ = UnionValue::Type::EMPTY;   union_.value_.as_pointer_ = nullptr; } 
base/src/category-source.cpp view
@@ -182,20 +182,17 @@ const BoxedValue Var_empty;  -ReturnTuple TypeCategory::Dispatch(const CategoryFunction& label,-                                   const ParamTuple& params, const ValueTuple& args) {+ReturnTuple TypeCategory::Dispatch(const CategoryFunction& label, const ParamsArgs& params_args) {   FAIL() << CategoryName() << " does not implement " << label;   __builtin_unreachable(); } -ReturnTuple TypeInstance::Dispatch(const TypeFunction& label,-                                   const ParamTuple& params, const ValueTuple& args) const {+ReturnTuple TypeInstance::Dispatch(const TypeFunction& label, const ParamsArgs& params_args) const {   FAIL() << CategoryName() << " does not implement " << label;   __builtin_unreachable(); } -ReturnTuple TypeValue::Dispatch(const ValueFunction& label,-                                const ParamTuple& params, const ValueTuple& args) {+ReturnTuple TypeValue::Dispatch(const ValueFunction& label, const ParamsArgs& params_args) {   FAIL() << CategoryName() << " does not implement " << label;   __builtin_unreachable(); }
+ base/src/returns.cpp view
@@ -0,0 +1,93 @@+/* -----------------------------------------------------------------------------+Copyright 2019,2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++#include "returns.hpp"++#include "logging.hpp"+++void ReturnTuple::TransposeFrom(ReturnTuple&& other) {+  if (Size() != other.Size()) {+    FAIL() << "ReturnTuple size mismatch in assignment: " << Size()+           << " (expected) " << other.Size() << " (actual)";+  }+  first_ = std::move(other.first_);+  for (int i = 0; i < data_.Size(); ++i) {+    data_[i] = std::move(other.data_[i]);+  }+}++int ReturnTuple::Size() const {+  return data_.Size()+1;+}++BoxedValue& ReturnTuple::At(int pos) {+  if (pos == 0) {+    return first_;+  }+  if (pos < 0 || pos >= Size()) {+    FAIL() << "Bad return index";+  }+  return data_[pos-1];+}++const BoxedValue& ReturnTuple::At(int pos) const {+  if (pos == 0) {+    return first_;+  }+  if (pos < 0 || pos >= Size()) {+    FAIL() << "Bad return index";+  }+  return data_[pos-1];+}+++namespace zeolite_internal {++thread_local PoolCache<BoxedValue> PoolManager<BoxedValue>::cache3_(256);++// static+typename PoolManager<BoxedValue>::PoolEntry* PoolManager<BoxedValue>::Take(int orig_size) {+  int size = orig_size;+  if (size < 1) return nullptr;+  if (size < 3) {+    size = 3;+  }+  PoolEntry* storage = nullptr;+  if (size == 3 && (storage = cache3_.Take())) {+  } else {+    storage = new (new unsigned char[sizeof(PoolEntry) + size*sizeof(Managed)]) PoolEntry(size, nullptr);+  }+  new (storage->data()) Managed[orig_size];+  return storage;+}++// static+void PoolManager<BoxedValue>::Return(PoolEntry* storage, int orig_size) {+  if (!storage) return;+  for (int i = 0; i < orig_size; ++i) {+    storage->data()[i].~Managed();+  }+  if (storage->size == 3 && cache3_.Return(storage)) {+    return;+  }+  storage->~PoolEntry();+  delete[] (unsigned char*) storage;+}++}  // namespace zeolite_internal
− base/src/types.cpp
@@ -1,233 +0,0 @@-/* ------------------------------------------------------------------------------Copyright 2019,2021 Kevin P. Barry--Licensed under the Apache License, Version 2.0 (the "License");-you may not use this file except in compliance with the License.-You may obtain a copy of the License at--    http://www.apache.org/licenses/LICENSE-2.0--Unless required by applicable law or agreed to in writing, software-distributed under the License is distributed on an "AS IS" BASIS,-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.-See the License for the specific language governing permissions and-limitations under the License.------------------------------------------------------------------------------ */--// Author: Kevin P. Barry [ta0kira@gmail.com]--#include "types.hpp"--#include <atomic>--#include "boxed.hpp"-#include "logging.hpp"---int ArgTuple::Size() const {-  return data_.Size();-}--const BoxedValue& ArgTuple::At(int pos) const {-  if (pos < 0 || pos >= data_.Size()) {-    FAIL() << "Bad ArgTuple index";-  }-  return *data_[pos];-}--const BoxedValue& ArgTuple::Only() const {-  if (data_.Size() != 1) {-    FAIL() << "Bad ArgTuple index";-  }-  return *data_[0];-}--void ReturnTuple::TransposeFrom(ReturnTuple&& other) {-  if (Size() != other.Size()) {-    FAIL() << "ReturnTuple size mismatch in assignment: " << Size()-           << " (expected) " << other.Size() << " (actual)";-  }-  for (int i = 0; i < Size(); ++i) {-    At(i) = std::move(other.At(i));-  }-}--int ReturnTuple::Size() const {-  return data_.Size();-}--BoxedValue& ReturnTuple::At(int pos) {-  if (pos < 0 || pos >= data_.Size()) {-    FAIL() << "Bad ReturnTuple index";-  }-  return data_[pos];-}--const BoxedValue& ReturnTuple::At(int pos) const {-  if (pos < 0 || pos >= data_.Size()) {-    FAIL() << "Bad ReturnTuple index";-  }-  return data_[pos];-}--const BoxedValue& ReturnTuple::Only() const {-  if (data_.Size() != 1) {-    FAIL() << "Bad ReturnTuple index";-  }-  return data_[0];-}--int ParamTuple::Size() const {-  return data_.Size();-}--const S<const TypeInstance>& ParamTuple::At(int pos) const {-  if (pos < 0 || pos >= data_.Size()) {-    FAIL() << "Bad ParamTuple index";-  }-  return data_[pos];-}---namespace {--template<class P>-static inline P* PoolTakeCommon(std::atomic_flag& flag,-                                P*& pool, unsigned int& size) {-  while (flag.test_and_set(std::memory_order_acquire));-  P* const storage = pool;-  if (storage == nullptr) {-    flag.clear(std::memory_order_release);-    return nullptr;-  } else {-    --size;-    pool = storage->next;-    flag.clear(std::memory_order_release);-    storage->next = nullptr;-    return storage;-  }-}--template<class P>-static inline bool PoolReturnCommon(P* storage, std::atomic_flag& flag,-                                    P*& pool, unsigned int& size,-                                    unsigned int limit) {-  while (flag.test_and_set(std::memory_order_acquire));-  P* const head = pool;-  if (size < limit) {-    ++size;-    storage->next = head;-    pool = storage;-    flag.clear(std::memory_order_release);-    return true;-  } else {-    flag.clear(std::memory_order_release);-    return false;-  }-}--}  // namespace---namespace zeolite_internal {--unsigned int PoolManager<BoxedValue>::pool4_size_ = 0;-typename PoolManager<BoxedValue>::PoolEntry* PoolManager<BoxedValue>::pool4_{nullptr};-std::atomic_flag PoolManager<BoxedValue>::pool4_flag_ = ATOMIC_FLAG_INIT;--// static-typename PoolManager<BoxedValue>::PoolEntry* PoolManager<BoxedValue>::Take(int orig_size) {-  int size = orig_size;-  if (size == 0) return nullptr;-  if (size < 4) {-    size = 4;-  }-  PoolEntry* storage = nullptr;-  if (size == 4 && (storage = PoolTakeCommon(pool4_flag_, pool4_, pool4_size_))) {-  } else {-    storage = new (new unsigned char[sizeof(PoolEntry) + size*sizeof(Managed)]) PoolEntry(size, nullptr);-  }-  new (storage->data()) Managed[orig_size];-  return storage;-}--// static-void PoolManager<BoxedValue>::Return(PoolEntry* storage, int orig_size) {-  if (!storage) return;-  for (int i = 0; i < orig_size; ++i) {-    storage->data()[i].~Managed();-  }-  if (storage->size == 4 && PoolReturnCommon(storage, pool4_flag_, pool4_, pool4_size_, pool_limit_)) {-    return;-  }-  storage->~PoolEntry();-  delete[] (unsigned char*) storage;-}---unsigned int PoolManager<const BoxedValue*>::pool4_size_ = 0;-typename PoolManager<const BoxedValue*>::PoolEntry* PoolManager<const BoxedValue*>::pool4_{nullptr};-std::atomic_flag PoolManager<const BoxedValue*>::pool4_flag_ = ATOMIC_FLAG_INIT;--// static-typename PoolManager<const BoxedValue*>::PoolEntry* PoolManager<const BoxedValue*>::Take(int orig_size) {-  int size = orig_size;-  if (size == 0) return nullptr;-  if (size < 4) {-    size = 4;-  }-  PoolEntry* storage = nullptr;-  if (size == 4 && (storage = PoolTakeCommon(pool4_flag_, pool4_, pool4_size_))) {-  } else {-    storage = new (new unsigned char[sizeof(PoolEntry) + size*sizeof(Managed)]) PoolEntry(size, nullptr);-  }-  // NOTE: Skipping constructor calls since pointers are trivial.-  return storage;-}--// static-void PoolManager<const BoxedValue*>::Return(PoolEntry* storage, int orig_size) {-  if (!storage) return;-  // NOTE: Skipping destructor calls since pointers are trivial.-  if (storage->size == 4 && PoolReturnCommon(storage, pool4_flag_, pool4_, pool4_size_, pool_limit_)) {-    return;-  }-  storage->~PoolEntry();-  delete[] (unsigned char*) storage;-}---unsigned int PoolManager<S<const TypeInstance>>::pool4_size_ = 0;-typename PoolManager<S<const TypeInstance>>::PoolEntry* PoolManager<S<const TypeInstance>>::pool4_{nullptr};-std::atomic_flag PoolManager<S<const TypeInstance>>::pool4_flag_ = ATOMIC_FLAG_INIT;--// static-typename PoolManager<S<const TypeInstance>>::PoolEntry* PoolManager<S<const TypeInstance>>::Take(int orig_size) {-  int size = orig_size;-  if (size == 0) return nullptr;-  if (size < 4) {-    size = 4;-  }-  PoolEntry* storage = nullptr;-  if (size == 4 && (storage = PoolTakeCommon(pool4_flag_, pool4_, pool4_size_))) {-  } else {-    storage = new (new unsigned char[sizeof(PoolEntry) + size*sizeof(Managed)]) PoolEntry(size, nullptr);-  }-  new (storage->data()) Managed[orig_size];-  return storage;-}--// static-void PoolManager<S<const TypeInstance>>::Return(PoolEntry* storage, int orig_size) {-  if (!storage) return;-  for (int i = 0; i < orig_size; ++i) {-    storage->data()[i].~Managed();-  }-  if (storage->size == 4 && PoolReturnCommon(storage, pool4_flag_, pool4_, pool4_size_, pool_limit_)) {-    return;-  }-  storage->~PoolEntry();-  delete[] (unsigned char*) storage;-}--}  // namespace zeolite_internal
base/types.hpp view
@@ -19,7 +19,6 @@ #ifndef TYPES_HPP_ #define TYPES_HPP_ -#include <atomic> #include <cstdint> #include <functional> #include <memory>@@ -168,148 +167,5 @@ typename ParamsKey<N>::Type GetKeyFromParams(const typename Params<N>::Type& from) {   return KeyFromParams<N, 0>::Get(from); }--class ValueTuple {- public:-  virtual int Size() const = 0;-  virtual const BoxedValue& At(int pos) const = 0;-  virtual const BoxedValue& Only() const = 0;-- protected:-  ValueTuple() = default;-  virtual ~ValueTuple() = default;-- private:-  void* operator new(std::size_t size) = delete;-};---namespace zeolite_internal {--template<>-class PoolManager<BoxedValue> {-  using PoolEntry = PoolStorage<BoxedValue>;-  using Managed = PoolEntry::Managed;--  template<class> friend class PoolArray;--  static PoolEntry* Take(int size);-  static void Return(PoolEntry* storage, int size);--  static constexpr unsigned int pool_limit_ = 256;-  static unsigned int pool4_size_;-  static PoolEntry* pool4_;-  static std::atomic_flag pool4_flag_;-};--template<>-class PoolManager<const BoxedValue*> {-  using PoolEntry = PoolStorage<const BoxedValue*>;-  using Managed = PoolEntry::Managed;--  template<class> friend class PoolArray;--  static PoolEntry* Take(int size);-  static void Return(PoolEntry* storage, int size);--  static constexpr unsigned int pool_limit_ = 256;-  static unsigned int pool4_size_;-  static PoolEntry* pool4_;-  static std::atomic_flag pool4_flag_;-};--template<>-class PoolManager<S<const TypeInstance>> {-  using PoolEntry = PoolStorage<S<const TypeInstance>>;-  using Managed = PoolEntry::Managed;--  template<class> friend class PoolArray;--  static PoolEntry* Take(int size);-  static void Return(PoolEntry* storage, int size);--  static constexpr unsigned int pool_limit_ = 256;-  static unsigned int pool4_size_;-  static PoolEntry* pool4_;-  static std::atomic_flag pool4_flag_;-};--}  // namespace zeolite_internal---class ReturnTuple : public ValueTuple {- public:-  constexpr ReturnTuple() : data_() {}--  ReturnTuple(int size) : data_(size) {}--  template<class...Ts>-  explicit ReturnTuple(Ts... returns) : data_(sizeof...(Ts)) {-    data_.Init(std::move(returns)...);-  }--  ReturnTuple(ReturnTuple&&) = default;--  void TransposeFrom(ReturnTuple&& other);--  int Size() const final;-  BoxedValue& At(int pos);-  const BoxedValue& At(int pos) const final;-  const BoxedValue& Only() const final;-- private:-  ReturnTuple(const ReturnTuple&) = delete;-  ReturnTuple& operator =(ReturnTuple&&) = delete;-  ReturnTuple& operator =(const ReturnTuple&) = delete;-  void* operator new(std::size_t size) = delete;--  zeolite_internal::PoolArray<BoxedValue> data_;-};--class ArgTuple : public ValueTuple {- public:-  constexpr ArgTuple() : data_() {}--  template<class...Ts>-  explicit ArgTuple(const Ts&... args) : data_(sizeof...(Ts)) {-    data_.Init(&args...);-  }--  int Size() const final;-  const BoxedValue& At(int pos) const final;-  const BoxedValue& Only() const final;-- private:-  ArgTuple(const ArgTuple&) = delete;-  ArgTuple(ArgTuple&&) = delete;-  ArgTuple& operator = (const ArgTuple&) = delete;-  ArgTuple& operator = (ArgTuple&&) =  delete;-  void* operator new(std::size_t size) = delete;--  zeolite_internal::PoolArray<const BoxedValue*> data_;-};--class ParamTuple {- public:-  constexpr ParamTuple() : data_() {}--  template<class...Ts>-  explicit ParamTuple(const Ts&... params) : data_(sizeof...(Ts)) {-    data_.Init(std::move(params)...);-  }--  ParamTuple(ParamTuple&& other) = default;--  int Size() const;-  const S<const TypeInstance>& At(int pos) const;-- private:-  ParamTuple(const ParamTuple&) = delete;-  ParamTuple& operator = (const ParamTuple&) = delete;-  ParamTuple& operator = (ParamTuple&&) = delete;-  void* operator new(std::size_t size) = delete;--  zeolite_internal::PoolArray<S<const TypeInstance>> data_;-};  #endif  // TYPES_HPP_
bin/unit-tests.hs view
@@ -1,5 +1,5 @@ {- ------------------------------------------------------------------------------Copyright 2019-2020 Kevin P. Barry+Copyright 2019-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -23,6 +23,7 @@ import qualified Test.DefinedCategory as TestDefinedCategory import qualified Test.IntegrationTest as TestIntegrationTest import qualified Test.MergeTree       as TestMergeTree+import qualified Test.ParseConfig     as TestParseConfig import qualified Test.ParseMetadata   as TestParseMetadata import qualified Test.Parser          as TestParser import qualified Test.Pragma          as TestPragma@@ -38,6 +39,7 @@     labelWith "DefinedCategory" TestDefinedCategory.tests,     labelWith "IntegrationTest" TestIntegrationTest.tests,     labelWith "MergeTree"       TestMergeTree.tests,+    labelWith "ParseConfig"     TestParseConfig.tests,     labelWith "ParseMetadata"   TestParseMetadata.tests,     labelWith "Parser"          TestParser.tests,     labelWith "Pragma"          TestPragma.tests,
bin/zeolite-setup.hs view
@@ -1,5 +1,5 @@ {- ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -17,6 +17,7 @@ -- Author: Kevin P. Barry [ta0kira@gmail.com]  import Control.Monad (when)+import Control.Monad.Trans import System.Directory import System.Environment import System.Exit@@ -28,20 +29,26 @@ import Cli.RunCompiler import Config.LoadConfig import Config.LocalConfig+import Config.ParseConfig ()   main :: IO ()-main = do-  (cxxSpec:arSpec:_) <- fmap ((++ repeat Nothing) . map Just) getArgs-  f <- localConfigPath-  isFile <- doesFileExist f-  when isFile $ do-    hPutStrLn stderr $ "*** WARNING: Local config " ++ f ++ " will be overwritten. ***"-  config <- createConfig cxxSpec arSpec-  hPutStrLn stderr $ "Writing local config to " ++ f ++ "."-  writeFile f (show config ++ "\n")-  initLibraries config-  hPutStrLn stderr "Setup is now complete!"+main = tryTrackedErrorsIO "" "Zeolite setup failed:" (lift getArgs >>= handle) where+  handle ("--reuse":_) = do+    config <- loadConfig+    runWith config+  handle args = do+    let (cxxSpec:arSpec:_) = (map Just $ args) ++ repeat Nothing+    f <- lift $ localConfigPath+    isFile <- lift $ doesFileExist f+    when isFile $+      lift $ hPutStrLn stderr $ "*** WARNING: Local config " ++ f ++ " will be overwritten. ***"+    config <- lift $ createConfig cxxSpec arSpec+    saveConfig config+    runWith config+  runWith config = do+    initLibraries config+    lift $ hPutStrLn stderr "Setup is now complete!"  clangBinary :: String clangBinary = "clang++"@@ -85,27 +92,25 @@   handle [(n,"")] = Left n   handle _        = Right s -createConfig :: Maybe String -> Maybe String -> IO LocalConfig+createConfig :: Maybe String -> Maybe String -> IO (Resolver,Backend) createConfig cxxSpec arSpec = do   clang <- findExecutables clangBinary   gcc   <- findExecutables gccBinary   ar    <- findExecutables arBinary   compiler <- promptChoice "Which clang-compatible C++ compiler should be used?" cxxSpec (clang ++ gcc)   archiver <- promptChoice "Which ar-compatible archiver should be used?"        arSpec  ar-  let config = LocalConfig {-      lcBackend = UnixBackend {-        ucCxxBinary    = compiler,-        ucCompileFlags = compileFlags,-        ucLibraryFlags = libraryFlags,-        ucBinaryFlags  = binaryFlags,-        ucArBinary     = archiver-      },-      lcResolver = SimpleResolver {-        srVisibleSystem = includePaths,-        srExtraPaths = []-      }-    }-  return config+  return (+    SimpleResolver {+      srVisibleSystem = includePaths,+      srExtraPaths = []+    },+    UnixBackend {+      ucCxxBinary    = compiler,+      ucCompileFlags = compileFlags,+      ucLibraryFlags = libraryFlags,+      ucBinaryFlags  = binaryFlags,+      ucArBinary     = archiver+    })  promptChoice :: String -> Maybe String -> [String] -> IO String promptChoice _ (Just spec) cs = handle $ intOrString spec where@@ -147,9 +152,9 @@     exitFailure   hGetLine stdin -initLibraries :: LocalConfig -> IO ()-initLibraries (LocalConfig backend resolver) = do-  path <- rootPath >>= canonicalizePath+initLibraries :: (Resolver,Backend) -> TrackedErrorsIO ()+initLibraries (resolver,backend) = do+  path <- lift $ rootPath >>= canonicalizePath   let options = CompileOptions {       coHelp = HelpNotNeeded,       coPublicDeps = [],@@ -161,7 +166,6 @@       coMode = CompileRecompileRecursive,       coForce = ForceAll     }-  tryTrackedErrorsIO "Warnings:" "Zeolite setup failed:" $ do-    runCompiler resolver backend options-    mapM_ optionalWarning optionalLibraries where-    optionalWarning library = compilerWarningM $ "Optional library " ++ library ++ " must be built manually if needed"+  runCompiler resolver backend options+  mapM_ optionalWarning optionalLibraries where+  optionalWarning library = compilerWarningM $ "Optional library " ++ library ++ " must be built manually if needed"
bin/zeolite.hs view
@@ -1,5 +1,5 @@ {- ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -18,10 +18,11 @@  import Control.Monad (when) import Control.Monad.Trans-import GHC.IO.Handle+import System.FilePath import System.Directory import System.Environment import System.Exit+import GHC.IO.Handle import System.IO import qualified Data.Map as Map import qualified Data.Set as Set@@ -85,57 +86,74 @@   if null os      then exitSuccess      else exitFailure-tryFastModes ("--show-traces":ps) = do-  tryZeoliteIO $ do-    (_,backend) <- loadConfig-    let h = getCompilerHash backend-    mapM_ (showTraces h) ps-  exitSuccess where-    showTraces h p = do-      p' <- errorFromIO $ canonicalizePath p-      -- Not needed to show traces, but causes the error to be about the module-      -- rather than the filename if the module hasn't been compiled.-      _ <- loadModuleMetadata h ForceAll Map.empty p'-      ts <- readPossibleTraces p-      mapM_ (errorFromIO . hPutStrLn stdout) $ Set.toList ts-tryFastModes ("--missed-lines":l:ps) = do-  tryZeoliteIO $ do-    (_,backend) <- loadConfig-    let h = getCompilerHash backend-    expected <- fmap Set.unions $ mapM (getTraces h) ps-    actual <- loadTraces-    mapM_ (errorFromIO . hPutStrLn stdout) $ Set.toList $ expected `Set.difference` actual-  exitSuccess where-    loadTraces = do-      errorFromIO $ hPutStrLn stderr $ "Loading trace data from \"" ++ l ++ "\"."-      lc <- errorFromIO $ readFile l-      fmap (Set.fromList . map teContext) $ parseTracesFile (l,lc)-    getTraces h p = do-      p' <- errorFromIO $ canonicalizePath p-      -- Not needed to show traces, but causes the error to be about the module-      -- rather than the filename if the module hasn't been compiled.-      _ <- loadModuleMetadata h ForceAll Map.empty p'-      readPossibleTraces p-tryFastModes ("--missed-lines":_) = do-  hPutStrLn stderr $ "Pass a .csv generated by -t --log-traces."-  exitFailure-tryFastModes ("--show-deps":ps) = do-  tryZeoliteIO $ do-    (_,backend) <- loadConfig-    let h = getCompilerHash backend-    mapM_ (showDeps h) ps-  exitSuccess where-    showDeps h p = do-      p' <- errorFromIO $ canonicalizePath p-      m <- loadModuleMetadata h ForceAll Map.empty p'-      errorFromIO $ hPutStrLn stdout $ show p'-      errorFromIO $ mapM_ showDep (cmObjectFiles m)-    showDep (CategoryObjectFile c ds _) = do-      mapM_ (\d -> hPutStrLn stdout $ "  " ++ show (ciCategory c) ++-                                      " -> " ++ show (ciCategory d) ++-                                      " " ++ show (ciPath d)) ds-    showDep _ = return ()-tryFastModes _ = return ()+tryFastModes os0 = maybePath os0 where+  maybePath ("-p":root:os) = tryMode root os+  maybePath os             = tryMode "" os+  tryMode root ("--clean":ps) = do+    tryZeoliteIO $ do+      mapCompilerM_ loadModule ps+      mapCompilerM_ clean ps+    exitSuccess where+      loadModule p = do+        p' <- errorFromIO $ canonicalizePath (root </> p)+        -- Not needed for clean, but forces the caller to only pass real modules.+        loadRecompile p'+      clean p = do+        p' <- errorFromIO $ canonicalizePath (root </> p)+        errorFromIO $ hPutStrLn stderr $ "Clearing cached data for module \"" ++ p' ++ "\"."+        eraseCachedData p'+  tryMode root ("--show-traces":ps) = do+    tryZeoliteIO $ do+      (_,backend) <- loadConfig+      h <- getCompilerHash backend+      mapCompilerM_ (showTraces h) ps+    exitSuccess where+      showTraces h p = do+        p' <- errorFromIO $ canonicalizePath (root </> p)+        -- Not needed to show traces, but causes the error to be about the+        -- module rather than the filename if the module hasn't been compiled.+        _ <- loadModuleMetadata h ForceAll Map.empty p'+        ts <- readPossibleTraces p'+        mapM_ (errorFromIO . hPutStrLn stdout) $ Set.toList ts+  tryMode root ("--missed-lines":l:ps) = do+    tryZeoliteIO $ do+      (_,backend) <- loadConfig+      h <- getCompilerHash backend+      expected <- fmap Set.unions $ mapCompilerM (getTraces h) ps+      actual <- loadTraces+      mapM_ (errorFromIO . hPutStrLn stdout) $ Set.toList $ expected `Set.difference` actual+    exitSuccess where+      loadTraces = do+        l' <- errorFromIO $ canonicalizePath (root </> l)+        errorFromIO $ hPutStrLn stderr $ "Loading trace data from \"" ++ l' ++ "\"."+        lc <- errorFromIO $ readFile l'+        fmap (Set.fromList . map teContext) $ parseTracesFile (l,lc)+      getTraces h p = do+        p' <- errorFromIO $ canonicalizePath (root </> p)+        -- Not needed to check traces, but causes the error to be about the+        -- module rather than the filename if the module hasn't been compiled.+        _ <- loadModuleMetadata h ForceAll Map.empty p'+        readPossibleTraces p'+  tryMode _ ("--missed-lines":_) = do+    hPutStrLn stderr $ "Pass a .csv generated by -t --log-traces."+    exitFailure+  tryMode root ("--show-deps":ps) = do+    tryZeoliteIO $ do+      (_,backend) <- loadConfig+      h <- getCompilerHash backend+      mapCompilerM_ (showDeps h) ps+    exitSuccess where+      showDeps h p = do+        p' <- errorFromIO $ canonicalizePath (root </> p)+        m <- loadModuleMetadata h ForceAll Map.empty p'+        errorFromIO $ hPutStrLn stdout $ show p'+        errorFromIO $ mapM_ showDep (cmObjectFiles m)+      showDep (CategoryObjectFile c ds _) = do+        mapM_ (\d -> hPutStrLn stdout $ "  " ++ show (ciCategory c) +++                                        " -> " ++ show (ciCategory d) +++                                        " " ++ show (ciPath d)) ds+      showDep _ = return ()+  tryMode _ _ = return ()  tryZeoliteIO :: TrackedErrorsIO a -> IO a tryZeoliteIO = tryTrackedErrorsIO "Warnings (ignored):" "Zeolite execution failed:"
example/parser/parse-text.0rx view
@@ -16,12 +16,12 @@           // Partial match => set error context.           return context.setBrokenInput(message)         } else {-          return context.setValue<?>(ErrorOr:error(message))+          return context.setValue(ErrorOr:error(message))         }       }       context <- context.advance()     }-    return context.setValue<?>(ErrorOr:value<?>(match))+    return context.setValue(ErrorOr:value(match))   }    create (match) {@@ -74,12 +74,12 @@       context <- context.advance()     }     if (count >= min) {-      return context.setValue<?>(ErrorOr:value<?>(builder.build()))+      return context.setValue(ErrorOr:value(builder.build()))     } elif (count > 0) {       // Partial match => set error context.       return context.setBrokenInput(message)     } else {-      return context.setValue<?>(ErrorOr:error(message))+      return context.setValue(ErrorOr:error(message))     }   } @@ -99,9 +99,9 @@     }     if (contextOld.atEof() || contextOld.current() != match) {       String message <- "Failed to match '" + match.formatted() + "' at " + contextOld.getPosition()-      return contextOld.setValue<?>(ErrorOr:error(message))+      return contextOld.setValue(ErrorOr:error(message))     } else {-      return contextOld.advance().setValue<?>(ErrorOr:value<?>(match))+      return contextOld.advance().setValue(ErrorOr:value(match))     }   } @@ -122,7 +122,7 @@   @value #x value    run (contextOld) {-    return contextOld.setValue<?>(ErrorOr:value<?>(value))+    return contextOld.setValue(ErrorOr:value(value))   }    create (value) {@@ -140,7 +140,7 @@   @value String message    run (contextOld) {-    return contextOld.setValue<?>(ErrorOr:error(message))+    return contextOld.setValue(ErrorOr:error(message))   }    create (message) {@@ -163,7 +163,7 @@     }     ParseContext<#x> context <- contextOld.run<#x>(parser)     if (context.hasAnyError()) {-      return contextOld.setValue<?>(context.getValue().convertError())+      return contextOld.setValue(context.getValue().convertError())     } else {       return context.toState()     }@@ -220,11 +220,11 @@     if (context.hasAnyError()) {       return context.toState()     } else {-      ParseContext<any> context2 <- context.run<?>(parser2)+      ParseContext<any> context2 <- context.run(parser2)       if (context2.hasAnyError()) {         return context2.convertError()       } else {-        return context2.setValue<?>(context.getValue())+        return context2.setValue(context.getValue())       }     }   }@@ -248,7 +248,7 @@     if (contextOld.hasAnyError()) {       return contextOld.convertError()     }-    ParseContext<any> context <- contextOld.run<?>(parser1)+    ParseContext<any> context <- contextOld.run(parser1)     if (context.hasAnyError()) {       return context.convertError()     } else {
example/parser/parser-test.0rt view
@@ -4,10 +4,10 @@  unittest test {   String raw <- FileTesting.forceReadFile($ExprLookup[MODULE_PATH]$ + "/test-data.txt")-  ErrorOr<TestData> errorOrData <- TestDataParser.create() `ParseState:consumeAll<?>` raw+  ErrorOr<TestData> errorOrData <- TestDataParser.create() `ParseState:consumeAll` raw   TestData data <- errorOrData.getValue() -  \ Testing.checkEquals<?>(data.getName(),"example data")-  \ Testing.checkEquals<?>(data.getDescription(),"THIS_IS_A_TOKEN")-  \ Testing.checkEquals<?>(data.getBoolean(),false)+  \ Testing.checkEquals(data.getName(),"example data")+  \ Testing.checkEquals(data.getDescription(),"THIS_IS_A_TOKEN")+  \ Testing.checkFalse(data.getBoolean()) }
example/parser/parser.0rx view
@@ -94,7 +94,7 @@    @category new (String) -> (ParseState<any>)   new (data) {-    return ParseState<any>{ data, 0, 1, 1, ErrorOr:value<?>(Void.void()), empty }+    return ParseState<any>{ data, 0, 1, 1, ErrorOr:value(Void.void()), empty }   }    @value getError () -> (Formatted)
example/parser/test-data.0rx view
@@ -44,7 +44,7 @@    refines Parser<TestData> -  @category Parser<any> whitespace <- SequenceOfParser.create(" \n\t",1,0) `Parse.or<?>` Parse.error("Expected whitespace")+  @category Parser<any> whitespace <- SequenceOfParser.create(" \n\t",1,0) `Parse.or` Parse.error("Expected whitespace")    @category String sentenceChars <- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +                                     "abcdefghijklmnopqrstuvwxyz" +@@ -52,36 +52,36 @@   @category Parser<String> sentence <- SequenceOfParser.create(sentenceChars,0,0)   @category Parser<any>    quote    <- CharParser.create('"') -  @category Parser<String> quotedSentence  <- quote `Parse.right<?>` sentence `Parse.left<?>` quote+  @category Parser<String> quotedSentence  <- quote `Parse.right` sentence `Parse.left` quote   @category Parser<String> token           <- SequenceOfParser.create("ABCDEFGHIJKLMNOPQRSTUVWXYZ_",1,0)-  @category Parser<String> sentenceOrToken <- quotedSentence `Parse.or<?>` token `Parse.left<?>` whitespace+  @category Parser<String> sentenceOrToken <- quotedSentence `Parse.or` token `Parse.left` whitespace -  @category Parser<Bool> acronym           <- StringParser.create("acronym")  `Parse.right<?>` Parse.const<?>(true)-  @category Parser<Bool> aardvark          <- StringParser.create("aardvark") `Parse.right<?>` Parse.const<?>(false)-  @category Parser<Bool> acronymOrAardvark <- Parse.try<?>(acronym) `Parse.or<?>` aardvark `Parse.left<?>` whitespace+  @category Parser<Bool> acronym           <- StringParser.create("acronym")  `Parse.right` Parse.const(true)+  @category Parser<Bool> aardvark          <- StringParser.create("aardvark") `Parse.right` Parse.const(false)+  @category Parser<Bool> acronymOrAardvark <- Parse.try(acronym) `Parse.or` aardvark `Parse.left` whitespace -  @category Parser<any> fileStart      <- StringParser.create("file_start")   `Parse.left<?>` whitespace-  @category Parser<any> fileEnd        <- StringParser.create("file_end")     `Parse.left<?>` whitespace-  @category Parser<any> nameTag        <- StringParser.create("name:")        `Parse.left<?>` whitespace-  @category Parser<any> descriptionTag <- StringParser.create("description:") `Parse.left<?>` whitespace-  @category Parser<any> aWordTag       <- StringParser.create("a_word:")      `Parse.left<?>` whitespace+  @category Parser<any> fileStart      <- StringParser.create("file_start")   `Parse.left` whitespace+  @category Parser<any> fileEnd        <- StringParser.create("file_end")     `Parse.left` whitespace+  @category Parser<any> nameTag        <- StringParser.create("name:")        `Parse.left` whitespace+  @category Parser<any> descriptionTag <- StringParser.create("description:") `Parse.left` whitespace+  @category Parser<any> aWordTag       <- StringParser.create("a_word:")      `Parse.left` whitespace    run (contextOld) {     ParseContext<any> context <- contextOld-    context                              <- context.run<?>(fileStart)-    context                              <- context.run<?>(nameTag)-    context, ErrorOr<String> name        <- context.runAndGet<?>(sentenceOrToken)-    context                              <- context.run<?>(descriptionTag)-    context, ErrorOr<String> description <- context.runAndGet<?>(sentenceOrToken)-    context                              <- context.run<?>(aWordTag)-    context, ErrorOr<Bool> boolean       <- context.runAndGet<?>(acronymOrAardvark)-    context                              <- context.run<?>(fileEnd)+    context                              <- context.run(fileStart)+    context                              <- context.run(nameTag)+    context, ErrorOr<String> name        <- context.runAndGet(sentenceOrToken)+    context                              <- context.run(descriptionTag)+    context, ErrorOr<String> description <- context.runAndGet(sentenceOrToken)+    context                              <- context.run(aWordTag)+    context, ErrorOr<Bool> boolean       <- context.runAndGet(acronymOrAardvark)+    context                              <- context.run(fileEnd)      if (context.hasAnyError()) {       return context.convertError()     } else {-      return context.setValue<?>(-        ErrorOr:value<?>(TestData.create(name.getValue(),+      return context.setValue(+        ErrorOr:value(TestData.create(name.getValue(),                                          description.getValue(),                                          boolean.getValue())))     }
lib/container/helpers.0rp view
@@ -29,7 +29,7 @@   //   // Example:   //-  //   Bool lt <- x `KeyValueH:lessThan<?,?>` y+  //   Bool lt <- x `KeyValueH:lessThan` y   @category lessThan<#k,#v>     #k defines LessThan<#k>     #v defines LessThan<#v>@@ -63,7 +63,7 @@   //   // Example:   //-  //   Bool eq <- x `KeyValueH:equals<?,?>` y+  //   Bool eq <- x `KeyValueH:equals` y   @category equals<#k,#v>     #k defines Equals<#k>     #v defines Equals<#v>
lib/container/list.0rp view
@@ -55,6 +55,10 @@ }  // Node in a doubly-linked list.+//+// Notes:+// - This list is weak in the reverse direction. In other words, prev only+//   exists if there is another non-weak reference to it. concrete LinkedNode<#x> {   defines NewNode<#x>   // Duplication happens only in the forward direction.@@ -93,6 +97,9 @@    // Create a new builder.   @type new () -> (#self)++  // Append all of the elements from the Order.+  @value appendAll (optional Order<#x>) -> (#self)    // Build the list.   //
lib/container/src/Extension_Vector.cpp view
@@ -41,31 +41,31 @@ BoxedValue CreateValue_Vector(S<const Type_Vector> parent, VectorType values);  struct ExtCategory_Vector : public Category_Vector {-  ReturnTuple Call_copyFrom(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_copyFrom(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector:copyFrom")-    const S<const TypeInstance> Param_y = params.At(0);-    const BoxedValue& Var_arg1 = (args.At(0));+    const S<const TypeInstance> Param_y = params_args.GetParam(0);+    const BoxedValue& Var_arg1 = (params_args.GetArg(0));     VectorType values;-    const PrimInt size = TypeValue::Call(Var_arg1, Function_Container_size, ParamTuple(), ArgTuple()).Only().AsInt();+    const PrimInt size = TypeValue::Call(Var_arg1, Function_Container_size, PassParamsArgs()).At(0).AsInt();     for (int i = 0; i < size; ++i) {-      values.push_back(TypeValue::Call(Var_arg1, Function_ReadAt_readAt, ParamTuple(), ArgTuple(Box_Int(i))).Only());+      values.push_back(TypeValue::Call(Var_arg1, Function_ReadAt_readAt, PassParamsArgs(Box_Int(i))).At(0));     }     return ReturnTuple(CreateValue_Vector(CreateType_Vector(Params<1>::Type(Param_y)), std::move(values)));   } -  ReturnTuple Call_create(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_create(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector:create")-    const S<const TypeInstance> Param_y = params.At(0);+    const S<const TypeInstance> Param_y = params_args.GetParam(0);     return ReturnTuple(CreateValue_Vector(CreateType_Vector(Params<1>::Type(Param_y)), VectorType()));   } -  ReturnTuple Call_createSize(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_createSize(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector:createSize")-    const S<const TypeInstance> Param_y = params.At(0);-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const S<const TypeInstance> Param_y = params_args.GetParam(0);+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     VectorType values;     for (int i = 0; i < Var_arg1; ++i) {-      values.push_back(TypeInstance::Call(Param_y, Function_Default_default, ParamTuple(), ArgTuple()).Only());+      values.push_back(TypeInstance::Call(Param_y, Function_Default_default, PassParamsArgs()).At(0));     }     return ReturnTuple(CreateValue_Vector(CreateType_Vector(Params<1>::Type(Param_y)), std::move(values)));   }@@ -82,9 +82,7 @@    std::string CategoryName() const final { return "VectorOrder"; } -  ReturnTuple Dispatch(const ValueFunction& label,-                       const ParamTuple& params,-                       const ValueTuple& args) final {+  ReturnTuple Dispatch(const ValueFunction& label, const ParamsArgs& params_args) final {     if (&label == &Function_Order_next) {       TRACE_FUNCTION("VectorOrder.next")       if (index_+1 >= values_.size()) {@@ -101,7 +99,7 @@       }       return ReturnTuple(values_[index_]);     }-    return TypeValue::Dispatch(label, params, args);+    return TypeValue::Dispatch(label, params_args);   }   private:@@ -114,14 +112,14 @@   inline ExtValue_Vector(S<const Type_Vector> p, VectorType v)     : Value_Vector(std::move(p)), values(std::move(v)) {} -  ReturnTuple Call_append(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_append(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.append")-    const BoxedValue& Var_arg1 = (args.At(0));+    const BoxedValue& Var_arg1 = (params_args.GetArg(0));     values.push_back(Var_arg1);     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_defaultOrder(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_defaultOrder(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.defaultOrder")     if (values.empty()) {       return ReturnTuple(Var_empty);@@ -130,12 +128,12 @@     }   } -  ReturnTuple Call_duplicate(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_duplicate(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.duplicate")     return ReturnTuple(BoxedValue::New<ExtValue_Vector>(parent, values));   } -  ReturnTuple Call_pop(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_pop(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.pop")     if (values.empty()) {       BUILTIN_FAIL(Box_String(PrimString_FromLiteral("no elements left to pop")))@@ -145,31 +143,31 @@     return ReturnTuple(value);   } -  ReturnTuple Call_push(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_push(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.push")-    const BoxedValue& Var_arg1 = (args.At(0));+    const BoxedValue& Var_arg1 = (params_args.GetArg(0));     values.push_back(Var_arg1);     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_readAt(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_readAt(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.readAt")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0 || Var_arg1 >= values.size()) {       FAIL() << "index " << Var_arg1 << " is out of bounds";     }     return ReturnTuple(values[Var_arg1]);   } -  ReturnTuple Call_size(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_size(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.size")     return ReturnTuple(Box_Int(values.size()));   } -  ReturnTuple Call_writeAt(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_writeAt(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Vector.writeAt")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();-    const BoxedValue& Var_arg2 = (args.At(1));+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();+    const BoxedValue& Var_arg2 = (params_args.GetArg(1));     if (Var_arg1 < 0 || Var_arg1 >= values.size()) {       FAIL() << "index " << Var_arg1 << " is out of bounds";     }
lib/container/src/auto-tree.0rx view
@@ -304,7 +304,7 @@   }    get () {-    return TreeKeyValue:create<?,?>(node.getKey(),node.getValue())+    return TreeKeyValue:create(node.getKey(),node.getValue())   } } @@ -353,6 +353,6 @@   }    get () {-    return TreeKeyValue:create<?,?>(node.getKey(),node.getValue())+    return TreeKeyValue:create(node.getKey(),node.getValue())   } }
lib/container/src/list.0rx view
@@ -16,9 +16,9 @@  // Author: Kevin P. Barry [ta0kira@gmail.com] -define LinkedNode {+define LinkedNode { $FlatCleanup[next]$   @value #x value-  @value optional #self prev+  @value weak #self prev   @value optional #self next    newNode (value) {@@ -43,43 +43,35 @@   }    prev () {-    return prev+    return strong(prev)   }    duplicate () {     $Hidden[prev,next,value]$-    ListBuilder<#x,#self> builder <- #self.builder()-    traverse (self -> #x value2) {-      \ builder.append(value2)-    }-    scoped {-      optional #self head, _ <- builder.build()-    } in return require(head)+    return require(builder().appendAll(self).build(){0})   }    setNext (next2) (old) {     old <- next-    $Hidden[old]$-    if (present(next)) {-      \ require(next).setPrevBase(empty)+    if (present(old)) {+      \ require(old).setPrevBase(empty)     }     next <- next2-    if (present(next)) {-      \ require(next).setPrev(empty)-      \ require(next).setPrevBase(self)+    if (present(next2)) {+      \ require(next2).setPrev(empty)+      \ require(next2).setPrevBase(self)     }   }    setPrev (prev2) (old) {-    old <- prev-    $Hidden[old]$-    if (present(prev)) {-      \ require(prev).setNextBase(empty)+    old <- strong(prev)+    if (present(old)) {+      \ require(old).setNextBase(empty)     }     prev <- prev2-    if (present(prev)) {-      \ require(prev).setNext(empty)-      \ require(prev).setNextBase(self)+    if (present(prev2)) {+      \ require(prev2).setNext(empty)+      \ require(prev2).setNextBase(self)     }   } @@ -94,7 +86,7 @@   } } -define ForwardNode {+define ForwardNode { $FlatCleanup[next]$   @value #x value   @value optional #self next @@ -121,13 +113,7 @@    duplicate () {     $Hidden[next,value]$-    ListBuilder<#x,#self> builder <- #self.builder()-    traverse (self -> #x value2) {-      \ builder.append(value2)-    }-    scoped {-      optional #self head, _ <- builder.build()-    } in return require(head)+    return require(builder().appendAll(self).build(){0})   }    setNext (next2) (old) {@@ -152,6 +138,13 @@       \ require(tail).setNext(node)     }     tail <- node+    return self+  }++  appendAll (values) {+    traverse (values -> #x value) {+      \ append(value)+    }     return self   } 
lib/container/src/search-tree.0rx view
@@ -46,19 +46,19 @@   }    defaultOrder () {-    return ForwardTreeOrder:create<?,?>(tree.getRoot())+    return ForwardTreeOrder:create(tree.getRoot())   }    reverseOrder () {-    return ReverseTreeOrder:create<?,?>(tree.getRoot())+    return ReverseTreeOrder:create(tree.getRoot())   }    getForward (k) {-    return ForwardTreeOrder:seek<?,?>(k,tree.getRoot())+    return ForwardTreeOrder:seek(k,tree.getRoot())   }    getReverse (k) {-    return ReverseTreeOrder:seek<?,?>(k,tree.getRoot())+    return ReverseTreeOrder:seek(k,tree.getRoot())   } } 
lib/container/src/tree-set.0rx view
@@ -36,6 +36,10 @@     return self   } +  append (k) {+    return add(k)+  }+   remove (k) {     \ tree.remove(k)     return self
lib/container/src/type-map.0rx view
@@ -28,7 +28,7 @@   }    set (k,v) {-    \ tree.set(k,GenericValue:create<?>(v))+    \ tree.set(k,GenericValue:create(v))     return self   } @@ -45,6 +45,17 @@     } else {       return empty     }+  }++  getAll (output) {+    traverse (tree.defaultOrder() -> KeyValue<any,GenericValue<any>> pair) {+      scoped {+        optional #x value <- pair.getValue().check<#x>()+      } in if (present(value)) {+        \ output.append(require(value))+      }+    }+    return output   } } 
lib/container/test/helpers.0rt view
@@ -21,41 +21,41 @@ }  unittest keyValueHLessThan {-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:lessThan<?,?>` KV.new(1,"a"),false)-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:lessThan<?,?>` KV.new(1,"b"),true)-  \ Testing.checkEquals<?>(KV.new(2,"a") `KeyValueH:lessThan<?,?>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(1,"b") `KeyValueH:lessThan<?,?>` KV.new(2,"a"),true)+  \ Testing.checkFalse(KV.new(1,"a") `KeyValueH:lessThan` KV.new(1,"a"))+  \ Testing.checkTrue(KV.new(1,"a") `KeyValueH:lessThan` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(2,"a") `KeyValueH:lessThan` KV.new(1,"b"))+  \ Testing.checkTrue(KV.new(1,"b") `KeyValueH:lessThan` KV.new(2,"a")) }  unittest keyValueHLessThanWith {-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(1,"a"),false)-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(2,"a") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(1,"b") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(2,"a"),true)+  \ Testing.checkFalse(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(1,"a"))+  \ Testing.checkFalse(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(2,"a") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"))+  \ Testing.checkTrue(KV.new(1,"b") `KeyValueH:lessThanWith<?,?,Int,AlwaysEqual>` KV.new(2,"a")) -  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(1,"a"),false)-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(1,"b"),true)-  \ Testing.checkEquals<?>(KV.new(2,"a") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(1,"b"),true)-  \ Testing.checkEquals<?>(KV.new(1,"b") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(2,"a"),false)+  \ Testing.checkFalse(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(1,"a"))+  \ Testing.checkTrue(KV.new(1,"a") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(1,"b"))+  \ Testing.checkTrue(KV.new(2,"a") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(1,"b") `KeyValueH:lessThanWith<?,?,AlwaysEqual,String>` KV.new(2,"a")) }  unittest keyValueHEquals {-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:equals<?,?>` KV.new(1,"a"),true)-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:equals<?,?>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(2,"a") `KeyValueH:equals<?,?>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(1,"b") `KeyValueH:equals<?,?>` KV.new(2,"a"),false)+  \ Testing.checkTrue(KV.new(1,"a") `KeyValueH:equals` KV.new(1,"a"))+  \ Testing.checkFalse(KV.new(1,"a") `KeyValueH:equals` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(2,"a") `KeyValueH:equals` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(1,"b") `KeyValueH:equals` KV.new(2,"a")) }  unittest keyValueHEqualsWith {-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(1,"a"),true)-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"),true)-  \ Testing.checkEquals<?>(KV.new(2,"a") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(1,"b") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(2,"a"),false)+  \ Testing.checkTrue(KV.new(1,"a") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(1,"a"))+  \ Testing.checkTrue(KV.new(1,"a") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(2,"a") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(1,"b") `KeyValueH:equalsWith<?,?,Int,AlwaysEqual>` KV.new(2,"a")) -  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(1,"a"),true)-  \ Testing.checkEquals<?>(KV.new(1,"a") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(2,"a") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(1,"b"),false)-  \ Testing.checkEquals<?>(KV.new(1,"b") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(2,"a"),false)+  \ Testing.checkTrue(KV.new(1,"a") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(1,"a"))+  \ Testing.checkFalse(KV.new(1,"a") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(2,"a") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(1,"b"))+  \ Testing.checkFalse(KV.new(1,"b") `KeyValueH:equalsWith<?,?,AlwaysEqual,String>` KV.new(2,"a")) }  unittest integrationTest {@@ -64,9 +64,9 @@   SearchTree<Int,String> tree2 <- SearchTree<Int,String>.new()       .set(1,"a").set(2,"b").set(3,"c").set(4,"d") -  \ Testing.checkEquals<?>(tree1.defaultOrder() `OrderH:equalsWith<?,KVEquals<Int,AlwaysEqual>>`    tree2.defaultOrder(),true)-  \ Testing.checkEquals<?>(tree1.defaultOrder() `OrderH:equalsWith<?,KVEquals<Int,String>>`         tree2.defaultOrder(),false)-  \ Testing.checkEquals<?>(tree1.defaultOrder() `OrderH:equalsWith<?,KVEquals<AlwaysEqual,String>>` tree2.defaultOrder(),false)+  \ Testing.checkTrue(tree1.defaultOrder() `OrderH:equalsWith<?,KVEquals<Int,AlwaysEqual>>`    tree2.defaultOrder())+  \ Testing.checkFalse(tree1.defaultOrder() `OrderH:equalsWith<?,KVEquals<Int,String>>`         tree2.defaultOrder())+  \ Testing.checkFalse(tree1.defaultOrder() `OrderH:equalsWith<?,KVEquals<AlwaysEqual,String>>` tree2.defaultOrder()) }  concrete KVEquals<#k,#v> {
lib/container/test/list.0rt view
@@ -40,15 +40,16 @@       .append(4)    traverse (expected.defaultOrder() -> Int value) {-    \ Testing.checkEquals<?>(require(head).get(),value)+    \ Testing.checkEquals(require(head).get(),value)   } update {     head <- require(head).next()   }-  \ Testing.checkEquals<?>(present(head),false)+  \ Testing.checkFalse(present(head)) }  unittest reverseTraverse {-  _, optional LinkedNode<Int> tail <- LinkedNode<Int>.builder()+  // NOTE: Since the list is weak in reverse, we need to store head.+  optional LinkedNode<Int> head, optional LinkedNode<Int> tail <- LinkedNode<Int>.builder()       .append(3)       .append(2)       .append(5)@@ -66,11 +67,11 @@       .append(3)    traverse (expected.defaultOrder() -> Int value) {-    \ Testing.checkEquals<?>(require(tail).get(),value)+    \ Testing.checkEquals(require(tail).get(),value)   } update {     tail <- require(tail).prev()   }-  \ Testing.checkEquals<?>(present(tail),false)+  \ Testing.checkFalse(present(tail)) }  unittest setNext {@@ -83,7 +84,7 @@       .append(4)       .build() -  optional LinkedNode<Int> after1  <- Helper.jumpBy<?>(3,head1)+  optional LinkedNode<Int> after1  <- Helper.jumpBy(3,head1)   optional LinkedNode<Int> before1 <- require(after1).prev()    optional LinkedNode<Int> head2, _ <- LinkedNode<Int>.builder()@@ -95,15 +96,15 @@       .append(14)       .build() -  optional LinkedNode<Int> after2  <- Helper.jumpBy<?>(3,head2)+  optional LinkedNode<Int> after2  <- Helper.jumpBy(3,head2)   optional LinkedNode<Int> before2 <- require(after2).prev() -  \ Testing.checkEquals<?>(require(require(before1).setNext(after2)).get(),1)+  \ Testing.checkEquals(require(require(before1).setNext(after2)).get(),1) -  \ Testing.checkEquals<?>(present(require(after1).prev()),false)-  \ Testing.checkEquals<?>(require(require(before1).next()).get(),11)-  \ Testing.checkEquals<?>(require(require(after2).prev()).get(),5)-  \ Testing.checkEquals<?>(present(require(before2).next()),false)+  \ Testing.checkFalse(present(require(after1).prev()))+  \ Testing.checkEquals(require(require(before1).next()).get(),11)+  \ Testing.checkEquals(require(require(after2).prev()).get(),5)+  \ Testing.checkFalse(present(require(before2).next())) }  unittest setPrev {@@ -116,7 +117,7 @@       .append(4)       .build() -  optional LinkedNode<Int> after1  <- Helper.jumpBy<?>(3,head1)+  optional LinkedNode<Int> after1  <- Helper.jumpBy(3,head1)   optional LinkedNode<Int> before1 <- require(after1).prev()    optional LinkedNode<Int> head2, _ <- LinkedNode<Int>.builder()@@ -128,15 +129,15 @@       .append(14)       .build() -  optional LinkedNode<Int> after2  <- Helper.jumpBy<?>(3,head2)+  optional LinkedNode<Int> after2  <- Helper.jumpBy(3,head2)   optional LinkedNode<Int> before2 <- require(after2).prev() -  \ Testing.checkEquals<?>(require(require(after1).setPrev(before2)).get(),5)+  \ Testing.checkEquals(require(require(after1).setPrev(before2)).get(),5) -  \ Testing.checkEquals<?>(require(require(after1).prev()).get(),15)-  \ Testing.checkEquals<?>(present(require(before1).next()),false)-  \ Testing.checkEquals<?>(present(require(after2).prev()),false)-  \ Testing.checkEquals<?>(require(require(before2).next()).get(),1)+  \ Testing.checkEquals(require(require(after1).prev()).get(),15)+  \ Testing.checkFalse(present(require(before1).next()))+  \ Testing.checkFalse(present(require(after2).prev()))+  \ Testing.checkEquals(require(require(before2).next()).get(),1) }  unittest setNextSame {@@ -149,13 +150,13 @@       .append(4)       .build() -  optional LinkedNode<Int> after  <- Helper.jumpBy<?>(3,head)+  optional LinkedNode<Int> after  <- Helper.jumpBy(3,head)   optional LinkedNode<Int> before <- require(after).prev()    \ require(before).setNext(after) -  \ Testing.checkEquals<?>(require(require(after).prev()).get(),5)-  \ Testing.checkEquals<?>(require(require(before).next()).get(),1)+  \ Testing.checkEquals(require(require(after).prev()).get(),5)+  \ Testing.checkEquals(require(require(before).next()).get(),1) }  unittest setPrevSame {@@ -168,13 +169,13 @@       .append(4)       .build() -  optional LinkedNode<Int> after  <- Helper.jumpBy<?>(3,head)+  optional LinkedNode<Int> after  <- Helper.jumpBy(3,head)   optional LinkedNode<Int> before <- require(after).prev()    \ require(after).setPrev(before) -  \ Testing.checkEquals<?>(require(require(after).prev()).get(),5)-  \ Testing.checkEquals<?>(require(require(before).next()).get(),1)+  \ Testing.checkEquals(require(require(after).prev()).get(),5)+  \ Testing.checkEquals(require(require(before).next()).get(),1) }  unittest setNextSelf {@@ -187,14 +188,14 @@       .append(4)       .build() -  optional LinkedNode<Int> after  <- Helper.jumpBy<?>(3,head)+  optional LinkedNode<Int> after  <- Helper.jumpBy(3,head)   optional LinkedNode<Int> before <- require(after).prev()    \ require(before).setNext(before) -  \ Testing.checkEquals<?>(present(require(after).prev()),false)-  \ Testing.checkEquals<?>(require(require(before).prev()).get(),5)-  \ Testing.checkEquals<?>(require(require(before).next()).get(),5)+  \ Testing.checkFalse(present(require(after).prev()))+  \ Testing.checkEquals(require(require(before).prev()).get(),5)+  \ Testing.checkEquals(require(require(before).next()).get(),5) }  unittest setPrevSelf {@@ -207,14 +208,14 @@       .append(4)       .build() -  optional LinkedNode<Int> after  <- Helper.jumpBy<?>(3,head)+  optional LinkedNode<Int> after  <- Helper.jumpBy(3,head)   optional LinkedNode<Int> before <- require(after).prev()    \ require(after).setPrev(after) -  \ Testing.checkEquals<?>(present(require(before).next()),false)-  \ Testing.checkEquals<?>(require(require(after).prev()).get(),1)-  \ Testing.checkEquals<?>(require(require(after).next()).get(),1)+  \ Testing.checkFalse(present(require(before).next()))+  \ Testing.checkEquals(require(require(after).prev()).get(),1)+  \ Testing.checkEquals(require(require(after).next()).get(),1) }  unittest duplicate {@@ -236,17 +237,25 @@       .append(4)    optional LinkedNode<Int> head2 <- require(head).duplicate()-  \ require(Helper.jumpBy<?>(3,head)).set(7).setNext(empty)+  \ require(Helper.jumpBy(3,head)).set(7).setNext(empty)   $Hidden[head]$    traverse (expected.defaultOrder() -> Int value) {-    \ Testing.checkEquals<?>(require(head2).get(),value)+    \ Testing.checkEquals(require(head2).get(),value)   } update {     head2 <- require(head2).next()   }-  \ Testing.checkEquals<?>(present(head2),false)+  \ Testing.checkFalse(present(head2)) } +unittest hugeCleanup { $DisableCoverage$+  scoped {+    ListBuilder<Int,LinkedNode<Int>> builder <- LinkedNode<Int>.builder()+  } in traverse (Counter.zeroIndexed(1000000) -> _) {+    \ builder.append(0)+  }+}+ unittest forwardTraverseSingle {   optional ForwardNode<Int> head, _ <- ForwardNode<Int>.builder()       .append(3)@@ -266,11 +275,11 @@       .append(4)    traverse (expected.defaultOrder() -> Int value) {-    \ Testing.checkEquals<?>(require(head).get(),value)+    \ Testing.checkEquals(require(head).get(),value)   } update {     head <- require(head).next()   }-  \ Testing.checkEquals<?>(present(head),false)+  \ Testing.checkFalse(present(head)) }  unittest duplicateSingle {@@ -292,15 +301,23 @@       .append(4)    optional ForwardNode<Int> head2 <- require(head).duplicate()-  \ require(Helper.jumpBy<?>(3,head)).set(7).setNext(empty)+  \ require(Helper.jumpBy(3,head)).set(7).setNext(empty)   $Hidden[head]$    traverse (expected.defaultOrder() -> Int value) {-    \ Testing.checkEquals<?>(require(head2).get(),value)+    \ Testing.checkEquals(require(head2).get(),value)   } update {     head2 <- require(head2).next()   }-  \ Testing.checkEquals<?>(present(head2),false)+  \ Testing.checkFalse(present(head2))+}++unittest hugeCleanupSingle { $DisableCoverage$+  scoped {+    ListBuilder<Int,ForwardNode<Int>> builder <- ForwardNode<Int>.builder()+  } in traverse (Counter.zeroIndexed(1000000) -> _) {+    \ builder.append(0)+  } }  concrete Helper {
lib/container/test/search-tree.0rt view
@@ -20,16 +20,16 @@   success } -unittest integrationTest { $DisableCoverage$+unittest integrationTest {   ValidatedTree<Int,Int> tree <- ValidatedTree<Int,Int>.new()-  Int count <- 30+  Int count <- 33   $ReadOnly[count]$    // Insert values.   traverse (Counter.zeroIndexed(count) -> Int i) {     Int new <- ((i + 13) * 3547) % count     \ tree.set(new,i)-    \ Testing.checkEquals<?>(tree.size(),i+1)+    \ Testing.checkEquals(tree.size(),i+1)   }    // Check and remove values.@@ -55,7 +55,7 @@           .writeTo(SimpleOutput.error())     }     \ tree.remove(new)-    \ Testing.checkEquals<?>(tree.size(),count-i-1)+    \ Testing.checkEquals(tree.size(),count-i-1)   } } @@ -73,12 +73,12 @@   // Validate the traversal order.   Int index <- 0   traverse (tree.defaultOrder() -> KeyValue<Int,Int> entry) {-    \ Testing.checkEquals<?>(entry.getKey(),index)-    \ Testing.checkEquals<?>((entry.getValue()*hash)%max,entry.getKey())+    \ Testing.checkEquals(entry.getKey(),index)+    \ Testing.checkEquals((entry.getValue()*hash)%max,entry.getKey())     index <- index+1   } -  \ Testing.checkEquals<?>(index,max)+  \ Testing.checkEquals(index,max) }  unittest reverseOrder {@@ -96,11 +96,11 @@   Int index <- max   traverse (tree.reverseOrder() -> KeyValue<Int,Int> entry) {     index <- index-1-    \ Testing.checkEquals<?>(entry.getKey(),index)-    \ Testing.checkEquals<?>((entry.getValue()*hash)%max,entry.getKey())+    \ Testing.checkEquals(entry.getKey(),index)+    \ Testing.checkEquals((entry.getValue()*hash)%max,entry.getKey())   } -  \ Testing.checkEquals<?>(index,0)+  \ Testing.checkEquals(index,0) }  unittest getForward {@@ -118,11 +118,11 @@   traverse (Counter.zeroIndexed(max) -> Int i) {     Int index <- i     traverse (tree.getForward(index) -> KeyValue<Int,Int> entry) {-      \ Testing.checkEquals<?>(entry.getKey(),index)-      \ Testing.checkEquals<?>((entry.getValue()*hash)%max,entry.getKey())+      \ Testing.checkEquals(entry.getKey(),index)+      \ Testing.checkEquals((entry.getValue()*hash)%max,entry.getKey())       index <- index+1     }-    \ Testing.checkEquals<?>(index,max)+    \ Testing.checkEquals(index,max)   } } @@ -135,7 +135,7 @@   } in if (!present(start)) {     fail("Failed")   } else {-    \ Testing.checkEquals<?>(require(start).get().getKey(),5)+    \ Testing.checkEquals(require(start).get().getKey(),5)   }    scoped {@@ -160,11 +160,11 @@   traverse (Counter.zeroIndexed(max) -> Int i) {     Int index <- i     traverse (tree.getReverse(index) -> KeyValue<Int,Int> entry) {-      \ Testing.checkEquals<?>(entry.getKey(),index)-      \ Testing.checkEquals<?>((entry.getValue()*hash)%max,entry.getKey())+      \ Testing.checkEquals(entry.getKey(),index)+      \ Testing.checkEquals((entry.getValue()*hash)%max,entry.getKey())       index <- index-1     }-    \ Testing.checkEquals<?>(index,-1)+    \ Testing.checkEquals(index,-1)   } } @@ -177,7 +177,7 @@   } in if (!present(start)) {     fail("Failed")   } else {-    \ Testing.checkEquals<?>(require(start).get().getKey(),1)+    \ Testing.checkEquals(require(start).get().getKey(),1)   }    scoped {@@ -191,16 +191,23 @@   SearchTree<Int,Int> tree <- SearchTree<Int,Int>.new().set(1,1).set(2,2).set(3,3)    SearchTree<Int,Int> copy <- tree.duplicate()-  \ Testing.checkEquals<?>(copy.size(),3)-  \ Testing.checkOptional<?>(copy.get(1),1)-  \ Testing.checkOptional<?>(copy.get(2),2)-  \ Testing.checkOptional<?>(copy.get(3),3)+  \ Testing.checkEquals(copy.size(),3)+  \ Testing.checkOptional(copy.get(1),1)+  \ Testing.checkOptional(copy.get(2),2)+  \ Testing.checkOptional(copy.get(3),3)    \ copy.remove(2)   $Hidden[copy]$ -  \ Testing.checkEquals<?>(tree.size(),3)-  \ Testing.checkOptional<?>(tree.get(1),1)-  \ Testing.checkOptional<?>(tree.get(2),2)-  \ Testing.checkOptional<?>(tree.get(3),3)+  \ Testing.checkEquals(tree.size(),3)+  \ Testing.checkOptional(tree.get(1),1)+  \ Testing.checkOptional(tree.get(2),2)+  \ Testing.checkOptional(tree.get(3),3)+}++unittest duplicateEmpty {+  SearchTree<Int,Int> tree <- SearchTree<Int,Int>.new()++  SearchTree<Int,Int> copy <- tree.duplicate()+  \ Testing.checkEquals(copy.size(),0) }
lib/container/test/sorting.0rt view
@@ -33,8 +33,8 @@     \ expected.append(i/3)   } -  \ Sorting:sort<?>(original)-  \ Testing.checkEquals<?>(original,expected)+  \ Sorting:sort(original)+  \ Testing.checkEquals(original,expected) }  unittest sortWith { $DisableCoverage$@@ -50,15 +50,15 @@   }    \ Sorting:sortWith<?,Reversed<Int>>(original)-  \ Testing.checkEquals<?>(original,expected)+  \ Testing.checkEquals(original,expected) }  unittest sortEmpty {   TestSequence original <- TestSequence.create()   TestSequence expected <- TestSequence.create() -  \ Sorting:sort<?>(original)-  \ Testing.checkEquals<?>(original,expected)+  \ Sorting:sort(original)+  \ Testing.checkEquals(original,expected) }  unittest reverseEvenSize {@@ -75,8 +75,8 @@     \ original.append(i)   } -  \ Sorting:reverse<?>(original)-  \ Testing.checkEquals<?>(original,expected)+  \ Sorting:reverse(original)+  \ Testing.checkEquals(original,expected) }  unittest reverseOddSize { $DisableCoverage$@@ -93,16 +93,16 @@     \ original.append(i)   } -  \ Sorting:reverse<?>(original)-  \ Testing.checkEquals<?>(original,expected)+  \ Sorting:reverse(original)+  \ Testing.checkEquals(original,expected) }  unittest reverseEmpty {   TestSequence original <- TestSequence.create()   TestSequence expected <- TestSequence.create() -  \ Sorting:reverse<?>(original)-  \ Testing.checkEquals<?>(original,expected)+  \ Sorting:reverse(original)+  \ Testing.checkEquals(original,expected) }  unittest sortList {@@ -117,16 +117,14 @@     \ expected.append(i/3)   } -  scoped {-    optional LinkedNode<Int> head, _ <- builder.build()-  } in optional LinkedNode<Int> actual <- Sorting:sortList<?,?>(head)+  optional LinkedNode<Int> actual <- Sorting:sortList(builder.build(){0})    traverse (expected.defaultOrder() -> Int n) {-    \ Testing.checkEquals<?>(require(actual).get(),n)+    \ Testing.checkEquals(require(actual).get(),n)   } update {     actual <- require(actual).next()   }-  \ Testing.checkEquals<?>(present(actual),false)+  \ Testing.checkFalse(present(actual)) }  unittest sortListSingle { $DisableCoverage$@@ -141,16 +139,14 @@     \ expected.append(i/3)   } -  scoped {-    optional ForwardNode<Int> head, _ <- builder.build()-  } in optional ForwardNode<Int> actual <- Sorting:sortList<?,?>(head)+  optional ForwardNode<Int> actual <- Sorting:sortList(builder.build(){0})    traverse (expected.defaultOrder() -> Int n) {-    \ Testing.checkEquals<?>(require(actual).get(),n)+    \ Testing.checkEquals(require(actual).get(),n)   } update {     actual <- require(actual).next()   }-  \ Testing.checkEquals<?>(present(actual),false)+  \ Testing.checkFalse(present(actual)) }  unittest sortListEmpty {@@ -169,16 +165,14 @@     \ expected.append(i/3)   } -  scoped {-    optional LinkedNode<Int> head, _ <- builder.build()-  } in optional LinkedNode<Int> actual <- Sorting:sortList<?,?>(head)+  optional LinkedNode<Int> actual <- Sorting:sortList(builder.build(){0})    traverse (expected.defaultOrder() -> Int n) {-    \ Testing.checkEquals<?>(require(actual).get(),n)+    \ Testing.checkEquals(require(actual).get(),n)   } update {     actual <- require(actual).next()   }-  \ Testing.checkEquals<?>(present(actual),false)+  \ Testing.checkFalse(present(actual)) }  unittest sortListWith { $DisableCoverage$@@ -193,16 +187,14 @@     \ expected.append(i/3)   } -  scoped {-    optional LinkedNode<Int> head, _ <- builder.build()-  } in optional LinkedNode<Int> actual <- Sorting:sortListWith<?,?,Reversed<Int>>(head)+  optional LinkedNode<Int> actual <- Sorting:sortListWith<?,?,Reversed<Int>>(builder.build(){0})    traverse (expected.defaultOrder() -> Int n) {-    \ Testing.checkEquals<?>(require(actual).get(),n)+    \ Testing.checkEquals(require(actual).get(),n)   } update {     actual <- require(actual).next()   }-  \ Testing.checkEquals<?>(present(actual),false)+  \ Testing.checkFalse(present(actual)) }  unittest reverseList {@@ -219,16 +211,14 @@     \ builder.append(i)   } -  scoped {-    optional LinkedNode<Int> head, _ <- builder.build()-  } in optional LinkedNode<Int> reversed <- Sorting:reverseList<?,?>(head)+  optional LinkedNode<Int> reversed <- Sorting:reverseList(builder.build(){0})    traverse (expected.defaultOrder() -> Int value) {-    \ Testing.checkEquals<?>(require(reversed).get(),value)+    \ Testing.checkEquals(require(reversed).get(),value)   } update {     reversed <- require(reversed).next()   }-  \ Testing.checkEquals<?>(present(reversed),false)+  \ Testing.checkFalse(present(reversed)) }  unittest reverseListSingle { $DisableCoverage$@@ -245,16 +235,14 @@     \ builder.append(i)   } -  scoped {-    optional ForwardNode<Int> head, _ <- builder.build()-  } in optional ForwardNode<Int> reversed <- Sorting:reverseList<?,?>(head)+  optional ForwardNode<Int> reversed <- Sorting:reverseList(builder.build(){0})    traverse (expected.defaultOrder() -> Int value) {-    \ Testing.checkEquals<?>(require(reversed).get(),value)+    \ Testing.checkEquals(require(reversed).get(),value)   } update {     reversed <- require(reversed).next()   }-  \ Testing.checkEquals<?>(present(reversed),false)+  \ Testing.checkFalse(present(reversed)) }  unittest reverseListEmpty {@@ -306,6 +294,6 @@   }    equals (x,y) {-    return x `ReadAtH:equals<?>` y+    return x `ReadAtH:equals` y   } }
lib/container/test/tree-set.0rt view
@@ -29,7 +29,7 @@   // Populate the set in a pseudo-random order.   traverse (Counter.zeroIndexed(max) -> Int i) {     \ set.add((i*hash)%max)-    \ Testing.checkEquals<?>(set.size(),i+1)+    \ Testing.checkEquals(set.size(),i+1)   }    // Remove only the odd elements.@@ -38,12 +38,12 @@       // Remove it twice to ensure idempotence.       \ set.remove(i).remove(i)     }-    \ Testing.checkEquals<?>(set.size(),max-(i+1)/2)+    \ Testing.checkEquals(set.size(),max-(i+1)/2)   }    // Validate set membership.   traverse (Counter.zeroIndexed(max) -> Int i) {-    \ Testing.checkEquals<?>(set.member(i),i%2 == 0)+    \ Testing.checkEquals(set.member(i),i%2 == 0)   } } @@ -61,11 +61,11 @@   // Validate the traversal order.   Int index <- 0   traverse (set.defaultOrder() -> Int entry) {-    \ Testing.checkEquals<?>(entry,index)+    \ Testing.checkEquals(entry,index)     index <- index+1   } -  \ Testing.checkEquals<?>(index,max)+  \ Testing.checkEquals(index,max) }  unittest reverseOrder {@@ -83,10 +83,10 @@   Int index <- max   traverse (set.reverseOrder() -> Int entry) {     index <- index-1-    \ Testing.checkEquals<?>(entry,index)+    \ Testing.checkEquals(entry,index)   } -  \ Testing.checkEquals<?>(index,0)+  \ Testing.checkEquals(index,0) }  unittest getForward {@@ -104,10 +104,10 @@   traverse (Counter.zeroIndexed(max) -> Int i) {     Int index <- i     traverse (set.getForward(index) -> Int entry) {-      \ Testing.checkEquals<?>(entry,index)+      \ Testing.checkEquals(entry,index)       index <- index+1     }-    \ Testing.checkEquals<?>(index,max)+    \ Testing.checkEquals(index,max)   } } @@ -120,7 +120,7 @@   } in if (!present(start)) {     fail("Failed")   } else {-    \ Testing.checkEquals<?>(require(start).get(),5)+    \ Testing.checkEquals(require(start).get(),5)   }    scoped {@@ -145,10 +145,10 @@   traverse (Counter.zeroIndexed(max) -> Int i) {     Int index <- i     traverse (set.getReverse(index) -> Int entry) {-      \ Testing.checkEquals<?>(entry,index)+      \ Testing.checkEquals(entry,index)       index <- index-1     }-    \ Testing.checkEquals<?>(index,-1)+    \ Testing.checkEquals(index,-1)   } } @@ -161,7 +161,7 @@   } in if (!present(start)) {     fail("Failed")   } else {-    \ Testing.checkEquals<?>(require(start).get(),1)+    \ Testing.checkEquals(require(start).get(),1)   }    scoped {@@ -175,12 +175,12 @@   TreeSet<Int> set <- TreeSet<Int>.new().add(1).add(2)    TreeSet<Int> copy <- set.duplicate()-  \ Testing.checkEquals<?>(copy.size(),2)-  \ Testing.checkEquals<?>(copy.member(1),true)-  \ Testing.checkEquals<?>(copy.member(1),true)+  \ Testing.checkEquals(copy.size(),2)+  \ Testing.checkTrue(copy.member(1))+  \ Testing.checkTrue(copy.member(1))    \ copy.remove(2)-  \ Testing.checkEquals<?>(copy.size(),1)-  \ Testing.checkEquals<?>(copy.member(1),true)-  \ Testing.checkEquals<?>(set.member(2),true)+  \ Testing.checkEquals(copy.size(),1)+  \ Testing.checkTrue(copy.member(1))+  \ Testing.checkTrue(set.member(2)) }
lib/container/test/type-map.0rt view
@@ -27,21 +27,21 @@   TypeKey<String> keyString <- TypeKey<String>.new()   TypeKey<Value>  keyValue  <- TypeKey<Value>.new() -  \ Testing.checkOptional<?>(tree.get<?>(keyInt),   empty)-  \ Testing.checkOptional<?>(tree.get<?>(keyString),empty)-  \ Testing.checkOptional<?>(tree.get<?>(keyValue), empty)+  \ Testing.checkOptional(tree.get(keyInt),   empty)+  \ Testing.checkOptional(tree.get(keyString),empty)+  \ Testing.checkOptional(tree.get(keyValue), empty) -  \ tree.set<?>(keyInt,1)-  \ tree.set<?>(keyString,"a")-  \ tree.set<?>(keyValue,Value.new())+  \ tree.set(keyInt,1)+  \ tree.set(keyString,"a")+  \ tree.set(keyValue,Value.new()) -  \ Testing.checkOptional<?>(tree.get<?>(keyInt),   1)-  \ Testing.checkOptional<?>(tree.get<?>(keyString),"a")-  \ Testing.checkOptional<?>(tree.get<?>(keyValue), Value.new())+  \ Testing.checkOptional(tree.get(keyInt),   1)+  \ Testing.checkOptional(tree.get(keyString),"a")+  \ Testing.checkOptional(tree.get(keyValue), Value.new())    \ tree.remove(keyString) -  \ Testing.checkOptional<?>(tree.get<?>(keyString),empty)+  \ Testing.checkOptional(tree.get(keyString),empty) }  unittest wrongReturnType {@@ -51,28 +51,51 @@    // Added as Formatted, which means it cannot be retrieved as String later.   \ tree.set<Formatted>(keyString,"a")-  \ Testing.checkOptional<?>(tree.get<String>(keyString),empty)+  \ Testing.checkOptional(tree.get<String>(keyString),empty)    \ tree.set<String>(keyString,"a")-  \ Testing.checkOptional<?>(tree.get<String>(keyString),"a")+  \ Testing.checkOptional(tree.get<String>(keyString),"a") }  unittest duplicate {   TypeKey<Int>    keyInt    <- TypeKey<Int>.new()   TypeKey<String> keyString <- TypeKey<String>.new() -  TypeMap tree <- TypeMap.new().set<?>(keyInt,1).set<?>(keyString,"a")+  TypeMap tree <- TypeMap.new().set(keyInt,1).set(keyString,"a")    TypeMap copy <- tree.duplicate()-  \ Testing.checkOptional<?>(copy.get<?>(keyInt),1)-  \ Testing.checkOptional<?>(copy.get<?>(keyString),"a")+  \ Testing.checkOptional(copy.get(keyInt),1)+  \ Testing.checkOptional(copy.get(keyString),"a")    \ copy.remove(keyString)-  \ Testing.checkOptional<?>(copy.get<?>(keyInt),1)-  \ Testing.checkOptional<?>(copy.get<?>(keyString),empty)-  \ Testing.checkOptional<?>(tree.get<?>(keyString),"a")+  \ Testing.checkOptional(copy.get(keyInt),1)+  \ Testing.checkOptional(copy.get(keyString),empty)+  \ Testing.checkOptional(tree.get(keyString),"a") } +unittest getValues {+  TypeMap tree <- TypeMap.new()+      .set(TypeKey<String>.new(),"one")+      .set(TypeKey<Int>.new(),2)+      .set(TypeKey<String>.new(),"two")+      .set(TypeKey<Int>.new(),1)++  [Container&SetReader<String>] actual <- tree.getAll(TreeSet<String>.new())++  \ Testing.checkEquals(actual.size(),2)+  \ Testing.checkTrue(actual.member("one"))+  \ Testing.checkTrue(actual.member("two"))+}++unittest keyEquals {+  TypeKey<Int>    key1 <- TypeKey<Int>.new()+  TypeKey<Int>    key2 <- TypeKey<Int>.new()+  TypeKey<String> key3 <- TypeKey<String>.new()+  \ Testing.checkEquals<TypeKey<Int>>(key1,key1)+  \ Testing.checkFalse(key1 `TypeKey<any>.equals` key2)+  \ Testing.checkFalse(key1 `TypeKey<any>.equals` key3)+}+ concrete Value {   refines Formatted   defines Equals<Value>@@ -92,4 +115,14 @@   equals (_,_) {     return true   }+}+++testcase "TypeKey formatted" {+  crash+  require "TypeKey<Int>\{[0-9]+\}"+}++unittest test {+  fail(TypeKey<Int>.new()) }
lib/container/test/vector.0rt view
@@ -22,12 +22,12 @@  unittest createSize {   Vector<Int> values <- Vector:createSize<Int>(10)-  \ Testing.checkEquals<?>(values.size(),10)+  \ Testing.checkEquals(values.size(),10)    scoped {     Int i <- 0   } in while (i < values.size()) {-    \ Testing.checkEquals<?>(values.readAt(i),Int.default())+    \ Testing.checkEquals(values.readAt(i),Int.default())   } update {     i <- i+1   }@@ -35,13 +35,13 @@  unittest copyFrom {   String original <- "abcde"-  Vector<Char> values <- Vector:copyFrom<?>(original)-  \ Testing.checkEquals<?>(values.size(),original.size())+  Vector<Char> values <- Vector:copyFrom(original)+  \ Testing.checkEquals(values.size(),original.size())    scoped {     Int i <- 0   } in while (i < original.size()) {-    \ Testing.checkEquals<?>(values.readAt(i),original.readAt(i))+    \ Testing.checkEquals(values.readAt(i),original.readAt(i))   } update {     i <- i+1   }@@ -54,16 +54,16 @@     Int i <- 0   } in while (i < 10) {     \ values.append(i)-    \ Testing.checkEquals<?>(values.size(),i+1)+    \ Testing.checkEquals(values.size(),i+1)   } update {     i <- i+1   }-  \ Testing.checkEquals<?>(values.size(),10)+  \ Testing.checkEquals(values.size(),10)    scoped {     Int i <- 0   } in while (i < values.size()) {-    \ Testing.checkEquals<?>(values.readAt(i),i)+    \ Testing.checkEquals(values.readAt(i),i)   } update {     i <- i+1   }@@ -76,21 +76,21 @@     Int i <- 0   } in while (i < 10) {     \ values.push(i)-    \ Testing.checkEquals<?>(values.size(),i+1)+    \ Testing.checkEquals(values.size(),i+1)   } update {     i <- i+1   }-  \ Testing.checkEquals<?>(values.size(),10)+  \ Testing.checkEquals(values.size(),10)    scoped {     Int i <- 0   } in while (i < 10) {-    \ Testing.checkEquals<?>(values.pop(),10-i-1)-    \ Testing.checkEquals<?>(values.size(),10-i-1)+    \ Testing.checkEquals(values.pop(),10-i-1)+    \ Testing.checkEquals(values.size(),10-i-1)   } update {     i <- i+1   }-  \ Testing.checkEquals<?>(values.size(),0)+  \ Testing.checkEquals(values.size(),0) }  unittest writeAt {@@ -107,7 +107,7 @@   scoped {     Int i <- 0   } in while (i < values.size()) {-    \ Testing.checkEquals<?>(values.readAt(i),2*i)+    \ Testing.checkEquals(values.readAt(i),2*i)   } update {     i <- i+1   }@@ -124,25 +124,25 @@   \ vector.push(1)    traverse (vector.defaultOrder() -> Int i) {-    \ Testing.checkEquals<?>(i,vector.readAt(index))+    \ Testing.checkEquals(i,vector.readAt(index))     index <- index+1   } -  \ Testing.checkEquals<?>(index,6)+  \ Testing.checkEquals(index,6) }  unittest duplicate {   Vector<Int> vector <- Vector:create<Int>().push(1).push(2)    Vector<Int> copy <- vector.duplicate()-  \ Testing.checkEquals<?>(copy.size(),2)-  \ Testing.checkEquals<?>(copy.readAt(0),1)-  \ Testing.checkEquals<?>(copy.readAt(1),2)+  \ Testing.checkEquals(copy.size(),2)+  \ Testing.checkEquals(copy.readAt(0),1)+  \ Testing.checkEquals(copy.readAt(1),2)    \ copy.pop()-  \ Testing.checkEquals<?>(copy.size(),1)-  \ Testing.checkEquals<?>(copy.readAt(0),1)-  \ Testing.checkEquals<?>(vector.readAt(1),2)+  \ Testing.checkEquals(copy.size(),1)+  \ Testing.checkEquals(copy.readAt(0),1)+  \ Testing.checkEquals(vector.readAt(1),2) }  @@ -154,13 +154,13 @@   Vector<Type> values <- Vector:createSize<Type>(10)   \ values.readAt(3).set(7) -  \ Testing.checkEquals<?>(values.readAt(3),Type.create(7))+  \ Testing.checkEquals(values.readAt(3),Type.create(7))    scoped {     Int i <- 0   } in while (i < values.size()) {     if (i != 3) {-      \ Testing.checkEquals<?>(values.readAt(i),Type.create(0))+      \ Testing.checkEquals(values.readAt(i),Type.create(0))     }   } update {     i <- i+1
lib/container/tree-set.0rp view
@@ -17,6 +17,7 @@ // Author: Kevin P. Barry [ta0kira@gmail.com]  concrete TreeSet<#k> {+  refines Append<#k>   refines Container   refines DefaultOrder<#k>   refines Duplicate
lib/container/type-map.0rp view
@@ -44,6 +44,11 @@   //   example, if the value is actually a String but it was added as Formatted   //   (a parent of String), then the value cannot be retrieved as a String.   @value get<#x> (TypeKey<#x>) -> (optional #x)++  // Get all values of type #x.+  @value getAll<#c,#x>+    #c requires Append<#x>+  (#c) -> (#c) }  // A typed key for use with TypeMap.
lib/file/src/Extension_RawFileReader.cpp view
@@ -25,7 +25,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_RawFileReader(S<const Type_RawFileReader> parent, const ValueTuple& args);+BoxedValue CreateValue_RawFileReader(S<const Type_RawFileReader> parent, const ParamsArgs& params_args);  struct ExtCategory_RawFileReader : public Category_RawFileReader { };@@ -33,19 +33,19 @@ struct ExtType_RawFileReader : public Type_RawFileReader {   inline ExtType_RawFileReader(Category_RawFileReader& p, Params<0>::Type params) : Type_RawFileReader(p, params) {} -  ReturnTuple Call_open(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_open(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("RawFileReader.open")-    return ReturnTuple(CreateValue_RawFileReader(PARAM_SELF, args));+    return ReturnTuple(CreateValue_RawFileReader(PARAM_SELF, params_args));   } };  struct ExtValue_RawFileReader : public Value_RawFileReader {-  inline ExtValue_RawFileReader(S<const Type_RawFileReader> p, const ValueTuple& args)+  inline ExtValue_RawFileReader(S<const Type_RawFileReader> p, const ParamsArgs& params_args)     : Value_RawFileReader(std::move(p)),-      filename(args.At(0).AsString()),+      filename(params_args.GetArg(0).AsString()),       file(new std::ifstream(filename, std::ios::in | std::ios::binary)) {} -  ReturnTuple Call_freeResource(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_freeResource(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RawFileReader.freeResource")     std::lock_guard<std::mutex> lock(mutex);     if (file) {@@ -54,7 +54,7 @@     return ReturnTuple();   } -  ReturnTuple Call_getFileError(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_getFileError(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RawFileReader.getFileError")     std::lock_guard<std::mutex> lock(mutex);     if (!file) {@@ -69,17 +69,17 @@     return ReturnTuple(Var_empty);   } -  ReturnTuple Call_pastEnd(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_pastEnd(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RawFileReader.pastEnd")     std::lock_guard<std::mutex> lock(mutex);     return ReturnTuple(Box_Bool(!file || file->fail() || file->eof()));   } -  ReturnTuple Call_readBlock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_readBlock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RawFileReader.readBlock")     TRACE_CREATION     std::lock_guard<std::mutex> lock(mutex);-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0) {       FAIL() << "Read size " << Var_arg1 << " is invalid";     }@@ -122,8 +122,8 @@  void RemoveType_RawFileReader(const Params<0>::Type& params) {} -BoxedValue CreateValue_RawFileReader(S<const Type_RawFileReader> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_RawFileReader>(std::move(parent), args);+BoxedValue CreateValue_RawFileReader(S<const Type_RawFileReader> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_RawFileReader>(std::move(parent), params_args); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
lib/file/src/Extension_RawFileWriter.cpp view
@@ -25,7 +25,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_RawFileWriter(S<const Type_RawFileWriter> parent, const ValueTuple& args);+BoxedValue CreateValue_RawFileWriter(S<const Type_RawFileWriter> parent, const ParamsArgs& params_args);  struct ExtCategory_RawFileWriter : public Category_RawFileWriter { };@@ -33,19 +33,19 @@ struct ExtType_RawFileWriter : public Type_RawFileWriter {   inline ExtType_RawFileWriter(Category_RawFileWriter& p, Params<0>::Type params) : Type_RawFileWriter(p, params) {} -  ReturnTuple Call_open(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_open(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("RawFileWriter.open")-    return ReturnTuple(CreateValue_RawFileWriter(PARAM_SELF, args));+    return ReturnTuple(CreateValue_RawFileWriter(PARAM_SELF, params_args));   } };  struct ExtValue_RawFileWriter : public Value_RawFileWriter {-  inline ExtValue_RawFileWriter(S<const Type_RawFileWriter> p, const ValueTuple& args)+  inline ExtValue_RawFileWriter(S<const Type_RawFileWriter> p, const ParamsArgs& params_args)     : Value_RawFileWriter(std::move(p)),-      filename(args.At(0).AsString()),+      filename(params_args.GetArg(0).AsString()),       file(new std::ofstream(filename, std::ios::out | std::ios::binary | std::ios::trunc | std::ios::ate)) {} -  ReturnTuple Call_freeResource(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_freeResource(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RawFileWriter.freeResource")     std::lock_guard<std::mutex> lock(mutex);     if (file) {@@ -54,7 +54,7 @@     return ReturnTuple();   } -  ReturnTuple Call_getFileError(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_getFileError(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RawFileWriter.getFileError")     std::lock_guard<std::mutex> lock(mutex);     if (!file) {@@ -69,11 +69,11 @@     return ReturnTuple(Var_empty);   } -  ReturnTuple Call_writeBlock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_writeBlock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RawFileWriter.writeBlock")     TRACE_CREATION     std::lock_guard<std::mutex> lock(mutex);-    const PrimString& Var_arg1 = args.At(0).AsString();+    const PrimString& Var_arg1 = params_args.GetArg(0).AsString();     if (!file || file->rdstate() != std::ios::goodbit) {       FAIL() << "Error writing file \"" << filename << "\"";     }@@ -104,8 +104,8 @@  void RemoveType_RawFileWriter(const Params<0>::Type& params) {} -BoxedValue CreateValue_RawFileWriter(S<const Type_RawFileWriter> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_RawFileWriter>(std::move(parent), args);+BoxedValue CreateValue_RawFileWriter(S<const Type_RawFileWriter> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_RawFileWriter>(std::move(parent), params_args); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
lib/file/test/tests.0rt view
@@ -70,7 +70,7 @@     \ writer.freeResource()   } in \ writer.writeBlock(data) -  \ Testing.checkEquals<?>(FileTesting.forceReadFile("testfile"),data)+  \ Testing.checkEquals(FileTesting.forceReadFile("testfile"),data) }  unittest readEmpty {
lib/math/src/Extension_Math.cpp view
@@ -33,167 +33,167 @@ struct ExtType_Math : public Type_Math {   inline ExtType_Math(Category_Math& p, Params<0>::Type params) : Type_Math(p, params) {} -  ReturnTuple Call_acos(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_acos(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.acos")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::acos(Var_arg1)));   } -  ReturnTuple Call_acosh(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_acosh(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.acosh")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::acosh(Var_arg1)));   } -  ReturnTuple Call_asin(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_asin(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.asin")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::asin(Var_arg1)));   } -  ReturnTuple Call_asinh(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_asinh(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.asinh")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::asinh(Var_arg1)));   } -  ReturnTuple Call_atan(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_atan(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.atan")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::atan(Var_arg1)));   } -  ReturnTuple Call_atanh(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_atanh(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.atanh")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::atanh(Var_arg1)));   } -  ReturnTuple Call_ceil(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_ceil(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.ceil")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::ceil(Var_arg1)));   } -  ReturnTuple Call_cos(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_cos(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.cos")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::cos(Var_arg1)));   } -  ReturnTuple Call_cosh(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_cosh(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.cosh")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::cosh(Var_arg1)));   } -  ReturnTuple Call_exp(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_exp(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.exp")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::exp(Var_arg1)));   } -  ReturnTuple Call_fabs(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_fabs(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.fabs")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::fabs(Var_arg1)));   } -  ReturnTuple Call_floor(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_floor(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.floor")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::floor(Var_arg1)));   } -  ReturnTuple Call_fmod(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_fmod(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.fmod")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();-    const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();+    const PrimFloat Var_arg2 = (params_args.GetArg(1)).AsFloat();     return ReturnTuple(Box_Float(std::fmod(Var_arg1,Var_arg2)));   } -  ReturnTuple Call_isinf(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_isinf(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.isinf")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Bool(std::isinf(Var_arg1)));   } -  ReturnTuple Call_isnan(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_isnan(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.isnan")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Bool(std::isnan(Var_arg1)));   } -  ReturnTuple Call_log(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_log(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.log")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::log(Var_arg1)));   } -  ReturnTuple Call_log10(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_log10(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.log10")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::log10(Var_arg1)));   } -  ReturnTuple Call_log2(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_log2(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.log2")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::log2(Var_arg1)));   } -  ReturnTuple Call_pow(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_pow(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.pow")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();-    const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();+    const PrimFloat Var_arg2 = (params_args.GetArg(1)).AsFloat();     return ReturnTuple(Box_Float(std::pow(Var_arg1,Var_arg2)));   } -  ReturnTuple Call_round(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_round(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.round")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::round(Var_arg1)));   } -  ReturnTuple Call_sin(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_sin(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.sin")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::sin(Var_arg1)));   } -  ReturnTuple Call_sinh(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_sinh(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.sinh")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::sinh(Var_arg1)));   } -  ReturnTuple Call_sqrt(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_sqrt(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.sqrt")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::sqrt(Var_arg1)));   } -  ReturnTuple Call_tan(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_tan(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.tan")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::tan(Var_arg1)));   } -  ReturnTuple Call_tanh(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_tanh(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.tanh")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::tanh(Var_arg1)));   } -  ReturnTuple Call_trunc(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_trunc(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.trunc")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     return ReturnTuple(Box_Float(std::trunc(Var_arg1)));   } -  ReturnTuple Call_abs(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_abs(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Math.abs")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     return ReturnTuple(Box_Int(std::abs(Var_arg1)));   } };
lib/math/src/Extension_RandomExponential.cpp view
@@ -29,7 +29,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_RandomExponential(S<const Type_RandomExponential> parent, const ValueTuple& args);+BoxedValue CreateValue_RandomExponential(S<const Type_RandomExponential> parent, const ParamsArgs& params_args);  struct ExtCategory_RandomExponential : public Category_RandomExponential { };@@ -37,31 +37,31 @@ struct ExtType_RandomExponential : public Type_RandomExponential {   inline ExtType_RandomExponential(Category_RandomExponential& p, Params<0>::Type params) : Type_RandomExponential(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("RandomExponential.new")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     if (Var_arg1 <= 0) {       FAIL() << "Invalid lambda " << Var_arg1;     }-    return ReturnTuple(CreateValue_RandomExponential(PARAM_SELF, args));+    return ReturnTuple(CreateValue_RandomExponential(PARAM_SELF, params_args));   } };  struct ExtValue_RandomExponential : public Value_RandomExponential {-  inline ExtValue_RandomExponential(S<const Type_RandomExponential> p, const ValueTuple& args)+  inline ExtValue_RandomExponential(S<const Type_RandomExponential> p, const ParamsArgs& params_args)     : Value_RandomExponential(std::move(p)),       generator_((int) (long) this),-      distribution_(args.At(0).AsFloat()) {}+      distribution_(params_args.GetArg(0).AsFloat()) {} -  ReturnTuple Call_generate(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_generate(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RandomExponential.generate")     return ReturnTuple(Box_Float(distribution_(generator_)));   } -  ReturnTuple Call_setSeed(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_setSeed(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RandomExponential.setSeed")     distribution_.reset();-    generator_.seed(args.At(0).AsInt());+    generator_.seed(params_args.GetArg(0).AsInt());     return ReturnTuple(VAR_SELF);   } @@ -81,8 +81,8 @@  void RemoveType_RandomExponential(const Params<0>::Type& params) {} -BoxedValue CreateValue_RandomExponential(S<const Type_RandomExponential> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_RandomExponential>(std::move(parent), args);+BoxedValue CreateValue_RandomExponential(S<const Type_RandomExponential> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_RandomExponential>(std::move(parent), params_args); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
lib/math/src/Extension_RandomGaussian.cpp view
@@ -29,7 +29,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_RandomGaussian(S<const Type_RandomGaussian> parent, const ValueTuple& args);+BoxedValue CreateValue_RandomGaussian(S<const Type_RandomGaussian> parent, const ParamsArgs& params_args);  struct ExtCategory_RandomGaussian : public Category_RandomGaussian { };@@ -37,32 +37,32 @@ struct ExtType_RandomGaussian : public Type_RandomGaussian {   inline ExtType_RandomGaussian(Category_RandomGaussian& p, Params<0>::Type params) : Type_RandomGaussian(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("RandomGaussian.new")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();-    const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();+    const PrimFloat Var_arg2 = (params_args.GetArg(1)).AsFloat();     if (Var_arg2 <= 0) {       FAIL() << "Invalid standard deviation " << Var_arg2;     }-    return ReturnTuple(CreateValue_RandomGaussian(PARAM_SELF, args));+    return ReturnTuple(CreateValue_RandomGaussian(PARAM_SELF, params_args));   } };  struct ExtValue_RandomGaussian : public Value_RandomGaussian {-  inline ExtValue_RandomGaussian(S<const Type_RandomGaussian> p, const ValueTuple& args)+  inline ExtValue_RandomGaussian(S<const Type_RandomGaussian> p, const ParamsArgs& params_args)     : Value_RandomGaussian(std::move(p)),       generator_((int) (long) this),-      distribution_(args.At(0).AsFloat(), args.At(1).AsFloat()) {}+      distribution_(params_args.GetArg(0).AsFloat(), params_args.GetArg(1).AsFloat()) {} -  ReturnTuple Call_generate(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_generate(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RandomGaussian.generate")     return ReturnTuple(Box_Float(distribution_(generator_)));   } -  ReturnTuple Call_setSeed(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_setSeed(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RandomGaussian.setSeed")     distribution_.reset();-    generator_.seed(args.At(0).AsInt());+    generator_.seed(params_args.GetArg(0).AsInt());     return ReturnTuple(VAR_SELF);   } @@ -82,8 +82,8 @@  void RemoveType_RandomGaussian(const Params<0>::Type& params) {} -BoxedValue CreateValue_RandomGaussian(S<const Type_RandomGaussian> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_RandomGaussian>(std::move(parent), args);+BoxedValue CreateValue_RandomGaussian(S<const Type_RandomGaussian> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_RandomGaussian>(std::move(parent), params_args); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
lib/math/src/Extension_RandomUniform.cpp view
@@ -28,7 +28,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_RandomUniform(S<const Type_RandomUniform> parent, const ValueTuple& args);+BoxedValue CreateValue_RandomUniform(S<const Type_RandomUniform> parent, const ParamsArgs& params_args);  struct ExtCategory_RandomUniform : public Category_RandomUniform { };@@ -36,32 +36,32 @@ struct ExtType_RandomUniform : public Type_RandomUniform {   inline ExtType_RandomUniform(Category_RandomUniform& p, Params<0>::Type params) : Type_RandomUniform(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("RandomUniform.new")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();-    const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();+    const PrimFloat Var_arg2 = (params_args.GetArg(1)).AsFloat();     if (Var_arg2 <= Var_arg1) {       FAIL() << "Invalid range (" << Var_arg1 << "," << Var_arg2 << ")";     }-    return ReturnTuple(CreateValue_RandomUniform(PARAM_SELF, args));+    return ReturnTuple(CreateValue_RandomUniform(PARAM_SELF, params_args));   } };  struct ExtValue_RandomUniform : public Value_RandomUniform {-  inline ExtValue_RandomUniform(S<const Type_RandomUniform> p, const ValueTuple& args)+  inline ExtValue_RandomUniform(S<const Type_RandomUniform> p, const ParamsArgs& params_args)     : Value_RandomUniform(std::move(p)),       generator_((int) (long) this),-      distribution_(args.At(0).AsFloat(), args.At(1).AsFloat()) {}+      distribution_(params_args.GetArg(0).AsFloat(), params_args.GetArg(1).AsFloat()) {} -  ReturnTuple Call_generate(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_generate(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RandomUniform.generate")     return ReturnTuple(Box_Float(distribution_(generator_)));   } -  ReturnTuple Call_setSeed(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_setSeed(const ParamsArgs& params_args) final {     TRACE_FUNCTION("RandomUniform.setSeed")     distribution_.reset();-    generator_.seed(args.At(0).AsInt());+    generator_.seed(params_args.GetArg(0).AsInt());     return ReturnTuple(VAR_SELF);   } @@ -81,8 +81,8 @@  void RemoveType_RandomUniform(const Params<0>::Type& params) {} -BoxedValue CreateValue_RandomUniform(S<const Type_RandomUniform> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_RandomUniform>(std::move(parent), args);+BoxedValue CreateValue_RandomUniform(S<const Type_RandomUniform> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_RandomUniform>(std::move(parent), params_args); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
+ lib/math/src/token.0rx view
@@ -0,0 +1,56 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++define Token {+  $ReadOnly[mutex,toToken]$++  @category Mutex mutex <- SpinlockMutex.new()+  @category SearchTree<String,Token> toToken <- SearchTree<String,Token>.new()+  @category Int counter <- 0++  @value String string+  @value Int    value++  from (string) (token) {+    scoped {+      \ mutex.lock()+      optional Token existing <- toToken.get(string)+    } cleanup {+      \ mutex.unlock()+    } in if (present(existing)) {+      return require(existing)+    } else {+      \ toToken.set(string,(token <- Token{ string, (counter <- counter+1) }))+    }+  }++  formatted () {+    return string+  }++  equals (x,y) {+    return x.get() == y.get()+  }++  lessThan (x,y) {+    return x.get() < y.get()+  }++  @value get () -> (Int)+  get () { return value }+}
lib/math/test/categorical-tree.0rt view
@@ -37,16 +37,16 @@       .push(5).push(5).push(5).push(5)       .push(6).push(6) -  \ Testing.checkEquals<?>(tree.getTotal(),expected.size())-  \ Testing.checkEquals<?>(tree.getWeight(1),3)-  \ Testing.checkEquals<?>(tree.getWeight(2),7)-  \ Testing.checkEquals<?>(tree.getWeight(3),1)-  \ Testing.checkEquals<?>(tree.getWeight(4),3)-  \ Testing.checkEquals<?>(tree.getWeight(5),4)-  \ Testing.checkEquals<?>(tree.getWeight(6),2)+  \ Testing.checkEquals(tree.getTotal(),expected.size())+  \ Testing.checkEquals(tree.getWeight(1),3)+  \ Testing.checkEquals(tree.getWeight(2),7)+  \ Testing.checkEquals(tree.getWeight(3),1)+  \ Testing.checkEquals(tree.getWeight(4),3)+  \ Testing.checkEquals(tree.getWeight(5),4)+  \ Testing.checkEquals(tree.getWeight(6),2)    traverse (Counter.zeroIndexed(tree.getTotal()) -> Int pos) {-    \ Testing.checkEquals<?>(tree.locate(pos),expected.readAt(pos))+    \ Testing.checkEquals(tree.locate(pos),expected.readAt(pos))   } } @@ -71,22 +71,22 @@       .push(6).push(6)       .push(7).push(7).push(7) -  \ Testing.checkEquals<?>(tree.getTotal(),expected.size())-  \ Testing.checkEquals<?>(tree.getWeight(1),3)-  \ Testing.checkEquals<?>(tree.getWeight(2),7)-  \ Testing.checkEquals<?>(tree.getWeight(3),0)-  \ Testing.checkEquals<?>(tree.getWeight(4),3)-  \ Testing.checkEquals<?>(tree.getWeight(5),1)-  \ Testing.checkEquals<?>(tree.getWeight(6),2)-  \ Testing.checkEquals<?>(tree.getWeight(7),3)+  \ Testing.checkEquals(tree.getTotal(),expected.size())+  \ Testing.checkEquals(tree.getWeight(1),3)+  \ Testing.checkEquals(tree.getWeight(2),7)+  \ Testing.checkEquals(tree.getWeight(3),0)+  \ Testing.checkEquals(tree.getWeight(4),3)+  \ Testing.checkEquals(tree.getWeight(5),1)+  \ Testing.checkEquals(tree.getWeight(6),2)+  \ Testing.checkEquals(tree.getWeight(7),3)    traverse (Counter.zeroIndexed(tree.getTotal()) -> Int pos) {-    \ Testing.checkEquals<?>(tree.locate(pos),expected.readAt(pos))+    \ Testing.checkEquals(tree.locate(pos),expected.readAt(pos))   }    // Use ReadAt aliases for the same functionality.   traverse (Counter.zeroIndexed(tree.size()) -> Int pos) {-    \ Testing.checkEquals<?>(tree.readAt(pos),expected.readAt(pos))+    \ Testing.checkEquals(tree.readAt(pos),expected.readAt(pos))   } } @@ -96,8 +96,8 @@     .incrWeight(1)     .incrWeight(1) -  \ Testing.checkEquals<?>(tree.getTotal(),3)-  \ Testing.checkEquals<?>(tree.getWeight(1),3)+  \ Testing.checkEquals(tree.getTotal(),3)+  \ Testing.checkEquals(tree.getWeight(1),3) }  unittest decrement {@@ -107,22 +107,22 @@     .decrWeight(1)     .decrWeight(1) -  \ Testing.checkEquals<?>(tree.getTotal(),7)-  \ Testing.checkEquals<?>(tree.getWeight(1),7)+  \ Testing.checkEquals(tree.getTotal(),7)+  \ Testing.checkEquals(tree.getWeight(1),7) }  unittest duplicate {   CategoricalTree<Int> tree <- CategoricalTree<Int>.new().setWeight(1,1).setWeight(2,2)    CategoricalTree<Int> copy <- tree.duplicate()-  \ Testing.checkEquals<?>(copy.size(),3)-  \ Testing.checkEquals<?>(copy.getWeight(1),1)-  \ Testing.checkEquals<?>(copy.getWeight(2),2)+  \ Testing.checkEquals(copy.size(),3)+  \ Testing.checkEquals(copy.getWeight(1),1)+  \ Testing.checkEquals(copy.getWeight(2),2)    \ copy.setWeight(2,0)-  \ Testing.checkEquals<?>(copy.size(),1)-  \ Testing.checkEquals<?>(copy.getWeight(1),1)-  \ Testing.checkEquals<?>(tree.getWeight(2),2)+  \ Testing.checkEquals(copy.size(),1)+  \ Testing.checkEquals(copy.getWeight(1),1)+  \ Testing.checkEquals(tree.getWeight(2),2) }  unittest integrationTest { $DisableCoverage$@@ -159,13 +159,12 @@     }     $ReadOnly[key]$     $Hidden[node]$-    \ Testing.checkEquals<?>(tree.locate(pos),key)+    \ Testing.checkEquals(tree.locate(pos),key)     remaining <- remaining-1   } -  // NOTE: Order does not refine Formatted => can't use checkEmpty here.-  \ Testing.checkEquals<?>(present(node),false)-  \ Testing.checkEquals<?>(remaining,0)+  \ Testing.checkEmpty(node)+  \ Testing.checkEquals(remaining,0) }  
lib/math/test/math.0rt view
@@ -21,99 +21,99 @@ }  unittest cos {-  \ Testing.checkBetween<?>(Math.cos(2.0),-0.42,-0.41)+  \ Testing.checkBetween(Math.cos(2.0),-0.42,-0.41) }  unittest sin {-  \ Testing.checkBetween<?>(Math.sin(2.0),0.90,0.91)+  \ Testing.checkBetween(Math.sin(2.0),0.90,0.91) }  unittest tan {-  \ Testing.checkBetween<?>(Math.tan(2.0),-2.19,-2.18)+  \ Testing.checkBetween(Math.tan(2.0),-2.19,-2.18) }  unittest acos {-  \ Testing.checkBetween<?>(Math.acos(0.5),1.04,1.05)+  \ Testing.checkBetween(Math.acos(0.5),1.04,1.05) }  unittest asin {-  \ Testing.checkBetween<?>(Math.asin(0.5),0.52,0.53)+  \ Testing.checkBetween(Math.asin(0.5),0.52,0.53) }  unittest atan {-  \ Testing.checkBetween<?>(Math.atan(0.5),0.46,0.47)+  \ Testing.checkBetween(Math.atan(0.5),0.46,0.47) }  unittest cosh {-  \ Testing.checkBetween<?>(Math.cosh(2.0),3.76,3.77)+  \ Testing.checkBetween(Math.cosh(2.0),3.76,3.77) }  unittest sinh {-  \ Testing.checkBetween<?>(Math.sinh(2.0),3.62,3.63)+  \ Testing.checkBetween(Math.sinh(2.0),3.62,3.63) }  unittest tanh {-  \ Testing.checkBetween<?>(Math.tanh(2.0),0.96,0.97)+  \ Testing.checkBetween(Math.tanh(2.0),0.96,0.97) }  unittest acosh {-  \ Testing.checkBetween<?>(Math.acosh(2.0),1.31,1.32)+  \ Testing.checkBetween(Math.acosh(2.0),1.31,1.32) }  unittest asinh {-  \ Testing.checkBetween<?>(Math.asinh(2.0),1.44,1.45)+  \ Testing.checkBetween(Math.asinh(2.0),1.44,1.45) }  unittest atanh {-  \ Testing.checkBetween<?>(Math.atanh(0.5),0.54,0.55)+  \ Testing.checkBetween(Math.atanh(0.5),0.54,0.55) }  unittest exp {-  \ Testing.checkBetween<?>(Math.exp(1.0),2.71,2.72)+  \ Testing.checkBetween(Math.exp(1.0),2.71,2.72) }  unittest log {-  \ Testing.checkBetween<?>(Math.log(9.0),2.19,2.20)+  \ Testing.checkBetween(Math.log(9.0),2.19,2.20) }  unittest log10 {-  \ Testing.checkBetween<?>(Math.log10(100.0),1.99,2.01)+  \ Testing.checkBetween(Math.log10(100.0),1.99,2.01) }  unittest log2 {-  \ Testing.checkBetween<?>(Math.log2(8.0),2.99,3.01)+  \ Testing.checkBetween(Math.log2(8.0),2.99,3.01) }  unittest pow {-  \ Testing.checkBetween<?>(Math.pow(2.0,3.0),7.99,8.01)+  \ Testing.checkBetween(Math.pow(2.0,3.0),7.99,8.01) }  unittest sqrt {-  \ Testing.checkBetween<?>(Math.sqrt(4.0),1.99,2.01)+  \ Testing.checkBetween(Math.sqrt(4.0),1.99,2.01) }  unittest ceil {-  \ Testing.checkBetween<?>(Math.ceil(2.2),2.99,3.01)+  \ Testing.checkBetween(Math.ceil(2.2),2.99,3.01) }  unittest floor {-  \ Testing.checkBetween<?>(Math.floor(2.2),1.99,2.01)+  \ Testing.checkBetween(Math.floor(2.2),1.99,2.01) }  unittest fmod {-  \ Testing.checkBetween<?>(Math.fmod(7.0,4.0),2.99,3.01)+  \ Testing.checkBetween(Math.fmod(7.0,4.0),2.99,3.01) }  unittest trunc {-  \ Testing.checkBetween<?>(Math.trunc(2.2),1.99,2.01)+  \ Testing.checkBetween(Math.trunc(2.2),1.99,2.01) }  unittest round {-  \ Testing.checkBetween<?>(Math.round(2.7),2.99,3.01)+  \ Testing.checkBetween(Math.round(2.7),2.99,3.01) }  unittest fabs {-  \ Testing.checkBetween<?>(Math.fabs(-10.0),9.99,10.01)+  \ Testing.checkBetween(Math.fabs(-10.0),9.99,10.01) }  unittest isinf {@@ -129,7 +129,7 @@ }  unittest abs {-  \ Testing.checkEquals<?>(Math.abs(-10),10)-  \ Testing.checkEquals<?>(Math.abs(10),10)-  \ Testing.checkEquals<?>(Math.abs(0),0)+  \ Testing.checkEquals(Math.abs(-10),10)+  \ Testing.checkEquals(Math.abs(10),10)+  \ Testing.checkEquals(Math.abs(0),0) }
lib/math/test/random.0rt view
@@ -83,11 +83,11 @@   Float sum <- 0.0   traverse (Counter.zeroIndexed(count) -> _) {     Float value <- random.generate()-    \ Testing.checkGreaterThan<?>(value,0.0)+    \ Testing.checkGreaterThan(value,0.0)     sum <- sum+value   } -  \ Testing.checkBetween<?>(sum/count.asFloat(),0.9/lambda,1.1/lambda)+  \ Testing.checkBetween(sum/count.asFloat(),0.9/lambda,1.1/lambda) }  unittest gaussian { $DisableCoverage$@@ -103,7 +103,7 @@     sum <- sum+random.generate()   } -  \ Testing.checkBetween<?>(sum/count.asFloat(),mean-0.1*sd,mean+0.1*sd)+  \ Testing.checkBetween(sum/count.asFloat(),mean-0.1*sd,mean+0.1*sd) }  unittest uniform { $DisableCoverage$@@ -117,11 +117,11 @@   Float sum <- 0.0   traverse (Counter.zeroIndexed(count) -> _) {     Float value <- random.generate()-    \ Testing.checkBetween<?>(value,min,max)+    \ Testing.checkBetween(value,min,max)     sum <- sum+value   } -  \ Testing.checkBetween<?>(sum/count.asFloat(),min-0.1*(max-min),max-0.1*(max-min))+  \ Testing.checkBetween(sum/count.asFloat(),min-0.1*(max-min),max-0.1*(max-min)) }  @@ -143,9 +143,9 @@   random2 <- random2.setSeed(123)   Float v4 <- random2.generate() -  \ Testing.checkEquals<?>(v1 == v2,false)-  \ Testing.checkEquals<?>(v1 == v3,false)-  \ Testing.checkEquals<?>(v3,v4)+  \ Testing.checkFalse(v1 == v2)+  \ Testing.checkFalse(v1 == v3)+  \ Testing.checkEquals(v3,v4) }  unittest gaussian {@@ -163,9 +163,9 @@   random2 <- random2.setSeed(123)   Float v4 <- random2.generate() -  \ Testing.checkEquals<?>(v1 == v2,false)-  \ Testing.checkEquals<?>(v1 == v3,false)-  \ Testing.checkEquals<?>(v3,v4)+  \ Testing.checkFalse(v1 == v2)+  \ Testing.checkFalse(v1 == v3)+  \ Testing.checkEquals(v3,v4) }  unittest uniform {@@ -183,9 +183,9 @@   random2 <- random2.setSeed(123)   Float v4 <- random2.generate() -  \ Testing.checkEquals<?>(v1 == v2,false)-  \ Testing.checkEquals<?>(v1 == v3,false)-  \ Testing.checkEquals<?>(v3,v4)+  \ Testing.checkFalse(v1 == v2)+  \ Testing.checkFalse(v1 == v3)+  \ Testing.checkEquals(v3,v4) }  @@ -208,15 +208,15 @@       .append("c")    Vector<String> output <- Vector:create<String>()-  \ Randomize:permuteFrom<?>(tree,RandomUniform.new(0.0,1.0),output)-  \ Sorting:sort<?>(output)+  \ Randomize:permuteFrom(tree,RandomUniform.new(0.0,1.0),output)+  \ Sorting:sort(output) -  \ Testing.checkEquals<?>(output.size(),expected.size())+  \ Testing.checkEquals(output.size(),expected.size())   traverse (Counter.zeroIndexed(output.size()) -> Int pos) {-    \ Testing.checkEquals<?>(output.readAt(pos),expected.readAt(pos))+    \ Testing.checkEquals(output.readAt(pos),expected.readAt(pos))   } -  \ Testing.checkEquals<?>(tree.getWeight("a"),2)-  \ Testing.checkEquals<?>(tree.getWeight("b"),3)-  \ Testing.checkEquals<?>(tree.getWeight("c"),1)+  \ Testing.checkEquals(tree.getWeight("a"),2)+  \ Testing.checkEquals(tree.getWeight("b"),3)+  \ Testing.checkEquals(tree.getWeight("c"),1) }
+ lib/math/test/token.0rt view
@@ -0,0 +1,36 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++testcase "basic Token tests" {+  success+}++unittest equals {+  \ Testing.checkEquals(Token.from("message"),Token.from("message"))+  \ Testing.checkFalse(Token.from("message") `Token.equals` Token.from("other"))+}++unittest lessThan {+  \ Testing.checkFalse(Token.from("message") `Token.lessThan` Token.from("message"))+  \ Testing.checkTrue((Token.from("message") `Token.lessThan` Token.from("other")) ||+                      (Token.from("other") `Token.lessThan` Token.from("message")))+}++unittest formatted {+  \ Testing.checkEquals(Token.from("message").formatted(),"message")+}
+ lib/math/token.0rp view
@@ -0,0 +1,35 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++// String-based token with fast comparisons.+concrete Token {+  immutable+  defines Equals<Token>+  // LessThan is not lexicographical.+  defines LessThan<Token>+  refines Formatted++  // Get a Token from the provided String.+  //+  // Notes:+  // - This function is not particularly fast. The trade-off is that Equals and+  //   LessThan do not depend on the original strings' lengths.+  // - All tokens created with this function will persist until the process+  //   exits, regardless of if they are no longer in use.+  @type from (String) -> (Token)+}
lib/testing/helpers.0rp view
@@ -33,8 +33,8 @@   // Check the value for empty. Crashes if present.   //   // Args:-  // - optional Formatted: Actual value.-  @type checkEmpty (optional Formatted) -> ()+  // - #x: Actual value.+  @type checkEmpty<#x> (optional #x) -> ()    // Check the value for present. Crashes if empty.   //@@ -51,6 +51,18 @@     #x requires Formatted     #x defines Equals<#x>   (optional #x,optional #x) -> ()++  // Check the value for true. Crashes if false.+  //+  // Args:+  // - AsBool: Actual value.+  @type checkTrue (AsBool) -> ()++  // Check the value for false. Crashes if true.+  //+  // Args:+  // - AsBool: Actual value.+  @type checkFalse (AsBool) -> ()    // Check that the value is within a range. Crashes if it is not in the range.   //
lib/testing/src/helpers.0rx view
@@ -1,5 +1,5 @@ /* ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -19,7 +19,7 @@ $TestsOnly$  define Testing {-  checkEquals (x,y) {+  checkEquals (x,y) { $NoTrace$     if (!#x.equals(x,y)) {       fail(String.builder()           .append(x)@@ -29,16 +29,22 @@     }   } -  checkEmpty (x) {+  checkEmpty (x) { $NoTrace$     if (present(x)) {-      fail(String.builder()-          .append(require(x))-          .append(" is not empty")-          .build())+      scoped {+        optional Formatted formatted <- reduce<#x,Formatted>(require(x))+      } in if (present(formatted)) {+        fail(String.builder()+            .append(require(formatted))+            .append(" is not empty")+            .build())+      } else {+        fail("(unformatted value) is not empty")+      }     }   } -  checkPresent (x) {+  checkPresent (x) { $NoTrace$     if (!present(x)) {       fail(String.builder()           .append("expected non-empty value")@@ -46,9 +52,9 @@     }   } -  checkOptional (x,y) {+  checkOptional (x,y) { $NoTrace$     if (present(x) && present(y)) {-      \ checkEquals<?>(require(x),require(y))+      \ checkEquals(require(x),require(y))     } elif (!present(x) && present(y)) {       fail("empty is not equal to " + require(y).formatted())     } elif (present(x) && !present(y)) {@@ -56,8 +62,20 @@     }   } -  checkBetween (x,l,h) {-    if (!lessEquals<?>(l,h)) {+  checkTrue (x) { $NoTrace$+    if (!x.asBool()) {+      fail("expected true")+    }+  }++  checkFalse (x) { $NoTrace$+    if (x.asBool()) {+      fail("expected false")+    }+  }++  checkBetween (x,l,h) { $NoTrace$+    if (!lessEquals(l,h)) {       fail(String.builder()           .append("Upper limit ")           .append(l)@@ -65,7 +83,7 @@           .append(h)           .build())     }-    if (!lessEquals<?>(l,x) || !lessEquals<?>(x,h)) {+    if (!lessEquals(l,x) || !lessEquals(x,h)) {       fail(String.builder()           .append(x)           .append(" is not between ")@@ -76,8 +94,8 @@     }   } -  checkGreaterThan (x,l) {-    if (lessEquals<?>(x,l)) {+  checkGreaterThan (x,l) { $NoTrace$+    if (lessEquals(x,l)) {       fail(String.builder()           .append(x)           .append(" is not greater than ")@@ -86,8 +104,8 @@     }   } -  checkLessThan (x,h) {-    if (lessEquals<?>(h,x)) {+  checkLessThan (x,h) { $NoTrace$+    if (lessEquals(h,x)) {       fail(String.builder()           .append(x)           .append(" is not less than ")@@ -100,7 +118,7 @@     #x defines Equals<#x>     #x defines LessThan<#x>   (#x,#x) -> (Bool)-  lessEquals (x,y) {+  lessEquals (x,y) { $NoTrace$     // Using !#x.lessThan(y,x) wouldn't account for NaNs.     return #x.lessThan(x,y) || #x.equals(x,y)   }
lib/testing/test/tests.0rt view
@@ -1,5 +1,5 @@ /* ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -21,7 +21,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(13,13)+  \ Testing.checkEquals(13,13) }  @@ -32,7 +32,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(13,15)+  \ Testing.checkEquals(13,15) }  @@ -40,12 +40,17 @@   success } -unittest test {+unittest formatted {   \ Testing.checkEmpty(empty) } +unittest notFormatted {+  optional CharBuffer value <- empty+  \ Testing.checkEmpty(value)+} -testcase "checkEmpty fail" {++testcase "checkEmpty fail formatted" {   crash   require stderr "13"   require stderr "empty"@@ -56,6 +61,18 @@ }  +testcase "checkEmpty fail unformatted" {+  crash+  require stderr "unformatted"+  require stderr "empty"+}++unittest test {+  CharBuffer value <- CharBuffer.new(10)+  \ Testing.checkEmpty(value)+}++ testcase "checkPresent success" {   success }@@ -81,7 +98,7 @@  unittest test {   \ Testing.checkOptional<Int>(empty,empty)-  \ Testing.checkOptional<?>(13,13)+  \ Testing.checkOptional(13,13) }  @@ -92,7 +109,7 @@ }  unittest test {-  \ Testing.checkOptional<?>(13,empty)+  \ Testing.checkOptional(13,empty) }  @@ -103,7 +120,7 @@ }  unittest test {-  \ Testing.checkOptional<?>(empty,13)+  \ Testing.checkOptional(empty,13) }  @@ -112,7 +129,7 @@ }  unittest test {-  \ Testing.checkBetween<?>(13,13,15)+  \ Testing.checkBetween(13,13,15) }  @@ -124,7 +141,7 @@ }  unittest test {-  \ Testing.checkBetween<?>(13,14,15)+  \ Testing.checkBetween(13,14,15) }  @@ -136,7 +153,7 @@ }  unittest test {-  \ Testing.checkBetween<?>(14,15,13)+  \ Testing.checkBetween(14,15,13) }  @@ -145,7 +162,7 @@ }  unittest test {-  \ Testing.checkGreaterThan<?>(13,11)+  \ Testing.checkGreaterThan(13,11) }  @@ -156,7 +173,7 @@ }  unittest test {-  \ Testing.checkGreaterThan<?>(13,14)+  \ Testing.checkGreaterThan(13,14) }  @@ -165,7 +182,7 @@ }  unittest test {-  \ Testing.checkLessThan<?>(13,14)+  \ Testing.checkLessThan(13,14) }  @@ -176,5 +193,43 @@ }  unittest test {-  \ Testing.checkLessThan<?>(13,11)+  \ Testing.checkLessThan(13,11)+}+++testcase "checkTrue success" {+  success+}++unittest test {+  \ Testing.checkTrue(1)+}+++testcase "checkTrue fail" {+  crash+  require stderr "true"+}++unittest test {+  \ Testing.checkTrue(0)+}+++testcase "checkFalse success" {+  success+}++unittest test {+  \ Testing.checkFalse(0)+}+++testcase "checkFalse fail" {+  crash+  require stderr "false"+}++unittest test {+  \ Testing.checkFalse(1) }
lib/thread/src/Extension_Enumerated.cpp view
@@ -115,7 +115,7 @@   inline ExtValue_EnumeratedWait(S<const Type_EnumeratedWait> p, S<Barrier> b, int i)     : Value_EnumeratedWait(std::move(p)), barrier(b), index(i) {} -  ReturnTuple Call_wait(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_wait(const ParamsArgs& params_args) final {     TRACE_FUNCTION("EnumeratedWait.wait")     barrier->Wait(index);     return ReturnTuple(VAR_SELF);@@ -165,9 +165,9 @@ struct ExtType_EnumeratedBarrier : public Type_EnumeratedBarrier {   inline ExtType_EnumeratedBarrier(Category_EnumeratedBarrier& p, Params<0>::Type params) : Type_EnumeratedBarrier(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("EnumeratedBarrier.new")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0) {       FAIL() << "Invalid barrier thread count " << Var_arg1;     }@@ -186,16 +186,16 @@   inline ExtValue_EnumeratedBarrier(S<const Type_EnumeratedBarrier> p, std::vector<BoxedValue> w)     : Value_EnumeratedBarrier(std::move(p)), waits(std::move(w)) {} -  ReturnTuple Call_readAt(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_readAt(const ParamsArgs& params_args) final {     TRACE_FUNCTION("EnumeratedBarrier.readAt")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     if (Var_arg1 < 0 || Var_arg1 >= waits.size()) {       FAIL() << "index " << Var_arg1 << " is out of bounds";     }     return ReturnTuple(waits[Var_arg1]);   } -  ReturnTuple Call_size(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_size(const ParamsArgs& params_args) final {     TRACE_FUNCTION("EnumeratedBarrier.size")     return ReturnTuple(Box_Int(waits.size()));   }
lib/thread/src/Extension_ProcessThread.cpp view
@@ -31,7 +31,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_ProcessThread(S<const Type_ProcessThread> parent, const ValueTuple& args);+BoxedValue CreateValue_ProcessThread(S<const Type_ProcessThread> parent, const ParamsArgs& params_args);  struct ExtCategory_ProcessThread : public Category_ProcessThread { };@@ -39,17 +39,17 @@ struct ExtType_ProcessThread : public Type_ProcessThread {   inline ExtType_ProcessThread(Category_ProcessThread& p, Params<0>::Type params) : Type_ProcessThread(p, params) {} -  ReturnTuple Call_from(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_from(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("ProcessThread.from")-    return ReturnTuple(CreateValue_ProcessThread(PARAM_SELF, args));+    return ReturnTuple(CreateValue_ProcessThread(PARAM_SELF, params_args));   } };  struct ExtValue_ProcessThread : public Value_ProcessThread {-  inline ExtValue_ProcessThread(S<const Type_ProcessThread> p, const ValueTuple& args)-    : Value_ProcessThread(std::move(p)), routine(args.Only()) {}+  inline ExtValue_ProcessThread(S<const Type_ProcessThread> p, const ParamsArgs& params_args)+    : Value_ProcessThread(std::move(p)), routine(params_args.GetArg(0)) {} -  ReturnTuple Call_detach(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_detach(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ProcessThread.detach")     S<std::thread> temp = thread;     thread = nullptr;@@ -61,12 +61,12 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_isRunning(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_isRunning(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ProcessThread.isRunning")     return ReturnTuple(Box_Bool(isJoinable(thread.get())));   } -  ReturnTuple Call_join(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_join(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ProcessThread.join")     S<std::thread> temp = thread;     thread = nullptr;@@ -78,7 +78,7 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_start(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_start(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ProcessThread.start")     if (isJoinable(thread.get())) {       FAIL() << "thread is already running";@@ -90,7 +90,7 @@       thread.reset(new std::thread(         capture_thread::ThreadCrosser::WrapCall([this,self] {           TRACE_CREATION-          TypeValue::Call(routine, Function_Routine_run, ParamTuple(), ArgTuple());+          TypeValue::Call(routine, Function_Routine_run, PassParamsArgs());         })));     }     return ReturnTuple(VAR_SELF);@@ -126,8 +126,8 @@  void RemoveType_ProcessThread(const Params<0>::Type& params) {} -BoxedValue CreateValue_ProcessThread(S<const Type_ProcessThread> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_ProcessThread>(std::move(parent), args);+BoxedValue CreateValue_ProcessThread(S<const Type_ProcessThread> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_ProcessThread>(std::move(parent), params_args); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
lib/thread/src/Extension_Realtime.cpp view
@@ -44,18 +44,18 @@ struct ExtType_Realtime : public Type_Realtime {   inline ExtType_Realtime(Category_Realtime& p, Params<0>::Type params) : Type_Realtime(p, params) {} -  ReturnTuple Call_sleepSeconds(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_sleepSeconds(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Realtime.sleepSeconds")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     if (Var_arg1 > 0) {       std::this_thread::sleep_for(std::chrono::duration<double>(Var_arg1));     }     return ReturnTuple();   } -  ReturnTuple Call_sleepSecondsPrecise(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_sleepSecondsPrecise(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Realtime.sleepSecondsPrecise")-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();      const auto spinlock_limit = std::chrono::duration<double>(SLEEP_SPINLOCK_LIMIT); @@ -78,7 +78,7 @@     return ReturnTuple();   } -  ReturnTuple Call_monoSeconds(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_monoSeconds(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Realtime.monoSeconds")     const auto time = std::chrono::steady_clock::now().time_since_epoch();     const PrimFloat seconds =
lib/thread/src/Extension_ThreadCondition.cpp view
@@ -40,7 +40,7 @@ struct ExtType_ThreadCondition : public Type_ThreadCondition {   inline ExtType_ThreadCondition(Category_ThreadCondition& p, Params<0>::Type params) : Type_ThreadCondition(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("ThreadCondition.new")     return ReturnTuple(CreateValue_ThreadCondition(PARAM_SELF));   }@@ -57,7 +57,7 @@     pthread_mutex_init(&mutex, &mutex_attr);   } -  ReturnTuple Call_lock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_lock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ThreadCondition.lock")     int error = 0;     if ((error = pthread_mutex_lock(&mutex)) != 0) {@@ -66,7 +66,7 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_resumeAll(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_resumeAll(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ThreadCondition.resumeAll")     int error = 0;     if ((error = pthread_cond_broadcast(&cond)) != 0) {@@ -75,7 +75,7 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_resumeOne(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_resumeOne(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ThreadCondition.resumeOne")     int error = 0;     if ((error = pthread_cond_signal(&cond)) != 0) {@@ -84,10 +84,10 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_timedWait(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_timedWait(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ThreadCondition.timedWait")     int error = 0;-    const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+    const PrimFloat Var_arg1 = (params_args.GetArg(0)).AsFloat();     if (Var_arg1 < 0) {       FAIL() << "Bad wait time " << Var_arg1;     }@@ -107,7 +107,7 @@     return ReturnTuple(Box_Bool(true));   } -  ReturnTuple Call_unlock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_unlock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ThreadCondition.unlock")     int error = 0;     if ((error = pthread_mutex_unlock(&mutex)) != 0) {@@ -116,7 +116,7 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_wait(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_wait(const ParamsArgs& params_args) final {     TRACE_FUNCTION("ThreadCondition.wait")     int error = 0;     if ((error = pthread_cond_wait(&cond, &mutex)) != 0) {
lib/thread/test/barrier.0rt view
@@ -22,7 +22,7 @@  unittest correctCount {   ReadAt<BarrierWait> barriers <- EnumeratedBarrier.new(13)-  \ Testing.checkEquals<?>(barriers.size(),13)+  \ Testing.checkEquals(barriers.size(),13) }  unittest waitForOneThread {@@ -32,7 +32,7 @@  unittest zeroAllowed {   ReadAt<BarrierWait> barriers <- EnumeratedBarrier.new(0)-  \ Testing.checkEquals<?>(barriers.size(),0)+  \ Testing.checkEquals(barriers.size(),0) }  unittest waitForMultipleThreads {@@ -44,10 +44,10 @@   Thread thread2 <- ProcessThread.from(WaitAndIncrement.create(2,value,mutex,barriers.readAt(2))).start()    \ barriers.readAt(0).wait()-  \ Testing.checkEquals<?>(value.get(),2)+  \ Testing.checkEquals(value.get(),2)    \ barriers.readAt(0).wait()-  \ Testing.checkEquals<?>(value.get(),4)+  \ Testing.checkEquals(value.get(),4)    \ thread1.join()   \ thread2.join()
lib/thread/test/condition.0rt view
@@ -42,7 +42,7 @@   \ thread1.join()   \ thread2.join() -  \ Testing.checkEquals<?>(value.get(),4)+  \ Testing.checkEquals(value.get(),4) }  unittest resumeOne {@@ -69,7 +69,7 @@   \ thread1.join()   \ thread2.join() -  \ Testing.checkEquals<?>(value.get(),3)+  \ Testing.checkEquals(value.get(),3) }  unittest forceWaitTimeout {@@ -82,7 +82,7 @@   \ cond.resumeOne()   \ thread.join() -  \ Testing.checkEquals<?>(value.get(),1)+  \ Testing.checkEquals(value.get(),1) }  unittest waitNoTimeout {
lib/thread/test/thread.0rt view
@@ -22,11 +22,11 @@  unittest test {   CountLoop counter <- CountLoop.create(10000)-  \ Testing.checkEquals<?>(counter.get(),0)+  \ Testing.checkEquals(counter.get(),0)   \ counter.start()-  \ Testing.checkEquals<?>(counter.get(),10000)+  \ Testing.checkEquals(counter.get(),10000)   \ counter.start()-  \ Testing.checkEquals<?>(counter.get(),20000)+  \ Testing.checkEquals(counter.get(),20000) }  concrete CountLoop {@@ -89,7 +89,7 @@   Thread oddThread  <- ProcessThread.from(EvenOrOdd.create(mutex,false,10,value)).start()   \ evenThread.join()   \ oddThread.join()-  \ Testing.checkEquals<?>(value.get(),20)+  \ Testing.checkEquals(value.get(),20) }  concrete EvenOrOdd {@@ -163,7 +163,7 @@   }    run () {-    \ Testing.checkEquals<?>(Argv.global().readAt(1),"arg1")+    \ Testing.checkEquals(Argv.global().readAt(1),"arg1")   } } 
lib/thread/test/time.0rt view
@@ -68,12 +68,12 @@   Float start <- Realtime.monoSeconds()   \ Realtime.sleepSeconds(0.5)   Float stop <- Realtime.monoSeconds()-  \ Testing.checkBetween<?>(stop-start,0.5,0.6)+  \ Testing.checkBetween(stop-start,0.5,0.6) }  unittest testPrecise {   Float start <- Realtime.monoSeconds()   \ Realtime.sleepSecondsPrecise(0.5)   Float stop <- Realtime.monoSeconds()-  \ Testing.checkBetween<?>(stop-start,0.5,0.51)+  \ Testing.checkBetween(stop-start,0.5,0.51) }
lib/util/helpers.0rp view
@@ -26,7 +26,7 @@   //   // Example:   //-  //   Bool lt <- x.defaultOrder() `OrderH:lessThan<?>` y.defaultOrder()+  //   Bool lt <- x.defaultOrder() `OrderH:lessThan` y.defaultOrder()   @category lessThan<#x>     #x defines LessThan<#x>   (optional Order<#x>,optional Order<#x>) -> (Bool)@@ -48,7 +48,7 @@   //   // Example:   //-  //   Bool eq <- x.defaultOrder() `OrderH:equals<?>` y.defaultOrder()+  //   Bool eq <- x.defaultOrder() `OrderH:equals` y.defaultOrder()   @category equals<#x>     #x defines Equals<#x>   (optional Order<#x>,optional Order<#x>) -> (Bool)@@ -77,7 +77,7 @@   //   // Example:   //-  //   Bool lt <- x `ReadAtH:lessThan<?>` y+  //   Bool lt <- x `ReadAtH:lessThan` y   @category lessThan<#x>     #x defines LessThan<#x>   (ReadAt<#x>,ReadAt<#x>) -> (Bool)@@ -99,7 +99,7 @@   //   // Example:   //-  //   Bool eq <- x `ReadAtH:equals<?>` y+  //   Bool eq <- x `ReadAtH:equals` y   @category equals<#x>     #x defines Equals<#x>   (ReadAt<#x>,ReadAt<#x>) -> (Bool)
lib/util/src/Extension_Argv.cpp view
@@ -35,7 +35,7 @@ struct ExtType_Argv : public Type_Argv {   inline ExtType_Argv(Category_Argv& p, Params<0>::Type params) : Type_Argv(p, params) {} -  ReturnTuple Call_global(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_global(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Argv.global")     return ReturnTuple(Var_global);   }@@ -45,21 +45,21 @@   inline ExtValue_Argv(S<const Type_Argv> p, int st, int sz)     : Value_Argv(std::move(p)), start(st), size(sz) {} -  ReturnTuple Call_readAt(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_readAt(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Argv.readAt")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();     return ReturnTuple(Box_String(Argv::GetArgAt(start + Var_arg1)));   } -  ReturnTuple Call_size(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_size(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Argv.size")     return ReturnTuple(Box_Int(GetSize()));   } -  ReturnTuple Call_subSequence(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_subSequence(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Argv.subSequence")-    const PrimInt Var_arg1 = (args.At(0)).AsInt();-    const PrimInt Var_arg2 = (args.At(1)).AsInt();+    const PrimInt Var_arg1 = (params_args.GetArg(0)).AsInt();+    const PrimInt Var_arg2 = (params_args.GetArg(1)).AsInt();     if (Var_arg1 < 0 || (Var_arg1 > 0 && Var_arg1 >= GetSize())) {       FAIL() << "index " << Var_arg1 << " is out of bounds";     }
lib/util/src/Extension_MutexLock.cpp view
@@ -28,7 +28,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_MutexLock(S<const Type_MutexLock> parent, const ValueTuple& args);+BoxedValue CreateValue_MutexLock(S<const Type_MutexLock> parent, const BoxedValue& mutex);  struct ExtCategory_MutexLock : public Category_MutexLock { };@@ -36,41 +36,41 @@ struct ExtType_MutexLock : public Type_MutexLock {   inline ExtType_MutexLock(Category_MutexLock& p, Params<0>::Type params) : Type_MutexLock(p, params) {} -  ReturnTuple Call_lock(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_lock(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("MutexLock.lock")-    return ReturnTuple(CreateValue_MutexLock(CreateType_MutexLock(Params<0>::Type()), args));+    return ReturnTuple(CreateValue_MutexLock(CreateType_MutexLock(Params<0>::Type()), params_args.GetArg(0)));   } };  struct ExtValue_MutexLock : public Value_MutexLock {-  inline ExtValue_MutexLock(S<const Type_MutexLock> p, const ValueTuple& args)-    : Value_MutexLock(std::move(p)), mutex(args.Only()) {-    TypeValue::Call(BoxedValue::Require(mutex), Function_Mutex_lock, ParamTuple(), ArgTuple());+  inline ExtValue_MutexLock(S<const Type_MutexLock> p, const BoxedValue& mutex)+    : Value_MutexLock(std::move(p)), mutex_(mutex) {+    TypeValue::Call(BoxedValue::Require(mutex_), Function_Mutex_lock, PassParamsArgs());   } -  ReturnTuple Call_freeResource(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_freeResource(const ParamsArgs& params_args) final {     TRACE_FUNCTION("MutexLock.freeResource")     TRACE_CREATION-    if (!BoxedValue::Present(mutex)) {+    if (!BoxedValue::Present(mutex_)) {       FAIL() << "MutexLock freed multiple times";     } else {-      TypeValue::Call(mutex, Function_Mutex_unlock, ParamTuple(), ArgTuple());-      mutex = Var_empty;+      TypeValue::Call(mutex_, Function_Mutex_unlock, PassParamsArgs());+      mutex_ = Var_empty;     }     return ReturnTuple();   }    ~ExtValue_MutexLock() {-    if (BoxedValue::Present(mutex)) {+    if (BoxedValue::Present(mutex_)) {       TRACE_CREATION-      TypeValue::Call(BoxedValue::Require(mutex), Function_Mutex_unlock, ParamTuple(), ArgTuple());-      mutex = Var_empty;+      TypeValue::Call(BoxedValue::Require(mutex_), Function_Mutex_unlock, PassParamsArgs());+      mutex_ = Var_empty;       FAIL() << "MutexLock not freed with freeResource()";     }   }    // optional Mutex-  BoxedValue mutex;+  BoxedValue mutex_;   CAPTURE_CREATION("MutexLock") }; @@ -86,8 +86,8 @@  void RemoveType_MutexLock(const Params<0>::Type& params) {} -BoxedValue CreateValue_MutexLock(S<const Type_MutexLock> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_MutexLock>(std::move(parent), args);+BoxedValue CreateValue_MutexLock(S<const Type_MutexLock> parent, const BoxedValue& mutex) {+  return BoxedValue::New<ExtValue_MutexLock>(std::move(parent), mutex); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
lib/util/src/Extension_SimpleInput.cpp view
@@ -38,26 +38,26 @@ struct ExtType_SimpleInput : public Type_SimpleInput {   inline ExtType_SimpleInput(Category_SimpleInput& p, Params<0>::Type params) : Type_SimpleInput(p, params) {} -  ReturnTuple Call_stdin(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_stdin(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("SimpleInput.stdin")     return ReturnTuple(Var_stdin);   } };  struct ExtValue_SimpleInput : public Value_SimpleInput {-  inline ExtValue_SimpleInput(S<const Type_SimpleInput> p, const ValueTuple& args)+  inline ExtValue_SimpleInput(S<const Type_SimpleInput> p)     : Value_SimpleInput(std::move(p)) {} -  ReturnTuple Call_pastEnd(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_pastEnd(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SimpleInput.pastEnd")     std::lock_guard<std::mutex> lock(mutex);     return ReturnTuple(Box_Bool(zero_read));   } -  ReturnTuple Call_readBlock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_readBlock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SimpleInput.readBlock")     std::lock_guard<std::mutex> lock(mutex);-    const int size = args.At(0).AsInt();+    const int size = params_args.GetArg(0).AsInt();     if (size < 0) {       FAIL() << "Read size " << size << " is invalid";     }@@ -76,7 +76,7 @@ };  namespace {-const BoxedValue Var_stdin = BoxedValue::New<ExtValue_SimpleInput>(CreateType_SimpleInput(Params<0>::Type()), ArgTuple());+const BoxedValue Var_stdin = BoxedValue::New<ExtValue_SimpleInput>(CreateType_SimpleInput(Params<0>::Type())); }  // namespace  Category_SimpleInput& CreateCategory_SimpleInput() {
lib/util/src/Extension_SimpleMutex.cpp view
@@ -35,7 +35,7 @@ struct ExtType_SimpleMutex : public Type_SimpleMutex {   inline ExtType_SimpleMutex(Category_SimpleMutex& p, Params<0>::Type params) : Type_SimpleMutex(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("SimpleMutex.new")     return ReturnTuple(CreateValue_SimpleMutex(CreateType_SimpleMutex(Params<0>::Type())));   }@@ -45,13 +45,13 @@   inline ExtValue_SimpleMutex(S<const Type_SimpleMutex> p)     : Value_SimpleMutex(std::move(p)) {} -  ReturnTuple Call_lock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_lock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SimpleMutex.lock")     mutex.lock();     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_unlock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_unlock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SimpleMutex.unlock")     mutex.unlock();     return ReturnTuple(VAR_SELF);
lib/util/src/Extension_SimpleOutput.cpp view
@@ -41,17 +41,17 @@ struct ExtType_SimpleOutput : public Type_SimpleOutput {   inline ExtType_SimpleOutput(Category_SimpleOutput& p, Params<0>::Type params) : Type_SimpleOutput(p, params) {} -  ReturnTuple Call_error(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_error(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("SimpleOutput.error")     return ReturnTuple(Var_error);   } -  ReturnTuple Call_stderr(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_stderr(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("SimpleOutput.stderr")     return ReturnTuple(Var_stderr);   } -  ReturnTuple Call_stdout(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_stdout(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("SimpleOutput.stdout")     return ReturnTuple(Var_stdout);   }@@ -69,19 +69,19 @@   inline ExtValue_SimpleOutput(S<const Type_SimpleOutput> p, S<Writer> w)     : Value_SimpleOutput(std::move(p)), writer(w) {} -  ReturnTuple Call_flush(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_flush(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SimpleOutput.flush")     std::lock_guard<std::mutex> lock(mutex);     writer->Flush();     return ReturnTuple();   } -  ReturnTuple Call_write(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_write(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SimpleOutput.write")-    const BoxedValue& Var_arg1 = (args.At(0));+    const BoxedValue& Var_arg1 = (params_args.GetArg(0));     std::lock_guard<std::mutex> lock(mutex);-    writer->Write(TypeValue::Call(args.At(0), Function_Formatted_formatted,-                                  ParamTuple(), ArgTuple()).Only().AsString());+    writer->Write(TypeValue::Call(params_args.GetArg(0), Function_Formatted_formatted,+                                  PassParamsArgs()).At(0).AsString());     return ReturnTuple();   } 
lib/util/src/Extension_SpinlockMutex.cpp view
@@ -35,7 +35,7 @@ struct ExtType_SpinlockMutex : public Type_SpinlockMutex {   inline ExtType_SpinlockMutex(Category_SpinlockMutex& p, Params<0>::Type params) : Type_SpinlockMutex(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("SpinlockMutex.new")     return ReturnTuple(CreateValue_SpinlockMutex(CreateType_SpinlockMutex(Params<0>::Type())));   }@@ -45,13 +45,13 @@   inline ExtValue_SpinlockMutex(S<const Type_SpinlockMutex> p)     : Value_SpinlockMutex(std::move(p)) {} -  ReturnTuple Call_lock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_lock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SpinlockMutex.lock")     while (flag.test_and_set(std::memory_order_acquire));     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_unlock(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_unlock(const ParamsArgs& params_args) final {     TRACE_FUNCTION("SpinlockMutex.unlock")     flag.clear(std::memory_order_release);     return ReturnTuple(VAR_SELF);
lib/util/src/counters.0rx view
@@ -154,12 +154,12 @@ }  define Ranges {-  min (x,y) (z) {-    z, _ <- minMax<?>(x,y)+  min (x,y) {+    return minMax(x,y){0}   }    max (x,y) (z) {-    _, z <- minMax<?>(x,y)+    return minMax(x,y){1}   }    minMax (x,y) {
lib/util/src/helpers.0rx view
@@ -66,7 +66,7 @@   }    lessThanWith (x,y) {-    traverse (Counter.zeroIndexed(Ranges:min<?>(x.size(),y.size())) -> Int i) {+    traverse (Counter.zeroIndexed(Ranges:min(x.size(),y.size())) -> Int i) {       $ReadOnly[i]$       if (x.readAt(i) `#xx.lessThan` y.readAt(i)) {         return true
lib/util/src/parse.0rx view
@@ -145,7 +145,7 @@       }     } -    return ErrorOr:value<?>(total)+    return ErrorOr:value(total)   }    int (data) {@@ -177,7 +177,7 @@       return ErrorOr:error("missing digits in Int value")     } -    return ErrorOr:value<?>(sign*total)+    return ErrorOr:value(sign*total)   }    hexInt (data) {@@ -219,7 +219,7 @@       return ErrorOr:error("missing digits in Int value")     } -    return ErrorOr:value<?>(sign*total)+    return ErrorOr:value(sign*total)   }    octInt (data) {@@ -251,7 +251,7 @@       return ErrorOr:error("missing digits in Int value")     } -    return ErrorOr:value<?>(sign*total)+    return ErrorOr:value(sign*total)   }    binInt (data) {@@ -283,7 +283,7 @@       return ErrorOr:error("missing digits in Int value")     } -    return ErrorOr:value<?>(sign*total)+    return ErrorOr:value(sign*total)   }    @type autoFail<#x> (Char) -> (ErrorOr<all>)
lib/util/src/testing.0rx view
@@ -37,7 +37,7 @@           .append(x.getError())           .build())     } else {-      \ Testing.checkEquals<?>(x.getValue(),y)+      \ Testing.checkEquals(x.getValue(),y)     }   } @@ -52,7 +52,7 @@           .append(x.getError())           .build())     } else {-      \ Testing.checkBetween<?>(x.getValue(),l,h)+      \ Testing.checkBetween(x.getValue(),l,h)     }   } }
lib/util/test/counters.0rt view
@@ -24,11 +24,11 @@   Int index <- 0    traverse (Counter.zeroIndexed(10) -> Int i) {-    \ Testing.checkEquals<?>(i,index)+    \ Testing.checkEquals(i,index)     index <- index+1   } -  \ Testing.checkEquals<?>(index,10)+  \ Testing.checkEquals(index,10) }  unittest revZeroIndexed {@@ -36,81 +36,81 @@    traverse (Counter.revZeroIndexed(10) -> Int i) {     index <- index-1-    \ Testing.checkEquals<?>(i,index)+    \ Testing.checkEquals(i,index)   } -  \ Testing.checkEquals<?>(index,0)+  \ Testing.checkEquals(index,0) }  unittest unlimitedCount {   Int index <- 0    traverse (Counter.unlimited() -> Int i) {-    \ Testing.checkEquals<?>(i,index)+    \ Testing.checkEquals(i,index)     if ((index <- index+1) >= 10) {       break     }   } -  \ Testing.checkEquals<?>(index,10)+  \ Testing.checkEquals(index,10) }  unittest times {   Int index <- 0 -  traverse ("message" `Repeat:times<?>` 10 -> String m) {-    \ Testing.checkEquals<?>(m,"message")+  traverse ("message" `Repeat:times` 10 -> String m) {+    \ Testing.checkEquals(m,"message")     index <- index+1   } -  \ Testing.checkEquals<?>(index,10)+  \ Testing.checkEquals(index,10) }  unittest unlimitedValue {   Int index <- 0 -  traverse (Repeat:unlimited<?>("message") -> String m) {-    \ Testing.checkEquals<?>(m,"message")+  traverse (Repeat:unlimited("message") -> String m) {+    \ Testing.checkEquals(m,"message")     if ((index <- index+1) >= 10) {       break     }   } -  \ Testing.checkEquals<?>(index,10)+  \ Testing.checkEquals(index,10) }  unittest minMax {   scoped {-    Int x, Int y <- Ranges:minMax<?>(10,3)+    Int x, Int y <- Ranges:minMax(10,3)   } in {-    \ Testing.checkEquals<?>(x,3)-    \ Testing.checkEquals<?>(y,10)+    \ Testing.checkEquals(x,3)+    \ Testing.checkEquals(y,10)   }    scoped {-    Int x, Int y <- Ranges:minMax<?>(3,10)+    Int x, Int y <- Ranges:minMax(3,10)   } in {-    \ Testing.checkEquals<?>(x,3)-    \ Testing.checkEquals<?>(y,10)+    \ Testing.checkEquals(x,3)+    \ Testing.checkEquals(y,10)   } }  unittest min {   scoped {-    Int x <- Ranges:min<?>(10,3)-  } in \ Testing.checkEquals<?>(x,3)+    Int x <- Ranges:min(10,3)+  } in \ Testing.checkEquals(x,3)    scoped {-    Int x <- Ranges:min<?>(3,10)-  } in \ Testing.checkEquals<?>(x,3)+    Int x <- Ranges:min(3,10)+  } in \ Testing.checkEquals(x,3) }  unittest max {   scoped {-    Int x <- Ranges:max<?>(10,3)-  } in \ Testing.checkEquals<?>(x,10)+    Int x <- Ranges:max(10,3)+  } in \ Testing.checkEquals(x,10)    scoped {-    Int x <- Ranges:max<?>(3,10)-  } in \ Testing.checkEquals<?>(x,10)+    Int x <- Ranges:max(3,10)+  } in \ Testing.checkEquals(x,10) }
lib/util/test/extra.0rt view
@@ -23,20 +23,20 @@  unittest global {   Int count <- Argv.global().size()-  \ Testing.checkEquals<?>(count,5)-  \ Testing.checkEquals<?>(Argv.global().readAt(0),"testcase")-  \ Testing.checkEquals<?>(Argv.global().readAt(1),"arg1")-  \ Testing.checkEquals<?>(Argv.global().readAt(2),"arg2")-  \ Testing.checkEquals<?>(Argv.global().readAt(3),"arg3")-  \ Testing.checkEquals<?>(Argv.global().readAt(4),"arg4")+  \ Testing.checkEquals(count,5)+  \ Testing.checkEquals(Argv.global().readAt(0),"testcase")+  \ Testing.checkEquals(Argv.global().readAt(1),"arg1")+  \ Testing.checkEquals(Argv.global().readAt(2),"arg2")+  \ Testing.checkEquals(Argv.global().readAt(3),"arg3")+  \ Testing.checkEquals(Argv.global().readAt(4),"arg4") }  unittest subSequence {   ReadAt<String> argv <- Argv.global().subSequence(2,2)   Int count <- argv.size()-  \ Testing.checkEquals<?>(count,2)-  \ Testing.checkEquals<?>(argv.readAt(0),"arg2")-  \ Testing.checkEquals<?>(argv.readAt(1),"arg3")+  \ Testing.checkEquals(count,2)+  \ Testing.checkEquals(argv.readAt(0),"arg2")+  \ Testing.checkEquals(argv.readAt(1),"arg3") }  @@ -66,21 +66,21 @@  unittest withValue {   ErrorOr<Int> value <- ErrorOr:value<Int>(10)-  \ Testing.checkEquals<?>(value.isError(),false)-  \ Testing.checkEquals<?>(value.getValue(),10)+  \ Testing.checkFalse(value.isError())+  \ Testing.checkEquals(value.getValue(),10) }  unittest withError {   ErrorOr<String> value <- ErrorOr:error("error message")-  \ Testing.checkEquals<?>(value.isError(),true)-  \ Testing.checkEquals<?>(value.getError().formatted(),"error message")+  \ Testing.checkTrue(value.isError())+  \ Testing.checkEquals(value.getError().formatted(),"error message") }  unittest convertError {   scoped {     ErrorOr<String> error <- ErrorOr:error("error message")   } in ErrorOr<Int> value <- error.convertError()-  \ Testing.checkEquals<?>(value.getError().formatted(),"error message")+  \ Testing.checkEquals(value.getError().formatted(),"error message") }  
lib/util/test/helpers.0rt view
@@ -21,69 +21,69 @@ }  unittest orderHLessThan {-  \ Testing.checkEquals<?>("".defaultOrder()    `OrderH:lessThan<?>` "".defaultOrder(),   false)-  \ Testing.checkEquals<?>("a".defaultOrder()   `OrderH:lessThan<?>` "abc".defaultOrder(),true)-  \ Testing.checkEquals<?>("b".defaultOrder()   `OrderH:lessThan<?>` "abc".defaultOrder(),false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:lessThan<?>` "abc".defaultOrder(),false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:lessThan<?>` "a".defaultOrder(),  false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:lessThan<?>` "b".defaultOrder(),  true)+  \ Testing.checkFalse("".defaultOrder()    `OrderH:lessThan` "".defaultOrder())+  \ Testing.checkTrue("a".defaultOrder()    `OrderH:lessThan` "abc".defaultOrder())+  \ Testing.checkFalse("b".defaultOrder()   `OrderH:lessThan` "abc".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:lessThan` "abc".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:lessThan` "a".defaultOrder())+  \ Testing.checkTrue("abc".defaultOrder()  `OrderH:lessThan` "b".defaultOrder()) }  unittest orderHLessThanWith {-  \ Testing.checkEquals<?>("".defaultOrder()    `OrderH:lessThanWith<?,Reversed<Char>>` "".defaultOrder(),   false)-  \ Testing.checkEquals<?>("a".defaultOrder()   `OrderH:lessThanWith<?,Reversed<Char>>` "abc".defaultOrder(),true)-  \ Testing.checkEquals<?>("b".defaultOrder()   `OrderH:lessThanWith<?,Reversed<Char>>` "abc".defaultOrder(),true)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:lessThanWith<?,Reversed<Char>>` "abc".defaultOrder(),false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:lessThanWith<?,Reversed<Char>>` "a".defaultOrder(),  false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:lessThanWith<?,Reversed<Char>>` "b".defaultOrder(),  false)+  \ Testing.checkFalse("".defaultOrder()    `OrderH:lessThanWith<?,Reversed<Char>>` "".defaultOrder())+  \ Testing.checkTrue("a".defaultOrder()    `OrderH:lessThanWith<?,Reversed<Char>>` "abc".defaultOrder())+  \ Testing.checkTrue("b".defaultOrder()    `OrderH:lessThanWith<?,Reversed<Char>>` "abc".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:lessThanWith<?,Reversed<Char>>` "abc".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:lessThanWith<?,Reversed<Char>>` "a".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:lessThanWith<?,Reversed<Char>>` "b".defaultOrder()) }  unittest orderHEquals {-  \ Testing.checkEquals<?>("".defaultOrder()    `OrderH:equals<?>` "".defaultOrder(),   true)-  \ Testing.checkEquals<?>("a".defaultOrder()   `OrderH:equals<?>` "abc".defaultOrder(),false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:equals<?>` "abc".defaultOrder(),true)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:equals<?>` "a".defaultOrder(),  false)+  \ Testing.checkTrue("".defaultOrder()     `OrderH:equals` "".defaultOrder())+  \ Testing.checkFalse("a".defaultOrder()   `OrderH:equals` "abc".defaultOrder())+  \ Testing.checkTrue("abc".defaultOrder()  `OrderH:equals` "abc".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:equals` "a".defaultOrder()) }  unittest orderHEqualsWith {-  \ Testing.checkEquals<?>("".defaultOrder()    `OrderH:equalsWith<?,IgnoreCase>` "".defaultOrder(),   true)-  \ Testing.checkEquals<?>("a".defaultOrder()   `OrderH:equalsWith<?,IgnoreCase>` "ABC".defaultOrder(),false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:equalsWith<?,IgnoreCase>` "ABC".defaultOrder(),true)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:equalsWith<?,IgnoreCase>` "DEF".defaultOrder(),false)-  \ Testing.checkEquals<?>("abc".defaultOrder() `OrderH:equalsWith<?,IgnoreCase>` "A".defaultOrder(),  false)+  \ Testing.checkTrue("".defaultOrder()     `OrderH:equalsWith<?,IgnoreCase>` "".defaultOrder())+  \ Testing.checkFalse("a".defaultOrder()   `OrderH:equalsWith<?,IgnoreCase>` "ABC".defaultOrder())+  \ Testing.checkTrue("abc".defaultOrder()  `OrderH:equalsWith<?,IgnoreCase>` "ABC".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:equalsWith<?,IgnoreCase>` "DEF".defaultOrder())+  \ Testing.checkFalse("abc".defaultOrder() `OrderH:equalsWith<?,IgnoreCase>` "A".defaultOrder()) }  unittest readAtHLessThan {-  \ Testing.checkEquals<?>(""    `ReadAtH:lessThan<?>` "",   false)-  \ Testing.checkEquals<?>("a"   `ReadAtH:lessThan<?>` "abc",true)-  \ Testing.checkEquals<?>("b"   `ReadAtH:lessThan<?>` "abc",false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:lessThan<?>` "abc",false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:lessThan<?>` "a",  false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:lessThan<?>` "b",  true)+  \ Testing.checkFalse(""    `ReadAtH:lessThan` "")+  \ Testing.checkTrue("a"    `ReadAtH:lessThan` "abc")+  \ Testing.checkFalse("b"   `ReadAtH:lessThan` "abc")+  \ Testing.checkFalse("abc" `ReadAtH:lessThan` "abc")+  \ Testing.checkFalse("abc" `ReadAtH:lessThan` "a")+  \ Testing.checkTrue("abc"  `ReadAtH:lessThan` "b") }  unittest readAtHLessThanWith {-  \ Testing.checkEquals<?>(""    `ReadAtH:lessThanWith<?,Reversed<Char>>` "",   false)-  \ Testing.checkEquals<?>("a"   `ReadAtH:lessThanWith<?,Reversed<Char>>` "abc",true)-  \ Testing.checkEquals<?>("b"   `ReadAtH:lessThanWith<?,Reversed<Char>>` "abc",true)-  \ Testing.checkEquals<?>("abc" `ReadAtH:lessThanWith<?,Reversed<Char>>` "abc",false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:lessThanWith<?,Reversed<Char>>` "a",  false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:lessThanWith<?,Reversed<Char>>` "b",  false)+  \ Testing.checkFalse(""    `ReadAtH:lessThanWith<?,Reversed<Char>>` "")+  \ Testing.checkTrue("a"    `ReadAtH:lessThanWith<?,Reversed<Char>>` "abc")+  \ Testing.checkTrue("b"    `ReadAtH:lessThanWith<?,Reversed<Char>>` "abc")+  \ Testing.checkFalse("abc" `ReadAtH:lessThanWith<?,Reversed<Char>>` "abc")+  \ Testing.checkFalse("abc" `ReadAtH:lessThanWith<?,Reversed<Char>>` "a")+  \ Testing.checkFalse("abc" `ReadAtH:lessThanWith<?,Reversed<Char>>` "b") }  unittest readAtHEquals {-  \ Testing.checkEquals<?>(""    `ReadAtH:equals<?>` "",   true)-  \ Testing.checkEquals<?>("a"   `ReadAtH:equals<?>` "abc",false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:equals<?>` "abc",true)-  \ Testing.checkEquals<?>("abc" `ReadAtH:equals<?>` "a",  false)+  \ Testing.checkTrue(""     `ReadAtH:equals` "")+  \ Testing.checkFalse("a"   `ReadAtH:equals` "abc")+  \ Testing.checkTrue("abc"  `ReadAtH:equals` "abc")+  \ Testing.checkFalse("abc" `ReadAtH:equals` "a") }  unittest readAtHEqualsWith {-  \ Testing.checkEquals<?>(""    `ReadAtH:equalsWith<?,IgnoreCase>` "",   true)-  \ Testing.checkEquals<?>("a"   `ReadAtH:equalsWith<?,IgnoreCase>` "ABC",false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:equalsWith<?,IgnoreCase>` "ABC",true)-  \ Testing.checkEquals<?>("abc" `ReadAtH:equalsWith<?,IgnoreCase>` "DEF",false)-  \ Testing.checkEquals<?>("abc" `ReadAtH:equalsWith<?,IgnoreCase>` "a",  false)+  \ Testing.checkTrue(""     `ReadAtH:equalsWith<?,IgnoreCase>` "")+  \ Testing.checkFalse("a"   `ReadAtH:equalsWith<?,IgnoreCase>` "ABC")+  \ Testing.checkTrue("abc"  `ReadAtH:equalsWith<?,IgnoreCase>` "ABC")+  \ Testing.checkFalse("abc" `ReadAtH:equalsWith<?,IgnoreCase>` "DEF")+  \ Testing.checkFalse("abc" `ReadAtH:equalsWith<?,IgnoreCase>` "a") }  concrete IgnoreCase {@@ -106,34 +106,34 @@ }  unittest reversed {-  \ Testing.checkEquals<?>(0 `Reversed<Int>.lessThan` 0,false)-  \ Testing.checkEquals<?>(0 `Reversed<Int>.lessThan` 1,false)-  \ Testing.checkEquals<?>(1 `Reversed<Int>.lessThan` 0,true)+  \ Testing.checkFalse(0 `Reversed<Int>.lessThan` 0)+  \ Testing.checkFalse(0 `Reversed<Int>.lessThan` 1)+  \ Testing.checkTrue(1  `Reversed<Int>.lessThan` 0) }  unittest bySizeLessThan {-  \ Testing.checkEquals<?>(""   `BySize.lessThan` "",  false)-  \ Testing.checkEquals<?>("b"  `BySize.lessThan` "ac",true)-  \ Testing.checkEquals<?>("ac" `BySize.lessThan` "b", false)-  \ Testing.checkEquals<?>("a"  `BySize.lessThan` "b", false)+  \ Testing.checkFalse(""   `BySize.lessThan` "")+  \ Testing.checkTrue("b"   `BySize.lessThan` "ac")+  \ Testing.checkFalse("ac" `BySize.lessThan` "b")+  \ Testing.checkFalse("a"  `BySize.lessThan` "b") }  unittest bySizeEquals {-  \ Testing.checkEquals<?>(""   `BySize.equals` "",  true)-  \ Testing.checkEquals<?>("b"  `BySize.equals` "ac",false)-  \ Testing.checkEquals<?>("ac" `BySize.equals` "b", false)-  \ Testing.checkEquals<?>("a"  `BySize.equals` "b", true)+  \ Testing.checkTrue(""    `BySize.equals` "")+  \ Testing.checkFalse("b"  `BySize.equals` "ac")+  \ Testing.checkFalse("ac" `BySize.equals` "b")+  \ Testing.checkTrue("a"   `BySize.equals` "b") }  unittest alwaysEqualLessThan {-  \ Testing.checkEquals<?>(""   `AlwaysEqual.lessThan` "",  false)-  \ Testing.checkEquals<?>("b"  `AlwaysEqual.lessThan` "ac",false)-  \ Testing.checkEquals<?>("ac" `AlwaysEqual.lessThan` "b", false)+  \ Testing.checkFalse(""   `AlwaysEqual.lessThan` "")+  \ Testing.checkFalse("b"  `AlwaysEqual.lessThan` "ac")+  \ Testing.checkFalse("ac" `AlwaysEqual.lessThan` "b") }  unittest alwaysEqualEquals {-  \ Testing.checkEquals<?>(""   `AlwaysEqual.equals` "",  true)-  \ Testing.checkEquals<?>("b"  `AlwaysEqual.equals` "ac",true)-  \ Testing.checkEquals<?>("ac" `AlwaysEqual.equals` "b", true)-  \ Testing.checkEquals<?>("a"  `AlwaysEqual.equals` "b", true)+  \ Testing.checkTrue(""   `AlwaysEqual.equals` "")+  \ Testing.checkTrue("b"  `AlwaysEqual.equals` "ac")+  \ Testing.checkTrue("ac" `AlwaysEqual.equals` "b")+  \ Testing.checkTrue("a"  `AlwaysEqual.equals` "b") }
lib/util/test/input.0rt view
@@ -30,7 +30,7 @@       fail("past end")     }     String value <- reader.readNextLine()-    \ Testing.checkEquals<?>(value,line)+    \ Testing.checkEquals(value,line)   } } @@ -85,7 +85,7 @@  unittest readAll {   String allContents <- TextReader.readAll(FakeFile.create())-  \ Testing.checkEquals<?>(allContents,"this is a partial line\nwith some more data\nand\nmore lines\nunfinished")+  \ Testing.checkEquals(allContents,"this is a partial line\nwith some more data\nand\nmore lines\nunfinished") }  @@ -95,5 +95,5 @@ }  unittest test {-  \ Testing.checkEquals<?>(TextReader.readAll(SimpleInput.stdin()),"")+  \ Testing.checkEquals(TextReader.readAll(SimpleInput.stdin()),"") }
lib/util/test/parse.0rt view
@@ -21,59 +21,59 @@ }  unittest floatNoDecimal {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123"),122.9,123.1)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123"),122.9,123.1) }  unittest floatDecimalLeft {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float(".123"),0.1229,0.1231)+  \ UtilTesting.checkSuccessBetween(ParseChars.float(".123"),0.1229,0.1231) }  unittest floatDecimalRight {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123."),122.9,123.1)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123."),122.9,123.1) }  unittest floatDecimalMiddle {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123.456"),123.4559,123.4561)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123.456"),123.4559,123.4561) }  unittest floatLeadingTrailingZeros {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("000123.456000"),123.4559,123.4561)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("000123.456000"),123.4559,123.4561) }  unittest floatNegative {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("-123.456"),-123.4561,-123.4559)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("-123.456"),-123.4561,-123.4559) }  unittest floatPositive {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("+123.456"),123.4559,123.4561)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("+123.456"),123.4559,123.4561) }  unittest floatNegativeDecimalLeft {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("-.456"),-0.4561,-0.4559)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("-.456"),-0.4561,-0.4559) }  unittest floatExponentNoDecimal {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123E5"),122.9E5,123.1E5)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123E5"),122.9E5,123.1E5) }  unittest floatNegativeExponent {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123E-5"),122.9E-5,123.1E-5)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123E-5"),122.9E-5,123.1E-5) }  unittest floatPositiveExponent {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123E+5"),122.9E5,123.1E5)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123E+5"),122.9E5,123.1E5) }  unittest floatExponentDecimalRight {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123.E5"),122.9E5,123.1E5)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123.E5"),122.9E5,123.1E5) }  unittest floatExponentDecimalLeft {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float(".123E5"),122.9E2,123.1E2)+  \ UtilTesting.checkSuccessBetween(ParseChars.float(".123E5"),122.9E2,123.1E2) }  unittest floatExponentDecimalMiddle {-  \ UtilTesting.checkSuccessBetween<?>(ParseChars.float("123.456E5"),123.4559E5,123.4561E5)+  \ UtilTesting.checkSuccessBetween(ParseChars.float("123.456E5"),123.4559E5,123.4561E5) }  unittest floatEmpty {@@ -109,19 +109,19 @@ }  unittest int {-  \ UtilTesting.checkSuccess<?>(ParseChars.int("1234"),1234)+  \ UtilTesting.checkSuccess(ParseChars.int("1234"),1234) }  unittest intNegative {-  \ UtilTesting.checkSuccess<?>(ParseChars.int("-1234"),-1234)+  \ UtilTesting.checkSuccess(ParseChars.int("-1234"),-1234) }  unittest intPositive {-  \ UtilTesting.checkSuccess<?>(ParseChars.int("+1234"),1234)+  \ UtilTesting.checkSuccess(ParseChars.int("+1234"),1234) }  unittest intLeadingZeros {-  \ UtilTesting.checkSuccess<?>(ParseChars.int("001234"),1234)+  \ UtilTesting.checkSuccess(ParseChars.int("001234"),1234) }  unittest intEmpty {@@ -137,19 +137,19 @@ }  unittest hexInt {-  \ UtilTesting.checkSuccess<?>(ParseChars.hexInt("12AbCdEf"),\x12ABCDEF)+  \ UtilTesting.checkSuccess(ParseChars.hexInt("12AbCdEf"),\x12ABCDEF) }  unittest hexIntNegative {-  \ UtilTesting.checkSuccess<?>(ParseChars.hexInt("-12AbCdEf"),-\x12ABCDEF)+  \ UtilTesting.checkSuccess(ParseChars.hexInt("-12AbCdEf"),-\x12ABCDEF) }  unittest hexIntPositive {-  \ UtilTesting.checkSuccess<?>(ParseChars.hexInt("+12AbCdEf"),\x12ABCDEF)+  \ UtilTesting.checkSuccess(ParseChars.hexInt("+12AbCdEf"),\x12ABCDEF) }  unittest hexIntLeadingZeros {-  \ UtilTesting.checkSuccess<?>(ParseChars.hexInt("0012AbCdEf"),\x12ABCDEF)+  \ UtilTesting.checkSuccess(ParseChars.hexInt("0012AbCdEf"),\x12ABCDEF) }  unittest hexIntEmpty {@@ -165,19 +165,19 @@ }  unittest octInt {-  \ UtilTesting.checkSuccess<?>(ParseChars.octInt("127"),\o127)+  \ UtilTesting.checkSuccess(ParseChars.octInt("127"),\o127) }  unittest octIntNegative {-  \ UtilTesting.checkSuccess<?>(ParseChars.octInt("-127"),-\o127)+  \ UtilTesting.checkSuccess(ParseChars.octInt("-127"),-\o127) }  unittest octIntPositive {-  \ UtilTesting.checkSuccess<?>(ParseChars.octInt("+127"),\o127)+  \ UtilTesting.checkSuccess(ParseChars.octInt("+127"),\o127) }  unittest octIntLeadingZeros {-  \ UtilTesting.checkSuccess<?>(ParseChars.octInt("00127"),\o127)+  \ UtilTesting.checkSuccess(ParseChars.octInt("00127"),\o127) }  unittest octIntEmpty {@@ -193,19 +193,19 @@ }  unittest binInt {-  \ UtilTesting.checkSuccess<?>(ParseChars.binInt("100101"),\b100101)+  \ UtilTesting.checkSuccess(ParseChars.binInt("100101"),\b100101) }  unittest binIntNegative {-  \ UtilTesting.checkSuccess<?>(ParseChars.binInt("-100101"),-\b100101)+  \ UtilTesting.checkSuccess(ParseChars.binInt("-100101"),-\b100101) }  unittest binIntPositive {-  \ UtilTesting.checkSuccess<?>(ParseChars.binInt("+100101"),\b100101)+  \ UtilTesting.checkSuccess(ParseChars.binInt("+100101"),\b100101) }  unittest binIntLeadingZeros {-  \ UtilTesting.checkSuccess<?>(ParseChars.binInt("00100101"),\b100101)+  \ UtilTesting.checkSuccess(ParseChars.binInt("00100101"),\b100101) }  unittest binIntEmpty {
lib/util/test/testing.0rt view
@@ -31,7 +31,7 @@ }  unittest test {-  \ UtilTesting.checkError(ErrorOr:value<?>("message"))+  \ UtilTesting.checkError(ErrorOr:value("message")) }  @@ -40,7 +40,7 @@ }  unittest test {-  \ UtilTesting.checkSuccess<?>(ErrorOr:value<?>("message"),"message")+  \ UtilTesting.checkSuccess(ErrorOr:value("message"),"message") }  @@ -51,7 +51,7 @@ }  unittest test {-  \ UtilTesting.checkSuccess<?>(ErrorOr:value<?>("foo"),"message")+  \ UtilTesting.checkSuccess(ErrorOr:value("foo"),"message") }  @@ -62,7 +62,7 @@ }  unittest test {-  \ UtilTesting.checkSuccess<?>(ErrorOr:error("failure"),"message")+  \ UtilTesting.checkSuccess(ErrorOr:error("failure"),"message") }  @@ -71,7 +71,7 @@ }  unittest test {-  \ UtilTesting.checkSuccessBetween<?>(ErrorOr:value<?>(1),0,2)+  \ UtilTesting.checkSuccessBetween(ErrorOr:value(1),0,2) }  @@ -81,7 +81,7 @@ }  unittest test {-  \ UtilTesting.checkSuccessBetween<?>(ErrorOr:value<?>(7),0,2)+  \ UtilTesting.checkSuccessBetween(ErrorOr:value(7),0,2) }  @@ -92,5 +92,5 @@ }  unittest test {-  \ UtilTesting.checkSuccessBetween<?>(ErrorOr:error("failure"),0,2)+  \ UtilTesting.checkSuccessBetween(ErrorOr:error("failure"),0,2) }
src/Cli/Compiler.hs view
@@ -74,8 +74,6 @@  data LoadedTests =   LoadedTests {-    ltRoot :: FilePath,-    ltPath :: FilePath,     ltMetadata :: CompileMetadata,     ltExprMap :: ExprMap SourceContext,     ltPublicDeps :: [CompileMetadata],@@ -88,6 +86,7 @@   as  <- fmap fixPaths $ mapCompilerM (resolveModule resolver (p </> d)) is   as2 <- fmap fixPaths $ mapCompilerM (resolveModule resolver (p </> d)) is2   let ca0 = Map.empty+  compilerHash <- getCompilerHash backend   deps1 <- loadPublicDeps compilerHash f ca0 as   let ca1 = ca0 `Map.union` mapMetadata deps1   deps2 <- loadPublicDeps compilerHash f ca1 as2@@ -102,14 +101,15 @@                  bpDeps <- loadPublicDeps compilerHash f ca2 [base]                  return $ bpDeps ++ deps1   time <- errorFromIO getZonedTime-  path <- errorFromIO $ canonicalizePath $ p </> d+  root <- errorFromIO $ canonicalizePath p+  path <- errorFromIO $ canonicalizePath (p </> d)   extra <- errorFromIO $ sequence $ map (canonicalizePath . (p</>)) ee   -- NOTE: Making the public namespace deterministic allows freshness checks to   -- skip checking all inputs/outputs for each dependency.   let ns0 = StaticNamespace $ publicNamespace  $ show compilerHash ++ path   let ns1 = StaticNamespace . privateNamespace $ show time ++ show compilerHash ++ path   let extensions = concat $ map getSourceCategories es-  cs <- loadModuleGlobals resolver p (ns0,ns1) ps Nothing deps1' deps2+  (cs,private) <- loadModuleGlobals resolver p (ns0,ns1) ps Nothing deps1' deps2   let cm = createLanguageModule extensions em cs   let cs2 = filter (not . hasCodeVisibility FromDependency) cs   let pc = map (getCategoryName . wvData) $ filter (not . hasCodeVisibility ModuleOnly) cs2@@ -119,9 +119,10 @@   fs <- compileLanguageModule cm xa   mf <- maybeCreateMain cm xa m   eraseCachedData (p </> d)-  ps2 <- mapCompilerM (errorFromIO. canonicalizePath . (p </>)) ps-  xs2 <- mapCompilerM (errorFromIO. canonicalizePath . (p </>)) xs-  ts2 <- mapCompilerM (errorFromIO. canonicalizePath . (p </>)) ts+  pps <- fmap (zip ps) $ mapCompilerM (errorFromIO . canonicalizePath . (p</>)) ps+  let ps2 = map fst $ filter (not . ((`Set.member` private) . snd)) pps+  let xs2 = xs ++ (map fst $ filter ((`Set.member` private) . snd) pps)+  let ts2 = ts   let paths = map (\ns -> getCachedPath (p </> d) ns "") $ nub $ filter (not . null) $ map show $ map coNamespace fs   paths' <- mapM (errorFromIO . canonicalizePath) paths   s0 <- errorFromIO $ canonicalizePath $ getCachedPath (p </> d) (show ns0) ""@@ -145,6 +146,7 @@   ls <- createLibrary libraryName (getLinkFlags m) (deps1' ++ deps2) allObjects   let cm2 = CompileMetadata {       cmVersionHash = compilerHash,+      cmRoot = root,       cmPath = path,       cmExtra = extra,       cmPublicNamespace = ns0,@@ -165,9 +167,10 @@       cmLinkFlags = getLinkFlags m,       cmObjectFiles = os1' ++ osOther ++ map OtherObjectFile os'     }-  bs <- createBinary paths' (cm2:(deps1' ++ deps2)) m mf+  bs <- createBinary compilerHash paths' (cm2:(deps1' ++ deps2)) m mf   let cm2' = CompileMetadata {       cmVersionHash = cmVersionHash cm2,+      cmRoot = cmRoot cm2,       cmPath = cmPath cm2,       cmExtra = cmExtra cm2,       cmPublicNamespace = cmPublicNamespace cm2,@@ -191,7 +194,6 @@   writeMetadata (p </> d) cm2'   let traces = Set.unions $ map coPossibleTraces $ hxx ++ other   writePossibleTraces (p </> d) traces where-    compilerHash = getCompilerHash backend     ep' = fixPaths $ map (p </>) ep     writeOutputFile paths ca@(CxxOutput _ f2 ns _ _ _ content) = do       errorFromIO $ hPutStrLn stderr $ "Writing file " ++ f2@@ -243,7 +245,7 @@           fmap Just $ runCxxCommand backend command       | isSuffixOf ".a" f2 || isSuffixOf ".o" f2 = return (Just f2)       | otherwise = return Nothing-    createBinary paths deps (CompileBinary n _ lm o lf) [CxxOutput _ _ _ ns2 req _ content] = do+    createBinary compilerHash paths deps (CompileBinary n _ lm o lf) [CxxOutput _ _ _ ns2 req _ content] = do       f0 <- if null o                 then errorFromIO $ canonicalizePath $ p </> d </> show n                 else errorFromIO $ canonicalizePath $ p </> d </> o@@ -267,11 +269,11 @@         getCommand LinkDynamic mainAbs f0 deps2 paths2 = do           let objects = getLibrariesForDeps deps2           return $ CompileToBinary mainAbs objects [] f0 paths2 []-    createBinary _ _ (CompileBinary n _ _ _ _) [] =+    createBinary _ _ _ (CompileBinary n _ _ _ _) [] =       compilerErrorM $ "Main category " ++ show n ++ " not found."-    createBinary _ _ (CompileBinary n _ _ _ _) _ =+    createBinary _ _ _ (CompileBinary n _ _ _ _) _ =       compilerErrorM $ "Multiple matches for main category " ++ show n ++ "."-    createBinary _ _ _ _ = return []+    createBinary _ _ _ _ _ = return []     createLibrary _ _ [] [] = return []     createLibrary name lf deps os = do       let flags = lf ++ getLinkFlagsForDeps deps@@ -289,7 +291,7 @@ createModuleTemplates resolver p d ds deps1 deps2 = do   (ps,xs,_) <- findSourceFiles p (d:ds)   (LanguageModule _ _ _ cs0 ps0 ts0 cs1 ps1 ts1 _ _) <--    fmap (createLanguageModule [] Map.empty) $ loadModuleGlobals resolver p (PublicNamespace,PrivateNamespace) ps Nothing deps1 deps2+    fmap (createLanguageModule [] Map.empty . fst) $ loadModuleGlobals resolver p (PublicNamespace,PrivateNamespace) ps Nothing deps1 deps2   xs' <- zipWithContents resolver p xs   ds2 <- mapCompilerM parseInternalSource xs'   let ds3 = concat $ map (\(_,_,d2) -> d2) ds2@@ -315,12 +317,12 @@ runModuleTests :: (PathIOHandler r, CompilerBackend b) =>   r -> b -> FilePath -> FilePath -> [FilePath] -> LoadedTests ->   TrackedErrorsIO [((Int,Int),TrackedErrors ())]-runModuleTests resolver backend cl base tp (LoadedTests p d m em deps1 deps2) = do+runModuleTests resolver backend cl base tp (LoadedTests m em deps1 deps2) = do   let paths = base:(cmPublicSubdirs m ++ cmPrivateSubdirs m ++ getIncludePathsForDeps deps1)   mapCompilerM_ showSkipped $ filter (not . isTestAllowed) $ cmTestFiles m-  ts' <- zipWithContents resolver p $ map (d </>) $ filter isTestAllowed $ cmTestFiles m-  path <- errorFromIO $ canonicalizePath (p </> d)-  cm <- fmap (createLanguageModule [] em) $ loadModuleGlobals resolver path (NoNamespace,NoNamespace) [] (Just m) deps1 []+  ts' <- zipWithContents resolver (cmRoot m) $ filter isTestAllowed $ cmTestFiles m+  let path = cmPath m+  cm <- fmap (createLanguageModule [] em . fst) $ loadModuleGlobals resolver path (NoNamespace,NoNamespace) [] (Just m) deps1 []   mapCompilerM (runSingleTest backend cl cm paths (m:deps2)) ts' where     allowTests = Set.fromList tp     isTestAllowed t
src/Cli/ParseCompileOptions.hs view
@@ -23,11 +23,11 @@ ) where  import Control.Monad (when)-import Data.List (isSuffixOf) import Text.Regex.TDFA  import Base.CompilerError import Cli.CompileOptions+import Module.ProcessMetadata (isPrivateSource,isPublicSource,isTestSource) import Types.TypeCategory (FunctionName(..)) import Types.TypeInstance (CategoryName(..)) @@ -35,39 +35,53 @@ optionHelpText :: [String] optionHelpText = [     "",-    "zeolite [options...] --fast [category(.function)] [.0rx source]",-    "zeolite [options...] -r [modules...]",-    "zeolite [options...] -R [modules...]",-    "zeolite [options...] -t [modules...] (--log-traces [filename])",+    "Compilation Modes:",     "",-    "zeolite [options...] -c [module]",-    "zeolite [options...] -m [category(.function)] (-o [binary]) [module]",+    "  zeolite [options...] --fast [category(.function)] [.0rx source]",+    "    Create a binary without needing a config.",     "",-    "zeolite [options...] --templates [modules...]",-    "zeolite --get-path",-    "zeolite --missed-lines [filename] [modules...]",-    "zeolite --show-deps [modules...]",-    "zeolite --show-traces [modules...]",-    "zeolite --version",+    "  zeolite [options...] -r [modules...]",+    "    Recompile using each module's .zeolite-module config.",     "",-    "Compilation Modes:",-    "  --fast: Create a binary without needing a config.",-    "  -r: Recompile using each module's .zeolite-module config.",-    "  -R: Recursively recompile using each module's .zeolite-module config.",-    "  -t: Only execute tests, without other compilation.",+    "  zeolite [options...] -R [modules...]",+    "    Recursively recompile using each module's .zeolite-module config.",     "",+    "  zeolite [options...] -t (--log-traces [filename]) [modules...] (tests...)",+    "    Only execute tests, without other compilation.",+    "",     "Configuration Modes:",-    "  -c: Create a new .zeolite-module config for a libary module.",-    "  -m: Create a new .zeolite-module config for a binary module.",     "",+    "  zeolite [options...] -c [module]",+    "    Create a new .zeolite-module config for a libary module.",+    "",+    "  zeolite [options...] -m [category(.function)] (-o [binary]) [module]",+    "    Create a new .zeolite-module config for a binary module.",+    "",     "Special Modes:",-    "  --templates: Only create C++ templates for undefined categories in .0rp sources.",-    "  --get-path: Show the data path and immediately exit.",-    "  --missed-lines: List all lines missed in a log file taken from --log-traces.",-    "  --show-deps: Show category dependencies for the modules.",-    "  --show-traces: Show the possible code traces for the modules.",-    "  --version: Show the compiler version and immediately exit.",     "",+    "  zeolite [options...] --templates [modules...]",+    "    Only create C++ templates for undefined categories in .0rp sources.",+    "",+    "  zeolite (-p [path]) --clean [modules...]",+    "    Remove all cached data for the modules.",+    "",+    "  zeolite (-p [path]) --missed-lines [filename] [modules...]",+    "    List all lines missed in a log file taken from --log-traces.",+    "",+    "  zeolite (-p [path]) --show-deps [modules...]",+    "    Show category dependencies for the modules.",+    "",+    "  zeolite (-p [path]) --show-traces [modules...]",+    "    Show the possible code traces for the modules.",+    "",+    "Compiler Info:",+    "",+    "  zeolite --get-path",+    "    Show the data path and immediately exit.",+    "",+    "  zeolite --version",+    "    Show the compiler version and immediately exit.",+    "",     "Options:",     "  -f: Force an operation that zeolite would otherwise reject.",     "  -i [module]: A single source module to include as a public dependency.",@@ -80,6 +94,7 @@     "  category: The name of a concrete category with no params.",     "  function: The name of a @type function (defaults to \"run\") with no args or params.",     "  module: Path to a directory containing an existing or to-be-created Zeolite module.",+    "  test: Name of a .0rt file to limit test execution to.",     "",     "Examples:",     "",@@ -174,7 +189,7 @@         (t,fn) <- check $ break (== '.') c         checkCategoryName n2 t  "--fast"         checkFunctionName n2 fn "--fast"-        when (not $ isSuffixOf ".0rx" f2) $ argError n3 f2 $ "Must specify a .0rx source file."+        when (not $ isPrivateSource f2) $ argError n3 f2 $ "Must specify a .0rx source file."         let m2 = CompileFast (CategoryName t) (FunctionName fn) f2         return (os2,CompileOptions (maybeDisableHelp h) is is2 ds es ep p m2 f) where           check (t,"")     = return (t,defaultMainFunc)@@ -200,9 +215,9 @@    parseSingle (CompileOptions h is is2 ds es ep p m f) ((n,"-i"):os) = update os where     update ((n2,d):os2)-      | isSuffixOf ".0rp" d = argError n2 d "Cannot directly include .0rp source files."-      | isSuffixOf ".0rx" d = argError n2 d "Cannot directly include .0rx source files."-      | isSuffixOf ".0rt" d = argError n2 d "Cannot directly include .0rt test files."+      | isPublicSource  d = argError n2 d "Cannot directly include .0rp source files."+      | isPrivateSource d = argError n2 d "Cannot directly include .0rx source files."+      | isTestSource    d = argError n2 d "Cannot directly include .0rt test files."       | otherwise = do           checkPathName n2 d "-i"           return (os2,CompileOptions (maybeDisableHelp h) (is ++ [d]) is2 ds es ep p m f)@@ -210,9 +225,9 @@    parseSingle (CompileOptions h is is2 ds es ep p m f) ((n,"-I"):os) = update os where     update ((n2,d):os2)-      | isSuffixOf ".0rp" d = argError n2 d "Cannot directly include .0rp source files."-      | isSuffixOf ".0rx" d = argError n2 d "Cannot directly include .0rx source files."-      | isSuffixOf ".0rt" d = argError n2 d "Cannot directly include .0rt test files."+      | isPublicSource  d = argError n2 d "Cannot directly include .0rp source files."+      | isPrivateSource d = argError n2 d "Cannot directly include .0rx source files."+      | isTestSource    d = argError n2 d "Cannot directly include .0rt test files."       | otherwise = do           checkPathName n2 d "-i"           return (os2,CompileOptions (maybeDisableHelp h) is (is2 ++ [d]) ds es ep p m f)@@ -229,9 +244,9 @@   parseSingle _ ((n,o@('-':_)):_) = argError n o "Unknown option."    parseSingle (CompileOptions h is is2 ds es ep p m f) ((n,d):os)-      | isSuffixOf ".0rp" d = argError n d "Cannot directly include .0rp source files."-      | isSuffixOf ".0rx" d = argError n d "Cannot directly include .0rx source files."-      | isSuffixOf ".0rt" d = do+      | isPublicSource  d = argError n d "Cannot directly include .0rp source files."+      | isPrivateSource d = argError n d "Cannot directly include .0rx source files."+      | isTestSource    d = do         when (not $ isExecuteTests m) $           argError n d "Test mode (-t) must be enabled before listing any .0rt test files."         checkPathName n d ""
src/Cli/Programs.hs view
@@ -1,5 +1,5 @@ {- ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -32,9 +32,9 @@   class CompilerBackend b where-  runCxxCommand   :: (MonadIO m, ErrorContextM m) => b -> CxxCommand -> m FilePath-  runTestCommand  :: (MonadIO m, ErrorContextM m) => b -> TestCommand -> m TestCommandResult-  getCompilerHash :: b -> VersionHash+  runCxxCommand   :: (MonadIO m, CollectErrorsM m) => b -> CxxCommand -> m FilePath+  runTestCommand  :: (MonadIO m, CollectErrorsM m) => b -> TestCommand -> m TestCommandResult+  getCompilerHash :: (MonadIO m, CollectErrorsM m) => b -> m VersionHash  newtype VersionHash = VersionHash String deriving (Eq) 
src/Cli/RunCompiler.hs view
@@ -56,12 +56,11 @@     prepareCallLog (Just cl2) = do       clFull <- errorFromIO $ canonicalizePath (p </> cl2)       compilerWarningM $ "Logging calls to " ++ clFull-      errorFromIO $ writeFile clFull (intercalate "," (map show logHeader) ++ "\n")+      errorFromIO $ writeFile clFull (intercalate "," (map show tracesLogHeader) ++ "\n")       return clFull     prepareCallLog _ = return ""-    logHeader = ["microseconds","pid","function","context"]-    compilerHash = getCompilerHash backend     preloadTests (ca,ms) d = do+      compilerHash <- getCompilerHash backend       m <- loadModuleMetadata compilerHash f ca (p </> d)       let ca2 = ca `Map.union` mapMetadata [m]       rm <- loadRecompile (p </> d)@@ -71,7 +70,7 @@       deps2 <- loadPrivateDeps compilerHash f ca4 ([m]++deps1)       let ca5 = ca4 `Map.union` mapMetadata deps2       em <- getExprMap (p </> d) rm-      return (ca5,ms ++ [LoadedTests p d m em (deps1) deps2])+      return (ca5,ms ++ [LoadedTests m em (deps1) deps2])     checkTestFilters ts = do       let possibleTests = concat $ map (cmTestFiles . ltMetadata) ts       let remaining = filter (not . flip any (map (flip isSuffixOf) possibleTests). flip ($)) tp@@ -127,8 +126,8 @@   runRecompileCommon resolver backend f False p ds  runCompiler resolver backend (CompileOptions _ is is2 ds _ _ p CreateTemplates f) = mapM_ compileSingle ds where-  compilerHash = getCompilerHash backend   compileSingle d = do+    compilerHash <- getCompilerHash backend     d' <- errorFromIO $ canonicalizePath (p </> d)     (ep,is',is2') <- maybeUseConfig d'     as  <- fmap fixPaths $ mapCompilerM (resolveModule resolver d') is'@@ -188,20 +187,17 @@     teContext :: String   } +tracesLogHeader :: [String]+tracesLogHeader = ["microseconds","pid","function","context"]+ parseTracesFile :: (FilePath,String) -> TrackedErrorsIO [TraceEntry] parseTracesFile (f,s) = runTextParser (between nullParse endOfDoc tracesFile) f s where   tracesFile =  do     parseHeader     many parseSingle   parseHeader = do-    _ <- quotedString-    string_ ","-    _ <- quotedString-    string_ ","-    _ <- quotedString-    string_ ","-    _ <- quotedString-    many (char '\n' <|> char '\n') >> return ()+    sequence_ $ intercalate [string_ ","] $ map ((:[]) . parseColTitle) tracesLogHeader+    some (char '\n' <|> char '\r') >> return ()   parseSingle = do     ms <- parseDec     string_ ","@@ -210,15 +206,17 @@     func <- quotedString     string_ ","     c <- quotedString-    many (char '\n' <|> char '\n') >> return ()+    some (char '\n' <|> char '\r') >> return ()     return $ TraceEntry ms pid func c+  parseColTitle expected = do+    title <- quotedString+    when (expected /= title) $ compilerErrorM $ "Expected column named \"" ++ expected ++ "\" but found \"" ++ title ++ "\""  runRecompileCommon :: (PathIOHandler r, CompilerBackend b) => r -> b ->   ForceMode -> Bool -> FilePath -> [FilePath] -> TrackedErrorsIO () runRecompileCommon resolver backend f rec p ds = do   explicit <- fmap Set.fromList $ mapCompilerM (errorFromIO . canonicalizePath . (p </>)) ds   foldM (recursive resolver explicit) Set.empty (map ((,) p) ds) >> return () where-    compilerHash = getCompilerHash backend     recursive r explicit da (p2,d0) = do       d <- resolveModule r p2 d0       isSystem <- isSystemModule r p2 d0@@ -234,6 +232,7 @@            recompile d            return da'     recompile d = do+      compilerHash <- getCompilerHash backend       upToDate <- isPathUpToDate compilerHash f d       if f < ForceAll && upToDate          then compilerWarningM $ "Path " ++ d ++ " is up to date"
src/Compilation/ScopeContext.hs view
@@ -110,6 +110,7 @@       mapCompilerM_ (\v -> compilerErrorM $ "Member " ++ show v ++                                             " does not exist (marked Hidden at " ++                                             formatFullContext c2 ++ ")") missing+    checkPragma _ = return ()     allMembers = Set.fromList $ map dmName ms     valueMembers = map dmName $ filter ((== ValueScope) . dmScope) ms     immutableContext t = head $ (map ciContext $ filter isCategoryImmutable (getCategoryPragmas t)) ++ [[]]
src/CompilerCxx/Code.hs view
@@ -189,22 +189,22 @@  useAsArgs :: ExpressionValue -> String useAsArgs (OpaqueMulti e)                 = e-useAsArgs (WrappedSingle e)               = "ArgTuple(" ++ e ++ ")"-useAsArgs (UnwrappedSingle e)             = "ArgTuple(" ++ e ++ ")"-useAsArgs (BoxedPrimitive PrimBool e)     = "ArgTuple(Box_Bool(" ++ e ++ "))"-useAsArgs (BoxedPrimitive PrimString e)   = "ArgTuple(Box_String(" ++ e ++ "))"-useAsArgs (BoxedPrimitive PrimChar e)     = "ArgTuple(Box_Char(" ++ e ++ "))"-useAsArgs (BoxedPrimitive PrimInt e)      = "ArgTuple(Box_Int(" ++ e ++ "))"-useAsArgs (BoxedPrimitive PrimFloat e)    = "ArgTuple(Box_Float(" ++ e ++ "))"-useAsArgs (UnboxedPrimitive PrimBool e)   = "ArgTuple(Box_Bool(" ++ e ++ "))"-useAsArgs (UnboxedPrimitive PrimString e) = "ArgTuple(Box_String(" ++ e ++ "))"-useAsArgs (UnboxedPrimitive PrimChar e)   = "ArgTuple(Box_Char(" ++ e ++ "))"-useAsArgs (UnboxedPrimitive PrimInt e)    = "ArgTuple(Box_Int(" ++ e ++ "))"-useAsArgs (UnboxedPrimitive PrimFloat e)  = "ArgTuple(Box_Float(" ++ e ++ "))"+useAsArgs (WrappedSingle e)               = e+useAsArgs (UnwrappedSingle e)             = e+useAsArgs (BoxedPrimitive PrimBool e)     = "Box_Bool(" ++ e ++ ")"+useAsArgs (BoxedPrimitive PrimString e)   = "Box_String(" ++ e ++ ")"+useAsArgs (BoxedPrimitive PrimChar e)     = "Box_Char(" ++ e ++ ")"+useAsArgs (BoxedPrimitive PrimInt e)      = "Box_Int(" ++ e ++ ")"+useAsArgs (BoxedPrimitive PrimFloat e)    = "Box_Float(" ++ e ++ ")"+useAsArgs (UnboxedPrimitive PrimBool e)   = "Box_Bool(" ++ e ++ ")"+useAsArgs (UnboxedPrimitive PrimString e) = "Box_String(" ++ e ++ ")"+useAsArgs (UnboxedPrimitive PrimChar e)   = "Box_Char(" ++ e ++ ")"+useAsArgs (UnboxedPrimitive PrimInt e)    = "Box_Int(" ++ e ++ ")"+useAsArgs (UnboxedPrimitive PrimFloat e)  = "Box_Float(" ++ e ++ ")" useAsArgs (LazySingle e)                  = useAsArgs $ getFromLazy e  useAsUnwrapped :: ExpressionValue -> String-useAsUnwrapped (OpaqueMulti e)                 = "(" ++ e ++ ").Only()"+useAsUnwrapped (OpaqueMulti e)                 = "(" ++ e ++ ").At(0)" useAsUnwrapped (WrappedSingle e)               = e useAsUnwrapped (UnwrappedSingle e)             = e useAsUnwrapped (BoxedPrimitive PrimBool e)     = "Box_Bool(" ++ e ++ ")"@@ -220,11 +220,11 @@ useAsUnwrapped (LazySingle e)                  = useAsUnwrapped $ getFromLazy e  useAsUnboxed :: PrimitiveType -> ExpressionValue -> String-useAsUnboxed PrimBool   (OpaqueMulti e)     = "(" ++ e ++ ").Only().AsBool()"-useAsUnboxed PrimString (OpaqueMulti e)     = "(" ++ e ++ ").Only().AsString()"-useAsUnboxed PrimChar   (OpaqueMulti e)     = "(" ++ e ++ ").Only().AsChar()"-useAsUnboxed PrimInt    (OpaqueMulti e)     = "(" ++ e ++ ").Only().AsInt()"-useAsUnboxed PrimFloat  (OpaqueMulti e)     = "(" ++ e ++ ").Only().AsFloat()"+useAsUnboxed PrimBool   (OpaqueMulti e)     = "(" ++ e ++ ").At(0).AsBool()"+useAsUnboxed PrimString (OpaqueMulti e)     = "(" ++ e ++ ").At(0).AsString()"+useAsUnboxed PrimChar   (OpaqueMulti e)     = "(" ++ e ++ ").At(0).AsChar()"+useAsUnboxed PrimInt    (OpaqueMulti e)     = "(" ++ e ++ ").At(0).AsInt()"+useAsUnboxed PrimFloat  (OpaqueMulti e)     = "(" ++ e ++ ").At(0).AsFloat()" useAsUnboxed PrimBool   (WrappedSingle e)   = "(" ++ e ++ ").AsBool()" useAsUnboxed PrimString (WrappedSingle e)   = "(" ++ e ++ ").AsString()" useAsUnboxed PrimChar   (WrappedSingle e)   = "(" ++ e ++ ").AsChar()"@@ -251,7 +251,7 @@ valueAsWrapped v                               = v  valueAsUnwrapped :: ExpressionValue -> ExpressionValue-valueAsUnwrapped (OpaqueMulti e)                 = UnwrappedSingle $ "(" ++ e ++ ").Only()"+valueAsUnwrapped (OpaqueMulti e)                 = UnwrappedSingle $ "(" ++ e ++ ").At(0)" valueAsUnwrapped (WrappedSingle e)               = UnwrappedSingle e valueAsUnwrapped (UnboxedPrimitive PrimBool e)   = UnwrappedSingle $ "Box_Bool(" ++ e ++ ")" valueAsUnwrapped (UnboxedPrimitive PrimString e) = UnwrappedSingle $ "Box_String(" ++ e ++ ")"
src/CompilerCxx/CxxFiles.hs view
@@ -31,6 +31,7 @@   generateVerboseExtension, ) where +import Control.Arrow (second) import Data.List (intercalate,sortBy) import Data.Hashable (hash) import Prelude hiding (pi)@@ -424,6 +425,7 @@   defineConcreteValue r params fs t d = concatM [       return $ onlyCode $ "struct " ++ valueName (getCategoryName t) ++ " : public " ++ valueBase ++ " {",       fmap indentCompiled $ inlineValueConstructor t d,+      fmap indentCompiled $ inlineFlatCleanup d,       return declareValueOverrides,       fmap indentCompiled $ concatM $ map (declareProcedure t False) fs,       fmap indentCompiled $ concatM $ map (createMember r params t) members,@@ -495,23 +497,23 @@    declareCategoryOverrides = onlyCodes [       "  std::string CategoryName() const final;",-      "  ReturnTuple Dispatch(const CategoryFunction& label, const ParamTuple& params, const ValueTuple& args) final;"+      "  ReturnTuple Dispatch(const CategoryFunction& label, const ParamsArgs& params_args) final;"     ]   declareTypeOverrides = onlyCodes [       "  std::string CategoryName() const final;",       "  void BuildTypeName(std::ostream& output) const final;",       "  bool TypeArgsForParent(const CategoryId& category, std::vector<S<const TypeInstance>>& args) const final;",-      "  ReturnTuple Dispatch(const TypeFunction& label, const ParamTuple& params, const ValueTuple& args) const final;",+      "  ReturnTuple Dispatch(const TypeFunction& label, const ParamsArgs& params_args) const final;",       "  bool CanConvertFrom(const S<const TypeInstance>& from) const final;"     ]   declareValueOverrides = onlyCodes [       "  std::string CategoryName() const final;",-      "  ReturnTuple Dispatch(const ValueFunction& label, const ParamTuple& params, const ValueTuple& args) final;"+      "  ReturnTuple Dispatch(const ValueFunction& label, const ParamsArgs& params_args) final;"     ]    defineCategoryOverrides t fs = return $ mconcat [       onlyCode $ "std::string " ++ className ++ "::CategoryName() const { return \"" ++ show (getCategoryName t) ++ "\"; }",-      onlyCode $ "ReturnTuple " ++ className ++ "::Dispatch(const CategoryFunction& label, const ParamTuple& params, const ValueTuple& args) {",+      onlyCode $ "ReturnTuple " ++ className ++ "::Dispatch(const CategoryFunction& label, const ParamsArgs& params_args) {",       createFunctionDispatch t CategoryScope fs,       onlyCode "}"     ] where@@ -524,7 +526,7 @@       onlyCode $ "bool " ++ className ++ "::TypeArgsForParent(const CategoryId& category, std::vector<S<const TypeInstance>>& args) const {",       createTypeArgsForParent t,       onlyCode $ "}",-      onlyCode $ "ReturnTuple " ++ className ++ "::Dispatch(const TypeFunction& label, const ParamTuple& params, const ValueTuple& args) const {",+      onlyCode $ "ReturnTuple " ++ className ++ "::Dispatch(const TypeFunction& label, const ParamsArgs& params_args) const {",       createFunctionDispatch t TypeScope fs,       onlyCode $ "}",       onlyCode $ "bool " ++ className ++ "::CanConvertFrom(const S<const TypeInstance>& from) const {",@@ -535,7 +537,7 @@       params = map vpParam $ getCategoryParams t   defineValueOverrides t fs = return $ mconcat [       onlyCode $ "std::string " ++ className ++ "::CategoryName() const { return parent->CategoryName(); }",-      onlyCode $ "ReturnTuple " ++ className ++ "::Dispatch(const ValueFunction& label, const ParamTuple& params, const ValueTuple& args) {",+      onlyCode $ "ReturnTuple " ++ className ++ "::Dispatch(const ValueFunction& label, const ParamsArgs& params_args) {",       createFunctionDispatch t ValueScope fs,       onlyCode $ "}"     ] where@@ -587,16 +589,31 @@         prefix ++ "~" ++ typeName (getCategoryName t) ++ "() { " ++ typeRemover (getCategoryName t) ++ "(" ++ params ++ "); }"       ] +  inlineFlatCleanup d = do+    let pragmas = filter isFlatCleanup $ dcPragmas d+    handle pragmas where+      handle [] = return emptyCode+      handle [FlatCleanup c v] = do+        let ms = filter ((== v) . dmName) members+        case ms of+             [m] -> return $ onlyCode $ "BoxedValue FlatCleanup() final { return std::move(" ++ variableName (dmName m) ++ "); }"+             _ -> compilerErrorM $ "FlatCleanup requires a non-weak boxed member" ++ formatFullContextBrace c+      handle ps = "Only one FlatCleanup is allowed" !!>+        (mapErrorsM $ map (\p -> "FlatCleanup using " ++ show (fcMember p) ++ formatFullContextBrace (fcContext p)) ps)+      members = filter ((/= WeakValue) . vtRequired . dmType) $+                filter (not . isStoredUnboxed . dmType) $+                filter ((== ValueScope) . dmScope) $ dcMembers d+   inlineValueConstructor t d = do     let argParent = "S<const " ++ typeName (getCategoryName t) ++ "> p"-    let argsPassed = "const ValueTuple& args"+    let argsPassed = "const ParamsArgs& params_args"     let allArgs = intercalate ", " [argParent,argsPassed]     let initParent = "parent(p)"     let initArgs = map (\(i,m) -> variableName (dmName m) ++ "(" ++ unwrappedArg i m ++ ")") $ zip ([0..] :: [Int]) members     let allInit = intercalate ", " $ initParent:initArgs     return $ onlyCode $ "inline " ++ valueName (getCategoryName t) ++ "(" ++ allArgs ++ ") : " ++ allInit ++ " {}" where-      unwrappedArg i m = writeStoredVariable (dmType m) (UnwrappedSingle $ "args.At(" ++ show i ++ ")")-      members = filter ((== ValueScope). dmScope) $ dcMembers d+      unwrappedArg i m = writeStoredVariable (dmType m) (UnwrappedSingle $ "params_args.GetArg(" ++ show i ++ ")")+      members = filter ((== ValueScope) . dmScope) $ dcMembers d    abstractValueConstructor t = do     let argParent = "S<const " ++ typeName (getCategoryName t) ++ "> p"@@ -614,7 +631,7 @@     return $ onlyCode $ "inline " ++ typeCustom (getCategoryName t) ++ "(" ++ allArgs ++ ") : " ++ allInit ++ " {}"   customValueConstructor t = do     let argParent = "S<const " ++ typeName (getCategoryName t) ++ "> p"-    let argsPassed = "const ValueTuple& args"+    let argsPassed = "const ParamsArgs& params_args"     let allArgs = intercalate ", " [argParent,argsPassed]     let allInit = valueName (getCategoryName t) ++ "(std::move(p))"     return $ onlyCode $ "inline " ++ valueCustom (getCategoryName t) ++ "(" ++ allArgs ++ ") : " ++ allInit ++ " {}"@@ -745,18 +762,18 @@   name = getCategoryName t   function     | null filtered = onlyCode fallback-    | otherwise = onlyCodes $ [typedef] ++ concat (map table $ byCategory) ++ select+    | otherwise = onlyCodes $ [typedef] ++ select   filtered = filter ((== s) . sfScope) fs   flatten f = f:(concat $ map flatten $ sfMerges f)   flattened = concat $ map flatten filtered-  byCategory = Map.toList $ Map.fromListWith (++) $ map (\f -> (sfType f,[f])) flattened+  byCategory = map (second Set.toList) $ Map.toList $ Map.fromListWith Set.union $ map (\f -> (sfType f,Set.fromList [sfName f])) flattened   typedef     | s == CategoryScope = "  using CallType = ReturnTuple(" ++ categoryName name ++-                           "::*)(const ParamTuple&, const ValueTuple&);"+                           "::*)(const ParamsArgs&);"     | s == TypeScope     = "  using CallType = ReturnTuple(" ++ typeName name ++-                           "::*)(const ParamTuple&, const ValueTuple&) const;"+                           "::*)(const ParamsArgs&) const;"     | s == ValueScope    = "  using CallType = ReturnTuple(" ++ valueName name ++-                           "::*)(const ParamTuple&, const ValueTuple&)" ++ suffix ++ ";"+                           "::*)(const ParamsArgs&)" ++ suffix ++ ";"     | otherwise = undefined   suffix     | isImmutable t = " const"@@ -766,11 +783,6 @@     | s == TypeScope     = typeName name     ++ "::" ++ callName f     | s == ValueScope    = valueName name    ++ "::" ++ callName f     | otherwise = undefined-  table (_,[_]) = []-  table (n2,fs2) =-    ["  static const CallType " ++ tableName n2 ++ "[] = {"] ++-    map (\f -> "    &" ++ funcName f ++ ",") (Set.toList $ Set.fromList $ map sfName fs2) ++-    ["  };"]   select = [       "  switch (label.collection) {"     ] ++ categoryCases ++ [@@ -781,21 +793,25 @@   categoryCases = concat $ map singleCase byCategory   singleCase (n2,[f]) = [       "    case " ++ categoryIdName n2 ++ ":",-      "      return " ++ callName (sfName f) ++ "(" ++ args ++ ");"+      "      // " ++ show n2 ++ " only has one " ++ show s ++ " function.",+      "      return " ++ callName f ++ "(" ++ args ++ ");"     ]-  singleCase (n2,_) = [+  singleCase (n2,fs2) = [       "    case " ++ categoryIdName n2 ++ ":",+      "      static const CallType " ++ tableName n2 ++ "[] = {"+    ] ++ map (\f -> "        &" ++ funcName f ++ ",") fs2 ++ [+      "      };",       "      return (this->*" ++ tableName n2 ++ "[label.function_num])(" ++ args ++ ");"     ]   args-    | s == CategoryScope = "params, args"-    | s == TypeScope     = "params, args"-    | s == ValueScope    = "params, args"+    | s == CategoryScope = "params_args"+    | s == TypeScope     = "params_args"+    | s == ValueScope    = "params_args"     | otherwise = undefined   fallback-    | s == CategoryScope = "  return TypeCategory::Dispatch(label, params, args);"-    | s == TypeScope     = "  return TypeInstance::Dispatch(label, params, args);"-    | s == ValueScope    = "  return TypeValue::Dispatch(label, params, args);"+    | s == CategoryScope = "  return TypeCategory::Dispatch(label, params_args);"+    | s == TypeScope     = "  return TypeInstance::Dispatch(label, params_args);"+    | s == ValueScope    = "  return TypeValue::Dispatch(label, params_args);"     | otherwise = undefined  createCanConvertFrom :: AnyCategory c -> CompiledData [String]@@ -937,7 +953,7 @@   onlyCodes [       "BoxedValue " ++ valueCreator (getCategoryName t) ++       "(S<const " ++ typeName (getCategoryName t) ++ "> parent, " ++-      "const ValueTuple& args);"+      "const ParamsArgs& params_args);"     ]  defineInternalValue :: AnyCategory c -> CompiledData [String]@@ -948,8 +964,8 @@   onlyCodes [       "BoxedValue " ++ valueCreator (getCategoryName t) ++       "(S<const " ++ typeName (getCategoryName t) ++ "> parent, " ++-      "const ValueTuple& args) {",-      "  return BoxedValue::New<" ++ className ++ ">(std::move(parent), args);",+      "const ParamsArgs& params_args) {",+      "  return BoxedValue::New<" ++ className ++ ">(std::move(parent), params_args);",       "}"     ] 
src/CompilerCxx/Procedure.hs view
@@ -73,11 +73,11 @@     | otherwise = ""   proto     | sfScope f == CategoryScope =-      "ReturnTuple " ++ name ++ "(const ParamTuple& params, const ValueTuple& args)"+      "ReturnTuple " ++ name ++ "(const ParamsArgs& params_args)"     | sfScope f == TypeScope =-      "ReturnTuple " ++ name ++ "(const ParamTuple& params, const ValueTuple& args) const"+      "ReturnTuple " ++ name ++ "(const ParamsArgs& params_args) const"     | sfScope f == ValueScope =-      "ReturnTuple " ++ name ++ "(const ParamTuple& params, const ValueTuple& args)" ++ suffix+      "ReturnTuple " ++ name ++ "(const ParamsArgs& params_args)" ++ suffix     | otherwise = undefined  data CxxFunctionType =@@ -132,11 +132,11 @@       | otherwise = ""     proto       | s == CategoryScope =-        "ReturnTuple " ++ prefix ++ name ++ "(const ParamTuple& params, const ValueTuple& args)" ++ final ++ " {"+        "ReturnTuple " ++ prefix ++ name ++ "(const ParamsArgs& params_args)" ++ final ++ " {"       | s == TypeScope =-        "ReturnTuple " ++ prefix ++ name ++ "(const ParamTuple& params, const ValueTuple& args) const" ++ final ++ " {"+        "ReturnTuple " ++ prefix ++ name ++ "(const ParamsArgs& params_args) const" ++ final ++ " {"       | s == ValueScope =-        "ReturnTuple " ++ prefix ++ name ++ "(const ParamTuple& params, const ValueTuple& args)" ++ suffix ++ final ++ " {"+        "ReturnTuple " ++ prefix ++ name ++ "(const ParamsArgs& params_args)" ++ suffix ++ final ++ " {"       | otherwise = undefined     setProcedureTrace       | any isNoTrace pragmas = return []@@ -151,12 +151,12 @@       | isUnnamedReturns rs2 = []       | otherwise            = ["ReturnTuple returns(" ++ show (length $ pValues rs1) ++ ");"]     nameParams = flip map (zip ([0..] :: [Int]) $ pValues ps1) $-      (\(i,p2) -> paramType ++ " " ++ paramName (vpParam p2) ++ " = params.At(" ++ show i ++ ");")+      (\(i,p2) -> paramType ++ " " ++ paramName (vpParam p2) ++ " = params_args.GetParam(" ++ show i ++ ");")     nameArgs = map nameSingleArg (zip ([0..] :: [Int]) $ zip (pValues as1) (pValues $ avNames as2))     nameSingleArg (i,(t2,n2))       | isDiscardedInput n2 = "// Arg " ++ show i ++ " (" ++ show (pvType t2) ++ ") is discarded"       | otherwise = "const " ++ variableProxyType (pvType t2) ++ " " ++ variableName (ivName n2) ++-                    " = " ++ writeStoredVariable (pvType t2) (UnwrappedSingle $ "args.At(" ++ show i ++ ")") ++ ";"+                    " = " ++ writeStoredVariable (pvType t2) (UnwrappedSingle $ "params_args.GetArg(" ++ show i ++ ")") ++ ";"     nameReturns       | isUnnamedReturns rs2 = []       | otherwise = map (\(i,(t2,n2)) -> nameReturn i (pvType t2) n2) (zip ([0..] :: [Int]) $ zip (pValues rs1) (pValues $ nrNames rs2))@@ -719,6 +719,13 @@     t' <- requireSingle c ts     f' <- lookupValueFunction t' f     compileFunctionCall (Just $ useAsUnwrapped e') f' f+  transform e (SelectReturn c pos) = do+    (Positional ts,e') <- e+    when (not $ isOpaqueMulti e') $+      compilerErrorM $ "Return selection can only be used with function returns" ++ formatFullContextBrace c+    when (pos >= length ts) $+      compilerErrorM $ "Position " ++ show pos ++ " exceeds return count " ++ show (length ts) ++ formatFullContext c+    return (Positional [ts !! pos],WrappedSingle $ useAsReturns e' ++ ".At(" ++ show pos ++ ")")   requireSingle _ [t] = return t   requireSingle c2 ts =     compilerErrorM $ "Function call requires 1 return but found but found {" ++@@ -902,7 +909,7 @@   let typeInstance = getType t' sameType s params   -- TODO: This is unsafe if used in a type or category constructor.   return (Positional [ValueType RequiredValue $ singleType $ JustTypeInstance t'],-          UnwrappedSingle $ valueCreator (tiName t') ++ "(" ++ typeInstance ++ ", " ++ es'' ++ ")")+          UnwrappedSingle $ valueCreator (tiName t') ++ "(" ++ typeInstance ++ ", PassParamsArgs(" ++ es'' ++ "))")   where     getType _  True ValueScope _      = "parent"     getType _  True TypeScope  _      = "PARAM_SELF"@@ -913,8 +920,7 @@     getValues rs = do       (mapCompilerM_ checkArity $ zip ([0..] :: [Int]) $ map fst rs) <??         "In return at " ++ formatFullContext c-      return (map (head . pValues . fst) rs,-              "ArgTuple(" ++ intercalate ", " (map (useAsUnwrapped . snd) rs) ++ ")")+      return (map (head . pValues . fst) rs, intercalate ", " (map (useAsUnwrapped . snd) rs))     checkArity (_,Positional [_]) = return ()     checkArity (i,Positional ts)  =       compilerErrorM $ "Initializer position " ++ show i ++ " has " ++ show (length ts) ++ " values but should have 1"@@ -972,12 +978,15 @@   fa <- csAllFilters   es' <- sequence $ map compileExpression $ pValues es   (ts,es'') <- lift $ getValues es'+  f' <- lift $ parsedToFunctionType f+  let psActual = case ps of+                      (Positional []) -> Positional $ take (length $ pValues $ ftParams f') $ repeat (InferredInstance c)+                      _ -> ps   self <- autoSelfType-  ps' <- lift $ fmap Positional $ mapCompilerM (replaceSelfParam self) $ pValues ps+  ps' <- lift $ fmap Positional $ mapCompilerM (replaceSelfParam self) $ pValues psActual   ps2 <- lift $ guessParamsFromArgs r fa f ps' (Positional ts)-  lift $ mapCompilerM_ backgroundMessage $ zip3 (map vpParam $ pValues $ sfParams f) (pValues ps') (pValues ps2)-  f' <- lift $ parsedToFunctionType f   f'' <- lift $ assignFunctionParams r fa Map.empty ps2 f'+  lift $ mapCompilerM_ backgroundMessage $ zip3 (map vpParam $ pValues $ sfParams f) (pValues ps') (pValues ps2)   -- Called an extra time so arg count mismatches have reasonable errors.   lift $ processPairs_ (\_ _ -> return ()) (ftArgs f'') (Positional ts)   lift $ processPairs_ (checkArg r fa) (ftArgs f'') (Positional $ zip ([0..] :: [Int]) ts)@@ -998,28 +1007,29 @@       compilerBackgroundM $ "Parameter " ++ show n ++ " (from " ++ show (sfType f) ++ "." ++         show (sfName f) ++ ") inferred as " ++ show t ++ " at " ++ formatFullContext c2     backgroundMessage _ = return ()+    joinParamsArgs ps2 es2 = "PassParamsArgs(" ++ intercalate ", " (ps2 ++ es2) ++ ")"     assemble Nothing _ ValueScope ValueScope ps2 es2 =-      return $ callName (sfName f) ++ "(" ++ ps2 ++ ", " ++ es2 ++ ")"+      return $ callName (sfName f) ++ "(" ++ joinParamsArgs ps2 es2 ++ ")"     assemble Nothing _ TypeScope TypeScope ps2 es2 =-      return $ callName (sfName f) ++ "(" ++ ps2 ++ ", " ++ es2 ++ ")"+      return $ callName (sfName f) ++ "(" ++ joinParamsArgs ps2 es2 ++ ")"     assemble Nothing scoped ValueScope TypeScope ps2 es2 =-      return $ scoped ++ callName (sfName f) ++ "(" ++ ps2 ++ ", " ++ es2 ++ ")"+      return $ scoped ++ callName (sfName f) ++ "(" ++ joinParamsArgs ps2 es2 ++ ")"     assemble Nothing scoped _ _ ps2 es2 =-      return $ scoped ++ callName (sfName f) ++ "(" ++ ps2 ++ ", " ++ es2 ++ ")"+      return $ scoped ++ callName (sfName f) ++ "(" ++ joinParamsArgs ps2 es2 ++ ")"     assemble (Just e2) _ _ ValueScope ps2 es2 =-      return $ valueBase ++ "::Call(" ++ e2 ++ ", " ++ functionName f ++ ", " ++ ps2 ++ ", " ++ es2 ++ ")"+      return $ valueBase ++ "::Call(" ++ e2 ++ ", " ++ functionName f ++ ", " ++ joinParamsArgs ps2 es2 ++ ")"     assemble (Just e2) _ _ TypeScope ps2 es2 =-      return $ typeBase ++ "::Call(" ++ e2 ++ ", " ++ functionName f ++ ", " ++ ps2 ++ ", " ++ es2 ++ ")"+      return $ typeBase ++ "::Call(" ++ e2 ++ ", " ++ functionName f ++ ", " ++ joinParamsArgs ps2 es2 ++ ")"     assemble (Just e2) _ _ _ ps2 es2 =-      return $ e2 ++ ".Call(" ++ functionName f ++ ", " ++ ps2 ++ ", " ++ es2 ++ ")"+      return $ e2 ++ ".Call(" ++ functionName f ++ ", " ++ joinParamsArgs ps2 es2 ++ ")"     -- TODO: Lots of duplication with assignments and initialization.     -- Single expression, but possibly multi-return.-    getValues [(Positional ts,e2)] = return (ts,useAsArgs e2)+    getValues [(Positional ts,e2)] = return (ts,[useAsArgs e2])     -- Multi-expression => must all be singles.     getValues rs = do       (mapCompilerM_ checkArity $ zip ([0..] :: [Int]) $ map fst rs) <??         "In return at " ++ formatFullContext c-      return (map (head . pValues . fst) rs, "ArgTuple(" ++ intercalate ", " (map (useAsUnwrapped . snd) rs) ++ ")")+      return (map (head . pValues . fst) rs,map (useAsUnwrapped . snd) rs)     checkArity (_,Positional [_]) = return ()     checkArity (i,Positional ts)  =       compilerErrorM $ "Return position " ++ show i ++ " has " ++ show (length ts) ++ " values but should have 1"@@ -1152,10 +1162,8 @@   return $ "T_get(" ++ intercalate ", " ps' ++ ")"  expandParams2 :: (CollectErrorsM m, CompilerContext c m s a) =>-  Positional GeneralInstance -> CompilerState a m String-expandParams2 ps = do-  ps' <- sequence $ map expandGeneralInstance $ pValues ps-  return $ "ParamTuple(" ++ intercalate "," ps' ++ ")"+  Positional GeneralInstance -> CompilerState a m [String]+expandParams2 ps = sequence $ map expandGeneralInstance $ pValues ps  expandCategory :: CompilerContext c m s a =>   CategoryName -> CompilerState a m String
+ src/Config/CompilerConfig.hs view
@@ -0,0 +1,50 @@+{- -----------------------------------------------------------------------------+Copyright 2020-2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- -}++-- Author: Kevin P. Barry [ta0kira@gmail.com]++{-# LANGUAGE Safe #-}++module Config.CompilerConfig (+  Backend(..),+  LocalConfig(..),+  Resolver(..),+) where+++data LocalConfig =+  LocalConfig {+    lcResolver :: Resolver,+    lcBackend :: Backend+  }+  deriving (Eq,Show)++data Backend =+  UnixBackend {+    ucCxxBinary :: FilePath,+    ucCompileFlags :: [String],+    ucLibraryFlags :: [String],+    ucBinaryFlags :: [String],+    ucArBinary :: FilePath+  }+  deriving (Eq,Show)++data Resolver =+  SimpleResolver {+    srVisibleSystem :: [FilePath],+    srExtraPaths :: [FilePath]+  }+  deriving (Eq,Show)
src/Config/LoadConfig.hs view
@@ -1,5 +1,5 @@ {- ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -16,39 +16,45 @@  -- Author: Kevin P. Barry [ta0kira@gmail.com] -{-# LANGUAGE Safe #-}- module Config.LoadConfig (   localConfigPath,   loadConfig,+  saveConfig, ) where  import Control.Monad (when) import Control.Monad.IO.Class import System.Directory+import System.IO  import Base.CompilerError import Config.LocalConfig+import Config.ParseConfig ()+import Module.ParseMetadata  import Paths_zeolite_lang (getDataFileName)  -loadConfig :: (MonadIO m, ErrorContextM m) => m (Resolver,Backend)+saveConfig :: (MonadIO m, CollectErrorsM m) => (Resolver,Backend) -> m ()+saveConfig (resolver,backend) = do+  configFile <- liftIO localConfigPath+  liftIO $ hPutStrLn stderr $ "Writing local config to " ++ configFile ++ "."+  serialized <- autoWriteConfig (LocalConfig resolver backend)+  liftIO $ writeFile configFile serialized++loadConfig :: (MonadIO m, CollectErrorsM m) => m (Resolver,Backend) loadConfig = do   configFile <- liftIO localConfigPath   isFile <- liftIO $ doesFileExist configFile   when (not isFile) $ compilerErrorM "Zeolite has not been configured. Please run zeolite-setup."   configString <- liftIO $ readFile configFile-  lc <- check $ (reads configString :: [(LocalConfig,String)])+  lc <- autoReadConfig configFile configString <!! "Zeolite configuration is corrupt. Please rerun zeolite-setup."   pathsFile   <- liftIO $ globalPathsPath   pathsExists <- liftIO $ doesFileExist pathsFile   paths <- if pathsExists               then liftIO $ readFile pathsFile >>= return . lines               else return []-  return (addPaths (lcResolver lc) paths,lcBackend lc) where-    check [(cm,"")]   = return cm-    check [(cm,"\n")] = return cm-    check _ = compilerErrorM "Zeolite configuration is corrupt. Please rerun zeolite-setup."+  return (addPaths (lcResolver lc) paths,lcBackend lc)  localConfigPath :: IO FilePath localConfigPath = getDataFileName localConfigFilename >>= canonicalizePath
src/Config/LocalConfig.hs view
@@ -1,5 +1,5 @@ {- ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -16,8 +16,6 @@  -- Author: Kevin P. Barry [ta0kira@gmail.com] -{-# LANGUAGE Safe #-}- module Config.LocalConfig (   Backend(..),   LocalConfig(..),@@ -43,35 +41,14 @@  import Base.CompilerError import Cli.Programs+import Config.CompilerConfig+import Config.ParseConfig ()+import Module.ParseMetadata import Module.Paths  import Paths_zeolite_lang (getDataFileName,version)  -data Backend =-  UnixBackend {-    ucCxxBinary :: FilePath,-    ucCompileFlags :: [String],-    ucLibraryFlags :: [String],-    ucBinaryFlags :: [String],-    ucArBinary :: FilePath-  }-  deriving (Read,Show)--data Resolver =-  SimpleResolver {-    srVisibleSystem :: [FilePath],-    srExtraPaths :: [FilePath]-  }-  deriving (Read,Show)--data LocalConfig =-  LocalConfig {-    lcBackend :: Backend,-    lcResolver :: Resolver-  }-  deriving (Read,Show)- rootPath :: IO FilePath rootPath = getDataFileName "" @@ -129,8 +106,10 @@         hDuplicateTo h1 stdout         hDuplicateTo h2 stderr         executeFile b True as Nothing-  getCompilerHash b = VersionHash $ flip showHex "" $ abs $ hash $ minorVersion ++ show b where-    minorVersion = show $ take 3 $ versionBranch version+  getCompilerHash b = do+    let minorVersion = show $ take 3 $ versionBranch version+    serialized <- autoWriteConfig b+    return $ VersionHash $ flip showHex "" $ abs $ hash $ minorVersion ++ serialized  executeProcess :: (MonadIO m, ErrorContextM m) => String -> [String] -> m () executeProcess c os = do
+ src/Config/ParseConfig.hs view
@@ -0,0 +1,86 @@+{- -----------------------------------------------------------------------------+Copyright 2020-2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- -}++-- Author: Kevin P. Barry [ta0kira@gmail.com]++module Config.ParseConfig (+) where++import Control.Applicative.Permutations++import Config.CompilerConfig+import Module.ParseMetadata+import Parser.Common+++instance ConfigFormat Backend where+  readConfig = do+    sepAfter (string_ "unix_backend")+    structOpen+    o <- runPermutation $ UnixBackend+      <$> parseRequired "cxx_binary:"    parseQuoted+      <*> parseRequired "compile_flags:" (parseList parseQuoted)+      <*> parseRequired "library_flags:" (parseList parseQuoted)+      <*> parseRequired "binary_flags:"  (parseList parseQuoted)+      <*> parseRequired "ar_binary:"     parseQuoted+    structClose+    return o+  writeConfig (UnixBackend cb cf lf bf ar) = do+    return $ [+        "unix_backend {",+        indent $ "cxx_binary: " ++ show cb,+        indent "compile_flags: ["+      ] ++ (indents . indents) (map show cf) ++ [+        indent "]",+        indent "library_flags: ["+      ] ++ (indents . indents) (map show lf) ++ [+        indent "]",+        indent "binary_flags: ["+      ] ++ (indents . indents) (map show bf) ++ [+        indent "]",+        indent $ "ar_binary: " ++ show ar,+        "}"+      ]++instance ConfigFormat Resolver where+  readConfig = do+    sepAfter (string_ "simple_resolver")+    structOpen+    o <- runPermutation $ SimpleResolver+      <$> parseRequired "system_allowed:" (parseList parseQuoted)+      <*> parseRequired "extra_paths:"    (parseList parseQuoted)+    structClose+    return o+  writeConfig (SimpleResolver ss es) = do+    return $ [+        "simple_resolver {",+        indent "system_allowed: ["+      ] ++ (indents . indents) (map show ss) ++ [+        indent "]",+        indent "extra_paths: ["+      ] ++ (indents . indents) (map show es) ++ [+        indent "]",+        "}"+      ]++instance ConfigFormat LocalConfig where+  readConfig = runPermutation $ LocalConfig+    <$> parseRequired "resolver:" readConfig+    <*> parseRequired "backend:"  readConfig+  writeConfig (LocalConfig r b) = do+    r' <- writeConfig r+    b' <- writeConfig b+    return $ ("resolver: " `prependFirst` r') ++ ("backend: " `prependFirst` b')
src/Module/CompileMetadata.hs view
@@ -39,6 +39,7 @@ data CompileMetadata =   CompileMetadata {     cmVersionHash :: VersionHash,+    cmRoot :: FilePath,     cmPath :: FilePath,     cmExtra :: [FilePath],     cmPublicNamespace :: Namespace,
src/Module/ParseMetadata.hs view
@@ -17,9 +17,18 @@ -- Author: Kevin P. Barry [ta0kira@gmail.com]  module Module.ParseMetadata (-  ConfigFormat,+  ConfigFormat(..),   autoReadConfig,   autoWriteConfig,+  indent,+  indents,+  parseList,+  parseOptional,+  parseQuoted,+  parseRequired,+  prependFirst,+  structClose,+  structOpen, ) where  import Control.Applicative.Permutations@@ -124,6 +133,7 @@ instance ConfigFormat CompileMetadata where   readConfig = runPermutation $ CompileMetadata     <$> parseRequired "version_hash:"       parseHash+    <*> parseRequired "root:"               parseQuoted     <*> parseRequired "path:"               parseQuoted     <*> parseOptional "extra_paths:"        [] (parseList parseQuoted)     <*> parseOptional "public_namespace:"   NoNamespace parseNamespace@@ -143,7 +153,7 @@     <*> parseRequired "libraries:"          (parseList parseQuoted)     <*> parseRequired "link_flags:"         (parseList parseQuoted)     <*> parseRequired "object_files:"       (parseList readConfig)-  writeConfig (CompileMetadata h p ee ns1 ns2 is is2 cs1 cs2 ds1 ds2 ps xs ts hxx cxx bs ls lf os) = do+  writeConfig (CompileMetadata h p d ee ns1 ns2 is is2 cs1 cs2 ds1 ds2 ps xs ts hxx cxx bs ls lf os) = do     validateHash h     ns1' <- maybeShowNamespace "public_namespace:"  ns1     ns2' <- maybeShowNamespace "private_namespace:" ns2@@ -152,7 +162,8 @@     os' <- fmap concat $ mapCompilerM writeConfig os     return $ [         "version_hash: " ++ show h,-        "path: " ++ show p+        "root: " ++ show p,+        "path: " ++ show d       ] ++ ns1' ++ ns2' ++ [         "extra_paths: ["       ] ++ indents (map show ee) ++ [
src/Module/ProcessMetadata.hs view
@@ -35,6 +35,9 @@   getSourceFilesForDeps,   isPathConfigured,   isPathUpToDate,+  isPrivateSource,+  isPublicSource,+  isTestSource,   loadModuleGlobals,   loadModuleMetadata,   loadPrivateDeps,@@ -90,6 +93,15 @@ tracesFilename :: FilePath tracesFilename = "traced-lines" +isPublicSource :: FilePath -> Bool+isPublicSource = isSuffixOf ".0rp"++isPrivateSource :: FilePath -> Bool+isPrivateSource = isSuffixOf ".0rx"++isTestSource :: FilePath -> Bool+isTestSource = isSuffixOf ".0rt"+ type MetadataMap = Map.Map FilePath CompileMetadata  mapMetadata :: [CompileMetadata] -> MetadataMap@@ -192,9 +204,9 @@     when (not isDir) $ compilerErrorM $ "Path \"" ++ absolute ++ "\" does not exist"     errorFromIO $ getDirectoryContents absolute >>= return . map (p </>)   select ds = (ps,xs,ts) where-    ps = nub $ filter (isSuffixOf ".0rp") ds-    xs = nub $ filter (isSuffixOf ".0rx") ds-    ts = nub $ filter (isSuffixOf ".0rt") ds+    ps = nub $ filter isPublicSource  ds+    xs = nub $ filter isPrivateSource ds+    ts = nub $ filter isTestSource    ds  getExprMap :: FilePath -> ModuleConfig -> TrackedErrorsIO (ExprMap SourceContext) getExprMap p m = do@@ -207,7 +219,7 @@  getSourceFilesForDeps :: [CompileMetadata] -> [FilePath] getSourceFilesForDeps = concat . map extract where-  extract m = map (cmPath m </>) (cmPublicFiles m)+  extract m = map (cmRoot m </>) (filter isPublicSource $ cmPublicFiles m ++ cmPrivateFiles m)  getNamespacesForDeps :: [CompileMetadata] -> [Namespace] getNamespacesForDeps = filter (not . isNoNamespace) . map cmPublicNamespace@@ -309,20 +321,21 @@ checkModuleVersionHash h m = cmVersionHash m == h  checkModuleFreshness :: VersionHash -> MetadataMap -> FilePath -> CompileMetadata -> TrackedErrorsIO ()-checkModuleFreshness h ca p m@(CompileMetadata _ p2 ep _ _ is is2 _ _ _ _ ps xs ts hxx cxx bs ls _ os) = do+checkModuleFreshness h ca p m@(CompileMetadata _ p2 d ep _ _ is is2 _ _ _ _ ps xs ts hxx cxx bs ls _ os) = do   time <- errorFromIO $ getModificationTime $ getCachedPath p "" metadataFilename-  (ps2,xs2,ts2) <- findSourceFiles "" (p2:ep)+  (ps2,xs2,ts2) <- findSourceFiles p2 (d:ep)   let rs = Set.toList $ Set.fromList $ concat $ map getRequires os+  expectedFiles <- mapCompilerM (errorFromIO . canonicalizePath . (p2</>)) (ps++xs++ts)+  actualFiles   <- mapCompilerM (errorFromIO . canonicalizePath . (p2</>)) (ps2++xs2++ts2)+  inputFiles    <- mapCompilerM (errorFromIO . canonicalizePath . (p2</>)) (xs++ts)   collectAllM_ $ [       checkHash,       checkInput time (p </> moduleFilename),-      mapCompilerM (errorFromIO . canonicalizePath) ps2 >>= checkMissing ps,-      mapCompilerM (errorFromIO . canonicalizePath) xs2 >>= checkMissing xs,-      mapCompilerM (errorFromIO . canonicalizePath) ts2 >>= checkMissing ts+      checkMissing expectedFiles actualFiles     ] ++     (map (checkDep time) $ is ++ is2) ++-    (map (checkInput time) $ ps ++ xs) ++-    (map (checkInput time . getCachedPath p2 "") $ hxx ++ cxx) +++    (map (checkInput time) inputFiles) +++    (map (checkInput time . getCachedPath d "") $ hxx ++ cxx) ++     (map checkOutput bs) ++     (map checkOutput ls) ++     (map checkObject os) ++@@ -341,20 +354,21 @@       when (not exists) $ compilerErrorM $ "Output file \"" ++ f ++ "\" is missing"     checkDep time dep = do       cm <- loadMetadata ca dep-      mapCompilerM_ (checkInput time . (cmPath cm </>)) (cmPublicFiles cm)+      files <- mapM (errorFromIO . canonicalizePath . (cmRoot cm </>)) (cmPublicFiles cm)+      mapCompilerM_ (checkInput time) files     checkObject (CategoryObjectFile _ _ fs) = mapCompilerM_ checkOutput fs     checkObject (OtherObjectFile f)         = checkOutput f     getRequires (CategoryObjectFile _ rs _) = rs     getRequires _                           = []-    checkRequire (CategoryIdentifier d c ns) = do-      cm <- loadMetadata ca d-      when (cmPath cm /= p2 && ns /= cmPublicNamespace cm) $+    checkRequire (CategoryIdentifier d2 c ns) = do+      cm <- loadMetadata ca d2+      when (cmPath cm /= d && ns /= cmPublicNamespace cm) $         compilerErrorM $ "Required category " ++ show c ++ " is newer than cached data"     checkRequire (UnresolvedCategory c) =       compilerErrorM $ "Required category " ++ show c ++ " is unresolved"     checkMissing s0 s1 = do       let missing = Set.toList $ Set.fromList s1 `Set.difference` Set.fromList s0-      mapCompilerM_ (\f -> compilerErrorM $ "Required path \"" ++ f ++ "\" is not present in cached data") missing+      mapCompilerM_ (\f -> compilerErrorM $ "Input path \"" ++ f ++ "\" is not present in cached data") missing     doesFileOrDirExist f2 = do       existF <- errorFromIO $ doesFileExist f2       if existF@@ -427,20 +441,20 @@  loadModuleGlobals :: PathIOHandler r => r -> FilePath -> (Namespace,Namespace) -> [FilePath] ->   Maybe CompileMetadata -> [CompileMetadata] -> [CompileMetadata] ->-  TrackedErrorsIO ([WithVisibility (AnyCategory SourceContext)])+  TrackedErrorsIO ([WithVisibility (AnyCategory SourceContext)],Set.Set FilePath) loadModuleGlobals r p (ns0,ns1) fs m deps1 deps2 = do   let public = Set.fromList $ map cmPath deps1   let deps2' = filter (\cm -> not $ cmPath cm `Set.member` public) deps2   cs0 <- fmap concat $ mapCompilerM (processDeps False [FromDependency])            deps1   cs1 <- fmap concat $ mapCompilerM (processDeps False [FromDependency,ModuleOnly]) deps2'-  cs2 <- loadAllPublic (ns0,ns1) fs+  (cs2,xa) <- loadAllPublic (ns0,ns1) fs   cs3 <- case m of               Just m2 -> processDeps True [FromDependency] m2               _       -> return []-  return (cs0++cs1++cs2++cs3) where+  return (cs0++cs1++cs2++cs3,xa) where     processDeps same ss dep = do       let fs2 = getSourceFilesForDeps [dep]-      cs <- loadAllPublic (cmPublicNamespace dep,cmPrivateNamespace dep) fs2+      (cs,_) <- loadAllPublic (cmPublicNamespace dep,cmPrivateNamespace dep) fs2       let cs' = if not same                    -- Allow ModuleOnly if the dep is the same module being                    -- compiled. (Tests load the module being tested as a dep.)@@ -449,14 +463,18 @@       return $ map (updateCodeVisibility (Set.union (Set.fromList ss))) cs'     loadAllPublic (ns2,ns3) fs2 = do       fs2' <- zipWithContents r p fs2-      fmap concat $ mapCompilerM loadPublic fs2'+      loaded <- mapCompilerM loadPublic fs2'+      return (concat $ map fst loaded,Set.fromList $ concat $ map snd loaded)       where         loadPublic p3 = do           (pragmas,cs) <- parsePublicSource p3+          xs <- if any isModuleOnly pragmas+                   then errorFromIO $ fmap (:[]) $ canonicalizePath $ p </> fst p3+                   else return []           let tags = Set.fromList $                      (if any isTestsOnly  pragmas then [TestsOnly]  else []) ++                      (if any isModuleOnly pragmas then [ModuleOnly] else [])           let cs' = if any isModuleOnly pragmas                        then map (setCategoryNamespace ns3) cs                        else map (setCategoryNamespace ns2) cs-          return $ map (WithVisibility tags) cs'+          return (map (WithVisibility tags) cs',xs)
src/Parser/Common.hs view
@@ -374,7 +374,7 @@ lineComment = labeled "line comment" $   between (string_ "//")           lineEnd-          (many $ satisfy (/= '\n'))+          (many $ satisfy (\c -> c /= '\n' && c /= '\r'))  blockComment :: TextParser String blockComment = labeled "block comment" $
src/Parser/DefinedCategory.hs view
@@ -49,7 +49,11 @@     return $ DefinedCategory [c] n pragmas ds rs ms ps fs     where       parseRefinesDefines = fmap merge2 $ sepBy refineOrDefine optionalSpace-      singlePragma = readOnly <|> hidden+      singlePragma = readOnly <|> hidden <|> flatCleanup+      flatCleanup = autoPragma "FlatCleanup" $ Right parseAt where+        parseAt c = do+          v <- labeled "variable name" sourceParser+          return $ FlatCleanup [c] v       readOnly = autoPragma "ReadOnly" $ Right parseAt where         parseAt c = do           vs <- labeled "variable names" $ sepBy sourceParser (sepAfter $ string ",")
src/Parser/Procedure.hs view
@@ -658,7 +658,7 @@       return $ EmptyLiteral [c]  instance ParseFromSource (ValueOperation SourceContext) where-  sourceParser = try valueCall <|> try conversion where+  sourceParser = try valueCall <|> try conversion <|> selectReturn where     valueCall = labeled "function call" $ do       c <- getSourceContext       valueSymbolGet@@ -673,6 +673,12 @@       n <- sourceParser       f <- parseFunctionCall c n       return $ ConvertedCall [c] t f+    selectReturn = labeled "return selection" $ do+      c <- getSourceContext+      sepAfter_ (string_ "{")+      pos <- labeled "return position" parseDec+      sepAfter_ (string_ "}")+      return $ SelectReturn [c] (fromIntegral pos)  instance ParseFromSource MacroName where   sourceParser = labeled "macro name" $ do
src/Test/Common.hs view
@@ -23,6 +23,8 @@   checkParseError,   checkParseMatch,   checkTypeFail,+  checkWriteFail,+  checkWriteThenRead,   checkTypeSuccess,   containsAtLeast,   containsAtMost,@@ -53,6 +55,7 @@ import Base.CompilerError import Base.CompilerMessage import Base.TrackedErrors+import Module.ParseMetadata (ConfigFormat,autoReadConfig,autoWriteConfig) import Parser.Common import Parser.TextParser import Parser.TypeInstance ()@@ -216,3 +219,27 @@             compilerErrorM $ "Expected pattern " ++ show m ++ " in error output but got\n" ++ text       | otherwise =           compilerErrorM $ "Expected write failure but got\n" ++ show (getCompilerSuccess c)++checkWriteThenRead :: (Eq a, Show a, ConfigFormat a) => a -> IO (TrackedErrors ())+checkWriteThenRead m = return $ do+  text <- fmap spamComments $ autoWriteConfig m+  m' <- autoReadConfig "(string)" text <!! "Serialized >>>\n\n" ++ text ++ "\n<<< Serialized\n\n"+  when (m' /= m) $+    compilerErrorM $ "Failed to match after write/read\n" +++                   "Before:\n" ++ show m ++ "\n" +++                   "After:\n" ++ show m' ++ "\n" +++                   "Intermediate:\n" ++ text where+   spamComments = unlines . map (++ " // spam") . lines++checkWriteFail :: ConfigFormat a => String -> a -> IO (TrackedErrors ())+checkWriteFail p m = return $ do+  let m' = autoWriteConfig m+  check m'+  where+    check c+      | isCompilerError c = do+          let text = show (getCompilerError c)+          when (not $ text =~ p) $+            compilerErrorM $ "Expected pattern " ++ show p ++ " in error output but got\n" ++ text+      | otherwise =+          compilerErrorM $ "Expected write failure but got\n" ++ getCompilerSuccess c
+ src/Test/ParseConfig.hs view
@@ -0,0 +1,61 @@+{- -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- -}++-- Author: Kevin P. Barry [ta0kira@gmail.com]++module Test.ParseConfig (tests) where++import Base.TrackedErrors+import Config.CompilerConfig+import Config.ParseConfig ()+import Test.Common+++compilerConfig :: LocalConfig+compilerConfig = LocalConfig {+    lcBackend = UnixBackend {+      ucCxxBinary = "/usr/bin/clang++",+      ucCompileFlags = [+        "-O2",+        "-std=c++11",+        "-fPIC"+      ],+      ucLibraryFlags = [+        "-shared",+        "-fpic"+      ],+      ucBinaryFlags = [+        "-02",+        "-std=c++11"+      ],+      ucArBinary = "/usr/bin/ar"+    },+    lcResolver = SimpleResolver {+      srVisibleSystem = [+        "lib",+        "testing"+      ],+      srExtraPaths = [+        "extra1",+        "extra2"+      ]+    }+  }++tests :: [IO (TrackedErrors ())]+tests = [+    checkWriteThenRead compilerConfig+  ]
src/Test/ParseMetadata.hs view
@@ -19,7 +19,6 @@ module Test.ParseMetadata (tests) where  import Control.Monad (when)-import Text.Regex.TDFA  import Base.CompilerError import Base.Positional@@ -38,6 +37,7 @@ hugeCompileMetadata :: CompileMetadata  -- testfiles/module-cache.txt hugeCompileMetadata = CompileMetadata {     cmVersionHash = VersionHash "0123456789ABCDEFabcdef",+    cmRoot = "/home/project",     cmPath = "/home/project/special",     cmExtra = [       "extra1",@@ -177,6 +177,7 @@      checkWriteFail "bad hash" $ CompileMetadata {       cmVersionHash = VersionHash "bad hash",+      cmRoot = "/home/project",       cmPath = "/home/project/special",       cmExtra = [],       cmPublicNamespace = NoNamespace,@@ -200,6 +201,7 @@      checkWriteFail "bad namespace" $ CompileMetadata {       cmVersionHash = VersionHash "0123456789ABCDEFabcdef",+      cmRoot = "/home/project",       cmPath = "/home/project/special",       cmExtra = [],       cmPublicNamespace = StaticNamespace "bad namespace",@@ -223,6 +225,7 @@      checkWriteFail "bad namespace" $ CompileMetadata {       cmVersionHash = VersionHash "0123456789ABCDEFabcdef",+      cmRoot = "/home/project",       cmPath = "/home/project/special",       cmExtra = [],       cmPublicNamespace = NoNamespace,@@ -246,6 +249,7 @@      checkWriteFail "bad category" $ CompileMetadata {       cmVersionHash = VersionHash "0123456789ABCDEFabcdef",+      cmRoot = "/home/project",       cmPath = "/home/project/special",       cmExtra = [],       cmPublicNamespace = NoNamespace,@@ -271,6 +275,7 @@      checkWriteFail "bad category" $ CompileMetadata {       cmVersionHash = VersionHash "0123456789ABCDEFabcdef",+      cmRoot = "/home/project",       cmPath = "/home/project/special",       cmExtra = [],       cmPublicNamespace = NoNamespace,@@ -410,30 +415,6 @@      checkParsesAs ("testfiles" </> "module-cache.txt") (== hugeCompileMetadata)   ]--checkWriteThenRead :: (Eq a, Show a, ConfigFormat a) => a -> IO (TrackedErrors ())-checkWriteThenRead m = return $ do-  text <- fmap spamComments $ autoWriteConfig m-  m' <- autoReadConfig "(string)" text <!! "Serialized >>>\n\n" ++ text ++ "\n<<< Serialized\n\n"-  when (m' /= m) $-    compilerErrorM $ "Failed to match after write/read\n" ++-                   "Before:\n" ++ show m ++ "\n" ++-                   "After:\n" ++ show m' ++ "\n" ++-                   "Intermediate:\n" ++ text where-   spamComments = unlines . map (++ " // spam") . lines--checkWriteFail :: ConfigFormat a => String -> a -> IO (TrackedErrors ())-checkWriteFail p m = return $ do-  let m' = autoWriteConfig m-  check m'-  where-    check c-      | isCompilerError c = do-          let text = show (getCompilerError c)-          when (not $ text =~ p) $-            compilerErrorM $ "Expected pattern " ++ show p ++ " in error output but got\n" ++ text-      | otherwise =-          compilerErrorM $ "Expected write failure but got\n" ++ getCompilerSuccess c  checkParsesAs :: (Show a, ConfigFormat a) => String -> (a -> Bool) -> IO (TrackedErrors ()) checkParsesAs f m = do
src/Test/Procedure.hs view
@@ -223,6 +223,11 @@     checkShortParseSuccess "_ <- 1 / 2 - 3",     checkShortParseSuccess "_ <- x < y || z > w", +    checkShortParseSuccess "\\ call(){0}",+    checkShortParseSuccess "\\ call(){0}.bar()",+    checkShortParseFail "\\ call(){x}",+    checkShortParseFail "\\ call(){-1}",+     checkParsesAs "'\"'"                   (\e -> case e of                               (Expression _ (UnambiguousLiteral (CharLiteral _ '"')) []) -> True
src/Test/testfiles/module-cache.txt view
@@ -26,6 +26,7 @@   "/home/project/public-dep1"   "/home/project/public-dep2" ]+root: "/home/project" private_deps: [   "/home/project/private-dep1"   "/home/project/private-dep2"
src/Types/Builtin.hs view
@@ -28,6 +28,7 @@   floatRequiredValue,   formattedRequiredValue,   intRequiredValue,+  isOpaqueMulti,   orderOptionalValue,   stringRequiredValue, ) where@@ -83,3 +84,7 @@   -- Value with lazy initialization. Requires indirection to get/set.   LazySingle ExpressionValue   deriving (Show)++isOpaqueMulti :: ExpressionValue -> Bool+isOpaqueMulti (OpaqueMulti _) = True+isOpaqueMulti _               = False
src/Types/DefinedCategory.hs view
@@ -25,6 +25,7 @@   VariableRule(..),   VariableValue(..),   isInitialized,+  isFlatCleanup,   isMembersHidden,   isMembersReadOnly,   mapMembers,@@ -81,6 +82,10 @@   MembersHidden {     mhContext :: [c],     mhMembers :: [VariableName]+  } |+  FlatCleanup {+    fcContext :: [c],+    fcMember :: VariableName   }   deriving (Show) @@ -91,6 +96,10 @@ isMembersHidden :: PragmaDefined c -> Bool isMembersHidden (MembersHidden _ _) = True isMembersHidden _                   = False++isFlatCleanup :: PragmaDefined c -> Bool+isFlatCleanup (FlatCleanup _ _) = True+isFlatCleanup _                 = False  data VariableRule c =   VariableDefault |
src/Types/Procedure.hs view
@@ -331,7 +331,8 @@  data ValueOperation c =   ConvertedCall [c] TypeInstance (FunctionCall c) |-  ValueCall [c] (FunctionCall c)+  ValueCall [c] (FunctionCall c) |+  SelectReturn [c] Int   deriving (Show)  newtype MacroName =
tests/builtin-types.0rt view
@@ -302,23 +302,23 @@ }  unittest boolDefault {-  \ Testing.checkEquals<?>(Bool.default(),false)+  \ Testing.checkFalse(Bool.default()) }  unittest charDefault {-  \ Testing.checkEquals<?>(Char.default(),'\000')+  \ Testing.checkEquals(Char.default(),'\000') }  unittest floatDefault {-  \ Testing.checkEquals<?>(Float.default(),0.0)+  \ Testing.checkEquals(Float.default(),0.0) }  unittest intDefault {-  \ Testing.checkEquals<?>(Int.default(),0)+  \ Testing.checkEquals(Int.default(),0) }  unittest stringDefault {-  \ Testing.checkEquals<?>(String.default(),"")+  \ Testing.checkEquals(String.default(),"") }  unittest stringLessThan {@@ -341,9 +341,9 @@  unittest stringBuilder {   [Append<Formatted>&Build<String>] builder <- String.builder()-  \ Testing.checkEquals<?>(builder.build(),"")-  \ Testing.checkEquals<?>(builder.append("xyz").build(),"xyz")-  \ Testing.checkEquals<?>(builder.append(123).build(),"xyz123")+  \ Testing.checkEquals(builder.build(),"")+  \ Testing.checkEquals(builder.append("xyz").build(),"xyz")+  \ Testing.checkEquals(builder.append(123).build(),"xyz123") }  unittest charLessThan {@@ -488,24 +488,24 @@       .writeAt(1,'B')       .writeAt(2,'C') -  \ Testing.checkEquals<?>(buffer.size(),5)-  \ Testing.checkEquals<?>(buffer.readAt(0),'a')-  \ Testing.checkEquals<?>(buffer.readAt(1),'B')-  \ Testing.checkEquals<?>(buffer.readAt(2),'C')-  \ Testing.checkEquals<?>(buffer.readAt(3),'d')-  \ Testing.checkEquals<?>(buffer.readAt(4),'e')+  \ Testing.checkEquals(buffer.size(),5)+  \ Testing.checkEquals(buffer.readAt(0),'a')+  \ Testing.checkEquals(buffer.readAt(1),'B')+  \ Testing.checkEquals(buffer.readAt(2),'C')+  \ Testing.checkEquals(buffer.readAt(3),'d')+  \ Testing.checkEquals(buffer.readAt(4),'e') }  unittest resizeDown {   CharBuffer buffer <- CharBuffer.new(5).resize(3).writeAt(2,'a')-  \ Testing.checkEquals<?>(buffer.size(),3)-  \ Testing.checkEquals<?>(buffer.readAt(2),'a')+  \ Testing.checkEquals(buffer.size(),3)+  \ Testing.checkEquals(buffer.readAt(2),'a') }  unittest resizeUp {   CharBuffer buffer <- CharBuffer.new(5).resize(7).writeAt(6,'a')-  \ Testing.checkEquals<?>(buffer.size(),7)-  \ Testing.checkEquals<?>(buffer.readAt(6),'a')+  \ Testing.checkEquals(buffer.size(),7)+  \ Testing.checkEquals(buffer.readAt(6),'a') }  @@ -634,11 +634,11 @@   String value <- "abcdefg"    traverse (value.defaultOrder() -> Char c) {-    \ Testing.checkEquals<?>(c,value.readAt(index))+    \ Testing.checkEquals(c,value.readAt(index))     index <- index+1   } -  \ Testing.checkEquals<?>(index,7)+  \ Testing.checkEquals(index,7) }  unittest fromCharBuffer {@@ -648,7 +648,7 @@       .writeAt(2,'c')       .writeAt(3,'d')       .writeAt(4,'e')-  \ Testing.checkEquals<?>(String.fromCharBuffer(buffer),"abcde")+  \ Testing.checkEquals(String.fromCharBuffer(buffer),"abcde") }  @@ -720,19 +720,19 @@ }  unittest accurateMax {-  \ Testing.checkEquals<?>(Char.maxBound().asInt(),255)+  \ Testing.checkEquals(Char.maxBound().asInt(),255) }  unittest accurateMin {-  \ Testing.checkEquals<?>(Char.minBound().asInt(),0)+  \ Testing.checkEquals(Char.minBound().asInt(),0) }  unittest asIntIsUnsigned {-  \ Testing.checkEquals<?>('\xff'.asInt(),255)+  \ Testing.checkEquals('\xff'.asInt(),255) }  unittest asFloatIsUnsigned {-  \ Testing.checkEquals<?>('\xff'.asFloat(),255.0)+  \ Testing.checkEquals('\xff'.asFloat(),255.0) }  @@ -741,21 +741,21 @@ }  unittest accurateMax {-  \ Testing.checkEquals<?>(Int.maxBound(),9223372036854775807)+  \ Testing.checkEquals(Int.maxBound(),9223372036854775807) }  unittest accurateMin {-  \ Testing.checkEquals<?>(Int.minBound(),-9223372036854775808)+  \ Testing.checkEquals(Int.minBound(),-9223372036854775808) }  unittest asCharIsPeriodic {-  \ Testing.checkEquals<?>((65).asChar(),(65+256).asChar())-  \ Testing.checkEquals<?>((65).asChar(),(65+1024).asChar())-  \ Testing.checkEquals<?>((65).asChar(),(65-1024).asChar())+  \ Testing.checkEquals((65).asChar(),(65+256).asChar())+  \ Testing.checkEquals((65).asChar(),(65+1024).asChar())+  \ Testing.checkEquals((65).asChar(),(65-1024).asChar()) }  unittest hexUnsigned {-  \ Testing.checkEquals<?>(\xffffffffffffffff,-1)+  \ Testing.checkEquals(\xffffffffffffffff,-1) }  
tests/cli-tests.sh view
@@ -78,6 +78,128 @@ }  +require_patterns() {+  local output=$1+  local error=0+  while read pattern; do+    if ! echo "$output" | egrep -q "$pattern"; then+      show_message "Expected pattern \"$pattern\" in output"+      error=1+    fi+  done+  if ((error)); then+    echo "$output" 1>&2+    return 1+  fi+}+++exclude_patterns() {+  local output=$1+  local error=0+  while read pattern; do+    if echo "$output" | egrep -q "$pattern"; then+      show_message "Unexpected pattern \"$pattern\" in output"+      error=1+    fi+  done+  if ((error)); then+    echo "$output" 1>&2+    return 1+  fi+}+++test_freshness() {+  mkdir -p "$ZEOLITE_PATH/tests/freshness"/{,sub1/,sub2/}+  touch "$ZEOLITE_PATH/tests/freshness"/{,sub1/,sub2/}{public{1,2}.0rp,private{1,2}.0rp,source{1,2}.0rx,test{1,2}.0rt}+  echo '$ModuleOnly$' | tee "$ZEOLITE_PATH/tests/freshness"/{,sub1/,sub2/}private{1,2}.0rp > /dev/null+  echo 'concrete Type {} define Type {}' | tee "$ZEOLITE_PATH/tests/freshness"/{,sub1/,sub2/}private{1,2}.0rx > /dev/null+  rm -f "$ZEOLITE_PATH/tests/freshness"/{,sub1/,sub2/}{public3.0rp,source3.0rx,test3.0rt}++  # Compile and test normally.+  do_zeolite -p "$ZEOLITE_PATH" -R tests/freshness/reverse -f+  do_zeolite -p "$ZEOLITE_PATH" -t tests/freshness/reverse++  # Modify the module's files.+  touch "$ZEOLITE_PATH/tests/freshness"/{,sub1/,sub2/}{public{1,3}.0rp,source{1,3}.0rx,test{1,3}.0rt}+  rm -f "$ZEOLITE_PATH/tests/freshness"/{,sub1/,sub2/}{public2.0rp,private2.0rp,source2.0rx,test2.0rt}+  rm -f "$ZEOLITE_PATH/tests/freshness/.zeolite-cache"/*.so++  local output=$(do_zeolite -p "$ZEOLITE_PATH" -t tests/freshness/reverse || true)+  require_patterns "$output" <<END+tests/freshness/reverse.+out of date+freshness/public1\.0rp.+newer+freshness/public2\.0rp.+missing+freshness/sub1/public1\.0rp.+newer+freshness/sub1/public2\.0rp.+missing+freshness/sub2/public1\.0rp.+newer+freshness/sub2/public2\.0rp.+missing+END+[[ $? -eq 0 ]] || return 1+  exclude_patterns "$output" <<END+private+0rt+0rx+END+[[ $? -eq 0 ]] || return 1++  local output=$(do_zeolite -p "$ZEOLITE_PATH" -t tests/freshness || true)+  require_patterns "$output" <<END+tests/freshness[^/].+out of date+freshness/public3\.0rp.+not present+freshness/source1\.0rx.+newer+freshness/source2\.0rx.+missing+freshness/source3\.0rx.+not present+freshness/sub1/public3\.0rp.+not present+freshness/sub1/source1\.0rx.+newer+freshness/sub1/source2\.0rx.+missing+freshness/sub1/source3\.0rx.+not present+freshness/sub1/test1\.0rt.+newer+freshness/sub1/test2\.0rt.+missing+freshness/sub1/test3\.0rt.+not present+freshness/sub2/public3\.0rp.+not present+freshness/sub2/source1\.0rx.+newer+freshness/sub2/source2\.0rx.+missing+freshness/sub2/source3\.0rx.+not present+freshness/sub2/test1\.0rt.+newer+freshness/sub2/test2\.0rt.+missing+freshness/sub2/test3\.0rt.+not present+freshness/test1\.0rt.+newer+freshness/test2\.0rt.+missing+freshness/test3\.0rt.+not present+freshness/.zeolite-cache/public_[a-f0-9]+\.so.+missing+END+[[ $? -eq 0 ]] || return 1+  exclude_patterns "$output" <<END+cpp+hpp+\.o\b+END+[[ $? -eq 0 ]] || return 1++  do_zeolite -p "$ZEOLITE_PATH" -r tests/freshness++  local output=$(do_zeolite -p "$ZEOLITE_PATH" -t tests/freshness/reverse || true)+  require_patterns "$output" <<END+tests/freshness/reverse.+out of date+freshness/public1\.0rp.+newer+freshness/public3\.0rp.+newer+freshness/sub1/public1\.0rp.+newer+freshness/sub1/public3\.0rp.+newer+freshness/sub2/public1\.0rp.+newer+freshness/sub2/public3\.0rp.+newer+END+[[ $? -eq 0 ]] || return 1+  exclude_patterns "$output" <<END+private+0rt+0rx+END+[[ $? -eq 0 ]] || return 1+}++ test_leak_check() {   local binary="$ZEOLITE_PATH/tests/leak-check/LeakTest"   rm -f "$binary"@@ -260,11 +382,11 @@ test_show_deps() {   local output=$(do_zeolite -p "$ZEOLITE_PATH" --show-deps tests)   local patterns=(-    'ExprLookup -> Int ".*zeolite/base"'-    'ExprLookup -> String ".*zeolite/base"'+    'ExprLookup -> Int "/.+/base"'+    'ExprLookup -> String "/.+/base"'   )   for pattern in "${patterns[@]}"; do-    if echo "$output" | egrep -q "$pattern"; then+    if ! echo "$output" | egrep -q "$pattern"; then       show_message "Expected \"$pattern\" in --show-deps for tests:"       echo "$output" 1>&2       return 1@@ -380,7 +502,7 @@   do_zeolite -p "$ZEOLITE_PATH" -r tests/traces -f   local source_files=("$ZEOLITE_PATH/tests/traces/traces.0rx")   local expected=$(fgrep -n '// TRACED' "${source_files[@]}" | egrep -o '^[0-9]+' | sort -u)-  local actual=$(do_zeolite --show-traces "$ZEOLITE_PATH/tests/traces" | grep 0rx | sed -r 's/^line ([0-9]+).*/\1/' | sort -u)+  local actual=$(do_zeolite -p "$ZEOLITE_PATH" --show-traces "tests/traces" | grep 0rx | sed -r 's/^line ([0-9]+).*/\1/' | sort -u)   if [[ "$actual" != "$expected" ]]; then     show_message "Mismatch between expected and actual traced lines:"     echo "Expected:" $expected 1>&2@@ -431,6 +553,7 @@   test_example_primes   test_example_random   test_fast_static+  test_freshness   test_global_include   test_leak_check   test_module_only
tests/expr-lookup.0rt view
@@ -71,7 +71,7 @@ }  unittest test {-  \ Testing.checkEquals<?>($ExprLookup[INT_EXPR]$,4)+  \ Testing.checkEquals($ExprLookup[INT_EXPR]$,4)   // Use it a second time to ensure that reserving the macro name doesn't   // carry over to the next statement.   \ $ExprLookup[INT_EXPR]$@@ -83,7 +83,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(ExprLookup.intExpr(),4)+  \ Testing.checkEquals(ExprLookup.intExpr(),4) }  @@ -99,7 +99,7 @@   @category String macroLocalVar <- "hello"    run () {-    \ Testing.checkEquals<?>($ExprLookup[LOCAL_VAR]$,"hello")+    \ Testing.checkEquals($ExprLookup[LOCAL_VAR]$,"hello")   } } @@ -124,7 +124,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(ExprLookup.localVar(),99)+  \ Testing.checkEquals(ExprLookup.localVar(),99) }  @@ -133,7 +133,7 @@ }  unittest test {-  \ Testing.checkEquals<?>($ExprLookup[META_VAR]$,20)+  \ Testing.checkEquals($ExprLookup[META_VAR]$,20) }  @@ -142,7 +142,7 @@ }  unittest test {-  \ Testing.checkEquals<?>($ExprLookup[INT_EXPR]$.formatted(),"4")+  \ Testing.checkEquals($ExprLookup[INT_EXPR]$.formatted(),"4") }  
+ tests/freshness/.zeolite-module view
@@ -0,0 +1,7 @@+root: "../.."+path: "tests/freshness"+extra_paths: [+  "tests/freshness/sub1"+  "tests/../tests/freshness/sub2"+]+mode: incremental {}
+ tests/freshness/README.md view
@@ -0,0 +1,4 @@+# Testing CLI Freshness Check++There isn't much you can do with this module. The CLI tests use it to verify+that the `zeolite` module-freshness checks work properly.
+ tests/freshness/reverse/.zeolite-module view
@@ -0,0 +1,6 @@+root: "../../.."+path: "tests/freshness/reverse"+private_deps: [+  "../../../tests/freshness"+]+mode: incremental {}
tests/function-calls.0rt view
@@ -454,25 +454,25 @@ }  unittest callDispatch {-  \ Testing.checkEquals<?>(Type.new().get(),00)-  \ Testing.checkEquals<?>(Type.new().get01(),01)-  \ Testing.checkEquals<?>(Type.new().get02(),02)-  \ Testing.checkEquals<?>(Type.new().get03(),03)-  \ Testing.checkEquals<?>(Type.new().get04(),04)-  \ Testing.checkEquals<?>(Type.new().get05(),05)-  \ Testing.checkEquals<?>(Type.new().get06(),06)-  \ Testing.checkEquals<?>(Type.new().get07(),07)-  \ Testing.checkEquals<?>(Type.new().get08(),08)-  \ Testing.checkEquals<?>(Type.new().get09(),09)-  \ Testing.checkEquals<?>(Type.new().get10(),10)-  \ Testing.checkEquals<?>(Type.new().get11(),11)-  \ Testing.checkEquals<?>(Type.new().get12(),12)-  \ Testing.checkEquals<?>(Type.new().get13(),13)-  \ Testing.checkEquals<?>(Type.new().get14(),14)-  \ Testing.checkEquals<?>(Type.new().get15(),15)-  \ Testing.checkEquals<?>(Type.new().get16(),16)-  \ Testing.checkEquals<?>(Type.new().get17(),17)-  \ Testing.checkEquals<?>(Type.new().get18(),18)+  \ Testing.checkEquals(Type.new().get(),00)+  \ Testing.checkEquals(Type.new().get01(),01)+  \ Testing.checkEquals(Type.new().get02(),02)+  \ Testing.checkEquals(Type.new().get03(),03)+  \ Testing.checkEquals(Type.new().get04(),04)+  \ Testing.checkEquals(Type.new().get05(),05)+  \ Testing.checkEquals(Type.new().get06(),06)+  \ Testing.checkEquals(Type.new().get07(),07)+  \ Testing.checkEquals(Type.new().get08(),08)+  \ Testing.checkEquals(Type.new().get09(),09)+  \ Testing.checkEquals(Type.new().get10(),10)+  \ Testing.checkEquals(Type.new().get11(),11)+  \ Testing.checkEquals(Type.new().get12(),12)+  \ Testing.checkEquals(Type.new().get13(),13)+  \ Testing.checkEquals(Type.new().get14(),14)+  \ Testing.checkEquals(Type.new().get15(),15)+  \ Testing.checkEquals(Type.new().get16(),16)+  \ Testing.checkEquals(Type.new().get17(),17)+  \ Testing.checkEquals(Type.new().get18(),18) }  unittest reduceBuiltin {@@ -719,7 +719,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(Value.create().call(1,"mess",2,"age"),"message")+  \ Testing.checkEquals(Value.create().call(1,"mess",2,"age"),"message") }  concrete Value {
tests/inference.0rt view
@@ -21,16 +21,45 @@ }  unittest test {-  Int value <- Test.get<?>(10)+  Int value1, String value2 <- Test.get<?,?>(10,"message")+  \ Testing.checkEquals<?>(value1,10)+  \ Testing.checkEquals<?>(value2,"message") } +unittest testImplicit {+  Int value1, String value2 <- Test.get(10,"message")+  \ Testing.checkEquals<?>(value1,10)+  \ Testing.checkEquals<?>(value2,"message")+}+ concrete Test {-  @type get<#x> (#x) -> (#x)+  @type get<#x,#y> (#x,#y) -> (#x,#y) }  define Test {-  get (x) {-    return x+  get (x,y) {+    return x, y+  }+}+++testcase "wrong param count" {+  error+  require "mismatch"+  require "get"+}++unittest test {+  Int value1, String value2 <- Test.get<?>(10,"message")+}++concrete Test {+  @type get<#x,#y> (#x,#y) -> (#x,#y)+}++define Test {+  get (x,y) {+    return x, y   } } 
tests/infix-functions.0rt view
@@ -172,20 +172,20 @@  define Test {   check () {-    \ Testing.checkEquals<?>(1 `one` 2 `two` 4,5)+    \ Testing.checkEquals(1 `one` 2 `two` 4,5)   }    @type one (Int,Int) -> (Int)   one (x,y) {-    \ Testing.checkEquals<?>(x,1)-    \ Testing.checkEquals<?>(y,2)+    \ Testing.checkEquals(x,1)+    \ Testing.checkEquals(y,2)     return 3   }    @type two (Int,Int) -> (Int)   two (x,y) {-    \ Testing.checkEquals<?>(x,3)-    \ Testing.checkEquals<?>(y,4)+    \ Testing.checkEquals(x,3)+    \ Testing.checkEquals(y,4)     return 5   } }
tests/infix-operations.0rt view
@@ -21,55 +21,55 @@ }  unittest plus {-  \ Testing.checkEquals<?>(8 + 2,10)+  \ Testing.checkEquals(8 + 2,10) }  unittest minus {-  \ Testing.checkEquals<?>(8 - 2,6)+  \ Testing.checkEquals(8 - 2,6) }  unittest times {-  \ Testing.checkEquals<?>(8 * 2,16)+  \ Testing.checkEquals(8 * 2,16) }  unittest divide {-  \ Testing.checkEquals<?>(8 / 2,4)+  \ Testing.checkEquals(8 / 2,4) }  unittest modulo {-  \ Testing.checkEquals<?>(8 % 2,0)+  \ Testing.checkEquals(8 % 2,0) }  unittest left {-  \ Testing.checkEquals<?>(1 << 2,4)+  \ Testing.checkEquals(1 << 2,4) }  unittest right {-  \ Testing.checkEquals<?>(7 >> 1,3)+  \ Testing.checkEquals(7 >> 1,3) }  unittest xor {-  \ Testing.checkEquals<?>(7 ^ 2 ,5)+  \ Testing.checkEquals(7 ^ 2 ,5) }  unittest and {-  \ Testing.checkEquals<?>(7 & ~2,5)+  \ Testing.checkEquals(7 & ~2,5) }  unittest or {-  \ Testing.checkEquals<?>(5 | 2 ,7)+  \ Testing.checkEquals(5 | 2 ,7) }  unittest arithmetic {-  \ Testing.checkEquals<?>(\x10 + 1 * 2 - 8 / 2 - 3 % 2,13)+  \ Testing.checkEquals(\x10 + 1 * 2 - 8 / 2 - 3 % 2,13) }  unittest bitwise {-  \ Testing.checkEquals<?>(1 << 4 | 7 >> 1 & ~2,17)+  \ Testing.checkEquals(1 << 4 | 7 >> 1 & ~2,17) }  unittest sameOperator {-  \ Testing.checkEquals<?>(2 - 1 - 1,0)+  \ Testing.checkEquals(2 - 1 - 1,0) }  unittest lessThan {@@ -136,15 +136,15 @@ unittest rightAssociative {   Int x <- 2   Bool y <- true && (x <- 3) == 2 || x == 3-  \ Testing.checkEquals<?>(x,3)-  \ Testing.checkEquals<?>(y,true)+  \ Testing.checkEquals(x,3)+  \ Testing.checkTrue(y) }  unittest shortCircuit {   Int x <- 2   Bool y <- true || (x <- 3) == 2 || x == 3-  \ Testing.checkEquals<?>(x,2)-  \ Testing.checkEquals<?>(y,true)+  \ Testing.checkEquals(x,2)+  \ Testing.checkTrue(y) }  @@ -153,7 +153,7 @@ }  unittest precedence {-  \ Testing.checkEquals<?>(16.0 + 1.0 * 2.0 - 8.0 / 2.0 - 3.0 / 3.0,13.0)+  \ Testing.checkEquals(16.0 + 1.0 * 2.0 - 8.0 / 2.0 - 3.0 / 3.0,13.0) }  unittest lessThan {@@ -190,7 +190,7 @@ }  unittest add {-  \ Testing.checkEquals<?>("x" + "y" + "z","xyz")+  \ Testing.checkEquals("x" + "y" + "z","xyz") }  unittest lessThan {@@ -227,7 +227,7 @@ }  unittest minus {-  \ Testing.checkEquals<?>('z' - 'a',25)+  \ Testing.checkEquals('z' - 'a',25) }  unittest lessThan {
tests/leak-check/leak-check.0rx view
@@ -29,7 +29,7 @@    @type runWith (Int,Int) -> ()   runWith (iterations,size) {-    Int threads <- Ranges:max<?>(3,$ExprLookup[CPU_CORE_COUNT]$-1)+    Int threads <- Ranges:max(3,$ExprLookup[CPU_CORE_COUNT]$-1)     ReadAt<BarrierWait> barriers <- EnumeratedBarrier.new(threads+1)     traverse (Counter.zeroIndexed(iterations) -> Int i) {       \ doIteration<LastReference>(i,size,barriers)
tests/local-rules.0rt view
@@ -52,7 +52,7 @@     $ReadOnly[foo]$   }   foo <- 2-  \ Testing.checkEquals<?>(foo,2)+  \ Testing.checkEquals(foo,2) }  @@ -82,7 +82,7 @@     $ReadOnly[foo]$   }   foo <- 2-  \ Testing.checkEquals<?>(foo,2)+  \ Testing.checkEquals(foo,2) }  @@ -97,9 +97,9 @@     foo <- 2     $ReadOnly[foo]$   }-  \ Testing.checkEquals<?>(foo,2)+  \ Testing.checkEquals(foo,2)   foo <- 3-  \ Testing.checkEquals<?>(foo,3)+  \ Testing.checkEquals(foo,3) }  @@ -151,7 +151,7 @@   cleanup {     foo <- 2   } in $ReadOnly[foo]$-  \ Testing.checkEquals<?>(foo,2)+  \ Testing.checkEquals(foo,2) }  @@ -181,7 +181,7 @@     $Hidden[foo]$   }   foo <- 2-  \ Testing.checkEquals<?>(foo,2)+  \ Testing.checkEquals(foo,2) }  @@ -240,9 +240,9 @@     foo <- 2     $Hidden[foo]$   }-  \ Testing.checkEquals<?>(foo,2)+  \ Testing.checkEquals(foo,2)   foo <- 3-  \ Testing.checkEquals<?>(foo,3)+  \ Testing.checkEquals(foo,3) }  @@ -321,7 +321,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(Type:get(),2)+  \ Testing.checkEquals(Type:get(),2) }  concrete Type {@@ -404,7 +404,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(Type.create().get(),1)+  \ Testing.checkEquals(Type.create().get(),1) }  concrete Type {
tests/member-init.0rt view
@@ -90,7 +90,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(Test:get(),2)+  \ Testing.checkEquals(Test:get(),2) }  concrete Test {
tests/module-only4/common-source.cpp view
@@ -29,7 +29,7 @@ namespace ZEOLITE_PRIVATE_NAMESPACE { #endif  // ZEOLITE_PRIVATE_NAMESPACE -BoxedValue CreateValue_Type1(S<const Type_Type1> parent, const ValueTuple& args);+BoxedValue CreateValue_Type1(S<const Type_Type1> parent, const ParamsArgs& params_args);  struct ExtCategory_Type1 : public Category_Type1 { };@@ -37,20 +37,20 @@ struct ExtType_Type1 : public Type_Type1 {   inline ExtType_Type1(Category_Type1& p, Params<0>::Type params) : Type_Type1(p, params) {} -  ReturnTuple Call_create(const ParamTuple& params, const ValueTuple& args) const {+  ReturnTuple Call_create(const ParamsArgs& params_args) const {     TRACE_FUNCTION("Type1.create")     return ReturnTuple(CreateValue_Type1(PARAM_SELF,-      TypeInstance::Call(GetType_Type2(Params<0>::Type()), Function_Type2_create, ParamTuple(), ArgTuple())));+      PassParamsArgs(TypeInstance::Call(GetType_Type2(Params<0>::Type()), Function_Type2_create, PassParamsArgs()))));   } };  struct ExtValue_Type1 : public Value_Type1 {-  inline ExtValue_Type1(S<const Type_Type1> p, const ValueTuple& args)-    : Value_Type1(std::move(p)), value(args.At(0)) {}+  inline ExtValue_Type1(S<const Type_Type1> p, const ParamsArgs& params_args)+    : Value_Type1(std::move(p)), value(params_args.GetArg(0)) {} -  ReturnTuple Call_get(const ParamTuple& params, const ValueTuple& args) {+  ReturnTuple Call_get(const ParamsArgs& params_args) {     TRACE_FUNCTION("Type1.get")-    return ReturnTuple(TypeValue::Call(value, Function_Type2_get, ParamTuple(), ArgTuple()));+    return ReturnTuple(TypeValue::Call(value, Function_Type2_get, PassParamsArgs()));   }    const BoxedValue value;@@ -68,8 +68,8 @@  void RemoveType_Type1(const Params<0>::Type& params) {} -BoxedValue CreateValue_Type1(S<const Type_Type1> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_Type1>(std::move(parent), args);+BoxedValue CreateValue_Type1(S<const Type_Type1> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_Type1>(std::move(parent), params_args); }  #ifdef ZEOLITE_PRIVATE_NAMESPACE@@ -82,7 +82,7 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_Type3(S<const Type_Type3> parent, const ValueTuple& args);+BoxedValue CreateValue_Type3(S<const Type_Type3> parent, const ParamsArgs& params_args);  struct ExtCategory_Type3 : public Category_Type3 { };@@ -90,20 +90,20 @@ struct ExtType_Type3 : public Type_Type3 {   inline ExtType_Type3(Category_Type3& p, Params<0>::Type params) : Type_Type3(p, params) {} -  ReturnTuple Call_create(const ParamTuple& params, const ValueTuple& args) const {+  ReturnTuple Call_create(const ParamsArgs& params_args) const {     TRACE_FUNCTION("Type3.create")     return ReturnTuple(CreateValue_Type3(PARAM_SELF,-      TypeInstance::Call(GetType_Type2(Params<0>::Type()), Function_Type2_create, ParamTuple(), ArgTuple())));+      PassParamsArgs(TypeInstance::Call(GetType_Type2(Params<0>::Type()), Function_Type2_create, PassParamsArgs()))));   } };  struct ExtValue_Type3 : public Value_Type3 {-  inline ExtValue_Type3(S<const Type_Type3> p, const ValueTuple& args)-    : Value_Type3(std::move(p)), value(args.At(0)) {}+  inline ExtValue_Type3(S<const Type_Type3> p, const ParamsArgs& params_args)+    : Value_Type3(std::move(p)), value(params_args.GetArg(0)) {} -  ReturnTuple Call_get(const ParamTuple& params, const ValueTuple& args) {+  ReturnTuple Call_get(const ParamsArgs& params_args) {     TRACE_FUNCTION("Type3.get")-    return ReturnTuple(TypeValue::Call(value, Function_Type2_get, ParamTuple(), ArgTuple()));+    return ReturnTuple(TypeValue::Call(value, Function_Type2_get, PassParamsArgs()));   }    const BoxedValue value;@@ -121,8 +121,8 @@  void RemoveType_Type3(const Params<0>::Type& params) {} -BoxedValue CreateValue_Type3(S<const Type_Type3> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_Type3>(std::move(parent), args);+BoxedValue CreateValue_Type3(S<const Type_Type3> parent, const ParamsArgs& params_args) {+  return BoxedValue::New<ExtValue_Type3>(std::move(parent), params_args); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
tests/multiple-returns.0rt view
@@ -1,5 +1,5 @@ /* ------------------------------------------------------------------------------Copyright 2020 Kevin P. Barry+Copyright 2020-2021 Kevin P. Barry  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.@@ -108,4 +108,91 @@ concrete Test {   @type get () -> (Int,Int)   @type call (Int,Int) -> ()+}+++testcase "return selection" {+  success+}++unittest correctPosition {+  \ Testing.checkEquals(Test.get(){0},123)+  \ Testing.checkEquals(Test.get(){1},"message")+}++unittest chainedCall {+  \ Testing.checkEquals(Test.get(){0}.formatted(),"123")+}++concrete Test {+  @type get () -> (Int,String)+}++define Test {+  get () {+    return 123, "message"+  }+}+++testcase "bad return-selection index" {+  error+  require "100"+}++unittest test {+  \ Test.get(){100}+}++concrete Test {+  @type get () -> (Int,String)+}++define Test {+  get () {+    return 123, "message"+  }+}+++testcase "cannot select return from literal" {+  error+  require "selection"+}++unittest test {+  \ "message"{0}+}+++testcase "cannot select return from boxed variable" {+  error+  require "selection"+}++unittest test {+  String value <- "message"+  \ value{0}+}+++testcase "cannot select return from unboxed variable" {+  error+  require "selection"+}++unittest test {+  Int value <- 123+  \ value{0}+}+++testcase "cannot double select" {+  error+  require "selection"+  exclude "123"+}++unittest test {+  \ "message".formatted(){0}{123} }
tests/named-returns.0rt view
@@ -287,11 +287,11 @@ }  unittest withScoped {-  \ Testing.checkEquals<?>(Test.withScoped(),"message")+  \ Testing.checkEquals(Test.withScoped(),"message") }  unittest withCleanup {-  \ Testing.checkEquals<?>(Test.withCleanup(),"message")+  \ Testing.checkEquals(Test.withCleanup(),"message") }  concrete Test {
tests/reduce.0rt view
@@ -763,21 +763,21 @@ }  unittest leftNestedInRight {-  \ Testing.checkEquals<?>(present(reduce<[A&B],[[A&B]|C]>(AB.create())),true)+  \ Testing.checkTrue(present(reduce<[A&B],[[A&B]|C]>(AB.create()))) }  unittest rightNestedInLeft {-  \ Testing.checkEquals<?>(present(reduce<[[A|B]&C],[A|B]>(AC.create())),true)+  \ Testing.checkTrue(present(reduce<[[A|B]&C],[A|B]>(AC.create()))) }  unittest unionToUnion {-  \ Testing.checkEquals<?>(present(reduce<[[A&B]|C],[[A&B]|C]>(AB.create())),true)+  \ Testing.checkTrue(present(reduce<[[A&B]|C],[[A&B]|C]>(AB.create()))) }  unittest intersectToIntersect {-  \ Testing.checkEquals<?>(present(reduce<[[A|B]&C],[[A|B]&C]>(AC.create())),true)+  \ Testing.checkTrue(present(reduce<[[A|B]&C],[[A|B]&C]>(AC.create()))) }  unittest unionToIntersect {-  \ Testing.checkEquals<?>(present(reduce<[A|B],[A&B]>(AB.create())),false)+  \ Testing.checkFalse(present(reduce<[A|B],[A&B]>(AB.create()))) }
tests/scoped.0rt view
@@ -396,7 +396,7 @@     value <- 1   } in Int value <- 2 -  \ Testing.checkEquals<?>(value,1)+  \ Testing.checkEquals(value,1) }  @@ -610,13 +610,13 @@         }       }     }-    \ Testing.checkEquals<?>(x,0)-    \ Testing.checkEquals<?>(y,2)-    \ Testing.checkEquals<?>(z,3)+    \ Testing.checkEquals(x,0)+    \ Testing.checkEquals(y,2)+    \ Testing.checkEquals(z,3)   }-  \ Testing.checkEquals<?>(x,1)-  \ Testing.checkEquals<?>(y,2)-  \ Testing.checkEquals<?>(z,3)+  \ Testing.checkEquals(x,1)+  \ Testing.checkEquals(y,2)+  \ Testing.checkEquals(z,3) }  @@ -634,8 +634,8 @@   } in {     while ((called <- called+1) < 3) {       if (called > 1) {-        \ Testing.checkEquals<?>(y,2)-        \ Testing.checkEquals<?>(z,3)+        \ Testing.checkEquals(y,2)+        \ Testing.checkEquals(z,3)       }       cleanup {         y <- 2@@ -647,14 +647,14 @@         }       }     }-    \ Testing.checkEquals<?>(called,3)-    \ Testing.checkEquals<?>(x,0)-    \ Testing.checkEquals<?>(y,2)-    \ Testing.checkEquals<?>(z,3)+    \ Testing.checkEquals(called,3)+    \ Testing.checkEquals(x,0)+    \ Testing.checkEquals(y,2)+    \ Testing.checkEquals(z,3)   }-  \ Testing.checkEquals<?>(x,1)-  \ Testing.checkEquals<?>(y,2)-  \ Testing.checkEquals<?>(z,3)+  \ Testing.checkEquals(x,1)+  \ Testing.checkEquals(y,2)+  \ Testing.checkEquals(z,3) }  @@ -667,16 +667,16 @@   scoped {     Int x, Int y, Int z <- value.call()   } in {-    \ Testing.checkEquals<?>(x,0)-    \ Testing.checkEquals<?>(y,0)-    \ Testing.checkEquals<?>(z,0)+    \ Testing.checkEquals(x,0)+    \ Testing.checkEquals(y,0)+    \ Testing.checkEquals(z,0)   }   scoped {     Int x, Int y, Int z <- value.get()   } in {-    \ Testing.checkEquals<?>(x,1)-    \ Testing.checkEquals<?>(y,2)-    \ Testing.checkEquals<?>(z,3)+    \ Testing.checkEquals(x,1)+    \ Testing.checkEquals(y,2)+    \ Testing.checkEquals(z,3)   } } 
tests/self-offset/Extension_Destructor.cpp view
@@ -24,21 +24,21 @@ namespace ZEOLITE_PUBLIC_NAMESPACE { #endif  // ZEOLITE_PUBLIC_NAMESPACE -BoxedValue CreateValue_Destructor(S<const Type_Destructor> parent, const ValueTuple& args);+BoxedValue CreateValue_Destructor(S<const Type_Destructor> parent);  struct ExtCategory_Destructor : public Category_Destructor { };  struct ExtType_Destructor : public Type_Destructor {   inline ExtType_Destructor(Category_Destructor& p, Params<0>::Type params) : Type_Destructor(p, params) {}-  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Destructor.new")-    return ReturnTuple(CreateValue_Destructor(PARAM_SELF, ArgTuple()));+    return ReturnTuple(CreateValue_Destructor(PARAM_SELF));   } };  struct ExtValue_Destructor : public Value_Destructor {-  inline ExtValue_Destructor(S<const Type_Destructor> p, const ValueTuple& args)+  inline ExtValue_Destructor(S<const Type_Destructor> p)     : Value_Destructor(std::move(p)) {}    ~ExtValue_Destructor() {@@ -58,8 +58,8 @@  void RemoveType_Destructor(const Params<0>::Type& params) {} -BoxedValue CreateValue_Destructor(S<const Type_Destructor> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_Destructor>(std::move(parent), args);+BoxedValue CreateValue_Destructor(S<const Type_Destructor> parent) {+  return BoxedValue::New<ExtValue_Destructor>(std::move(parent)); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
tests/self-offset/Extension_Offset.cpp view
@@ -32,7 +32,7 @@  }  // namespace -BoxedValue CreateValue_Offset(S<const Type_Offset> parent, const ValueTuple& args);+BoxedValue CreateValue_Offset(S<const Type_Offset> parent);  struct ExtCategory_Offset : public Category_Offset { };@@ -40,18 +40,18 @@ struct ExtType_Offset : public Type_Offset {   inline ExtType_Offset(Category_Offset& p, Params<0>::Type params) : Type_Offset(p, params) {} -  ReturnTuple Call_new(const ParamTuple& params, const ValueTuple& args) const final {+  ReturnTuple Call_new(const ParamsArgs& params_args) const final {     TRACE_FUNCTION("Offset.new")-    return ReturnTuple(CreateValue_Offset(PARAM_SELF, ArgTuple()));+    return ReturnTuple(CreateValue_Offset(PARAM_SELF));   } };  // Using virtual will (ideally) change the offset. struct ExtValue_Offset : public Base, virtual public Value_Offset {-  inline ExtValue_Offset(S<const Type_Offset> p, const ValueTuple& args)+  inline ExtValue_Offset(S<const Type_Offset> p)     : Value_Offset(std::move(p)) {} -  ReturnTuple Call_call(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_call(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Offset.call")     if ((void*) this == (void*) static_cast<TypeValue*>(this)) {       message = "same";@@ -61,7 +61,7 @@     return ReturnTuple(VAR_SELF);   } -  ReturnTuple Call_get(const ParamTuple& params, const ValueTuple& args) final {+  ReturnTuple Call_get(const ParamsArgs& params_args) final {     TRACE_FUNCTION("Offset.get")     return ReturnTuple(Box_String(message));   }@@ -79,8 +79,8 @@  void RemoveType_Offset(const Params<0>::Type& params) {} -BoxedValue CreateValue_Offset(S<const Type_Offset> parent, const ValueTuple& args) {-  return BoxedValue::New<ExtValue_Offset>(std::move(parent), args);+BoxedValue CreateValue_Offset(S<const Type_Offset> parent) {+  return BoxedValue::New<ExtValue_Offset>(std::move(parent)); }  #ifdef ZEOLITE_PUBLIC_NAMESPACE
tests/self-offset/offset.0rt view
@@ -21,7 +21,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(Offset.new().call().get(),"different")+  \ Testing.checkEquals(Offset.new().call().get(),"different") }  
tests/self-type.0rt view
@@ -221,10 +221,10 @@ unittest test {   Type<String>    value1 <- Type<String>.create()   Type<Formatted> value2 <- Type<Formatted>.create()-  \ Testing.checkEquals<?>(value1.checkFrom<Type<Formatted>>(),true)-  \ Testing.checkEquals<?>(value2.checkFrom<Type<String>>(),false)-  \ Testing.checkEquals<?>(value1.checkTo<?>(value2),false)-  \ Testing.checkEquals<?>(value2.checkTo<?>(value1),true)+  \ Testing.checkTrue(value1.checkFrom<Type<Formatted>>())+  \ Testing.checkFalse(value2.checkFrom<Type<String>>())+  \ Testing.checkFalse(value1.checkTo(value2))+  \ Testing.checkTrue(value2.checkTo(value1)) }  concrete Type<|#x> {@@ -253,7 +253,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(Type<Bool>.get(),"Type<Type<Bool>>")+  \ Testing.checkEquals(Type<Bool>.get(),"Type<Type<Bool>>") }  concrete Type<#x> {@@ -272,7 +272,7 @@ }  unittest test {-  \ Type.create().call<?>("message")+  \ Type.create().call("message") }  concrete Type {@@ -374,12 +374,12 @@  unittest withConcrete {   Type value <- Type.create()-  \ Testing.checkEquals<?>(value.next().prev().prev().next().next().get(),1)+  \ Testing.checkEquals(value.next().prev().prev().next().next().get(),1) }  unittest withIntersect {   [Cell<Int>&Forward&Reverse] value <- Type.create()-  \ Testing.checkEquals<?>(value.next().prev().prev().next().next().get(),1)+  \ Testing.checkEquals(value.next().prev().prev().next().next().get(),1) }  @value interface Cell<|#x> {@@ -431,7 +431,7 @@  unittest test {   Type value <- Helper.new<Type>()-  \ Testing.checkEquals<?>((value `Advance.by<?>` 3).get(),3)+  \ Testing.checkEquals((value `Advance.by` 3).get(),3) }  @value interface Forward {
tests/traces/README.md view
@@ -12,6 +12,6 @@  Note that there *will* be warnings about unreachable code. -You can then examine `zeolite --show-traces $ZEOLITE_PATH/tests/traces` to see-what trace contexts `zeolite` picked up during compilation. Every line that is-commented with `TRACED` should have an entry in `--show-traces`.+You can then examine `zeolite -p $ZEOLITE_PATH --show-traces tests/traces` to+see what trace contexts `zeolite` picked up during compilation. Every line that+is commented with `TRACED` should have an entry in `--show-traces`.
tests/traverse.0rt view
@@ -25,7 +25,7 @@   traverse (Counter.zeroIndexed(5) -> Int i) {     total <- total+i   }-  \ Testing.checkEquals<?>(total,10)+  \ Testing.checkEquals(total,10) }  unittest ignoreValue {@@ -33,7 +33,7 @@   traverse (Counter.zeroIndexed(5) -> _) {     total <- total+1   }-  \ Testing.checkEquals<?>(total,5)+  \ Testing.checkEquals(total,5) }  unittest existingVariable {@@ -42,8 +42,8 @@   traverse (Counter.zeroIndexed(5) -> i) {     total <- total+i   }-  \ Testing.checkEquals<?>(total,10)-  \ Testing.checkEquals<?>(i,4)+  \ Testing.checkEquals(total,10)+  \ Testing.checkEquals(i,4) }  unittest breakAtLimit {@@ -54,7 +54,7 @@     }     total <- total+i   }-  \ Testing.checkEquals<?>(total,10)+  \ Testing.checkEquals(total,10) }  unittest continueOnOdd {@@ -65,7 +65,7 @@     }     total <- total+i   }-  \ Testing.checkEquals<?>(total,20)+  \ Testing.checkEquals(total,20) }  unittest withUpdate {@@ -77,7 +77,7 @@   } update {     total <- total+i   }-  \ Testing.checkEquals<?>(total,45)+  \ Testing.checkEquals(total,45) }  unittest overwriteVisibleValue {@@ -86,7 +86,7 @@     // i shouldn't be overwritten after the last iteration.     i <- 0   }-  \ Testing.checkEquals<?>(i,0)+  \ Testing.checkEquals(i,0) }  unittest overwriteLocalValue {@@ -95,7 +95,7 @@     i <- 0   } update {     // i should also be visible here.-    \ Testing.checkEquals<?>(i,0)+    \ Testing.checkEquals(i,0)   } } @@ -191,7 +191,7 @@     traverse (Counter.new() -> Int i) {       total <- total+i     }-    \ Testing.checkEquals<?>(total,10)+    \ Testing.checkEquals(total,10)   } } @@ -242,7 +242,7 @@     traverse (Counter.new() -> Int i) {       total <- total+i     }-    \ Testing.checkEquals<?>(total,10)+    \ Testing.checkEquals(total,10)   } } @@ -280,7 +280,7 @@ }  unittest test {-  \ Testing.checkEquals<?>(Test.run<?>("message"),"message")+  \ Testing.checkEquals(Test.run("message"),"message") }  concrete Test {@@ -291,10 +291,10 @@   run (x) (i) {     i <- x     Int total <- 0-    traverse (Repeat:times<?>(x,10) -> i) {+    traverse (Repeat:times(x,10) -> i) {       total <- total+1     }-    \ Testing.checkEquals<?>(total,10)+    \ Testing.checkEquals(total,10)   } } 
tests/typename.0rt view
@@ -21,49 +21,49 @@ }  unittest string {-  \ Testing.checkEquals<?>(typename<String>().formatted(),"String")+  \ Testing.checkEquals(typename<String>().formatted(),"String") }  unittest int {-  \ Testing.checkEquals<?>(typename<Int>().formatted(),"Int")+  \ Testing.checkEquals(typename<Int>().formatted(),"Int") }  unittest char {-  \ Testing.checkEquals<?>(typename<Char>().formatted(),"Char")+  \ Testing.checkEquals(typename<Char>().formatted(),"Char") }  unittest charBuffer {-  \ Testing.checkEquals<?>(typename<CharBuffer>().formatted(),"CharBuffer")+  \ Testing.checkEquals(typename<CharBuffer>().formatted(),"CharBuffer") }  unittest float {-  \ Testing.checkEquals<?>(typename<Float>().formatted(),"Float")+  \ Testing.checkEquals(typename<Float>().formatted(),"Float") }  unittest bool {-  \ Testing.checkEquals<?>(typename<Bool>().formatted(),"Bool")+  \ Testing.checkEquals(typename<Bool>().formatted(),"Bool") }  unittest anyType {-  \ Testing.checkEquals<?>(typename<any>().formatted(),"any")+  \ Testing.checkEquals(typename<any>().formatted(),"any") }  unittest allType {-  \ Testing.checkEquals<?>(typename<all>().formatted(),"all")+  \ Testing.checkEquals(typename<all>().formatted(),"all") }  unittest intersectDedup {-  \ Testing.checkEquals<?>(typename<[AsBool&Char&Formatted&Int]>().formatted(),+  \ Testing.checkEquals(typename<[AsBool&Char&Formatted&Int]>().formatted(),                            typename<[Char&Int]>().formatted()) }  unittest unionDedup {-  \ Testing.checkEquals<?>(typename<[AsBool|Char|Formatted|Int]>().formatted(),+  \ Testing.checkEquals(typename<[AsBool|Char|Formatted|Int]>().formatted(),                            typename<[AsBool|Formatted]>().formatted()) }  unittest param {-  \ Testing.checkEquals<?>(Wrapped:getTypename<String,Value<Int>>().formatted(),+  \ Testing.checkEquals(Wrapped:getTypename<String,Value<Int>>().formatted(),                            "Type<String,Value<Int>>") } @@ -82,11 +82,11 @@ }  unittest intersectDedupParam {-  \ Testing.checkEquals<?>(Wrapped:getTypenameIntersect<Int,Int>().formatted(),"Int")+  \ Testing.checkEquals(Wrapped:getTypenameIntersect<Int,Int>().formatted(),"Int") }  unittest unionDedupParam {-  \ Testing.checkEquals<?>(Wrapped:getTypenameUnion<Int,Int>().formatted(),"Int")+  \ Testing.checkEquals(Wrapped:getTypenameUnion<Int,Int>().formatted(),"Int") }  @value interface Value<#x> {}
zeolite-lang.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.2  name:                zeolite-lang-version:             0.20.0.1+version:             0.21.0.0 synopsis:            Zeolite is a statically-typed, general-purpose programming language.  description:@@ -145,6 +145,9 @@                      tests/check-defs/*.0rx,                      tests/fast-static/README.md,                      tests/fast-static/*.0rx,+                     tests/freshness/.zeolite-module,+                     tests/freshness/README.md,+                     tests/freshness/reverse/.zeolite-module,                      tests/leak-check/README.md,                      tests/leak-check/.zeolite-module,                      tests/leak-check/*.0rx,@@ -252,8 +255,10 @@                        CompilerCxx.LanguageModule,                        CompilerCxx.Naming,                        CompilerCxx.Procedure,+                       Config.CompilerConfig,                        Config.LoadConfig,                        Config.LocalConfig,+                       Config.ParseConfig,                        Module.CompileMetadata,                        Module.ParseMetadata,                        Module.Paths,@@ -271,6 +276,7 @@                        Test.DefinedCategory,                        Test.IntegrationTest,                        Test.MergeTree,+                       Test.ParseConfig,                        Test.ParseMetadata,                        Test.Parser,                        Test.Pragma,@@ -344,6 +350,7 @@   build-depends:       base,                        directory,                        filepath,+                       mtl,                        zeolite-internal