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 +23/−0
- base/.zeolite-module +0/−1
- base/Category_Bool.cpp +2/−4
- base/Category_Char.cpp +2/−4
- base/Category_Float.cpp +2/−4
- base/Category_Int.cpp +2/−4
- base/Category_String.cpp +51/−4
- base/argv.cpp +0/−42
- base/argv.hpp +0/−52
- base/builtin.0rp +6/−0
- base/category-source.hpp +1/−1
- base/logging.cpp +23/−4
- base/logging.hpp +29/−4
- bin/zeolite-setup.hs +4/−3
- lib/file/Category_RawFileReader.cpp +7/−4
- lib/file/Category_RawFileWriter.cpp +6/−4
- lib/math/.zeolite-module +12/−0
- lib/math/Category_Math.cpp +361/−0
- lib/math/math.0rp +50/−0
- lib/math/tests.0rt +410/−0
- lib/util/Category_Argv.cpp +2/−4
- lib/util/Category_SimpleInput.cpp +6/−4
- lib/util/Category_SimpleOutput.cpp +5/−0
- src/Cli/CompileOptions.hs +14/−2
- src/Cli/Compiler.hs +64/−20
- src/Cli/ParseCompileOptions.hs +48/−5
- src/Cli/ProcessMetadata.hs +20/−15
- src/Cli/TestRunner.hs +8/−3
- src/CompilerCxx/Category.hs +20/−9
- src/CompilerCxx/Naming.hs +1/−1
- src/CompilerCxx/Procedure.hs +9/−0
- src/Config/LoadConfig.hs +2/−0
- src/Parser/Procedure.hs +38/−10
- src/Test/ParseMetadata.hs +7/−0
- src/Test/Procedure.hs +5/−0
- tests/builtin-types.0rt +42/−0
- tests/helpers.0rp +30/−0
- tests/helpers.0rx +43/−0
- tests/infix-operations.0rt +72/−20
- tests/simple.0rt +23/−0
- tests/templates/.zeolite-module +9/−0
- tests/templates/README.md +15/−0
- tests/templates/templates.0rp +22/−0
- tests/templates/tests.0rt +32/−0
- zeolite-lang.cabal +12/−2
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,