packages feed

zeolite-lang 0.4.0.0 → 0.4.1.0

raw patch · 45 files changed

+1540/−230 lines, 45 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Cli.CompileOptions: CompileFast :: String -> String -> String -> CompileMode
+ Cli.CompileOptions: CompileRecompileRecursive :: CompileMode
+ Cli.CompileOptions: [cfCategory] :: CompileMode -> String
+ Cli.CompileOptions: [cfFunction] :: CompileMode -> String
+ Cli.CompileOptions: [cfSource] :: CompileMode -> String
+ Cli.CompileOptions: isCompileFast :: CompileMode -> Bool
+ Cli.ProcessMetadata: loadTestingDeps :: String -> String -> IO (Bool, [CompileMetadata])

Files

ChangeLog.md view
@@ -1,5 +1,28 @@ # Revision history for zeolite-lang +## 0.4.1.0  -- 2020-05-05++* **[new]** Adds a compiler mode (`--show-deps`) to display the symbolic+  dependencies of a module.++* **[new]** Adds a compiler mode (`--fast`) to quickly compile a binary from a+  single source file without needing to create a module.++* **[new]** Adds a compiler mode (`-R`) to recursively recompile modules.++* **[new]** Improves thread-safety of internal code so that thread support can+  be safely added later. (Probably via a library.)++* **[new]** Adds the `Builder` interface to make `String` concatenation more+  efficient.++* **[new]** Adds support for basic mathematical `Float` operations, such as+  `sin`, `exp`, and `sqrt`.++* **[new]** Adds support for bitwise `Int` operations.++* **[fix]** Fixes broken `--templates` mode when builtin types are used.+ ## 0.4.0.0  -- 2020-05-05  * **[new]** Allows modules to specify custom linker flags and private include
base/.zeolite-module view
@@ -21,7 +21,6 @@     source: "base/Category_String.cpp"     categories: [String]   }-  "base/argv.cpp"   "base/category-header.hpp"   "base/category-source.cpp"   "base/category-source.hpp"
base/Category_Bool.cpp view
@@ -116,10 +116,8 @@   ReturnTuple Call_equals(const ParamTuple& params, const ValueTuple& args); }; Type_Bool& CreateType_Bool(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_Bool>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_Bool(CreateCategory_Bool(), params)); }-  return *cached;+  static auto& cached = *new Type_Bool(CreateCategory_Bool(), Params<0>::Type());+  return cached; } struct Value_Bool : public TypeValue {   Value_Bool(Type_Bool& p, bool value) : parent(p), value_(value) {}
base/Category_Char.cpp view
@@ -132,10 +132,8 @@   ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args); }; Type_Char& CreateType_Char(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_Char>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_Char(CreateCategory_Char(), params)); }-  return *cached;+  static auto& cached = *new Type_Char(CreateCategory_Char(), Params<0>::Type());+  return cached; } struct Value_Char : public TypeValue {   Value_Char(Type_Char& p, PrimChar value) : parent(p), value_(value) {}
base/Category_Float.cpp view
@@ -127,10 +127,8 @@   ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args); }; Type_Float& CreateType_Float(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_Float>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_Float(CreateCategory_Float(), params)); }-  return *cached;+  static auto& cached = *new Type_Float(CreateCategory_Float(), Params<0>::Type());+  return cached; } struct Value_Float : public TypeValue {   Value_Float(Type_Float& p, PrimFloat value) : parent(p), value_(value) {}
base/Category_Int.cpp view
@@ -132,10 +132,8 @@   ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args); }; Type_Int& CreateType_Int(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_Int>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_Int(CreateCategory_Int(), params)); }-  return *cached;+  static auto& cached = *new Type_Int(CreateCategory_Int(), Params<0>::Type());+  return cached; } struct Value_Int : public TypeValue {   Value_Int(Type_Int& p, PrimInt value) : parent(p), value_(value) {}
base/Category_String.cpp view
@@ -28,6 +28,7 @@ #include "Category_Char.hpp" #include "Category_Equals.hpp" #include "Category_LessThan.hpp"+#include "Category_Builder.hpp"   #ifdef ZEOLITE_DYNAMIC_NAMESPACE@@ -38,6 +39,7 @@ }  // namespace const void* const Functions_String = &collection_String; const ValueFunction& Function_String_subSequence = (*new ValueFunction{ 0, 2, 1, "String", "subSequence", Functions_String, 0 });+const TypeFunction& Function_String_builder = (*new TypeFunction{ 0, 0, 1, "String", "builder", Functions_String, 0 }); namespace { class Category_String; class Type_String;@@ -106,6 +108,9 @@     static const CallType Table_LessThan[] = {       &Type_String::Call_lessThan,     };+    static const CallType Table_String[] = {+      &Type_String::Call_builder,+    };     if (label.collection == Functions_Equals) {       if (label.function_num < 0 || label.function_num >= 1) {         FAIL() << "Bad function call " << label;@@ -118,16 +123,21 @@       }       return (this->*Table_LessThan[label.function_num])(params, args);     }+    if (label.collection == Functions_String) {+      if (label.function_num < 0 || label.function_num >= 1) {+        FAIL() << "Bad function call " << label;+      }+      return (this->*Table_String[label.function_num])(params, args);+    }     return TypeInstance::Dispatch(label, params, args);   }+  ReturnTuple Call_builder(const ParamTuple& params, const ValueTuple& args);   ReturnTuple Call_equals(const ParamTuple& params, const ValueTuple& args);   ReturnTuple Call_lessThan(const ParamTuple& params, const ValueTuple& args); }; Type_String& CreateType_String(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_String>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_String(CreateCategory_String(), params)); }-  return *cached;+  static auto& cached = *new Type_String(CreateCategory_String(), Params<0>::Type());+  return cached; } struct Value_String : public TypeValue {   Value_String(Type_String& p, const PrimString& value) : parent(p), value_(value) {}@@ -183,6 +193,43 @@   Type_String& parent;   const PrimString value_; };++class Value_StringBuilder : public TypeValue {+ public:+  std::string CategoryName() const final { return "StringBuilder"; }++  ReturnTuple Dispatch(const S<TypeValue>& self,+                       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";+    }+    if (&label == &Function_Builder_append) {+      TRACE_FUNCTION("StringBuilder.append")+      std::lock_guard<std::mutex> lock(mutex);+      output_ << args.At(0)->AsString();+      return ReturnTuple(self);+    }+    if (&label == &Function_Builder_build) {+      TRACE_FUNCTION("SimpleOutput.build")+      std::lock_guard<std::mutex> lock(mutex);+      return ReturnTuple(Box_String(output_.str()));+    }+    return TypeValue::Dispatch(self, label, params, args);+  }++ private:+  std::mutex mutex;+  std::ostringstream output_;+};++ReturnTuple Type_String::Call_builder(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("String.builder")+  return ReturnTuple(S<TypeValue>(new Value_StringBuilder));+} ReturnTuple Type_String::Call_equals(const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("String.equals")   const S<TypeValue>& Var_arg1 = (args.At(0));
− base/argv.cpp
@@ -1,42 +0,0 @@-/* ------------------------------------------------------------------------------Copyright 2020 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 "argv.hpp"-#include "logging.hpp"---int Argv::ArgCount() {-  if (GetCurrent()) {-    return GetCurrent()->GetArgs().size();-  } else {-    return 0;-  }-}--const std::string& Argv::GetArgAt(int pos) {-  if (pos < 0 || pos >= ArgCount()) {-    FAIL() << "Argv index " << pos << " is out of bounds";-    __builtin_unreachable();-  } else {-    return GetCurrent()->GetArgs()[pos];-  }-}--const std::vector<std::string>& ProgramArgv::GetArgs() const {-  return argv_;-}
− base/argv.hpp
@@ -1,52 +0,0 @@-/* ------------------------------------------------------------------------------Copyright 2020 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 ARGV_HPP_-#define ARGV_HPP_--#include <string>-#include <vector>--#include "thread-capture.h"---class Argv : public capture_thread::ThreadCapture<Argv> {- public:-  static int ArgCount();-  static const std::string& GetArgAt(int pos);-- protected:-  virtual ~Argv() = default;-- private:-  virtual const std::vector<std::string>& GetArgs() const = 0;-};--class ProgramArgv : public Argv {- public:-  inline ProgramArgv(int argc, const char** argv)-    : argv_(argv, argv + argc), capture_to_(this) {}-- private:-  const std::vector<std::string>& GetArgs() const final;--  const std::vector<std::string> argv_;-  const ScopedCapture capture_to_;-};--#endif  // ARGV_HPP_
base/builtin.0rp view
@@ -66,6 +66,7 @@   defines LessThan<String>    @value subSequence (Int,Int) -> (String)+  @type builder () -> (Builder<String>) }  @value interface AsBool {@@ -92,6 +93,11 @@   readPosition (Int) -> (#x)   readSize () -> (Int)   subSequence (Int,Int) -> (ReadPosition<#x>)+}++@value interface Builder<#x> {+  append (#x) -> (Builder<#x>)+  build () -> (#x) }  @type interface Equals<#x|> {
base/category-source.hpp view
@@ -20,12 +20,12 @@ #define CATEGORY_SOURCE_HPP_  #include <map>+#include <mutex> #include <sstream> #include <vector>  #include "types.hpp" #include "function.hpp"-#include "argv.hpp" #include "cycle-check.hpp"  
base/logging.cpp view
@@ -22,9 +22,7 @@ #include <csignal> #include <iostream> -#include "argv.hpp" - LogThenCrash::LogThenCrash(bool fail, const std::string& condition)     : fail_(fail), signal_(SIGABRT), condition_(condition) {} @@ -120,7 +118,7 @@ }  const TraceContext* SourceContext::GetNext() const {-  return cross_and_capture_to_.Previous();+  return capture_to_.Previous(); }  @@ -139,5 +137,26 @@ }  const TraceContext* CleanupContext::GetNext() const {-  return cross_and_capture_to_.Previous();+  return capture_to_.Previous();+}++int Argv::ArgCount() {+  if (GetCurrent()) {+    return GetCurrent()->GetArgs().size();+  } else {+    return 0;+  }+}++const std::string& Argv::GetArgAt(int pos) {+  if (pos < 0 || pos >= ArgCount()) {+    FAIL() << "Argv index " << pos << " is out of bounds";+    __builtin_unreachable();+  } else {+    return GetCurrent()->GetArgs()[pos];+  }+}++const std::vector<std::string>& ProgramArgv::GetArgs() const {+  return argv_; }
base/logging.hpp view
@@ -22,6 +22,7 @@ #include <list> #include <sstream> #include <string>+#include <vector>  #include "thread-capture.h" @@ -108,7 +109,7 @@  public:   template<int S>   inline SourceContext(const char(&name)[S])-    : at_(nullptr), name_(name), cross_and_capture_to_(this) {}+    : at_(nullptr), name_(name), capture_to_(this) {}   private:   void SetLocal(const char*) final;@@ -117,13 +118,13 @@    const char* at_;   const char* const name_;-  const AutoThreadCrosser cross_and_capture_to_;+  const ScopedCapture capture_to_; };  class CleanupContext : public TraceContext {  public:   inline CleanupContext()-    : at_(nullptr), cross_and_capture_to_(this) {}+    : at_(nullptr), capture_to_(this) {}   private:   void SetLocal(const char*) final;@@ -131,7 +132,31 @@   const TraceContext* GetNext() const final;    const char* at_;-  const AutoThreadCrosser cross_and_capture_to_;+  const ScopedCapture capture_to_;+};++class Argv : public capture_thread::ThreadCapture<Argv> {+ public:+  static int ArgCount();+  static const std::string& GetArgAt(int pos);++ protected:+  virtual ~Argv() = default;++ private:+  virtual const std::vector<std::string>& GetArgs() const = 0;+};++class ProgramArgv : public Argv {+ public:+  inline ProgramArgv(int argc, const char** argv)+    : argv_(argv, argv + argc), capture_to_(this) {}++ private:+  const std::vector<std::string>& GetArgs() const final;++  const std::vector<std::string> argv_;+  const ScopedCapture capture_to_; };  #endif  // LOGGING_HPP_
bin/zeolite-setup.hs view
@@ -53,13 +53,14 @@ libraries :: [String] libraries = [     "base",-    "lib/util",-    "lib/file",     "tests/visibility/internal",     "tests/visibility",     "tests/visibility2/internal",     "tests/visibility2",-    "tests"+    "tests",+    "lib/util",+    "lib/file",+    "lib/math"   ]  createConfig :: IO LocalConfig
lib/file/Category_RawFileReader.cpp view
@@ -109,10 +109,8 @@   ReturnTuple Call_open(const ParamTuple& params, const ValueTuple& args); }; Type_RawFileReader& CreateType(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_RawFileReader>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_RawFileReader(CreateCategory(), params)); }-  return *cached;+  static auto& cached = *new Type_RawFileReader(CreateCategory(), Params<0>::Type());+  return cached; } struct Value_RawFileReader : public TypeValue {   Value_RawFileReader(Type_RawFileReader& p, const ParamTuple& params, const ValueTuple& args)@@ -157,6 +155,7 @@   ReturnTuple Call_readBlock(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args);   Type_RawFileReader& parent; +  std::mutex mutex;   R<std::istream> file; }; S<TypeValue> CreateValue(Type_RawFileReader& parent, const ParamTuple& params, const ValueTuple& args) {@@ -170,6 +169,7 @@  ReturnTuple Value_RawFileReader::Call_freeResource(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("RawFileReader.freeResource")+  std::lock_guard<std::mutex> lock(mutex);   if (file) {     file = nullptr;   }@@ -178,6 +178,7 @@  ReturnTuple Value_RawFileReader::Call_getFileError(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("RawFileReader.getFileError")+  std::lock_guard<std::mutex> lock(mutex);   if (!file) {     return ReturnTuple(Box_String(PrimString_FromLiteral("file has already been closed")));   }@@ -192,11 +193,13 @@  ReturnTuple Value_RawFileReader::Call_pastEnd(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("RawFileReader.pastEnd")+  std::lock_guard<std::mutex> lock(mutex);   return ReturnTuple(Box_Bool(!file || file->fail() || file->eof())); }  ReturnTuple Value_RawFileReader::Call_readBlock(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("RawFileReader.readBlock")+  std::lock_guard<std::mutex> lock(mutex);   const PrimInt Var_arg1 = (args.At(0))->AsInt();   if (Var_arg1 < 0) {     FAIL() << "Read size " << Var_arg1 << " is invalid";
lib/file/Category_RawFileWriter.cpp view
@@ -109,10 +109,8 @@   ReturnTuple Call_open(const ParamTuple& params, const ValueTuple& args); }; Type_RawFileWriter& CreateType(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_RawFileWriter>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_RawFileWriter(CreateCategory(), params)); }-  return *cached;+  static auto& cached = *new Type_RawFileWriter(CreateCategory(), Params<0>::Type());+  return cached; } struct Value_RawFileWriter : public TypeValue {   Value_RawFileWriter(Type_RawFileWriter& p, const ParamTuple& params, const ValueTuple& args)@@ -155,6 +153,7 @@   ReturnTuple Call_writeBlock(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args);   Type_RawFileWriter& parent; +  std::mutex mutex;   R<std::ostream> file; }; S<TypeValue> CreateValue(Type_RawFileWriter& parent, const ParamTuple& params, const ValueTuple& args) {@@ -167,6 +166,7 @@ } ReturnTuple Value_RawFileWriter::Call_freeResource(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("RawFileWriter.freeResource")+  std::lock_guard<std::mutex> lock(mutex);   if (file) {     file = nullptr;   }@@ -174,6 +174,7 @@ } ReturnTuple Value_RawFileWriter::Call_getFileError(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("RawFileWriter.getFileError")+  std::lock_guard<std::mutex> lock(mutex);   if (!file) {     return ReturnTuple(Box_String(PrimString_FromLiteral("file has already been closed")));   }@@ -187,6 +188,7 @@ } ReturnTuple Value_RawFileWriter::Call_writeBlock(const S<TypeValue>& Var_self, const ParamTuple& params, const ValueTuple& args) {   TRACE_FUNCTION("RawFileWriter.writeBlock")+  std::lock_guard<std::mutex> lock(mutex);   const PrimString& Var_arg1 = args.At(0)->AsString();   int write_size = 0;   if (file) {
+ lib/math/.zeolite-module view
@@ -0,0 +1,12 @@+root: "../.."+path: "lib/math"+private_deps: [+  "../../tests"+]+extra_files: [+  category_source {+    source: "lib/math/Category_Math.cpp"+    categories: [Math]+  }+]+mode: incremental {}
+ lib/math/Category_Math.cpp view
@@ -0,0 +1,361 @@+/* -----------------------------------------------------------------------------+Copyright 2020 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 <cmath>++#include "category-source.hpp"+#include "Category_Float.hpp"+#include "Category_Formatted.hpp"+#include "Category_Math.hpp"+#include "Category_String.hpp"++#ifdef ZEOLITE_DYNAMIC_NAMESPACE+namespace ZEOLITE_DYNAMIC_NAMESPACE {+#endif  // ZEOLITE_DYNAMIC_NAMESPACE++namespace {+const int collection_Math = 0;+}  // namespace+const void* const Functions_Math = &collection_Math;+const TypeFunction& Function_Math_acos = (*new TypeFunction{ 0, 1, 1, "Math", "acos", Functions_Math, 0 });+const TypeFunction& Function_Math_acosh = (*new TypeFunction{ 0, 1, 1, "Math", "acosh", Functions_Math, 1 });+const TypeFunction& Function_Math_asin = (*new TypeFunction{ 0, 1, 1, "Math", "asin", Functions_Math, 2 });+const TypeFunction& Function_Math_asinh = (*new TypeFunction{ 0, 1, 1, "Math", "asinh", Functions_Math, 3 });+const TypeFunction& Function_Math_atan = (*new TypeFunction{ 0, 1, 1, "Math", "atan", Functions_Math, 4 });+const TypeFunction& Function_Math_atanh = (*new TypeFunction{ 0, 1, 1, "Math", "atanh", Functions_Math, 5 });+const TypeFunction& Function_Math_ceil = (*new TypeFunction{ 0, 1, 1, "Math", "ceil", Functions_Math, 6 });+const TypeFunction& Function_Math_cos = (*new TypeFunction{ 0, 1, 1, "Math", "cos", Functions_Math, 7 });+const TypeFunction& Function_Math_cosh = (*new TypeFunction{ 0, 1, 1, "Math", "cosh", Functions_Math, 8 });+const TypeFunction& Function_Math_exp = (*new TypeFunction{ 0, 1, 1, "Math", "exp", Functions_Math, 9 });+const TypeFunction& Function_Math_fabs = (*new TypeFunction{ 0, 1, 1, "Math", "fabs", Functions_Math, 10 });+const TypeFunction& Function_Math_floor = (*new TypeFunction{ 0, 1, 1, "Math", "floor", Functions_Math, 11 });+const TypeFunction& Function_Math_fmod = (*new TypeFunction{ 0, 2, 1, "Math", "fmod", Functions_Math, 12 });+const TypeFunction& Function_Math_isinf = (*new TypeFunction{ 0, 1, 1, "Math", "isinf", Functions_Math, 13 });+const TypeFunction& Function_Math_isnan = (*new TypeFunction{ 0, 1, 1, "Math", "isnan", Functions_Math, 14 });+const TypeFunction& Function_Math_log = (*new TypeFunction{ 0, 1, 1, "Math", "log", Functions_Math, 15 });+const TypeFunction& Function_Math_log10 = (*new TypeFunction{ 0, 1, 1, "Math", "log10", Functions_Math, 16 });+const TypeFunction& Function_Math_log2 = (*new TypeFunction{ 0, 1, 1, "Math", "log2", Functions_Math, 17 });+const TypeFunction& Function_Math_pow = (*new TypeFunction{ 0, 2, 1, "Math", "pow", Functions_Math, 18 });+const TypeFunction& Function_Math_round = (*new TypeFunction{ 0, 1, 1, "Math", "round", Functions_Math, 19 });+const TypeFunction& Function_Math_sin = (*new TypeFunction{ 0, 1, 1, "Math", "sin", Functions_Math, 20 });+const TypeFunction& Function_Math_sinh = (*new TypeFunction{ 0, 1, 1, "Math", "sinh", Functions_Math, 21 });+const TypeFunction& Function_Math_sqrt = (*new TypeFunction{ 0, 1, 1, "Math", "sqrt", Functions_Math, 22 });+const TypeFunction& Function_Math_tan = (*new TypeFunction{ 0, 1, 1, "Math", "tan", Functions_Math, 23 });+const TypeFunction& Function_Math_tanh = (*new TypeFunction{ 0, 1, 1, "Math", "tanh", Functions_Math, 24 });+const TypeFunction& Function_Math_trunc = (*new TypeFunction{ 0, 1, 1, "Math", "trunc", Functions_Math, 25 });+namespace {+class Category_Math;+class Type_Math;+Type_Math& CreateType_Math(Params<0>::Type params);+class Value_Math;+S<TypeValue> CreateValue_Math(Type_Math& parent, const ParamTuple& params, const ValueTuple& args);+struct Category_Math : public TypeCategory {+  std::string CategoryName() const final { return "Math"; }+  Category_Math() {+    CycleCheck<Category_Math>::Check();+    CycleCheck<Category_Math> marker(*this);+    TRACE_FUNCTION("Math (init @category)")+  }+  ReturnTuple Dispatch(const CategoryFunction& label, const ParamTuple& params, const ValueTuple& args) final {+    using CallType = ReturnTuple(Category_Math::*)(const ParamTuple&, const ValueTuple&);+    return TypeCategory::Dispatch(label, params, args);+  }+};+Category_Math& CreateCategory_Math() {+  static auto& category = *new Category_Math();+  return category;+}+struct Type_Math : public TypeInstance {+  std::string CategoryName() const final { return parent.CategoryName(); }+  void BuildTypeName(std::ostream& output) const final {+    return TypeInstance::TypeNameFrom(output, parent);+  }+  Category_Math& parent;+  bool CanConvertFrom(const TypeInstance& from) const final {+    std::vector<const TypeInstance*> args;+    if (!from.TypeArgsForParent(parent, args)) return false;+    if(args.size() != 0) {+      FAIL() << "Wrong number of args (" << args.size() << ")  for " << CategoryName();+    }+    return true;+  }+  bool TypeArgsForParent(const TypeCategory& category, std::vector<const TypeInstance*>& args) const final {+    if (&category == &GetCategory_Math()) {+      args = std::vector<const TypeInstance*>{};+      return true;+    }+    return false;+  }+  Type_Math(Category_Math& p, Params<0>::Type params) : parent(p) {+    CycleCheck<Type_Math>::Check();+    CycleCheck<Type_Math> marker(*this);+    TRACE_FUNCTION("Math (init @type)")+  }+  ReturnTuple Dispatch(const TypeFunction& label, const ParamTuple& params, const ValueTuple& args) final {+    using CallType = ReturnTuple(Type_Math::*)(const ParamTuple&, const ValueTuple&);+    static const CallType Table_Math[] = {+      &Type_Math::Call_acos,+      &Type_Math::Call_acosh,+      &Type_Math::Call_asin,+      &Type_Math::Call_asinh,+      &Type_Math::Call_atan,+      &Type_Math::Call_atanh,+      &Type_Math::Call_ceil,+      &Type_Math::Call_cos,+      &Type_Math::Call_cosh,+      &Type_Math::Call_exp,+      &Type_Math::Call_fabs,+      &Type_Math::Call_floor,+      &Type_Math::Call_fmod,+      &Type_Math::Call_isinf,+      &Type_Math::Call_isnan,+      &Type_Math::Call_log,+      &Type_Math::Call_log10,+      &Type_Math::Call_log2,+      &Type_Math::Call_pow,+      &Type_Math::Call_round,+      &Type_Math::Call_sin,+      &Type_Math::Call_sinh,+      &Type_Math::Call_sqrt,+      &Type_Math::Call_tan,+      &Type_Math::Call_tanh,+      &Type_Math::Call_trunc,+    };+    if (label.collection == Functions_Math) {+      if (label.function_num < 0 || label.function_num >= 26) {+        FAIL() << "Bad function call " << label;+      }+      return (this->*Table_Math[label.function_num])(params, args);+    }+    return TypeInstance::Dispatch(label, params, args);+  }+  ReturnTuple Call_acos(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_acosh(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_asin(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_asinh(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_atan(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_atanh(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_ceil(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_cos(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_cosh(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_exp(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_fabs(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_floor(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_fmod(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_isinf(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_isnan(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_log(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_log10(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_log2(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_pow(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_round(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_sin(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_sinh(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_sqrt(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_tan(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_tanh(const ParamTuple& params, const ValueTuple& args);+  ReturnTuple Call_trunc(const ParamTuple& params, const ValueTuple& args);+};+Type_Math& CreateType_Math(Params<0>::Type params) {+  static auto& cached = *new Type_Math(CreateCategory_Math(), Params<0>::Type());+  return cached;+}+struct Value_Math : public TypeValue {+  Value_Math(Type_Math& p, const ParamTuple& params, const ValueTuple& args) : parent(p) {}+  ReturnTuple Dispatch(const S<TypeValue>& self, const ValueFunction& label, const ParamTuple& params,const ValueTuple& args) final {+    using CallType = ReturnTuple(Value_Math::*)(const S<TypeValue>&, const ParamTuple&, const ValueTuple&);+    return TypeValue::Dispatch(self, label, params, args);+  }+  std::string CategoryName() const final { return parent.CategoryName(); }+  Type_Math& parent;+};+S<TypeValue> CreateValue_Math(Type_Math& parent, const ParamTuple& params, const ValueTuple& args) {+  return S_get(new Value_Math(parent, params, args));+}++ReturnTuple Type_Math::Call_acos(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.acos")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::acos(Var_arg1)));+}++ReturnTuple Type_Math::Call_acosh(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.acosh")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::acosh(Var_arg1)));+}++ReturnTuple Type_Math::Call_asin(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.asin")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::asin(Var_arg1)));+}++ReturnTuple Type_Math::Call_asinh(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.asinh")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::asinh(Var_arg1)));+}++ReturnTuple Type_Math::Call_atan(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.atan")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::atan(Var_arg1)));+}++ReturnTuple Type_Math::Call_atanh(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.atanh")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::atanh(Var_arg1)));+}++ReturnTuple Type_Math::Call_ceil(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.ceil")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::ceil(Var_arg1)));+}++ReturnTuple Type_Math::Call_cos(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.cos")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::cos(Var_arg1)));+}++ReturnTuple Type_Math::Call_cosh(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.cosh")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::cosh(Var_arg1)));+}++ReturnTuple Type_Math::Call_exp(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.exp")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::exp(Var_arg1)));+}++ReturnTuple Type_Math::Call_fabs(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.fabs")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::fabs(Var_arg1)));+}++ReturnTuple Type_Math::Call_floor(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.floor")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::floor(Var_arg1)));+}++ReturnTuple Type_Math::Call_fmod(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.fmod")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  const PrimFloat Var_arg2 = (args.At(1))->AsFloat();+  return ReturnTuple(Box_Float(std::fmod(Var_arg1,Var_arg2)));+}++ReturnTuple Type_Math::Call_isinf(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.isinf")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Bool(std::isinf(Var_arg1)));+}++ReturnTuple Type_Math::Call_isnan(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.isnan")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Bool(std::isnan(Var_arg1)));+}++ReturnTuple Type_Math::Call_log(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.log")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::log(Var_arg1)));+}++ReturnTuple Type_Math::Call_log10(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.log10")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::log10(Var_arg1)));+}++ReturnTuple Type_Math::Call_log2(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.log2")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::log2(Var_arg1)));+}++ReturnTuple Type_Math::Call_pow(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.pow")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  const PrimFloat Var_arg2 = (args.At(1))->AsFloat();+  return ReturnTuple(Box_Float(std::pow(Var_arg1,Var_arg2)));+}++ReturnTuple Type_Math::Call_round(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.round")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::round(Var_arg1)));+}++ReturnTuple Type_Math::Call_sin(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.sin")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::sin(Var_arg1)));+}++ReturnTuple Type_Math::Call_sinh(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.sinh")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::sinh(Var_arg1)));+}++ReturnTuple Type_Math::Call_sqrt(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.sqrt")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::sqrt(Var_arg1)));+}++ReturnTuple Type_Math::Call_tan(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.tan")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::tan(Var_arg1)));+}++ReturnTuple Type_Math::Call_tanh(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.tanh")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::tanh(Var_arg1)));+}++ReturnTuple Type_Math::Call_trunc(const ParamTuple& params, const ValueTuple& args) {+  TRACE_FUNCTION("Math.trunc")+  const PrimFloat Var_arg1 = (args.At(0))->AsFloat();+  return ReturnTuple(Box_Float(std::trunc(Var_arg1)));+}++}  // namespace++TypeCategory& GetCategory_Math() {+  return CreateCategory_Math();+}+TypeInstance& GetType_Math(Params<0>::Type params) {+  return CreateType_Math(params);+}++#ifdef ZEOLITE_DYNAMIC_NAMESPACE+}  // namespace ZEOLITE_DYNAMIC_NAMESPACE+using namespace ZEOLITE_DYNAMIC_NAMESPACE;+#endif  // ZEOLITE_DYNAMIC_NAMESPACE
+ lib/math/math.0rp view
@@ -0,0 +1,50 @@+/* -----------------------------------------------------------------------------+Copyright 2020 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]++concrete Math {+  @type cos (Float) -> (Float)+  @type sin (Float) -> (Float)+  @type tan (Float) -> (Float)+  @type acos (Float) -> (Float)+  @type asin (Float) -> (Float)+  @type atan (Float) -> (Float)++  @type cosh (Float) -> (Float)+  @type sinh (Float) -> (Float)+  @type tanh (Float) -> (Float)+  @type acosh (Float) -> (Float)+  @type asinh (Float) -> (Float)+  @type atanh (Float) -> (Float)++  @type exp (Float) -> (Float)+  @type log (Float) -> (Float)+  @type log10 (Float) -> (Float)+  @type log2 (Float) -> (Float)+  @type pow (Float,Float) -> (Float)+  @type sqrt (Float) -> (Float)++  @type ceil (Float) -> (Float)+  @type floor (Float) -> (Float)+  @type fmod (Float,Float) -> (Float)+  @type trunc (Float) -> (Float)+  @type round (Float) -> (Float)+  @type fabs (Float) -> (Float)++  @type isinf (Float) -> (Bool)+  @type isnan (Float) -> (Bool)+}
+ lib/math/tests.0rt view
@@ -0,0 +1,410 @@+/* -----------------------------------------------------------------------------+Copyright 2020 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 "sanity check cos" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$cos(2.0),-0.42,-0.41)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check sin" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$sin(2.0),0.90,0.91)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check tan" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$tan(2.0),-2.19,-2.18)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check acos" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$acos(0.5),1.04,1.05)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check asin" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$asin(0.5),0.52,0.53)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check atan" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$atan(0.5),0.46,0.47)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check cosh" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$cosh(2.0),3.76,3.77)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check sinh" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$sinh(2.0),3.62,3.63)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check tanh" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$tanh(2.0),0.96,0.97)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check acosh" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$acosh(2.0),1.31,1.32)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check asinh" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$asinh(2.0),1.44,1.45)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check atanh" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$atanh(0.5),0.54,0.55)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check exp" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$exp(1.0),2.71,2.72)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check log" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$log(9.0),2.19,2.20)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check log10" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$log10(100.0),1.99,2.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check log2" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$log2(8.0),2.99,3.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check pow" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$pow(2.0,3.0),7.99,8.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check sqrt" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$sqrt(4.0),1.99,2.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check ceil" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$ceil(2.2),2.99,3.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check floor" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$floor(2.2),1.99,2.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check fmod" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$fmod(7.0,4.0),2.99,3.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check trunc" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$trunc(2.2),1.99,2.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check round" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$round(2.7),2.99,3.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check fabs" {+  success Test$run()+}++define Test {+  run () {+   \ Testing$checkBetween<Float>(Math$fabs(-10.0),9.99,10.01)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check isinf" {+  success Test$run()+}++define Test {+  run () {+    if (!Math$isinf(Math$log(0.0))) {+      fail("Failed")+    }+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "sanity check isnan" {+  success Test$run()+}++define Test {+  run () {+    if (!Math$isnan(Math$sqrt(-1.0))) {+      fail("Failed")+    }+  }+}++concrete Test {+  @type run () -> ()+}
lib/util/Category_Argv.cpp view
@@ -107,10 +107,8 @@   } }; Type_Argv& CreateType(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_Argv>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_Argv(CreateCategory(), params)); }-  return *cached;+  static auto& cached = *new Type_Argv(CreateCategory(), Params<0>::Type());+  return cached; } struct Value_Argv : public TypeValue {   Value_Argv(Type_Argv& p, const ParamTuple& params, const ValueTuple& args) : parent(p) {}
lib/util/Category_SimpleInput.cpp view
@@ -104,10 +104,8 @@   } }; Type_SimpleInput& CreateType(Params<0>::Type params) {-  static auto& cache = *new InstanceMap<0,Type_SimpleInput>();-  auto& cached = cache[params];-  if (!cached) { cached = R_get(new Type_SimpleInput(CreateCategory(), params)); }-  return *cached;+  static auto& cached = *new Type_SimpleInput(CreateCategory(), Params<0>::Type());+  return cached; } struct Value_SimpleInput : public TypeValue {   Value_SimpleInput(Type_SimpleInput& p, const ParamTuple& params, const ValueTuple& args) : parent(p) {}@@ -123,6 +121,7 @@     }     if (&label == &Function_BlockReader_readBlock) {       TRACE_FUNCTION("SimpleInput.readBlock")+      std::lock_guard<std::mutex> lock(mutex);       const int size = args.At(0)->AsInt();       if (size < 0) {         FAIL() << "Read size " << size << " is invalid";@@ -137,6 +136,8 @@       }     }     if (&label == &Function_BlockReader_pastEnd) {+      TRACE_FUNCTION("SimpleInput.pastEnd")+      std::lock_guard<std::mutex> lock(mutex);       return ReturnTuple(Box_Bool(zero_read));     }     return TypeValue::Dispatch(self, label, params, args);@@ -144,6 +145,7 @@    std::string CategoryName() const final { return parent.CategoryName(); }   bool zero_read = false;+  std::mutex mutex;   Type_SimpleInput& parent; }; S<TypeValue> CreateValue(Type_SimpleInput& parent, const ParamTuple& params, const ValueTuple& args) {
lib/util/Category_SimpleOutput.cpp view
@@ -98,6 +98,7 @@     }     if (&label == &Function_Writer_write) {       TRACE_FUNCTION("SimpleOutput.write")+      std::lock_guard<std::mutex> lock(mutex_);       output_ << TypeValue::Call(args.At(0), Function_Formatted_formatted,                                  ParamTuple(), ArgTuple()).Only()->AsString();       return ReturnTuple();@@ -109,6 +110,7 @@   }   private:+  std::mutex mutex_;   std::ostream& output_; }; @@ -127,12 +129,14 @@     }     if (&label == &Function_Writer_write) {       TRACE_FUNCTION("SimpleOutput.write")+      std::lock_guard<std::mutex> lock(mutex_);       output_ << TypeValue::Call(args.At(0), Function_Formatted_formatted,                                  ParamTuple(), ArgTuple()).Only()->AsString();       return ReturnTuple();     }     if (&label == &Function_BufferedWriter_flush) {       TRACE_FUNCTION("SimpleOutput.flush")+      std::lock_guard<std::mutex> lock(mutex_);       FAIL() << output_.str();       return ReturnTuple();     }@@ -140,6 +144,7 @@   }   private:+  std::mutex mutex_;   std::ostringstream output_; }; 
src/Cli/CompileOptions.hs view
@@ -30,6 +30,7 @@   getSourceDeps,   getSourceFile,   isCompileBinary,+  isCompileFast,   isCompileIncremental,   isCompileRecompile,   isCreateTemplates,@@ -99,6 +100,11 @@     cbOutputName :: String,     cbLinkFlags :: [String]   } |+  CompileFast {+    cfCategory :: String,+    cfFunction :: String,+    cfSource :: String+  } |   ExecuteTests {     etInclude :: [String]   } |@@ -106,6 +112,7 @@     ciLinkFlags :: [String]   } |   CompileRecompile |+  CompileRecompileRecursive |   CreateTemplates |   CompileUnspecified   deriving (Eq,Show)@@ -114,13 +121,18 @@ isCompileBinary (CompileBinary _ _ _ _) = True isCompileBinary _                       = False +isCompileFast :: CompileMode -> Bool+isCompileFast (CompileFast _ _ _) = True+isCompileFast _                   = False+ isCompileIncremental :: CompileMode -> Bool isCompileIncremental (CompileIncremental _) = True isCompileIncremental _                      = False  isCompileRecompile :: CompileMode -> Bool-isCompileRecompile CompileRecompile = True-isCompileRecompile _                = False+isCompileRecompile CompileRecompile          = True+isCompileRecompile CompileRecompileRecursive = True+isCompileRecompile _                         = False  isExecuteTests :: CompileMode -> Bool isExecuteTests (ExecuteTests _) = True
src/Cli/Compiler.hs view
@@ -26,7 +26,7 @@ import System.Directory import System.Exit import System.FilePath-import System.Posix.Temp (mkstemps)+import System.Posix.Temp (mkdtemp,mkstemps) import System.IO import qualified Data.Set as Set @@ -67,11 +67,13 @@   processResults passed failed (mergeAllM $ map snd allResults) where     preloadModule b base d = do       m <- loadMetadata (p </> d)-      (fr1,deps1) <- loadPublicDeps (getCompilerHash b) [base,p </> d]+      (fr0,deps0) <- loadPublicDeps (getCompilerHash b) [base]+      checkAllowedStale fr0 f+      (fr1,deps1) <- loadTestingDeps (getCompilerHash b) (p </> d)       checkAllowedStale fr1 f-      (fr2,deps2) <- loadPrivateDeps (getCompilerHash b) deps1+      (fr2,deps2) <- loadPrivateDeps (getCompilerHash b) (deps0++deps1)       checkAllowedStale fr2 f-      return (d,m,deps1,deps2)+      return (d,m,deps0++deps1,deps2)     getTestsFromPreload (_,m,_,_) = cmTestFiles m     allowTests = Set.fromList tp     isTestAllowed t = if null allowTests then True else t `Set.member` allowTests@@ -99,6 +101,39 @@       | otherwise = do           hPutStrLn stderr $ "\nPassed: " ++ show passed ++ " test(s), Failed: " ++ show failed ++ " test(s)"           hPutStrLn stderr $ "Zeolite tests passed."+runCompiler (CompileOptions h is is2 _ _ _ p (CompileFast c fn f2) f) = do+  dir <- mkdtemp "/tmp/zfast_"+  absolute <- canonicalizePath p+  is' <- sequence $ map (canonicalizePath . (p </>)) is+  is2' <- sequence $ map (canonicalizePath . (p </>)) is2+  f2' <- canonicalizePath (p </> f2)+  let config = ModuleConfig {+      rmRoot = absolute,+      rmPath = dir,+      rmPublicDeps = is',+      rmPrivateDeps = is2',+      rmExtraFiles = [OtherSource f2'],+      rmExtraPaths = [],+      rmMode = (CompileBinary c fn (absolute </> c) [])+    }+  writeRecompile dir config+  runCompiler (CompileOptions h [] [] [dir] [] [] "" CompileRecompile f)+  removeDirectoryRecursive dir+runCompiler (CompileOptions h _ _ ds _ _ p CompileRecompileRecursive f) = do+  recursiveSequence Set.empty ds where+    recursiveSequence da (d0:ds2) = do+      d <- canonicalizePath (p </> d0)+      rm <- tryLoadRecompile d+      case rm of+           Nothing -> do+             hPutStrLn stderr $ "Path " ++ d ++ " does not have a valid configuration."+             exitFailure+           Just m -> when (not $ rmPath m `Set.member` da) $ do+             let ds3 = map (\d2 -> d </> d2) (rmPublicDeps m ++ rmPrivateDeps m)+             let da' = rmPath m `Set.insert` da+             recursiveSequence da' (ds3 ++ ds2)+             runCompiler (CompileOptions h [] [] [d] [] [] "" CompileRecompile f)+    recursiveSequence _ _ = return () runCompiler (CompileOptions h _ _ ds _ _ p CompileRecompile f) = do   (backend,_) <- loadConfig   fmap mergeAll $ sequence $ map (recompileSingle $ getCompilerHash backend) ds where@@ -108,7 +143,7 @@       upToDate <- isPathUpToDate h2 d       maybeCompile rm upToDate where         maybeCompile Nothing _ = do-          hPutStrLn stderr $ "Path " ++ d0 ++ " has not been configured or compiled yet."+          hPutStrLn stderr $ "Path " ++ d0 ++ " does not have a valid configuration."           exitFailure         maybeCompile (Just rm') upToDate           | f < ForceAll && upToDate = hPutStrLn stderr $ "Path " ++ d0 ++ " is up to date."@@ -137,18 +172,23 @@   (fr,deps) <- loadPublicDeps (getCompilerHash backend) (as ++ as2)   checkAllowedStale fr f   if isCreateTemplates m-      then sequence_ $ map (processTemplates deps) ds+      then do+        base <- resolveBaseModule resolver+        (fr2,bpDeps) <- loadPublicDeps (getCompilerHash backend) [base]+        checkAllowedStale fr2 f+        sequence_ $ map (processTemplates $ bpDeps ++ deps) ds       else do         ma <- sequence $ map (processPath backend resolver deps as as2) ds         let ms = concat $ map snd ma-        let deps2 = map fst ma-        createBinary backend resolver (deps ++ deps2) m ms+        let deps2 = map (snd . fst) ma+        let paths2 = concat $ map (fst . fst) ma+        createBinary backend resolver paths2 (deps ++ deps2) m ms   hPutStrLn stderr $ "Zeolite compilation succeeded." where     ep' = fixPaths $ map (p </>) ep     processPath b r deps as as2 d = do       isConfigured <- isPathConfigured d       when (isConfigured && f == DoNotForce) $ do-        hPutStrLn stderr $ "Module " ++ d ++ " has already been configured. " +++        hPutStrLn stderr $ "Module " ++ d ++ " has an existing configuration. " ++                            "Recompile with -r or use -f to overwrite the config."         exitFailure       eraseCachedData (p </> d)@@ -164,6 +204,9 @@       }       when (f == DoNotForce || f == ForceAll) $ writeRecompile (p </> d) rm       (ps,xs,ts) <- findSourceFiles p d+      ps2 <- sequence $ map canonicalizePath $ filter (isSuffixOf ".0rp") $ map ((p </>) . getSourceFile) es+      xs2 <- sequence $ map canonicalizePath $ filter (isSuffixOf ".0rx") $ map ((p </>) . getSourceFile) es+      ts2 <- sequence $ map canonicalizePath $ filter (isSuffixOf ".0rt") $ map ((p </>) . getSourceFile) es       base <- resolveBaseModule r       actual <- resolveModule r p d       isBase <- isBaseModule r actual@@ -177,15 +220,15 @@       let ss = fixPaths $ getSourceFilesForDeps deps2       ss' <- zipWithContents p ss       let paths = base:(getIncludePathsForDeps deps2)-      ps' <- zipWithContents p ps-      xs' <- zipWithContents p xs+      ps' <- zipWithContents p (ps ++ ps2)+      xs' <- zipWithContents p (xs ++ xs2)       ns0 <- canonicalizePath (p </> d) >>= return . StaticNamespace . publicNamespace       let ns2 = map StaticNamespace $ filter (not . null) $ getNamespacesForDeps deps       let fs = compileAll ns0 ns2 ss' ps' xs'       writeOutput b paths ns0 deps2 d as as2-                  (map takeFileName ps)-                  (map takeFileName xs)-                  (map takeFileName ts) fs+                  (map takeFileName ps ++ ps2)+                  (map takeFileName xs ++ xs2)+                  (map takeFileName ts ++ ts2) fs     writeOutput b paths ns0 deps d as as2 ps xs ts fs       | isCompileError fs = do           formatWarnings fs@@ -197,6 +240,7 @@           let (pc,mf,fs') = getCompileSuccess fs           let ss = map (\ns -> getCachedPath (p </> d) ns "") $ nub $ filter (not . null) $ map show $ [ns0] ++ map coNamespace fs'           ss' <- sequence $ map canonicalizePath ss+          s0 <- canonicalizePath $ getCachedPath (p </> d) (show ns0) ""           let paths' = paths ++ ep' ++ ss'           let hxx   = filter (isSuffixOf ".hpp" . coFilename)       fs'           let other = filter (not . isSuffixOf ".hpp" . coFilename) fs'@@ -216,7 +260,7 @@               cmPublicDeps = as,               cmPrivateDeps = as2,               cmCategories = sort $ map show pc,-              cmSubdirs = sort $ ss',+              cmSubdirs = [s0],               cmPublicFiles = sort ps,               cmPrivateFiles = sort xs,               cmTestFiles = sort ts,@@ -226,7 +270,7 @@               cmObjectFiles = os1' ++ osOther ++ map OtherObjectFile os'             }           when (not $ isCreateTemplates m) $ writeMetadata (p </> d) cm-          return (cm,mf)+          return ((ss',cm),mf)     formatWarnings c       | null $ getCompileWarnings c = return ()       | otherwise = hPutStr stderr $ "Compiler warnings:\n" ++ (concat $ map (++ "\n") (getCompileWarnings c))@@ -339,7 +383,7 @@     addIncludes tm fs = do       cs <- fmap concat $ collectAllOrErrorM $ map parsePublicSource fs       includeNewTypes tm cs-    createBinary b r deps (CompileBinary n _ o lf) ms+    createBinary b r paths deps (CompileBinary n _ o lf) ms       | length ms > 1 = do         hPutStrLn stderr $ "Multiple matches for main category " ++ n ++ "."         exitFailure@@ -359,15 +403,15 @@           (_,bpDeps) <- loadPublicDeps (getCompilerHash b) [base]           (_,deps2) <- loadPrivateDeps (getCompilerHash b) (bpDeps ++ deps)           let lf' = lf ++ getLinkFlagsForDeps deps2-          let paths = fixPaths $ base:(getIncludePathsForDeps deps2)+          let paths' = fixPaths $ paths ++ base:(getIncludePathsForDeps deps2)           let os    = getObjectFilesForDeps deps2           let ofr = getObjectFileResolver os           let os' = ofr ns2 req-          let command = CompileToBinary o' os' f0 paths lf'+          let command = CompileToBinary o' os' f0 paths' lf'           hPutStrLn stderr $ "Creating binary " ++ f0           _ <- runCxxCommand b command           removeFile o'-    createBinary _ _ _ _ _ = return ()+    createBinary _ _ _ _ _ _ = return ()     maybeCreateMain cm (CompileBinary n f2 _ _) =       fmap (:[]) $ compileModuleMain cm (CategoryName n) (FunctionName f2)     maybeCreateMain _ _ = return []
src/Cli/ParseCompileOptions.hs view
@@ -31,7 +31,9 @@ import Text.Regex.TDFA -- Not safe!  import Base.CompileError+import Cli.CompileMetadata import Cli.CompileOptions+import Cli.ProcessMetadata import Config.LoadConfig (compilerVersion,rootPath)  @@ -39,24 +41,33 @@ optionHelpText = [     "",     "zeolite [options...] -m [category(.function)] -o [binary] [path]",+    "zeolite [options...] --fast [category(.function)] [.0rx source]",     "zeolite [options...] -c [paths...]",     "zeolite [options...] -r [paths...]",+    "zeolite [options...] -R [paths...]",     "zeolite [options...] -t [paths...]",+    "",     "zeolite [options...] --templates [paths...]",     "zeolite --get-path",+    "zeolite --show-deps [paths...]",     "zeolite --version",     "",-    "Modes:",+    "Normal Modes:",     "  -c: Only compile the individual files. (default)",     "  -m [category(.function)]: Create a binary that executes the function.",+    "  --fast [category(.function)] [.0rx source]: Create a binary without needing a module.",     "  -r: Recompile using the previous compilation options.",+    "  -R: Recursively recompile using the previous compilation options.",     "  -t: Only execute tests, without other compilation.",+    "",+    "Special Modes:",     "  --templates: Only create C++ templates for undefined categories in .0rp sources.",     "  --get-path: Show the data path and immediately exit.",+    "  --show-deps: Show category dependencies for the modules.",     "  --version: Show the compiler version and immediately exit.",     "",     "Options:",-    "  -f: Force compilation instead of recompiling with -r.",+    "  -f: Force compilation instead of recompiling with -r/-R.",     "  -i [path]: A single source path to include as a *public* dependency.",     "  -I [path]: A single source path to include as a *private* dependency.",     "  -o [binary]: The name of the binary file to create with -m.",@@ -85,6 +96,17 @@   if null os      then exitSuccess      else exitFailure+tryFastModes ("--show-deps":ps) = do+  mapM_ showDeps ps+  exitSuccess where+    showDeps p = do+      p' <- canonicalizePath p+      m <- loadMetadata p'+      hPutStrLn stdout $ show p'+      mapM_ showDep (cmObjectFiles m)+    showDep (CategoryObjectFile c ds _) = do+      mapM_ (\d -> hPutStrLn stdout $ "  " ++ ciCategory c ++ " -> " ++ ciCategory d ++ " " ++ show (ciPath d)) ds+    showDep _ = return () tryFastModes _ = return ()  parseCompileOptions :: CompileErrorM m => [String] -> m CompileOptions@@ -121,6 +143,10 @@     | m /= CompileUnspecified = argError n "-r" "Compiler mode already set."     | otherwise = return (os,CompileOptions (maybeDisableHelp h) is is2 ds es ep p CompileRecompile f) +  parseSingle (CompileOptions h is is2 ds es ep p m f) ((n,"-R"):os)+    | m /= CompileUnspecified = argError n "-r" "Compiler mode already set."+    | otherwise = return (os,CompileOptions (maybeDisableHelp h) is is2 ds es ep p CompileRecompileRecursive f)+   parseSingle (CompileOptions h is is2 ds es ep p m f) ((n,"-t"):os)     | m /= CompileUnspecified = argError n "-t" "Compiler mode already set."     | otherwise = return (os,CompileOptions (maybeDisableHelp h) is is2 ds es ep p (ExecuteTests []) f)@@ -139,9 +165,23 @@         return (os2,CompileOptions (maybeDisableHelp h) is is2 ds es ep p (CompileBinary t fn "" []) f) where           check (t,"")     = return (t,defaultMainFunc)           check (t,'.':fn) = return (t,fn)-          check _          = argError n2 "-m" $ "Invalid entry point \"" ++ c ++ "\"."+          check _          = argError n2 c $ "Invalid entry point."       update _ = argError n "-m" "Requires a category name." +  parseSingle (CompileOptions h is is2 ds es ep p m f) ((n,"--fast"):os)+    | m /= CompileUnspecified = argError n "--fast" "Compiler mode already set."+    | otherwise = update os where+      update ((n2,c):(n3,f2):os2) =  do+        (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."+        return (os2,CompileOptions (maybeDisableHelp h) is is2 ds es ep p (CompileFast t fn f2) f) where+          check (t,"")     = return (t,defaultMainFunc)+          check (t,'.':fn) = return (t,fn)+          check _          = argError n2 c $ "Invalid entry point."+      update _ = argError n "--fast" "Requires a category name and a .0rx file."+   parseSingle (CompileOptions h is is2 ds es ep p (CompileBinary t fn o lf) f) ((n,"-o"):os)     | not $ null o = argError n "-o" "Output name already set."     | otherwise = update os where@@ -202,10 +242,13 @@     compileError "Include paths (-i/-I) are not allowed in test mode (-t)."    | (not $ null $ is ++ is2) && (isCompileRecompile m) =-    compileError "Include paths (-i/-I) are not allowed in recompile mode (-r)."+    compileError "Include paths (-i/-I) are not allowed in recompile mode (-r/-R)." -  | null ds =+  | null ds && (not $ isCompileFast m) =     compileError "Please specify at least one input path."   | (length ds /= 1) && (isCompileBinary m) =     compileError "Specify exactly one input path for binary mode (-m)."+  | (length ds /= 0) && (isCompileFast m) =+    compileError "Specify exactly one input path for fast mode (--fast)."+   | otherwise = return co
src/Cli/ProcessMetadata.hs view
@@ -35,6 +35,7 @@   isPathUpToDate,   loadPrivateDeps,   loadPublicDeps,+  loadTestingDeps,   loadMetadata,   resolveCategoryDeps,   resolveObjectDeps,@@ -47,7 +48,7 @@  import Control.Applicative ((<|>)) import Control.Monad (when)-import Data.List (nub,isSuffixOf)+import Data.List (isSuffixOf) import Data.Maybe (isJust) import System.Directory import System.Exit (exitFailure)@@ -118,7 +119,7 @@       if isCompileError m          then do            hPutStrLn stderr $ "Could not parse config file:"-           hPutStrLn stderr $ show (getCompileError m)+           hPutStr stderr $ show (getCompileError m)            return Nothing          else return $ Just (getCompileSuccess m) @@ -128,11 +129,14 @@   case m of        Nothing -> return False        Just _ -> do-         (fr,_) <- loadDepsCommon True h (\m2 -> cmPublicDeps m2 ++ cmPrivateDeps m2) [p]+         (fr,_) <- loadDepsCommon True h Set.empty (\m2 -> cmPublicDeps m2 ++ cmPrivateDeps m2) [p]          return fr  isPathConfigured :: String -> IO Bool-isPathConfigured p = tryLoadRecompile p >>= return . isJust+isPathConfigured p = do+  -- Just for error messages.+  _ <- tryLoadRecompile p+  doesFileExist (p </> recompileFilename)  writeMetadata :: String -> CompileMetadata -> IO () writeMetadata p m = do@@ -223,22 +227,23 @@ getObjectFilesForDeps = concat . map cmObjectFiles  loadPublicDeps :: String -> [String] -> IO (Bool,[CompileMetadata])-loadPublicDeps h = loadDepsCommon False h cmPublicDeps+loadPublicDeps h = loadDepsCommon False h Set.empty cmPublicDeps +loadTestingDeps :: String -> String -> IO (Bool,[CompileMetadata])+loadTestingDeps h p = do+  m <- loadMetadata p+  loadDepsCommon False h Set.empty cmPublicDeps (p:cmPrivateDeps m)+ loadPrivateDeps :: String -> [CompileMetadata] -> IO (Bool,[CompileMetadata]) loadPrivateDeps h ms = do-  (fr,new) <- loadDepsCommon False h (\m -> cmPublicDeps m ++ cmPrivateDeps m) toFind-  return (fr,ms ++ existing ++ new) where+  (fr,new) <- loadDepsCommon False h pa (\m -> cmPublicDeps m ++ cmPrivateDeps m) paths+  return (fr,ms ++ new) where     paths = concat $ map (\m -> cmPublicDeps m ++ cmPrivateDeps m) ms-    (existing,toFind) = foldl splitByExisting ([],[]) $ nub paths-    byPath = Map.fromList $ map (\m -> (cmPath m,m)) ms-    splitByExisting (es,fs) p =-      case p `Map.lookup` byPath of-          Just m  -> (es ++ [m],fs)-          Nothing -> (es,fs ++ [p])+    pa = Set.fromList $ map cmPath ms -loadDepsCommon :: Bool -> String -> (CompileMetadata -> [String]) -> [String] -> IO (Bool,[CompileMetadata])-loadDepsCommon s h f ps = fmap snd $ fixedPaths >>= collect (Set.empty,(True,[])) where+loadDepsCommon :: Bool -> String -> Set.Set String->+  (CompileMetadata -> [String]) -> [String] -> IO (Bool,[CompileMetadata])+loadDepsCommon s h pa0 f ps = fmap snd $ fixedPaths >>= collect (pa0,(True,[])) where   fixedPaths = sequence $ map canonicalizePath ps   collect xa@(pa,(fr,xs)) (p:ps2)     | p `Set.member` pa = collect xa ps2
src/Cli/TestRunner.hs view
@@ -23,6 +23,7 @@ import Control.Arrow (second) import Control.Monad (when) import Data.List (isSuffixOf,nub)+import System.Directory import System.IO import System.Posix.Temp (mkdtemp) import System.FilePath@@ -105,13 +106,16 @@          else do            let warnings = getCompileWarnings result            let (req,main,ns,fs) = getCompileSuccess result-           binaryName <- createBinary main req [ns] fs+           (dir,binaryName) <- createBinary main req [ns] fs            let command = TestCommand binaryName (takeDirectory binaryName)            (TestCommandResult s2' out err) <- runTestCommand b command            case (s2,s2') of                 (True,False) -> return $ mergeAllM $ map compileError $ warnings ++ err ++ out                 (False,True) -> return $ compileError "Expected runtime failure"-                _ -> return $ checkContent rs es warnings err out+                _ -> do+                  let result2 = checkContent rs es warnings err out+                  when (not $ isCompileError result) $ removeDirectoryRecursive dir+                  return result2      compileAll e cs ds = do       let ns0 = map (StaticNamespace . cmNamespace) deps@@ -163,7 +167,8 @@       let ofr = getObjectFileResolver (sources' ++ os)       let os' = ofr ns req       let command = CompileToBinary main os' binary paths' lf-      runCxxCommand b command+      file <- runCxxCommand b command+      return (dir,file)     writeSingleFile d ca@(CxxOutput _ f2 _ _ _ content) = do       writeFile (d </> f2) $ concat $ map (++ "\n") content       if isSuffixOf ".cpp" f2
src/CompilerCxx/Category.hs view
@@ -236,7 +236,7 @@       }     createArg = InputValue [] . VariableName . ("arg" ++) . show     failProcedure f = Procedure [] [-        NoValueExpression [] $ LineComment $ "// TODO: Implement " ++ funcName f ++ ".",+        NoValueExpression [] $ LineComment $ "TODO: Implement " ++ funcName f ++ ".",         FailCall [] (Literal (StringLiteral [] $ funcName f ++ " is not implemented"))       ]     funcName f = show (sfType f) ++ "." ++ show (sfName f)@@ -656,14 +656,25 @@  defineInternalType :: Monad m =>   CategoryName -> Int -> m (CompiledData [String])-defineInternalType t n = return $ onlyCodes [-    typeName t ++ "& " ++ typeCreator t ++ "(Params<" ++ show n ++ ">::Type params) {",-    "  static auto& cache = *new InstanceMap<" ++ show n ++ "," ++ typeName t ++ ">();",-    "  auto& cached = cache[params];",-    "  if (!cached) { cached = R_get(new " ++ typeName t ++ "(" ++ categoryCreator t ++ "(), params)); }",-    "  return *cached;",-    "}"-  ]+defineInternalType t n+  | n < 1 =+      return $ onlyCodes [+        typeName t ++ "& " ++ typeCreator t ++ "(Params<" ++ show n ++ ">::Type params) {",+        "  static auto& cached = *new " ++ typeName t ++ "(" ++ categoryCreator t ++ "(), Params<" ++ show n ++ ">::Type());",+        "  return cached;",+        "}"+      ]+  | otherwise =+      return $ onlyCodes [+        typeName t ++ "& " ++ typeCreator t ++ "(Params<" ++ show n ++ ">::Type params) {",+        "  static auto& cache = *new InstanceMap<" ++ show n ++ "," ++ typeName t ++ ">();",+        "  static auto& cache_mutex = *new std::mutex;",+        "  std::lock_guard<std::mutex> lock(cache_mutex);",+        "  auto& cached = cache[params];",+        "  if (!cached) { cached = R_get(new " ++ typeName t ++ "(" ++ categoryCreator t ++ "(), params)); }",+        "  return *cached;",+        "}"+      ]  declareInternalValue :: Monad m =>   CategoryName -> Int -> Int -> m (CompiledData [String])
src/CompilerCxx/Naming.hs view
@@ -74,7 +74,7 @@ baseSourceIncludes = ["#include \"category-source.hpp\""]  mainSourceIncludes :: [String]-mainSourceIncludes = ["#include \"argv.hpp\""]+mainSourceIncludes = ["#include \"logging.hpp\""]  paramName :: ParamName -> String paramName p = "Param_" ++ tail (pnName p) -- Remove leading '#'.
src/CompilerCxx/Procedure.hs view
@@ -470,6 +470,7 @@       doUnary t e2         | o == "!" = doNot t e2         | o == "-" = doNeg t e2+        | o == "~" = doComp t e2         | otherwise = lift $ compileError $ "Unknown unary operator \"" ++ o ++ "\" " ++                                             formatFullContextBrace c       doNot t e2 = do@@ -484,6 +485,11 @@                                              UnboxedPrimitive PrimFloat $ "-" ++ useAsUnboxed PrimFloat e2)         | otherwise = lift $ compileError $ "Cannot use " ++ show t ++ " with unary - operator" ++                                             formatFullContextBrace c+      doComp t e2+        | t == intRequiredValue = return $ (Positional [intRequiredValue],+                                            UnboxedPrimitive PrimInt $ "~" ++ useAsUnboxed PrimInt e2)+        | otherwise = lift $ compileError $ "Cannot use " ++ show t ++ " with unary ~ operator" +++                                            formatFullContextBrace c   compile (InitializeValue c t ps es) = do     es' <- sequence $ map compileExpression $ pValues es     (ts,es'') <- getValues es'@@ -536,6 +542,7 @@   equals = Set.fromList ["==","!="]   comparison = Set.fromList ["==","!=","<","<=",">",">="]   logical = Set.fromList ["&&","||"]+  bitwise = Set.fromList ["&","|","^",">>","<<"]   bindInfix c (Positional ts1,e1) o (Positional ts2,e2) = do     -- TODO: Needs better error messages.     t1' <- requireSingle c ts1@@ -555,6 +562,8 @@         | o `Set.member` comparison && t1 == charRequiredValue = do           return (Positional [boolRequiredValue],glueInfix PrimChar PrimBool e1 o e2)         | o `Set.member` arithmetic1 && t1 == intRequiredValue = do+          return (Positional [intRequiredValue],glueInfix PrimInt PrimInt e1 o e2)+        | o `Set.member` bitwise && t1 == intRequiredValue = do           return (Positional [intRequiredValue],glueInfix PrimInt PrimInt e1 o e2)         | o `Set.member` arithmetic2 && t1 == intRequiredValue = do           return (Positional [intRequiredValue],glueInfix PrimInt PrimInt e1 o e2)
src/Config/LoadConfig.hs view
@@ -122,7 +122,9 @@     hClose errH     status <- getProcessStatus True True pid     out <- readFile outF+    removeFile outF     err <- readFile errF+    removeFile errF     let success = case status of                       Just (Exited ExitSuccess) -> True                       _ -> False
src/Parser/Procedure.hs view
@@ -240,24 +240,52 @@  unaryOperator :: Parser (Operator c) unaryOperator = op >>= return . NamedOperator where-  op = labeled "unary operator" $ foldr (<|>) (fail "empty") $ map (try . operator) [-      "!", "-"-    ]+  op = labeled "unary operator" $ foldr (<|>) (fail "empty") $ map (try . operator) ops+  ops = logicalUnary ++ arithUnary ++ bitwiseUnary +logicalUnary :: [String]+logicalUnary = ["!"]++arithUnary :: [String]+arithUnary = ["-"]++bitwiseUnary :: [String]+bitwiseUnary = ["~"]+ infixOperator :: Parser (Operator c) infixOperator = op >>= return . NamedOperator where-  op = labeled "binary operator" $ foldr (<|>) (fail "empty") $ map (try . operator) [-      "+","-","*","/","%","==","!=","<","<=",">",">=","&&","||"-    ]+  op = labeled "binary operator" $ foldr (<|>) (fail "empty") $ map (try . operator) ops+  ops = compareInfix ++ logicalInfix ++ addInfix ++ subInfix ++ multInfix ++ bitwiseInfix ++ bitshiftInfix +compareInfix :: [String]+compareInfix = ["==","!=","<","<=",">",">="]++logicalInfix :: [String]+logicalInfix = ["&&","||"]++addInfix :: [String]+addInfix = ["+"]++subInfix :: [String]+subInfix = ["-"]++multInfix :: [String]+multInfix = ["*","/","%"]++bitwiseInfix :: [String]+bitwiseInfix = ["&","|","^"]++bitshiftInfix :: [String]+bitshiftInfix = [">>","<<"]+ infixBefore :: Operator c -> Operator c -> Bool infixBefore o1 o2 = (infixOrder o1 :: Int) <= (infixOrder o2 :: Int) where   infixOrder (NamedOperator o)     -- TODO: Don't hard-code this.-    | o `Set.member` Set.fromList ["*","/","%"] = 1-    | o `Set.member` Set.fromList ["+","-"] = 2-    | o `Set.member` Set.fromList ["==","!=","<","<=",">",">="] = 4-    | o `Set.member` Set.fromList ["&&","||"] = 5+    | o `Set.member` Set.fromList (multInfix ++ bitshiftInfix) = 1+    | o `Set.member` Set.fromList (addInfix ++ subInfix ++ bitwiseInfix) = 2+    | o `Set.member` Set.fromList compareInfix = 4+    | o `Set.member` Set.fromList logicalInfix = 5   infixOrder _ = 3  functionOperator :: Parser (Operator SourcePos)
src/Test/ParseMetadata.hs view
@@ -243,6 +243,12 @@       cbLinkFlags = []     }, +    checkWriteFail "compile mode" $ CompileFast {+      cfCategory = "SpecialCategory",+      cfFunction = "specialFunction",+      cfSource = "source.0rx"+    },+     checkWriteThenRead $ CompileIncremental {       ciLinkFlags = [         "-lm",@@ -252,6 +258,7 @@      checkWriteFail "compile mode" $ ExecuteTests { etInclude = [] },     checkWriteFail "compile mode" $ CompileRecompile,+    checkWriteFail "compile mode" $ CompileRecompileRecursive,     checkWriteFail "compile mode" $ CreateTemplates,     checkWriteFail "compile mode" $ CompileUnspecified   ]
src/Test/Procedure.hs view
@@ -170,6 +170,11 @@     checkShortParseSuccess "\\ !x >= !y",     checkShortParseSuccess "\\ !x && !y",     checkShortParseSuccess "\\ !x || !y",+    checkShortParseSuccess "\\ ~x >> ~y",+    checkShortParseSuccess "\\ ~x << ~y",+    checkShortParseSuccess "\\ ~x & ~y",+    checkShortParseSuccess "\\ ~x | ~y",+    checkShortParseSuccess "\\ ~x ^ ~y",      checkShortParseSuccess "x <- y + z",     checkShortParseSuccess "x <- !y == !z",
tests/builtin-types.0rt view
@@ -278,6 +278,24 @@ }  +testcase "String Builder" {+  success Test$run()+}++define Test {+  run () {+    Builder<String> builder <- String$builder()+    \ Testing$check<String>(builder.build(),"")+    \ Testing$check<String>(builder.append("xyz").build(),"xyz")+    \ Testing$check<String>(builder.append("123").build(),"xyz123")+  }+}++concrete Test {+  @type run () -> ()+}++ testcase "Char LessThan" {   success Test$run() }@@ -409,6 +427,30 @@     String value1 <- "x"     weak String value2 <- value1     if (!present(strong(value2))) {+      fail("Failed")+    }+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "String Builder is not lazy" {+  success Test$run()+}++define Test {+  run () {+    optional String value1 <- "value"+    weak String value2 <- value1+    if (!present(strong(value2))) {+      fail("Failed")+    }+    Builder<String> builder <- String$builder().append(require(value1))+    value1 <- empty+    if (present(strong(value2))) {       fail("Failed")     }   }
+ tests/helpers.0rp view
@@ -0,0 +1,30 @@+/* -----------------------------------------------------------------------------+Copyright 2020 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]++concrete Testing {+  @type check<#x>+    #x requires Formatted+    #x defines Equals<#x>+  (#x /*actual*/, #x /*expected*/) -> ()++  @type checkBetween<#x>+    #x requires Formatted+    #x defines Equals<#x>+    #x defines LessThan<#x>+  (#x /*actual*/, #x /*lower*/, #x /*upper*/) -> ()+}
+ tests/helpers.0rx view
@@ -0,0 +1,43 @@+/* -----------------------------------------------------------------------------+Copyright 2020 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 Testing {+  check (x,y) {+    if (!#x$equals(x,y)) {+      fail(x)+    }+  }++  checkBetween (x,l,h) {+    if (!lessEquals<#x>(l,h)) {+      fail("Invalid range")+    }+    if (!lessEquals<#x>(l,x) || !lessEquals<#x>(x,h)) {+      fail(x)+    }+  }++  @type lessEquals<#x>+    #x defines Equals<#x>+    #x defines LessThan<#x>+  (#x,#x) -> (Bool)+  lessEquals (x,y) {+    // Using !#x$lessThan(y,x) wouldn't account for NaNs.+    return #x$lessThan(x,y) || #x$equals(x,y)+  }+}
tests/infix-operations.0rt view
@@ -22,11 +22,7 @@  define Test {   run () {-    scoped {-      Int x <- \x10 + 1 * 2 - 8 / 2 - 3 % 2-    } in if (x != 13) {-      fail(x)-    }+    \ Testing$check<Int>(\x10 + 1 * 2 - 8 / 2 - 3 % 2,13)   } } @@ -35,17 +31,66 @@ }  +testcase "Int arithmetic" {+  success Test$run()+}++define Test {+  run () {+    \ Testing$check<Int>(8 + 2,10)+    \ Testing$check<Int>(8 - 2,6)+    \ Testing$check<Int>(8 * 2,16)+    \ Testing$check<Int>(8 / 2,4)+    \ Testing$check<Int>(8 % 2,0)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "Int bitwise" {+  success Test$run()+}++define Test {+  run () {+    \ Testing$check<Int>(1 << 2,4)+    \ Testing$check<Int>(7 >> 1,3)+    \ Testing$check<Int>(7 ^ 2 ,5)+    \ Testing$check<Int>(7 & ~2,5)+    \ Testing$check<Int>(5 | 2 ,7)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "Int bitwise with precedence" {+  success Test$run()+}++define Test {+  run () {+    \ Testing$check<Int>(1 << 4 | 7 >> 1 & ~2,17)+  }+}++concrete Test {+  @type run () -> ()+}++ testcase "same operators applied left to right" {   success Test$run() }  define Test {   run () {-    scoped {-      Int x <- 2 - 1 - 1-    } in if (x != 0) {-      fail(x)-    }+    \ Testing$check<Int>(2 - 1 - 1,0)   } } @@ -92,11 +137,7 @@  define Test {   run () {-    scoped {-      String x <- "x" + "y" + "z"-    } in if (x != "xyz") {-      fail(x)-    }+    \ Testing$check<String>("x" + "y" + "z","xyz")   } } @@ -111,11 +152,22 @@  define Test {   run () {-    scoped {-      Float x <- 16.0 + 1.0 * 2.0 - 8.0 / 2.0 - 3.0 / 3.0-    } in if (x != 13.0) {-      fail(x)-    }+    \ Testing$check<Float>(16.0 + 1.0 * 2.0 - 8.0 / 2.0 - 3.0 / 3.0,13.0)+  }+}++concrete Test {+  @type run () -> ()+}+++testcase "Char minus" {+  success Test$run()+}++define Test {+  run () {+    \ Testing$check<Int>('z' - 'a',25)   } } 
tests/simple.0rt view
@@ -82,3 +82,26 @@  // The declaration for String is in scope, but it lives outside of this module. define String {}+++testcase "no deadlock with recursive type" {+  success Test$execute()+}++concrete Test {+  @type execute () -> ()+}++concrete Type<#x> {+  @type call () -> ()+}++define Type {+  call () {}+}++define Test {+  execute () {+    \ Type<Type<Type<Int>>>$call()+  }+}
+ tests/templates/.zeolite-module view
@@ -0,0 +1,9 @@+root: "../.."+path: "tests/templates"+extra_files: [+  category_source {+    source: "tests/templates/Category_Templated.cpp"+    categories: [Templated]+  }+]+mode: incremental {}
+ tests/templates/README.md view
@@ -0,0 +1,15 @@+# Template Generation Test++This module tests `--templates` mode for generating `.cpp` templates.++To compile and execute:++```shell+ZEOLITE_PATH=$(zeolite --get-path)+rm -f $ZEOLITE_PATH/tests/templates/Category_Templated.cpp  # Remove the old template.+zeolite -p $ZEOLITE_PATH --templates tests/templates        # Create a new template.+zeolite -p $ZEOLITE_PATH -r tests/templates                 # Recompile.+zeolite -p $ZEOLITE_PATH -t tests/templates                 # Run the test.+```++The most important step above is to delete the *old* template first.
+ tests/templates/templates.0rp view
@@ -0,0 +1,22 @@+/* -----------------------------------------------------------------------------+Copyright 2020 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]++concrete Templated<#x> {+  @type create () -> (Templated<#x>)+  @value get () -> (#x)+}
+ tests/templates/tests.0rt view
@@ -0,0 +1,32 @@+/* -----------------------------------------------------------------------------+Copyright 2020 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 "template compiles to binary" {+  crash Test$run()+  require "Templated\.create is not implemented"+}++define Test {+  run () {+    \ Templated<Int>$create()+  }+}++concrete Test {+  @type run () -> ()+}
zeolite-lang.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.2  name:                zeolite-lang-version:             0.4.0.0+version:             0.4.1.0 synopsis:            Zeolite is a statically-typed, general-purpose programming language.  description:@@ -36,7 +36,7 @@     .     @     ZEOLITE_PATH=$(zeolite --get-path)-    zeolite -p "$ZEOLITE_PATH" -t tests lib\/file lib\/util+    zeolite -p "$ZEOLITE_PATH" -t tests lib\/file lib\/math lib\/util     @   .   The <https://github.com/ta0kira/zeolite/tree/master/example code examples> are@@ -83,17 +83,27 @@                      lib/file/*.0rp,                      lib/file/*.0rt,                      lib/file/*.cpp,+                     lib/math/.zeolite-module,+                     lib/math/*.0rp,+                     lib/math/*.0rt,+                     lib/math/*.cpp,                      lib/util/.zeolite-module,                      lib/util/*.0rp,                      lib/util/*.0rt,                      lib/util/*.0rx,                      lib/util/*.cpp,                      tests/.zeolite-module,+                     tests/*.0rp,                      tests/*.0rt,+                     tests/*.0rx,                      tests/check-defs/README.md,                      tests/check-defs/.zeolite-module,                      tests/check-defs/*.0rp,                      tests/check-defs/*.0rx,+                     tests/templates/README.md,+                     tests/templates/.zeolite-module,+                     tests/templates/*.0rp,+                     tests/templates/*.0rt,                      tests/visibility/.zeolite-module,                      tests/visibility/*.0rp,                      tests/visibility/*.0rx,