zeolite-lang 0.18.0.1 → 0.18.1.0
raw patch · 20 files changed
+642/−28 lines, 20 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Types.Procedure: isAssignableDiscard :: Assignable c -> Bool
Files
- ChangeLog.md +18/−0
- lib/math/.zeolite-module +12/−0
- lib/math/random.0rp +46/−0
- lib/math/random.0rt +125/−0
- lib/math/src/Extension_RandomExponential.cpp +81/−0
- lib/math/src/Extension_RandomGaussian.cpp +82/−0
- lib/math/src/Extension_RandomUniform.cpp +81/−0
- lib/testing/helpers.0rp +34/−0
- lib/testing/helpers.0rx +20/−0
- lib/testing/tests.0rt +40/−0
- lib/thread/src/Extension_Realtime.cpp +29/−8
- lib/thread/time.0rp +3/−0
- lib/thread/time.0rt +31/−11
- src/CompilerCxx/CxxFiles.hs +1/−1
- src/CompilerCxx/Procedure.hs +6/−5
- src/Parser/Procedure.hs +1/−1
- src/Types/Procedure.hs +5/−0
- tests/leak-check/README.md +5/−1
- tests/regressions.0rt +21/−0
- zeolite-lang.cabal +1/−1
ChangeLog.md view
@@ -1,5 +1,23 @@ # Revision history for zeolite-lang +## 0.18.1.0 -- 2021-10-19++### Language++* **[fix]** Fixes issue with explicit return discards skipping generation of+ function calls. Previously, `_ <- foo()` skipped generating the call to `foo`.++### Libraries++* **[new]** Adds `RandomExponential`, `RandomGaussian`, and `RandomUniform` to+ `lib/math` for generating random `Float` values.++* **[new]** Adds `Realtime.sleepSecondsPrecise` function to allow sleeps that+ are more precise than the kernel's latency.++* **[new]** Adds `checkGreaterThan` and `checkLessThan` to `Testing` in+ `lib/testing`.+ ## 0.18.0.0 -- 2021-08-01 ### Compiler CLI
lib/math/.zeolite-module view
@@ -10,5 +10,17 @@ source: "lib/math/src/Extension_Math.cpp" categories: [Math] }+ category_source {+ source: "lib/math/src/Extension_RandomExponential.cpp"+ categories: [RandomExponential]+ }+ category_source {+ source: "lib/math/src/Extension_RandomGaussian.cpp"+ categories: [RandomGaussian]+ }+ category_source {+ source: "lib/math/src/Extension_RandomUniform.cpp"+ categories: [RandomUniform]+ } ] mode: incremental {}
+ lib/math/random.0rp view
@@ -0,0 +1,46 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++// Generates values of type #x.+@value interface Generator<|#x> {+ generate () -> (#x)+}++// Generates exponentially-distributed Float values.+concrete RandomExponential {+ refines Generator<Float>++ // Creates a new generator with the specified lambda value.+ @type new (Float) -> (Generator<Float>)+}++// Generates Gaussian-distributed Float values.+concrete RandomGaussian {+ refines Generator<Float>++ // Creates a new generator with the specified mean and standard deviation.+ @type new (Float,Float) -> (Generator<Float>)+}++// Generates uniformly-distributed Float values.+concrete RandomUniform {+ refines Generator<Float>++ // Creates a new generator with the specified min and max values.+ @type new (Float,Float) -> (Generator<Float>)+}
+ lib/math/random.0rt view
@@ -0,0 +1,125 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++testcase "valid instantiations" {+ success+}++unittest exponential {+ Generator<Float> random <- RandomExponential.new(1.0)+ Float value <- random.generate()+}++unittest gaussian {+ Generator<Float> random <- RandomGaussian.new(0.0,1.0)+ Float value <- random.generate()+}++unittest uniform {+ Generator<Float> random <- RandomUniform.new(0.0,1.0)+ Float value <- random.generate()+}+++testcase "negative lambda in exponential" {+ crash+ require "lambda"+ require "-1"+}++unittest test {+ Generator<Float> random <- RandomExponential.new(-1.0)+}+++testcase "negative standard deviation in gaussian" {+ crash+ require "standard deviation"+ require "-1"+}++unittest test {+ Generator<Float> random <- RandomGaussian.new(0.0,-1.0)+}+++testcase "empty range in uniform" {+ crash+ require "range"+ require "0,-1"+}++unittest test {+ Generator<Float> random <- RandomUniform.new(0.0,-1.0)+}+++testcase "distribution sanity checks" {+ success+}++unittest exponential {+ Int count <- 10000+ Float lambda <- 10.0+ $ReadOnly[count,lambda]$++ Generator<Float> random <- RandomExponential.new(lambda)++ Float sum <- 0.0+ traverse (Counter.zeroIndexed(count) -> _) {+ Float value <- random.generate()+ \ Testing.checkGreaterThan<?>(value,0.0)+ sum <- sum+value+ }++ \ Testing.checkBetween<?>(sum/count.asFloat(),0.9/lambda,1.1/lambda)+}++unittest gaussian {+ Int count <- 10000+ Float mean <- 100.0+ Float sd <- 1.0+ $ReadOnly[count,mean,sd]$++ Generator<Float> random <- RandomGaussian.new(mean,sd)++ Float sum <- 0.0+ traverse (Counter.zeroIndexed(count) -> _) {+ sum <- sum+random.generate()+ }++ \ Testing.checkBetween<?>(sum/count.asFloat(),mean-0.1*sd,mean+0.1*sd)+}++unittest uniform {+ Int count <- 10000+ Float min <- -11.0+ Float max <- 5.0+ $ReadOnly[count,min,max]$++ Generator<Float> random <- RandomUniform.new(min,max)++ Float sum <- 0.0+ traverse (Counter.zeroIndexed(count) -> _) {+ Float value <- random.generate()+ \ Testing.checkBetween<?>(value,min,max)+ sum <- sum+value+ }++ \ Testing.checkBetween<?>(sum/count.asFloat(),min-0.1*(max-min),max-0.1*(max-min))+}
+ lib/math/src/Extension_RandomExponential.cpp view
@@ -0,0 +1,81 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++#include <random>++#include "category-source.hpp"+#include "Streamlined_RandomExponential.hpp"+#include "Category_Float.hpp"+#include "Category_Generator.hpp"+#include "Category_RandomExponential.hpp"+#include "Category_RandomUniform.hpp"++#ifdef ZEOLITE_PUBLIC_NAMESPACE+namespace ZEOLITE_PUBLIC_NAMESPACE {+#endif // ZEOLITE_PUBLIC_NAMESPACE++BoxedValue CreateValue_RandomExponential(S<Type_RandomExponential> parent, const ValueTuple& args);++struct ExtCategory_RandomExponential : public Category_RandomExponential {+};++struct ExtType_RandomExponential : public Type_RandomExponential {+ inline ExtType_RandomExponential(Category_RandomExponential& p, Params<0>::Type params) : Type_RandomExponential(p, params) {}++ ReturnTuple Call_new(const S<TypeInstance>& Param_self, const ParamTuple& params, const ValueTuple& args) final {+ TRACE_FUNCTION("RandomExponential.new")+ const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+ if (Var_arg1 <= 0) {+ FAIL() << "Invalid lambda " << Var_arg1;+ }+ return ReturnTuple(CreateValue_RandomExponential(shared_from_this(), args));+ }+};++struct ExtValue_RandomExponential : public Value_RandomExponential {+ inline ExtValue_RandomExponential(S<Type_RandomExponential> p, const ValueTuple& args)+ : Value_RandomExponential(p),+ distribution_(args.At(0).AsFloat()) {}++ ReturnTuple Call_generate(const BoxedValue& Var_self, const ParamTuple& params, const ValueTuple& args) final {+ TRACE_FUNCTION("RandomExponential.generate")+ return ReturnTuple(Box_Float(distribution_(generator_)));+ }++ std::default_random_engine generator_;+ std::exponential_distribution<double> distribution_;+};++Category_RandomExponential& CreateCategory_RandomExponential() {+ static auto& category = *new ExtCategory_RandomExponential();+ return category;+}++S<Type_RandomExponential> CreateType_RandomExponential(Params<0>::Type params) {+ static const auto cached = S_get(new ExtType_RandomExponential(CreateCategory_RandomExponential(), Params<0>::Type()));+ return cached;+}++BoxedValue CreateValue_RandomExponential(S<Type_RandomExponential> parent, const ValueTuple& args) {+ return BoxedValue(new ExtValue_RandomExponential(parent, args));+}++#ifdef ZEOLITE_PUBLIC_NAMESPACE+} // namespace ZEOLITE_PUBLIC_NAMESPACE+using namespace ZEOLITE_PUBLIC_NAMESPACE;+#endif // ZEOLITE_PUBLIC_NAMESPACE
+ lib/math/src/Extension_RandomGaussian.cpp view
@@ -0,0 +1,82 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++#include <random>++#include "category-source.hpp"+#include "Streamlined_RandomGaussian.hpp"+#include "Category_Float.hpp"+#include "Category_Generator.hpp"+#include "Category_RandomGaussian.hpp"+#include "Category_RandomUniform.hpp"++#ifdef ZEOLITE_PUBLIC_NAMESPACE+namespace ZEOLITE_PUBLIC_NAMESPACE {+#endif // ZEOLITE_PUBLIC_NAMESPACE++BoxedValue CreateValue_RandomGaussian(S<Type_RandomGaussian> parent, const ValueTuple& args);++struct ExtCategory_RandomGaussian : public Category_RandomGaussian {+};++struct ExtType_RandomGaussian : public Type_RandomGaussian {+ inline ExtType_RandomGaussian(Category_RandomGaussian& p, Params<0>::Type params) : Type_RandomGaussian(p, params) {}++ ReturnTuple Call_new(const S<TypeInstance>& Param_self, const ParamTuple& params, const ValueTuple& args) final {+ TRACE_FUNCTION("RandomGaussian.new")+ const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+ const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+ if (Var_arg2 <= 0) {+ FAIL() << "Invalid standard deviation " << Var_arg2;+ }+ return ReturnTuple(CreateValue_RandomGaussian(shared_from_this(), args));+ }+};++struct ExtValue_RandomGaussian : public Value_RandomGaussian {+ inline ExtValue_RandomGaussian(S<Type_RandomGaussian> p, const ValueTuple& args)+ : Value_RandomGaussian(p),+ distribution_(args.At(0).AsFloat(), args.At(1).AsFloat()) {}++ ReturnTuple Call_generate(const BoxedValue& Var_self, const ParamTuple& params, const ValueTuple& args) final {+ TRACE_FUNCTION("RandomGaussian.generate")+ return ReturnTuple(Box_Float(distribution_(generator_)));+ }++ std::default_random_engine generator_;+ std::normal_distribution<double> distribution_;+};++Category_RandomGaussian& CreateCategory_RandomGaussian() {+ static auto& category = *new ExtCategory_RandomGaussian();+ return category;+}++S<Type_RandomGaussian> CreateType_RandomGaussian(Params<0>::Type params) {+ static const auto cached = S_get(new ExtType_RandomGaussian(CreateCategory_RandomGaussian(), Params<0>::Type()));+ return cached;+}++BoxedValue CreateValue_RandomGaussian(S<Type_RandomGaussian> parent, const ValueTuple& args) {+ return BoxedValue(new ExtValue_RandomGaussian(parent, args));+}++#ifdef ZEOLITE_PUBLIC_NAMESPACE+} // namespace ZEOLITE_PUBLIC_NAMESPACE+using namespace ZEOLITE_PUBLIC_NAMESPACE;+#endif // ZEOLITE_PUBLIC_NAMESPACE
+ lib/math/src/Extension_RandomUniform.cpp view
@@ -0,0 +1,81 @@+/* -----------------------------------------------------------------------------+Copyright 2021 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- */++// Author: Kevin P. Barry [ta0kira@gmail.com]++#include <random>++#include "category-source.hpp"+#include "Streamlined_RandomUniform.hpp"+#include "Category_Float.hpp"+#include "Category_Generator.hpp"+#include "Category_RandomUniform.hpp"++#ifdef ZEOLITE_PUBLIC_NAMESPACE+namespace ZEOLITE_PUBLIC_NAMESPACE {+#endif // ZEOLITE_PUBLIC_NAMESPACE++BoxedValue CreateValue_RandomUniform(S<Type_RandomUniform> parent, const ValueTuple& args);++struct ExtCategory_RandomUniform : public Category_RandomUniform {+};++struct ExtType_RandomUniform : public Type_RandomUniform {+ inline ExtType_RandomUniform(Category_RandomUniform& p, Params<0>::Type params) : Type_RandomUniform(p, params) {}++ ReturnTuple Call_new(const S<TypeInstance>& Param_self, const ParamTuple& params, const ValueTuple& args) final {+ TRACE_FUNCTION("RandomUniform.new")+ const PrimFloat Var_arg1 = (args.At(0)).AsFloat();+ const PrimFloat Var_arg2 = (args.At(1)).AsFloat();+ if (Var_arg2 <= Var_arg1) {+ FAIL() << "Invalid range (" << Var_arg1 << "," << Var_arg2 << ")";+ }+ return ReturnTuple(CreateValue_RandomUniform(shared_from_this(), args));+ }+};++struct ExtValue_RandomUniform : public Value_RandomUniform {+ inline ExtValue_RandomUniform(S<Type_RandomUniform> p, const ValueTuple& args)+ : Value_RandomUniform(p),+ distribution_(args.At(0).AsFloat(), args.At(1).AsFloat()) {}++ ReturnTuple Call_generate(const BoxedValue& Var_self, const ParamTuple& params, const ValueTuple& args) final {+ TRACE_FUNCTION("RandomUniform.generate")+ return ReturnTuple(Box_Float(distribution_(generator_)));+ }++ std::default_random_engine generator_;+ std::uniform_real_distribution<double> distribution_;+};++Category_RandomUniform& CreateCategory_RandomUniform() {+ static auto& category = *new ExtCategory_RandomUniform();+ return category;+}++S<Type_RandomUniform> CreateType_RandomUniform(Params<0>::Type params) {+ static const auto cached = S_get(new ExtType_RandomUniform(CreateCategory_RandomUniform(), Params<0>::Type()));+ return cached;+}++BoxedValue CreateValue_RandomUniform(S<Type_RandomUniform> parent, const ValueTuple& args) {+ return BoxedValue(new ExtValue_RandomUniform(parent, args));+}++#ifdef ZEOLITE_PUBLIC_NAMESPACE+} // namespace ZEOLITE_PUBLIC_NAMESPACE+using namespace ZEOLITE_PUBLIC_NAMESPACE;+#endif // ZEOLITE_PUBLIC_NAMESPACE
lib/testing/helpers.0rp view
@@ -68,4 +68,38 @@ #x defines Equals<#x> #x defines LessThan<#x> (#x,#x,#x) -> ()++ // Check that the value is above the limit. Crashes if it is not in the range.+ //+ // Args:+ // - #x: Actual value.+ // - #x: Lower bound.+ //+ // Notes:+ // - This could be done without Equals, except that some types have+ // "undefined" values (e.g., NaN, for Float) that prevent inferring equality+ // from less-than comparisons.+ // - This comparison doesn't allow the value to equal the bound.+ @type checkGreaterThan<#x>+ #x requires Formatted+ #x defines Equals<#x>+ #x defines LessThan<#x>+ (#x,#x) -> ()++ // Check that the value is below the limit. Crashes if it is not in the range.+ //+ // Args:+ // - #x: Actual value.+ // - #x: Upper bound.+ //+ // Notes:+ // - This could be done without Equals, except that some types have+ // "undefined" values (e.g., NaN, for Float) that prevent inferring equality+ // from less-than comparisons.+ // - This comparison doesn't allow the value to equal the bound.+ @type checkLessThan<#x>+ #x requires Formatted+ #x defines Equals<#x>+ #x defines LessThan<#x>+ (#x,#x) -> () }
lib/testing/helpers.0rx view
@@ -76,6 +76,26 @@ } } + checkGreaterThan (x,l) {+ if (lessEquals<?>(x,l)) {+ fail(String.builder()+ .append(x.formatted())+ .append(" is not greater than ")+ .append(l.formatted())+ .build())+ }+ }++ checkLessThan (x,h) {+ if (lessEquals<?>(h,x)) {+ fail(String.builder()+ .append(x.formatted())+ .append(" is not less than ")+ .append(h.formatted())+ .build())+ }+ }+ @type lessEquals<#x> #x defines Equals<#x> #x defines LessThan<#x>
lib/testing/tests.0rt view
@@ -138,3 +138,43 @@ unittest test { \ Testing.checkBetween<?>(14,15,13) }+++testcase "checkGreaterThan success" {+ success+}++unittest test {+ \ Testing.checkGreaterThan<?>(13,11)+}+++testcase "checkGreaterThan fail" {+ crash+ require stderr "13"+ require stderr "14"+}++unittest test {+ \ Testing.checkGreaterThan<?>(13,14)+}+++testcase "checkLessThan success" {+ success+}++unittest test {+ \ Testing.checkLessThan<?>(13,14)+}+++testcase "checkLessThan fail" {+ crash+ require stderr "13"+ require stderr "11"+}++unittest test {+ \ Testing.checkLessThan<?>(13,11)+}
lib/thread/src/Extension_Realtime.cpp view
@@ -23,12 +23,17 @@ #include <chrono> #include <iomanip>+#include <thread> #include "category-source.hpp" #include "Streamlined_Realtime.hpp" #include "Category_Float.hpp" #include "Category_Realtime.hpp" +#ifndef SLEEP_SPINLOCK_LIMIT+#define SLEEP_SPINLOCK_LIMIT 0.001+#endif+ #ifdef ZEOLITE_PUBLIC_NAMESPACE namespace ZEOLITE_PUBLIC_NAMESPACE { #endif // ZEOLITE_PUBLIC_NAMESPACE@@ -42,18 +47,34 @@ ReturnTuple Call_sleepSeconds(const S<TypeInstance>& Param_self, const ParamTuple& params, const ValueTuple& args) final { TRACE_FUNCTION("Realtime.sleepSeconds") const PrimFloat Var_arg1 = (args.At(0)).AsFloat();- if (Var_arg1 < 0) {- FAIL() << "Bad wait time " << Var_arg1;+ if (Var_arg1 > 0) {+ std::this_thread::sleep_for(std::chrono::duration<double>(Var_arg1)); }- struct timespec timeout{ (int) trunc(Var_arg1), (int) (1000000000.0 * (Var_arg1-trunc(Var_arg1))) };- struct timespec remainder;- while (nanosleep(&timeout, &remainder) != 0) {- if (errno == EINTR) {- timeout = remainder;+ return ReturnTuple();+ }++ ReturnTuple Call_sleepSecondsPrecise(const S<TypeInstance>& Param_self, const ParamTuple& params, const ValueTuple& args) final {+ TRACE_FUNCTION("Realtime.sleepSecondsPrecise")+ const PrimFloat Var_arg1 = (args.At(0)).AsFloat();++ const auto spinlock_limit = std::chrono::duration<double>(SLEEP_SPINLOCK_LIMIT);++ const auto target_time =+ std::chrono::high_resolution_clock::now().time_since_epoch() ++ std::chrono::duration<double>(Var_arg1);++ while (true) {+ const auto now = std::chrono::high_resolution_clock::now().time_since_epoch();+ if (now >= target_time) break;+ const auto sleep_time = target_time - now;+ if (sleep_time <= spinlock_limit) {+ while (std::chrono::high_resolution_clock::now().time_since_epoch() < target_time);+ break; } else {- FAIL() << "Error sleeping: " << strerror(errno) << " (error " << errno << ")";+ std::this_thread::sleep_for(sleep_time - spinlock_limit); } }+ return ReturnTuple(); }
lib/thread/time.0rp view
@@ -21,6 +21,9 @@ // Sleep for the given number of seconds. @type sleepSeconds (Float) -> () + // Sleep for the given number of seconds, with more precision.+ @type sleepSecondsPrecise (Float) -> ()+ // Get a timestamp from a monotonic clock. // // Notes:
lib/thread/time.0rt view
@@ -16,22 +16,24 @@ // Author: Kevin P. Barry [ta0kira@gmail.com] -testcase "negative sleepSeconds() crashes" {- crash- require "-0\.1"+testcase "zero sleep is allowed" {+ success } -unittest test {- \ Realtime.sleepSeconds(-0.1)+unittest zeroSleep {+ \ Realtime.sleepSeconds(0.0) } +unittest negativeSleep {+ \ Realtime.sleepSeconds(-0.1)+} -testcase "zero sleepSeconds() is allowed" {- success+unittest zeroPrecise {+ \ Realtime.sleepSecondsPrecise(0.0) } -unittest test {- \ Realtime.sleepSeconds(0.0)+unittest negativePrecise {+ \ Realtime.sleepSecondsPrecise(-0.1) } @@ -46,14 +48,32 @@ } +testcase "sleepSecondsPrecise() does not interfere with test timeout" {+ crash+ require "signal 14"+ timeout 1+}++unittest test {+ \ Realtime.sleepSecondsPrecise(5.0)+}++ testcase "monoSeconds() diff is somewhat accurate" { success timeout 2 } -unittest test {+unittest testSleep { Float start <- Realtime.monoSeconds() \ Realtime.sleepSeconds(0.5) Float stop <- Realtime.monoSeconds()- \ Testing.checkBetween<?>(stop-start,0.5,0.75)+ \ Testing.checkBetween<?>(stop-start,0.5,0.6)+}++unittest testPrecise {+ Float start <- Realtime.monoSeconds()+ \ Realtime.sleepSecondsPrecise(0.5)+ Float stop <- Realtime.monoSeconds()+ \ Testing.checkBetween<?>(stop-start,0.5,0.51) }
src/CompilerCxx/CxxFiles.hs view
@@ -725,7 +725,7 @@ createFunctionDispatch :: CategoryName -> SymbolScope -> [ScopedFunction c] -> CompiledData [String] createFunctionDispatch n s fs = function where function- | null filtered = onlyCode $ "{ " ++ fallback ++ " }"+ | null filtered = onlyCode fallback | otherwise = onlyCodes $ [typedef] ++ concat (map table $ byCategory) ++ metaTable ++ select filtered = filter ((== s) . sfScope) fs flatten f = f:(concat $ map flatten $ sfMerges f)
src/CompilerCxx/Procedure.hs view
@@ -279,7 +279,7 @@ _ <- processPairsT alwaysPair (fmap assignableName as) ts _ <- processPairsT (createVariable r fa) as ts maybeSetTrace c- variableTypes <- sequence $ map (uncurry getVariableType) $ zip (pValues as) (pValues ts)+ variableTypes <- sequence $ map getVariableType (pValues as) assignAll (zip3 ([0..] :: [Int]) variableTypes (pValues as)) e' where message = "In assignment at " ++ formatFullContext c@@ -288,11 +288,11 @@ csWrite ["{","const auto r = " ++ useAsReturns e2 ++ ";"] sequence_ $ map assignMulti vs csWrite ["}"]- getVariableType (CreateVariable _ t _) _ = return t- getVariableType (ExistingVariable (InputValue c2 n)) _ = do+ getVariableType (CreateVariable _ t _) = return t+ getVariableType (ExistingVariable (InputValue c2 n)) = do (VariableValue _ _ t _) <- csGetVariable (UsedVariable c2 n) return t- getVariableType (ExistingVariable (DiscardInput _)) t = return t+ getVariableType _ = return undefined createVariable r fa (CreateVariable c2 t1 n) t2 = "In creation of " ++ show n ++ " at " ++ formatFullContext c2 ??> do self <- autoSelfType@@ -315,7 +315,8 @@ (VariableValue _ s _ _) <- csGetVariable (UsedVariable c2 n) scoped <- autoScope s csWrite [scoped ++ variableName n ++ " = " ++ writeStoredVariable t e2 ++ ";"]- assignSingle _ _ = return ()+ assignSingle (_,_,ExistingVariable (DiscardInput _)) e2 = do+ csWrite ["(void)" ++ useAsWhatever e2 ++ ";"] assignMulti (i,t,CreateVariable _ _ n) = csWrite [variableName n ++ " = " ++ writeStoredVariable t (UnwrappedSingle $ "r.At(" ++ show i ++ ")") ++ ";"]
src/Parser/Procedure.hs view
@@ -104,7 +104,7 @@ return $ InputValue [c] v discard = do c <- getSourceContext- sepAfter (string_ "_")+ sepAfter_ kwIgnore return $ DiscardInput [c] instance ParseFromSource (OutputValue SourceContext) where
src/Types/Procedure.hs view
@@ -51,6 +51,7 @@ getOperatorContext, getOperatorName, getStatementContext,+ isAssignableDiscard, isDiscardedInput, isFunctionOperator, isNoTrace,@@ -203,6 +204,10 @@ assignableName (CreateVariable _ _ n) = n assignableName (ExistingVariable (InputValue _ n)) = n assignableName _ = discardInputName++isAssignableDiscard :: Assignable c -> Bool+isAssignableDiscard (CreateVariable _ _ _) = False+isAssignableDiscard (ExistingVariable v) = isDiscardedInput v data VoidExpression c = Conditional (IfElifElse c) |
tests/leak-check/README.md view
@@ -58,8 +58,12 @@ ```shell # The "race" argument is important.-valgrind --leak-check=yes $ZEOLITE_PATH/tests/leak-check/LeakTest race+$ZEOLITE_PATH/tests/leak-check/LeakTest race ```++*Do not use `valgrind` to run in `race` mode!* The latency introduced by+tracking memory usage will eliminate the race conditions that this mode is+intended to introduce, defeating the purpose of the test. You should see `no race conditions this time` upon success. Any sort of error message means a crash, and thus a test failure.
tests/regressions.0rt view
@@ -292,3 +292,24 @@ return "return" } }+++testcase "Issue #185 is fixed" {+ // https://github.com/ta0kira/zeolite/issues/185+ crash+ require "message"+}++concrete Type {+ @type sideEffects () -> (Bool)+}++define Type {+ sideEffects () {+ fail("message")+ }+}++unittest test {+ _ <- Type.sideEffects()+}
zeolite-lang.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2 name: zeolite-lang-version: 0.18.0.1+version: 0.18.1.0 synopsis: Zeolite is a statically-typed, general-purpose programming language. description: