summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--starts/meaning-vm/.gitignore1
-rw-r--r--starts/meaning-vm/habit-starts/rhythm.cpp19
-rw-r--r--starts/meaning-vm/level-0/common.hpp46
-rw-r--r--starts/meaning-vm/level-2/baseref.hpp2
-rw-r--r--starts/meaning-vm/level-2/common.hpp3
-rw-r--r--starts/meaning-vm/level-2/concepts.hpp4
-rw-r--r--starts/meaning-vm/level-2/funcs.cpp43
-rw-r--r--starts/meaning-vm/level-2/funcs.hpp5
-rw-r--r--starts/meaning-vm/level-2/sugar.hpp73
-rw-r--r--starts/meaning-vm/makefile10
10 files changed, 145 insertions, 61 deletions
diff --git a/starts/meaning-vm/.gitignore b/starts/meaning-vm/.gitignore
index 1859903..285fc08 100644
--- a/starts/meaning-vm/.gitignore
+++ b/starts/meaning-vm/.gitignore
@@ -1,3 +1,4 @@
+*.ii
*.o
*.a
level?
diff --git a/starts/meaning-vm/habit-starts/rhythm.cpp b/starts/meaning-vm/habit-starts/rhythm.cpp
index 7afb8ed..0877250 100644
--- a/starts/meaning-vm/habit-starts/rhythm.cpp
+++ b/starts/meaning-vm/habit-starts/rhythm.cpp
@@ -32,35 +32,34 @@ int main()
// next -> habit that follows
#undef self
- ahabit(next-habit,
+ ahabit(next-habit, (),
{
ref n = ctx[active-habit].get(next);
ctx.set(active-habit, n);
return n();
});
- ahabit(start-habit,
+ ahabit(start-habit, ((start,s)),
{
- ref s = ctx[start];
ctx.set(active-habit, s);
return s();
});
- ahabit(keep-doing-habit,
+ ahabit(keep-doing-habit, ((start,s)),
{
- (start-habit)();
+ (start-habit)(s);
while (true) {
(next-habit)();
}
});
- ahabit(start-beat,
+ ahabit(start-beat, (),
{
ctx.vset(beat, int(0));
self.set(next, wait-habit);
(beat-habit).set(next, wait-habit);
(wait-habit).set(next, beat-habit);
});
- ahabit(beat-habit,
+ ahabit(beat-habit, (),
{
int & b = ctx.vget<int>(beat);
char const * beats[] = {
@@ -118,12 +117,10 @@ int main()
std::cout << beats[b] << std::endl;
b = (b + 1) % (sizeof(beats) / sizeof(*beats));
});
- ahabit(wait-habit,
+ ahabit(wait-habit, (),
{
usleep(micros);
});
-
- ref::context().set(start, start-beat);
- (keep-doing-habit)();
+ (keep-doing-habit)(start-beat);
}
diff --git a/starts/meaning-vm/level-0/common.hpp b/starts/meaning-vm/level-0/common.hpp
index e06e478..d75229d 100644
--- a/starts/meaning-vm/level-0/common.hpp
+++ b/starts/meaning-vm/level-0/common.hpp
@@ -2,24 +2,48 @@
#define self (*this)
+// macro tools
+#define _macro_expand_to_args(...) __VA_ARGS__
+#define _macro_expand_to_comma_args(...) ,##__VA_ARGS__
+#define _macro_call(funcormacro, ...) funcormacro(__VA_ARGS__)
+#define _macro_remove_parens(args) _macro_expand_to_args args
+#define _macro_comma_remove_parens(args) _macro_expand_to_comma_args args
+
+#define _macro_expand_to_arg1(arg, ...) arg
+#define _macro_expand_to_arg2(_1, arg, ...) arg
+
// macro argument iteration, from stackoverflow.com/questions/1872220
#define _macro_for_each(funcormacro,...) \
- _macro_fe_get(__VA_ARGS__, \
+ _macro_fe_get(_0,##__VA_ARGS__, \
_macro_fe_9,_macro_fe_8,_macro_fe_7,_macro_fe_6,_macro_fe_5,_macro_fe_4,_macro_fe_3,_macro_fe_2,_macro_fe_1,_macro_fe_0 \
)(funcormacro,__VA_ARGS__)
- #define _macro_fe_0(what, x, ...) what(x)
- #define _macro_fe_1(what, x, ...) what(x)fe_0(what, __VA_ARGS__)
- #define _macro_fe_2(what, x, ...) what(x)fe_1(what, __VA_ARGS__)
- #define _macro_fe_3(what, x, ...) what(x)fe_2(what, __VA_ARGS__)
- #define _macro_fe_4(what, x, ...) what(x)fe_3(what, __VA_ARGS__)
- #define _macro_fe_5(what, x, ...) what(x)fe_4(what, __VA_ARGS__)
- #define _macro_fe_6(what, x, ...) what(x)fe_5(what, __VA_ARGS__)
- #define _macro_fe_7(what, x, ...) what(x)fe_6(what, __VA_ARGS__)
- #define _macro_fe_8(what, x, ...) what(x)fe_7(what, __VA_ARGS__)
- #define _macro_fe_9(what, x, ...) what(x)fe_8(what, __VA_ARGS__)
+ #define _macro_fe_0(what, ...)
+ #define _macro_fe_1(what, x, ...) what(x)_macro_fe_0(what, __VA_ARGS__)
+ #define _macro_fe_2(what, x, ...) what(x)_macro_fe_1(what, __VA_ARGS__)
+ #define _macro_fe_3(what, x, ...) what(x)_macro_fe_2(what, __VA_ARGS__)
+ #define _macro_fe_4(what, x, ...) what(x)_macro_fe_3(what, __VA_ARGS__)
+ #define _macro_fe_5(what, x, ...) what(x)_macro_fe_4(what, __VA_ARGS__)
+ #define _macro_fe_6(what, x, ...) what(x)_macro_fe_5(what, __VA_ARGS__)
+ #define _macro_fe_7(what, x, ...) what(x)_macro_fe_6(what, __VA_ARGS__)
+ #define _macro_fe_8(what, x, ...) what(x)_macro_fe_7(what, __VA_ARGS__)
+ #define _macro_fe_9(what, x, ...) what(x)_macro_fe_8(what, __VA_ARGS__)
#define _macro_fe_get( \
_0,_1,_2,_3,_4,_5,_6,_7,_8,_9, \
name,...) name
+#define _macro_for_each_parens(funcormacro,...) \
+ _macro_fe_get(_0,##__VA_ARGS__, \
+ _macro_fep9,_macro_fep8,_macro_fep7,_macro_fe_6,_macro_fep5,_macro_fep4,_macro_fep3,_macro_fep2,_macro_fep1,_macro_fep0 \
+ )(funcormacro,__VA_ARGS__)
+ #define _macro_fep0(what, ...)
+ #define _macro_fep1(what, x, ...) what x _macro_fep0(what, __VA_ARGS__)
+ #define _macro_fep2(what, x, ...) what x _macro_fep1(what, __VA_ARGS__)
+ #define _macro_fep3(what, x, ...) what x _macro_fep2(what, __VA_ARGS__)
+ #define _macro_fep4(what, x, ...) what x _macro_fep3(what, __VA_ARGS__)
+ #define _macro_fep5(what, x, ...) what x _macro_fep4(what, __VA_ARGS__)
+ #define _macro_fep6(what, x, ...) what x _macro_fep5(what, __VA_ARGS__)
+ #define _macro_fep7(what, x, ...) what x _macro_fep6(what, __VA_ARGS__)
+ #define _macro_fep8(what, x, ...) what x _macro_fep7(what, __VA_ARGS__)
+ #define _macro_fep9(what, x, ...) what x _macro_fep8(what, __VA_ARGS__)
namespace intellect {
namespace level0 {
diff --git a/starts/meaning-vm/level-2/baseref.hpp b/starts/meaning-vm/level-2/baseref.hpp
index c2bc0d1..921d1d3 100644
--- a/starts/meaning-vm/level-2/baseref.hpp
+++ b/starts/meaning-vm/level-2/baseref.hpp
@@ -19,6 +19,8 @@ struct baseref : public level1::baseref<ref>
// thread-local context
static ref context() { return level2::context(); }
+ template <typename... Refs>
+ ref operator()(Refs... args) { return level2::dohabit(self, {args.ptr()...}); }
};
}
diff --git a/starts/meaning-vm/level-2/common.hpp b/starts/meaning-vm/level-2/common.hpp
index aac072e..3d38155 100644
--- a/starts/meaning-vm/level-2/common.hpp
+++ b/starts/meaning-vm/level-2/common.hpp
@@ -6,5 +6,8 @@ namespace level2 {
template <typename T> struct baseref;
struct ref;
+namespace concepts {
+}
+
}
}
diff --git a/starts/meaning-vm/level-2/concepts.hpp b/starts/meaning-vm/level-2/concepts.hpp
index a8cfb0d..3a6ac6b 100644
--- a/starts/meaning-vm/level-2/concepts.hpp
+++ b/starts/meaning-vm/level-2/concepts.hpp
@@ -8,6 +8,10 @@ namespace level2 {
namespace concepts {
static ref context("context");
+static ref habit("habit");
+static ref next("next");
+static ref positional("positional");
+static ref argument("argument");
}
diff --git a/starts/meaning-vm/level-2/funcs.cpp b/starts/meaning-vm/level-2/funcs.cpp
index c25ead2..b17d221 100644
--- a/starts/meaning-vm/level-2/funcs.cpp
+++ b/starts/meaning-vm/level-2/funcs.cpp
@@ -2,17 +2,58 @@
#include "../level-1/sugar.hpp"
#include "ref.hpp"
+#include "concepts.hpp"
namespace intellect {
using namespace level1;
namespace level2 {
+using namespace concepts;
+
ref context()
{
- static thread_local auto ctx = a("context");
+ static thread_local auto ctx = a(concepts::context);
return ctx;
}
+ref makehabit(ref name, std::initializer_list<ref> argnames, std::function<void()> code)
+{
+ ref habit = level1::a(habit, name);
+ ref posarg = habit;
+ for (auto argname : argnames) {
+ ref nextarg = a(positional-argument);
+ nextarg.set(argument, argname);
+ posarg.set(next-positional-argument, nextarg);
+ posarg = nextarg;
+ }
+ habit.fun(code);
+ return habit;
+}
+
+ref dohabit(ref habit, std::initializer_list<ref> args)
+{
+ using namespace concepts;
+ ref posarg = habit;
+ for (ref const & arg : args) {
+ if (!posarg.linked(next-positional-argument)) {
+ throw std::invalid_argument("wrong number of arguments to habit");
+ }
+ posarg = posarg[next-positional-argument];
+ // TODO: subcontexts
+ ref::context().set(posarg[argument], arg);
+ }
+ if (posarg.linked(next-positional-argument)) {
+ throw std::invalid_argument("wrong number of arguments to habit");
+ }
+ ref ret = habit.fun<>()();
+ posarg = habit;
+ while (posarg.linked(next-positional-argument)) {
+ posarg = posarg[next-positional-argument];
+ ref::context().unlink(posarg[argument]);
+ }
+ return ret;
+}
+
}
}
diff --git a/starts/meaning-vm/level-2/funcs.hpp b/starts/meaning-vm/level-2/funcs.hpp
index 52c041d..770ff0a 100644
--- a/starts/meaning-vm/level-2/funcs.hpp
+++ b/starts/meaning-vm/level-2/funcs.hpp
@@ -2,10 +2,15 @@
#include "common.hpp"
+#include <functional>
+#include <initializer_list>
+
namespace intellect {
namespace level2 {
ref context();
+ref makehabit(ref name, std::initializer_list<ref> argnames, std::function<void()> code);
+ref dohabit(ref habit, std::initializer_list<ref> args);
}
}
diff --git a/starts/meaning-vm/level-2/sugar.hpp b/starts/meaning-vm/level-2/sugar.hpp
index 6734eae..3b0e2c0 100644
--- a/starts/meaning-vm/level-2/sugar.hpp
+++ b/starts/meaning-vm/level-2/sugar.hpp
@@ -4,45 +4,46 @@
#include <time.h> // int time(0); int clock_gettime(CLOCK_REALTIME, struct timespec *tp{tv_sec,tv_nsec})
#include <unistd.h> // usleep(unsigned int usecs)
-#define habitdelay \
- static int thisdelay = (double(rand()) / RAND_MAX * 400000 + 200000); \
- usleep(thisdelay)
-
#undef self
-#define ahabit(name, ...) \
- a(habit, name); \
- (name).fun((std::function<void()>) \
- [=]() -> ref\
+
+// habits have a structure such that they contain information about their positional
+// arguments. they are made with a macro that turns the args into local variables.
+// the function to call them takes any number of arguments, and these are placed in the
+// thread context according to the information in the habit.
+
+// idea: preprocessor for level3 runs with habits
+// runs after C preprocessor and responds to output produced by macros e.g.
+// SET SYMBOL: <any string>
+// UNSET SYMBOL: <any string>
+// between the two <any string> is converted to valid c symbol when not double quoted.
+// removes much of the need for individual word declarations,
+// and starts to pave way towards user/intellect participation
+// here, could remove the 'tok' for local refnames.
+
+#define ahabit(name, argnametoklist, ...) \
+ intellect::level2::makehabit( \
+ name, \
+ {_macro_call(_macro_for_each_parens, _macro_habit_argnameref _macro_comma_remove_parens(argnametoklist))}, \
+ (std::function<void()>) \
+ [=]() \
{ \
- habitdelay; \
+ { \
+ static int delay = (double(rand()) / RAND_MAX * 400000 + 200000); \
+ usleep(delay); \
+ } \
ref self = name; (void)self; \
ref ctx = intellect::level2::ref::context(); (void) ctx;\
+ _macro_call(_macro_for_each_parens, _macro_habit_set_posarg _macro_comma_remove_parens(argnametoklist)); \
__VA_ARGS__ \
- return intellect::level1::concepts::nothing; \
});
-
-// thinking on handling arguments with less boilerplate, more positional sugar
-// transfer argslist to a context for calling?
-// possibly transfer argslist to a function signature for the call
-// transfer context to the argslist for handling call
-// for each item of argslist, make a local variable, and set it to its value
-/*
-#define _positionalhabitarg(local, arg) \
- ref local = ctx.get(arg);
-#define _ph
-
-#define apositionalhabit(name, argslist, ...) \
- a(habit, name); \
- (name).fun((std::function<ref(ref)>) \
- [=](ref ctx) \
- { \
- \
- });
-*/
-
-// seed random number generator statically, for habitdelay
-namespace __internal {
-static struct timespec __tp;
-static int __timeres = clock_gettime(CLOCK_REALTIME, &__tp);
-static int __seed = (srand(__tp.tv_nsec), __tp.tv_nsec);
-}
+ #define _macro_habit_argnameref(name, tok) \
+ ref(#name)
+ #define _macro_habit_set_posarg(name, tok) \
+ ref tok = ctx[ref(#name)];
+
+ // seed random number generator statically, for habit delay
+ namespace _macro_habit {
+ static struct timespec tp;
+ static int timeres = clock_gettime(CLOCK_REALTIME, &tp);
+ static int seed = (srand(tp.tv_nsec), tp.tv_nsec);
+ }
diff --git a/starts/meaning-vm/makefile b/starts/meaning-vm/makefile
index fbb8a57..bd0d2bd 100644
--- a/starts/meaning-vm/makefile
+++ b/starts/meaning-vm/makefile
@@ -1,4 +1,4 @@
-CXXFLAGS=-Wall -Werror -std=c++17 -fno-operator-names -ggdb -O0
+CXXFLAGS=-Wall -Werror -std=gnu++17 -fno-operator-names -ggdb -O0
LINK.o=$(LINK.cc)
all: level0 level1 habit-starts/rhythm
@@ -11,10 +11,16 @@ liblevel2.a: $(patsubst %.cpp,%.o,$(wildcard level-0/*.cpp)) $(patsubst %.cpp,%.
habit-starts/rhythm: habit-starts/rhythm.o liblevel2.a
+%.o: %.ii
+ $(CXX) $(CXXFLAGS) -c $^ -o $@
+%.ii: %.cpp
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -E $^ -o $@
+.INTERMEDIATE: $(patsubst %.cpp,%.ii,$(wildcard */*.cpp *.cpp))
+
liblevel%.a: level-%/*.hpp
%.a:
ar ru $@ $^
ranlib $@
clean:
- -rm *.o level? *.a */*.o
+ -rm *.ii *.o level? *.a */*.o */*.ii